Skip to contentSkip to conversation

ARM: EXYNOS: Add secure firmware support

PATCH Superseded Tomasz Figa 4 participants 17 messages Oct 25, 2012 – Dec 26, 2012

Subsystems (4)

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v3 cover ARM: EXYNOS: Add secure firmware support

Some Exynos-based boards are running with secure firmware running in TrustZone secure world, which changes the way some things have to be initialized.

This series adds support for specifying firmware operations, implements some firmware operations for Exynos secure firmware and adds a method of enabling secure firmware operations on Exynos-based boards through board file and device tree.

Changes since v2
( http://thread.gmane.org/gmane.linux.kernel.samsung-soc/12848 )
- Made Exynos firmware binding require address
- Minor style fixes

Changes since v1
( http://thread.gmane.org/gmane.linux.kernel.samsung-soc/12583/focus=12820 )
- Changed return types of all operations to int
- Defined all operations to return 0 on success, -ENOSYS when not implemented or appropriate error code on error

Tomasz Figa (6):
ARM: Add interface for registering and calling firmware-specific
operations
ARM: EXYNOS: Add support for secure monitor calls
ARM: EXYNOS: Add IO mapping for non-secure SYSRAM.
ARM: EXYNOS: Add support for Exynos secure firmware
ARM: EXYNOS: Add support for secondary CPU bring-up on Exynos4412
ARM: EXYNOS: Add secure firmware support to secondary CPU bring-up

 .../devicetree/bindings/arm/samsung-boards.txt     | 10 ++++
 arch/arm/common/Makefile                           |  2 +
 arch/arm/common/firmware.c                         | 18 ++++++
 arch/arm/include/asm/firmware.h                    | 31 ++++++++++
 arch/arm/mach-exynos/Makefile                      |  6 ++
 arch/arm/mach-exynos/common.c                      | 35 +++++++++++
 arch/arm/mach-exynos/common.h                      |  2 +
 arch/arm/mach-exynos/exynos-smc.S                  | 22 +++++++
 arch/arm/mach-exynos/firmware.c                    | 67 ++++++++++++++++++++++
 arch/arm/mach-exynos/include/mach/map.h            |  3 +
 arch/arm/mach-exynos/mach-exynos4-dt.c             |  1 +
 arch/arm/mach-exynos/platsmp.c                     | 37 ++++++++++--
 arch/arm/mach-exynos/smc.h                         | 31 ++++++++++
 arch/arm/plat-samsung/include/plat/map-s5p.h       |  1 +
 14 files changed, 260 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm/common/firmware.c
 create mode 100644 arch/arm/include/asm/firmware.h
 create mode 100644 arch/arm/mach-exynos/exynos-smc.S
 create mode 100644 arch/arm/mach-exynos/firmware.c
 create mode 100644 arch/arm/mach-exynos/smc.h
Signature · 1 line
1.7.12
#1 lore raw

PATCH v3 1/6 ARM: Add interface for registering and calling firmware-specific operations

Some boards are running with secure firmware running in TrustZone secure world, which changes the way some things have to be initialized.

This patch adds an interface for platforms to specify available firmware operations and call them.

A wrapper macro, call_firmware_op(), checks if the operation is provided and calls it if so, otherwise returns -ENOSYS to allow fallback to legacy operation..

By default no operations are provided.

Example of use:

In code using firmware ops:

	__raw_writel(virt_to_phys(exynos4_secondary_startup),
		CPU1_BOOT_REG);

	/* Call Exynos specific smc call */
	if (call_firmware_op(cpu_boot, cpu) == -ENOSYS)
		cpu_boot_legacy(...); /* Try legacy way */

	gic_raise_softirq(cpumask_of(cpu), 1);

In board-/platform-specific code:

	static int platformX_do_idle(void)
	{
		/* tell platformX firmware to enter idle */
	        return 0;
	}

	static int platformX_cpu_boot(int i)
	{
		/* tell platformX firmware to boot CPU i */
		return 0;
	}

	static const struct firmware_ops platformX_firmware_ops = {
		.do_idle	= exynos_do_idle,
		.cpu_boot	= exynos_cpu_boot,
		/* other operations not available on platformX */
	};

	static void __init board_init_early(void)
	{
	????????register_firmware_ops(&platformX_firmware_ops);
	}
---
 arch/arm/common/Makefile        |  2 ++
 arch/arm/common/firmware.c      | 18 ++++++++++++++++++
 arch/arm/include/asm/firmware.h | 31 +++++++++++++++++++++++++++++++
 3 files changed, 51 insertions(+)
 create mode 100644 arch/arm/common/firmware.c
 create mode 100644 arch/arm/include/asm/firmware.h
arch/arm/common/Makefile +2 -0
index e8a4e58..55d4182 100644
@@ -2,6 +2,8 @@
 # Makefile for the linux kernel.
 #
 
+obj-y += firmware.o
+
 obj-$(CONFIG_ARM_GIC)		+= gic.o
 obj-$(CONFIG_ARM_VIC)		+= vic.o
 obj-$(CONFIG_ICST)		+= icst.o
arch/arm/common/firmware.c new file +18 -0
new file mode 100644
index 0000000..27ddccb
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics.
+ * Kyungmin Park <[email protected]>
+ * Tomasz Figa <[email protected]>
+ *
+ * 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/suspend.h>
+
+#include <asm/firmware.h>
+
+static const struct firmware_ops default_firmware_ops;
+
+const struct firmware_ops *firmware_ops = &default_firmware_ops;
arch/arm/include/asm/firmware.h new file +31 -0
new file mode 100644
index 0000000..5d87d8e
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics.
+ * Kyungmin Park <[email protected]>
+ * Tomasz Figa <[email protected]>
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARM_FIRMWARE_H
+#define __ASM_ARM_FIRMWARE_H
+
+struct firmware_ops {
+	int (*do_idle)(void);
+	int (*cpu_boot)(int cpu);
+	int (*cpu_boot_reg)(int cpu, void __iomem **ptr);
+	int (*l2x0_init)(void);
+};
+
+extern const struct firmware_ops *firmware_ops;
+
+#define call_firmware_op(op, ...)					\
+	((firmware_ops->op) ? firmware_ops->op(__VA_ARGS__) : (-ENOSYS))
+
+static inline void register_firmware_ops(const struct firmware_ops *ops)
+{
+	firmware_ops = ops;
+}
+
+#endif
Signature · 1 line
1.7.12
#2 lore raw

PATCH v3 2/6 ARM: EXYNOS: Add support for secure monitor calls

In reply to Tomasz Figa

Some boards use secure monitor calls to communicate with secure firmware.

This patch adds exynos_smc function which uses smc assembly instruction to do secure monitor calls.

---
 arch/arm/mach-exynos/Makefile     |  5 +++++
 arch/arm/mach-exynos/exynos-smc.S | 22 ++++++++++++++++++++++
 arch/arm/mach-exynos/smc.h        | 31 +++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+)
 create mode 100644 arch/arm/mach-exynos/exynos-smc.S
 create mode 100644 arch/arm/mach-exynos/smc.h
arch/arm/mach-exynos/Makefile +5 -0
index 9b58024..5c1de47 100644
@@ -30,6 +30,11 @@ obj-$(CONFIG_EXYNOS4_MCT)	+= mct.o
 
 obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
 
+obj-$(CONFIG_ARCH_EXYNOS)	+= exynos-smc.o
+
+plus_sec := $(call as-instr,.arch_extension sec,+sec)
+AFLAGS_exynos-smc.o		:=-Wa,-march=armv7-a$(plus_sec)
+
 # machine support
 
 obj-$(CONFIG_MACH_SMDKC210)		+= mach-smdkv310.o
arch/arm/mach-exynos/exynos-smc.S new file +22 -0
new file mode 100644
index 0000000..2e27aa3
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics.
+ *
+ * Copied from omap-smc.S Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * 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/linkage.h>
+
+/*
+ * Function signature: void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3)
+ */
+
+ENTRY(exynos_smc)
+	stmfd	sp!, {r4-r11, lr}
+	dsb
+	smc	#0
+	ldmfd	sp!, {r4-r11, pc}
+ENDPROC(exynos_smc)
arch/arm/mach-exynos/smc.h new file +31 -0
new file mode 100644
index 0000000..e972390
@@ -0,0 +1,31 @@
+/*
+ *  Copyright (c) 2012 Samsung Electronics.
+ *
+ * EXYNOS - SMC Call
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_EXYNOS_SMC_H
+#define __ASM_ARCH_EXYNOS_SMC_H
+
+#define SMC_CMD_INIT            (-1)
+#define SMC_CMD_INFO            (-2)
+/* For Power Management */
+#define SMC_CMD_SLEEP           (-3)
+#define SMC_CMD_CPU1BOOT        (-4)
+#define SMC_CMD_CPU0AFTR        (-5)
+/* For CP15 Access */
+#define SMC_CMD_C15RESUME       (-11)
+/* For L2 Cache Access */
+#define SMC_CMD_L2X0CTRL        (-21)
+#define SMC_CMD_L2X0SETUP1      (-22)
+#define SMC_CMD_L2X0SETUP2      (-23)
+#define SMC_CMD_L2X0INVALL      (-24)
+#define SMC_CMD_L2X0DEBUG       (-25)
+
+extern void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3);
+
+#endif
Signature · 1 line
1.7.12
#3 lore raw

