diff mbox series

[v4,12/30] arm64: Add support for setting up the PSCI conduit through ACPI

Message ID 20230213101759.2577077-13-nikos.nikoleris@arm.com (mailing list archive)
State New, archived
Headers show
Series EFI and ACPI support for arm64 | expand

Commit Message

Nikos Nikoleris Feb. 13, 2023, 10:17 a.m. UTC
In systems with ACPI support and when a DT is not provided, we can use
the FADT to discover whether PSCI calls need to use smc or hvc
calls. This change implements this but retains the default behavior;
we check if a valid DT is provided, if not, we try to setup the PSCI
conduit using ACPI.

Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Ricardo Koller <ricarkol@google.com>
---
 arm/Makefile.arm64 |  4 ++++
 lib/acpi.h         |  5 +++++
 lib/arm/psci.c     | 37 ++++++++++++++++++++++++++++++++++++-
 3 files changed, 45 insertions(+), 1 deletion(-)

Comments

Andrew Jones March 21, 2023, 5:31 p.m. UTC | #1
On Mon, Feb 13, 2023 at 10:17:41AM +0000, Nikos Nikoleris wrote:
> In systems with ACPI support and when a DT is not provided, we can use
> the FADT to discover whether PSCI calls need to use smc or hvc
> calls. This change implements this but retains the default behavior;
> we check if a valid DT is provided, if not, we try to setup the PSCI
> conduit using ACPI.
> 
> Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
> Reviewed-by: Andrew Jones <drjones@redhat.com>
> Reviewed-by: Ricardo Koller <ricarkol@google.com>
> ---
>  arm/Makefile.arm64 |  4 ++++
>  lib/acpi.h         |  5 +++++
>  lib/arm/psci.c     | 37 ++++++++++++++++++++++++++++++++++++-
>  3 files changed, 45 insertions(+), 1 deletion(-)
> 
> diff --git a/arm/Makefile.arm64 b/arm/Makefile.arm64
> index 42e18e77..6dff6cad 100644
> --- a/arm/Makefile.arm64
> +++ b/arm/Makefile.arm64
> @@ -25,6 +25,10 @@ cflatobjs += lib/arm64/processor.o
>  cflatobjs += lib/arm64/spinlock.o
>  cflatobjs += lib/arm64/gic-v3-its.o lib/arm64/gic-v3-its-cmd.o
>  
> +ifeq ($(CONFIG_EFI),y)
> +cflatobjs += lib/acpi.o
> +endif

This is already in arm/Makefile.common due to an earlier patch in
this series. Putting it in Makefile.arm64 makes more sense, though,
so let's just drop the earlier patch.

Thanks,
drew
diff mbox series

Patch

diff --git a/arm/Makefile.arm64 b/arm/Makefile.arm64
index 42e18e77..6dff6cad 100644
--- a/arm/Makefile.arm64
+++ b/arm/Makefile.arm64
@@ -25,6 +25,10 @@  cflatobjs += lib/arm64/processor.o
 cflatobjs += lib/arm64/spinlock.o
 cflatobjs += lib/arm64/gic-v3-its.o lib/arm64/gic-v3-its-cmd.o
 
+ifeq ($(CONFIG_EFI),y)
+cflatobjs += lib/acpi.o
+endif
+
 OBJDIRS += lib/arm64
 
 # arm64 specific tests
diff --git a/lib/acpi.h b/lib/acpi.h
index 38b6d5c9..5ba6e29d 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -129,6 +129,11 @@  struct acpi_table_fadt {
 	u64 hypervisor_id;	/* Hypervisor Vendor ID (ACPI 6.0) */
 };
 
+/* Masks for FADT ARM Boot Architecture Flags (arm_boot_flags) ACPI 5.1 */
+
+#define ACPI_FADT_PSCI_COMPLIANT    (1)	/* 00: [V5+] PSCI 0.2+ is implemented */
+#define ACPI_FADT_PSCI_USE_HVC      (1<<1)	/* 01: [V5+] HVC must be used instead of SMC as the PSCI conduit */
+
 struct acpi_table_facs_rev1 {
 	u32 signature;		/* ACPI Signature */
 	u32 length;		/* Length of structure, in bytes */
diff --git a/lib/arm/psci.c b/lib/arm/psci.c
index 9c031a12..bddb0787 100644
--- a/lib/arm/psci.c
+++ b/lib/arm/psci.c
@@ -56,7 +56,7 @@  void psci_system_off(void)
 	printf("CPU%d unable to do system off (error = %d)\n", smp_processor_id(), err);
 }
 
-void psci_set_conduit(void)
+static void psci_set_conduit_fdt(void)
 {
 	const void *fdt = dt_fdt();
 	const struct fdt_property *method;
@@ -75,3 +75,38 @@  void psci_set_conduit(void)
 	else
 		assert_msg(false, "Unknown PSCI conduit: %s", method->data);
 }
+
+#ifdef CONFIG_EFI
+
+#include <acpi.h>
+
+static void psci_set_conduit_acpi(void)
+{
+	struct acpi_table_fadt *fadt = find_acpi_table_addr(FACP_SIGNATURE);
+
+	assert_msg(fadt, "Unable to find ACPI FADT");
+	assert_msg(fadt->arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT,
+		   "PSCI is not supported in this platform");
+
+	if (fadt->arm_boot_flags & ACPI_FADT_PSCI_USE_HVC)
+		psci_invoke = psci_invoke_hvc;
+	else
+		psci_invoke = psci_invoke_smc;
+}
+
+#else
+
+static void psci_set_conduit_acpi(void)
+{
+	assert_msg(false, "ACPI not available");
+}
+
+#endif
+
+void psci_set_conduit(void)
+{
+	if (dt_available())
+		psci_set_conduit_fdt();
+	else
+		psci_set_conduit_acpi();
+}