diff options
author | Clément Chigot <chigot@adacore.com> | 2024-01-31 09:50:46 +0100 |
---|---|---|
committer | Philippe Mathieu-Daudé <philmd@linaro.org> | 2024-02-15 16:58:46 +0100 |
commit | 56bd9678ef553498274f1d29ebb2839f220bce6d (patch) | |
tree | b1f37e949164d529abfa8b259894878fd6cbb97e /hw | |
parent | d65aba8286e40bc02f26f19e53fa20c9396d02e7 (diff) |
hw/sparc/leon3: check cpu_id in the tiny bootloader
Now that SMP is possible, the asr17 must be checked in the little boot
code or the secondary CPU will reinitialize the Timer and the Uart.
Co-developed-by: Frederic Konrad <konrad.frederic@yahoo.fr>
Signed-off-by: Clément Chigot <chigot@adacore.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240131085047.18458-9-chigot@adacore.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/sparc/leon3.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index 1637900162..bea84f3ad6 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -99,12 +99,26 @@ static uint32_t *gen_store_u32(uint32_t *code, hwaddr addr, uint32_t val) /* * When loading a kernel in RAM the machine is expected to be in a different - * state (eg: initialized by the bootloader). This little code reproduces - * this behavior. + * state (eg: initialized by the bootloader). This little code reproduces + * this behavior. Also this code can be executed by the secondary cpus as + * well since it looks at the %asr17 register before doing any + * initialization, it allows to use the same reset address for all the + * cpus. */ static void write_bootloader(void *ptr, hwaddr kernel_addr) { uint32_t *p = ptr; + uint32_t *sec_cpu_branch_p = NULL; + + /* If we are running on a secondary CPU, jump directly to the kernel. */ + + stl_p(p++, 0x85444000); /* rd %asr17, %g2 */ + stl_p(p++, 0x8530a01c); /* srl %g2, 0x1c, %g2 */ + stl_p(p++, 0x80908000); /* tst %g2 */ + /* Filled below. */ + sec_cpu_branch_p = p; + stl_p(p++, 0x0BADC0DE); /* bne xxx */ + stl_p(p++, 0x01000000); /* nop */ /* Initialize the UARTs */ /* *UART_CONTROL = UART_RECEIVE_ENABLE | UART_TRANSMIT_ENABLE; */ @@ -118,6 +132,10 @@ static void write_bootloader(void *ptr, hwaddr kernel_addr) /* *GPTIMER0_CONFIG = GPTIMER_ENABLE | GPTIMER_RESTART; */ p = gen_store_u32(p, 0x80000318, 3); + /* Now, the relative branch above can be computed. */ + stl_p(sec_cpu_branch_p, 0x12800000 + + (p - sec_cpu_branch_p)); + /* JUMP to the entry point */ stl_p(p++, 0x82100000); /* mov %g0, %g1 */ stl_p(p++, 0x03000000 + extract32(kernel_addr, 10, 22)); |