PATCH v3 3/6 ARM: EXYNOS: Add IO mapping for non-secure SYSRAM.

In reply to Tomasz Figa

On TrustZone-enabled boards the non-secure SYSRAM is used for secondary CPU bring-up, so add a mapping for it.

---
 arch/arm/mach-exynos/common.c                | 35 ++++++++++++++++++++++++++++
 arch/arm/mach-exynos/include/mach/map.h      |  3 +++
 arch/arm/plat-samsung/include/plat/map-s5p.h |  1 +
 3 files changed, 39 insertions(+)
arch/arm/mach-exynos/common.c +35 -0
index 1947be8..cb891a7 100644
@@ -215,6 +215,33 @@ static struct map_desc exynos4_iodesc1[] __initdata = {
 	},
 };
 
+static struct map_desc exynos4210_iodesc[] __initdata = {
+	{
+		.virtual	= (unsigned long)S5P_VA_SYSRAM_NS,
+		.pfn		= __phys_to_pfn(EXYNOS4210_PA_SYSRAM_NS),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	},
+};
+
+static struct map_desc exynos4x12_iodesc[] __initdata = {
+	{
+		.virtual	= (unsigned long)S5P_VA_SYSRAM_NS,
+		.pfn		= __phys_to_pfn(EXYNOS4x12_PA_SYSRAM_NS),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	},
+};
+
+static struct map_desc exynos5250_iodesc[] __initdata = {
+	{
+		.virtual	= (unsigned long)S5P_VA_SYSRAM_NS,
+		.pfn		= __phys_to_pfn(EXYNOS5250_PA_SYSRAM_NS),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	},
+};
+
 static struct map_desc exynos5_iodesc[] __initdata = {
 	{
 		.virtual	= (unsigned long)S3C_VA_SYS,
@@ -322,6 +349,11 @@ static void __init exynos4_map_io(void)
 	else
 		iotable_init(exynos4_iodesc1, ARRAY_SIZE(exynos4_iodesc1));
 
+	if (soc_is_exynos4210())
+		iotable_init(exynos4210_iodesc, ARRAY_SIZE(exynos4210_iodesc));
+	if (soc_is_exynos4212() || soc_is_exynos4412())
+		iotable_init(exynos4x12_iodesc, ARRAY_SIZE(exynos4x12_iodesc));
+
 	/* initialize device information early */
 	exynos4_default_sdhci0();
 	exynos4_default_sdhci1();
@@ -355,6 +387,9 @@ static void __init exynos5_map_io(void)
 {
 	iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
 
+	if (soc_is_exynos5250())
+		iotable_init(exynos5250_iodesc, ARRAY_SIZE(exynos5250_iodesc));
+
 	s3c_device_i2c0.resource[0].start = EXYNOS5_PA_IIC(0);
 	s3c_device_i2c0.resource[0].end   = EXYNOS5_PA_IIC(0) + SZ_4K - 1;
 	s3c_device_i2c0.resource[1].start = EXYNOS5_IRQ_IIC;
arch/arm/mach-exynos/include/mach/map.h +3 -0
index 8480849..42f4444 100644
@@ -26,6 +26,9 @@
 #define EXYNOS4_PA_SYSRAM0		0x02025000
 #define EXYNOS4_PA_SYSRAM1		0x02020000
 #define EXYNOS5_PA_SYSRAM		0x02020000
+#define EXYNOS4210_PA_SYSRAM_NS		0x0203F000
+#define EXYNOS4x12_PA_SYSRAM_NS		0x0204F000
+#define EXYNOS5250_PA_SYSRAM_NS		0x0204F000
 
 #define EXYNOS4_PA_FIMC0		0x11800000
 #define EXYNOS4_PA_FIMC1		0x11810000
arch/arm/plat-samsung/include/plat/map-s5p.h +1 -0
index c2d7bda..c186786 100644
@@ -22,6 +22,7 @@
 #define S5P_VA_GPIO3		S3C_ADDR(0x02280000)
 
 #define S5P_VA_SYSRAM		S3C_ADDR(0x02400000)
+#define S5P_VA_SYSRAM_NS	S3C_ADDR(0x02410000)
 #define S5P_VA_DMC0		S3C_ADDR(0x02440000)
 #define S5P_VA_DMC1		S3C_ADDR(0x02480000)
 #define S5P_VA_SROMC		S3C_ADDR(0x024C0000)
Signature · 1 line
1.7.12
#4 lore raw

PATCH v3 4/6 ARM: EXYNOS: Add support for Exynos secure firmware

In reply to Tomasz Figa

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 at 0203F000 {
			compatible = "samsung,secure-firmware";
			reg = <0x0203F000 0x1000>;
		};

		/* ... */
	};
---
 .../devicetree/bindings/arm/samsung-boards.txt     | 10 ++++
 arch/arm/mach-exynos/Makefile                      |  1 +
 arch/arm/mach-exynos/common.h                      |  2 +
 arch/arm/mach-exynos/firmware.c                    | 67 ++++++++++++++++++++++
 arch/arm/mach-exynos/mach-exynos4-dt.c             |  1 +
 5 files changed, 81 insertions(+)
 create mode 100644 arch/arm/mach-exynos/firmware.c
Documentation/devicetree/bindings/arm/samsung-boards.txt +10 -0
index 0bf68be..2168ed3 100644
@@ -6,3 +6,13 @@ 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:
+        - compatible: only "samsung,secure-firmware" is currently supported
+        - reg: address of non-secure SYSRAM used for communication with firmware
+
+	firmware at 0203F000 {
+		compatible = "samsung,secure-firmware";
+		reg = <0x0203F000 0x1000>;
+	};
arch/arm/mach-exynos/Makefile +1 -0
index 5c1de47..b464333 100644
@@ -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)
arch/arm/mach-exynos/common.h +2 -0
index dac146d..5f1d393 100644
@@ -22,6 +22,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
arch/arm/mach-exynos/firmware.c new file +67 -0

67 lines not on this page · raw message

arch/arm/mach-exynos/mach-exynos4-dt.c +1 -0
index eadf4b5..977bd39 100644
@@ -103,6 +103,7 @@ DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
 	.init_irq	= exynos4_init_irq,
 	.map_io		= exynos4_dt_map_io,
 	.handle_irq	= gic_handle_irq,
+	.init_early	= exynos_firmware_init,
 	.init_machine	= exynos4_dt_machine_init,
 	.init_late	= exynos_init_late,
 	.timer		= &exynos4_timer,
Signature · 1 line
1.7.12
#5 lore raw

PATCH v3 4/6 ARM: EXYNOS: Add support for Exynos secure firmware

arch/arm/mach-exynos/firmware.c line 26

Quoted 5 lines · Tomasz Figa
arch/arm/mach-exynos/firmware.c new file +5 -0
+static int exynos_do_idle(void)
+{
+        exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
+        return 0;
+}

This looks fine as an API - it has a defined purpose.

arch/arm/mach-exynos/firmware.c line 32

Quoted 6 lines
arch/arm/mach-exynos/firmware.c new file +6 -0
+
+static int exynos_cpu_boot(int cpu)
+{
+	exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0);
+	return 0;
+}

