[U-Boot] [PATCH v5 4/8] ARMv7: PSCI: add codes to save context ID for CPU_ON
Chen-Yu Tsai
wens at csie.org
Tue Jun 28 05:15:52 CEST 2016
Hi,
On Tue, Jun 14, 2016 at 3:01 PM, <macro.wave.z at gmail.com> wrote:
> From: Hongbo Zhang <hongbo.zhang at nxp.com>
>
> 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.
Interesting. This doesn't seem to be used by Linux yet. This led me using r3
as a scratch register. See below.
>
> Signed-off-by: Hongbo Zhang <hongbo.zhang at nxp.com>
> Signed-off-by: Wang Dongsheng <dongsheng.wang at nxp.com>
> ---
> arch/arm/cpu/armv7/nonsec_virt.S | 7 +++++++
> arch/arm/cpu/armv7/psci.S | 4 +++-
> arch/arm/include/asm/psci.h | 1 +
> 3 files changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S
> index b7563ed..6566643 100644
> --- a/arch/arm/cpu/armv7/nonsec_virt.S
> +++ b/arch/arm/cpu/armv7/nonsec_virt.S
> @@ -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
You should do this in psci_cpu_entry, for a couple of reasons:
- That is also where the target PC is loaded.
- It is PSCI specific.
- All first time SMC calls would go through _secure_monitor.
This includes when U-boot jumps into the kernel through
_do_nonsec_entry, at which point you don't have a proper value
stored, while U-boot passes 0 here. See:
http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/lib/bootm.c;h=0838d89907b9a2eb81f4ebb31d8c045e031c5e11;hb=HEAD#l324
> +#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 5b235df..3ba9e51 100644
> --- a/arch/arm/cpu/armv7/psci.S
> +++ b/arch/arm/cpu/armv7/psci.S
> @@ -253,7 +253,7 @@ ENTRY(psci_enable_smp)
> ENDPROC(psci_enable_smp)
> .weak psci_enable_smp
>
> -/* expects target CPU in r1, target PC in r2 */
> +/* expects target CPU in r1, target PC in r2, target conetxt ID in r3 */
> ENTRY(psci_cpu_on_common)
> push {lr}
>
> @@ -261,6 +261,8 @@ ENTRY(psci_cpu_on_common)
> bl psci_get_cpu_stack_top @ get stack top of target CPU
r3 get overwritten in psci_get_cpu_stack_top in
http://git.denx.de/?p=u-boot.git;a=commitdiff;h=dae08d228122e4ad296077106520a4db3ca17872
Some of the functions now follow the ARM calling conventions.
You should save r3 and possibly other registers across any function
calls.
Regards
ChenYu
> sub r5, r0, #PSCI_TARGET_PC_OFFSET
> str r2, [r5] @ store target PC
> + sub r5, r0, #PSCI_CONTEXT_ID_OFFSET
> + str r3, [r5] @ store target context ID
> dsb
>
> pop {pc}
> diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
> index cb08544..bedcd30 100644
> --- a/arch/arm/include/asm/psci.h
> +++ b/arch/arm/include/asm/psci.h
> @@ -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);
> --
> 2.1.4
>
More information about the U-Boot
mailing list