[U-Boot] [PATCH 0/9] ARM: ARMv7: PSCI: add PSCI v1.0 support

From: Wang Dongsheng dongsheng.wang@nxp.com
Support PSCI v1.0 for u-boot.
Wang Dongsheng (9): ARM: PSCI: Change function ID base value ARM: PSCI: Change PSCI related macro definition style ARM: ARMv7: PSCI: move target PC in each CPU stack no longer is shared ARM: ARMv7: PSCI: Factor out reusable psci_cpu_on_common ARM: ARMv7: PSCI: Pass contextID to target CPU ARM: ARMv7: PSCI: ls102xa: Verify CPU ID for CPU_ON ARM: ARMv7: PSCI: Add PSCI 1.0 version support ARM: ARMv7: PSCI: ls102xa: add psci functions implemention ARM: ARMv7: PSCI: ls102xa: put secure text section into OCRAM
arch/arm/cpu/armv7/ls102xa/psci.S | 155 +++++++++++++++++++++++---- arch/arm/cpu/armv7/mx7/psci.S | 5 - arch/arm/cpu/armv7/nonsec_virt.S | 4 + arch/arm/cpu/armv7/psci.S | 162 ++++++++++++++++++++++++++--- arch/arm/cpu/armv7/sunxi/psci_sun6i.S | 11 +- arch/arm/cpu/armv7/sunxi/psci_sun7i.S | 11 +- arch/arm/cpu/armv7/virt-dt.c | 48 ++++++--- arch/arm/include/asm/arch-ls102xa/config.h | 3 +- arch/arm/include/asm/psci.h | 62 ++++++++--- arch/arm/mach-tegra/psci.S | 11 +- board/freescale/ls1021aqds/Makefile | 1 + board/freescale/ls1021aqds/psci.S | 36 +++++++ board/freescale/ls1021atwr/Makefile | 1 + board/freescale/ls1021atwr/psci.S | 28 +++++ include/configs/ls1021aqds.h | 3 + include/configs/ls1021atwr.h | 2 + 16 files changed, 451 insertions(+), 92 deletions(-) create mode 100644 board/freescale/ls1021aqds/psci.S create mode 100644 board/freescale/ls1021atwr/psci.S

From: Wang Dongsheng dongsheng.wang@nxp.com
Following PSCI v1.0 spec and Linux kernel bindings:
U-Boot's choice of base value is arbitrary for v0.1, because it's described in the device tree, so we're choosing to make things easier by using 0x84000000 for all PSCI versions.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com --- arch/arm/include/asm/psci.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index 128a606..a4a19e3 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -19,13 +19,13 @@ #define __ARM_PSCI_H__
/* PSCI interface */ -#define ARM_PSCI_FN_BASE 0x95c1ba5e +#define ARM_PSCI_FN_BASE 0x84000000 #define ARM_PSCI_FN(n) (ARM_PSCI_FN_BASE + (n))
-#define ARM_PSCI_FN_CPU_SUSPEND ARM_PSCI_FN(0) -#define ARM_PSCI_FN_CPU_OFF ARM_PSCI_FN(1) -#define ARM_PSCI_FN_CPU_ON ARM_PSCI_FN(2) -#define ARM_PSCI_FN_MIGRATE ARM_PSCI_FN(3) +#define ARM_PSCI_FN_CPU_SUSPEND ARM_PSCI_FN(1) +#define ARM_PSCI_FN_CPU_OFF ARM_PSCI_FN(2) +#define ARM_PSCI_FN_CPU_ON ARM_PSCI_FN(3) +#define ARM_PSCI_FN_MIGRATE ARM_PSCI_FN(5)
#define ARM_PSCI_RET_SUCCESS 0 #define ARM_PSCI_RET_NI (-1)

From: Wang Dongsheng dongsheng.wang@nxp.com
The macro style changes just to keep the style of the macro concise and consistent, and style mimicking linux.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com --- arch/arm/cpu/armv7/ls102xa/psci.S | 2 +- arch/arm/cpu/armv7/psci.S | 12 ++++++------ arch/arm/cpu/armv7/sunxi/psci_sun6i.S | 2 +- arch/arm/cpu/armv7/sunxi/psci_sun7i.S | 2 +- arch/arm/cpu/armv7/virt-dt.c | 8 ++++---- arch/arm/include/asm/psci.h | 27 ++++++++++++++++----------- arch/arm/mach-tegra/psci.S | 2 +- 7 files changed, 30 insertions(+), 25 deletions(-)
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index cf5cd48..0b067d9 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -99,7 +99,7 @@ holdoff_release: dsb
@ Return - mov r0, #ARM_PSCI_RET_SUCCESS + mov r0, #PSCI_RET_SUCCESS
pop {lr} bx lr diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index 87c0c0b..2425f6a 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -50,7 +50,7 @@ ENTRY(psci_cpu_suspend) ENTRY(psci_cpu_off) ENTRY(psci_cpu_on) ENTRY(psci_migrate) - mov r0, #ARM_PSCI_RET_NI @ Return -1 (Not Implemented) + mov r0, #PSCI_RET_NOT_SUPPORTED @ Return -1 (Not Implemented) mov pc, lr ENDPROC(psci_migrate) ENDPROC(psci_cpu_on) @@ -62,13 +62,13 @@ ENDPROC(psci_cpu_suspend) .weak psci_migrate
_psci_table: - .word ARM_PSCI_FN_CPU_SUSPEND + .word PSCI_FN_CPU_SUSPEND .word psci_cpu_suspend - .word ARM_PSCI_FN_CPU_OFF + .word PSCI_FN_CPU_OFF .word psci_cpu_off - .word ARM_PSCI_FN_CPU_ON + .word PSCI_FN_CPU_ON .word psci_cpu_on - .word ARM_PSCI_FN_MIGRATE + .word PSCI_FN_MIGRATE .word psci_migrate .word 0 .word 0 @@ -86,7 +86,7 @@ _smc_psci: 1: ldr r5, [r4] @ Load PSCI function ID ldr r6, [r4, #4] @ Load target PC cmp r5, #0 @ If reach the end, bail out - moveq r0, #ARM_PSCI_RET_INVAL @ Return -2 (Invalid) + moveq r0, #PSCI_RET_INVALID_PARAMS @ Return -2 (Invalid) beq 2f cmp r0, r5 @ If not matching, try next entry addne r4, r4, #8 diff --git a/arch/arm/cpu/armv7/sunxi/psci_sun6i.S b/arch/arm/cpu/armv7/sunxi/psci_sun6i.S index 4ff46e4..b96c5ef 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_sun6i.S +++ b/arch/arm/cpu/armv7/sunxi/psci_sun6i.S @@ -204,7 +204,7 @@ psci_cpu_on: orr r6, r6, r4 str r6, [r0, #0x1e4]
- mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS + mov r0, #PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS pop {pc}
.globl psci_cpu_off diff --git a/arch/arm/cpu/armv7/sunxi/psci_sun7i.S b/arch/arm/cpu/armv7/sunxi/psci_sun7i.S index e15d587..59d7ff0 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_sun7i.S +++ b/arch/arm/cpu/armv7/sunxi/psci_sun7i.S @@ -179,7 +179,7 @@ psci_cpu_on: orr r6, r6, r4 str r6, [r0, #0x1e4]
- mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS + mov r0, #PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS pop {pc}
.globl psci_cpu_off diff --git a/arch/arm/cpu/armv7/virt-dt.c b/arch/arm/cpu/armv7/virt-dt.c index 32c368f..f1251d1 100644 --- a/arch/arm/cpu/armv7/virt-dt.c +++ b/arch/arm/cpu/armv7/virt-dt.c @@ -73,16 +73,16 @@ static int fdt_psci(void *fdt) tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc"); if (tmp) return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", ARM_PSCI_FN_CPU_SUSPEND); + tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", PSCI_FN_CPU_SUSPEND); if (tmp) return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", ARM_PSCI_FN_CPU_OFF); + tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", PSCI_FN_CPU_OFF); if (tmp) return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", ARM_PSCI_FN_CPU_ON); + tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", PSCI_FN_CPU_ON); if (tmp) return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", ARM_PSCI_FN_MIGRATE); + tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", PSCI_FN_MIGRATE); if (tmp) return tmp; #endif diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index a4a19e3..f7b8f65 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -18,19 +18,24 @@ #ifndef __ARM_PSCI_H__ #define __ARM_PSCI_H__
-/* PSCI interface */ -#define ARM_PSCI_FN_BASE 0x84000000 -#define ARM_PSCI_FN(n) (ARM_PSCI_FN_BASE + (n))
-#define ARM_PSCI_FN_CPU_SUSPEND ARM_PSCI_FN(1) -#define ARM_PSCI_FN_CPU_OFF ARM_PSCI_FN(2) -#define ARM_PSCI_FN_CPU_ON ARM_PSCI_FN(3) -#define ARM_PSCI_FN_MIGRATE ARM_PSCI_FN(5) +#define PSCI_FN_BASE 0x84000000 +#define PSCI_FN_ID(n) (PSCI_FN_BASE + (n))
-#define ARM_PSCI_RET_SUCCESS 0 -#define ARM_PSCI_RET_NI (-1) -#define ARM_PSCI_RET_INVAL (-2) -#define ARM_PSCI_RET_DENIED (-3) +/* PSCI v0.1 interface */ +#define PSCI_FN_CPU_SUSPEND PSCI_FN_ID(1) +#define PSCI_FN_CPU_OFF PSCI_FN_ID(2) +#define PSCI_FN_CPU_ON PSCI_FN_ID(3) +#define PSCI_FN_MIGRATE PSCI_FN_ID(5) + +/* + * Original from Linux kernel: include/uapi/linux/psci.h + */ +/* PSCI return values (inclusive of all PSCI versions) */ +#define PSCI_RET_SUCCESS 0 +#define PSCI_RET_NOT_SUPPORTED (-1) +#define PSCI_RET_INVALID_PARAMS (-2) +#define PSCI_RET_DENIED (-3)
#ifndef __ASSEMBLY__ int psci_update_dt(void *fdt); diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S index b836da1..5f326c9 100644 --- a/arch/arm/mach-tegra/psci.S +++ b/arch/arm/mach-tegra/psci.S @@ -105,7 +105,7 @@ ENTRY(psci_cpu_on) mov r5, #(CSR_IMMEDIATE_WAKE | CSR_ENABLE) str r5, [r6, r2]
- mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS + mov r0, #PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS pop {pc} ENDPROC(psci_cpu_on)