Same for this (though, what _exactly_ is 'cpu', is it the physical CPU number or the logical CPU number?)

arch/arm/mach-exynos/firmware.c line 38

Quoted 6 lines
arch/arm/mach-exynos/firmware.c new file +6 -0
+
+static int exynos_cpu_boot_reg(int cpu, void __iomem **ptr)
+{
+	*ptr = S5P_VA_SYSRAM_NS + 0x1c + 4*cpu;
+	return 0;
+}

This is really bad. What's it trying to do? What is the significance of the 'ptr' returned? What if a platform doesn't have a boot register?

#6 lore raw

PATCH v3 4/6 ARM: EXYNOS: Add support for Exynos secure firmware

Hi Russel,

Quoted 9 lines · On Monday 12 of November 2012 09:51:14 Russell King - ARM Linux wrote:

arch/arm/mach-exynos/firmware.c line 32

Quoted 6 lines
arch/arm/mach-exynos/firmware.c new file +6 -0
+
+static int exynos_cpu_boot(int cpu)
+{
+	exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0);
+	return 0;
+}

Same for this (though, what _exactly_ is 'cpu', is it the physical CPU number or the logical CPU number?)

Yes, it's the physical CPU number.

Quoted 9 lines

arch/arm/mach-exynos/firmware.c line 38

