You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.1 KiB
ArmAsm
74 lines
2.1 KiB
ArmAsm
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
//
|
|
// Copyright (c) 2021 Andre Richter <andre.o.richter@gmail.com>
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
// Definitions
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
// Load the address of a symbol into a register, PC-relative.
|
|
//
|
|
// The symbol must lie within +/- 4 GiB of the Program Counter.
|
|
//
|
|
// # Resources
|
|
//
|
|
// - https://sourceware.org/binutils/docs-2.36/as/AArch64_002dRelocations.html
|
|
.macro ADR_REL register, symbol
|
|
adrp \register, \symbol
|
|
add \register, \register, #:lo12:\symbol
|
|
.endm
|
|
|
|
.equ _EL2, 0x8
|
|
.equ _core_id_mask, 0b11
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
// Public Code
|
|
//--------------------------------------------------------------------------------------------------
|
|
.section .text._start
|
|
|
|
//------------------------------------------------------------------------------
|
|
// fn _start()
|
|
//------------------------------------------------------------------------------
|
|
_start:
|
|
// Only proceed if the core executes in EL2. Park it otherwise.
|
|
mrs x0, CurrentEL
|
|
cmp x0, _EL2
|
|
b.ne .L_parking_loop
|
|
|
|
// Only proceed on the boot core. Park it otherwise.
|
|
mrs x1, MPIDR_EL1
|
|
and x1, x1, _core_id_mask
|
|
ldr x2, BOOT_CORE_ID // provided by bsp/__board_name__/cpu.rs
|
|
cmp x1, x2
|
|
b.ne .L_parking_loop
|
|
|
|
// If execution reaches here, it is the boot core.
|
|
|
|
// Initialize DRAM.
|
|
ADR_REL x0, __bss_start
|
|
ADR_REL x1, __bss_end_exclusive
|
|
|
|
.L_bss_init_loop:
|
|
cmp x0, x1
|
|
b.eq .L_prepare_rust
|
|
stp xzr, xzr, [x0], #16
|
|
b .L_bss_init_loop
|
|
|
|
// Prepare the jump to Rust code.
|
|
.L_prepare_rust:
|
|
// Set the stack pointer. This ensures that any code in EL2 that needs the stack will work.
|
|
ADR_REL x0, __boot_core_stack_end_exclusive
|
|
mov sp, x0
|
|
|
|
// Jump to Rust code. x0 holds the function argument provided to _start_rust().
|
|
b _start_rust
|
|
|
|
// Infinitely wait for events (aka "park the core").
|
|
.L_parking_loop:
|
|
wfe
|
|
b .L_parking_loop
|
|
|
|
.size _start, . - _start
|
|
.type _start, function
|
|
.global _start
|