diff options
author | Clément Chigot <chigot@adacore.com> | 2025-05-26 10:55:20 +0200 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2025-06-13 11:31:28 +0100 |
commit | 5dc8e4e892ba10e040d12afece0d36b8b6a269d6 (patch) | |
tree | 378b6004ecfc46a3b8c81a37e58357349582c7a0 | |
parent | 73cdd846adb80060fbdb2f2557aeafb41cb39064 (diff) | |
download | qemu-5dc8e4e892ba10e040d12afece0d36b8b6a269d6.zip qemu-5dc8e4e892ba10e040d12afece0d36b8b6a269d6.tar.gz qemu-5dc8e4e892ba10e040d12afece0d36b8b6a269d6.tar.bz2 |
hw/arm: make cpu targeted by arm_load_kernel the primary CPU.
Currently, arm booting processus assumes that the first_cpu is the CPU
that will boot: `arm_load_kernel` is powering off all but the `first_cpu`;
`do_cpu_reset` is setting the loader address only for this `first_cpu`.
For most of the boards, this isn't an issue as the kernel is loaded and
booted on the first CPU anyway. However, for zynqmp, the option
"boot-cpu" allows to choose any CPUs.
Create a new arm_boot_info entry `primary_cpu` recording which CPU will
be boot first. This one is set when `arm_boot_kernel` is called.
Signed-off-by: Clément Chigot <chigot@adacore.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20250526085523.809003-2-chigot@adacore.com
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/arm/boot.c | 15 | ||||
-rw-r--r-- | include/hw/arm/boot.h | 3 |
2 files changed, 10 insertions, 8 deletions
diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 79afb51..3c93d87 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -744,7 +744,7 @@ static void do_cpu_reset(void *opaque) } else { if (arm_feature(env, ARM_FEATURE_EL3) && (info->secure_boot || - (info->secure_board_setup && cs == first_cpu))) { + (info->secure_board_setup && cpu == info->primary_cpu))) { /* Start this CPU in Secure SVC */ target_el = 3; } @@ -752,7 +752,7 @@ static void do_cpu_reset(void *opaque) arm_emulate_firmware_reset(cs, target_el); - if (cs == first_cpu) { + if (cpu == info->primary_cpu) { AddressSpace *as = arm_boot_address_space(cpu, info); cpu_set_pc(cs, info->loader_start); @@ -1239,6 +1239,9 @@ void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info) info->dtb_filename = ms->dtb; info->dtb_limit = 0; + /* We assume the CPU passed as argument is the primary CPU. */ + info->primary_cpu = cpu; + /* Load the kernel. */ if (!info->kernel_filename || info->firmware_loaded) { arm_setup_firmware_boot(cpu, info); @@ -1288,12 +1291,8 @@ void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info) object_property_set_int(cpuobj, "psci-conduit", info->psci_conduit, &error_abort); - /* - * Secondary CPUs start in PSCI powered-down state. Like the - * code in do_cpu_reset(), we assume first_cpu is the primary - * CPU. - */ - if (cs != first_cpu) { + /* Secondary CPUs start in PSCI powered-down state. */ + if (ARM_CPU(cs) != info->primary_cpu) { object_property_set_bool(cpuobj, "start-powered-off", true, &error_abort); } diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h index b12bf61..a2e22bd 100644 --- a/include/hw/arm/boot.h +++ b/include/hw/arm/boot.h @@ -132,6 +132,9 @@ struct arm_boot_info { bool secure_board_setup; arm_endianness endianness; + + /* CPU having load the kernel and that should be the first to boot. */ + ARMCPU *primary_cpu; }; /** |