[U-Boot] [PATCH 00/15] ARM: PSCI: Add secure stack and data sections

Hi everyone,
This is ARM PSCI improvements part 2. This series cleans up PSCI stack allocation and target PC storage by introducing a secure stack section and a secure data section.
The series got larger than I planned. Some patches are just moving or consolidating code, and a few are adding missing macros. It's based on v3 of my "sunxi: PSCI implementation rewrite in C" series from earlier.
Patch 1 consolidates the stack setup code from all the PSCI-enabled platforms (which likely originated from the initial sunxi version) into a common function, and moves it into a seperate common function that is called before psci_arch_init. A weak stub psci_arch_init is added for platforms that no longer need a custom version.
Patch 2 converts the remaining sunxi PSCI assembly code into C.
Patch 3 adds the missing CONFIG_ARMV7_PSCI_NR_CPUS=2 for sun7i/A20.
Patch 4 makes the linker page align PSCI text only when it is directly executed, i.e. not copied to CONFIG_ARMV7_SECURE_BASE.
Patch 5 adds a fallback value for CONFIG_ARMV7_PSCI_NR_CPUS. The value is 4, which was the fixed maximum number of stacks allocated.
Patch 6 adds an empty stack section for the secure monitor.
Patch 7 has PSCI allocate its stack in the new secure stack section.
Patch 8 removes the now unused psci_text_end symbol. This was previously used to find where to allocate the stack.
Patch 9 adds a config variable for specifying the maximum size of the secure section (text, data, stack, etc.) and checks if the binary exceeds it.
Patch 10 defines CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i (A31/A20), Allwinner SoCs that have a block of secure SRAM.
Patch 11 moves the __secure macro to asm/secure.h. Previously sunxi and i.MX7 were defining it themselves.
Patch 12 adds a secure data section, and a __secure_data macro.
Patch 13 adds helper functions to save and get per-CPU target PC addresses for use in PSCI.
Patch 14 converts all PSCI-enabled platforms to the new helper functions to save/get target PC addresses.
Patch 15 makes the psci_get_cpu_stack_top function local/static. This function should only be used by the stack setup routine.
Regards ChenYu
Chen-Yu Tsai (15): ARM: PSCI: Split out common stack setup code from psci_arch_init sunxi: Move remaining PSCI assembly code to C sunxi: Add missing CONFIG_ARMV7_PSCI_NR_CPUS for sun7i ARM: Page align secure section only when it is executed in situ ARM: PSCI: Add fallback value for CONFIG_ARMV7_PSCI_NR_CPUS ARM: Add an empty secure stack section ARM: PSCI: Allocate PSCI stack in secure stack section ARM: PSCI: Remove unused psci_text_end symbol ARM: Add CONFIG_ARMV7_SECURE_MAX_SIZE and check size of secure section sunxi: Define CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i ARM: Move __secure definition to common asm/secure.h ARM: Add secure section for initialized data ARM: PSCI: Add helper functions to access per-CPU target PC storage ARM: PSCI: Switch to per-CPU target PC storage in secure data section ARM: PSCI: Make psci_get_cpu_stack_top local to armv7/psci.S
arch/arm/cpu/armv7/Makefile | 1 + arch/arm/cpu/armv7/ls102xa/psci.S | 26 ++++---------- arch/arm/cpu/armv7/mx7/psci-mx7.c | 2 +- arch/arm/cpu/armv7/mx7/psci.S | 31 +++++------------ arch/arm/cpu/armv7/nonsec_virt.S | 7 +++- arch/arm/cpu/armv7/psci-common.c | 39 +++++++++++++++++++++ arch/arm/cpu/armv7/psci.S | 55 ++++++++++++++++++++++-------- arch/arm/cpu/armv7/sunxi/Makefile | 1 - arch/arm/cpu/armv7/sunxi/psci.c | 9 +++-- arch/arm/cpu/armv7/sunxi/psci_head.S | 66 ------------------------------------ arch/arm/cpu/u-boot.lds | 60 +++++++++++++++++++++++++------- arch/arm/include/asm/armv7.h | 2 ++ arch/arm/include/asm/config.h | 5 +++ arch/arm/include/asm/psci.h | 9 ++++- arch/arm/include/asm/secure.h | 3 ++ arch/arm/lib/sections.c | 2 ++ arch/arm/mach-tegra/psci.S | 16 ++++----- include/configs/sun6i.h | 1 + include/configs/sun7i.h | 2 ++ 19 files changed, 183 insertions(+), 154 deletions(-) create mode 100644 arch/arm/cpu/armv7/psci-common.c delete mode 100644 arch/arm/cpu/armv7/sunxi/psci_head.S

Every platform has the same stack setup code in assembly as part of psci_arch_init.
Move this out into a common separate function, psci_stack_setup, for all platforms. This will allow us to move the remaining parts of psci_arch_init into C code, or drop it entirely.
Also provide a stub no-op psci_arch_init for platforms that don't need their own specific setup code.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- arch/arm/cpu/armv7/ls102xa/psci.S | 10 ---------- arch/arm/cpu/armv7/mx7/psci.S | 16 ---------------- arch/arm/cpu/armv7/nonsec_virt.S | 7 ++++++- arch/arm/cpu/armv7/psci.S | 18 ++++++++++++++++++ arch/arm/cpu/armv7/sunxi/psci_head.S | 16 +--------------- arch/arm/mach-tegra/psci.S | 3 --- 6 files changed, 25 insertions(+), 45 deletions(-)
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index cf5cd48bcbec..86116e1fcc65 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -111,16 +111,6 @@ psci_cpu_off: 1: wfi b 1b
-.globl psci_arch_init -psci_arch_init: - mov r6, lr - - bl psci_get_cpu_id - bl psci_get_cpu_stack_top - mov sp, r0 - - bx r6 - .globl psci_text_end psci_text_end: .popsection diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S index 34c6ab33f058..12cca7cc6deb 100644 --- a/arch/arm/cpu/armv7/mx7/psci.S +++ b/arch/arm/cpu/armv7/mx7/psci.S @@ -9,22 +9,6 @@
.arch_extension sec
- @ r1 = target CPU - @ r2 = target PC - -.globl psci_arch_init -psci_arch_init: - mov r6, lr - - bl psci_get_cpu_id - bl psci_get_cpu_stack_top - mov sp, r0 - - bx r6 - - @ r1 = target CPU - @ r2 = target PC - .globl psci_cpu_on psci_cpu_on: push {lr} diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S index b7563edbe6bc..95ce9387b83e 100644 --- a/arch/arm/cpu/armv7/nonsec_virt.S +++ b/arch/arm/cpu/armv7/nonsec_virt.S @@ -49,8 +49,13 @@ _secure_monitor: mcr p15, 0, r5, c12, c0, 1 isb
- @ Obtain a secure stack, and configure the PSCI backend + @ Obtain a secure stack + bl psci_stack_setup + + @ Configure the PSCI backend + push {r0, r1, r2, ip} bl psci_arch_init + pop {r0, r1, r2, ip} #endif
#ifdef CONFIG_ARM_ERRATA_773022 diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index ab408378fcae..46fcf770c214 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -211,6 +211,24 @@ ENTRY(psci_get_cpu_stack_top) bx lr ENDPROC(psci_get_cpu_stack_top)
+@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in +@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across +@ this function. +ENTRY(psci_stack_setup) + mov r6, lr + mov r7, r0 + bl psci_get_cpu_id @ CPU ID => r0 + bl psci_get_cpu_stack_top @ stack top => r0 + mov sp, r0 + mov r0, r7 + bx r6 +ENDPROC(psci_stack_setup) + +ENTRY(psci_arch_init) + mov pc, lr +ENDPROC(psci_arch_init) +.weak psci_arch_init + ENTRY(psci_cpu_entry) bl psci_enable_smp
diff --git a/arch/arm/cpu/armv7/sunxi/psci_head.S b/arch/arm/cpu/armv7/sunxi/psci_head.S index 8fa823d1df3a..e51db04cf1e2 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_head.S +++ b/arch/arm/cpu/armv7/sunxi/psci_head.S @@ -44,22 +44,8 @@ #define GICD_BASE (SUNXI_GIC400_BASE + 0x1000) #define GICC_BASE (SUNXI_GIC400_BASE + 0x2000)
-@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in -@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across -@ this function. ENTRY(psci_arch_init) - mov r6, lr - mov r7, r0 - bl psci_get_cpu_id @ CPU ID => r0 - bl psci_get_cpu_stack_top @ stack top => r0 - sub r0, r0, #4 @ Save space for target PC - mov sp, r0 - mov r0, r7 - mov lr, r6 - - push {r0, r1, r2, ip, lr} - bl sunxi_gic_init - pop {r0, r1, r2, ip, pc} + b sunxi_gic_init ENDPROC(psci_arch_init)
ENTRY(psci_text_end) diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S index b836da1c0ed7..75068f34c052 100644 --- a/arch/arm/mach-tegra/psci.S +++ b/arch/arm/mach-tegra/psci.S @@ -61,9 +61,6 @@ ENTRY(psci_arch_init) ldrne r7, [r5] mcrne p15, 0, r7, c14, c0, 0 @ write CNTFRQ to CPU1..3
- bl psci_get_cpu_stack_top @ stack top => r0 - mov sp, r0 - bx r6 ENDPROC(psci_arch_init)

Tested-by: Hongbo Zhang hongbo.zhang@nxp.com
On Sun, Jun 19, 2016 at 12:38 PM, Chen-Yu Tsai wens@csie.org wrote:
Every platform has the same stack setup code in assembly as part of psci_arch_init.
Move this out into a common separate function, psci_stack_setup, for all platforms. This will allow us to move the remaining parts of psci_arch_init into C code, or drop it entirely.
Also provide a stub no-op psci_arch_init for platforms that don't need their own specific setup code.
Signed-off-by: Chen-Yu Tsai wens@csie.org
arch/arm/cpu/armv7/ls102xa/psci.S | 10 ---------- arch/arm/cpu/armv7/mx7/psci.S | 16 ---------------- arch/arm/cpu/armv7/nonsec_virt.S | 7 ++++++- arch/arm/cpu/armv7/psci.S | 18 ++++++++++++++++++ arch/arm/cpu/armv7/sunxi/psci_head.S | 16 +--------------- arch/arm/mach-tegra/psci.S | 3 --- 6 files changed, 25 insertions(+), 45 deletions(-)
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index cf5cd48bcbec..86116e1fcc65 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -111,16 +111,6 @@ psci_cpu_off: 1: wfi b 1b
-.globl psci_arch_init -psci_arch_init:
mov r6, lr
bl psci_get_cpu_id
bl psci_get_cpu_stack_top
mov sp, r0
bx r6
.globl psci_text_end
psci_text_end: .popsection diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S index 34c6ab33f058..12cca7cc6deb 100644 --- a/arch/arm/cpu/armv7/mx7/psci.S +++ b/arch/arm/cpu/armv7/mx7/psci.S @@ -9,22 +9,6 @@
.arch_extension sec
@ r1 = target CPU
@ r2 = target PC
-.globl psci_arch_init -psci_arch_init:
mov r6, lr
bl psci_get_cpu_id
bl psci_get_cpu_stack_top
mov sp, r0
bx r6
@ r1 = target CPU
@ r2 = target PC
.globl psci_cpu_on psci_cpu_on: push {lr} diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S index b7563edbe6bc..95ce9387b83e 100644 --- a/arch/arm/cpu/armv7/nonsec_virt.S +++ b/arch/arm/cpu/armv7/nonsec_virt.S @@ -49,8 +49,13 @@ _secure_monitor: mcr p15, 0, r5, c12, c0, 1 isb
@ Obtain a secure stack, and configure the PSCI backend
@ Obtain a secure stack
bl psci_stack_setup
@ Configure the PSCI backend
push {r0, r1, r2, ip} bl psci_arch_init
pop {r0, r1, r2, ip}
#endif
#ifdef CONFIG_ARM_ERRATA_773022 diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index ab408378fcae..46fcf770c214 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -211,6 +211,24 @@ ENTRY(psci_get_cpu_stack_top) bx lr ENDPROC(psci_get_cpu_stack_top)
+@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in +@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across +@ this function. +ENTRY(psci_stack_setup)
mov r6, lr
mov r7, r0
bl psci_get_cpu_id @ CPU ID => r0
bl psci_get_cpu_stack_top @ stack top => r0
mov sp, r0
mov r0, r7
bx r6
+ENDPROC(psci_stack_setup)
+ENTRY(psci_arch_init)
mov pc, lr
+ENDPROC(psci_arch_init) +.weak psci_arch_init
ENTRY(psci_cpu_entry) bl psci_enable_smp
diff --git a/arch/arm/cpu/armv7/sunxi/psci_head.S b/arch/arm/cpu/armv7/sunxi/psci_head.S index 8fa823d1df3a..e51db04cf1e2 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_head.S +++ b/arch/arm/cpu/armv7/sunxi/psci_head.S @@ -44,22 +44,8 @@ #define GICD_BASE (SUNXI_GIC400_BASE + 0x1000) #define GICC_BASE (SUNXI_GIC400_BASE + 0x2000)
-@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in -@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across -@ this function. ENTRY(psci_arch_init)
mov r6, lr
mov r7, r0
bl psci_get_cpu_id @ CPU ID => r0
bl psci_get_cpu_stack_top @ stack top => r0
sub r0, r0, #4 @ Save space for target PC
mov sp, r0
mov r0, r7
mov lr, r6
push {r0, r1, r2, ip, lr}
bl sunxi_gic_init
pop {r0, r1, r2, ip, pc}
b sunxi_gic_init
ENDPROC(psci_arch_init)
ENTRY(psci_text_end) diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S index b836da1c0ed7..75068f34c052 100644 --- a/arch/arm/mach-tegra/psci.S +++ b/arch/arm/mach-tegra/psci.S @@ -61,9 +61,6 @@ ENTRY(psci_arch_init) ldrne r7, [r5] mcrne p15, 0, r7, c14, c0, 0 @ write CNTFRQ to CPU1..3
bl psci_get_cpu_stack_top @ stack top => r0
mov sp, r0
bx r6
ENDPROC(psci_arch_init)
-- 2.8.1

