diff mbox

[5/6] ARM: EXYNOS: Add support for Exynos secure firmware

Message ID 1348496913-25422-6-git-send-email-t.figa@samsung.com (mailing list archive)
State New, archived
Headers show

Commit Message

Tomasz Figa Sept. 24, 2012, 2:28 p.m. UTC
Some Exynos-based boards contain secure firmware and must use firmware
operations to set up some hardware.

This patch adds firmware operations for Exynos secure firmware and a way
for board code and device tree to specify that they must be used.

Example of use:

In board code:

	...MACHINE_START(...)
		/* ... */
		.init_early	= exynos_firmware_init,
		/* ... */
	MACHINE_END

In device tree:

	/ {
		/* ... */

		firmware {
			compatible = "samsung,secure-firmware";
		};

		/* ... */
	};

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 .../devicetree/bindings/arm/samsung-boards.txt     |  8 ++++
 arch/arm/mach-exynos/Makefile                      |  1 +
 arch/arm/mach-exynos/common.h                      |  2 +
 arch/arm/mach-exynos/firmware.c                    | 54 ++++++++++++++++++++++
 arch/arm/mach-exynos/mach-exynos4-dt.c             |  1 +
 5 files changed, 66 insertions(+)
 create mode 100644 arch/arm/mach-exynos/firmware.c

Comments

Olof Johansson Oct. 10, 2012, 4 p.m. UTC | #1
Hi,

On Mon, Sep 24, 2012 at 04:28:32PM +0200, Tomasz Figa wrote:
> Some Exynos-based boards contain secure firmware and must use firmware
> operations to set up some hardware.
> 
> This patch adds firmware operations for Exynos secure firmware and a way
> for board code and device tree to specify that they must be used.
> 
> Example of use:
> 
> In board code:
> 
> 	...MACHINE_START(...)
> 		/* ... */
> 		.init_early	= exynos_firmware_init,
> 		/* ... */
> 	MACHINE_END
> 
> In device tree:
> 
> 	/ {
> 		/* ... */
> 
> 		firmware {
> 			compatible = "samsung,secure-firmware";
> 		};
> 
> 		/* ... */
> 	};
> 
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> ---
>  .../devicetree/bindings/arm/samsung-boards.txt     |  8 ++++
>  arch/arm/mach-exynos/Makefile                      |  1 +
>  arch/arm/mach-exynos/common.h                      |  2 +
>  arch/arm/mach-exynos/firmware.c                    | 54 ++++++++++++++++++++++
>  arch/arm/mach-exynos/mach-exynos4-dt.c             |  1 +
>  5 files changed, 66 insertions(+)
>  create mode 100644 arch/arm/mach-exynos/firmware.c
> 
> diff --git a/Documentation/devicetree/bindings/arm/samsung-boards.txt b/Documentation/devicetree/bindings/arm/samsung-boards.txt
> index 0bf68be..f447059 100644
> --- a/Documentation/devicetree/bindings/arm/samsung-boards.txt
> +++ b/Documentation/devicetree/bindings/arm/samsung-boards.txt
> @@ -6,3 +6,11 @@ Required root node properties:
>      - compatible = should be one or more of the following.
>          (a) "samsung,smdkv310" - for Samsung's SMDKV310 eval board.
>          (b) "samsung,exynos4210"  - for boards based on Exynos4210 SoC.
> +
> +Optional:
> +    - firmware node, specifying presence and type of secure firmware, currently
> +        supported value of compatible property is "samsung,secure-firmware":
> +
> +	firmware {
> +		compatible = "samsung,secure-firmware";
> +	};

If you require the binding to specify the memory area, then you at least allow
for future work to move to a dynamic mapping without updating the binding and
all device trees. So, please do that even if the code is hardcoded to the
static address today.

For extra credit, make sure that the reg property is matching the static mapping
when you setup your firmware interface on your platform.


[...]

