diff mbox series

[v2,5/6] aarch64: Support PSCI for Armv8-R AArch64

Message ID 20240716142906.1502802-6-luca.fancellu@arm.com (mailing list archive)
State New, archived
Headers show
Series Add Armv8-R AArch64 support | expand

Commit Message

Luca Fancellu July 16, 2024, 2:29 p.m. UTC
Add support for PSCI when booting Linux on Armv8-R AArch64,
allow the autoconf parameter --enable-psci to take an argument
which is the conduit to be used, it can be empty or 'smc' to
select the smc conduit, it can be 'hvc' for the hvc conduit.

Depending on the selected conduit, the vector table will be
installed on the VBAR_EL3 or VBAR_EL2 register.

Signed-off-by: Luca Fancellu <luca.fancellu@arm.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
---
v2 changes:
 - Add Andre R-by
---
 Makefile.am         |  5 ++++-
 arch/aarch64/init.c | 15 ++++++++++++---
 configure.ac        | 16 +++++++++++-----
 3 files changed, 27 insertions(+), 9 deletions(-)

Comments

Mark Rutland July 29, 2024, 4:09 p.m. UTC | #1
On Tue, Jul 16, 2024 at 03:29:05PM +0100, Luca Fancellu wrote:
> Add support for PSCI when booting Linux on Armv8-R AArch64,
> allow the autoconf parameter --enable-psci to take an argument
> which is the conduit to be used, it can be empty or 'smc' to
> select the smc conduit, it can be 'hvc' for the hvc conduit.
> 
> Depending on the selected conduit, the vector table will be
> installed on the VBAR_EL3 or VBAR_EL2 register.
> 
> Signed-off-by: Luca Fancellu <luca.fancellu@arm.com>
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
> ---
> v2 changes:
>  - Add Andre R-by
> ---
>  Makefile.am         |  5 ++++-
>  arch/aarch64/init.c | 15 ++++++++++++---
>  configure.ac        | 16 +++++++++++-----
>  3 files changed, 27 insertions(+), 9 deletions(-)
> 
> diff --git a/Makefile.am b/Makefile.am
> index 6ebece25b230..34fbfb1f4ff8 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -49,11 +49,14 @@ endif
>  
>  if PSCI
>  DEFINES		+= -DPSCI
> +if PSCI_HVC
> +DEFINES		+= -DPSCI_HVC
> +endif
>  ARCH_OBJ	+= psci.o
>  COMMON_OBJ	+= psci.o
>  PSCI_NODE	:= psci {				\
>  			compatible = \"arm,psci\";	\
> -			method = \"smc\";		\
> +			method = \"$(PSCI_METHOD)\";	\
>  			cpu_on = <$(PSCI_CPU_ON)>;	\
>  			cpu_off = <$(PSCI_CPU_OFF)>;	\
>  		   };
> diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c
> index 9402a01b9dca..9b8bd8723dba 100644
> --- a/arch/aarch64/init.c
> +++ b/arch/aarch64/init.c
> @@ -179,10 +179,19 @@ extern char psci_vectors[];
>  
>  bool cpu_init_psci_arch(void)
>  {
> -	if (mrs(CurrentEL) != CURRENTEL_EL3)
> +	switch (mrs(CurrentEL)) {
> +#if !defined(PSCI_HVC)
> +	case CURRENTEL_EL3:
> +		msr(VBAR_EL3, (unsigned long)psci_vectors);
> +		break;
> +#else
> +	case CURRENTEL_EL2:
> +		msr(VBAR_EL2, (unsigned long)psci_vectors);
> +		break;
> +#endif
> +	default:
>  		return false;
> -
> -	msr(VBAR_EL3, (unsigned long)psci_vectors);
> +	}
>  	isb();
>  
>  	return true;
> diff --git a/configure.ac b/configure.ac
> index 9e3b7226cd69..44459a4c849e 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -83,13 +83,19 @@ AS_IF([test "x$X_IMAGE" != "x"],
>  # Allow a user to pass --enable-psci
>  AC_ARG_ENABLE([psci],
>  	AS_HELP_STRING([--disable-psci], [disable the psci boot method]),
> -	[USE_PSCI=$enableval], [USE_PSCI="yes"])
> -AM_CONDITIONAL([PSCI], [test "x$USE_PSCI" = "xyes"])
> -AS_IF([test "x$USE_PSCI" = "xyes"], [], [USE_PSCI=no])
> -
> -AS_IF([test "x$USE_PSCI" != "xyes" -a "x$KERNEL_ES" = "x32"],
> +	[case "${enableval}" in
> +		yes|smc) USE_PSCI=smc ;;
> +		hvc) USE_PSCI=hvc ;;
> +		no) ;;
> +		*) AC_MSG_ERROR([Bad value "${enableval}" for --enable-psci. Use "smc" or "hvc"]) ;;
> +	esac])
> +AM_CONDITIONAL([PSCI], [test "x$USE_PSCI" = "xyes" -o "x$USE_PSCI" = "xsmc" -o "x$USE_PSCI" = "xhvc"])
> +AM_CONDITIONAL([PSCI_HVC], [test "x$USE_PSCI" = "xhvc"])
> +
> +AS_IF([test "x$USE_PSCI" = "xno" -a "x$KERNEL_ES" = "x32"],
>  	[AC_MSG_ERROR([With an AArch32 kernel, boot method must be PSCI.])]
>  )
> +AC_SUBST([PSCI_METHOD], [$USE_PSCI])