Quoted 6 lines
arch/arm/mach-exynos/firmware.c new file +6 -0
+
+static int exynos_cpu_boot_reg(int cpu, void __iomem **ptr)
+{
+	*ptr = S5P_VA_SYSRAM_NS + 0x1c + 4*cpu;
+	return 0;
+}

This is really bad. What's it trying to do? What is the significance of the 'ptr' returned? What if a platform doesn't have a boot register?

It returns a pointer to the area where boot code (secondary startup) address must be stored.

This callback (just as all the firmware callbacks) is optional, if it is not appropriate for given platform, it will not use it.

However, now when I think of it, it may be better to just add a callback like set_boot_addr(cpu, addr), which would set boot address of given CPU without exporting address of its boot register outside firmware code. Are you OK with this kind of approach?

Best regards,

Signature · 3 lines
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Linux Platform
#7 lore raw

PATCH v3 4/6 ARM: EXYNOS: Add support for Exynos secure firmware

2012/11/12, Tomasz Figa <[email protected]>:

Quoted 28 lines

Hi Russel,

Quoted 9 lines · On Monday 12 of November 2012 09:51:14 Russell King - ARM Linux wrote:

arch/arm/mach-exynos/firmware.c line 32

Quoted 6 lines
arch/arm/mach-exynos/firmware.c new file +6 -0
+
+static int exynos_cpu_boot(int cpu)
+{
+	exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0);
+	return 0;
+}

