[U-Boot] [PATCH v2 6/9] ARMv8: PCSI: Add generic ARMv8 PSCI code

Mark Rutland mark.rutland at arm.com
Thu Jan 15 20:43:54 CET 2015


Hi,

On Mon, Jan 12, 2015 at 08:56:45PM +0000, Arnab Basu wrote:
> Implement core support for PSCI. As this is generic code, it doesn't
> implement anything really useful (all the functions are returning
> Not Implemented).
> 
> This is largely ported from the similar code that exists for ARMv7
> 
> Signed-off-by: Arnab Basu <arnab_basu at rocketmail.com>
> Cc: Bhupesh Sharma <bhupesh.sharma at freescale.com>
> Cc: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  arch/arm/cpu/armv8/Makefile      |   3 +-
>  arch/arm/cpu/armv8/psci.S        | 162 +++++++++++++++++++++++++++++++++++++++
>  arch/arm/include/asm/armv8/esr.h |  12 +++
>  3 files changed, 176 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/cpu/armv8/psci.S
>  create mode 100644 arch/arm/include/asm/armv8/esr.h
> 
> diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
> index 74c32b2..1c696ea 100644
> --- a/arch/arm/cpu/armv8/Makefile
> +++ b/arch/arm/cpu/armv8/Makefile
> @@ -16,4 +16,5 @@ obj-y	+= tlb.o
>  obj-y	+= transition.o
>  obj-y	+= cpu-dt.o
>  
> -obj-$(CONFIG_FSL_LSCH3) += fsl-lsch3/
> +obj-$(CONFIG_ARMV8_PSCI)	+= psci.o
> +obj-$(CONFIG_FSL_LSCH3) 	+= fsl-lsch3/
> diff --git a/arch/arm/cpu/armv8/psci.S b/arch/arm/cpu/armv8/psci.S
> new file mode 100644
> index 0000000..6028020
> --- /dev/null
> +++ b/arch/arm/cpu/armv8/psci.S
> @@ -0,0 +1,162 @@
> +/*
> + * (C) Copyright 2014
> + * Arnab Basu <arnab.basu at freescale.com>
> + * (C) Copyright 2015
> + * Arnab Basu <arnab_basu at rocketmail.com>
> + *
> + * Based on arch/arm/cpu/armv7/psci.S
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#include <linux/linkage.h>
> +#include <asm/psci.h>
> +#include <asm/armv8/esr.h>
> +
> +#define PSCI_FN(__id, __fn) \
> +        .quad __id; \
> +        .quad __fn
> +
> +.pushsection ._secure.text, "ax"
> +
> +ENTRY(psci_0_2_cpu_suspend_64)
> +ENTRY(psci_0_2_cpu_on_64)
> +ENTRY(psci_0_2_affinity_info_64)
> +ENTRY(psci_0_2_migrate_64)
> +ENTRY(psci_0_2_migrate_info_up_cpu_64)
> +	mov	x0, #ARM_PSCI_RET_NI	/* Return -1 (Not Implemented) */
> +	ret
> +ENDPROC(psci_0_2_cpu_suspend_64)
> +ENDPROC(psci_0_2_cpu_on_64)
> +ENDPROC(psci_0_2_affinity_info_64)
> +ENDPROC(psci_0_2_migrate_64)
> +ENDPROC(psci_0_2_migrate_info_up_cpu_64)
> +.weak psci_0_2_cpu_suspend_64
> +.weak psci_0_2_cpu_on_64
> +.weak psci_0_2_affinity_info_64
> +.weak psci_0_2_migrate_64
> +.weak psci_0_2_migrate_info_up_cpu_64

You also need to have MIGRATE_INFO_TYPE, which I didn't spot here or
elsewhere in this patch.

We need that to be able to detect and handle UP Trusted OSs (i.e.
firmware) which requires a particular CPU to remain enabled at all
times. While mainline Linux doesn't have that yet, it's coming shortly.

Do you require that a particular CPU remains online? If so you will need
to have MIGRATE_INFO_TYPE return 1, and MIGRATE_INFO_UP_CPU return the
MPIDR.Aff* fields for the CPU which must remain on.

If any arbitrary CPU can be disabled, it should return 2 (Trusted OS is
either not present or does not require migration).

Thanks,
Mark