This patch finishes the rewrite of sunxi specific PSCI parts into C code.
The assembly-only stack setup code has been factored out into a common function for ARMv7. The GIC setup code can be renamed as psci_arch_init. And we can use an empty stub function for psci_text_end.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- arch/arm/cpu/armv7/sunxi/Makefile | 1 - arch/arm/cpu/armv7/sunxi/psci.c | 7 ++++- arch/arm/cpu/armv7/sunxi/psci_head.S | 52 ------------------------------------ 3 files changed, 6 insertions(+), 54 deletions(-) delete mode 100644 arch/arm/cpu/armv7/sunxi/psci_head.S
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index c2085101685b..b35b9df4a9d6 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -14,7 +14,6 @@ obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o
ifndef CONFIG_SPL_BUILD obj-$(CONFIG_ARMV7_PSCI) += psci.o -obj-$(CONFIG_ARMV7_PSCI) += psci_head.o endif
ifdef CONFIG_SPL_BUILD diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c index 0059f4cbc9d6..ad3e0380c8ca 100644 --- a/arch/arm/cpu/armv7/sunxi/psci.c +++ b/arch/arm/cpu/armv7/sunxi/psci.c @@ -250,7 +250,7 @@ void __secure psci_cpu_off(void) wfi(); }
-void __secure sunxi_gic_init(void) +void __secure psci_arch_init(void) { u32 reg;
@@ -271,3 +271,8 @@ void __secure sunxi_gic_init(void) reg &= ~BIT(0); /* Secure mode */ cp15_write_scr(reg); } + +/* dummy entry for end of psci text */ +void __secure psci_text_end(void) +{ +} diff --git a/arch/arm/cpu/armv7/sunxi/psci_head.S b/arch/arm/cpu/armv7/sunxi/psci_head.S deleted file mode 100644 index e51db04cf1e2..000000000000 --- a/arch/arm/cpu/armv7/sunxi/psci_head.S +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2013 - ARM Ltd - * Author: Marc Zyngier marc.zyngier@arm.com - * - * Based on code by Carl van Schaik carl@ok-labs.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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - */ - -#include <config.h> -#include <linux/linkage.h> - -#include <asm/arch-armv7/generictimer.h> -#include <asm/gic.h> -#include <asm/macro.h> -#include <asm/psci.h> -#include <asm/arch/cpu.h> - -/* - * Memory layout: - * - * SECURE_RAM to text_end : - * ._secure_text section - * text_end to ALIGN_PAGE(text_end): - * nothing - * ALIGN_PAGE(text_end) to ALIGN_PAGE(text_end) + 0x1000) - * 1kB of stack per CPU (4 CPUs max). - */ - - .pushsection ._secure.text, "ax" - - .arch_extension sec - -#define GICD_BASE (SUNXI_GIC400_BASE + 0x1000) -#define GICC_BASE (SUNXI_GIC400_BASE + 0x2000) - -ENTRY(psci_arch_init) - b sunxi_gic_init -ENDPROC(psci_arch_init) - -ENTRY(psci_text_end) - .popsection

sun7i has 2 CPUs.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- include/configs/sun7i.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h index 0dd29029b9b3..1c89fdf0d356 100644 --- a/include/configs/sun7i.h +++ b/include/configs/sun7i.h @@ -21,6 +21,7 @@ #define CONFIG_SUNXI_USB_PHYS 3
#define CONFIG_ARMV7_PSCI 1 +#define CONFIG_ARMV7_PSCI_NR_CPUS 2 #define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE
/*

Targets that define CONFIG_ARMV7_SECURE_BASE will copy the secure section to another address before execution.
Since the secure section in the u-boot image is only storage, there's no reason to page align it and increase the binary image size.
Page align the secure section only when CONFIG_ARMV7_SECURE_BASE is not defined. And instead of just aligning the __secure_start symbol, align the whole .__secure_start section. This also makes the section empty, so we need to add KEEP() to the input entry to prevent the section from being garbage collected.
Also use ld constant "COMMONPAGESIZE" instead of hardcoded page size.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- arch/arm/cpu/u-boot.lds | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index 1769b6ea881b..ba177787d23c 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -48,16 +48,20 @@ SECTIONS
#ifdef CONFIG_ARMV7_NONSEC
+ /* Align the secure section only if we're going to use it in situ */ + .__secure_start : +#ifndef CONFIG_ARMV7_SECURE_BASE + ALIGN(CONSTANT(COMMONPAGESIZE)) +#endif + { + KEEP(*(.__secure_start)) + } + #ifndef CONFIG_ARMV7_SECURE_BASE #define CONFIG_ARMV7_SECURE_BASE #define __ARMV7_PSCI_STACK_IN_RAM #endif
- .__secure_start : { - . = ALIGN(0x1000); - *(.__secure_start) - } - .secure_text CONFIG_ARMV7_SECURE_BASE : AT(ADDR(.__secure_start) + SIZEOF(.__secure_start)) {

The original PSCI implementation assumed CONFIG_ARMV7_PSCI_NR_CPUS=4. Add this as a fallback value in case platforms have not defined it.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- arch/arm/include/asm/config.h | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index 435fc4521c2e..f70302dfc4f1 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -23,4 +23,9 @@ #include <asm/arch/config.h> #endif
+/* Original code assumed 4 CPUs */ +#ifndef CONFIG_ARMV7_PSCI_NR_CPUS +#define CONFIG_ARMV7_PSCI_NR_CPUS 4 +#endif + #endif

On Sun, Jun 19, 2016 at 12:38 PM, Chen-Yu Tsai wens@csie.org wrote:
The original PSCI implementation assumed CONFIG_ARMV7_PSCI_NR_CPUS=4. Add this as a fallback value in case platforms have not defined it.
Signed-off-by: Chen-Yu Tsai wens@csie.org
arch/arm/include/asm/config.h | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index 435fc4521c2e..f70302dfc4f1 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -23,4 +23,9 @@ #include <asm/arch/config.h> #endif
+/* Original code assumed 4 CPUs */ +#ifndef CONFIG_ARMV7_PSCI_NR_CPUS +#define CONFIG_ARMV7_PSCI_NR_CPUS 4
This makes platforms which have there own macro definition embarrassed somehow. we should add #define CONFIG_ARMV7_PSCI_NR_CPUS CONFIG_MAX_CPUS if this patch merged. some of our platform even has 16 cores.
+#endif
#endif
2.8.1

On Fri, Jul 1, 2016 at 6:39 PM, Hongbo Zhang macro.wave.z@gmail.com wrote:
On Sun, Jun 19, 2016 at 12:38 PM, Chen-Yu Tsai wens@csie.org wrote:
The original PSCI implementation assumed CONFIG_ARMV7_PSCI_NR_CPUS=4. Add this as a fallback value in case platforms have not defined it.
Signed-off-by: Chen-Yu Tsai wens@csie.org
arch/arm/include/asm/config.h | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index 435fc4521c2e..f70302dfc4f1 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -23,4 +23,9 @@ #include <asm/arch/config.h> #endif
+/* Original code assumed 4 CPUs */ +#ifndef CONFIG_ARMV7_PSCI_NR_CPUS +#define CONFIG_ARMV7_PSCI_NR_CPUS 4
This makes platforms which have there own macro definition embarrassed somehow. we should add #define CONFIG_ARMV7_PSCI_NR_CPUS CONFIG_MAX_CPUS if this patch merged. some of our platform even has 16 cores.
I'm not sure how CONFIG_MAX_CPUS is used though.
Thinking about this, my first approach is probably wrong. I should add missing PSCI_NR_CPUS for the existing platforms. New platforms should define it themselves when enabling PSCI. Failure to do so will result in a compile error, rather than having a fallback value that subtly breaks later on.
Regards ChenYu
+#endif
#endif
2.8.1

On Sat, Jul 2, 2016 at 5:17 PM, Chen-Yu Tsai wens@csie.org wrote:
On Fri, Jul 1, 2016 at 6:39 PM, Hongbo Zhang macro.wave.z@gmail.com wrote:
On Sun, Jun 19, 2016 at 12:38 PM, Chen-Yu Tsai wens@csie.org wrote:
The original PSCI implementation assumed CONFIG_ARMV7_PSCI_NR_CPUS=4. Add this as a fallback value in case platforms have not defined it.
Signed-off-by: Chen-Yu Tsai wens@csie.org
arch/arm/include/asm/config.h | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index 435fc4521c2e..f70302dfc4f1 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -23,4 +23,9 @@ #include <asm/arch/config.h> #endif
+/* Original code assumed 4 CPUs */ +#ifndef CONFIG_ARMV7_PSCI_NR_CPUS +#define CONFIG_ARMV7_PSCI_NR_CPUS 4
This makes platforms which have there own macro definition embarrassed somehow. we should add #define CONFIG_ARMV7_PSCI_NR_CPUS CONFIG_MAX_CPUS if this patch merged. some of our platform even has 16 cores.
I'm not sure how CONFIG_MAX_CPUS is used though.
Thinking about this, my first approach is probably wrong. I should add missing PSCI_NR_CPUS for the existing platforms. New platforms should define it themselves when enabling PSCI.
Yes, this is better.
Failure to do so will result in a compile error, rather than having a fallback value that subtly breaks later on.
Regards ChenYu
+#endif
#endif
2.8.1

Until now we've been using memory beyond psci_text_end as stack space for the secure monitor or PSCI implementation, even if space was not allocated for it.
This was partially fixed in ("ARM: allocate extra space for PSCI stack in secure section during link phase"). However, calculating stack space from psci_text_end in one place, while allocating the space in another is error prone.
This patch adds a separate empty secure stack section, with space for CONFIG_ARMV7_PSCI_NR_CPUS stacks, each 1 KB. There's also __secure_stack_start and __secure_stack_end symbols. The linker script handles calculating the correct VMAs for the stack section. For platforms that relocate/copy the secure monitor before using it, the space is not allocated in the executable, saving space.
For platforms that do not define CONFIG_ARMV7_PSCI_NR_CPUS, a whole page of stack space for 4 CPUs is allocated, matching the previous behavior.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- arch/arm/cpu/u-boot.lds | 32 +++++++++++++++++++++++--------- arch/arm/include/asm/armv7.h | 2 ++ arch/arm/include/asm/psci.h | 4 ++++ arch/arm/lib/sections.c | 2 ++ 4 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index ba177787d23c..002706ae635d 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -8,6 +8,7 @@ */
#include <config.h> +#include <asm/psci.h>
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) @@ -68,18 +69,31 @@ SECTIONS *(._secure.text) }
- . = LOADADDR(.__secure_start) + - SIZEOF(.__secure_start) + - SIZEOF(.secure_text); - + .secure_stack ALIGN(ADDR(.secure_text) + SIZEOF(.secure_text), + CONSTANT(COMMONPAGESIZE)) (NOLOAD) : #ifdef __ARMV7_PSCI_STACK_IN_RAM - /* Align to page boundary and skip 2 pages */ - . = (. & ~ 0xfff) + 0x2000; -#undef __ARMV7_PSCI_STACK_IN_RAM + AT(ADDR(.secure_stack)) +#else + AT(LOADADDR(.secure_text) + SIZEOF(.secure_text)) +#endif + { + KEEP(*(.__secure_stack_start)) + + /* Skip addreses for stack */ + . = . + CONFIG_ARMV7_PSCI_NR_CPUS * ARM_PSCI_STACK_SIZE; + + /* Align end of stack section to page boundary */ + . = ALIGN(CONSTANT(COMMONPAGESIZE)); + + KEEP(*(.__secure_stack_end)) + } + +#ifndef __ARMV7_PSCI_STACK_IN_RAM + /* Reset VMA but don't allocate space if we have secure SRAM */ + . = LOADADDR(.secure_stack); #endif
- __secure_end_lma = .; - .__secure_end : AT(__secure_end_lma) { + .__secure_end : AT(ADDR(.__secure_end)) { *(.__secure_end) LONG(0x1d1071c); /* Must output something to reset LMA */ } diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h index 423fc7011166..a20702e612b1 100644 --- a/arch/arm/include/asm/armv7.h +++ b/arch/arm/include/asm/armv7.h @@ -126,6 +126,8 @@ void _smp_pen(void);
extern char __secure_start[]; extern char __secure_end[]; +extern char __secure_stack_start[]; +extern char __secure_stack_end[];
#endif /* CONFIG_ARMV7_NONSEC */
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index bc5edda73f00..dab576997654 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -47,6 +47,10 @@ #define ARM_PSCI_0_2_FN_SYSTEM_OFF ARM_PSCI_0_2_FN(8) #define ARM_PSCI_0_2_FN_SYSTEM_RESET ARM_PSCI_0_2_FN(9)
+/* 1KB stack per core */ +#define ARM_PSCI_STACK_SHIFT 10 +#define ARM_PSCI_STACK_SIZE (1 << ARM_PSCI_STACK_SHIFT) + #ifndef __ASSEMBLY__ #include <asm/types.h>
diff --git a/arch/arm/lib/sections.c b/arch/arm/lib/sections.c index 6a9452241834..952e8ae49bf4 100644 --- a/arch/arm/lib/sections.c +++ b/arch/arm/lib/sections.c @@ -27,6 +27,8 @@ char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start"))); char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end"))); char __secure_start[0] __attribute__((section(".__secure_start"))); char __secure_end[0] __attribute__((section(".__secure_end"))); +char __secure_stack_start[0] __attribute__((section(".__secure_stack_start"))); +char __secure_stack_end[0] __attribute__((section(".__secure_stack_end"))); char __efi_runtime_start[0] __attribute__((section(".__efi_runtime_start"))); char __efi_runtime_stop[0] __attribute__((section(".__efi_runtime_stop"))); char __efi_runtime_rel_start[0] __attribute__((section(".__efi_runtime_rel_start")));