> +static int exynos_cpu_boot_reg(int cpu, void __iomem **ptr)
> +{
> +	*ptr = S5P_VA_SYSRAM_NS + 0x1c + 4*cpu;
> +	return 0;
> +}

It would be nice to get a memory map for the SMC area in documentation
somewhere, but that can be done separately later.


-Olof
Tomasz Figa Oct. 11, 2012, 1:18 p.m. UTC | #2
Hi Olof,

On Wednesday 10 of October 2012 09:00:27 Olof Johansson wrote:
> Hi,
> 
> On Mon, Sep 24, 2012 at 04:28:32PM +0200, Tomasz Figa wrote:
> > Some Exynos-based boards contain secure firmware and must use firmware
> > operations to set up some hardware.
> > 
> > This patch adds firmware operations for Exynos secure firmware and a
> > way
> > for board code and device tree to specify that they must be used.
> > 
> > Example of use:
> > 
> > In board code:
> > 	...MACHINE_START(...)
> > 	
> > 		/* ... */
> > 		.init_early	= exynos_firmware_init,
> > 		/* ... */
> > 	
> > 	MACHINE_END
> > 
> > In device tree:
> > 	/ {
> > 	
> > 		/* ... */
> > 		
> > 		firmware {
> > 		
> > 			compatible = "samsung,secure-firmware";
> > 		
> > 		};
> > 		
> > 		/* ... */
> > 	
> > 	};
> > 
> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> > Signed-off-by: Tomasz Figa <t.figa@samsung.com>
> > ---
> > 
> >  .../devicetree/bindings/arm/samsung-boards.txt     |  8 ++++
> >  arch/arm/mach-exynos/Makefile                      |  1 +
> >  arch/arm/mach-exynos/common.h                      |  2 +
> >  arch/arm/mach-exynos/firmware.c                    | 54
> >  ++++++++++++++++++++++ arch/arm/mach-exynos/mach-exynos4-dt.c        
> >      |  1 +
> >  5 files changed, 66 insertions(+)
> >  create mode 100644 arch/arm/mach-exynos/firmware.c
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/samsung-boards.txt
> > b/Documentation/devicetree/bindings/arm/samsung-boards.txt index
> > 0bf68be..f447059 100644
> > --- a/Documentation/devicetree/bindings/arm/samsung-boards.txt
> > +++ b/Documentation/devicetree/bindings/arm/samsung-boards.txt
> > 
> > @@ -6,3 +6,11 @@ Required root node properties:
> >      - compatible = should be one or more of the following.
> >      
> >          (a) "samsung,smdkv310" - for Samsung's SMDKV310 eval board.
> >          (b) "samsung,exynos4210"  - for boards based on Exynos4210
> >          SoC.
> > 
> > +
> > +Optional:
> > +    - firmware node, specifying presence and type of secure firmware,
> > currently +        supported value of compatible property is
> > "samsung,secure-firmware": +
> > +	firmware {
> > +		compatible = "samsung,secure-firmware";
> > +	};
> 
> If you require the binding to specify the memory area, then you at least
> allow for future work to move to a dynamic mapping without updating the
> binding and all device trees. So, please do that even if the code is
> hardcoded to the static address today.

All right.

> For extra credit, make sure that the reg property is matching the static
> mapping when you setup your firmware interface on your platform.

Hmm, do you know a way to look up physical address of such static mapping, 
given only the virtual address? Additional problem is that the code is 
executed very early (in init_early callback), before most of VM 
initialization code.

I could do something like

	if (soc_is_exynos4210())
		paddr = EXYNOS4210_PA_SYSRAM_NS;
	else if (soc_is_exynos4212() || soc_is_exynos4412())
		paddr = EXYNOS4x12_PA_SYSRAM_NS;
	...

and compare paddr with address received from device tree, but I don't 
really like this construct.
 