> +
> +ENTRY(psci_0_2_psci_version)
> +	mov	x0, #2			/* Return Major = 0, Minor = 2*/
> +	ret
> +ENDPROC(psci_0_2_psci_version)
> +
> +.align 4
> +_psci_0_2_table:
> +	PSCI_FN(PSCI_0_2_FN_PSCI_VERSION, psci_0_2_psci_version)
> +	PSCI_FN(PSCI_0_2_FN64_CPU_SUSPEND, psci_0_2_cpu_suspend_64)
> +	PSCI_FN(PSCI_0_2_FN64_CPU_ON, psci_0_2_cpu_on_64)
> +	PSCI_FN(PSCI_0_2_FN64_AFFINITY_INFO, psci_0_2_affinity_info_64)
> +	PSCI_FN(PSCI_0_2_FN64_MIGRATE, psci_0_2_migrate_64)
> +	PSCI_FN(PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU, psci_0_2_migrate_info_up_cpu_64)
> +	PSCI_FN(0, 0)
> +
> +.macro	psci_enter
> +	stp	x29, x30, [sp, #-16]!
> +	stp	x27, x28, [sp, #-16]!
> +	stp	x25, x26, [sp, #-16]!
> +	stp	x23, x24, [sp, #-16]!
> +	stp	x21, x22, [sp, #-16]!
> +	stp	x19, x20, [sp, #-16]!
> +        str     x18, [sp, #-8]!
> +        mrs     x16, sp_el0
> +        mrs     x15, elr_el3
> +	stp	x15, x16, [sp, #-16]!
> +
> +	/* Switching to Secure State to Execute U-Boot */
> +	mrs	x4, scr_el3
> +	bic	x4, x4, #1
> +	msr	scr_el3, x4
> +.endm
> +
> +.macro	psci_return
> +	/* Switching to Non-Secure State to Execute OS */
> +	mrs	x4, scr_el3
> +	orr	x4, x4, #1
> +	msr	scr_el3, x4
> +
> +        ldp     x15, x16, [sp], #16
> +        msr     elr_el3, x15
> +        msr     sp_el0, x16
> +        ldr     x18, [sp], #8
> +	ldp	x19, x20, [sp], #16
> +	ldp	x21, x22, [sp], #16
> +	ldp	x23, x24, [sp], #16
> +	ldp	x25, x26, [sp], #16
> +	ldp	x27, x28, [sp], #16
> +	ldp	x29, x30, [sp], #16
> +	eret
> +.endm
> +
> +ENTRY(_smc_psci)
> +	psci_enter
> +	adr	x4, _psci_0_2_table
> +1:	ldp	x5, x6, [x4]	      /* Load PSCI function ID and target PC */
> +	cbz	x5, fn_not_found      /* If reach the end, bail out */
> +	cmp	x0, x5		      /* If not matching, try next entry */
> +	b.eq	fn_call
> +	add	x4, x4, #16
> +	b	1b
> +
> +fn_call:
> +	blr	x6
> +	psci_return
> +
> +fn_not_found:
> +	mov	x0, #ARM_PSCI_RET_NI    /* Return -1 (Not Supported) */
> +	psci_return
> +ENDPROC(_smc_psci)
> +
> +ENTRY(unhandled_exception)
> +/* Returning to the place that caused the exception has the potential to cause
> + * an endless loop of taking the same exception over and over again. Looping
> + * here seems marginally better
> + */
> +1:      b       1b
> +ENDPROC(unhandled_exception)
> +
> +__handle_sync:
> +	str 	x4, [sp, #-8]!
> +	mrs	x4, esr_el3
> +	ubfx	x4, x4, #26, #6
> +	cmp	x4, #ESR_EC_SMC64
> +	b.eq	smc_found
> +	ldr	x4, [sp], #8
> +	b	unhandled_exception
> +smc_found:
> +	ldr     x4, [sp], #8
> +	b	_smc_psci
> +
> +/*
> + * PSCI Exception vectors.
> + */
> +	.align	11
> +	.globl	psci_vectors
> +psci_vectors:
> +	.align	7
> +	b	unhandled_exception	/* Current EL Synchronous Thread */
> +	.align	7
> +	b	unhandled_exception	/* Current EL IRQ Thread */
> +	.align	7
> +	b	unhandled_exception	/* Current EL FIQ Thread */
> +	.align	7
> +	b	unhandled_exception	/* Current EL Error Thread */
> +	.align	7
> +	b	unhandled_exception	/* Current EL Synchronous Handler */
> +	.align	7
> +	b	unhandled_exception	/* Current EL IRQ Handler */
> +	.align	7
> +	b	unhandled_exception	/* Current EL FIQ Handler */
> +	.align	7
> +	b	unhandled_exception	/* Current EL Error Handler */
> +	.align	7
> +	b	__handle_sync		/* Lower EL Synchronous (64b) */
> +	.align	7
> +	b	unhandled_exception	/* Lower EL IRQ (64b) */
> +	.align	7
> +	b	unhandled_exception	/* Lower EL FIQ (64b) */
> +	.align	7
> +	b	unhandled_exception	/* Lower EL Error (64b) */
> +
> +.popsection
> diff --git a/arch/arm/include/asm/armv8/esr.h b/arch/arm/include/asm/armv8/esr.h
> new file mode 100644
> index 0000000..59d4289
> --- /dev/null
> +++ b/arch/arm/include/asm/armv8/esr.h
> @@ -0,0 +1,12 @@
> +/*
> + * Copyright 2015, Arnab Basu <arnab_basu at rocketmail.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#ifndef _ARMV8_ESR_H
> +#define _ARMV8_ESR_H
> +
> +#define ESR_EC_SMC64	(0x17)
> +
> +#endif /* _ARMV8_ESR_H */
> -- 
> 1.9.1
> 
> 


More information about the U-Boot mailing list