As of this patch, if I build with --enable-psci=hvc, and boot on
ARMv8-A, it'll fail at boot time, since the boot-wrapper won't fix up
the SPSR (and will enter the kernel at EL2), and HVC will go to that
kernel.

I think that we either need to add support for dropping to EL1 in
ARMv8-A, or we should have an option to build for ARMv8-R specifically,
where we can automatically fix up the PSCI conduit.

Mark.
Luca Fancellu July 30, 2024, 11:31 a.m. UTC | #2
Hi Mark,

>> -
>> -AS_IF([test "x$USE_PSCI" != "xyes" -a "x$KERNEL_ES" = "x32"],
>> + [case "${enableval}" in
>> + yes|smc) USE_PSCI=smc ;;
>> + hvc) USE_PSCI=hvc ;;
>> + no) ;;
>> + *) AC_MSG_ERROR([Bad value "${enableval}" for --enable-psci. Use "smc" or "hvc"]) ;;
>> + esac])
>> +AM_CONDITIONAL([PSCI], [test "x$USE_PSCI" = "xyes" -o "x$USE_PSCI" = "xsmc" -o "x$USE_PSCI" = "xhvc"])
>> +AM_CONDITIONAL([PSCI_HVC], [test "x$USE_PSCI" = "xhvc"])
>> +
>> +AS_IF([test "x$USE_PSCI" = "xno" -a "x$KERNEL_ES" = "x32"],
>> [AC_MSG_ERROR([With an AArch32 kernel, boot method must be PSCI.])]
>> )
>> +AC_SUBST([PSCI_METHOD], [$USE_PSCI])
> 
> As of this patch, if I build with --enable-psci=hvc, and boot on
> ARMv8-A, it'll fail at boot time, since the boot-wrapper won't fix up
> the SPSR (and will enter the kernel at EL2), and HVC will go to that
> kernel.
> 
> I think that we either need to add support for dropping to EL1 in
> ARMv8-A, or we should have an option to build for ARMv8-R specifically,
> where we can automatically fix up the PSCI conduit.

True, maybe the best option is to have a flag to build for armv8r?
Would --armv8r64 be ok?

The behaviour would be:
 --armv8r64 without XEN -> starting at EL2 only, setting conduit to hvc, psci_vector to VBAR_EL2, drop to EL1 and start kernel
 --armv8r64 with XEN -> starting at EL2 only, psci not supported, keep xen at EL2

Cheers,
Luca
Mark Rutland July 30, 2024, 12:55 p.m. UTC | #3
On Tue, Jul 30, 2024 at 12:31:14PM +0100, Luca Fancellu wrote:
> Hi Mark,
> 
> >> -
> >> -AS_IF([test "x$USE_PSCI" != "xyes" -a "x$KERNEL_ES" = "x32"],
> >> + [case "${enableval}" in
> >> + yes|smc) USE_PSCI=smc ;;
> >> + hvc) USE_PSCI=hvc ;;
> >> + no) ;;
> >> + *) AC_MSG_ERROR([Bad value "${enableval}" for --enable-psci. Use "smc" or "hvc"]) ;;
> >> + esac])
> >> +AM_CONDITIONAL([PSCI], [test "x$USE_PSCI" = "xyes" -o "x$USE_PSCI" = "xsmc" -o "x$USE_PSCI" = "xhvc"])
> >> +AM_CONDITIONAL([PSCI_HVC], [test "x$USE_PSCI" = "xhvc"])
> >> +
> >> +AS_IF([test "x$USE_PSCI" = "xno" -a "x$KERNEL_ES" = "x32"],
> >> [AC_MSG_ERROR([With an AArch32 kernel, boot method must be PSCI.])]
> >> )
> >> +AC_SUBST([PSCI_METHOD], [$USE_PSCI])
> >
> > As of this patch, if I build with --enable-psci=hvc, and boot on
> > ARMv8-A, it'll fail at boot time, since the boot-wrapper won't fix up
> > the SPSR (and will enter the kernel at EL2), and HVC will go to that
> > kernel.
> >
> > I think that we either need to add support for dropping to EL1 in
> > ARMv8-A, or we should have an option to build for ARMv8-R specifically,
> > where we can automatically fix up the PSCI conduit.
> 
> True, maybe the best option is to have a flag to build for armv8r?

