[BOOT-WRAPPER v3 10/10] Boot CPUs sequentially
Andre Przywara
andre.przywara at arm.com
Thu Aug 22 09:11:13 PDT 2024
On Thu, 22 Aug 2024 11:14:41 +0100
Mark Rutland <mark.rutland at arm.com> wrote:
Hi,
> Currently the boot-wrapper initializes all CPUs in parallel. This means
> that we cannot log errors as they happen, as this would mean multiple
> CPUs concurrently writing to the UART, producing garbled output. To
> produce meaningful output we have to special-case errors on the boot CPU
> and hope CPUs have been configured consistently.
>
> To make it easier to handle errors, boot CPUs sequentially so that errors
> can be logged as they happen. With this change it's pretty clear that
> the cpu_init_bootmethod() abstraction isn't helpful, and so this is
> removed with cpu_init_arch() directly initializing PSCI where necessary.
>
> When things go well this looks like:
>
> | Boot-wrapper v0.2
> | Entered at EL3
> | Memory layout:
> | [0000000080000000..0000000080001f90] => boot-wrapper
> | [000000008000fff8..0000000080010000] => mbox
> | [0000000080200000..0000000082cbaa00] => kernel
> | [0000000088000000..0000000088002df1] => dtb
> | CPU0: (MPIDR 0000000000000000) initializing...
> | CPU1: (MPIDR 0000000000000100) initializing...
> | CPU2: (MPIDR 0000000000000200) initializing...
> | CPU3: (MPIDR 0000000000000300) initializing...
> | CPU4: (MPIDR 0000000000010000) initializing...
> | CPU5: (MPIDR 0000000000010100) initializing...
> | CPU6: (MPIDR 0000000000010200) initializing...
> | CPU7: (MPIDR 0000000000010300) initializing...
> | All CPUs initialized. Entering kernel...
> |
> | [ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd0f0]
>
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Acked-by: Marc Zyngier <maz at kernel.org>
> Cc: Akos Denke <akos.denke at arm.com>
> Cc: Andre Przywara <andre.przywara at arm.com>
> Cc: Luca Fancellu <luca.fancellu at arm.com>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
Cheers,
Andre
> ---
> arch/aarch32/boot.S | 2 --
> arch/aarch32/init.c | 17 ++++++++++------
> arch/aarch64/boot.S | 2 --
> arch/aarch64/init.c | 17 ++++++++++------
> arch/aarch64/spin.S | 3 ---
> common/init.c | 48 ++++++++++++++++++++++++++++++++++++---------
> common/psci.c | 14 -------------
> include/boot.h | 6 +-----
> 8 files changed, 62 insertions(+), 47 deletions(-)
>
> diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
> index cff8291..0d9cdc2 100644
> --- a/arch/aarch32/boot.S
> +++ b/arch/aarch32/boot.S
> @@ -70,8 +70,6 @@ reset_common:
>
> bl cpu_init_bootwrapper
>
> - bl cpu_init_arch
> -
> b start_bootmethod
>
> err_invalid_id:
> diff --git a/arch/aarch32/init.c b/arch/aarch32/init.c
> index cb67bf6..d08ac83 100644
> --- a/arch/aarch32/init.c
> +++ b/arch/aarch32/init.c
> @@ -6,6 +6,7 @@
> * Use of this source code is governed by a BSD-style license that can be
> * found in the LICENSE.txt file.
> */
> +#include <boot.h>
> #include <cpu.h>
> #include <gic.h>
> #include <platform.h>
> @@ -43,24 +44,28 @@ static void cpu_init_monitor(void)
> #ifdef PSCI
> extern char psci_vectors[];
>
> -bool cpu_init_psci_arch(void)
> +static void cpu_init_psci_arch(unsigned int cpu)
> {
> - if (read_cpsr_mode() != PSR_MON)
> - return false;
> + if (read_cpsr_mode() != PSR_MON) {
> + print_cpu_warn(cpu, "PSCI could not be initialized (not booted at PL1).\r\n");
> + return;
> + }
>
> mcr(MVBAR, (unsigned long)psci_vectors);
> isb();
> -
> - return true;
> }
> +#else
> +static static void cpu_init_psci_arch(unsigned int cpu) { }
> #endif
>
> -void cpu_init_arch(void)
> +void cpu_init_arch(unsigned int cpu)
> {
> if (read_cpsr_mode() == PSR_MON) {
> cpu_init_monitor();
> gic_secure_init();
> }
>
> + cpu_init_psci_arch(cpu);
> +
> mcr(CNTFRQ, COUNTER_FREQ);
> }
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index 5b9634f..5060a6d 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -69,8 +69,6 @@ reset_common:
>
> bl cpu_init_bootwrapper
>
> - bl cpu_init_arch
> -
> b start_bootmethod
>
> err_invalid_id:
> diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c
> index 68c220b..63fa949 100644
> --- a/arch/aarch64/init.c
> +++ b/arch/aarch64/init.c
> @@ -6,6 +6,7 @@
> * Use of this source code is governed by a BSD-style license that can be
> * found in the LICENSE.txt file.
> */
> +#include <boot.h>
> #include <cpu.h>
> #include <gic.h>
> #include <platform.h>
> @@ -159,24 +160,28 @@ static void cpu_init_el3(void)
> #ifdef PSCI
> extern char psci_vectors[];
>
> -bool cpu_init_psci_arch(void)
> +static void cpu_init_psci_arch(unsigned int cpu)
> {
> - if (mrs(CurrentEL) != CURRENTEL_EL3)
> - return false;
> + if (mrs(CurrentEL) != CURRENTEL_EL3) {
> + print_cpu_warn(cpu, "PSCI could not be initialized (not booted at EL3).\r\n");
> + return;
> + }
>
> msr(VBAR_EL3, (unsigned long)psci_vectors);
> isb();
> -
> - return true;
> }
> +#else
> +static void cpu_init_psci_arch(unsigned int cpu) { }
> #endif
>
> -void cpu_init_arch(void)
> +void cpu_init_arch(unsigned int cpu)
> {
> if (mrs(CurrentEL) == CURRENTEL_EL3) {
> cpu_init_el3();
> gic_secure_init();
> }
>
> + cpu_init_psci_arch(cpu);
> +
> msr(CNTFRQ_EL0, COUNTER_FREQ);
> }
> diff --git a/arch/aarch64/spin.S b/arch/aarch64/spin.S
> index 6597ca1..8089cf9 100644
> --- a/arch/aarch64/spin.S
> +++ b/arch/aarch64/spin.S
> @@ -12,9 +12,6 @@
>
> .text
>
> -ASM_FUNC(cpu_init_bootmethod)
> - ret
> -
> ASM_FUNC(start_bootmethod)
> cpuid x0, x1
> bl find_logical_id
> diff --git a/common/init.c b/common/init.c
> index 3c05ac3..5ebccd4 100644
> --- a/common/init.c
> +++ b/common/init.c
> @@ -43,18 +43,48 @@ static void announce_objects(void)
>
> void announce_arch(void);
>
> +static void init_bootwrapper(void)
> +{
> + init_uart();
> + announce_bootwrapper();
> + announce_arch();
> + announce_objects();
> + init_platform();
> +}
> +
> +static void cpu_init_self(unsigned int cpu)
> +{
> + print_string("CPU");
> + print_uint_dec(cpu);
> + print_string(": (MPIDR ");
> + print_ulong_hex(read_mpidr());
> + print_string(") initializing...\r\n");
> +
> + cpu_init_arch(cpu);
> +}
> +
> void cpu_init_bootwrapper(void)
> {
> + static volatile unsigned int cpu_next = 0;
> unsigned int cpu = this_cpu_logical_id();
>
> - if (cpu == 0) {
> - init_uart();
> - announce_bootwrapper();
> - announce_arch();
> - announce_objects();
> - print_string("\r\n");
> - init_platform();
> - }
> + if (cpu == 0)
> + init_bootwrapper();
> +
> + while (cpu_next != cpu)
> + wfe();
> +
> + cpu_init_self(cpu);
> +
> + cpu_next = cpu + 1;
> + dsb(sy);
> + sev();
> +
> + if (cpu != 0)
> + return;
> +
> + while (cpu_next != NR_CPUS)
> + wfe();
>
> - cpu_init_bootmethod(cpu);
> + print_string("All CPUs initialized. Entering kernel...\r\n\r\n");
> }
> diff --git a/common/psci.c b/common/psci.c
> index 19cc315..5fe8999 100644
> --- a/common/psci.c
> +++ b/common/psci.c
> @@ -87,17 +87,3 @@ void __noreturn psci_first_spin(void)
>
> unreachable();
> }
> -
> -void cpu_init_bootmethod(unsigned int cpu)
> -{
> - if (cpu_init_psci_arch())
> - return;
> -
> - if (cpu == 0) {
> - print_string("WARNING: PSCI could not be initialized. Boot may fail\r\n\r\n");
> - return;
> - }
> -
> - while (1)
> - wfe();
> -}
> diff --git a/include/boot.h b/include/boot.h
> index 18b805d..12c9c5c 100644
> --- a/include/boot.h
> +++ b/include/boot.h
> @@ -17,10 +17,6 @@ void __noreturn spin(unsigned long *mbox, unsigned long invalid);
> void __noreturn first_spin(unsigned int cpu, unsigned long *mbox,
> unsigned long invalid_addr);
>
> -void cpu_init_bootmethod(unsigned int cpu);
> -
> -#ifdef PSCI
> -bool cpu_init_psci_arch(void);
> -#endif
> +void cpu_init_arch(unsigned int cpu);
>
> #endif
More information about the linux-arm-kernel
mailing list