Now that we have a secure stack section that guarantees usable memory, allocate the PSCI stacks in that section.
Also add a diagram detailing how the stacks are placed in memory.
Reserved space for the target PC remains unchanged. This should be moved to global variables within a secure data section in the future.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- arch/arm/cpu/armv7/psci.S | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index 46fcf770c214..bfc4475e360c 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -196,18 +196,28 @@ ENTRY(psci_cpu_off_common) bx lr ENDPROC(psci_cpu_off_common)
-@ expects CPU ID in r0 and returns stack top in r0 +@ The stacks are allocated in reverse order, i.e. +@ the stack for CPU0 has the highest memory address. +@ +@ -------------------- __secure_stack_end +@ | CPU0 target PC | +@ |------------------| +@ | | +@ | CPU0 stack | +@ | | +@ |------------------| __secure_stack_end - 1KB +@ | . | +@ | . | +@ | . | +@ | . | +@ -------------------- __secure_stack_start +@ +@ This expects CPU ID in r0 and returns stack top in r0 ENTRY(psci_get_cpu_stack_top) - mov r3, #0x400 @ 1kB of stack per CPU - mul r0, r0, r3 - - ldr r3, =psci_text_end @ end of monitor text - add r3, r3, #0x2000 @ Skip two pages - lsr r3, r3, #12 @ Align to start of page - lsl r3, r3, #12 - sub r3, r3, #4 @ reserve 1 word for target PC - sub r0, r3, r0 @ here's our stack! - + @ stack top = __secure_stack_end - (cpuid << ARM_PSCI_STACK_SHIFT) + ldr r3, =__secure_stack_end + sub r0, r3, r0, LSL #ARM_PSCI_STACK_SHIFT + sub r0, r0, #4 @ Save space for target PC bx lr ENDPROC(psci_get_cpu_stack_top)

Tested-by: Hongbo Zhang hongbo.zhang@nxp.com
On Sun, Jun 19, 2016 at 12:38 PM, Chen-Yu Tsai wens@csie.org wrote:
Now that we have a secure stack section that guarantees usable memory, allocate the PSCI stacks in that section.
Also add a diagram detailing how the stacks are placed in memory.
Reserved space for the target PC remains unchanged. This should be moved to global variables within a secure data section in the future.
Signed-off-by: Chen-Yu Tsai wens@csie.org
arch/arm/cpu/armv7/psci.S | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index 46fcf770c214..bfc4475e360c 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -196,18 +196,28 @@ ENTRY(psci_cpu_off_common) bx lr ENDPROC(psci_cpu_off_common)
-@ expects CPU ID in r0 and returns stack top in r0 +@ The stacks are allocated in reverse order, i.e. +@ the stack for CPU0 has the highest memory address. +@ +@ -------------------- __secure_stack_end +@ | CPU0 target PC | +@ |------------------| +@ | | +@ | CPU0 stack | +@ | | +@ |------------------| __secure_stack_end - 1KB +@ | . | +@ | . | +@ | . | +@ | . | +@ -------------------- __secure_stack_start +@ +@ This expects CPU ID in r0 and returns stack top in r0 ENTRY(psci_get_cpu_stack_top)
mov r3, #0x400 @ 1kB of stack per CPU
mul r0, r0, r3
ldr r3, =psci_text_end @ end of monitor text
add r3, r3, #0x2000 @ Skip two pages
lsr r3, r3, #12 @ Align to start of page
lsl r3, r3, #12
sub r3, r3, #4 @ reserve 1 word for target PC
sub r0, r3, r0 @ here's our stack!
@ stack top = __secure_stack_end - (cpuid << ARM_PSCI_STACK_SHIFT)
ldr r3, =__secure_stack_end
sub r0, r3, r0, LSL #ARM_PSCI_STACK_SHIFT
sub r0, r0, #4 @ Save space for target PC bx lr
ENDPROC(psci_get_cpu_stack_top)
-- 2.8.1

psci_text_end was used to calculate the PSCI stack address following the secure monitor text. Now that we have an explicit secure stack section, this is no longer used.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- arch/arm/cpu/armv7/ls102xa/psci.S | 2 -- arch/arm/cpu/armv7/mx7/psci.S | 2 -- arch/arm/cpu/armv7/sunxi/psci.c | 5 ----- arch/arm/mach-tegra/psci.S | 2 -- 4 files changed, 11 deletions(-)
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 86116e1fcc65..ba043efed021 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -111,6 +111,4 @@ psci_cpu_off: 1: wfi b 1b
- .globl psci_text_end -psci_text_end: .popsection diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S index 12cca7cc6deb..d9e9fbfb9ebd 100644 --- a/arch/arm/cpu/armv7/mx7/psci.S +++ b/arch/arm/cpu/armv7/mx7/psci.S @@ -33,6 +33,4 @@ psci_cpu_off: 1: wfi b 1b
- .globl psci_text_end -psci_text_end: .popsection diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c index ad3e0380c8ca..b54f3631ecb2 100644 --- a/arch/arm/cpu/armv7/sunxi/psci.c +++ b/arch/arm/cpu/armv7/sunxi/psci.c @@ -271,8 +271,3 @@ void __secure psci_arch_init(void) reg &= ~BIT(0); /* Secure mode */ cp15_write_scr(reg); } - -/* dummy entry for end of psci text */ -void __secure psci_text_end(void) -{ -} diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S index 75068f34c052..85d5b6b59de4 100644 --- a/arch/arm/mach-tegra/psci.S +++ b/arch/arm/mach-tegra/psci.S @@ -106,6 +106,4 @@ ENTRY(psci_cpu_on) pop {pc} ENDPROC(psci_cpu_on)
- .globl psci_text_end -psci_text_end: .popsection

As the PSCI implementation grows, we might exceed the size of the secure memory that holds the firmware.
Add a configurable CONFIG_ARMV7_SECURE_MAX_SIZE so platforms can define how much secure memory is available. The linker then checks the size of the whole secure section against this.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- arch/arm/cpu/u-boot.lds | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index 002706ae635d..5a65c27cfa74 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -86,6 +86,17 @@ SECTIONS . = ALIGN(CONSTANT(COMMONPAGESIZE));
KEEP(*(.__secure_stack_end)) + +#ifdef CONFIG_ARMV7_SECURE_MAX_SIZE + /* + * We are not checking (__secure_end - __secure_start) here, + * as these are the load addresses, and do not include the + * stack section. Instead, use the end of the stack section + * and the start of the text section. + */ + ASSERT((. - ADDR(.secure_text)) <= CONFIG_ARMV7_SECURE_MAX_SIZE, + "Error: secure section exceeds secure memory size"); +#endif }
#ifndef __ARMV7_PSCI_STACK_IN_RAM