I think so.

> Would --armv8r64 be ok?
> 
> The behaviour would be:
>  --armv8r64 without XEN -> starting at EL2 only, setting conduit to hvc, psci_vector to VBAR_EL2, drop to EL1 and start kernel
>  --armv8r64 with XEN -> starting at EL2 only, psci not supported, keep xen at EL2

That sounds good. If you can sort out the logic for that, we can change
the option name later if we want.

That will have to interact with --enable-aarch32-bw and
--enable-aarch32-kernel, so maybe it's worth having a single option to
select the boot-wrapper architecture, e.g. --bw-arch=${PARAM} that
takes:

* "aarch64-a"	// default today
* "aarch32-a"	// replaces --aarch32-bw
* "aarch64-r"	// For armv8r64

Note I've used "aarch64" since we already have ARMv9-A bits.

Mark.

> 
> Cheers,
> Luca
>
diff mbox series

Patch

diff --git a/Makefile.am b/Makefile.am
index 6ebece25b230..34fbfb1f4ff8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,11 +49,14 @@  endif
 
 if PSCI
 DEFINES		+= -DPSCI
+if PSCI_HVC
+DEFINES		+= -DPSCI_HVC
+endif
 ARCH_OBJ	+= psci.o
 COMMON_OBJ	+= psci.o
 PSCI_NODE	:= psci {				\
 			compatible = \"arm,psci\";	\
-			method = \"smc\";		\
+			method = \"$(PSCI_METHOD)\";	\
 			cpu_on = <$(PSCI_CPU_ON)>;	\
 			cpu_off = <$(PSCI_CPU_OFF)>;	\
 		   };
diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c
index 9402a01b9dca..9b8bd8723dba 100644
--- a/arch/aarch64/init.c
+++ b/arch/aarch64/init.c
@@ -179,10 +179,19 @@  extern char psci_vectors[];
 
 bool cpu_init_psci_arch(void)
 {
-	if (mrs(CurrentEL) != CURRENTEL_EL3)
+	switch (mrs(CurrentEL)) {
+#if !defined(PSCI_HVC)
+	case CURRENTEL_EL3:
+		msr(VBAR_EL3, (unsigned long)psci_vectors);
+		break;
+#else
+	case CURRENTEL_EL2:
+		msr(VBAR_EL2, (unsigned long)psci_vectors);
+		break;
+#endif
+	default:
 		return false;
-
-	msr(VBAR_EL3, (unsigned long)psci_vectors);
+	}
 	isb();
 
 	return true;
diff --git a/configure.ac b/configure.ac
index 9e3b7226cd69..44459a4c849e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -83,13 +83,19 @@  AS_IF([test "x$X_IMAGE" != "x"],
 # Allow a user to pass --enable-psci
 AC_ARG_ENABLE([psci],
 	AS_HELP_STRING([--disable-psci], [disable the psci boot method]),
-	[USE_PSCI=$enableval], [USE_PSCI="yes"])
-AM_CONDITIONAL([PSCI], [test "x$USE_PSCI" = "xyes"])
-AS_IF([test "x$USE_PSCI" = "xyes"], [], [USE_PSCI=no])
-
-AS_IF([test "x$USE_PSCI" != "xyes" -a "x$KERNEL_ES" = "x32"],
+	[case "${enableval}" in
+		yes|smc) USE_PSCI=smc ;;
+		hvc) USE_PSCI=hvc ;;
+		no) ;;
+		*) AC_MSG_ERROR([Bad value "${enableval}" for --enable-psci. Use "smc" or "hvc"]) ;;
+	esac])
+AM_CONDITIONAL([PSCI], [test "x$USE_PSCI" = "xyes" -o "x$USE_PSCI" = "xsmc" -o "x$USE_PSCI" = "xhvc"])
+AM_CONDITIONAL([PSCI_HVC], [test "x$USE_PSCI" = "xhvc"])
+
+AS_IF([test "x$USE_PSCI" = "xno" -a "x$KERNEL_ES" = "x32"],
 	[AC_MSG_ERROR([With an AArch32 kernel, boot method must be PSCI.])]
 )
+AC_SUBST([PSCI_METHOD], [$USE_PSCI])
 
 # Allow a user to pass --with-initrd
 AC_ARG_WITH([initrd],