From b52813239c10d857bd262dc850232ccccdbaa69e Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:31 +0800 Subject: ARM: PSCI: Split out common stack setup code from psci_arch_init 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 Signed-off-by: Hans de Goede --- 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 +--------------- 5 files changed, 25 insertions(+), 42 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index cf5cd48bcb..86116e1fcc 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 34c6ab33f0..12cca7cc6d 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 b7563edbe6..95ce9387b8 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 ab408378fc..46fcf770c2 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 8fa823d1df..e51db04cf1 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) -- cgit From 94a389b257039511784b91a263913c845c8146e4 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:32 +0800 Subject: sunxi: Move remaining PSCI assembly code to C 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 Signed-off-by: Hans de Goede --- 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 (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index c208510168..b35b9df4a9 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 a118e9d0c4..cd0d94462b 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 e51db04cf1..0000000000 --- a/arch/arm/cpu/armv7/sunxi/psci_head.S +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2013 - ARM Ltd - * Author: Marc Zyngier - * - * Based on code by Carl van Schaik . - * - * 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 . - */ - -#include -#include - -#include -#include -#include -#include -#include - -/* - * 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 -- cgit From a1274cc94a20a0fc6715522d021ab84969b6bf91 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:34 +0800 Subject: ARM: Page align secure section only when it is executed in situ 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 Signed-off-by: Hans de Goede --- arch/arm/cpu/u-boot.lds | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index 1769b6ea88..ba177787d2 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)) { -- cgit From 980d6a55119f757ade4abed88bf4b2b7494c68e6 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:36 +0800 Subject: ARM: Add an empty secure stack section 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 Signed-off-by: Hans de Goede --- arch/arm/cpu/u-boot.lds | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index ba177787d2..002706ae63 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -8,6 +8,7 @@ */ #include +#include 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 */ } -- cgit From 8c0ef7fad676827125ad91060361d05ab4b16f44 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:37 +0800 Subject: ARM: PSCI: Allocate PSCI stack in secure stack section 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 Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/psci.S | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index 46fcf770c2..bfc4475e36 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) -- cgit From 28f90357323bc65e7da01c458222b84dc42988bb Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:38 +0800 Subject: ARM: PSCI: Remove unused psci_text_end symbol 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 Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/ls102xa/psci.S | 2 -- arch/arm/cpu/armv7/mx7/psci.S | 2 -- arch/arm/cpu/armv7/sunxi/psci.c | 5 ----- 3 files changed, 9 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 86116e1fcc..ba043efed0 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 12cca7cc6d..d9e9fbfb9e 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 cd0d94462b..c7d97fe2c9 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) -{ -} -- cgit From 3eff681818e2c858175a7cc4e766f75e95827920 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:39 +0800 Subject: ARM: Add CONFIG_ARMV7_SECURE_MAX_SIZE and check size of secure section 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 Signed-off-by: Hans de Goede --- arch/arm/cpu/u-boot.lds | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index 002706ae63..5a65c27cfa 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 -- cgit From afc1f65f504324cd5f87a8cb480bebeb0c61e4e0 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:41 +0800 Subject: ARM: Move __secure definition to common asm/secure.h 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 Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/mx7/psci-mx7.c | 2 +- arch/arm/cpu/armv7/sunxi/psci.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/mx7/psci-mx7.c b/arch/arm/cpu/armv7/mx7/psci-mx7.c index 9a330476cf..502552d171 100644 --- a/arch/arm/cpu/armv7/mx7/psci-mx7.c +++ b/arch/arm/cpu/armv7/mx7/psci-mx7.c @@ -1,9 +1,9 @@ #include #include +#include #include #include -#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 c7d97fe2c9..be3a1fbc00 100644 --- a/arch/arm/cpu/armv7/sunxi/psci.c +++ b/arch/arm/cpu/armv7/sunxi/psci.c @@ -17,11 +17,11 @@ #include #include #include +#include #include #include -#define __secure __attribute__ ((section ("._secure.text"))) #define __irq __attribute__ ((interrupt ("IRQ"))) #define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET) -- cgit From a5aa7ff33a942ce8ea38006fd5225a800827bb2c Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 5 Jul 2016 21:45:06 +0800 Subject: ARM: Add secure section for initialized data 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 Signed-off-by: Hans de Goede --- arch/arm/cpu/u-boot.lds | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index 5a65c27cfa..36c9fd0bd0 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)) -- cgit From 45c334e6b22bae75ada8662b88000c4347b1361b Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 5 Jul 2016 21:45:07 +0800 Subject: ARM: PSCI: Add helper functions to access per-CPU target PC storage Now that we have a data section, add helper functions to save and fetch per-CPU target PC. Signed-off-by: Chen-Yu Tsai Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/cpu/armv7/psci-common.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv7/psci-common.c (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index ddd8d12d51..0d4bfbc55b 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -19,7 +19,7 @@ endif endif obj-$(CONFIG_ARMV7_NONSEC) += nonsec_virt.o virt-v7.o virt-dt.o -obj-$(CONFIG_ARMV7_PSCI) += psci.o +obj-$(CONFIG_ARMV7_PSCI) += psci.o psci-common.o obj-$(CONFIG_IPROC) += iproc-common/ obj-$(CONFIG_KONA) += kona-common/ diff --git a/arch/arm/cpu/armv7/psci-common.c b/arch/arm/cpu/armv7/psci-common.c new file mode 100644 index 0000000000..d14b693747 --- /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 + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +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]; +} + -- cgit From 6e6622de166f53597172687b7269b07cf48844df Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:44 +0800 Subject: ARM: PSCI: Switch to per-CPU target PC storage in secure data section 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 Signed-off-by: Hans de Goede --- 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 ++--- 4 files changed, 18 insertions(+), 17 deletions(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index ba043efed0..f9b26b4321 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 d9e9fbfb9e..96e88d6184 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 bfc4475e36..50dfddb412 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 be3a1fbc00..7ac84065f4 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); -- cgit From b7073965a343fca2bcde4195fbba664c98f309d8 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:45 +0800 Subject: ARM: PSCI: Make psci_get_cpu_stack_top local to armv7/psci.S 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 Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/psci.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/cpu') diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index 50dfddb412..350b75ce20 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 -- cgit