[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 8/9] leon3: check cpu_id in the tiny bootloader
|
From: |
Clément Chigot |
|
Subject: |
[PATCH 8/9] leon3: check cpu_id in the tiny bootloader |
|
Date: |
Fri, 5 Jan 2024 11:24:20 +0100 |
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>
---
hw/sparc/leon3.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index 38fb8d9af1..7498eaa827 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -98,13 +98,27 @@ 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(CPUSPARCState *env, uint8_t *base,
hwaddr kernel_addr)
{
uint32_t *p = (uint32_t *) base;
+ 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 */
+ /* Fill that later. */
+ 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(CPUSPARCState *env, uint8_t
*base,
/* *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));
--
2.25.1
- Re: [PATCH 3/9] intc/grlib_irqmp: implements the multiprocessor status register, (continued)
[PATCH 4/9] intc/grlib_irqmp: implements multicore irq, Clément Chigot, 2024/01/05
[PATCH 5/9] target/sparc: implement asr17 feature for smp, Clément Chigot, 2024/01/05
[PATCH 6/9] target/sparc: simplify qemu_irq_ack, Clément Chigot, 2024/01/05
[PATCH 7/9] leon3: implement multiprocessor, Clément Chigot, 2024/01/05
[PATCH 8/9] leon3: check cpu_id in the tiny bootloader,
Clément Chigot <=
[PATCH 9/9] MAINTAINERS: replace Fabien by myself as Leon3 maintainer, Clément Chigot, 2024/01/05