> > +static int exynos_cpu_boot_reg(int cpu, void __iomem **ptr)
> > +{
> > +	*ptr = S5P_VA_SYSRAM_NS + 0x1c + 4*cpu;
> > +	return 0;
> > +}
> 
> It would be nice to get a memory map for the SMC area in documentation
> somewhere, but that can be done separately later.

OK.

Best regards,
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/arm/samsung-boards.txt b/Documentation/devicetree/bindings/arm/samsung-boards.txt
index 0bf68be..f447059 100644
--- a/Documentation/devicetree/bindings/arm/samsung-boards.txt
+++ b/Documentation/devicetree/bindings/arm/samsung-boards.txt
@@ -6,3 +6,11 @@  Required root node properties:
     - compatible = should be one or more of the following.
         (a) "samsung,smdkv310" - for Samsung's SMDKV310 eval board.
         (b) "samsung,exynos4210"  - for boards based on Exynos4210 SoC.
+
+Optional:
+    - firmware node, specifying presence and type of secure firmware, currently
+        supported value of compatible property is "samsung,secure-firmware":
+
+	firmware {
+		compatible = "samsung,secure-firmware";
+	};
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 5c1de47..b464333 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -31,6 +31,7 @@  obj-$(CONFIG_EXYNOS4_MCT)	+= mct.o
 obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
 
 obj-$(CONFIG_ARCH_EXYNOS)	+= exynos-smc.o
+obj-$(CONFIG_ARCH_EXYNOS)	+= firmware.o
 
 plus_sec := $(call as-instr,.arch_extension sec,+sec)
 AFLAGS_exynos-smc.o		:=-Wa,-march=armv7-a$(plus_sec)
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index aed2eeb..540918f 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -21,6 +21,8 @@  void exynos4_restart(char mode, const char *cmd);
 void exynos5_restart(char mode, const char *cmd);
 void exynos_init_late(void);
 
+void exynos_firmware_init(void);
+
 #ifdef CONFIG_PM_GENERIC_DOMAINS
 int exynos_pm_late_initcall(void);
 #else
diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
new file mode 100644
index 0000000..67d975d
--- /dev/null
+++ b/arch/arm/mach-exynos/firmware.c
@@ -0,0 +1,54 @@ 
+/*
+ * Copyright (C) 2012 Samsung Electronics.
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ * Tomasz Figa <t.figa@samsung.com>
+ *
+ * This program is free software,you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of.h>
+
+#include <asm/firmware.h>
+
+#include <mach/map.h>
+
+#include "smc.h"
+
+static int exynos_do_idle(void)
+{
+        exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
+        return 0;
+}
+
+static int exynos_cpu_boot(int cpu)
+{
+	exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0);
+	return 0;
+}
+
+static int exynos_cpu_boot_reg(int cpu, void __iomem **ptr)
+{
+	*ptr = S5P_VA_SYSRAM_NS + 0x1c + 4*cpu;
+	return 0;
+}
+
+static const struct firmware_ops exynos_firmware_ops = {
+	.do_idle	= exynos_do_idle,
+	.cpu_boot	= exynos_cpu_boot,
+	.cpu_boot_reg	= exynos_cpu_boot_reg,
+};
+
+void __init exynos_firmware_init(void)
+{
+	if (of_have_populated_dt() &&
+	    !of_find_compatible_node(NULL, NULL, "samsung,secure-firmware"))
+		return;
+
+	pr_info("Running under secure firmware.\n");
+
+	register_firmware_ops(&exynos_firmware_ops);
+}
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index b2b5d5f..a244e4a 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -88,6 +88,7 @@  DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
 	.init_irq	= exynos4_init_irq,
 	.map_io		= exynos4210_dt_map_io,
 	.handle_irq	= gic_handle_irq,
+	.init_early	= exynos_firmware_init,
 	.init_machine	= exynos4210_dt_machine_init,
 	.init_late	= exynos_init_late,
 	.timer		= &exynos4_timer,