Skip to contentSkip to conversation

ARMv7: PSCI: add PSCI v1.0 support

PATCH Superseded macro.wave.z at gmail.com 3 participants 14 messages Jun 2, 2016 – Jun 6, 2016

Subsystems (4)

v4 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

v4 cover ARMv7: PSCI: add PSCI v1.0 support

From: Hongbo Zhang <[email protected]>

v4 changes:
- since there is already PSCI v0.2 function IDs definition merged in 5a07abb, I give up my previous patches 1/11 and 2/11, and move previous 7/11 "ARMv7:
PSCI: add PSCI v1.0 functions skeleton" as current first one 1/9
- accept Andre's comment to add the missed "arm,psci-0,2" into compatible string

v3 changes:
- patch 3/11, re-init the stack pointer to address like start of page instead of page end, because for ARM push operation, the stack pointer is encreased before storing data.
- patch 10/11, delete the previous un-implemented cpu_suspend function for ls1 platform, because there is default blank functions for all those are not implemented in specific platform.

v2 changes:
- re-organize psci_cpu_on_common, this code should be called by each platform's psci_cpu_on, should not be a function calling each psci_cpu_on, all related functions are updated due to this change
- update some registers usage, e.g. if r10 is used without push/pop, u-boot cannot launch rt-kernel
- update some comments to be clearer, re-organize all patches for easier review
- add patch to check already_on or on_pending for LS102XA

This patch set contains two parts:
ARMv7 PSCI common framework: fix some issues and add v1.0 support NXP (was Freescale) LS102XA: codes enhancement and add v1.0 implementation And this patch set was initially created by Dongsheng Wang.

Hongbo Zhang (9):
ARMv7: PSCI: add PSCI v1.0 functions skeleton
ARMv7: PSCI: update function psci_get_cpu_stack_top
ARMv7: PSCI: update the place of saving target PC
ARMv7: PSCI: add codes to save context ID for CPU_ON
ARMv7: PSCI: factor out reusable psci_cpu_on_common
ARMv7: PSCI: ls102xa: check target CPU ID before further operations
ARMv7: PSCI: ls102xa: check ALREADY_ON or ON_PENDING for CPU_ON
ARMv7: PSCI: ls102xa: add more PSCI v1.0 functions implemention
ARMv7: PSCI: ls102xa: move secure text section into OCRAM

 arch/arm/cpu/armv7/ls102xa/psci.S          | 170 +++++++++++++++++++++++++++--
 arch/arm/cpu/armv7/mx7/psci.S              |   7 +-
 arch/arm/cpu/armv7/nonsec_virt.S           |   7 ++
 arch/arm/cpu/armv7/psci.S                  | 106 +++++++++++++++++-
 arch/arm/cpu/armv7/sunxi/psci_sun6i.S      |   6 +-
 arch/arm/cpu/armv7/sunxi/psci_sun7i.S      |   6 +-
 arch/arm/cpu/armv7/virt-dt.c               |  19 +++-
 arch/arm/include/asm/arch-ls102xa/config.h |   3 +-
 arch/arm/include/asm/psci.h                |  31 ++++++
 arch/arm/mach-tegra/psci.S                 |   5 +-
 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               |   3 +
 16 files changed, 398 insertions(+), 34 deletions(-)
 create mode 100644 board/freescale/ls1021aqds/psci.S
 create mode 100644 board/freescale/ls1021atwr/psci.S
Signature · 1 line
2.1.4
#1 lore raw

PATCH v4 1/9 ARMv7: PSCI: add PSCI v1.0 functions skeleton

From: Hongbo Zhang <[email protected]>

This patch adds all the PSCI v1.0 functions in to the common framework, with all the functions returning "not implemented" by default, as a common framework all the dummy functions are added here, it is up to every platform developer to decide which version of PSCI and which functions to implement.

---
 arch/arm/cpu/armv7/psci.S    | 78 ++++++++++++++++++++++++++++++++++++++++++++
 arch/arm/cpu/armv7/virt-dt.c | 10 +++++-
 arch/arm/include/asm/psci.h  | 16 +++++++++
 3 files changed, 103 insertions(+), 1 deletion(-)
arch/arm/cpu/armv7/psci.S +78 -0
index 87c0c0b..8e25300 100644
@@ -46,20 +46,62 @@ ENTRY(default_psci_vector)
 ENDPROC(default_psci_vector)
 .weak default_psci_vector
 
+ENTRY(psci_version)
 ENTRY(psci_cpu_suspend)
 ENTRY(psci_cpu_off)
 ENTRY(psci_cpu_on)
+ENTRY(psci_affinity_info)
 ENTRY(psci_migrate)
+ENTRY(psci_migrate_info_type)
+ENTRY(psci_migrate_info_up_cpu)
+ENTRY(psci_system_off)
+ENTRY(psci_system_reset)
+ENTRY(psci_features)
+ENTRY(psci_cpu_freeze)
+ENTRY(psci_cpu_default_suspend)
+ENTRY(psci_node_hw_state)
+ENTRY(psci_system_suspend)
+ENTRY(psci_set_suspend_mode)
+ENTRY(psi_stat_residency)
+ENTRY(psci_stat_count)
 	mov	r0, #ARM_PSCI_RET_NI	@ Return -1 (Not Implemented)
 	mov	pc, lr
+ENDPROC(psci_stat_count)
+ENDPROC(psi_stat_residency)
+ENDPROC(psci_set_suspend_mode)
+ENDPROC(psci_system_suspend)
+ENDPROC(psci_node_hw_state)
+ENDPROC(psci_cpu_default_suspend)
+ENDPROC(psci_cpu_freeze)
+ENDPROC(psci_features)
+ENDPROC(psci_system_reset)
+ENDPROC(psci_system_off)
+ENDPROC(psci_migrate_info_up_cpu)
+ENDPROC(psci_migrate_info_type)
 ENDPROC(psci_migrate)
+ENDPROC(psci_affinity_info)
 ENDPROC(psci_cpu_on)
 ENDPROC(psci_cpu_off)
 ENDPROC(psci_cpu_suspend)
+ENDPROC(psci_version)
+.weak psci_version
 .weak psci_cpu_suspend
 .weak psci_cpu_off
 .weak psci_cpu_on
+.weak psci_affinity_info
 .weak psci_migrate
+.weak psci_migrate_info_type
+.weak psci_migrate_info_up_cpu
+.weak psci_system_off
+.weak psci_system_reset
+.weak psci_features
+.weak psci_cpu_freeze
+.weak psci_cpu_default_suspend
+.weak psci_node_hw_state
+.weak psci_system_suspend
+.weak psci_set_suspend_mode
+.weak psi_stat_residency
+.weak psci_stat_count
 
 _psci_table:
 	.word	ARM_PSCI_FN_CPU_SUSPEND
@@ -70,6 +112,42 @@ _psci_table:
 	.word	psci_cpu_on
 	.word	ARM_PSCI_FN_MIGRATE
 	.word	psci_migrate