Same for this (though, what _exactly_ is 'cpu', is it the physical CPU number or the logical CPU number?)

Yes, it's the physical CPU number.

Quoted 9 lines

arch/arm/mach-exynos/firmware.c line 38

Quoted 6 lines
arch/arm/mach-exynos/firmware.c new file +6 -0
+
+static int exynos_cpu_boot_reg(int cpu, void __iomem **ptr)
+{
+	*ptr = S5P_VA_SYSRAM_NS + 0x1c + 4*cpu;
+	return 0;
+}

This is really bad. What's it trying to do? What is the significance of the 'ptr' returned? What if a platform doesn't have a boot register?

It returns a pointer to the area where boot code (secondary startup) address must be stored.

Quoted 7 lines

This callback (just as all the firmware callbacks) is optional, if it is not appropriate for given platform, it will not use it.

However, now when I think of it, it may be better to just add a callback like set_boot_addr(cpu, addr), which would set boot address of given CPU without exporting address of its boot register outside firmware code. Are you OK with this kind of approach?

it seems the firmware_ops you are providing is just for samsung EXYNOS SMC, esepecially for the boot of secondary physical cpu. then it really should be namespaced.

more callbacks for a common secure monitor APIs might need to cover
1. boot of 2nd CPU
2. do_idle(might let the other RTOS running on secure mode to be schedued in)
3. call SMC, send param and get feedback from firmware
4. might need to handle the steal time of firmware, firmware is also taking the CPU time, but linux doesn't know. it will affect the scheduler of Linux.

Quoted 7 lines

Best regards,
--
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Linux Platform

-barry

#8 lore raw

PATCH v3 5/6 ARM: EXYNOS: Add support for secondary CPU bring-up on Exynos4412

In reply to Tomasz Figa

Exynos4412 uses different information register for each core. This patch adjusts the bring-up code to take that into account.

