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>
This commit is contained in:
parent
d65aba8286
commit
56bd9678ef
@ -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
|
* 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
|
* state (eg: initialized by the bootloader). This little code reproduces
|
||||||
* this behavior.
|
* 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)
|
static void write_bootloader(void *ptr, hwaddr kernel_addr)
|
||||||
{
|
{
|
||||||
uint32_t *p = ptr;
|
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 */
|
/* Initialize the UARTs */
|
||||||
/* *UART_CONTROL = UART_RECEIVE_ENABLE | UART_TRANSMIT_ENABLE; */
|
/* *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; */
|
/* *GPTIMER0_CONFIG = GPTIMER_ENABLE | GPTIMER_RESTART; */
|
||||||
p = gen_store_u32(p, 0x80000318, 3);
|
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 */
|
/* JUMP to the entry point */
|
||||||
stl_p(p++, 0x82100000); /* mov %g0, %g1 */
|
stl_p(p++, 0x82100000); /* mov %g0, %g1 */
|
||||||
stl_p(p++, 0x03000000 + extract32(kernel_addr, 10, 22));
|
stl_p(p++, 0x03000000 + extract32(kernel_addr, 10, 22));
|
||||||
|
Loading…
Reference in New Issue
Block a user