Both sun6i and sun7i have 64 KB of secure SRAM.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- include/configs/sun6i.h | 1 + include/configs/sun7i.h | 1 + 2 files changed, 2 insertions(+)
diff --git a/include/configs/sun6i.h b/include/configs/sun6i.h index 95ccc35708a7..0625502f44b4 100644 --- a/include/configs/sun6i.h +++ b/include/configs/sun6i.h @@ -25,6 +25,7 @@ #define CONFIG_ARMV7_PSCI 1 #define CONFIG_ARMV7_PSCI_NR_CPUS 4 #define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE +#define CONFIG_ARMV7_SECURE_MAX_SIZE (64 * 1024) /* 64 KB */
/* * Include common sunxi configuration where most the settings are diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h index 1c89fdf0d356..e9074d5dfbf9 100644 --- a/include/configs/sun7i.h +++ b/include/configs/sun7i.h @@ -23,6 +23,7 @@ #define CONFIG_ARMV7_PSCI 1 #define CONFIG_ARMV7_PSCI_NR_CPUS 2 #define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE +#define CONFIG_ARMV7_SECURE_MAX_SIZE (64 * 1024) /* 64 KB */
/* * Include common sunxi configuration where most the settings are

sunxi and i.mx7 both define the __secure modifier to put functions in the secure section. Move this to a common place.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- arch/arm/cpu/armv7/mx7/psci-mx7.c | 2 +- arch/arm/cpu/armv7/sunxi/psci.c | 2 +- arch/arm/include/asm/secure.h | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv7/mx7/psci-mx7.c b/arch/arm/cpu/armv7/mx7/psci-mx7.c index 9a330476cf5f..502552d1718f 100644 --- a/arch/arm/cpu/armv7/mx7/psci-mx7.c +++ b/arch/arm/cpu/armv7/mx7/psci-mx7.c @@ -1,9 +1,9 @@ #include <asm/io.h> #include <asm/psci.h> +#include <asm/secure.h> #include <asm/arch/imx-regs.h> #include <common.h>
-#define __secure __attribute__((section("._secure.text")))
#define GPC_CPU_PGC_SW_PDN_REQ 0xfc #define GPC_CPU_PGC_SW_PUP_REQ 0xf0 diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c index b54f3631ecb2..55fa0e73444e 100644 --- a/arch/arm/cpu/armv7/sunxi/psci.c +++ b/arch/arm/cpu/armv7/sunxi/psci.c @@ -17,11 +17,11 @@ #include <asm/gic.h> #include <asm/io.h> #include <asm/psci.h> +#include <asm/secure.h> #include <asm/system.h>
#include <linux/bitops.h>
-#define __secure __attribute__ ((section ("._secure.text"))) #define __irq __attribute__ ((interrupt ("IRQ")))
#define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET) diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h index effdb1858d88..6d9088beb4d2 100644 --- a/arch/arm/include/asm/secure.h +++ b/arch/arm/include/asm/secure.h @@ -3,6 +3,8 @@
#include <config.h>
+#define __secure __attribute__ ((section ("._secure.text"))) + #ifdef CONFIG_ARMV7_SECURE_BASE /* * Warning, horror ahead.

The secure monitor may need to store global or static values within the secure section of memory, such as target PC or CPU power status.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- arch/arm/cpu/u-boot.lds | 9 +++++++-- arch/arm/include/asm/secure.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index 5a65c27cfa74..36c9fd0bd01f 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -69,12 +69,17 @@ SECTIONS *(._secure.text) }
- .secure_stack ALIGN(ADDR(.secure_text) + SIZEOF(.secure_text), + .secure_data : AT(LOADADDR(.secure_text) + SIZEOF(.secure_text)) + { + *(._secure.data) + } + + .secure_stack ALIGN(ADDR(.secure_data) + SIZEOF(.secure_data), CONSTANT(COMMONPAGESIZE)) (NOLOAD) : #ifdef __ARMV7_PSCI_STACK_IN_RAM AT(ADDR(.secure_stack)) #else - AT(LOADADDR(.secure_text) + SIZEOF(.secure_text)) + AT(LOADADDR(.secure_data) + SIZEOF(.secure_data)) #endif { KEEP(*(.__secure_stack_start)) diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h index 6d9088beb4d2..5a403bc0f153 100644 --- a/arch/arm/include/asm/secure.h +++ b/arch/arm/include/asm/secure.h @@ -4,6 +4,7 @@ #include <config.h>
#define __secure __attribute__ ((section ("._secure.text"))) +#define __secure_data __attribute__ ((section ("._secure.data")))
#ifdef CONFIG_ARMV7_SECURE_BASE /*

Now that we have a data section, add helper functions to save and fetch per-CPU target PC.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- arch/arm/cpu/armv7/Makefile | 1 + arch/arm/cpu/armv7/psci-common.c | 39 +++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/psci.h | 4 ++++ 3 files changed, 44 insertions(+) create mode 100644 arch/arm/cpu/armv7/psci-common.c
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 328c4b10e976..730b59986a01 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -26,6 +26,7 @@ endif
ifneq ($(CONFIG_ARMV7_PSCI),) obj-y += psci.o +obj-y += psci-common.o endif
obj-$(CONFIG_IPROC) += iproc-common/ diff --git a/arch/arm/cpu/armv7/psci-common.c b/arch/arm/cpu/armv7/psci-common.c new file mode 100644 index 000000000000..d14b6937473f --- /dev/null +++ b/arch/arm/cpu/armv7/psci-common.c @@ -0,0 +1,39 @@ +/* + * Common PSCI functions + * + * Copyright (C) 2016 Chen-Yu Tsai + * Author: Chen-Yu Tsai wens@csie.org + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include <config.h> +#include <asm/armv7.h> +#include <asm/macro.h> +#include <asm/psci.h> +#include <asm/secure.h> +#include <linux/linkage.h> + +static u32 psci_target_pc[CONFIG_ARMV7_PSCI_NR_CPUS] __secure_data = { 0 }; + +void __secure psci_save_target_pc(int cpu, u32 pc) +{ + psci_target_pc[cpu] = pc; + DSB; +} + +u32 __secure psci_get_target_pc(int cpu) +{ + return psci_target_pc[cpu]; +} + diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index dab576997654..a0da02300700 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -54,6 +54,10 @@ #ifndef __ASSEMBLY__ #include <asm/types.h>
+/* These 2 helper functions assume cpu < CONFIG_ARMV7_PSCI_NR_CPUS */ +u32 psci_get_target_pc(int cpu); +void psci_save_target_pc(int cpu, u32 pc); + void psci_cpu_entry(void); u32 psci_get_cpu_id(void); u32 psci_get_cpu_stack_top(int cpu);

On Sun, Jun 19, 2016 at 12:38 PM, Chen-Yu Tsai wens@csie.org wrote:
Now that we have a data section, add helper functions to save and fetch per-CPU target PC.
Signed-off-by: Chen-Yu Tsai wens@csie.org
arch/arm/cpu/armv7/Makefile | 1 + arch/arm/cpu/armv7/psci-common.c | 39 +++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/psci.h | 4 ++++ 3 files changed, 44 insertions(+) create mode 100644 arch/arm/cpu/armv7/psci-common.c
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 328c4b10e976..730b59986a01 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -26,6 +26,7 @@ endif
ifneq ($(CONFIG_ARMV7_PSCI),) obj-y += psci.o +obj-y += psci-common.o
The Makefile was updated, this patch doen't apply today, but only a minor change is needed.
endif
obj-$(CONFIG_IPROC) += iproc-common/ diff --git a/arch/arm/cpu/armv7/psci-common.c b/arch/arm/cpu/armv7/psci-common.c new file mode 100644 index 000000000000..d14b6937473f --- /dev/null +++ b/arch/arm/cpu/armv7/psci-common.c @@ -0,0 +1,39 @@ +/*
- Common PSCI functions
- Copyright (C) 2016 Chen-Yu Tsai
- Author: Chen-Yu Tsai wens@csie.org
- 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.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see http://www.gnu.org/licenses/.
- */
+#include <config.h> +#include <asm/armv7.h> +#include <asm/macro.h> +#include <asm/psci.h> +#include <asm/secure.h> +#include <linux/linkage.h>
+static u32 psci_target_pc[CONFIG_ARMV7_PSCI_NR_CPUS] __secure_data = { 0 };
+void __secure psci_save_target_pc(int cpu, u32 pc) +{
psci_target_pc[cpu] = pc;
DSB;
+}
+u32 __secure psci_get_target_pc(int cpu) +{
return psci_target_pc[cpu];
+}
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index dab576997654..a0da02300700 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -54,6 +54,10 @@ #ifndef __ASSEMBLY__ #include <asm/types.h>
+/* These 2 helper functions assume cpu < CONFIG_ARMV7_PSCI_NR_CPUS */ +u32 psci_get_target_pc(int cpu); +void psci_save_target_pc(int cpu, u32 pc);
void psci_cpu_entry(void); u32 psci_get_cpu_id(void); u32 psci_get_cpu_stack_top(int cpu); -- 2.8.1

On Fri, Jul 1, 2016 at 6:19 PM, Hongbo Zhang macro.wave.z@gmail.com wrote:
On Sun, Jun 19, 2016 at 12:38 PM, Chen-Yu Tsai wens@csie.org wrote:
Now that we have a data section, add helper functions to save and fetch per-CPU target PC.
Signed-off-by: Chen-Yu Tsai wens@csie.org
arch/arm/cpu/armv7/Makefile | 1 + arch/arm/cpu/armv7/psci-common.c | 39 +++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/psci.h | 4 ++++ 3 files changed, 44 insertions(+) create mode 100644 arch/arm/cpu/armv7/psci-common.c
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 328c4b10e976..730b59986a01 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -26,6 +26,7 @@ endif
ifneq ($(CONFIG_ARMV7_PSCI),) obj-y += psci.o +obj-y += psci-common.o
The Makefile was updated, this patch doen't apply today, but only a minor change is needed.
I'm aware of the change. I might post a new version after 2016.07 is released.
Thanks ChenYu
endif
obj-$(CONFIG_IPROC) += iproc-common/ diff --git a/arch/arm/cpu/armv7/psci-common.c b/arch/arm/cpu/armv7/psci-common.c new file mode 100644 index 000000000000..d14b6937473f --- /dev/null +++ b/arch/arm/cpu/armv7/psci-common.c @@ -0,0 +1,39 @@ +/*
- Common PSCI functions
- Copyright (C) 2016 Chen-Yu Tsai
- Author: Chen-Yu Tsai wens@csie.org
- 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.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see http://www.gnu.org/licenses/.
- */
+#include <config.h> +#include <asm/armv7.h> +#include <asm/macro.h> +#include <asm/psci.h> +#include <asm/secure.h> +#include <linux/linkage.h>
+static u32 psci_target_pc[CONFIG_ARMV7_PSCI_NR_CPUS] __secure_data = { 0 };
+void __secure psci_save_target_pc(int cpu, u32 pc) +{
psci_target_pc[cpu] = pc;
DSB;
+}
+u32 __secure psci_get_target_pc(int cpu) +{
return psci_target_pc[cpu];
+}
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index dab576997654..a0da02300700 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -54,6 +54,10 @@ #ifndef __ASSEMBLY__ #include <asm/types.h>
+/* These 2 helper functions assume cpu < CONFIG_ARMV7_PSCI_NR_CPUS */ +u32 psci_get_target_pc(int cpu); +void psci_save_target_pc(int cpu, u32 pc);
void psci_cpu_entry(void); u32 psci_get_cpu_id(void); u32 psci_get_cpu_stack_top(int cpu); -- 2.8.1

On Sun, Jun 19, 2016 at 12:38 PM, Chen-Yu Tsai wens@csie.org wrote:
Now that we have a data section, add helper functions to save and fetch per-CPU target PC.
Signed-off-by: Chen-Yu Tsai wens@csie.org
arch/arm/cpu/armv7/Makefile | 1 + arch/arm/cpu/armv7/psci-common.c | 39 +++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/psci.h | 4 ++++ 3 files changed, 44 insertions(+) create mode 100644 arch/arm/cpu/armv7/psci-common.c
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 328c4b10e976..730b59986a01 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -26,6 +26,7 @@ endif
ifneq ($(CONFIG_ARMV7_PSCI),) obj-y += psci.o +obj-y += psci-common.o endif
obj-$(CONFIG_IPROC) += iproc-common/ diff --git a/arch/arm/cpu/armv7/psci-common.c b/arch/arm/cpu/armv7/psci-common.c new file mode 100644 index 000000000000..d14b6937473f --- /dev/null +++ b/arch/arm/cpu/armv7/psci-common.c @@ -0,0 +1,39 @@ +/*
- Common PSCI functions
- Copyright (C) 2016 Chen-Yu Tsai
- Author: Chen-Yu Tsai wens@csie.org
- 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.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see http://www.gnu.org/licenses/.
- */
+#include <config.h> +#include <asm/armv7.h> +#include <asm/macro.h> +#include <asm/psci.h> +#include <asm/secure.h> +#include <linux/linkage.h>
+static u32 psci_target_pc[CONFIG_ARMV7_PSCI_NR_CPUS] __secure_data = { 0 };
+void __secure psci_save_target_pc(int cpu, u32 pc) +{
psci_target_pc[cpu] = pc;
DSB;
+}
+u32 __secure psci_get_target_pc(int cpu) +{
return psci_target_pc[cpu];
+}
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index dab576997654..a0da02300700 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -54,6 +54,10 @@ #ifndef __ASSEMBLY__ #include <asm/types.h>
+/* These 2 helper functions assume cpu < CONFIG_ARMV7_PSCI_NR_CPUS */
Only depends on this comment here? why not check parameter 'cpu' inside these functions?
+u32 psci_get_target_pc(int cpu); +void psci_save_target_pc(int cpu, u32 pc);
void psci_cpu_entry(void); u32 psci_get_cpu_id(void); u32 psci_get_cpu_stack_top(int cpu); -- 2.8.1