---
 arch/arm/mach-exynos/platsmp.c | 30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)
arch/arm/mach-exynos/platsmp.c +24 -6
index f93d820..4ca8ff1 100644
@@ -36,8 +36,22 @@
 
 extern void exynos4_secondary_startup(void);
 
-#define CPU1_BOOT_REG		(samsung_rev() == EXYNOS4210_REV_1_1 ? \
-				S5P_INFORM5 : S5P_VA_SYSRAM)
+static inline void __iomem *cpu_boot_reg_base(void)
+{
+	if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
+		return S5P_INFORM5;
+	return S5P_VA_SYSRAM;
+}
+
+static inline void __iomem *cpu_boot_reg(int cpu)
+{
+	void __iomem *boot_reg;
+
+	boot_reg = cpu_boot_reg_base();
+	if (soc_is_exynos4412())
+		boot_reg += 4*cpu;
+	return boot_reg;
+}
 
 /*
  * Write pen_release in a way that is guaranteed to be visible to all
@@ -84,6 +98,7 @@ static void __cpuinit exynos_secondary_init(unsigned int cpu)
 static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long timeout;
+	unsigned long phys_cpu = cpu_logical_map(cpu);
 
 	/*
 	 * Set synchronisation state between this boot processor
@@ -99,7 +114,7 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct
 	 * Note that "pen_release" is the hardware CPU ID, whereas
 	 * "cpu" is Linux's internal ID.
 	 */