From: Wang Dongsheng dongsheng.wang@nxp.com
All of cpu share the same targetPC space that is unsafe. So move target PC save space into CPU stack.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com --- arch/arm/cpu/armv7/ls102xa/psci.S | 4 +-- arch/arm/cpu/armv7/mx7/psci.S | 4 +-- arch/arm/cpu/armv7/psci.S | 51 ++++++++++++++++++++++++++++------- arch/arm/cpu/armv7/sunxi/psci_sun6i.S | 4 +-- arch/arm/cpu/armv7/sunxi/psci_sun7i.S | 4 +-- arch/arm/cpu/armv7/virt-dt.c | 3 ++- arch/arm/include/asm/psci.h | 4 +++ arch/arm/mach-tegra/psci.S | 4 +-- 8 files changed, 53 insertions(+), 25 deletions(-)
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 0b067d9..3a34064 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -36,9 +36,7 @@ psci_cpu_on: and r1, r1, #0xff
mov r0, r1 - bl psci_get_cpu_stack_top - str r2, [r0] - dsb + bl psci_save_target_pc
@ Get DCFG base address movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff) diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S index 34c6ab3..cb39f27 100644 --- a/arch/arm/cpu/armv7/mx7/psci.S +++ b/arch/arm/cpu/armv7/mx7/psci.S @@ -30,9 +30,7 @@ psci_cpu_on: push {lr}
mov r0, r1 - bl psci_get_cpu_stack_top - str r2, [r0] - dsb + bl psci_save_target_pc
ldr r2, =psci_cpu_entry bl imx_cpu_on diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index 2425f6a..0e0f98e 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -20,6 +20,8 @@ #include <asm/macro.h> #include <asm/psci.h>
+#define SAVE_SPACE_TARGET_PC_OFFSET 0x0 + .pushsection ._secure.text, "ax"
.arch_extension sec @@ -196,27 +198,58 @@ ENDPROC(psci_cpu_off_common)
@ expects CPU ID in r0 and returns stack top in r0 ENTRY(psci_get_cpu_stack_top) - mov r5, #0x400 @ 1kB of stack per CPU - mul r0, r0, r5 - + @ Align psci_text_end minumum page size. Even if page is greater than + @ 4K, we still can ensure that data is always safe access by the CPU. ldr r5, =psci_text_end @ end of monitor text - add r5, r5, #0x2000 @ Skip two pages - lsr r5, r5, #12 @ Align to start of page + @ Detect page border + lsl r4, r5, #20 + cmp r4, #0 + beq out_psci_stack_align + add r5, r5, #PSCI_STACK_ALIGN_SIZE + lsr r5, r5, #12 lsl r5, r5, #12 - sub r5, r5, #4 @ reserve 1 word for target PC - sub r0, r5, r0 @ here's our stack! + +out_psci_stack_align: + mov r4, #PSCI_PERCPU_STACK_SIZE + add r0, r0, #1 + mul r0, r0, r4 + add r0, r0, r5
bx lr ENDPROC(psci_get_cpu_stack_top)
+@ Save space in percpu stack tail. +@ expects CPU ID in r0 and returns save space address in r0. +ENTRY(psci_get_cpu_save_space) + mov r10, lr + + bl psci_get_cpu_stack_top + sub r0, r0, #PSCI_PERCPU_STACK_SIZE + + bx r10 +ENDPROC(psci_get_cpu_save_space) + +@ Expects cpu ID in r0 and PC in r2, please ignore the return value. +ENTRY(psci_save_target_pc) + push {lr} + + @ Save target PC into stack + bl psci_get_cpu_save_space + str r2, [r0, #SAVE_SPACE_TARGET_PC_OFFSET] + dsb + + pop {lr} + bx lr +ENDPROC(psci_save_target_pc) + ENTRY(psci_cpu_entry) bl psci_enable_smp
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_cpu_save_space + ldr r0, [r0, #SAVE_SPACE_TARGET_PC_OFFSET] b _do_nonsec_entry ENDPROC(psci_cpu_entry)
diff --git a/arch/arm/cpu/armv7/sunxi/psci_sun6i.S b/arch/arm/cpu/armv7/sunxi/psci_sun6i.S index b96c5ef..e8981af 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_sun6i.S +++ b/arch/arm/cpu/armv7/sunxi/psci_sun6i.S @@ -135,9 +135,7 @@ psci_cpu_on: push {lr}
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 + bl psci_save_target_pc
movw r0, #(SUN6I_CPUCFG_BASE & 0xffff) movt r0, #(SUN6I_CPUCFG_BASE >> 16) diff --git a/arch/arm/cpu/armv7/sunxi/psci_sun7i.S b/arch/arm/cpu/armv7/sunxi/psci_sun7i.S index 59d7ff0..a1fcc71 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_sun7i.S +++ b/arch/arm/cpu/armv7/sunxi/psci_sun7i.S @@ -124,9 +124,7 @@ psci_cpu_on: push {lr}
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 + bl psci_save_target_pc
movw r0, #(SUN7I_CPUCFG_BASE & 0xffff) movt r0, #(SUN7I_CPUCFG_BASE >> 16) diff --git a/arch/arm/cpu/armv7/virt-dt.c b/arch/arm/cpu/armv7/virt-dt.c index f1251d1..5ca353c 100644 --- a/arch/arm/cpu/armv7/virt-dt.c +++ b/arch/arm/cpu/armv7/virt-dt.c @@ -126,7 +126,8 @@ int psci_update_dt(void *fdt) #ifndef CONFIG_ARMV7_SECURE_BASE /* secure code lives in RAM, keep it alive */ fdt_add_mem_rsv(fdt, (unsigned long)__secure_start, - __secure_end - __secure_start); + __secure_end + CONFIG_MAX_CPUS * PSCI_PERCPU_STACK_SIZE + + PSCI_STACK_ALIGN_SIZE - __secure_start); #endif
return fdt_psci(fdt); diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index f7b8f65..274dbda 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -18,6 +18,10 @@ #ifndef __ARM_PSCI_H__ #define __ARM_PSCI_H__
+#define PSCI_STACK_ALIGN_SIZE 0x1000 + +/* 1kB for percpu stack */ +#define PSCI_PERCPU_STACK_SIZE 0x400
#define PSCI_FN_BASE 0x84000000 #define PSCI_FN_ID(n) (PSCI_FN_BASE + (n)) diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S index 5f326c9..e83566e 100644 --- a/arch/arm/mach-tegra/psci.S +++ b/arch/arm/mach-tegra/psci.S @@ -91,9 +91,7 @@ ENTRY(psci_cpu_on) push {lr}
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 + bl psci_save_target_pc
ldr r6, =TEGRA_RESET_EXCEPTION_VECTOR ldr r5, =psci_cpu_entry

Add Hongbo.
Thanks, Chenhui
________________________________________ From: Dongsheng Wang dongsheng.wang@nxp.com Sent: Monday, January 18, 2016 12:27 PM To: albert.u.boot@aribaud.net Cc: trini@konsulko.com; sbabic@denx.de; ijc@hellion.org.uk; hdegoede@redhat.com; twarren@nvidia.com; Huan Wang; york sun; jan.kiszka@siemens.com; Frank Li; Peng Fan; Zhengxiong Jin; Chenhui Zhao; oss@buserror.net; u-boot@lists.denx.de; Dongsheng Wang Subject: [PATCH 3/9] ARM: ARMv7: PSCI: move target PC in each CPU stack no longer is shared
From: Wang Dongsheng dongsheng.wang@nxp.com
All of cpu share the same targetPC space that is unsafe. So move target PC save space into CPU stack.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com --- arch/arm/cpu/armv7/ls102xa/psci.S | 4 +-- arch/arm/cpu/armv7/mx7/psci.S | 4 +-- arch/arm/cpu/armv7/psci.S | 51 ++++++++++++++++++++++++++++------- arch/arm/cpu/armv7/sunxi/psci_sun6i.S | 4 +-- arch/arm/cpu/armv7/sunxi/psci_sun7i.S | 4 +-- arch/arm/cpu/armv7/virt-dt.c | 3 ++- arch/arm/include/asm/psci.h | 4 +++ arch/arm/mach-tegra/psci.S | 4 +-- 8 files changed, 53 insertions(+), 25 deletions(-)
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 0b067d9..3a34064 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -36,9 +36,7 @@ psci_cpu_on: and r1, r1, #0xff
mov r0, r1 - bl psci_get_cpu_stack_top - str r2, [r0] - dsb + bl psci_save_target_pc
@ Get DCFG base address movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff) diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S index 34c6ab3..cb39f27 100644 --- a/arch/arm/cpu/armv7/mx7/psci.S +++ b/arch/arm/cpu/armv7/mx7/psci.S @@ -30,9 +30,7 @@ psci_cpu_on: push {lr}
mov r0, r1 - bl psci_get_cpu_stack_top - str r2, [r0] - dsb + bl psci_save_target_pc
ldr r2, =psci_cpu_entry bl imx_cpu_on diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index 2425f6a..0e0f98e 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -20,6 +20,8 @@ #include <asm/macro.h> #include <asm/psci.h>
+#define SAVE_SPACE_TARGET_PC_OFFSET 0x0 + .pushsection ._secure.text, "ax"
.arch_extension sec @@ -196,27 +198,58 @@ ENDPROC(psci_cpu_off_common)
@ expects CPU ID in r0 and returns stack top in r0 ENTRY(psci_get_cpu_stack_top) - mov r5, #0x400 @ 1kB of stack per CPU - mul r0, r0, r5 - + @ Align psci_text_end minumum page size. Even if page is greater than + @ 4K, we still can ensure that data is always safe access by the CPU. ldr r5, =psci_text_end @ end of monitor text - add r5, r5, #0x2000 @ Skip two pages - lsr r5, r5, #12 @ Align to start of page + @ Detect page border + lsl r4, r5, #20 + cmp r4, #0 + beq out_psci_stack_align + add r5, r5, #PSCI_STACK_ALIGN_SIZE + lsr r5, r5, #12 lsl r5, r5, #12 - sub r5, r5, #4 @ reserve 1 word for target PC - sub r0, r5, r0 @ here's our stack! + +out_psci_stack_align: + mov r4, #PSCI_PERCPU_STACK_SIZE + add r0, r0, #1 + mul r0, r0, r4 + add r0, r0, r5
bx lr ENDPROC(psci_get_cpu_stack_top)
+@ Save space in percpu stack tail. +@ expects CPU ID in r0 and returns save space address in r0. +ENTRY(psci_get_cpu_save_space) + mov r10, lr + + bl psci_get_cpu_stack_top + sub r0, r0, #PSCI_PERCPU_STACK_SIZE + + bx r10 +ENDPROC(psci_get_cpu_save_space) + +@ Expects cpu ID in r0 and PC in r2, please ignore the return value. +ENTRY(psci_save_target_pc) + push {lr} + + @ Save target PC into stack + bl psci_get_cpu_save_space + str r2, [r0, #SAVE_SPACE_TARGET_PC_OFFSET] + dsb + + pop {lr} + bx lr +ENDPROC(psci_save_target_pc) + ENTRY(psci_cpu_entry) bl psci_enable_smp
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_cpu_save_space + ldr r0, [r0, #SAVE_SPACE_TARGET_PC_OFFSET] b _do_nonsec_entry ENDPROC(psci_cpu_entry)
diff --git a/arch/arm/cpu/armv7/sunxi/psci_sun6i.S b/arch/arm/cpu/armv7/sunxi/psci_sun6i.S index b96c5ef..e8981af 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_sun6i.S +++ b/arch/arm/cpu/armv7/sunxi/psci_sun6i.S @@ -135,9 +135,7 @@ psci_cpu_on: push {lr}
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 + bl psci_save_target_pc
movw r0, #(SUN6I_CPUCFG_BASE & 0xffff) movt r0, #(SUN6I_CPUCFG_BASE >> 16) diff --git a/arch/arm/cpu/armv7/sunxi/psci_sun7i.S b/arch/arm/cpu/armv7/sunxi/psci_sun7i.S index 59d7ff0..a1fcc71 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_sun7i.S +++ b/arch/arm/cpu/armv7/sunxi/psci_sun7i.S @@ -124,9 +124,7 @@ psci_cpu_on: push {lr}
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 + bl psci_save_target_pc
movw r0, #(SUN7I_CPUCFG_BASE & 0xffff) movt r0, #(SUN7I_CPUCFG_BASE >> 16) diff --git a/arch/arm/cpu/armv7/virt-dt.c b/arch/arm/cpu/armv7/virt-dt.c index f1251d1..5ca353c 100644 --- a/arch/arm/cpu/armv7/virt-dt.c +++ b/arch/arm/cpu/armv7/virt-dt.c @@ -126,7 +126,8 @@ int psci_update_dt(void *fdt) #ifndef CONFIG_ARMV7_SECURE_BASE /* secure code lives in RAM, keep it alive */ fdt_add_mem_rsv(fdt, (unsigned long)__secure_start, - __secure_end - __secure_start); + __secure_end + CONFIG_MAX_CPUS * PSCI_PERCPU_STACK_SIZE + + PSCI_STACK_ALIGN_SIZE - __secure_start); #endif
return fdt_psci(fdt); diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index f7b8f65..274dbda 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -18,6 +18,10 @@ #ifndef __ARM_PSCI_H__ #define __ARM_PSCI_H__
+#define PSCI_STACK_ALIGN_SIZE 0x1000 + +/* 1kB for percpu stack */ +#define PSCI_PERCPU_STACK_SIZE 0x400
#define PSCI_FN_BASE 0x84000000 #define PSCI_FN_ID(n) (PSCI_FN_BASE + (n)) diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S index 5f326c9..e83566e 100644 --- a/arch/arm/mach-tegra/psci.S +++ b/arch/arm/mach-tegra/psci.S @@ -91,9 +91,7 @@ ENTRY(psci_cpu_on) push {lr}
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 + bl psci_save_target_pc
ldr r6, =TEGRA_RESET_EXCEPTION_VECTOR ldr r5, =psci_cpu_entry -- 2.1.0.27.g96db324

Hi Dongsheng,
-----Original Message----- From: Chenhui Zhao Sent: Wednesday, March 16, 2016 3:05 PM To: Hongbo Zhang hongbo.zhang@nxp.com Cc: trini@konsulko.com; sbabic@denx.de; ijc@hellion.org.uk; hdegoede@redhat.com; twarren@nvidia.com; Huan Wang alison.wang@nxp.com; york sun york.sun@nxp.com; jan.kiszka@siemens.com; Frank Li frank.li@nxp.com; Peng Fan peng.fan@nxp.com; Zhengxiong Jin jason.jin@nxp.com; oss@buserror.net; u-boot@lists.denx.de; albert.u.boot@aribaud.net Subject: Re: [PATCH 3/9] ARM: ARMv7: PSCI: move target PC in each CPU stack no longer is shared
Add Hongbo.
Thanks, Chenhui
From: Dongsheng Wang dongsheng.wang@nxp.com Sent: Monday, January 18, 2016 12:27 PM To: albert.u.boot@aribaud.net Cc: trini@konsulko.com; sbabic@denx.de; ijc@hellion.org.uk; hdegoede@redhat.com; twarren@nvidia.com; Huan Wang; york sun; jan.kiszka@siemens.com; Frank Li; Peng Fan; Zhengxiong Jin; Chenhui Zhao; oss@buserror.net; u-boot@lists.denx.de; Dongsheng Wang Subject: [PATCH 3/9] ARM: ARMv7: PSCI: move target PC in each CPU stack no longer is shared
From: Wang Dongsheng dongsheng.wang@nxp.com
All of cpu share the same targetPC space that is unsafe. So move target PC save space into CPU stack.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com
arch/arm/cpu/armv7/ls102xa/psci.S | 4 +-- arch/arm/cpu/armv7/mx7/psci.S | 4 +-- arch/arm/cpu/armv7/psci.S | 51 ++++++++++++++++++++++++++++----
arch/arm/cpu/armv7/sunxi/psci_sun6i.S | 4 +-- arch/arm/cpu/armv7/sunxi/psci_sun7i.S | 4 +-- arch/arm/cpu/armv7/virt-dt.c | 3 ++- arch/arm/include/asm/psci.h | 4 +++ arch/arm/mach-tegra/psci.S | 4 +-- 8 files changed, 53 insertions(+), 25 deletions(-)
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 0b067d9..3a34064 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -36,9 +36,7 @@ psci_cpu_on: and r1, r1, #0xff
mov r0, r1
bl psci_get_cpu_stack_top
str r2, [r0]
dsb
bl psci_save_target_pc @ Get DCFG base address movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S index 34c6ab3..cb39f27 100644 --- a/arch/arm/cpu/armv7/mx7/psci.S +++ b/arch/arm/cpu/armv7/mx7/psci.S @@ -30,9 +30,7 @@ psci_cpu_on: push {lr}
mov r0, r1
bl psci_get_cpu_stack_top
str r2, [r0]
dsb
bl psci_save_target_pc ldr r2, =psci_cpu_entry bl imx_cpu_on
diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index 2425f6a..0e0f98e 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -20,6 +20,8 @@ #include <asm/macro.h> #include <asm/psci.h>
+#define SAVE_SPACE_TARGET_PC_OFFSET 0x0
.pushsection ._secure.text, "ax" .arch_extension sec
@@ -196,27 +198,58 @@ ENDPROC(psci_cpu_off_common)
@ expects CPU ID in r0 and returns stack top in r0 ENTRY(psci_get_cpu_stack_top)
mov r5, #0x400 @ 1kB of stack per CPU
mul r0, r0, r5
@ Align psci_text_end minumum page size. Even if page is greater than
@ 4K, we still can ensure that data is always safe access by the CPU. ldr r5, =psci_text_end @ end of monitor text
add r5, r5, #0x2000 @ Skip two pages
lsr r5, r5, #12 @ Align to start of page
@ Detect page border
lsl r4, r5, #20
Why do you shift it 20 bits? I guess you wanted to shift 12 bits instead.
cmp r4, #0
beq out_psci_stack_align
add r5, r5, #PSCI_STACK_ALIGN_SIZE
lsr r5, r5, #12 lsl r5, r5, #12
sub r5, r5, #4 @ reserve 1 word for target PC
sub r0, r5, r0 @ here's our stack!
+out_psci_stack_align:
mov r4, #PSCI_PERCPU_STACK_SIZE
add r0, r0, #1
mul r0, r0, r4
add r0, r0, r5 bx lr
ENDPROC(psci_get_cpu_stack_top)
+@ Save space in percpu stack tail.
It is better to use term "reserve" here instead of "save"
+@ expects CPU ID in r0 and returns save space address in r0. +ENTRY(psci_get_cpu_save_space)
mov r10, lr
bl psci_get_cpu_stack_top
sub r0, r0, #PSCI_PERCPU_STACK_SIZE
(r0 - PSCI_PERCPU_STACK_SIZE ) is stack top of next CPU's stack. (r0 - PSCI_PERCPU_STACK_SIZE +1 ) is the stack tail you want, right?
bx r10
+ENDPROC(psci_get_cpu_save_space)
+@ Expects cpu ID in r0 and PC in r2, please ignore the return value. +ENTRY(psci_save_target_pc)
push {lr}
@ Save target PC into stack
bl psci_get_cpu_save_space
str r2, [r0, #SAVE_SPACE_TARGET_PC_OFFSET]
dsb
pop {lr}
bx lr
+ENDPROC(psci_save_target_pc)
ENTRY(psci_cpu_entry) bl psci_enable_smp
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_cpu_save_space
ldr r0, [r0, #SAVE_SPACE_TARGET_PC_OFFSET] b _do_nonsec_entry
ENDPROC(psci_cpu_entry)
diff --git a/arch/arm/cpu/armv7/sunxi/psci_sun6i.S b/arch/arm/cpu/armv7/sunxi/psci_sun6i.S index b96c5ef..e8981af 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_sun6i.S +++ b/arch/arm/cpu/armv7/sunxi/psci_sun6i.S @@ -135,9 +135,7 @@ psci_cpu_on: push {lr}
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
bl psci_save_target_pc movw r0, #(SUN6I_CPUCFG_BASE & 0xffff) movt r0, #(SUN6I_CPUCFG_BASE >> 16)
diff --git a/arch/arm/cpu/armv7/sunxi/psci_sun7i.S b/arch/arm/cpu/armv7/sunxi/psci_sun7i.S index 59d7ff0..a1fcc71 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_sun7i.S +++ b/arch/arm/cpu/armv7/sunxi/psci_sun7i.S @@ -124,9 +124,7 @@ psci_cpu_on: push {lr}
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
bl psci_save_target_pc movw r0, #(SUN7I_CPUCFG_BASE & 0xffff) movt r0, #(SUN7I_CPUCFG_BASE >> 16)
diff --git a/arch/arm/cpu/armv7/virt-dt.c b/arch/arm/cpu/armv7/virt-dt.c index f1251d1..5ca353c 100644 --- a/arch/arm/cpu/armv7/virt-dt.c +++ b/arch/arm/cpu/armv7/virt-dt.c @@ -126,7 +126,8 @@ int psci_update_dt(void *fdt) #ifndef CONFIG_ARMV7_SECURE_BASE /* secure code lives in RAM, keep it alive */ fdt_add_mem_rsv(fdt, (unsigned long)__secure_start,
__secure_end - __secure_start);
__secure_end + CONFIG_MAX_CPUS *
PSCI_PERCPU_STACK_SIZE
+ PSCI_STACK_ALIGN_SIZE - __secure_start);
#endif
return fdt_psci(fdt);
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index f7b8f65..274dbda 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -18,6 +18,10 @@ #ifndef __ARM_PSCI_H__ #define __ARM_PSCI_H__
+#define PSCI_STACK_ALIGN_SIZE 0x1000
+/* 1kB for percpu stack */ +#define PSCI_PERCPU_STACK_SIZE 0x400
#define PSCI_FN_BASE 0x84000000 #define PSCI_FN_ID(n) (PSCI_FN_BASE + (n)) diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S index 5f326c9..e83566e 100644 --- a/arch/arm/mach-tegra/psci.S +++ b/arch/arm/mach-tegra/psci.S @@ -91,9 +91,7 @@ ENTRY(psci_cpu_on) push {lr}
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
bl psci_save_target_pc ldr r6, =TEGRA_RESET_EXCEPTION_VECTOR ldr r5, =psci_cpu_entry
-- 2.1.0.27.g96db324

From: Wang Dongsheng dongsheng.wang@nxp.com
Move save target PC codes to a common function.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com --- arch/arm/cpu/armv7/ls102xa/psci.S | 20 ++++++++---------- arch/arm/cpu/armv7/mx7/psci.S | 3 --- arch/arm/cpu/armv7/psci.S | 39 ++++++++++++++++++++++++++++++++--- arch/arm/cpu/armv7/sunxi/psci_sun6i.S | 7 +------ arch/arm/cpu/armv7/sunxi/psci_sun7i.S | 7 +------ arch/arm/mach-tegra/psci.S | 7 +------ 6 files changed, 48 insertions(+), 35 deletions(-)
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 3a34064..461b785 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -25,19 +25,19 @@ #define ONE_MS (GENERIC_TIMER_CLK / 1000) #define RESET_WAIT (30 * ONE_MS)
- @ r1 = target CPU - @ r2 = target PC -.globl psci_cpu_on -psci_cpu_on: - push {lr} - +@ Expect target CPU in r1, return the target cpu number in R0 +.globl psci_get_target_cpu_id +psci_get_target_cpu_id: @ Clear and Get the correct CPU number - @ r1 = 0xf01 and r1, r1, #0xff - mov r0, r1 - bl psci_save_target_pc
+ bx lr + + @ r1 = target CPU + @ r2 = target PC +.globl psci_cpu_on +psci_cpu_on: @ Get DCFG base address movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff) movt r4, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16) @@ -98,8 +98,6 @@ holdoff_release:
@ Return mov r0, #PSCI_RET_SUCCESS - - pop {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 cb39f27..716c7ae 100644 --- a/arch/arm/cpu/armv7/mx7/psci.S +++ b/arch/arm/cpu/armv7/mx7/psci.S @@ -29,9 +29,6 @@ psci_arch_init: psci_cpu_on: push {lr}
- mov r0, r1 - bl psci_save_target_pc - ldr r2, =psci_cpu_entry bl imx_cpu_on
diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index 0e0f98e..c3651bd 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -69,7 +69,7 @@ _psci_table: .word PSCI_FN_CPU_OFF .word psci_cpu_off .word PSCI_FN_CPU_ON - .word psci_cpu_on + .word psci_cpu_on_common .word PSCI_FN_MIGRATE .word psci_migrate .word 0 @@ -177,6 +177,40 @@ ENTRY(psci_enable_smp) ENDPROC(psci_enable_smp) .weak psci_enable_smp
+@ Expect target CPU in r1, return the target cpu number in r0. +@ If detect an error, please return #PSCI_RET_INVALID_PARAMS. +ENTRY(psci_get_target_cpu_id) + mov r0, r1 + bx lr +ENDPROC(psci_get_target_cpu_id) +.weak psci_get_target_cpu_id + + @ r1 = target CPU + @ r2 = target PC + @ r3 = target Conetxt ID +ENTRY(psci_cpu_on_common) + push {lr} + + bl psci_get_target_cpu_id + cmp r0, #PSCI_RET_INVALID_PARAMS + beq out_psci_cpu_on_common + + @ Update the target CPU ID, translation have been completed. + mov r1, r0 + + @ Save target PC into stack + bl psci_save_target_pc + + @ Still pass on: + @ r1 = target CPU + @ r2 = target PC + @ r3 = target Conetxt ID + bl psci_cpu_on + +out_psci_cpu_on_common: + pop {pc} +ENDPROC(psci_cpu_on_common) + ENTRY(psci_cpu_off_common) push {lr}
@@ -238,8 +272,7 @@ ENTRY(psci_save_target_pc) str r2, [r0, #SAVE_SPACE_TARGET_PC_OFFSET] dsb
- pop {lr} - bx lr + pop {pc} ENDPROC(psci_save_target_pc)
ENTRY(psci_cpu_entry) diff --git a/arch/arm/cpu/armv7/sunxi/psci_sun6i.S b/arch/arm/cpu/armv7/sunxi/psci_sun6i.S index e8981af..b64b012 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_sun6i.S +++ b/arch/arm/cpu/armv7/sunxi/psci_sun6i.S @@ -132,11 +132,6 @@ out: mcr p15, 0, r7, c1, c1, 0 @ r2 = target PC .globl psci_cpu_on psci_cpu_on: - push {lr} - - mov r0, r1 - bl psci_save_target_pc - movw r0, #(SUN6I_CPUCFG_BASE & 0xffff) movt r0, #(SUN6I_CPUCFG_BASE >> 16)
@@ -203,7 +198,7 @@ psci_cpu_on: str r6, [r0, #0x1e4]
mov r0, #PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS - pop {pc} + bx lr
.globl psci_cpu_off psci_cpu_off: diff --git a/arch/arm/cpu/armv7/sunxi/psci_sun7i.S b/arch/arm/cpu/armv7/sunxi/psci_sun7i.S index a1fcc71..ed867b8 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_sun7i.S +++ b/arch/arm/cpu/armv7/sunxi/psci_sun7i.S @@ -121,11 +121,6 @@ out: mcr p15, 0, r7, c1, c1, 0 @ r2 = target PC .globl psci_cpu_on psci_cpu_on: - push {lr} - - mov r0, r1 - bl psci_save_target_pc - movw r0, #(SUN7I_CPUCFG_BASE & 0xffff) movt r0, #(SUN7I_CPUCFG_BASE >> 16)
@@ -178,7 +173,7 @@ psci_cpu_on: str r6, [r0, #0x1e4]
mov r0, #PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS - pop {pc} + bx lr
.globl psci_cpu_off psci_cpu_off: diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S index e83566e..278c8ed 100644 --- a/arch/arm/mach-tegra/psci.S +++ b/arch/arm/mach-tegra/psci.S @@ -88,11 +88,6 @@ _loop: wfi ENDPROC(psci_cpu_off)
ENTRY(psci_cpu_on) - push {lr} - - mov r0, r1 - bl psci_save_target_pc - ldr r6, =TEGRA_RESET_EXCEPTION_VECTOR ldr r5, =psci_cpu_entry str r5, [r6] @@ -104,7 +99,7 @@ ENTRY(psci_cpu_on) str r5, [r6, r2]
mov r0, #PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS - pop {pc} + bx lr ENDPROC(psci_cpu_on)
.globl psci_text_end

From: Wang Dongsheng dongsheng.wang@nxp.com
To follow PSCI, we need to save a "Context ID" in CPU_ON, and pass it to a CPU when it first enters the OS.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com --- arch/arm/cpu/armv7/nonsec_virt.S | 4 ++++ arch/arm/cpu/armv7/psci.S | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+)
diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S index 31d1c9e..779f25d 100644 --- a/arch/arm/cpu/armv7/nonsec_virt.S +++ b/arch/arm/cpu/armv7/nonsec_virt.S @@ -89,6 +89,10 @@ _secure_monitor: movne r4, #0 mcrrne p15, 4, r4, r4, c14 @ Reset CNTVOFF to zero 1: +#ifdef CONFIG_ARMV7_PSCI + bl psci_get_cpu_id + bl psci_get_cpu_context_id @ Context ID must in R0 +#endif mov lr, ip mov ip, #(F_BIT | I_BIT | A_BIT) @ Set A, I and F tst lr, #1 @ Check for Thumb PC diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index c3651bd..a83fa67 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -21,6 +21,7 @@ #include <asm/psci.h>
#define SAVE_SPACE_TARGET_PC_OFFSET 0x0 +#define SAVE_SPACE_CONTEXT_ID_OFFSET 0x4
.pushsection ._secure.text, "ax"
@@ -201,6 +202,10 @@ ENTRY(psci_cpu_on_common) @ Save target PC into stack bl psci_save_target_pc
+ @ Save target context into stack + mov r0, r1 + bl psci_save_cpu_context_id + @ Still pass on: @ r1 = target CPU @ r2 = target PC @@ -275,6 +280,29 @@ ENTRY(psci_save_target_pc) pop {pc} ENDPROC(psci_save_target_pc)
+@ Expects cpu ID in r0 and context ID in r3, please ignore the return value. +ENTRY(psci_save_cpu_context_id) + push {lr} + + @ Save context id + bl psci_get_cpu_save_space + str r3, [r0, #SAVE_SPACE_CONTEXT_ID_OFFSET] + dsb + + pop {pc} +ENDPROC(psci_save_cpu_context_id) + +@ Expect cpu ID in r0, return context ID in r0. +ENTRY(psci_get_cpu_context_id) + push {lr} + + @ Get context id + bl psci_get_cpu_save_space + ldr r0, [r0, #SAVE_SPACE_CONTEXT_ID_OFFSET] + + pop {pc} +ENDPROC(psci_get_cpu_context_id) + ENTRY(psci_cpu_entry) bl psci_enable_smp

From: Wang Dongsheng dongsheng.wang@nxp.com
Add validation code to make sure target cpu ID is valid.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com --- arch/arm/cpu/armv7/ls102xa/psci.S | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 461b785..3091362 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -25,13 +25,34 @@ #define ONE_MS (GENERIC_TIMER_CLK / 1000) #define RESET_WAIT (30 * ONE_MS)
+#define AFFINITY_LEVEL_PROCESSOR_SHIFT 8 @ Expect target CPU in r1, return the target cpu number in R0 .globl psci_get_target_cpu_id psci_get_target_cpu_id: - @ Clear and Get the correct CPU number - and r1, r1, #0xff - mov r0, r1 + @ Get the CPU number + and r0, r1, #0xff
+ @ Verify bit[31:24], bits must be zero. + tst r1, #0xff000000 + bne out_psci_get_target_cpu_id + + @ Verify Affinity level 2: Cluster, only one cluster in LS1021xa SoC. + tst r1, #0xff0000 + bne out_psci_get_target_cpu_id + + @ Verify Affinity level 1: Processors, should in 0xf00 processor. + lsr r1, r1, #AFFINITY_LEVEL_PROCESSOR_SHIFT + teq r1, #0xf + bne out_psci_get_target_cpu_id + + @ Verify CPU, Affinity level 0: Only 0, 1 is effective value. + cmp r0, #2 + bge out_psci_get_target_cpu_id + + bx lr + +out_psci_get_target_cpu_id: + mov r0, #PSCI_RET_INVALID_PARAMS bx lr
@ r1 = target CPU

On Mon, 2016-01-18 at 12:27 +0800, Dongsheng Wang wrote:
From: Wang Dongsheng dongsheng.wang@nxp.com
Add validation code to make sure target cpu ID is valid.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com
arch/arm/cpu/armv7/ls102xa/psci.S | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 461b785..3091362 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -25,13 +25,34 @@ #define ONE_MS (GENERIC_TIMER_CLK / 1000) #define RESET_WAIT (30 * ONE_MS)
+#define AFFINITY_LEVEL_PROCESSOR_SHIFT 8 @ Expect target CPU in r1, return the target cpu number in R0 .globl psci_get_target_cpu_id psci_get_target_cpu_id:
- @ Clear and Get the correct CPU number
- and r1, r1, #0xff
- mov r0, r1
@ Get the CPU number
and r0, r1, #0xff
@ Verify bit[31:24], bits must be zero.
tst r1, #0xff000000
bne out_psci_get_target_cpu_id
@ Verify Affinity level 2: Cluster, only one cluster in LS1021xa
SoC.
- tst r1, #0xff0000
- bne out_psci_get_target_cpu_id
- @ Verify Affinity level 1: Processors, should in 0xf00 processor.
- lsr r1, r1, #AFFINITY_LEVEL_PROCESSOR_SHIFT
- teq r1, #0xf
- bne out_psci_get_target_cpu_id
- @ Verify CPU, Affinity level 0: Only 0, 1 is effective value.
- cmp r0, #2
- bge out_psci_get_target_cpu_id
- bx lr
+out_psci_get_target_cpu_id:
- mov r0, #PSCI_RET_INVALID_PARAMS bx lr
Where do you check for ALREADY_ON or ON_PENDING?
-Scott

Hi Scott,
On Mon, 2016-01-18 at 12:27 +0800, Dongsheng Wang wrote:
From: Wang Dongsheng dongsheng.wang@nxp.com
Add validation code to make sure target cpu ID is valid.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com
arch/arm/cpu/armv7/ls102xa/psci.S | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 461b785..3091362 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -25,13 +25,34 @@ #define ONE_MS (GENERIC_TIMER_CLK / 1000) #define RESET_WAIT (30 * ONE_MS)
+#define AFFINITY_LEVEL_PROCESSOR_SHIFT 8 @ Expect target CPU in r1, return the target cpu number in R0 .globl psci_get_target_cpu_id psci_get_target_cpu_id:
- @ Clear and Get the correct CPU number
- and r1, r1, #0xff
- mov r0, r1
@ Get the CPU number
and r0, r1, #0xff
@ Verify bit[31:24], bits must be zero.
tst r1, #0xff000000
bne out_psci_get_target_cpu_id
@ Verify Affinity level 2: Cluster, only one cluster in LS1021xa
SoC.
- tst r1, #0xff0000
- bne out_psci_get_target_cpu_id
- @ Verify Affinity level 1: Processors, should in 0xf00 processor.
- lsr r1, r1, #AFFINITY_LEVEL_PROCESSOR_SHIFT
- teq r1, #0xf
- bne out_psci_get_target_cpu_id
- @ Verify CPU, Affinity level 0: Only 0, 1 is effective value.
- cmp r0, #2
- bge out_psci_get_target_cpu_id
- bx lr
+out_psci_get_target_cpu_id:
- mov r0, #PSCI_RET_INVALID_PARAMS bx lr
Where do you check for ALREADY_ON or ON_PENDING?
Add them in next patch version.
Regards, -Dongsheng

From: Wang Dongsheng dongsheng.wang@nxp.com
Add the PSCI v1.0 API to U-Boot: PSCI_VERSION, AFFINITY_INFO, MIGRATE_INFO_TYPE, MIGRATE_INFO_UP_CPU, SYSTEM_OFF, SYSTEM_RESET, PSCI_FEATURES, SYSTEM_SUSPEND.
In order to be compatible with PSCI v0.1 version, introduce CONFIG_ARMV7_PSCI_GTE_1_0 macro to add the PSCI v1.0 compatible to the dtb.
U-Boot currently uses the "arm,psci" compatible, which means PSCI v0.1. PSCI v1.0 imposes additional requirements, so the "arm,psci-1.0" property will only be added if the platform defines CONFIG_ARMV7_PSCI_GTE_1_0."
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com --- arch/arm/cpu/armv7/psci.S | 36 +++++++++++++++++++++++++++++++++++ arch/arm/cpu/armv7/virt-dt.c | 45 +++++++++++++++++++++++++++++++++----------- arch/arm/include/asm/psci.h | 27 ++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 11 deletions(-)
diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index a83fa67..68304bf 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -53,8 +53,18 @@ ENTRY(psci_cpu_suspend) ENTRY(psci_cpu_off) ENTRY(psci_cpu_on) ENTRY(psci_migrate) +#ifdef CONFIG_ARMV7_PSCI_GTE_1_0 +ENTRY(psci_migrate_info_type) +ENTRY(psci_migrate_info_up_cpu) +ENTRY(psci_system_suspend) +#endif mov r0, #PSCI_RET_NOT_SUPPORTED @ Return -1 (Not Implemented) mov pc, lr +#ifdef CONFIG_ARMV7_PSCI_GTE_1_0 +ENDPROC(psci_system_suspend) +ENDPROC(psci_migrate_info_up_cpu) +ENDPROC(psci_migrate_info_type) +#endif ENDPROC(psci_migrate) ENDPROC(psci_cpu_on) ENDPROC(psci_cpu_off) @@ -63,8 +73,14 @@ ENDPROC(psci_cpu_suspend) .weak psci_cpu_off .weak psci_cpu_on .weak psci_migrate +#ifdef CONFIG_ARMV7_PSCI_GTE_1_0 +.weak psci_migrate_info_type +.weak psci_migrate_info_up_cpu +.weak psci_system_suspend +#endif
_psci_table: + /* PSCI v0.1 */ .word PSCI_FN_CPU_SUSPEND .word psci_cpu_suspend .word PSCI_FN_CPU_OFF @@ -73,6 +89,26 @@ _psci_table: .word psci_cpu_on_common .word PSCI_FN_MIGRATE .word psci_migrate +#ifdef CONFIG_ARMV7_PSCI_GTE_1_0 + /* PSCI v0.2 */ + .word PSCI_FN_PSCI_VERSION + .word psci_version + .word PSCI_FN_AFFINITY_INFO + .word psci_affinity_info + .word PSCI_FN_MIGRATE_INFO_TYPE + .word psci_migrate_info_type + .word PSCI_FN_MIGRATE_INFO_UP_CPU + .word psci_migrate_info_up_cpu + .word PSCI_FN_SYSTEM_OFF + .word psci_system_off + .word PSCI_FN_SYSTEM_RESET + .word psci_system_reset + /* PSCI v1.0 */ + .word PSCI_FN_PSCI_FEATURES + .word psci_features + .word PSCI_FN_SYSTEM_SUSPEND + .word psci_system_suspend +#endif .word 0 .word 0
diff --git a/arch/arm/cpu/armv7/virt-dt.c b/arch/arm/cpu/armv7/virt-dt.c index 5ca353c..2865169 100644 --- a/arch/arm/cpu/armv7/virt-dt.c +++ b/arch/arm/cpu/armv7/virt-dt.c @@ -26,6 +26,35 @@ #include <asm/armv7.h> #include <asm/psci.h>
+#ifdef CONFIG_ARMV7_PSCI +#ifdef CONFIG_ARMV7_PSCI_GTE_1_0 +static int fdt_psci_gte_1_0_fixup(void *fdt, int nodeoff) +{ + return fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci-1.0"); +} +#endif + +static int fdt_psci_0_1_fixup(void *fdt, int nodeoff) +{ + int ret; + + ret = fdt_appendprop_string(fdt, nodeoff, "compatible", "arm,psci"); + if (ret) + return ret; + ret = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", PSCI_FN_CPU_SUSPEND); + if (ret) + return ret; + ret = fdt_setprop_u32(fdt, nodeoff, "cpu_off", PSCI_FN_CPU_OFF); + if (ret) + return ret; + ret = fdt_setprop_u32(fdt, nodeoff, "cpu_on", PSCI_FN_CPU_ON); + if (ret) + return ret; + + return fdt_setprop_u32(fdt, nodeoff, "migrate", PSCI_FN_MIGRATE); +} +#endif + static int fdt_psci(void *fdt) { #ifdef CONFIG_ARMV7_PSCI @@ -67,22 +96,16 @@ static int fdt_psci(void *fdt) return nodeoff; }
- tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci"); - if (tmp) - return tmp; tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc"); if (tmp) return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", PSCI_FN_CPU_SUSPEND); - if (tmp) - return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", PSCI_FN_CPU_OFF); - if (tmp) - return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", PSCI_FN_CPU_ON); + +#ifdef CONFIG_ARMV7_PSCI_GTE_1_0 + tmp = fdt_psci_gte_1_0_fixup(fdt, nodeoff); if (tmp) return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", PSCI_FN_MIGRATE); +#endif + tmp = fdt_psci_0_1_fixup(fdt, nodeoff); if (tmp) return tmp; #endif diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index 274dbda..71cd193 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -32,14 +32,41 @@ #define PSCI_FN_CPU_ON PSCI_FN_ID(3) #define PSCI_FN_MIGRATE PSCI_FN_ID(5)
+/* PSCI v0.2 interface */ +#define PSCI_FN_PSCI_VERSION PSCI_FN_ID(0) +#define PSCI_FN_AFFINITY_INFO PSCI_FN_ID(4) +#define PSCI_FN_MIGRATE_INFO_TYPE PSCI_FN_ID(6) +#define PSCI_FN_MIGRATE_INFO_UP_CPU PSCI_FN_ID(7) +#define PSCI_FN_SYSTEM_OFF PSCI_FN_ID(8) +#define PSCI_FN_SYSTEM_RESET PSCI_FN_ID(9) + +/* PSCI v1.0 interface */ +#define PSCI_FN_PSCI_FEATURES PSCI_FN_ID(10) +#define PSCI_FN_SYSTEM_SUSPEND PSCI_FN_ID(14) + + +/* PSCI features decoding (>=1.0) */ +#define PSCI_FEATURES_CPU_SUSPEND_PF_MASK 0x2 +#define PSCI_FEATURES_CPU_SUSPEND_OSIM_MASK 0x1 + /* * Original from Linux kernel: include/uapi/linux/psci.h */ +/* PSCI v0.2 affinity level state returned by AFFINITY_INFO */ +#define PSCI_AFFINITY_LEVEL_ON 0 +#define PSCI_AFFINITY_LEVEL_OFF 1 +#define PSCI_AFFINITY_LEVEL_ON_PENDING 2 + /* PSCI return values (inclusive of all PSCI versions) */ #define PSCI_RET_SUCCESS 0 #define PSCI_RET_NOT_SUPPORTED (-1) #define PSCI_RET_INVALID_PARAMS (-2) #define PSCI_RET_DENIED (-3) +#define PSCI_RET_ALREADY_ON (-4) +#define PSCI_RET_ON_PENDING (-5) +#define PSCI_RET_INTERNAL_FAILURE (-6) +#define PSCI_RET_NOT_PRESENT (-7) +#define PSCI_RET_DISABLED (-8)
#ifndef __ASSEMBLY__ int psci_update_dt(void *fdt);

