arm: cpu: Add ACPI parking protocol support
On Arm platforms that use ACPI they cannot rely on the "spin-table"
CPU bringup usually defined in the FDT. Thus implement the
'ACPI Multi-processor Startup for ARM Platforms', also referred to as
'ACPI parking protocol'.
The ACPI parking protocol works similar to the spin-table mechanism, but
the specification also covers lots of shortcomings of the spin-table
implementations.
Every CPU defined in the ACPI MADT table has it's own 4K page where the
spinloop code and the OS mailbox resides. When selected the U-Boot board
code must make sure that the secondary CPUs enter u-boot after relocation
as well, so that they can enter the spinloop code residing in the ACPI
parking protocol pages.
The OS will then write to the mailbox and generate an IPI to release the
CPUs from the spinloop code.
For now it's only implemented on ARMv8, but can easily be extended to
other platforms, like ARMv7.
TEST: Boots all CPUs on qemu-system-aarch64 -machine raspi4b
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Cc: Simon Glass <sjg@chromium.org>
Cc: Tom Rini <trini@konsulko.com>
diff --git a/lib/Kconfig b/lib/Kconfig
index 2e0fc1b..6ad079a 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -315,6 +315,22 @@
by the operating system. It defines platform-independent interfaces
for configuration and power management monitoring.
+config ACPI_PARKING_PROTOCOL
+ bool "Support ACPI parking protocol method"
+ depends on GENERATE_ACPI_TABLE
+ depends on ARMV8_MULTIENTRY
+ depends on BLOBLIST_TABLES
+ default y if !SEC_FIRMWARE_ARMV8_PSCI && !ARMV8_PSCI
+ help
+ Say Y here to support "ACPI parking protocol" enable method
+ for booting Linux.
+
+ To use this feature, you must do:
+ - Bring secondary CPUs into U-Boot proper in a board-specific
+ manner. This must be done *after* relocation. Otherwise, the
+ secondary CPUs will spin in unprotected memory-area because the
+ master CPU protects the relocated spin code.
+
config SPL_TINY_MEMSET
bool "Use a very small memset() in SPL"
depends on SPL