+	.word	ARM_PSCI_0_2_FN_PSCI_VERSION
+	.word	psci_version
+	.word	ARM_PSCI_0_2_FN_CPU_SUSPEND
+	.word	psci_cpu_suspend
+	.word	ARM_PSCI_0_2_FN_CPU_OFF
+	.word	psci_cpu_off
+	.word	ARM_PSCI_0_2_FN_CPU_ON
+	.word	psci_cpu_on
+	.word	ARM_PSCI_0_2_FN_AFFINITY_INFO
+	.word	psci_affinity_info
+	.word	ARM_PSCI_0_2_FN_MIGRATE
+	.word	psci_migrate
+	.word	ARM_PSCI_0_2_FN_MIGRATE_INFO_TYPE
+	.word	psci_migrate_info_type
+	.word	ARM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU
+	.word	psci_migrate_info_up_cpu
+	.word	ARM_PSCI_0_2_FN_SYSTEM_OFF
+	.word	psci_system_off
+	.word	ARM_PSCI_0_2_FN_SYSTEM_RESET
+	.word	psci_system_reset
+	.word	ARM_PSCI_1_0_FN_PSCI_FEATURES
+	.word	psci_features
+	.word	ARM_PSCI_1_0_FN_CPU_FREEZE
+	.word	psci_cpu_freeze
+	.word	ARM_PSCI_1_0_FN_CPU_DEFAULT_SUSPEND
+	.word	psci_cpu_default_suspend
+	.word	ARM_PSCI_1_0_FN_NODE_HW_STATE
+	.word	psci_node_hw_state
+	.word	ARM_PSCI_1_0_FN_SYSTEM_SUSPEND
+	.word	psci_system_suspend
+	.word	ARM_PSCI_1_0_FN_SET_SUSPEND_MODE
+	.word	psci_set_suspend_mode
+	.word	ARM_PSCI_1_0_FN_STAT_RESIDENCY
+	.word	psi_stat_residency
+	.word	ARM_PSCI_1_0_FN_STAT_COUNT
+	.word	psci_stat_count
 	.word	0
 	.word	0
 
arch/arm/cpu/armv7/virt-dt.c +9 -1
index 32c368f..5e31891 100644
@@ -67,7 +67,15 @@ static int fdt_psci(void *fdt)
 			return nodeoff;
 	}
 
-	tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci");
+#ifdef CONFIG_ARMV7_PSCI_1_0
+	tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci-1.0");
+	if (tmp)
+		return tmp;
+	tmp = fdt_appendprop_string(fdt, nodeoff, "compatible", "arm,psci-0.2");
+	if (tmp)
+		return tmp;
+#endif
+	tmp = fdt_appendprop_string(fdt, nodeoff, "compatible", "arm,psci");
 	if (tmp)
 		return tmp;
 	tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc");
arch/arm/include/asm/psci.h +16 -0
index 3704f07..2367ec0 100644
@@ -31,6 +31,12 @@
 #define ARM_PSCI_RET_NI			(-1)
 #define ARM_PSCI_RET_INVAL		(-2)
 #define ARM_PSCI_RET_DENIED		(-3)
+#define ARM_PSCI_RET_ALREADY_ON		(-4)
+#define ARM_PSCI_RET_ON_PENDING		(-5)
+#define ARM_PSCI_RET_INTERNAL_FAILURE	(-6)
+#define ARM_PSCI_RET_NOT_PRESENT	(-7)
+#define ARM_PSCI_RET_DISABLED		(-8)
+#define ARM_PSCI_RET_INVALID_ADDRESS	(-9)
 
 /* PSCI 0.2 interface */
 #define ARM_PSCI_0_2_FN_BASE			0x84000000
@@ -47,6 +53,16 @@
 #define ARM_PSCI_0_2_FN_SYSTEM_OFF		ARM_PSCI_0_2_FN(8)
 #define ARM_PSCI_0_2_FN_SYSTEM_RESET		ARM_PSCI_0_2_FN(9)
 
+/* PSCI 1.0 interface */
+#define ARM_PSCI_1_0_FN_PSCI_FEATURES		ARM_PSCI_0_2_FN(10)
+#define ARM_PSCI_1_0_FN_CPU_FREEZE		ARM_PSCI_0_2_FN(11)
+#define ARM_PSCI_1_0_FN_CPU_DEFAULT_SUSPEND	ARM_PSCI_0_2_FN(12)
+#define ARM_PSCI_1_0_FN_NODE_HW_STATE		ARM_PSCI_0_2_FN(13)
+#define ARM_PSCI_1_0_FN_SYSTEM_SUSPEND		ARM_PSCI_0_2_FN(14)
+#define ARM_PSCI_1_0_FN_SET_SUSPEND_MODE	ARM_PSCI_0_2_FN(15)
+#define ARM_PSCI_1_0_FN_STAT_RESIDENCY		ARM_PSCI_0_2_FN(16)
+#define ARM_PSCI_1_0_FN_STAT_COUNT		ARM_PSCI_0_2_FN(17)
+
 #ifndef __ASSEMBLY__
 int psci_update_dt(void *fdt);
 void psci_board_init(void);
Signature · 1 line
2.1.4
#2 lore raw

PATCH v4 2/9 ARMv7: PSCI: update function psci_get_cpu_stack_top

In reply to macro.wave.z at gmail.com

From: Hongbo Zhang <[email protected]>

There are issues of legacy fuction psci_get_cpu_stack_top:

First, the current algorithm arranges stacks from an fixed adress towards psci_text_end, if there are more CPUs, the stacks will overlap with psci text segment and even other segments.
This patch places stacks from psci text segment towards highter address, and all the stack space is reserved, so overlap can be avoided.

Second, even there is one word reserved in each stack for saving target PC, but this reserved space isn't used at all, the target PC is still saved to where the stack top pointer points.
This patch doesn't reserve this word as before, new way of saving target PC will be introduced in following patch.

---
 arch/arm/cpu/armv7/psci.S    | 10 +++++-----
 arch/arm/cpu/armv7/virt-dt.c |  9 +++++++--
 arch/arm/include/asm/psci.h  |  3 +++
 3 files changed, 15 insertions(+), 7 deletions(-)
arch/arm/cpu/armv7/psci.S +5 -5
index 8e25300..91a1dd1 100644
@@ -274,16 +274,16 @@ 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
+	mov	r5, #PSCI_PERCPU_STACK_SIZE	@ 1kB of stack per CPU
+	add	r0, r0, #1
+	mul	r0, r0, r5			@ offset of each stack
 
 	ldr	r5, =psci_text_end		@ end of monitor text
-	add	r5, r5, #0x2000			@ Skip two pages
+	add	r5, r5, #0x1000			@ Skip one page
 	lsr	r5, r5, #12			@ Align to start of page
 	lsl	r5, r5, #12
-	sub	r5, r5, #4			@ reserve 1 word for target PC
-	sub	r0, r5, r0			@ here's our stack!
 
+	add	r0, r5, r0			@ here's our stack!
 	bx	lr
 ENDPROC(psci_get_cpu_stack_top)
 