On Mon, 2016-01-18 at 12:27 +0800, Dongsheng Wang wrote:
+#ifdef CONFIG_ARMV7_PSCI_GTE_1_0
- tmp = fdt_psci_gte_1_0_fixup(fdt, nodeoff); if (tmp) return tmp;
- tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", PSCI_FN_MIGRATE);
+#endif
- tmp = fdt_psci_0_1_fixup(fdt, nodeoff);
The "gte" is needless verbosity and is inconsistent with "fdt_psci_0_1_fixup" which lacks it.
-Scott

Hi Scott,
Thanks for your review.
On Mon, 2016-01-18 at 12:27 +0800, Dongsheng Wang wrote:
+#ifdef CONFIG_ARMV7_PSCI_GTE_1_0
- tmp = fdt_psci_gte_1_0_fixup(fdt, nodeoff); if (tmp) return tmp;
- tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", PSCI_FN_MIGRATE);
+#endif
- tmp = fdt_psci_0_1_fixup(fdt, nodeoff);
The "gte" is needless verbosity and is inconsistent with "fdt_psci_0_1_fixup" which lacks it.
Yes, fdt_psci_1_0_fixup is better.
Another idea, maybe we should need to put the compatible fixup code into platform code. Because we cannot mandatory fix the compatible for all of platform, and If we support the follow-up version we don't need to put all of version into the compatible. The version used on platform should depend on platform code. We can provide a default version, but not mandatory for all of platform.
__weak int psci_compatible_fixup(void *fdt, int nodeoff) { ... ... }
static int fdt_psci(void *fdt) { ... ... psci_compatible_fixup(fdt, nodeoff); ... }
Regards, -Dongsheng