On Fri, Jul 1, 2016 at 6:54 PM, Hongbo Zhang macro.wave.z@gmail.com wrote:
On Sun, Jun 19, 2016 at 12:38 PM, Chen-Yu Tsai wens@csie.org wrote:
Now that we have a data section, add helper functions to save and fetch per-CPU target PC.
Signed-off-by: Chen-Yu Tsai wens@csie.org
arch/arm/cpu/armv7/Makefile | 1 + arch/arm/cpu/armv7/psci-common.c | 39 +++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/psci.h | 4 ++++ 3 files changed, 44 insertions(+) create mode 100644 arch/arm/cpu/armv7/psci-common.c
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 328c4b10e976..730b59986a01 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -26,6 +26,7 @@ endif
ifneq ($(CONFIG_ARMV7_PSCI),) obj-y += psci.o +obj-y += psci-common.o endif
obj-$(CONFIG_IPROC) += iproc-common/ diff --git a/arch/arm/cpu/armv7/psci-common.c b/arch/arm/cpu/armv7/psci-common.c new file mode 100644 index 000000000000..d14b6937473f --- /dev/null +++ b/arch/arm/cpu/armv7/psci-common.c @@ -0,0 +1,39 @@ +/*
- Common PSCI functions
- Copyright (C) 2016 Chen-Yu Tsai
- Author: Chen-Yu Tsai wens@csie.org
- 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.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see http://www.gnu.org/licenses/.
- */
+#include <config.h> +#include <asm/armv7.h> +#include <asm/macro.h> +#include <asm/psci.h> +#include <asm/secure.h> +#include <linux/linkage.h>
+static u32 psci_target_pc[CONFIG_ARMV7_PSCI_NR_CPUS] __secure_data = { 0 };
+void __secure psci_save_target_pc(int cpu, u32 pc) +{
psci_target_pc[cpu] = pc;
DSB;
+}
+u32 __secure psci_get_target_pc(int cpu) +{
return psci_target_pc[cpu];
+}
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index dab576997654..a0da02300700 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -54,6 +54,10 @@ #ifndef __ASSEMBLY__ #include <asm/types.h>
+/* These 2 helper functions assume cpu < CONFIG_ARMV7_PSCI_NR_CPUS */
Only depends on this comment here? why not check parameter 'cpu' inside these functions?
That's doable. But if you're passing a bad cpu index, chances are it's going to break elsewhere as well.
I was mostly concerned with keeping the helpers as simple as possible. They can't be static inlines in the header though, as some assembly code might use them.
ChenYu
+u32 psci_get_target_pc(int cpu); +void psci_save_target_pc(int cpu, u32 pc);
void psci_cpu_entry(void); u32 psci_get_cpu_id(void); u32 psci_get_cpu_stack_top(int cpu); -- 2.8.1

