blob: 68e1a0aa2600cf0fdd17828eae5df909c4c2272b [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
/**
* Boot ROM runtime initialization code.
*/
// NOTE: The "ax" flag below is necessary to ensure that this section
// is allocated executable space in ROM by the linker.
.section .crt, "ax"
/**
* Entry point after reset. This symbol is jumped to from the handler
* for IRQ 0x80.
*
* Sets up the stack, then jumps to `_start`.
*/
_reset_start:
.globl _reset_start
// Clobber all writeable registers.
li x1, 0x0
li x2, 0x0
li x3, 0x0
li x4, 0x0
li x5, 0x0
li x6, 0x0
li x7, 0x0
li x8, 0x0
li x9, 0x0
li x10, 0x0
li x11, 0x0
li x12, 0x0
li x13, 0x0
li x14, 0x0
li x15, 0x0
li x16, 0x0
li x17, 0x0
li x18, 0x0
li x19, 0x0
li x20, 0x0
li x21, 0x0
li x22, 0x0
li x23, 0x0
li x24, 0x0
li x25, 0x0
li x26, 0x0
li x27, 0x0
li x28, 0x0
li x29, 0x0
li x30, 0x0
li x31, 0x0
// Set up the stack.
la sp, _stack_start
// Set up the global pointer. This requires that we disable linker relaxations
// (or it will be relaxed to `mv gp, gp`).
.option push
.option norelax
la gp, __global_pointer$
.option pop
// Explicit fall-through to `_start`.
/**
* Callable entry point for the boot rom.
*
* Currently, this zeroes the `.bss` section, copies initial data to
* `.data`, and then jumps to the program entry point.
*/
_start:
.globl _start
// Zero out the `.bss` segment.
//
// We use `t0` and `t1` to represent the start and end pointers
// of `.bss`.
la t0, _bss_start
la t1, _bss_end
bgeu t0, t1, bss_zero_loop_end
bss_zero_loop:
sw zero, 0(t0)
addi t0, t0, 0x4
bltu t0, t1, bss_zero_loop
bss_zero_loop_end:
// Zero out the stack
//
// We use `t0` and `t1` to represent the start and end pointers of the stack.
// As the stack grows downwards and we zero going forwards the start pointer
// starts as _stack_end and the end pointer at _stack_start
la t0, _stack_end
la t1, _stack_start
bgeu t0, t1, stack_zero_loop_end
stack_zero_loop:
sw zero, 0(t0)
addi t0, t0, 0x4
bltu t0, t1, stack_zero_loop
stack_zero_loop_end:
// Initialize the `.data` segment from the `.idata` segment.
//
// We use `t0` and `t1` to represent the start and end pointers
// of `.data`, `t2` to represent the start pointer of `.idata`
// (which has the same length as `.data`) and `t3` is a scratch
// register for the copy.
la t0, _data_start
la t1, _data_end
la t2, _data_init_start
bgeu t0, t1, data_copy_loop_end
data_copy_loop:
lw t3, 0(t2)
sw t3, 0(t0)
addi t0, t0, 0x4
addi t2, t2, 0x4
bltu t0, t1, data_copy_loop
data_copy_loop_end:
// Re-clobber all of the registers from above.
li t0, 0x0
li t1, 0x0
li t2, 0x0
li t3, 0x0
// Jump into the C program entry point.
call _boot_start
// Loop forever if _boot_start somehow returns.
1:
wfi
j 1b