From: Wang Dongsheng dongsheng.wang@nxp.com
Based on PSCI v1.0, implement interface for ls102xa SoC: psci_version, psci_features, psci_cpu_suspend, psci_affinity_info, psci_system_reset, psci_system_off.
Tested on LS1021aQDS, LS1021aTWR.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com --- arch/arm/cpu/armv7/ls102xa/psci.S | 110 +++++++++++++++++++++++++++-- arch/arm/include/asm/arch-ls102xa/config.h | 1 + board/freescale/ls1021aqds/Makefile | 1 + board/freescale/ls1021aqds/psci.S | 36 ++++++++++ board/freescale/ls1021atwr/Makefile | 1 + board/freescale/ls1021atwr/psci.S | 28 ++++++++ include/configs/ls1021aqds.h | 3 + include/configs/ls1021atwr.h | 1 + 8 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 board/freescale/ls1021aqds/psci.S create mode 100644 board/freescale/ls1021atwr/psci.S
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 3091362..bfc908e 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -12,19 +12,72 @@ #include <asm/arch-armv7/generictimer.h> #include <asm/psci.h>
+#define RCPM_TWAITSR 0x04C + #define SCFG_CORE0_SFT_RST 0x130 #define SCFG_CORESRENCR 0x204
-#define DCFG_CCSR_BRR 0x0E4 -#define DCFG_CCSR_SCRATCHRW1 0x200 +#define DCFG_CCSR_RSTCR 0x0B0 +#define DCFG_CCSR_RSTCR_RESET_REQ 0x2 +#define DCFG_CCSR_BRR 0x0E4 +#define DCFG_CCSR_SCRATCHRW1 0x200 + +#define PSCI_FN_PSCI_VERSION_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_SUSPEND_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_OFF_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_ON_FEATURE_MASK 0x0 +#define PSCI_FN_AFFINITY_INFO_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_OFF_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_RESET_FEATURE_MASK 0x0
.pushsection ._secure.text, "ax"
.arch_extension sec
+ .align 5 + #define ONE_MS (GENERIC_TIMER_CLK / 1000) #define RESET_WAIT (30 * ONE_MS)
+.globl psci_version +psci_version: + movw r0, #0 + movt r0, #1 + + bx lr + +_ls102x_psci_supported_table: + .word PSCI_FN_PSCI_VERSION + .word PSCI_FN_PSCI_VERSION_FEATURE_MASK + .word PSCI_FN_CPU_SUSPEND + .word PSCI_FN_CPU_SUSPEND_FEATURE_MASK + .word PSCI_FN_CPU_OFF + .word PSCI_FN_CPU_OFF_FEATURE_MASK + .word PSCI_FN_CPU_ON + .word PSCI_FN_CPU_ON_FEATURE_MASK + .word PSCI_FN_AFFINITY_INFO + .word PSCI_FN_AFFINITY_INFO_FEATURE_MASK + .word PSCI_FN_SYSTEM_OFF + .word PSCI_FN_SYSTEM_OFF_FEATURE_MASK + .word PSCI_FN_SYSTEM_RESET + .word PSCI_FN_SYSTEM_RESET_FEATURE_MASK + .word 0 + .word PSCI_RET_NOT_SUPPORTED + +.globl psci_features +psci_features: + adr r2, _ls102x_psci_supported_table +1: ldr r3, [r2] + cmp r3, #0 + beq out_psci_features + cmp r1, r3 + addne r2, r2, #8 + bne 1b + +out_psci_features: + ldr r0, [r2, #4] + bx lr + #define AFFINITY_LEVEL_PROCESSOR_SHIFT 8 @ Expect target CPU in r1, return the target cpu number in R0 .globl psci_get_target_cpu_id @@ -128,6 +181,57 @@ psci_cpu_off: 1: wfi b 1b
+.globl psci_cpu_suspend +psci_cpu_suspend: + mov r0, #PSCI_RET_INVALID_PARAMS + bx lr + +.globl psci_affinity_info +psci_affinity_info: + push {lr} + + mov r0, #PSCI_RET_INVALID_PARAMS + + @ Verify Affinity level + cmp r2, #0 + bne out_affinity_info + + bl psci_get_target_cpu_id + cmp r0, #PSCI_RET_INVALID_PARAMS + beq out_affinity_info + mov r1, r0 + + @ Get RCPM base address + movw r4, #(CONFIG_SYS_FSL_RCPM_ADDR & 0xffff) + movt r4, #(CONFIG_SYS_FSL_RCPM_ADDR >> 16) + + mov r0, #PSCI_AFFINITY_LEVEL_ON + + @ Detect target CPU state + ldr r2, [r4, #RCPM_TWAITSR] + rev r2, r2 + lsr r2, r2, r1 + ands r2, r2, #1 + beq out_affinity_info + + mov r0, #PSCI_AFFINITY_LEVEL_OFF + +out_affinity_info: + pop {pc} + +.globl psci_system_reset +psci_system_reset: + @ Get DCFG base address + movw r1, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff) + movt r1, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16) + + mov r2, #DCFG_CCSR_RSTCR_RESET_REQ + rev r2, r2 + str r2, [r1, #DCFG_CCSR_RSTCR] + +1: wfi + b 1b + .globl psci_arch_init psci_arch_init: mov r6, lr @@ -138,6 +242,4 @@ psci_arch_init:
bx r6
- .globl psci_text_end -psci_text_end: .popsection diff --git a/arch/arm/include/asm/arch-ls102xa/config.h b/arch/arm/include/asm/arch-ls102xa/config.h index f066480..927c401 100644 --- a/arch/arm/include/asm/arch-ls102xa/config.h +++ b/arch/arm/include/asm/arch-ls102xa/config.h @@ -32,6 +32,7 @@ #define CONFIG_SYS_FSL_SERDES_ADDR (CONFIG_SYS_IMMR + 0x00ea0000) #define CONFIG_SYS_FSL_GUTS_ADDR (CONFIG_SYS_IMMR + 0x00ee0000) #define CONFIG_SYS_FSL_LS1_CLK_ADDR (CONFIG_SYS_IMMR + 0x00ee1000) +#define CONFIG_SYS_FSL_RCPM_ADDR (CONFIG_SYS_IMMR + 0x00ee2000) #define CONFIG_SYS_NS16550_COM1 (CONFIG_SYS_IMMR + 0x011c0500) #define CONFIG_SYS_NS16550_COM2 (CONFIG_SYS_IMMR + 0x011d0500) #define CONFIG_SYS_DCU_ADDR (CONFIG_SYS_IMMR + 0x01ce0000) diff --git a/board/freescale/ls1021aqds/Makefile b/board/freescale/ls1021aqds/Makefile index ab02344..f0390c1 100644 --- a/board/freescale/ls1021aqds/Makefile +++ b/board/freescale/ls1021aqds/Makefile @@ -8,3 +8,4 @@ obj-y += ls1021aqds.o obj-y += ddr.o obj-y += eth.o obj-$(CONFIG_FSL_DCU_FB) += dcu.o +obj-$(CONFIG_ARMV7_PSCI) += psci.o diff --git a/board/freescale/ls1021aqds/psci.S b/board/freescale/ls1021aqds/psci.S new file mode 100644 index 0000000..9201527 --- /dev/null +++ b/board/freescale/ls1021aqds/psci.S @@ -0,0 +1,36 @@ +/* + * Copyright 2015 NXP Semiconductor. + * Author: Wang Dongsheng dongsheng.wang@freescale.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <linux/linkage.h> + +#include <asm/armv7.h> +#include <asm/psci.h> + + .pushsection ._secure.text, "ax" + + .arch_extension sec + + .align 5 + +.globl psci_system_off +psci_system_off: + @ Get QIXIS base address + movw r1, #(QIXIS_BASE & 0xffff) + movt r1, #(QIXIS_BASE >> 16) + + ldrb r2, [r1, #QIXIS_PWR_CTL] + orr r2, r2, #QIXIS_PWR_CTL_POWEROFF + strb r2, [r1, #QIXIS_PWR_CTL] + +1: wfi + b 1b + +.globl psci_text_end +psci_text_end: + nop + .popsection diff --git a/board/freescale/ls1021atwr/Makefile b/board/freescale/ls1021atwr/Makefile index 01296c0..5238b15 100644 --- a/board/freescale/ls1021atwr/Makefile +++ b/board/freescale/ls1021atwr/Makefile @@ -6,3 +6,4 @@
obj-y += ls1021atwr.o obj-$(CONFIG_FSL_DCU_FB) += dcu.o +obj-$(CONFIG_ARMV7_PSCI) += psci.o diff --git a/board/freescale/ls1021atwr/psci.S b/board/freescale/ls1021atwr/psci.S new file mode 100644 index 0000000..03adea4 --- /dev/null +++ b/board/freescale/ls1021atwr/psci.S @@ -0,0 +1,28 @@ +/* + * Copyright 2015 NXP Semiconductor. + * Author: Wang Dongsheng dongsheng.wang@freescale.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <linux/linkage.h> + +#include <asm/armv7.h> +#include <asm/psci.h> + + .pushsection ._secure.text, "ax" + + .arch_extension sec + + .align 5 + +.globl psci_system_off +psci_system_off: +1: wfi + b 1b + +.globl psci_text_end +psci_text_end: + nop + .popsection diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h index 2e8dbc7..8574e78 100644 --- a/include/configs/ls1021aqds.h +++ b/include/configs/ls1021aqds.h @@ -10,6 +10,7 @@ #define CONFIG_LS102XA
#define CONFIG_ARMV7_PSCI +#define CONFIG_ARMV7_PSCI_GTE_1_0
#define CONFIG_SYS_FSL_CLK
@@ -270,6 +271,8 @@ unsigned long get_board_ddr_clk(void); #define QIXIS_LBMAP_SHIFT 0 #define QIXIS_LBMAP_DFLTBANK 0x00 #define QIXIS_LBMAP_ALTBANK 0x04 +#define QIXIS_PWR_CTL 0x21 +#define QIXIS_PWR_CTL_POWEROFF 0x80 #define QIXIS_RST_CTL_RESET 0x44 #define QIXIS_RCFG_CTL_RECONFIG_IDLE 0x20 #define QIXIS_RCFG_CTL_RECONFIG_START 0x21 diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h index c12ba3a..527a37a 100644 --- a/include/configs/ls1021atwr.h +++ b/include/configs/ls1021atwr.h @@ -10,6 +10,7 @@ #define CONFIG_LS102XA
#define CONFIG_ARMV7_PSCI +#define CONFIG_ARMV7_PSCI_GTE_1_0
#define CONFIG_SYS_FSL_CLK

On Mon, 2016-01-18 at 12:27 +0800, Dongsheng Wang wrote:
From: Wang Dongsheng dongsheng.wang@nxp.com
Based on PSCI v1.0, implement interface for ls102xa SoC: psci_version, psci_features, psci_cpu_suspend, psci_affinity_info, psci_system_reset, psci_system_off.
Tested on LS1021aQDS, LS1021aTWR.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com
arch/arm/cpu/armv7/ls102xa/psci.S | 110 +++++++++++++++++++++++++++-- arch/arm/include/asm/arch-ls102xa/config.h | 1 + board/freescale/ls1021aqds/Makefile | 1 + board/freescale/ls1021aqds/psci.S | 36 ++++++++++ board/freescale/ls1021atwr/Makefile | 1 + board/freescale/ls1021atwr/psci.S | 28 ++++++++ include/configs/ls1021aqds.h | 3 + include/configs/ls1021atwr.h | 1 + 8 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 board/freescale/ls1021aqds/psci.S create mode 100644 board/freescale/ls1021atwr/psci.S
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 3091362..bfc908e 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -12,19 +12,72 @@ #include <asm/arch-armv7/generictimer.h> #include <asm/psci.h>
+#define RCPM_TWAITSR 0x04C
#define SCFG_CORE0_SFT_RST 0x130 #define SCFG_CORESRENCR 0x204
-#define DCFG_CCSR_BRR 0x0E4 -#define DCFG_CCSR_SCRATCHRW1 0x200 +#define DCFG_CCSR_RSTCR 0x0B0 +#define DCFG_CCSR_RSTCR_RESET_REQ 0x2 +#define DCFG_CCSR_BRR 0x0E4 +#define DCFG_CCSR_SCRATCHRW1 0x200
+#define PSCI_FN_PSCI_VERSION_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_SUSPEND_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_OFF_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_ON_FEATURE_MASK 0x0 +#define PSCI_FN_AFFINITY_INFO_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_OFF_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_RESET_FEATURE_MASK 0x0
.pushsection ._secure.text, "ax"
.arch_extension sec
- .align 5
#define ONE_MS (GENERIC_TIMER_CLK / 1000) #define RESET_WAIT (30 * ONE_MS)
+.globl psci_version +psci_version:
- movw r0, #0
- movt r0, #1
- bx lr
+_ls102x_psci_supported_table:
- .word PSCI_FN_PSCI_VERSION
- .word PSCI_FN_PSCI_VERSION_FEATURE_MASK
- .word PSCI_FN_CPU_SUSPEND
- .word PSCI_FN_CPU_SUSPEND_FEATURE_MASK
- .word PSCI_FN_CPU_OFF
- .word PSCI_FN_CPU_OFF_FEATURE_MASK
- .word PSCI_FN_CPU_ON
- .word PSCI_FN_CPU_ON_FEATURE_MASK
- .word PSCI_FN_AFFINITY_INFO
- .word PSCI_FN_AFFINITY_INFO_FEATURE_MASK
- .word PSCI_FN_SYSTEM_OFF
- .word PSCI_FN_SYSTEM_OFF_FEATURE_MASK
- .word PSCI_FN_SYSTEM_RESET
- .word PSCI_FN_SYSTEM_RESET_FEATURE_MASK
- .word 0
- .word PSCI_RET_NOT_SUPPORTED
Can you use the main _psci_table instead of duplicating it?
+.globl psci_features +psci_features:
- adr r2, _ls102x_psci_supported_table
+1: ldr r3, [r2]
- cmp r3, #0
- beq out_psci_features
- cmp r1, r3
- addne r2, r2, #8
- bne 1b
Why are you adding 8 here?
+out_psci_features:
- ldr r0, [r2, #4]
- bx lr
If you find a match, you're supposed to return zero, not the next function id in the table.
How did you test this? There should really be a test suite for runtime services such as this, especially when trying to comply with a standard.
#define AFFINITY_LEVEL_PROCESSOR_SHIFT 8 @ Expect target CPU in r1, return the target cpu number in R0 .globl psci_get_target_cpu_id @@ -128,6 +181,57 @@ psci_cpu_off: 1: wfi b 1b
+.globl psci_cpu_suspend +psci_cpu_suspend:
- mov r0, #PSCI_RET_INVALID_PARAMS
- bx lr
+.globl psci_affinity_info +psci_affinity_info:
- push {lr}
- mov r0, #PSCI_RET_INVALID_PARAMS
- @ Verify Affinity level
- cmp r2, #0
- bne out_affinity_info
- bl psci_get_target_cpu_id
- cmp r0, #PSCI_RET_INVALID_PARAMS
- beq out_affinity_info
- mov r1, r0
- @ Get RCPM base address
- movw r4, #(CONFIG_SYS_FSL_RCPM_ADDR & 0xffff)
- movt r4, #(CONFIG_SYS_FSL_RCPM_ADDR >> 16)
- mov r0, #PSCI_AFFINITY_LEVEL_ON
- @ Detect target CPU state
- ldr r2, [r4, #RCPM_TWAITSR]
- rev r2, r2
- lsr r2, r2, r1
- ands r2, r2, #1
- beq out_affinity_info
- mov r0, #PSCI_AFFINITY_LEVEL_OFF
+out_affinity_info:
- pop {pc}
Where do you check for ON_PENDING?
-Scott

Hi Scott,
On Mon, 2016-01-18 at 12:27 +0800, Dongsheng Wang wrote:
From: Wang Dongsheng dongsheng.wang@nxp.com
Based on PSCI v1.0, implement interface for ls102xa SoC: psci_version, psci_features, psci_cpu_suspend, psci_affinity_info, psci_system_reset, psci_system_off.
Tested on LS1021aQDS, LS1021aTWR.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com
arch/arm/cpu/armv7/ls102xa/psci.S | 110 +++++++++++++++++++++++++++-- arch/arm/include/asm/arch-ls102xa/config.h | 1 + board/freescale/ls1021aqds/Makefile | 1 + board/freescale/ls1021aqds/psci.S | 36 ++++++++++ board/freescale/ls1021atwr/Makefile | 1 + board/freescale/ls1021atwr/psci.S | 28 ++++++++ include/configs/ls1021aqds.h | 3 + include/configs/ls1021atwr.h | 1 + 8 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 board/freescale/ls1021aqds/psci.S create mode 100644 board/freescale/ls1021atwr/psci.S
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 3091362..bfc908e 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -12,19 +12,72 @@ #include <asm/arch-armv7/generictimer.h> #include <asm/psci.h>
+#define RCPM_TWAITSR 0x04C
#define SCFG_CORE0_SFT_RST 0x130 #define SCFG_CORESRENCR 0x204
-#define DCFG_CCSR_BRR 0x0E4 -#define DCFG_CCSR_SCRATCHRW1 0x200 +#define DCFG_CCSR_RSTCR 0x0B0 +#define DCFG_CCSR_RSTCR_RESET_REQ 0x2 +#define DCFG_CCSR_BRR 0x0E4 +#define DCFG_CCSR_SCRATCHRW1 0x200
+#define PSCI_FN_PSCI_VERSION_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_SUSPEND_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_OFF_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_ON_FEATURE_MASK 0x0 +#define PSCI_FN_AFFINITY_INFO_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_OFF_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_RESET_FEATURE_MASK 0x0
.pushsection ._secure.text, "ax"
.arch_extension sec
- .align 5
#define ONE_MS (GENERIC_TIMER_CLK / 1000) #define RESET_WAIT (30 * ONE_MS)
+.globl psci_version +psci_version:
- movw r0, #0
- movt r0, #1
- bx lr
+_ls102x_psci_supported_table:
- .word PSCI_FN_PSCI_VERSION
- .word PSCI_FN_PSCI_VERSION_FEATURE_MASK
- .word PSCI_FN_CPU_SUSPEND
- .word PSCI_FN_CPU_SUSPEND_FEATURE_MASK
- .word PSCI_FN_CPU_OFF
- .word PSCI_FN_CPU_OFF_FEATURE_MASK
- .word PSCI_FN_CPU_ON
- .word PSCI_FN_CPU_ON_FEATURE_MASK
- .word PSCI_FN_AFFINITY_INFO
- .word PSCI_FN_AFFINITY_INFO_FEATURE_MASK
- .word PSCI_FN_SYSTEM_OFF
- .word PSCI_FN_SYSTEM_OFF_FEATURE_MASK
- .word PSCI_FN_SYSTEM_RESET
- .word PSCI_FN_SYSTEM_RESET_FEATURE_MASK
- .word 0
- .word PSCI_RET_NOT_SUPPORTED
Can you use the main _psci_table instead of duplicating it?
The main table does not apply here. Because this table shows what is supported in our platform. And this table also contains the sub-feature mask of PSCI functions.
+.globl psci_features +psci_features:
- adr r2, _ls102x_psci_supported_table
+1: ldr r3, [r2]
- cmp r3, #0
- beq out_psci_features
- cmp r1, r3
- addne r2, r2, #8
- bne 1b
Why are you adding 8 here?
+4 is the sub-feature mask of the PSCI function. So we need to +8 to jump to next PSCI function. .word PSCI_FN_PSCI_VERSION .word PSCI_FN_PSCI_VERSION_FEATURE_MASK
+out_psci_features:
- ldr r0, [r2, #4]
- bx lr
If you find a match, you're supposed to return zero, not the next function id in the table. How did you test this? There should really be a test suite for runtime services such as this, especially when trying to comply with a standard.
I think maybe you missed something about this code. The return value is PSCI_FN_PSCI_XXXXXX_FEATURE_MASK, not return next function ID.
#define AFFINITY_LEVEL_PROCESSOR_SHIFT 8 @ Expect target CPU in r1, return the target cpu number in R0 .globl psci_get_target_cpu_id @@ -128,6 +181,57 @@ psci_cpu_off: 1: wfi b 1b
+.globl psci_cpu_suspend +psci_cpu_suspend:
- mov r0, #PSCI_RET_INVALID_PARAMS
- bx lr
+.globl psci_affinity_info +psci_affinity_info:
- push {lr}
- mov r0, #PSCI_RET_INVALID_PARAMS
- @ Verify Affinity level
- cmp r2, #0
- bne out_affinity_info
- bl psci_get_target_cpu_id
- cmp r0, #PSCI_RET_INVALID_PARAMS
- beq out_affinity_info
- mov r1, r0
- @ Get RCPM base address
- movw r4, #(CONFIG_SYS_FSL_RCPM_ADDR & 0xffff)
- movt r4, #(CONFIG_SYS_FSL_RCPM_ADDR >> 16)
- mov r0, #PSCI_AFFINITY_LEVEL_ON
- @ Detect target CPU state
- ldr r2, [r4, #RCPM_TWAITSR]
- rev r2, r2
- lsr r2, r2, r1
- ands r2, r2, #1
- beq out_affinity_info
- mov r0, #PSCI_AFFINITY_LEVEL_OFF
+out_affinity_info:
- pop {pc}
Where do you check for ON_PENDING?
Add ON_PENDING in next patch version.
Regards, -Dongsheng

On Tue, 2016-01-19 at 06:28 +0000, Dongsheng Wang wrote:
Hi Scott,
On Mon, 2016-01-18 at 12:27 +0800, Dongsheng Wang wrote:
From: Wang Dongsheng dongsheng.wang@nxp.com
Based on PSCI v1.0, implement interface for ls102xa SoC: psci_version, psci_features, psci_cpu_suspend, psci_affinity_info, psci_system_reset, psci_system_off.
Tested on LS1021aQDS, LS1021aTWR.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com
arch/arm/cpu/armv7/ls102xa/psci.S | 110 +++++++++++++++++++++++++++-- arch/arm/include/asm/arch-ls102xa/config.h | 1 + board/freescale/ls1021aqds/Makefile | 1 + board/freescale/ls1021aqds/psci.S | 36 ++++++++++ board/freescale/ls1021atwr/Makefile | 1 + board/freescale/ls1021atwr/psci.S | 28 ++++++++ include/configs/ls1021aqds.h | 3 + include/configs/ls1021atwr.h | 1 + 8 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 board/freescale/ls1021aqds/psci.S create mode 100644 board/freescale/ls1021atwr/psci.S
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 3091362..bfc908e 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -12,19 +12,72 @@ #include <asm/arch-armv7/generictimer.h> #include <asm/psci.h>
+#define RCPM_TWAITSR 0x04C
#define SCFG_CORE0_SFT_RST 0x130 #define SCFG_CORESRENCR 0x204
-#define DCFG_CCSR_BRR 0x0E4 -#define DCFG_CCSR_SCRATCHRW1 0x200 +#define DCFG_CCSR_RSTCR 0x0B0 +#define DCFG_CCSR_RSTCR_RESET_REQ 0x2 +#define DCFG_CCSR_BRR 0x0E4 +#define DCFG_CCSR_SCRATCHRW1 0x200
+#define PSCI_FN_PSCI_VERSION_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_SUSPEND_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_OFF_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_ON_FEATURE_MASK 0x0 +#define PSCI_FN_AFFINITY_INFO_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_OFF_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_RESET_FEATURE_MASK 0x0
.pushsection ._secure.text, "ax"
.arch_extension sec
- .align 5
#define ONE_MS (GENERIC_TIMER_CLK / 1000) #define RESET_WAIT (30 * ONE_MS)
+.globl psci_version +psci_version:
- movw r0, #0
- movt r0, #1
- bx lr
+_ls102x_psci_supported_table:
- .word PSCI_FN_PSCI_VERSION
- .word PSCI_FN_PSCI_VERSION_FEATURE_MASK
- .word PSCI_FN_CPU_SUSPEND
- .word PSCI_FN_CPU_SUSPEND_FEATURE_MASK
- .word PSCI_FN_CPU_OFF
- .word PSCI_FN_CPU_OFF_FEATURE_MASK
- .word PSCI_FN_CPU_ON
- .word PSCI_FN_CPU_ON_FEATURE_MASK
- .word PSCI_FN_AFFINITY_INFO
- .word PSCI_FN_AFFINITY_INFO_FEATURE_MASK
- .word PSCI_FN_SYSTEM_OFF
- .word PSCI_FN_SYSTEM_OFF_FEATURE_MASK
- .word PSCI_FN_SYSTEM_RESET
- .word PSCI_FN_SYSTEM_RESET_FEATURE_MASK
- .word 0
- .word PSCI_RET_NOT_SUPPORTED
Can you use the main _psci_table instead of duplicating it?
The main table does not apply here. Because this table shows what is supported in our platform.
How does that set differ from what's in the main table?
And this table also contains the sub-feature mask of PSCI functions.
...which is always zero. As of PSCI 1.0 there's only one function that supports subfeatures, and you could put an explicit check in for that if it ever needs a non-zero value.
+.globl psci_features +psci_features:
- adr r2, _ls102x_psci_supported_table
+1: ldr r3, [r2]
- cmp r3, #0
- beq out_psci_features
- cmp r1, r3
- addne r2, r2, #8
- bne 1b
Why are you adding 8 here?
+4 is the sub-feature mask of the PSCI function. So we need to +8 to jump to next PSCI function. .word PSCI_FN_PSCI_VERSION .word PSCI_FN_PSCI_VERSION_FEATURE_MASK
+out_psci_features:
- ldr r0, [r2, #4]
- bx lr
If you find a match, you're supposed to return zero, not the next function id in the table. How did you test this? There should really be a test suite for runtime services such as this, especially when trying to comply with a standard.
I think maybe you missed something about this code. The return value is PSCI_FN_PSCI_XXXXXX_FEATURE_MASK, not return next function ID.
Yes, I misread the table and missed the masks. But see above about them being unnecessary.
In any case, a test suite would be very helpful.
-Scott

Hi Scott,
Thanks for your review.
On Tue, 2016-01-19 at 06:28 +0000, Dongsheng Wang wrote:
Hi Scott,
On Mon, 2016-01-18 at 12:27 +0800, Dongsheng Wang wrote:
From: Wang Dongsheng dongsheng.wang@nxp.com
Based on PSCI v1.0, implement interface for ls102xa SoC: psci_version, psci_features, psci_cpu_suspend, psci_affinity_info, psci_system_reset, psci_system_off.
Tested on LS1021aQDS, LS1021aTWR.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com
arch/arm/cpu/armv7/ls102xa/psci.S | 110 +++++++++++++++++++++++++++-- arch/arm/include/asm/arch-ls102xa/config.h | 1 + board/freescale/ls1021aqds/Makefile | 1 + board/freescale/ls1021aqds/psci.S | 36 ++++++++++ board/freescale/ls1021atwr/Makefile | 1 + board/freescale/ls1021atwr/psci.S | 28 ++++++++ include/configs/ls1021aqds.h | 3 + include/configs/ls1021atwr.h | 1 + 8 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 board/freescale/ls1021aqds/psci.S create mode 100644 board/freescale/ls1021atwr/psci.S
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 3091362..bfc908e 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -12,19 +12,72 @@ #include <asm/arch-armv7/generictimer.h> #include <asm/psci.h>
+#define RCPM_TWAITSR 0x04C
#define SCFG_CORE0_SFT_RST 0x130 #define SCFG_CORESRENCR 0x204
-#define DCFG_CCSR_BRR 0x0E4 -#define DCFG_CCSR_SCRATCHRW1 0x200 +#define DCFG_CCSR_RSTCR 0x0B0 +#define DCFG_CCSR_RSTCR_RESET_REQ 0x2 +#define DCFG_CCSR_BRR 0x0E4 +#define DCFG_CCSR_SCRATCHRW1 0x200
+#define PSCI_FN_PSCI_VERSION_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_SUSPEND_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_OFF_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_ON_FEATURE_MASK 0x0 +#define PSCI_FN_AFFINITY_INFO_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_OFF_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_RESET_FEATURE_MASK 0x0
.pushsection ._secure.text, "ax"
.arch_extension sec
- .align 5
#define ONE_MS (GENERIC_TIMER_CLK / 1000) #define RESET_WAIT (30 * ONE_MS)
+.globl psci_version +psci_version:
- movw r0, #0
- movt r0, #1
- bx lr
+_ls102x_psci_supported_table:
- .word PSCI_FN_PSCI_VERSION
- .word PSCI_FN_PSCI_VERSION_FEATURE_MASK
- .word PSCI_FN_CPU_SUSPEND
- .word PSCI_FN_CPU_SUSPEND_FEATURE_MASK
- .word PSCI_FN_CPU_OFF
- .word PSCI_FN_CPU_OFF_FEATURE_MASK
- .word PSCI_FN_CPU_ON
- .word PSCI_FN_CPU_ON_FEATURE_MASK
- .word PSCI_FN_AFFINITY_INFO
- .word PSCI_FN_AFFINITY_INFO_FEATURE_MASK
- .word PSCI_FN_SYSTEM_OFF
- .word PSCI_FN_SYSTEM_OFF_FEATURE_MASK
- .word PSCI_FN_SYSTEM_RESET
- .word PSCI_FN_SYSTEM_RESET_FEATURE_MASK
- .word 0
- .word PSCI_RET_NOT_SUPPORTED
Can you use the main _psci_table instead of duplicating it?
The main table does not apply here. Because this table shows what is supported in our platform.
How does that set differ from what's in the main table?
The main table include all of functions about PSCI spec. If we use main table to match the pass in parameter, it will always return SUPPORT.
This table just we supported table, if the parameter not matched in this table it will finally return NOT_SUPPORTED.
The main table include in functions ID and function handle, not match this feature return value, we not need to get the functions handler, just need to return sub-feature, and this table will return sub-feature if the PSCI ID be matched.
And this table also contains the sub-feature mask of PSCI functions.
...which is always zero. As of PSCI 1.0 there's only one function that supports subfeatures, and you could put an explicit check in for that if it ever needs a non-zero value.
Yes, for now there is only one function that supports sub-features. But this table is easy to extend, even if PSCI defines some other sub-features we just need to take care this table, and not need to modify the code logic. :)
+.globl psci_features +psci_features:
- adr r2, _ls102x_psci_supported_table
+1: ldr r3, [r2]
- cmp r3, #0
- beq out_psci_features
- cmp r1, r3
- addne r2, r2, #8
- bne 1b
Why are you adding 8 here?
+4 is the sub-feature mask of the PSCI function. So we need to +8 to +jump to next PSCI function. .word PSCI_FN_PSCI_VERSION .word PSCI_FN_PSCI_VERSION_FEATURE_MASK
+out_psci_features:
- ldr r0, [r2, #4]
- bx lr
If you find a match, you're supposed to return zero, not the next function id in the table. How did you test this? There should really be a test suite for runtime services such as this, especially when trying to comply with a standard.
I think maybe you missed something about this code. The return value is PSCI_FN_PSCI_XXXXXX_FEATURE_MASK, not return next function ID.
Yes, I misread the table and missed the masks. But see above about them being unnecessary.
In any case, a test suite would be very helpful.
Yes, thanks for your friendly reminder. And this table has tested on ls1021 platform. :)
Regards, -Dongsheng

+Zhang Hongbo.
Hi Scott,
Thanks for your review.
On Tue, 2016-01-19 at 06:28 +0000, Dongsheng Wang wrote:
Hi Scott,
On Mon, 2016-01-18 at 12:27 +0800, Dongsheng Wang wrote:
From: Wang Dongsheng dongsheng.wang@nxp.com
Based on PSCI v1.0, implement interface for ls102xa SoC: psci_version, psci_features, psci_cpu_suspend, psci_affinity_info, psci_system_reset, psci_system_off.
Tested on LS1021aQDS, LS1021aTWR.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com
arch/arm/cpu/armv7/ls102xa/psci.S | 110 +++++++++++++++++++++++++++-- arch/arm/include/asm/arch-ls102xa/config.h | 1 + board/freescale/ls1021aqds/Makefile | 1 + board/freescale/ls1021aqds/psci.S | 36 ++++++++++ board/freescale/ls1021atwr/Makefile | 1 + board/freescale/ls1021atwr/psci.S | 28 ++++++++ include/configs/ls1021aqds.h | 3 + include/configs/ls1021atwr.h | 1 + 8 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 board/freescale/ls1021aqds/psci.S create mode 100644 board/freescale/ls1021atwr/psci.S
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 3091362..bfc908e 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -12,19 +12,72 @@ #include <asm/arch-armv7/generictimer.h> #include <asm/psci.h>
+#define RCPM_TWAITSR 0x04C
#define SCFG_CORE0_SFT_RST 0x130 #define SCFG_CORESRENCR 0x204
-#define DCFG_CCSR_BRR 0x0E4 -#define DCFG_CCSR_SCRATCHRW1 0x200 +#define DCFG_CCSR_RSTCR 0x0B0 +#define DCFG_CCSR_RSTCR_RESET_REQ 0x2 +#define DCFG_CCSR_BRR 0x0E4 +#define DCFG_CCSR_SCRATCHRW1 0x200
+#define PSCI_FN_PSCI_VERSION_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_SUSPEND_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_OFF_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_ON_FEATURE_MASK 0x0 +#define PSCI_FN_AFFINITY_INFO_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_OFF_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_RESET_FEATURE_MASK 0x0
.pushsection ._secure.text, "ax"
.arch_extension sec
- .align 5
#define ONE_MS (GENERIC_TIMER_CLK / 1000) #define RESET_WAIT (30 * ONE_MS)
+.globl psci_version +psci_version:
- movw r0, #0
- movt r0, #1
- bx lr
+_ls102x_psci_supported_table:
- .word PSCI_FN_PSCI_VERSION
- .word PSCI_FN_PSCI_VERSION_FEATURE_MASK
- .word PSCI_FN_CPU_SUSPEND
- .word PSCI_FN_CPU_SUSPEND_FEATURE_MASK
- .word PSCI_FN_CPU_OFF
- .word PSCI_FN_CPU_OFF_FEATURE_MASK
- .word PSCI_FN_CPU_ON
- .word PSCI_FN_CPU_ON_FEATURE_MASK
- .word PSCI_FN_AFFINITY_INFO
- .word PSCI_FN_AFFINITY_INFO_FEATURE_MASK
- .word PSCI_FN_SYSTEM_OFF
- .word PSCI_FN_SYSTEM_OFF_FEATURE_MASK
- .word PSCI_FN_SYSTEM_RESET
- .word PSCI_FN_SYSTEM_RESET_FEATURE_MASK
- .word 0
- .word PSCI_RET_NOT_SUPPORTED
Can you use the main _psci_table instead of duplicating it?
The main table does not apply here. Because this table shows what is supported in our platform.
How does that set differ from what's in the main table?
The main table include all of functions about PSCI spec. If we use main table to match the pass in parameter, it will always return SUPPORT.
This table just we supported table, if the parameter not matched in this table it will finally return NOT_SUPPORTED.
The main table include in functions ID and function handle, not match this feature return value, we not need to get the functions handler, just need to return sub-feature, and this table will return sub-feature if the PSCI ID be matched.
And this table also contains the sub-feature mask of PSCI functions.
...which is always zero. As of PSCI 1.0 there's only one function that supports subfeatures, and you could put an explicit check in for that if it ever needs a non-zero value.
Yes, for now there is only one function that supports sub-features. But this table is easy to extend, even if PSCI defines some other sub-features we just need to take care this table, and not need to modify the code logic. :)
+.globl psci_features +psci_features:
- adr r2, _ls102x_psci_supported_table
+1: ldr r3, [r2]
- cmp r3, #0
- beq out_psci_features
- cmp r1, r3
- addne r2, r2, #8
- bne 1b
Why are you adding 8 here?
+4 is the sub-feature mask of the PSCI function. So we need to +8 to +jump to next PSCI function. .word PSCI_FN_PSCI_VERSION .word PSCI_FN_PSCI_VERSION_FEATURE_MASK
+out_psci_features:
- ldr r0, [r2, #4]
- bx lr
If you find a match, you're supposed to return zero, not the next function id in the table. How did you test this? There should really be a test suite for runtime services such as this, especially when trying to comply with a standard.
I think maybe you missed something about this code. The return value is PSCI_FN_PSCI_XXXXXX_FEATURE_MASK, not return next function ID.
Yes, I misread the table and missed the masks. But see above about them being unnecessary.
In any case, a test suite would be very helpful.
Yes, thanks for your friendly reminder. And this table has tested on ls1021 platform. :)
Regards, -Dongsheng

From: Wang Dongsheng dongsheng.wang@nxp.com
LS1021 support two secure OCRAM block for trustzone. So move all of secure text section into OCRAM, and not need to use memory anymore.
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com --- arch/arm/include/asm/arch-ls102xa/config.h | 2 +- include/configs/ls1021atwr.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/arch-ls102xa/config.h b/arch/arm/include/asm/arch-ls102xa/config.h index 927c401..49f35ee 100644 --- a/arch/arm/include/asm/arch-ls102xa/config.h +++ b/arch/arm/include/asm/arch-ls102xa/config.h @@ -10,7 +10,7 @@ #define CONFIG_SYS_CACHELINE_SIZE 64
#define OCRAM_BASE_ADDR 0x10000000 -#define OCRAM_SIZE 0x00020000 +#define OCRAM_SIZE 0x00010000 #define OCRAM_BASE_S_ADDR 0x10010000 #define OCRAM_S_SIZE 0x00010000
diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h index 527a37a..05ea348 100644 --- a/include/configs/ls1021atwr.h +++ b/include/configs/ls1021atwr.h @@ -11,6 +11,7 @@
#define CONFIG_ARMV7_PSCI #define CONFIG_ARMV7_PSCI_GTE_1_0 +#define CONFIG_ARMV7_SECURE_BASE OCRAM_BASE_S_ADDR
#define CONFIG_SYS_FSL_CLK

Hi all,
+Zhang Hongbo, Hongbo will take over this patchset.
Thanks.
Regards, -Dongsheng
From: Wang Dongsheng dongsheng.wang@nxp.com
Support PSCI v1.0 for u-boot.
Wang Dongsheng (9): ARM: PSCI: Change function ID base value ARM: PSCI: Change PSCI related macro definition style ARM: ARMv7: PSCI: move target PC in each CPU stack no longer is shared ARM: ARMv7: PSCI: Factor out reusable psci_cpu_on_common ARM: ARMv7: PSCI: Pass contextID to target CPU ARM: ARMv7: PSCI: ls102xa: Verify CPU ID for CPU_ON ARM: ARMv7: PSCI: Add PSCI 1.0 version support ARM: ARMv7: PSCI: ls102xa: add psci functions implemention ARM: ARMv7: PSCI: ls102xa: put secure text section into OCRAM
arch/arm/cpu/armv7/ls102xa/psci.S | 155 +++++++++++++++++++++++--
arch/arm/cpu/armv7/mx7/psci.S | 5 - arch/arm/cpu/armv7/nonsec_virt.S | 4 + arch/arm/cpu/armv7/psci.S | 162 ++++++++++++++++++++++++++--- arch/arm/cpu/armv7/sunxi/psci_sun6i.S | 11 +- arch/arm/cpu/armv7/sunxi/psci_sun7i.S | 11 +- arch/arm/cpu/armv7/virt-dt.c | 48 ++++++--- arch/arm/include/asm/arch-ls102xa/config.h | 3 +- arch/arm/include/asm/psci.h | 62 ++++++++--- arch/arm/mach-tegra/psci.S | 11 +- board/freescale/ls1021aqds/Makefile | 1 + board/freescale/ls1021aqds/psci.S | 36 +++++++ board/freescale/ls1021atwr/Makefile | 1 + board/freescale/ls1021atwr/psci.S | 28 +++++ include/configs/ls1021aqds.h | 3 + include/configs/ls1021atwr.h | 2 + 16 files changed, 451 insertions(+), 92 deletions(-) create mode 100644 board/freescale/ls1021aqds/psci.S create mode 100644 board/freescale/ls1021atwr/psci.S
-- 2.1.0.27.g96db324
participants (4)
-
Chenhui Zhao
-
Dongsheng Wang
-
Hongbo Zhang
-
Scott Wood