Now that we have a secure data section and space to store per-CPU target PC address, switch to it instead of storing the target PC on the stack.
Also save clobbered r4-r7 registers on the stack and restore them on return in psci_cpu_on for Tegra, i.MX7, and LS102xA platforms.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- arch/arm/cpu/armv7/ls102xa/psci.S | 14 +++++++------- arch/arm/cpu/armv7/mx7/psci.S | 13 ++++++++----- arch/arm/cpu/armv7/psci.S | 3 +-- arch/arm/cpu/armv7/sunxi/psci.c | 5 ++--- arch/arm/mach-tegra/psci.S | 11 ++++++----- 5 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index ba043efed021..f9b26b43218a 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -29,16 +29,16 @@ @ r2 = target PC .globl psci_cpu_on psci_cpu_on: - push {lr} + push {r4, r5, r6, lr}
@ Clear and Get the correct CPU number @ r1 = 0xf01 - and r1, r1, #0xff + and r4, r1, #0xff
- mov r0, r1 - bl psci_get_cpu_stack_top - str r2, [r0] - dsb + mov r0, r4 + mov r1, r2 + bl psci_save_target_pc + mov r1, r4
@ Get DCFG base address movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff) @@ -101,7 +101,7 @@ holdoff_release: @ Return mov r0, #ARM_PSCI_RET_SUCCESS
- pop {lr} + pop {r4, r5, r6, lr} bx lr
.globl psci_cpu_off diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S index d9e9fbfb9ebd..96e88d6184e4 100644 --- a/arch/arm/cpu/armv7/mx7/psci.S +++ b/arch/arm/cpu/armv7/mx7/psci.S @@ -11,17 +11,20 @@
.globl psci_cpu_on psci_cpu_on: - push {lr} + push {r4, r5, lr}
+ mov r4, r0 + mov r5, r1 mov r0, r1 - bl psci_get_cpu_stack_top - str r2, [r0] - dsb + mov r1, r2 + bl psci_save_target_pc
+ mov r0, r4 + mov r1, r5 ldr r2, =psci_cpu_entry bl imx_cpu_on
- pop {pc} + pop {r4, r5, pc}
.globl psci_cpu_off psci_cpu_off: diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index bfc4475e360c..50dfddb412af 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -245,8 +245,7 @@ ENTRY(psci_cpu_entry) bl _nonsec_init
bl psci_get_cpu_id @ CPU ID => r0 - bl psci_get_cpu_stack_top @ stack top => r0 - ldr r0, [r0] @ target PC at stack top + bl psci_get_target_pc @ target PC => r0 b _do_nonsec_entry ENDPROC(psci_cpu_entry)
diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c index 55fa0e73444e..a7c91fe3eb4a 100644 --- a/arch/arm/cpu/armv7/sunxi/psci.c +++ b/arch/arm/cpu/armv7/sunxi/psci.c @@ -209,9 +209,8 @@ int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc) (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE; u32 cpu = (mpidr & 0x3);
- /* store target PC at target CPU stack top */ - writel(pc, psci_get_cpu_stack_top(cpu)); - DSB; + /* store target PC */ + psci_save_target_pc(cpu, pc);
/* Set secondary core power on PC */ writel((u32)&psci_cpu_entry, &cpucfg->priv0); diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S index 85d5b6b59de4..645d08fa0bd8 100644 --- a/arch/arm/mach-tegra/psci.S +++ b/arch/arm/mach-tegra/psci.S @@ -85,12 +85,13 @@ _loop: wfi ENDPROC(psci_cpu_off)
ENTRY(psci_cpu_on) - push {lr} + push {r4, r5, r6, lr}
+ mov r4, r1 mov r0, r1 - bl psci_get_cpu_stack_top @ get stack top of target CPU - str r2, [r0] @ store target PC at stack top - dsb + mov r1, r2 + bl psci_save_target_pc @ store target PC + mov r1, r4
ldr r6, =TEGRA_RESET_EXCEPTION_VECTOR ldr r5, =psci_cpu_entry @@ -103,7 +104,7 @@ ENTRY(psci_cpu_on) str r5, [r6, r2]
mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS - pop {pc} + pop {r4, r5, r6, pc} ENDPROC(psci_cpu_on)
.popsection

Tested-by: Hongbo Zhang hongbo.zhang@nxp.com
On Sun, Jun 19, 2016 at 12:38 PM, Chen-Yu Tsai wens@csie.org wrote:
Now that we have a secure data section and space to store per-CPU target PC address, switch to it instead of storing the target PC on the stack.
Also save clobbered r4-r7 registers on the stack and restore them on return in psci_cpu_on for Tegra, i.MX7, and LS102xA platforms.
Signed-off-by: Chen-Yu Tsai wens@csie.org
arch/arm/cpu/armv7/ls102xa/psci.S | 14 +++++++------- arch/arm/cpu/armv7/mx7/psci.S | 13 ++++++++----- arch/arm/cpu/armv7/psci.S | 3 +-- arch/arm/cpu/armv7/sunxi/psci.c | 5 ++--- arch/arm/mach-tegra/psci.S | 11 ++++++----- 5 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index ba043efed021..f9b26b43218a 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -29,16 +29,16 @@ @ r2 = target PC .globl psci_cpu_on psci_cpu_on:
push {lr}
push {r4, r5, r6, lr} @ Clear and Get the correct CPU number @ r1 = 0xf01
and r1, r1, #0xff
and r4, r1, #0xff
mov r0, r1
bl psci_get_cpu_stack_top
str r2, [r0]
dsb
mov r0, r4
mov r1, r2
bl psci_save_target_pc
mov r1, r4 @ Get DCFG base address movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
@@ -101,7 +101,7 @@ holdoff_release: @ Return mov r0, #ARM_PSCI_RET_SUCCESS
pop {lr}
pop {r4, r5, r6, lr} bx lr
.globl psci_cpu_off diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S index d9e9fbfb9ebd..96e88d6184e4 100644 --- a/arch/arm/cpu/armv7/mx7/psci.S +++ b/arch/arm/cpu/armv7/mx7/psci.S @@ -11,17 +11,20 @@
.globl psci_cpu_on psci_cpu_on:
push {lr}
push {r4, r5, lr}
mov r4, r0
mov r5, r1 mov r0, r1
bl psci_get_cpu_stack_top
str r2, [r0]
dsb
mov r1, r2
bl psci_save_target_pc
mov r0, r4
mov r1, r5 ldr r2, =psci_cpu_entry bl imx_cpu_on
pop {pc}
pop {r4, r5, pc}
.globl psci_cpu_off psci_cpu_off: diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index bfc4475e360c..50dfddb412af 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -245,8 +245,7 @@ ENTRY(psci_cpu_entry) bl _nonsec_init
bl psci_get_cpu_id @ CPU ID => r0
bl psci_get_cpu_stack_top @ stack top => r0
ldr r0, [r0] @ target PC at stack top
bl psci_get_target_pc @ target PC => r0 b _do_nonsec_entry
ENDPROC(psci_cpu_entry)
diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c index 55fa0e73444e..a7c91fe3eb4a 100644 --- a/arch/arm/cpu/armv7/sunxi/psci.c +++ b/arch/arm/cpu/armv7/sunxi/psci.c @@ -209,9 +209,8 @@ int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc) (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE; u32 cpu = (mpidr & 0x3);
/* store target PC at target CPU stack top */
writel(pc, psci_get_cpu_stack_top(cpu));
DSB;
/* store target PC */
psci_save_target_pc(cpu, pc); /* Set secondary core power on PC */ writel((u32)&psci_cpu_entry, &cpucfg->priv0);
diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S index 85d5b6b59de4..645d08fa0bd8 100644 --- a/arch/arm/mach-tegra/psci.S +++ b/arch/arm/mach-tegra/psci.S @@ -85,12 +85,13 @@ _loop: wfi ENDPROC(psci_cpu_off)
ENTRY(psci_cpu_on)
push {lr}
push {r4, r5, r6, lr}
mov r4, r1 mov r0, r1
bl psci_get_cpu_stack_top @ get stack top of target CPU
str r2, [r0] @ store target PC at stack top
dsb
mov r1, r2
bl psci_save_target_pc @ store target PC
mov r1, r4 ldr r6, =TEGRA_RESET_EXCEPTION_VECTOR ldr r5, =psci_cpu_entry
@@ -103,7 +104,7 @@ ENTRY(psci_cpu_on) str r5, [r6, r2]
mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS
pop {pc}
pop {r4, r5, r6, pc}
ENDPROC(psci_cpu_on)
.popsection
-- 2.8.1

Now that we have a secure data section for storing variables, there should be no need for platform code to get the stack address.
Make psci_get_cpu_stack_top a local function, as it should only be used in armv7/psci.S and only by psci_stack_setup.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- arch/arm/cpu/armv7/psci.S | 2 +- arch/arm/include/asm/psci.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index 50dfddb412af..350b75ce20e8 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -213,7 +213,7 @@ ENDPROC(psci_cpu_off_common) @ -------------------- __secure_stack_start @ @ This expects CPU ID in r0 and returns stack top in r0 -ENTRY(psci_get_cpu_stack_top) +LENTRY(psci_get_cpu_stack_top) @ stack top = __secure_stack_end - (cpuid << ARM_PSCI_STACK_SHIFT) ldr r3, =__secure_stack_end sub r0, r3, r0, LSL #ARM_PSCI_STACK_SHIFT diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index a0da02300700..7ba7ce306ab1 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -60,7 +60,6 @@ void psci_save_target_pc(int cpu, u32 pc);
void psci_cpu_entry(void); u32 psci_get_cpu_id(void); -u32 psci_get_cpu_stack_top(int cpu); void psci_cpu_off_common(void);
int psci_update_dt(void *fdt);

I like the idea of secure stack and secure data section. I'd like to test this patch set, but only the psci common part and freescale platform's changes will be covered.
On Sun, Jun 19, 2016 at 12:38 PM, Chen-Yu Tsai wens@csie.org wrote:
Hi everyone,
This is ARM PSCI improvements part 2. This series cleans up PSCI stack allocation and target PC storage by introducing a secure stack section and a secure data section.
The series got larger than I planned. Some patches are just moving or consolidating code, and a few are adding missing macros. It's based on v3 of my "sunxi: PSCI implementation rewrite in C" series from earlier.
Patch 1 consolidates the stack setup code from all the PSCI-enabled platforms (which likely originated from the initial sunxi version) into a common function, and moves it into a seperate common function that is called before psci_arch_init. A weak stub psci_arch_init is added for platforms that no longer need a custom version.
Patch 2 converts the remaining sunxi PSCI assembly code into C.
Patch 3 adds the missing CONFIG_ARMV7_PSCI_NR_CPUS=2 for sun7i/A20.
Patch 4 makes the linker page align PSCI text only when it is directly executed, i.e. not copied to CONFIG_ARMV7_SECURE_BASE.
Patch 5 adds a fallback value for CONFIG_ARMV7_PSCI_NR_CPUS. The value is 4, which was the fixed maximum number of stacks allocated.
Patch 6 adds an empty stack section for the secure monitor.
Patch 7 has PSCI allocate its stack in the new secure stack section.
Patch 8 removes the now unused psci_text_end symbol. This was previously used to find where to allocate the stack.
Patch 9 adds a config variable for specifying the maximum size of the secure section (text, data, stack, etc.) and checks if the binary exceeds it.
Patch 10 defines CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i (A31/A20), Allwinner SoCs that have a block of secure SRAM.
Patch 11 moves the __secure macro to asm/secure.h. Previously sunxi and i.MX7 were defining it themselves.
Patch 12 adds a secure data section, and a __secure_data macro.
Patch 13 adds helper functions to save and get per-CPU target PC addresses for use in PSCI.
Patch 14 converts all PSCI-enabled platforms to the new helper functions to save/get target PC addresses.
Patch 15 makes the psci_get_cpu_stack_top function local/static. This function should only be used by the stack setup routine.
Regards ChenYu
Chen-Yu Tsai (15): ARM: PSCI: Split out common stack setup code from psci_arch_init sunxi: Move remaining PSCI assembly code to C sunxi: Add missing CONFIG_ARMV7_PSCI_NR_CPUS for sun7i ARM: Page align secure section only when it is executed in situ ARM: PSCI: Add fallback value for CONFIG_ARMV7_PSCI_NR_CPUS ARM: Add an empty secure stack section ARM: PSCI: Allocate PSCI stack in secure stack section ARM: PSCI: Remove unused psci_text_end symbol ARM: Add CONFIG_ARMV7_SECURE_MAX_SIZE and check size of secure section sunxi: Define CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i ARM: Move __secure definition to common asm/secure.h ARM: Add secure section for initialized data ARM: PSCI: Add helper functions to access per-CPU target PC storage ARM: PSCI: Switch to per-CPU target PC storage in secure data section ARM: PSCI: Make psci_get_cpu_stack_top local to armv7/psci.S
arch/arm/cpu/armv7/Makefile | 1 + arch/arm/cpu/armv7/ls102xa/psci.S | 26 ++++---------- arch/arm/cpu/armv7/mx7/psci-mx7.c | 2 +- arch/arm/cpu/armv7/mx7/psci.S | 31 +++++------------ arch/arm/cpu/armv7/nonsec_virt.S | 7 +++- arch/arm/cpu/armv7/psci-common.c | 39 +++++++++++++++++++++ arch/arm/cpu/armv7/psci.S | 55 ++++++++++++++++++++++-------- arch/arm/cpu/armv7/sunxi/Makefile | 1 - arch/arm/cpu/armv7/sunxi/psci.c | 9 +++-- arch/arm/cpu/armv7/sunxi/psci_head.S | 66 ------------------------------------ arch/arm/cpu/u-boot.lds | 60 +++++++++++++++++++++++++------- arch/arm/include/asm/armv7.h | 2 ++ arch/arm/include/asm/config.h | 5 +++ arch/arm/include/asm/psci.h | 9 ++++- arch/arm/include/asm/secure.h | 3 ++ arch/arm/lib/sections.c | 2 ++ arch/arm/mach-tegra/psci.S | 16 ++++----- include/configs/sun6i.h | 1 + include/configs/sun7i.h | 2 ++ 19 files changed, 183 insertions(+), 154 deletions(-) create mode 100644 arch/arm/cpu/armv7/psci-common.c delete mode 100644 arch/arm/cpu/armv7/sunxi/psci_head.S
-- 2.8.1

I applied all these patches and had a test. Patch 13/15 needs a manual merge, all the others apply well. There is no compiling warnings or errors. The PSCI function runs well after applying these patches. I will leave my Tested-by: tags in each patch touched separately.
On Thu, Jun 30, 2016 at 5:58 PM, Hongbo Zhang macro.wave.z@gmail.com wrote:
I like the idea of secure stack and secure data section. I'd like to test this patch set, but only the psci common part and freescale platform's changes will be covered.
On Sun, Jun 19, 2016 at 12:38 PM, Chen-Yu Tsai wens@csie.org wrote:
Hi everyone,
This is ARM PSCI improvements part 2. This series cleans up PSCI stack allocation and target PC storage by introducing a secure stack section and a secure data section.
The series got larger than I planned. Some patches are just moving or consolidating code, and a few are adding missing macros. It's based on v3 of my "sunxi: PSCI implementation rewrite in C" series from earlier.
Patch 1 consolidates the stack setup code from all the PSCI-enabled platforms (which likely originated from the initial sunxi version) into a common function, and moves it into a seperate common function that is called before psci_arch_init. A weak stub psci_arch_init is added for platforms that no longer need a custom version.
Patch 2 converts the remaining sunxi PSCI assembly code into C.
Patch 3 adds the missing CONFIG_ARMV7_PSCI_NR_CPUS=2 for sun7i/A20.
Patch 4 makes the linker page align PSCI text only when it is directly executed, i.e. not copied to CONFIG_ARMV7_SECURE_BASE.
Patch 5 adds a fallback value for CONFIG_ARMV7_PSCI_NR_CPUS. The value is 4, which was the fixed maximum number of stacks allocated.
Patch 6 adds an empty stack section for the secure monitor.
Patch 7 has PSCI allocate its stack in the new secure stack section.
Patch 8 removes the now unused psci_text_end symbol. This was previously used to find where to allocate the stack.
Patch 9 adds a config variable for specifying the maximum size of the secure section (text, data, stack, etc.) and checks if the binary exceeds it.
Patch 10 defines CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i (A31/A20), Allwinner SoCs that have a block of secure SRAM.
Patch 11 moves the __secure macro to asm/secure.h. Previously sunxi and i.MX7 were defining it themselves.
Patch 12 adds a secure data section, and a __secure_data macro.
Patch 13 adds helper functions to save and get per-CPU target PC addresses for use in PSCI.
Patch 14 converts all PSCI-enabled platforms to the new helper functions to save/get target PC addresses.
Patch 15 makes the psci_get_cpu_stack_top function local/static. This function should only be used by the stack setup routine.
Regards ChenYu
Chen-Yu Tsai (15): ARM: PSCI: Split out common stack setup code from psci_arch_init sunxi: Move remaining PSCI assembly code to C sunxi: Add missing CONFIG_ARMV7_PSCI_NR_CPUS for sun7i ARM: Page align secure section only when it is executed in situ ARM: PSCI: Add fallback value for CONFIG_ARMV7_PSCI_NR_CPUS ARM: Add an empty secure stack section ARM: PSCI: Allocate PSCI stack in secure stack section ARM: PSCI: Remove unused psci_text_end symbol ARM: Add CONFIG_ARMV7_SECURE_MAX_SIZE and check size of secure section sunxi: Define CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i ARM: Move __secure definition to common asm/secure.h ARM: Add secure section for initialized data ARM: PSCI: Add helper functions to access per-CPU target PC storage ARM: PSCI: Switch to per-CPU target PC storage in secure data section ARM: PSCI: Make psci_get_cpu_stack_top local to armv7/psci.S
arch/arm/cpu/armv7/Makefile | 1 + arch/arm/cpu/armv7/ls102xa/psci.S | 26 ++++---------- arch/arm/cpu/armv7/mx7/psci-mx7.c | 2 +- arch/arm/cpu/armv7/mx7/psci.S | 31 +++++------------ arch/arm/cpu/armv7/nonsec_virt.S | 7 +++- arch/arm/cpu/armv7/psci-common.c | 39 +++++++++++++++++++++ arch/arm/cpu/armv7/psci.S | 55 ++++++++++++++++++++++-------- arch/arm/cpu/armv7/sunxi/Makefile | 1 - arch/arm/cpu/armv7/sunxi/psci.c | 9 +++-- arch/arm/cpu/armv7/sunxi/psci_head.S | 66 ------------------------------------ arch/arm/cpu/u-boot.lds | 60 +++++++++++++++++++++++++------- arch/arm/include/asm/armv7.h | 2 ++ arch/arm/include/asm/config.h | 5 +++ arch/arm/include/asm/psci.h | 9 ++++- arch/arm/include/asm/secure.h | 3 ++ arch/arm/lib/sections.c | 2 ++ arch/arm/mach-tegra/psci.S | 16 ++++----- include/configs/sun6i.h | 1 + include/configs/sun7i.h | 2 ++ 19 files changed, 183 insertions(+), 154 deletions(-) create mode 100644 arch/arm/cpu/armv7/psci-common.c delete mode 100644 arch/arm/cpu/armv7/sunxi/psci_head.S
-- 2.8.1

Hi,
On 19-06-16 06:38, Chen-Yu Tsai wrote:
Hi everyone,
This is ARM PSCI improvements part 2. This series cleans up PSCI stack allocation and target PC storage by introducing a secure stack section and a secure data section.
I've added this series to my personal repo sunxi-wip branch for testing.
It might be best to also merge it via the u-boot-sunxi tree ?
Regards,
Hans
The series got larger than I planned. Some patches are just moving or consolidating code, and a few are adding missing macros. It's based on v3 of my "sunxi: PSCI implementation rewrite in C" series from earlier.
Patch 1 consolidates the stack setup code from all the PSCI-enabled platforms (which likely originated from the initial sunxi version) into a common function, and moves it into a seperate common function that is called before psci_arch_init. A weak stub psci_arch_init is added for platforms that no longer need a custom version.
Patch 2 converts the remaining sunxi PSCI assembly code into C.
Patch 3 adds the missing CONFIG_ARMV7_PSCI_NR_CPUS=2 for sun7i/A20.
Patch 4 makes the linker page align PSCI text only when it is directly executed, i.e. not copied to CONFIG_ARMV7_SECURE_BASE.
Patch 5 adds a fallback value for CONFIG_ARMV7_PSCI_NR_CPUS. The value is 4, which was the fixed maximum number of stacks allocated.
Patch 6 adds an empty stack section for the secure monitor.
Patch 7 has PSCI allocate its stack in the new secure stack section.
Patch 8 removes the now unused psci_text_end symbol. This was previously used to find where to allocate the stack.
Patch 9 adds a config variable for specifying the maximum size of the secure section (text, data, stack, etc.) and checks if the binary exceeds it.
Patch 10 defines CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i (A31/A20), Allwinner SoCs that have a block of secure SRAM.
Patch 11 moves the __secure macro to asm/secure.h. Previously sunxi and i.MX7 were defining it themselves.
Patch 12 adds a secure data section, and a __secure_data macro.
Patch 13 adds helper functions to save and get per-CPU target PC addresses for use in PSCI.
Patch 14 converts all PSCI-enabled platforms to the new helper functions to save/get target PC addresses.
Patch 15 makes the psci_get_cpu_stack_top function local/static. This function should only be used by the stack setup routine.
Regards ChenYu
Chen-Yu Tsai (15): ARM: PSCI: Split out common stack setup code from psci_arch_init sunxi: Move remaining PSCI assembly code to C sunxi: Add missing CONFIG_ARMV7_PSCI_NR_CPUS for sun7i ARM: Page align secure section only when it is executed in situ ARM: PSCI: Add fallback value for CONFIG_ARMV7_PSCI_NR_CPUS ARM: Add an empty secure stack section ARM: PSCI: Allocate PSCI stack in secure stack section ARM: PSCI: Remove unused psci_text_end symbol ARM: Add CONFIG_ARMV7_SECURE_MAX_SIZE and check size of secure section sunxi: Define CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i ARM: Move __secure definition to common asm/secure.h ARM: Add secure section for initialized data ARM: PSCI: Add helper functions to access per-CPU target PC storage ARM: PSCI: Switch to per-CPU target PC storage in secure data section ARM: PSCI: Make psci_get_cpu_stack_top local to armv7/psci.S
arch/arm/cpu/armv7/Makefile | 1 + arch/arm/cpu/armv7/ls102xa/psci.S | 26 ++++---------- arch/arm/cpu/armv7/mx7/psci-mx7.c | 2 +- arch/arm/cpu/armv7/mx7/psci.S | 31 +++++------------ arch/arm/cpu/armv7/nonsec_virt.S | 7 +++- arch/arm/cpu/armv7/psci-common.c | 39 +++++++++++++++++++++ arch/arm/cpu/armv7/psci.S | 55 ++++++++++++++++++++++-------- arch/arm/cpu/armv7/sunxi/Makefile | 1 - arch/arm/cpu/armv7/sunxi/psci.c | 9 +++-- arch/arm/cpu/armv7/sunxi/psci_head.S | 66 ------------------------------------ arch/arm/cpu/u-boot.lds | 60 +++++++++++++++++++++++++------- arch/arm/include/asm/armv7.h | 2 ++ arch/arm/include/asm/config.h | 5 +++ arch/arm/include/asm/psci.h | 9 ++++- arch/arm/include/asm/secure.h | 3 ++ arch/arm/lib/sections.c | 2 ++ arch/arm/mach-tegra/psci.S | 16 ++++----- include/configs/sun6i.h | 1 + include/configs/sun7i.h | 2 ++ 19 files changed, 183 insertions(+), 154 deletions(-) create mode 100644 arch/arm/cpu/armv7/psci-common.c delete mode 100644 arch/arm/cpu/armv7/sunxi/psci_head.S

Hi,
On Sat, Jul 2, 2016 at 8:00 PM, Hans de Goede hdegoede@redhat.com wrote:
Hi,
On 19-06-16 06:38, Chen-Yu Tsai wrote:
Hi everyone,
This is ARM PSCI improvements part 2. This series cleans up PSCI stack allocation and target PC storage by introducing a secure stack section and a secure data section.
I've added this series to my personal repo sunxi-wip branch for testing.
I might send a v2 of patch 5.
Also I forgot to add .secure_data to the sections that get copied to the actual u-boot blob. It currently works because the data structures in it are all written before they are read.
So a v2 of patch 12 is needed as well.
Could you also add Hongbo's tested-by tags?
It might be best to also merge it via the u-boot-sunxi tree ?
We should probably work out with the NXP/FreeScale people that are also working on PSCI support for their platform.
Hongbo, any comments?
Regards ChenYu
Regards,
Hans
The series got larger than I planned. Some patches are just moving or consolidating code, and a few are adding missing macros. It's based on v3 of my "sunxi: PSCI implementation rewrite in C" series from earlier.
Patch 1 consolidates the stack setup code from all the PSCI-enabled platforms (which likely originated from the initial sunxi version) into a common function, and moves it into a seperate common function that is called before psci_arch_init. A weak stub psci_arch_init is added for platforms that no longer need a custom version.
Patch 2 converts the remaining sunxi PSCI assembly code into C.
Patch 3 adds the missing CONFIG_ARMV7_PSCI_NR_CPUS=2 for sun7i/A20.
Patch 4 makes the linker page align PSCI text only when it is directly executed, i.e. not copied to CONFIG_ARMV7_SECURE_BASE.
Patch 5 adds a fallback value for CONFIG_ARMV7_PSCI_NR_CPUS. The value is 4, which was the fixed maximum number of stacks allocated.
Patch 6 adds an empty stack section for the secure monitor.
Patch 7 has PSCI allocate its stack in the new secure stack section.
Patch 8 removes the now unused psci_text_end symbol. This was previously used to find where to allocate the stack.
Patch 9 adds a config variable for specifying the maximum size of the secure section (text, data, stack, etc.) and checks if the binary exceeds it.
Patch 10 defines CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i (A31/A20), Allwinner SoCs that have a block of secure SRAM.
Patch 11 moves the __secure macro to asm/secure.h. Previously sunxi and i.MX7 were defining it themselves.
Patch 12 adds a secure data section, and a __secure_data macro.
Patch 13 adds helper functions to save and get per-CPU target PC addresses for use in PSCI.
Patch 14 converts all PSCI-enabled platforms to the new helper functions to save/get target PC addresses.
Patch 15 makes the psci_get_cpu_stack_top function local/static. This function should only be used by the stack setup routine.
Regards ChenYu
Chen-Yu Tsai (15): ARM: PSCI: Split out common stack setup code from psci_arch_init sunxi: Move remaining PSCI assembly code to C sunxi: Add missing CONFIG_ARMV7_PSCI_NR_CPUS for sun7i ARM: Page align secure section only when it is executed in situ ARM: PSCI: Add fallback value for CONFIG_ARMV7_PSCI_NR_CPUS ARM: Add an empty secure stack section ARM: PSCI: Allocate PSCI stack in secure stack section ARM: PSCI: Remove unused psci_text_end symbol ARM: Add CONFIG_ARMV7_SECURE_MAX_SIZE and check size of secure section sunxi: Define CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i ARM: Move __secure definition to common asm/secure.h ARM: Add secure section for initialized data ARM: PSCI: Add helper functions to access per-CPU target PC storage ARM: PSCI: Switch to per-CPU target PC storage in secure data section ARM: PSCI: Make psci_get_cpu_stack_top local to armv7/psci.S
arch/arm/cpu/armv7/Makefile | 1 + arch/arm/cpu/armv7/ls102xa/psci.S | 26 ++++---------- arch/arm/cpu/armv7/mx7/psci-mx7.c | 2 +- arch/arm/cpu/armv7/mx7/psci.S | 31 +++++------------ arch/arm/cpu/armv7/nonsec_virt.S | 7 +++- arch/arm/cpu/armv7/psci-common.c | 39 +++++++++++++++++++++ arch/arm/cpu/armv7/psci.S | 55 ++++++++++++++++++++++-------- arch/arm/cpu/armv7/sunxi/Makefile | 1 - arch/arm/cpu/armv7/sunxi/psci.c | 9 +++-- arch/arm/cpu/armv7/sunxi/psci_head.S | 66
arch/arm/cpu/u-boot.lds | 60 +++++++++++++++++++++++++------- arch/arm/include/asm/armv7.h | 2 ++ arch/arm/include/asm/config.h | 5 +++ arch/arm/include/asm/psci.h | 9 ++++- arch/arm/include/asm/secure.h | 3 ++ arch/arm/lib/sections.c | 2 ++ arch/arm/mach-tegra/psci.S | 16 ++++----- include/configs/sun6i.h | 1 + include/configs/sun7i.h | 2 ++ 19 files changed, 183 insertions(+), 154 deletions(-) create mode 100644 arch/arm/cpu/armv7/psci-common.c delete mode 100644 arch/arm/cpu/armv7/sunxi/psci_head.S

Hi,
On 03-07-16 02:35, Chen-Yu Tsai wrote:
Hi,
On Sat, Jul 2, 2016 at 8:00 PM, Hans de Goede hdegoede@redhat.com wrote:
Hi,
On 19-06-16 06:38, Chen-Yu Tsai wrote:
Hi everyone,
This is ARM PSCI improvements part 2. This series cleans up PSCI stack allocation and target PC storage by introducing a secure stack section and a secure data section.
I've added this series to my personal repo sunxi-wip branch for testing.
Note: I've also put it in u-boot-sunxi next now.
I might send a v2 of patch 5.
Also I forgot to add .secure_data to the sections that get copied to the actual u-boot blob. It currently works because the data structures in it are all written before they are read.
So a v2 of patch 12 is needed as well.
No problem I can replace any patches you want.
Could you also add Hongbo's tested-by tags?
I'll add any tags from patchwork before submitting an official pull-req for this (as well as wait for the v2-s you menetioned).
It might be best to also merge it via the u-boot-sunxi tree ?
We should probably work out with the NXP/FreeScale people that are also working on PSCI support for their platform.
Ack.
Regards,
Hans
Hongbo, any comments?
Regards ChenYu
Regards,
Hans
The series got larger than I planned. Some patches are just moving or consolidating code, and a few are adding missing macros. It's based on v3 of my "sunxi: PSCI implementation rewrite in C" series from earlier.
Patch 1 consolidates the stack setup code from all the PSCI-enabled platforms (which likely originated from the initial sunxi version) into a common function, and moves it into a seperate common function that is called before psci_arch_init. A weak stub psci_arch_init is added for platforms that no longer need a custom version.
Patch 2 converts the remaining sunxi PSCI assembly code into C.
Patch 3 adds the missing CONFIG_ARMV7_PSCI_NR_CPUS=2 for sun7i/A20.
Patch 4 makes the linker page align PSCI text only when it is directly executed, i.e. not copied to CONFIG_ARMV7_SECURE_BASE.
Patch 5 adds a fallback value for CONFIG_ARMV7_PSCI_NR_CPUS. The value is 4, which was the fixed maximum number of stacks allocated.
Patch 6 adds an empty stack section for the secure monitor.
Patch 7 has PSCI allocate its stack in the new secure stack section.
Patch 8 removes the now unused psci_text_end symbol. This was previously used to find where to allocate the stack.
Patch 9 adds a config variable for specifying the maximum size of the secure section (text, data, stack, etc.) and checks if the binary exceeds it.
Patch 10 defines CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i (A31/A20), Allwinner SoCs that have a block of secure SRAM.
Patch 11 moves the __secure macro to asm/secure.h. Previously sunxi and i.MX7 were defining it themselves.
Patch 12 adds a secure data section, and a __secure_data macro.
Patch 13 adds helper functions to save and get per-CPU target PC addresses for use in PSCI.
Patch 14 converts all PSCI-enabled platforms to the new helper functions to save/get target PC addresses.
Patch 15 makes the psci_get_cpu_stack_top function local/static. This function should only be used by the stack setup routine.
Regards ChenYu
Chen-Yu Tsai (15): ARM: PSCI: Split out common stack setup code from psci_arch_init sunxi: Move remaining PSCI assembly code to C sunxi: Add missing CONFIG_ARMV7_PSCI_NR_CPUS for sun7i ARM: Page align secure section only when it is executed in situ ARM: PSCI: Add fallback value for CONFIG_ARMV7_PSCI_NR_CPUS ARM: Add an empty secure stack section ARM: PSCI: Allocate PSCI stack in secure stack section ARM: PSCI: Remove unused psci_text_end symbol ARM: Add CONFIG_ARMV7_SECURE_MAX_SIZE and check size of secure section sunxi: Define CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i ARM: Move __secure definition to common asm/secure.h ARM: Add secure section for initialized data ARM: PSCI: Add helper functions to access per-CPU target PC storage ARM: PSCI: Switch to per-CPU target PC storage in secure data section ARM: PSCI: Make psci_get_cpu_stack_top local to armv7/psci.S
arch/arm/cpu/armv7/Makefile | 1 + arch/arm/cpu/armv7/ls102xa/psci.S | 26 ++++---------- arch/arm/cpu/armv7/mx7/psci-mx7.c | 2 +- arch/arm/cpu/armv7/mx7/psci.S | 31 +++++------------ arch/arm/cpu/armv7/nonsec_virt.S | 7 +++- arch/arm/cpu/armv7/psci-common.c | 39 +++++++++++++++++++++ arch/arm/cpu/armv7/psci.S | 55 ++++++++++++++++++++++-------- arch/arm/cpu/armv7/sunxi/Makefile | 1 - arch/arm/cpu/armv7/sunxi/psci.c | 9 +++-- arch/arm/cpu/armv7/sunxi/psci_head.S | 66
arch/arm/cpu/u-boot.lds | 60 +++++++++++++++++++++++++------- arch/arm/include/asm/armv7.h | 2 ++ arch/arm/include/asm/config.h | 5 +++ arch/arm/include/asm/psci.h | 9 ++++- arch/arm/include/asm/secure.h | 3 ++ arch/arm/lib/sections.c | 2 ++ arch/arm/mach-tegra/psci.S | 16 ++++----- include/configs/sun6i.h | 1 + include/configs/sun7i.h | 2 ++ 19 files changed, 183 insertions(+), 154 deletions(-) create mode 100644 arch/arm/cpu/armv7/psci-common.c delete mode 100644 arch/arm/cpu/armv7/sunxi/psci_head.S

On Sun, Jul 3, 2016 at 5:05 PM, Hans de Goede hdegoede@redhat.com wrote:
Hi,
On 03-07-16 02:35, Chen-Yu Tsai wrote:
Hi,
On Sat, Jul 2, 2016 at 8:00 PM, Hans de Goede hdegoede@redhat.com wrote:
Hi,
On 19-06-16 06:38, Chen-Yu Tsai wrote:
Hi everyone,
This is ARM PSCI improvements part 2. This series cleans up PSCI stack allocation and target PC storage by introducing a secure stack section and a secure data section.
I've added this series to my personal repo sunxi-wip branch for testing.
Note: I've also put it in u-boot-sunxi next now.
I might send a v2 of patch 5.
Also I forgot to add .secure_data to the sections that get copied to the actual u-boot blob. It currently works because the data structures in it are all written before they are read.
So a v2 of patch 12 is needed as well.
No problem I can replace any patches you want.
FYI I sent out v2 for patches 5, 12, and 13.
13 is just a rebase conflict fix, which you probably have done already.
ChenYu
Could you also add Hongbo's tested-by tags?
I'll add any tags from patchwork before submitting an official pull-req for this (as well as wait for the v2-s you menetioned).
It might be best to also merge it via the u-boot-sunxi tree ?
We should probably work out with the NXP/FreeScale people that are also working on PSCI support for their platform.
Ack.
Regards,
Hans
Hongbo, any comments?
Regards ChenYu
Regards,
Hans
The series got larger than I planned. Some patches are just moving or consolidating code, and a few are adding missing macros. It's based on v3 of my "sunxi: PSCI implementation rewrite in C" series from earlier.
Patch 1 consolidates the stack setup code from all the PSCI-enabled platforms (which likely originated from the initial sunxi version) into a common function, and moves it into a seperate common function that is called before psci_arch_init. A weak stub psci_arch_init is added for platforms that no longer need a custom version.
Patch 2 converts the remaining sunxi PSCI assembly code into C.
Patch 3 adds the missing CONFIG_ARMV7_PSCI_NR_CPUS=2 for sun7i/A20.
Patch 4 makes the linker page align PSCI text only when it is directly executed, i.e. not copied to CONFIG_ARMV7_SECURE_BASE.
Patch 5 adds a fallback value for CONFIG_ARMV7_PSCI_NR_CPUS. The value is 4, which was the fixed maximum number of stacks allocated.
Patch 6 adds an empty stack section for the secure monitor.
Patch 7 has PSCI allocate its stack in the new secure stack section.
Patch 8 removes the now unused psci_text_end symbol. This was previously used to find where to allocate the stack.
Patch 9 adds a config variable for specifying the maximum size of the secure section (text, data, stack, etc.) and checks if the binary exceeds it.
Patch 10 defines CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i (A31/A20), Allwinner SoCs that have a block of secure SRAM.
Patch 11 moves the __secure macro to asm/secure.h. Previously sunxi and i.MX7 were defining it themselves.
Patch 12 adds a secure data section, and a __secure_data macro.
Patch 13 adds helper functions to save and get per-CPU target PC addresses for use in PSCI.
Patch 14 converts all PSCI-enabled platforms to the new helper functions to save/get target PC addresses.
Patch 15 makes the psci_get_cpu_stack_top function local/static. This function should only be used by the stack setup routine.
Regards ChenYu
Chen-Yu Tsai (15): ARM: PSCI: Split out common stack setup code from psci_arch_init sunxi: Move remaining PSCI assembly code to C sunxi: Add missing CONFIG_ARMV7_PSCI_NR_CPUS for sun7i ARM: Page align secure section only when it is executed in situ ARM: PSCI: Add fallback value for CONFIG_ARMV7_PSCI_NR_CPUS ARM: Add an empty secure stack section ARM: PSCI: Allocate PSCI stack in secure stack section ARM: PSCI: Remove unused psci_text_end symbol ARM: Add CONFIG_ARMV7_SECURE_MAX_SIZE and check size of secure section sunxi: Define CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i ARM: Move __secure definition to common asm/secure.h ARM: Add secure section for initialized data ARM: PSCI: Add helper functions to access per-CPU target PC storage ARM: PSCI: Switch to per-CPU target PC storage in secure data section ARM: PSCI: Make psci_get_cpu_stack_top local to armv7/psci.S
arch/arm/cpu/armv7/Makefile | 1 + arch/arm/cpu/armv7/ls102xa/psci.S | 26 ++++---------- arch/arm/cpu/armv7/mx7/psci-mx7.c | 2 +- arch/arm/cpu/armv7/mx7/psci.S | 31 +++++------------ arch/arm/cpu/armv7/nonsec_virt.S | 7 +++- arch/arm/cpu/armv7/psci-common.c | 39 +++++++++++++++++++++ arch/arm/cpu/armv7/psci.S | 55 ++++++++++++++++++++++-------- arch/arm/cpu/armv7/sunxi/Makefile | 1 - arch/arm/cpu/armv7/sunxi/psci.c | 9 +++-- arch/arm/cpu/armv7/sunxi/psci_head.S | 66
arch/arm/cpu/u-boot.lds | 60 +++++++++++++++++++++++++------- arch/arm/include/asm/armv7.h | 2 ++ arch/arm/include/asm/config.h | 5 +++ arch/arm/include/asm/psci.h | 9 ++++- arch/arm/include/asm/secure.h | 3 ++ arch/arm/lib/sections.c | 2 ++ arch/arm/mach-tegra/psci.S | 16 ++++----- include/configs/sun6i.h | 1 + include/configs/sun7i.h | 2 ++ 19 files changed, 183 insertions(+), 154 deletions(-) create mode 100644 arch/arm/cpu/armv7/psci-common.c delete mode 100644 arch/arm/cpu/armv7/sunxi/psci_head.S

On Sun, Jul 3, 2016 at 8:35 AM, Chen-Yu Tsai wens@csie.org wrote:
Hi,
On Sat, Jul 2, 2016 at 8:00 PM, Hans de Goede hdegoede@redhat.com wrote:
Hi,
On 19-06-16 06:38, Chen-Yu Tsai wrote:
Hi everyone,
This is ARM PSCI improvements part 2. This series cleans up PSCI stack allocation and target PC storage by introducing a secure stack section and a secure data section.
I've added this series to my personal repo sunxi-wip branch for testing.
I might send a v2 of patch 5.
Also I forgot to add .secure_data to the sections that get copied to the actual u-boot blob. It currently works because the data structures in it are all written before they are read.
So a v2 of patch 12 is needed as well.
Could you also add Hongbo's tested-by tags?
It might be best to also merge it via the u-boot-sunxi tree ?
We should probably work out with the NXP/FreeScale people that are also working on PSCI support for their platform.
Hongbo, any comments?
Well, one concern is the macro definition of CPU numbers, it should work for all platforms. another is the method of saving target PC, I like the idea of a dedicated secure data section, hope your patches get merged and then I can rebase my patches against yours. (In fact my patches were originally created by Dongsheng and I just followed his idea, and what's more I am not good at the lds grammar to add new section) My purpose is to add v1.0 support and some v1.0 functions of my platform this time, further v1.0 function eg suspend-to-ram is coming later.
Regards ChenYu
Regards,
Hans
The series got larger than I planned. Some patches are just moving or consolidating code, and a few are adding missing macros. It's based on v3 of my "sunxi: PSCI implementation rewrite in C" series from earlier.
Patch 1 consolidates the stack setup code from all the PSCI-enabled platforms (which likely originated from the initial sunxi version) into a common function, and moves it into a seperate common function that is called before psci_arch_init. A weak stub psci_arch_init is added for platforms that no longer need a custom version.
Patch 2 converts the remaining sunxi PSCI assembly code into C.
Patch 3 adds the missing CONFIG_ARMV7_PSCI_NR_CPUS=2 for sun7i/A20.
Patch 4 makes the linker page align PSCI text only when it is directly executed, i.e. not copied to CONFIG_ARMV7_SECURE_BASE.
Patch 5 adds a fallback value for CONFIG_ARMV7_PSCI_NR_CPUS. The value is 4, which was the fixed maximum number of stacks allocated.
Patch 6 adds an empty stack section for the secure monitor.
Patch 7 has PSCI allocate its stack in the new secure stack section.
Patch 8 removes the now unused psci_text_end symbol. This was previously used to find where to allocate the stack.
Patch 9 adds a config variable for specifying the maximum size of the secure section (text, data, stack, etc.) and checks if the binary exceeds it.
Patch 10 defines CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i (A31/A20), Allwinner SoCs that have a block of secure SRAM.
Patch 11 moves the __secure macro to asm/secure.h. Previously sunxi and i.MX7 were defining it themselves.
Patch 12 adds a secure data section, and a __secure_data macro.
Patch 13 adds helper functions to save and get per-CPU target PC addresses for use in PSCI.
Patch 14 converts all PSCI-enabled platforms to the new helper functions to save/get target PC addresses.
Patch 15 makes the psci_get_cpu_stack_top function local/static. This function should only be used by the stack setup routine.
Regards ChenYu
Chen-Yu Tsai (15): ARM: PSCI: Split out common stack setup code from psci_arch_init sunxi: Move remaining PSCI assembly code to C sunxi: Add missing CONFIG_ARMV7_PSCI_NR_CPUS for sun7i ARM: Page align secure section only when it is executed in situ ARM: PSCI: Add fallback value for CONFIG_ARMV7_PSCI_NR_CPUS ARM: Add an empty secure stack section ARM: PSCI: Allocate PSCI stack in secure stack section ARM: PSCI: Remove unused psci_text_end symbol ARM: Add CONFIG_ARMV7_SECURE_MAX_SIZE and check size of secure section sunxi: Define CONFIG_ARMV7_SECURE_MAX_SIZE for sun6i/sun7i ARM: Move __secure definition to common asm/secure.h ARM: Add secure section for initialized data ARM: PSCI: Add helper functions to access per-CPU target PC storage ARM: PSCI: Switch to per-CPU target PC storage in secure data section ARM: PSCI: Make psci_get_cpu_stack_top local to armv7/psci.S
arch/arm/cpu/armv7/Makefile | 1 + arch/arm/cpu/armv7/ls102xa/psci.S | 26 ++++---------- arch/arm/cpu/armv7/mx7/psci-mx7.c | 2 +- arch/arm/cpu/armv7/mx7/psci.S | 31 +++++------------ arch/arm/cpu/armv7/nonsec_virt.S | 7 +++- arch/arm/cpu/armv7/psci-common.c | 39 +++++++++++++++++++++ arch/arm/cpu/armv7/psci.S | 55 ++++++++++++++++++++++-------- arch/arm/cpu/armv7/sunxi/Makefile | 1 - arch/arm/cpu/armv7/sunxi/psci.c | 9 +++-- arch/arm/cpu/armv7/sunxi/psci_head.S | 66
arch/arm/cpu/u-boot.lds | 60 +++++++++++++++++++++++++------- arch/arm/include/asm/armv7.h | 2 ++ arch/arm/include/asm/config.h | 5 +++ arch/arm/include/asm/psci.h | 9 ++++- arch/arm/include/asm/secure.h | 3 ++ arch/arm/lib/sections.c | 2 ++ arch/arm/mach-tegra/psci.S | 16 ++++----- include/configs/sun6i.h | 1 + include/configs/sun7i.h | 2 ++ 19 files changed, 183 insertions(+), 154 deletions(-) create mode 100644 arch/arm/cpu/armv7/psci-common.c delete mode 100644 arch/arm/cpu/armv7/sunxi/psci_head.S
participants (3)
-
Chen-Yu Tsai
-
Hans de Goede
-
Hongbo Zhang