-	write_pen_release(cpu_logical_map(cpu));
+	write_pen_release(phys_cpu);
 
 	if (!(__raw_readl(S5P_ARM_CORE1_STATUS) & S5P_CORE_LOCAL_PWR_EN)) {
 		__raw_writel(S5P_CORE_LOCAL_PWR_EN,
@@ -133,7 +148,7 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct
 		smp_rmb();
 
 		__raw_writel(virt_to_phys(exynos4_secondary_startup),
-			CPU1_BOOT_REG);
+							cpu_boot_reg(phys_cpu));
 		gic_raise_softirq(cpumask_of(cpu), 0);
 
 		if (pen_release == -1)
@@ -181,6 +196,8 @@ static void __init exynos_smp_init_cpus(void)
 
 static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
 {
+	int i;
+
 	if (!soc_is_exynos5250())
 		scu_enable(scu_base_addr());
 
@@ -190,8 +207,9 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
 	 * until it receives a soft interrupt, and then the
 	 * secondary CPU branches to this address.
 	 */
-	__raw_writel(virt_to_phys(exynos4_secondary_startup),
-			CPU1_BOOT_REG);
+	for (i = 1; i < max_cpus; ++i)
+		__raw_writel(virt_to_phys(exynos4_secondary_startup),
+					cpu_boot_reg(cpu_logical_map(i)));
 }
 
 struct smp_operations exynos_smp_ops __initdata = {
Signature · 1 line
1.7.12
#9 lore raw

PATCH v3 6/6 ARM: EXYNOS: Add secure firmware support to secondary CPU bring-up

In reply to Tomasz Figa

Boards using secure firmware must use different CPU boot registers and call secure firmware to boot the CPU.

---
 arch/arm/mach-exynos/platsmp.c | 7 +++++++
 1 file changed, 7 insertions(+)
arch/arm/mach-exynos/platsmp.c +7 -0
index 4ca8ff1..9f8bdaf 100644
@@ -25,6 +25,7 @@
 #include <asm/hardware/gic.h>
 #include <asm/smp_plat.h>
 #include <asm/smp_scu.h>
+#include <asm/firmware.h>
 
 #include <mach/hardware.h>
 #include <mach/regs-clock.h>
@@ -47,6 +48,8 @@ static inline void __iomem *cpu_boot_reg(int cpu)
 {
 	void __iomem *boot_reg;
 
+	if (!call_firmware_op(cpu_boot_reg, cpu, &boot_reg))
+		return boot_reg;
 	boot_reg = cpu_boot_reg_base();
 	if (soc_is_exynos4412())
 		boot_reg += 4*cpu;
@@ -149,6 +152,10 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct
 
 		__raw_writel(virt_to_phys(exynos4_secondary_startup),
 							cpu_boot_reg(phys_cpu));
+
+		/* Call Exynos specific smc call */
+		call_firmware_op(cpu_boot, phys_cpu);
+
 		gic_raise_softirq(cpumask_of(cpu), 0);
 
 		if (pen_release == -1)
Signature · 1 line
1.7.12
#10 lore raw

PATCH v3 6/6 ARM: EXYNOS: Add secure firmware support to secondary CPU bring-up

arch/arm/mach-exynos/platsmp.c static inline void __iomem *cpu_boot_reg(int cpu) · line 53

Quoted 7 lines · Tomasz Figa
arch/arm/mach-exynos/platsmp.c +2 -0
@@ -47,6 +48,8 @@ static inline void __iomem *cpu_boot_reg(int cpu)
 {
 	void __iomem *boot_reg;
 
+	if (!call_firmware_op(cpu_boot_reg, cpu, &boot_reg))
+		return boot_reg;
 	boot_reg = cpu_boot_reg_base();

That code makes no sense.

#11 lore raw

PATCH v3 6/6 ARM: EXYNOS: Add secure firmware support to secondary CPU bring-up

Quoted 5 lines · On Monday 12 of November 2012 09:52:31 Russell King - ARM Linux wrote:
Quoted 4 lines · Tomasz Figa
(quoted diff) +0 -0
@@ -47,6 +48,8 @@ static inline void __iomem *cpu_boot_reg(int cpu)
 
 {
 
Quoted 8 lines
Quoted 6 lines
arch/arm/mach-exynos/platsmp.c +2 -0
 	void __iomem *boot_reg;
 
+	if (!call_firmware_op(cpu_boot_reg, cpu, &boot_reg))
+		return boot_reg;
 

boot_reg = cpu_boot_reg_base();

That code makes no sense.

Why?

call_firmware_op returning 0 means a success, so boot_reg is filled with proper boot register address, which should be used.

Otherwise (call_firmware_op returning an error) the legacy boot register is used.

Best regards,

Signature · 3 lines
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Linux Platform
#12 lore raw

v3 cover ARM: EXYNOS: Add secure firmware support

In reply to Tomasz Figa
Quoted 52 lines · Tomasz Figa

Some Exynos-based boards are running with secure firmware running in TrustZone secure world, which changes the way some things have to be initialized.

This series adds support for specifying firmware operations, implements some firmware operations for Exynos secure firmware and adds a method of enabling secure firmware operations on Exynos-based boards through board file and device tree.

Changes since v2
( http://thread.gmane.org/gmane.linux.kernel.samsung-soc/12848 )
- Made Exynos firmware binding require address
- Minor style fixes

Changes since v1
( http://thread.gmane.org/gmane.linux.kernel.samsung-
soc/12583/focus=12820 )
- Changed return types of all operations to int
- Defined all operations to return 0 on success, -ENOSYS when not implemented or appropriate error code on error

Tomasz Figa (6):
ARM: Add interface for registering and calling firmware-specific
operations
ARM: EXYNOS: Add support for secure monitor calls
ARM: EXYNOS: Add IO mapping for non-secure SYSRAM.
ARM: EXYNOS: Add support for Exynos secure firmware
ARM: EXYNOS: Add support for secondary CPU bring-up on Exynos4412
ARM: EXYNOS: Add secure firmware support to secondary CPU bring-up

 .../devicetree/bindings/arm/samsung-boards.txt     | 10 ++++
 arch/arm/common/Makefile                           |  2 +
 arch/arm/common/firmware.c                         | 18 ++++++
 arch/arm/include/asm/firmware.h                    | 31 ++++++++++
 arch/arm/mach-exynos/Makefile                      |  6 ++
 arch/arm/mach-exynos/common.c                      | 35 +++++++++++
 arch/arm/mach-exynos/common.h                      |  2 +
 arch/arm/mach-exynos/exynos-smc.S                  | 22 +++++++
 arch/arm/mach-exynos/firmware.c                    | 67 ++++++++++++++++++++++
 arch/arm/mach-exynos/include/mach/map.h            |  3 +
 arch/arm/mach-exynos/mach-exynos4-dt.c             |  1 +
 arch/arm/mach-exynos/platsmp.c                     | 37 ++++++++++--
 arch/arm/mach-exynos/smc.h                         | 31 ++++++++++
 arch/arm/plat-samsung/include/plat/map-s5p.h       |  1 +
 14 files changed, 260 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm/common/firmware.c
 create mode 100644 arch/arm/include/asm/firmware.h
 create mode 100644 arch/arm/mach-exynos/exynos-smc.S
 create mode 100644 arch/arm/mach-exynos/firmware.c
 create mode 100644 arch/arm/mach-exynos/smc.h
Quoted 2 lines

--
1.7.12

(+ Russell King)

As we discussed, let me pick up this series into Samsung tree.

If any objections, please kindly let me know.

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.

#13 lore raw

v3 cover ARM: EXYNOS: Add secure firmware support

Quoted 1 line · Kukjin Kim

(+ Russell King)

I think there's still an amount of work to do here; it's not a generic interface at the moment because it makes some assumptions about how things are done (eg, it assumes that there _will_ be a CPU boot register; that is not always true.

Moreover, the 'cpu' arguments given seem to be uncertain whether they're logical CPU numbers or physical CPU numbers.

Lastly, where is this interface actually documented? It's just a bunch of code _without_ _any_ documentation. That means people will interpret it differently, and it'll get used differently from platform to platform.

Let's have some documentation on this.

#14 lore raw

v3 cover ARM: EXYNOS: Add secure firmware support

Quoted 11 lines · On Monday 12 of November 2012 09:55:30 Russell King - ARM Linux wrote:
Quoted 1 line · Kukjin Kim

(+ Russell King)

I think there's still an amount of work to do here; it's not a generic interface at the moment because it makes some assumptions about how things are done (eg, it assumes that there _will_ be a CPU boot register; that is not always true.

Moreover, the 'cpu' arguments given seem to be uncertain whether they're logical CPU numbers or physical CPU numbers.

Quoted 6 lines

Lastly, where is this interface actually documented? It's just a bunch of code _without_ _any_ documentation. That means people will interpret it differently, and it'll get used differently from platform to platform.

Let's have some documentation on this.

Right, I will include documentation in next version of this patchset.

Best regards,

Signature · 3 lines
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Linux Platform
#15 lore raw

v3 cover ARM: EXYNOS: Add secure firmware support

Quoted 13 lines · Tomasz Figa
Quoted 11 lines · On Monday 12 of November 2012 09:55:30 Russell King - ARM Linux wrote:
Quoted 1 line · Kukjin Kim

(+ Russell King)

I think there's still an amount of work to do here; it's not a generic interface at the moment because it makes some assumptions about how things are done (eg, it assumes that there _will_ be a CPU boot register; that is not always true.

Moreover, the 'cpu' arguments given seem to be uncertain whether they're logical CPU numbers or physical CPU numbers.

Quoted 9 lines
Quoted 6 lines

Lastly, where is this interface actually documented? It's just a bunch of code _without_ _any_ documentation. That means people will interpret it differently, and it'll get used differently from platform to platform.

Let's have some documentation on this.

Right, I will include documentation in next version of this patchset.

Any updates on this?

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.

#16 lore raw

v3 cover ARM: EXYNOS: Add secure firmware support

Hi Kgene,

Quoted 26 lines · On Thursday 22 of November 2012 15:52:14 Kukjin Kim wrote:
Quoted 19 lines · Tomasz Figa
Quoted 18 lines · On Monday 12 of November 2012 09:55:30 Russell King - ARM Linux wrote:
Quoted 1 line · Kukjin Kim

(+ Russell King)

I think there's still an amount of work to do here; it's not a generic
interface at the moment because it makes some assumptions about how things are done (eg, it assumes that there _will_ be a CPU boot register; that is not always true.

Moreover, the 'cpu' arguments given seem to be uncertain whether they're logical CPU numbers or physical CPU numbers.

Lastly, where is this interface actually documented? It's just a bunch
of code _without_ _any_ documentation. That means people will interpret it differently, and it'll get used differently from platform to platform.

Quoted 3 lines
Quoted 1 line

Let's have some documentation on this.

Right, I will include documentation in next version of this patchset.

Any updates on this?

Quoted 7 lines

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.

I was waiting for some comments about my proposals, but since there is no new input I will prepare and post next version today.

Best regards.

Signature · 3 lines
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Linux Platform