arch/arm/cpu/armv7/virt-dt.c +7 -2
index 5e31891..4fe6f58 100644
@@ -127,14 +127,19 @@ int armv7_apply_memory_carveout(u64 *start, u64 *size)
 
 int psci_update_dt(void *fdt)
 {
+	size_t sec_sz = __secure_end - __secure_start;
+#ifdef CONFIG_ARMV7_PSCI
+	sec_sz += CONFIG_MAX_CPUS * PSCI_PERCPU_STACK_SIZE;
+	/* margin to align psci_text_end to page end*/
+	sec_sz += 0x1000;
+#endif
 #ifdef CONFIG_ARMV7_NONSEC
 	if (!armv7_boot_nonsec())
 		return 0;
 #endif
 #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);
+	fdt_add_mem_rsv(fdt, (unsigned long)__secure_start, sec_sz);
 #endif
 
 	return fdt_psci(fdt);
arch/arm/include/asm/psci.h +3 -0
index 2367ec0..76c3c92 100644
@@ -63,6 +63,9 @@
 #define ARM_PSCI_1_0_FN_STAT_RESIDENCY		ARM_PSCI_0_2_FN(16)
 #define ARM_PSCI_1_0_FN_STAT_COUNT		ARM_PSCI_0_2_FN(17)
 
+/* size of percpu stack, 1kB */
+#define PSCI_PERCPU_STACK_SIZE		0x400
+
 #ifndef __ASSEMBLY__
 int psci_update_dt(void *fdt);
 void psci_board_init(void);
Signature · 1 line
2.1.4
#3 lore raw

PATCH v4 2/9 ARMv7: PSCI: update function psci_get_cpu_stack_top

Quoted 55 lines · macro.wave.z at gmail.com

From: Hongbo Zhang <[email protected]>

There are issues of legacy fuction psci_get_cpu_stack_top:

First, the current algorithm arranges stacks from an fixed adress towards psci_text_end, if there are more CPUs, the stacks will overlap with psci text segment and even other segments.
This patch places stacks from psci text segment towards highter address, and all the stack space is reserved, so overlap can be avoided.

Second, even there is one word reserved in each stack for saving target PC, but this reserved space isn't used at all, the target PC is still saved to where the stack top pointer points.
This patch doesn't reserve this word as before, new way of saving target PC will be introduced in following patch.

---
 arch/arm/cpu/armv7/psci.S    | 10 +++++-----
 arch/arm/cpu/armv7/virt-dt.c |  9 +++++++--
 arch/arm/include/asm/psci.h  |  3 +++
 3 files changed, 15 insertions(+), 7 deletions(-)
arch/arm/cpu/armv7/psci.S +5 -5
index 8e25300..91a1dd1 100644
@@ -274,16 +274,16 @@ 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
+	mov	r5, #PSCI_PERCPU_STACK_SIZE	@ 1kB of stack per CPU
+	add	r0, r0, #1
+	mul	r0, r0, r5			@ offset of each stack
 
 	ldr	r5, =psci_text_end		@ end of monitor text
-	add	r5, r5, #0x2000			@ Skip two pages
+	add	r5, r5, #0x1000			@ Skip one page
 	lsr	r5, r5, #12			@ Align to start of page
 	lsl	r5, r5, #12
-	sub	r5, r5, #4			@ reserve 1 word for target PC
-	sub	r0, r5, r0			@ here's our stack!
 
+	add	r0, r5, r0			@ here's our stack!
 	bx	lr
 ENDPROC(psci_get_cpu_stack_top)
 
arch/arm/cpu/armv7/virt-dt.c +0 -0
index 5e31891..4fe6f58 100644

arch/arm/cpu/armv7/virt-dt.c int armv7_apply_memory_carveout(u64 *start, u64 *size) · line 135

Quoted 9 lines
arch/arm/cpu/armv7/virt-dt.c +6 -0
@@ -127,14 +127,19 @@ int armv7_apply_memory_carveout(u64 *start, u64 *size)
 
 int psci_update_dt(void *fdt)
 {
+	size_t sec_sz = __secure_end - __secure_start;
+#ifdef CONFIG_ARMV7_PSCI
+	sec_sz += CONFIG_MAX_CPUS * PSCI_PERCPU_STACK_SIZE;
+	/* margin to align psci_text_end to page end*/
+	sec_sz += 0x1000;
+#endif

This causes a compiling error

+(mx7dsabresd) ../arch/arm/cpu/armv7/virt-dt.c: In function ?psci_update_dt?:
+(mx7dsabresd) ../arch/arm/cpu/armv7/virt-dt.c:132:12: error: ?CONFIG_MAX_CPUS? undeclared (first use in this function)
+(mx7dsabresd) ../arch/arm/cpu/armv7/virt-dt.c:132:12: note: each undeclared identifier is reported only once for each function it appears in

York

#4 lore raw

PATCH v4 2/9 ARMv7: PSCI: update function psci_get_cpu_stack_top

Hi York,
Which version of u-boot do you use? I don't have such problem. I was using the latest u-boot (when I re-worked this patch set), it was e4a94ce Merge git://git.denx.de/u-boot-dm
but there is some thing wrong that this version of u-boot cannot load my kernel properly, so I went a little backward to
c7757d4 arm: meson: implement calls to secure monitor because I need Beniamino's commits.
The above two patch sets are identical, and there is no such compiling error for me, and I've tested the later.

Quoted 75 lines · York Sun
Quoted 55 lines · macro.wave.z at gmail.com

From: Hongbo Zhang <[email protected]>

There are issues of legacy fuction psci_get_cpu_stack_top:

First, the current algorithm arranges stacks from an fixed adress towards psci_text_end, if there are more CPUs, the stacks will overlap with psci text segment and even other segments.
This patch places stacks from psci text segment towards highter address, and all the stack space is reserved, so overlap can be avoided.

Second, even there is one word reserved in each stack for saving target PC, but this reserved space isn't used at all, the target PC is still saved to where the stack top pointer points.
This patch doesn't reserve this word as before, new way of saving target PC will be introduced in following patch.

---
 arch/arm/cpu/armv7/psci.S    | 10 +++++-----
 arch/arm/cpu/armv7/virt-dt.c |  9 +++++++--
 arch/arm/include/asm/psci.h  |  3 +++
 3 files changed, 15 insertions(+), 7 deletions(-)
arch/arm/cpu/armv7/psci.S +5 -5
index 8e25300..91a1dd1 100644
@@ -274,16 +274,16 @@ 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
+     mov     r5, #PSCI_PERCPU_STACK_SIZE     @ 1kB of stack per CPU
+     add     r0, r0, #1
+     mul     r0, r0, r5                      @ offset of each stack
 
      ldr     r5, =psci_text_end              @ end of monitor text
-     add     r5, r5, #0x2000                 @ Skip two pages
+     add     r5, r5, #0x1000                 @ Skip one page
      lsr     r5, r5, #12                     @ Align to start of page
      lsl     r5, r5, #12
-     sub     r5, r5, #4                      @ reserve 1 word for target PC
-     sub     r0, r5, r0                      @ here's our stack!
 
+     add     r0, r5, r0                      @ here's our stack!
      bx      lr
 ENDPROC(psci_get_cpu_stack_top)
 
arch/arm/cpu/armv7/virt-dt.c +0 -0
index 5e31891..4fe6f58 100644

arch/arm/cpu/armv7/virt-dt.c int armv7_apply_memory_carveout(u64 *start, u64 *size) · line 135

Quoted 9 lines
arch/arm/cpu/armv7/virt-dt.c +6 -0
@@ -127,14 +127,19 @@ int armv7_apply_memory_carveout(u64 *start, u64 *size)
 
 int psci_update_dt(void *fdt)
 {
+     size_t sec_sz = __secure_end - __secure_start;
+#ifdef CONFIG_ARMV7_PSCI
+     sec_sz += CONFIG_MAX_CPUS * PSCI_PERCPU_STACK_SIZE;
+     /* margin to align psci_text_end to page end*/
+     sec_sz += 0x1000;
+#endif

This causes a compiling error

(quoted diff) +2 -0
+(mx7dsabresd) ../arch/arm/cpu/armv7/virt-dt.c: In function ?psci_update_dt?:
+(mx7dsabresd) ../arch/arm/cpu/armv7/virt-dt.c:132:12: error: ?CONFIG_MAX_CPUS?

undeclared (first use in this function)
+(mx7dsabresd) ../arch/arm/cpu/armv7/virt-dt.c:132:12: note: each undeclared identifier is reported only once for each function it appears in

York

#5 lore raw

PATCH v4 2/9 ARMv7: PSCI: update function psci_get_cpu_stack_top

Hi,

Quoted 10 lines · Hongbo Zhang

Hi York,
Which version of u-boot do you use? I don't have such problem. I was using the latest u-boot (when I re-worked this patch set), it was e4a94ce Merge git://git.denx.de/u-boot-dm
but there is some thing wrong that this version of u-boot cannot load my kernel properly, so I went a little backward to
c7757d4 arm: meson: implement calls to secure monitor because I need Beniamino's commits.
The above two patch sets are identical, and there is no such compiling error for me, and I've tested the later.

CONFIG_MAX_CPUS is not defined for all platforms.

On sunxi and mx7, we use CONFIG_ARMV7_PSCI_NR_CPUS.

ChenYu

Quoted 77 lines · York Sun
Quoted 75 lines · macro.wave.z at gmail.com
Quoted 55 lines

From: Hongbo Zhang <[email protected]>

There are issues of legacy fuction psci_get_cpu_stack_top:

First, the current algorithm arranges stacks from an fixed adress towards psci_text_end, if there are more CPUs, the stacks will overlap with psci text segment and even other segments.
This patch places stacks from psci text segment towards highter address, and all the stack space is reserved, so overlap can be avoided.

Second, even there is one word reserved in each stack for saving target PC, but this reserved space isn't used at all, the target PC is still saved to where the stack top pointer points.
This patch doesn't reserve this word as before, new way of saving target PC will be introduced in following patch.

---
 arch/arm/cpu/armv7/psci.S    | 10 +++++-----
 arch/arm/cpu/armv7/virt-dt.c |  9 +++++++--
 arch/arm/include/asm/psci.h  |  3 +++
 3 files changed, 15 insertions(+), 7 deletions(-)
arch/arm/cpu/armv7/psci.S +5 -5
index 8e25300..91a1dd1 100644
@@ -274,16 +274,16 @@ 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
+     mov     r5, #PSCI_PERCPU_STACK_SIZE     @ 1kB of stack per CPU
+     add     r0, r0, #1
+     mul     r0, r0, r5                      @ offset of each stack
 
      ldr     r5, =psci_text_end              @ end of monitor text
-     add     r5, r5, #0x2000                 @ Skip two pages
+     add     r5, r5, #0x1000                 @ Skip one page
      lsr     r5, r5, #12                     @ Align to start of page
      lsl     r5, r5, #12
-     sub     r5, r5, #4                      @ reserve 1 word for target PC
-     sub     r0, r5, r0                      @ here's our stack!
 
+     add     r0, r5, r0                      @ here's our stack!
      bx      lr
 ENDPROC(psci_get_cpu_stack_top)
 
arch/arm/cpu/armv7/virt-dt.c +0 -0
index 5e31891..4fe6f58 100644

arch/arm/cpu/armv7/virt-dt.c int armv7_apply_memory_carveout(u64 *start, u64 *size) · line 135

Quoted 9 lines
arch/arm/cpu/armv7/virt-dt.c +6 -0
@@ -127,14 +127,19 @@ int armv7_apply_memory_carveout(u64 *start, u64 *size)
 
 int psci_update_dt(void *fdt)
 {
+     size_t sec_sz = __secure_end - __secure_start;
+#ifdef CONFIG_ARMV7_PSCI
+     sec_sz += CONFIG_MAX_CPUS * PSCI_PERCPU_STACK_SIZE;
+     /* margin to align psci_text_end to page end*/
+     sec_sz += 0x1000;
+#endif

This causes a compiling error

(quoted diff) +2 -0
+(mx7dsabresd) ../arch/arm/cpu/armv7/virt-dt.c: In function ?psci_update_dt?:
+(mx7dsabresd) ../arch/arm/cpu/armv7/virt-dt.c:132:12: error: ?CONFIG_MAX_CPUS?

undeclared (first use in this function)
+(mx7dsabresd) ../arch/arm/cpu/armv7/virt-dt.c:132:12: note: each undeclared identifier is reported only once for each function it appears in

York

#6 lore raw

PATCH v4 2/9 ARMv7: PSCI: update function psci_get_cpu_stack_top

Quoted 14 lines · Chen-Yu Tsai

Hi,

Quoted 10 lines · Hongbo Zhang

Hi York,
Which version of u-boot do you use? I don't have such problem. I was using the latest u-boot (when I re-worked this patch set), it was e4a94ce Merge git://git.denx.de/u-boot-dm
but there is some thing wrong that this version of u-boot cannot load my kernel properly, so I went a little backward to
c7757d4 arm: meson: implement calls to secure monitor because I need Beniamino's commits.
The above two patch sets are identical, and there is no such compiling error for me, and I've tested the later.

Quoted 6 lines

CONFIG_MAX_CPUS is not defined for all platforms.

On sunxi and mx7, we use CONFIG_ARMV7_PSCI_NR_CPUS.

ChenYu

Hi,
Thanks for pointing it out, I see.
That means we don't have a unique macro for number of CPUs, it is time to define it now, CONFIG_ARMV7_PSCI_NR_CPUS is better?

Quoted 78 lines
Quoted 78 lines · York Sun
Quoted 75 lines · macro.wave.z at gmail.com
Quoted 55 lines

From: Hongbo Zhang <[email protected]>

There are issues of legacy fuction psci_get_cpu_stack_top:

First, the current algorithm arranges stacks from an fixed adress towards psci_text_end, if there are more CPUs, the stacks will overlap with psci text segment and even other segments.
This patch places stacks from psci text segment towards highter address, and all the stack space is reserved, so overlap can be avoided.

Second, even there is one word reserved in each stack for saving target PC, but this reserved space isn't used at all, the target PC is still saved to where the stack top pointer points.
This patch doesn't reserve this word as before, new way of saving target PC will be introduced in following patch.

---
 arch/arm/cpu/armv7/psci.S    | 10 +++++-----
 arch/arm/cpu/armv7/virt-dt.c |  9 +++++++--
 arch/arm/include/asm/psci.h  |  3 +++
 3 files changed, 15 insertions(+), 7 deletions(-)
arch/arm/cpu/armv7/psci.S +5 -5
index 8e25300..91a1dd1 100644
@@ -274,16 +274,16 @@ 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
+     mov     r5, #PSCI_PERCPU_STACK_SIZE     @ 1kB of stack per CPU
+     add     r0, r0, #1
+     mul     r0, r0, r5                      @ offset of each stack
 
      ldr     r5, =psci_text_end              @ end of monitor text
-     add     r5, r5, #0x2000                 @ Skip two pages
+     add     r5, r5, #0x1000                 @ Skip one page
      lsr     r5, r5, #12                     @ Align to start of page
      lsl     r5, r5, #12
-     sub     r5, r5, #4                      @ reserve 1 word for target PC
-     sub     r0, r5, r0                      @ here's our stack!
 
+     add     r0, r5, r0                      @ here's our stack!
      bx      lr
 ENDPROC(psci_get_cpu_stack_top)
 
arch/arm/cpu/armv7/virt-dt.c +0 -0
index 5e31891..4fe6f58 100644

arch/arm/cpu/armv7/virt-dt.c int armv7_apply_memory_carveout(u64 *start, u64 *size) · line 135

Quoted 9 lines
arch/arm/cpu/armv7/virt-dt.c +6 -0
@@ -127,14 +127,19 @@ int armv7_apply_memory_carveout(u64 *start, u64 *size)
 
 int psci_update_dt(void *fdt)
 {
+     size_t sec_sz = __secure_end - __secure_start;
+#ifdef CONFIG_ARMV7_PSCI
+     sec_sz += CONFIG_MAX_CPUS * PSCI_PERCPU_STACK_SIZE;
+     /* margin to align psci_text_end to page end*/
+     sec_sz += 0x1000;
+#endif

This causes a compiling error

(quoted diff) +2 -0
+(mx7dsabresd) ../arch/arm/cpu/armv7/virt-dt.c: In function ?psci_update_dt?:
+(mx7dsabresd) ../arch/arm/cpu/armv7/virt-dt.c:132:12: error: ?CONFIG_MAX_CPUS?

undeclared (first use in this function)
+(mx7dsabresd) ../arch/arm/cpu/armv7/virt-dt.c:132:12: note: each undeclared identifier is reported only once for each function it appears in

York

#7 lore raw

PATCH v4 3/9 ARMv7: PSCI: update the place of saving target PC

In reply to macro.wave.z at gmail.com

From: Hongbo Zhang <[email protected]>

The legacy code reserves one word in each stack for saving target PC, but it isn't used, the target PC is still saved to where the stack top pointer points. This patch relocates the place for saving target PC to the lowest address of each stack, convinience is that we can save more contents if needed ilater next to saved target PC without re-adjust the stack top pointer.

---
 arch/arm/cpu/armv7/ls102xa/psci.S     | 1 +
 arch/arm/cpu/armv7/mx7/psci.S         | 1 +
 arch/arm/cpu/armv7/psci.S             | 3 ++-
 arch/arm/cpu/armv7/sunxi/psci_sun6i.S | 3 ++-
 arch/arm/cpu/armv7/sunxi/psci_sun7i.S | 3 ++-
 arch/arm/include/asm/psci.h           | 1 +
 arch/arm/mach-tegra/psci.S            | 3 ++-
 7 files changed, 11 insertions(+), 4 deletions(-)
arch/arm/cpu/armv7/ls102xa/psci.S +1 -0
index cf5cd48..988a1d2 100644
@@ -37,6 +37,7 @@ psci_cpu_on:
 
 	mov	r0, r1
 	bl	psci_get_cpu_stack_top
+	sub	r0, r0, #PSCI_TARGET_PC_OFFSET
 	str	r2, [r0]
 	dsb
 
arch/arm/cpu/armv7/mx7/psci.S +1 -0
index 34c6ab3..02ca076 100644
@@ -31,6 +31,7 @@ psci_cpu_on:
 
 	mov	r0, r1
 	bl	psci_get_cpu_stack_top
+	sub	r0, r0, #PSCI_TARGET_PC_OFFSET
 	str	r2, [r0]
 	dsb
 
arch/arm/cpu/armv7/psci.S +2 -1
index 91a1dd1..14ffc85 100644
@@ -294,7 +294,8 @@ ENTRY(psci_cpu_entry)
 
 	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
+	sub	r0, r0, #PSCI_TARGET_PC_OFFSET
+	ldr	r0, [r0]			@ get target PC
 	b	_do_nonsec_entry
 ENDPROC(psci_cpu_entry)
 
arch/arm/cpu/armv7/sunxi/psci_sun6i.S +2 -1
index 90b5bfd..930aa7a 100644
@@ -136,7 +136,8 @@ psci_cpu_on:
 
 	mov	r0, r1
 	bl	psci_get_cpu_stack_top	@ get stack top of target CPU
-	str	r2, [r0]		@ store target PC at stack top
+	sub	r0, r0, #PSCI_TARGET_PC_OFFSET
+	str	r2, [r0]		@ store target PC
 	dsb
 
 	movw	r0, #(SUN6I_CPUCFG_BASE & 0xffff)
arch/arm/cpu/armv7/sunxi/psci_sun7i.S +2 -1
index e15d587..7fbeac1 100644
@@ -125,7 +125,8 @@ psci_cpu_on:
 
 	mov	r0, r1
 	bl	psci_get_cpu_stack_top	@ get stack top of target CPU
-	str	r2, [r0]		@ store target PC at stack top
+	sub	r0, r0, #PSCI_TARGET_PC_OFFSET
+	str	r2, [r0]		@ store target PC
 	dsb
 
 	movw	r0, #(SUN7I_CPUCFG_BASE & 0xffff)
arch/arm/include/asm/psci.h +1 -0
index 76c3c92..cb08544 100644
@@ -65,6 +65,7 @@
 
 /* size of percpu stack, 1kB */
 #define PSCI_PERCPU_STACK_SIZE		0x400
+#define PSCI_TARGET_PC_OFFSET		(PSCI_PERCPU_STACK_SIZE - 4)
 
 #ifndef __ASSEMBLY__
 int psci_update_dt(void *fdt);
arch/arm/mach-tegra/psci.S +2 -1
index b836da1..a335276 100644
@@ -92,7 +92,8 @@ ENTRY(psci_cpu_on)
 
 	mov	r0, r1
 	bl	psci_get_cpu_stack_top	@ get stack top of target CPU
-	str	r2, [r0]		@ store target PC at stack top
+	sub	r0, r0, #PSCI_TARGET_PC_OFFSET
+	str	r2, [r0]		@ store target PC
 	dsb
 
 	ldr	r6, =TEGRA_RESET_EXCEPTION_VECTOR
Signature · 1 line
2.1.4
#8 lore raw

PATCH v4 4/9 ARMv7: PSCI: add codes to save context ID for CPU_ON

In reply to macro.wave.z at gmail.com

From: Hongbo Zhang <[email protected]>

According to latest PSCI specification, the context ID is needed by CPU_ON. This patch saves context ID to the second lowest address of the stack (next to where target PC is saved), and restores it to r0 when needed while target CPU booting up.

This patch in current format is for easier review, there are some lines duplication with previous saving target PC codes, e.g. codes of calling the psci_get_cpu_stack_top, this will be optimized by the following patch.

---
 arch/arm/cpu/armv7/ls102xa/psci.S     | 7 +++++++
 arch/arm/cpu/armv7/mx7/psci.S         | 8 +++++++-
 arch/arm/cpu/armv7/nonsec_virt.S      | 7 +++++++
 arch/arm/cpu/armv7/sunxi/psci_sun6i.S | 7 +++++++
 arch/arm/cpu/armv7/sunxi/psci_sun7i.S | 8 ++++++++
 arch/arm/include/asm/psci.h           | 1 +
 arch/arm/mach-tegra/psci.S            | 6 ++++++
 7 files changed, 43 insertions(+), 1 deletion(-)
arch/arm/cpu/armv7/ls102xa/psci.S +7 -0
index 988a1d2..14d232a 100644
@@ -27,6 +27,7 @@
 
 	@ r1 = target CPU
 	@ r2 = target PC
+	@ r3 = target Conetxt ID
 .globl	psci_cpu_on
 psci_cpu_on:
 	push	{lr}
@@ -41,6 +42,12 @@ psci_cpu_on:
 	str	r2, [r0]
 	dsb
 
+	mov	r0, r1
+	bl	psci_get_cpu_stack_top
+	sub	r0, r0, #PSCI_CONTEXT_ID_OFFSET
+	str	r3, [r0]
+	dsb
+
 	@ Get DCFG base address
 	movw	r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
 	movt	r4, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16)
arch/arm/cpu/armv7/mx7/psci.S +7 -1
index 02ca076..90b8b9e 100644
@@ -24,7 +24,7 @@ psci_arch_init:
 
 	@ r1 = target CPU
 	@ r2 = target PC
-
+	@ r3 = target Conetxt ID
 .globl psci_cpu_on
 psci_cpu_on:
 	push	{lr}
@@ -35,6 +35,12 @@ psci_cpu_on:
 	str	r2, [r0]
 	dsb
 
+	mov	r0, r1
+	bl	psci_get_cpu_stack_top
+	sub	r0, r0, #PSCI_CONTEXT_ID_OFFSET
+	str	r3, [r0]
+	dsb
+
 	ldr	r2, =psci_cpu_entry
 	bl	imx_cpu_on
 
arch/arm/cpu/armv7/nonsec_virt.S +7 -0
index b7563ed..6566643 100644
@@ -11,6 +11,7 @@
 #include <asm/gic.h>
 #include <asm/armv7.h>
 #include <asm/proc-armv/ptrace.h>
+#include <asm/psci.h>
 
 .arch_extension sec
 .arch_extension virt
@@ -89,6 +90,12 @@ _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_stack_top
+	sub	r0, r0, #PSCI_CONTEXT_ID_OFFSET
+	ldr	r0, [r0]			@ get Context ID 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
arch/arm/cpu/armv7/sunxi/psci_sun6i.S +7 -0
index 930aa7a..6860b0a 100644
@@ -130,6 +130,7 @@ out:	mcr	p15, 0, r7, c1, c1, 0
 
 	@ r1 = target CPU
 	@ r2 = target PC
+	@ r3 = target Conetxt ID
 .globl	psci_cpu_on
 psci_cpu_on:
 	push	{lr}
@@ -140,6 +141,12 @@ psci_cpu_on:
 	str	r2, [r0]		@ store target PC
 	dsb
 
+	mov	r0, r1
+	bl	psci_get_cpu_stack_top
+	sub	r0, r0, #PSCI_CONTEXT_ID_OFFSET
+	str	r3, [r0]
+	dsb
+
 	movw	r0, #(SUN6I_CPUCFG_BASE & 0xffff)
 	movt	r0, #(SUN6I_CPUCFG_BASE >> 16)
 
arch/arm/cpu/armv7/sunxi/psci_sun7i.S +8 -0
index 7fbeac1..01d5eac 100644
@@ -119,6 +119,7 @@ out:	mcr	p15, 0, r7, c1, c1, 0
 
 	@ r1 = target CPU
 	@ r2 = target PC
+	@ r3 = target Conetxt ID
 .globl	psci_cpu_on
 psci_cpu_on:
 	push	{lr}
@@ -129,6 +130,13 @@ psci_cpu_on:
 	str	r2, [r0]		@ store target PC
 	dsb
 
+
+	mov	r0, r1
+	bl	psci_get_cpu_stack_top
+	sub	r0, r0, #PSCI_CONTEXT_ID_OFFSET
+	str	r3, [r0]
+	dsb
+
 	movw	r0, #(SUN7I_CPUCFG_BASE & 0xffff)
 	movt	r0, #(SUN7I_CPUCFG_BASE >> 16)
 
arch/arm/include/asm/psci.h +1 -0
index cb08544..bedcd30 100644
@@ -66,6 +66,7 @@
 /* size of percpu stack, 1kB */
 #define PSCI_PERCPU_STACK_SIZE		0x400
 #define PSCI_TARGET_PC_OFFSET		(PSCI_PERCPU_STACK_SIZE - 4)
+#define PSCI_CONTEXT_ID_OFFSET		(PSCI_PERCPU_STACK_SIZE - 8)
 
 #ifndef __ASSEMBLY__
 int psci_update_dt(void *fdt);
arch/arm/mach-tegra/psci.S +6 -0
index a335276..d87fd72 100644
@@ -96,6 +96,12 @@ ENTRY(psci_cpu_on)
 	str	r2, [r0]		@ store target PC
 	dsb
 
+	mov	r0, r1
+	bl	psci_get_cpu_stack_top
+	sub	r0, r0, #PSCI_CONTEXT_ID_OFFSET
+	str	r3, [r0]
+	dsb
+
 	ldr	r6, =TEGRA_RESET_EXCEPTION_VECTOR
 	ldr	r5, =psci_cpu_entry
 	str	r5, [r6]
Signature · 1 line
2.1.4
#9 lore raw

PATCH v4 5/9 ARMv7: PSCI: factor out reusable psci_cpu_on_common

In reply to macro.wave.z at gmail.com

From: Hongbo Zhang <[email protected]>

There are codes for saving target PC and target context ID in each platform psci_cpu_on routines, these can be factored out as psci_cpu_on_common.

---
 arch/arm/cpu/armv7/ls102xa/psci.S     | 12 +-----------
 arch/arm/cpu/armv7/mx7/psci.S         | 12 +-----------
 arch/arm/cpu/armv7/psci.S             | 15 +++++++++++++++
 arch/arm/cpu/armv7/sunxi/psci_sun6i.S | 12 +-----------
 arch/arm/cpu/armv7/sunxi/psci_sun7i.S | 13 +------------
 arch/arm/mach-tegra/psci.S            | 12 +-----------
 6 files changed, 20 insertions(+), 56 deletions(-)
arch/arm/cpu/armv7/ls102xa/psci.S +1 -11
index 14d232a..973a489 100644
@@ -36,17 +36,7 @@ psci_cpu_on:
 	@ r1 = 0xf01
 	and	r1, r1, #0xff
 
-	mov	r0, r1
-	bl	psci_get_cpu_stack_top
-	sub	r0, r0, #PSCI_TARGET_PC_OFFSET
-	str	r2, [r0]
-	dsb
-
-	mov	r0, r1
-	bl	psci_get_cpu_stack_top
-	sub	r0, r0, #PSCI_CONTEXT_ID_OFFSET
-	str	r3, [r0]
-	dsb
+	bl	psci_cpu_on_common
 
 	@ Get DCFG base address
 	movw	r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
arch/arm/cpu/armv7/mx7/psci.S +1 -11
index 90b8b9e..c9a7b00 100644
@@ -29,17 +29,7 @@ psci_arch_init:
 psci_cpu_on:
 	push	{lr}
 
-	mov	r0, r1
-	bl	psci_get_cpu_stack_top
-	sub	r0, r0, #PSCI_TARGET_PC_OFFSET
-	str	r2, [r0]
-	dsb
-
-	mov	r0, r1
-	bl	psci_get_cpu_stack_top
-	sub	r0, r0, #PSCI_CONTEXT_ID_OFFSET
-	str	r3, [r0]
-	dsb
+	bl	psci_cpu_on_common
 
 	ldr	r2, =psci_cpu_entry
 	bl	imx_cpu_on
arch/arm/cpu/armv7/psci.S +15 -0
index 14ffc85..c347ab8 100644
@@ -253,6 +253,21 @@ ENTRY(psci_enable_smp)
 ENDPROC(psci_enable_smp)
 .weak psci_enable_smp
 
+/* expects target CPU in r1, target PC in r2, target conetxt ID in r3 */
+ENTRY(psci_cpu_on_common)
+	push	{lr}
+
+	mov	r0, r1
+	bl	psci_get_cpu_stack_top		@ get stack top of target CPU
+	sub	r5, r0, #PSCI_TARGET_PC_OFFSET
+	str	r2, [r5]			@ save target PC
+	sub	r5, r0, #PSCI_CONTEXT_ID_OFFSET
+	str	r3, [r5]			@ save target context ID
+	dsb
+
+	pop	{pc}
+ENDPROC(psci_cpu_on_common)
+
 ENTRY(psci_cpu_off_common)
 	push	{lr}
 
arch/arm/cpu/armv7/sunxi/psci_sun6i.S +1 -11
index 6860b0a..62452be 100644
@@ -135,17 +135,7 @@ out:	mcr	p15, 0, r7, c1, c1, 0
 psci_cpu_on:
 	push	{lr}
 
-	mov	r0, r1
-	bl	psci_get_cpu_stack_top	@ get stack top of target CPU
-	sub	r0, r0, #PSCI_TARGET_PC_OFFSET
-	str	r2, [r0]		@ store target PC
-	dsb
-
-	mov	r0, r1
-	bl	psci_get_cpu_stack_top
-	sub	r0, r0, #PSCI_CONTEXT_ID_OFFSET
-	str	r3, [r0]
-	dsb
+	bl	psci_cpu_on_common
 
 	movw	r0, #(SUN6I_CPUCFG_BASE & 0xffff)
 	movt	r0, #(SUN6I_CPUCFG_BASE >> 16)
arch/arm/cpu/armv7/sunxi/psci_sun7i.S +1 -12
index 01d5eac..9dc4c6b 100644
@@ -124,18 +124,7 @@ out:	mcr	p15, 0, r7, c1, c1, 0
 psci_cpu_on:
 	push	{lr}
 
-	mov	r0, r1
-	bl	psci_get_cpu_stack_top	@ get stack top of target CPU
-	sub	r0, r0, #PSCI_TARGET_PC_OFFSET
-	str	r2, [r0]		@ store target PC
-	dsb
-
-
-	mov	r0, r1
-	bl	psci_get_cpu_stack_top
-	sub	r0, r0, #PSCI_CONTEXT_ID_OFFSET
-	str	r3, [r0]
-	dsb
+	bl	psci_cpu_on_common
 
 	movw	r0, #(SUN7I_CPUCFG_BASE & 0xffff)
 	movt	r0, #(SUN7I_CPUCFG_BASE >> 16)
arch/arm/mach-tegra/psci.S +1 -11
index d87fd72..8a0147c 100644
@@ -90,17 +90,7 @@ ENDPROC(psci_cpu_off)
 ENTRY(psci_cpu_on)
 	push	{lr}
 
-	mov	r0, r1
-	bl	psci_get_cpu_stack_top	@ get stack top of target CPU
-	sub	r0, r0, #PSCI_TARGET_PC_OFFSET
-	str	r2, [r0]		@ store target PC
-	dsb
-
-	mov	r0, r1
-	bl	psci_get_cpu_stack_top
-	sub	r0, r0, #PSCI_CONTEXT_ID_OFFSET
-	str	r3, [r0]
-	dsb
+	bl	psci_cpu_on_common
 
 	ldr	r6, =TEGRA_RESET_EXCEPTION_VECTOR
 	ldr	r5, =psci_cpu_entry
Signature · 1 line
2.1.4
#10 lore raw

PATCH v4 6/9 ARMv7: PSCI: ls102xa: check target CPU ID before further operations

In reply to macro.wave.z at gmail.com

From: Hongbo Zhang <[email protected]>

The input parameter CPU ID needs to be validated before furher oprations such as CPU_ON, this patch introduces the function to do this.

---
 arch/arm/cpu/armv7/ls102xa/psci.S | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)
arch/arm/cpu/armv7/ls102xa/psci.S +33 -1
index 973a489..4540bb1 100644
@@ -25,6 +25,34 @@
 #define	ONE_MS		(GENERIC_TIMER_CLK / 1000)
 #define	RESET_WAIT	(30 * ONE_MS)
 
+.globl	psci_check_target_cpu_id
+psci_check_target_cpu_id:
+	@ Get the real CPU number
+	and	r0, r1, #0xff
+
+	@ Verify bit[31:24], bits must be zero.
+	tst	r1, #0xff000000
+	bne	out_psci_invalid_target_cpu_id
+
+	@ Verify Affinity level 2: Cluster, only one cluster in LS1021xa SoC.
+	tst	r1, #0xff0000
+	bne	out_psci_invalid_target_cpu_id
+
+	@ Verify Affinity level 1: Processors, should be in 0xf00 format.
+	lsr	r1, r1, #8
+	teq	r1, #0xf
+	bne	out_psci_invalid_target_cpu_id
+
+	@ Verify Affinity level 0: CPU, only 0, 1 are valid values.
+	cmp	r0, #2
+	bge	out_psci_invalid_target_cpu_id
+
+	bx	lr
+
+out_psci_invalid_target_cpu_id:
+	mov	r0, #ARM_PSCI_RET_INVAL
+	bx	lr
+
 	@ r1 = target CPU
 	@ r2 = target PC
 	@ r3 = target Conetxt ID
@@ -34,7 +62,10 @@ psci_cpu_on:
 
 	@ Clear and Get the correct CPU number
 	@ r1 = 0xf01
-	and	r1, r1, #0xff
+	bl	psci_check_target_cpu_id
+	cmp	r0, #ARM_PSCI_RET_INVAL
+	beq	out_psci_cpu_on
+	mov	r1, r0
 
 	bl	psci_cpu_on_common
 
@@ -99,6 +130,7 @@ holdoff_release:
 	@ Return
 	mov	r0, #ARM_PSCI_RET_SUCCESS
 
+out_psci_cpu_on:
 	pop	{lr}
 	bx	lr
 
Signature · 1 line
2.1.4
#11 lore raw

PATCH v4 7/9 ARMv7: PSCI: ls102xa: check ALREADY_ON or ON_PENDING for CPU_ON

In reply to macro.wave.z at gmail.com

From: Hongbo Zhang <[email protected]>

For the robustness of codes, while powering on a CPU, it is better to check if the target CPU is already on or in the process of power on, if yes the power on routine shouldn't be executed further and should return with the corresponding status immediately.

---
 arch/arm/cpu/armv7/ls102xa/psci.S | 29 +++++++++++++++++++++++++++++
 arch/arm/include/asm/psci.h       |  5 +++++
 2 files changed, 34 insertions(+)
arch/arm/cpu/armv7/ls102xa/psci.S +29 -0
index 4540bb1..46fa68c 100644
@@ -67,6 +67,22 @@ psci_cpu_on:
 	beq	out_psci_cpu_on
 	mov	r1, r0
 
+	bl	psci_get_cpu_stack_top
+	sub	r0, r0, #PSCI_CPU_STATUS_OFFSET
+	ldr	r5, [r0]
+
+	cmp	r5, #PSCI_CPU_STATUS_ON
+	moveq	r0, #ARM_PSCI_RET_ALREADY_ON
+	beq	out_psci_cpu_on
+
+	cmp	r5, #PSCI_CPU_STATUS_ON_PENDING
+	moveq	r0, #ARM_PSCI_RET_ON_PENDING
+	beq	out_psci_cpu_on
+
+	mov	r5, #PSCI_CPU_STATUS_ON_PENDING
+	str	r5, [r0]
+	dsb
+
 	bl	psci_cpu_on_common
 
 	@ Get DCFG base address
@@ -124,6 +140,12 @@ holdoff_release:
 	rev	r6, r6
 	str	r6, [r4, #DCFG_CCSR_SCRATCHRW1]
 
+	mov	r0, r1
+	bl	psci_get_cpu_stack_top
+	sub	r0, r0, #PSCI_CPU_STATUS_OFFSET
+	mov	r5, #PSCI_CPU_STATUS_ON
+	str	r5, [r0]
+
 	isb
 	dsb
 
@@ -138,6 +160,13 @@ out_psci_cpu_on:
 psci_cpu_off:
 	bl	psci_cpu_off_common
 
+	bl	psci_get_cpu_id
+	bl	psci_get_cpu_stack_top
+	sub	r0, r0, #PSCI_CPU_STATUS_OFFSET
+	mov	r5, #PSCI_CPU_STATUS_OFF
+	str	r5, [r0]
+	dsb
+
 1:	wfi
 	b	1b
 
arch/arm/include/asm/psci.h +5 -0
index bedcd30..89a1ba5 100644
@@ -67,6 +67,11 @@
 #define PSCI_PERCPU_STACK_SIZE		0x400
 #define PSCI_TARGET_PC_OFFSET		(PSCI_PERCPU_STACK_SIZE - 4)
 #define PSCI_CONTEXT_ID_OFFSET		(PSCI_PERCPU_STACK_SIZE - 8)
+#define PSCI_CPU_STATUS_OFFSET		(PSCI_PERCPU_STACK_SIZE - 12)
+
+#define PSCI_CPU_STATUS_OFF		0
+#define PSCI_CPU_STATUS_ON		1
+#define PSCI_CPU_STATUS_ON_PENDING	2
 
 #ifndef __ASSEMBLY__
 int psci_update_dt(void *fdt);
Signature · 1 line
2.1.4
#12 lore raw

PATCH v4 8/9 ARMv7: PSCI: ls102xa: add more PSCI v1.0 functions implemention

In reply to macro.wave.z at gmail.com

From: Hongbo Zhang <[email protected]>

This patch implements PSCI functions for ls102xa SoC following PSCI v1.0, they are as the list:
psci_version,
psci_features,
psci_cpu_suspend,
psci_affinity_info,
psci_system_reset,
psci_system_off.

Tested on LS1021aQDS, LS1021aTWR.

---
 arch/arm/cpu/armv7/ls102xa/psci.S          | 105 +++++++++++++++++++++++++++--
 arch/arm/include/asm/arch-ls102xa/config.h |   1 +
 arch/arm/include/asm/psci.h                |   5 ++
 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 +
 9 files changed, 177 insertions(+), 4 deletions(-)
 create mode 100644 board/freescale/ls1021aqds/psci.S
 create mode 100644 board/freescale/ls1021atwr/psci.S
arch/arm/cpu/armv7/ls102xa/psci.S +101 -4
index 46fa68c..e480671 100644
@@ -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	ARM_PSCI_0_2_FN_PSCI_VERSION
+	.word	PSCI_FN_PSCI_VERSION_FEATURE_MASK
+	.word	ARM_PSCI_0_2_FN_CPU_SUSPEND
+	.word	PSCI_FN_CPU_SUSPEND_FEATURE_MASK
+	.word	ARM_PSCI_0_2_FN_CPU_OFF
+	.word	PSCI_FN_CPU_OFF_FEATURE_MASK
+	.word	ARM_PSCI_0_2_FN_CPU_ON
+	.word	PSCI_FN_CPU_ON_FEATURE_MASK
+	.word	ARM_PSCI_0_2_FN_AFFINITY_INFO
+	.word	PSCI_FN_AFFINITY_INFO_FEATURE_MASK
+	.word	ARM_PSCI_0_2_FN_SYSTEM_OFF
+	.word	PSCI_FN_SYSTEM_OFF_FEATURE_MASK
+	.word	ARM_PSCI_0_2_FN_SYSTEM_RESET
+	.word	PSCI_FN_SYSTEM_RESET_FEATURE_MASK
+	.word	0
+	.word	ARM_PSCI_RET_NI
+
+.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
+
 .globl	psci_check_target_cpu_id
 psci_check_target_cpu_id:
 	@ Get the real CPU number
@@ -170,6 +223,52 @@ psci_cpu_off:
 1:	wfi
 	b	1b
 
+.globl	psci_affinity_info
+psci_affinity_info:
+	push	{lr}
+
+	mov	r0, #ARM_PSCI_RET_INVAL
+
+	@ Verify Affinity level
+	cmp	r2, #0
+	bne	out_affinity_info
+
+	bl	psci_check_target_cpu_id
+	cmp	r0, #ARM_PSCI_RET_INVAL
+	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
@@ -180,6 +279,4 @@ psci_arch_init:
 
 	bx	r6
 
-	.globl psci_text_end
-psci_text_end:
 	.popsection
arch/arm/include/asm/arch-ls102xa/config.h +1 -0
index 04abec4..7a0e4bf 100644
@@ -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)
arch/arm/include/asm/psci.h +5 -0
index 89a1ba5..1c6d819 100644
@@ -73,6 +73,11 @@
 #define PSCI_CPU_STATUS_ON		1
 #define PSCI_CPU_STATUS_ON_PENDING	2
 
+/* PSCI 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
+
 #ifndef __ASSEMBLY__
 int psci_update_dt(void *fdt);
 void psci_board_init(void);
board/freescale/ls1021aqds/Makefile +1 -0
index ab02344..f0390c1 100644
@@ -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
board/freescale/ls1021aqds/psci.S new file +36 -0
new file mode 100644
index 0000000..6b75595
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2016 NXP Semiconductor.
+ * Author: Wang Dongsheng <[email protected]>
+ *
+ * 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
board/freescale/ls1021atwr/Makefile +1 -0
index 01296c0..5238b15 100644
@@ -6,3 +6,4 @@
 
 obj-y += ls1021atwr.o
 obj-$(CONFIG_FSL_DCU_FB) += dcu.o
+obj-$(CONFIG_ARMV7_PSCI) += psci.o
board/freescale/ls1021atwr/psci.S new file +28 -0
new file mode 100644
index 0000000..adf5b85
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2016 NXP Semiconductor.
+ * Author: Wang Dongsheng <[email protected]>
+ *
+ * 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
include/configs/ls1021aqds.h +3 -0
index f605ca6..839a8c7 100644
@@ -10,6 +10,7 @@
 #define CONFIG_LS102XA
 
 #define CONFIG_ARMV7_PSCI
+#define CONFIG_ARMV7_PSCI_1_0
 
 #define CONFIG_SYS_FSL_CLK
 
@@ -279,6 +280,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
include/configs/ls1021atwr.h +1 -0
index 32d2acc..ea655c8 100644
@@ -10,6 +10,7 @@
 #define CONFIG_LS102XA
 
 #define CONFIG_ARMV7_PSCI
+#define CONFIG_ARMV7_PSCI_1_0
 
 #define CONFIG_SYS_FSL_CLK
 
Signature · 1 line
2.1.4
#13 lore raw

PATCH v4 9/9 ARMv7: PSCI: ls102xa: move secure text section into OCRAM

In reply to macro.wave.z at gmail.com

From: Hongbo Zhang <[email protected]>

LS1021 offers two secure OCRAM blocks for trustzone. This patch moves all the secure text sections into the OCRAM.

---
 arch/arm/include/asm/arch-ls102xa/config.h | 2 +-
 include/configs/ls1021atwr.h               | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)
arch/arm/include/asm/arch-ls102xa/config.h +1 -1
index 7a0e4bf..4729044 100644
@@ -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
 
include/configs/ls1021atwr.h +2 -0
index ea655c8..bdbd1fc 100644
@@ -12,6 +12,8 @@
 #define CONFIG_ARMV7_PSCI
 #define CONFIG_ARMV7_PSCI_1_0
 
+#define CONFIG_ARMV7_SECURE_BASE	OCRAM_BASE_S_ADDR
+
 #define CONFIG_SYS_FSL_CLK
 
 #define CONFIG_DISPLAY_CPUINFO
Signature · 1 line
2.1.4