You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
2.6 KiB

# TODO rewrite in Rust, use crate cortex-a
.section .text.boot
boot:
# read cpu affinity, start core 0, halt rest
mrs x1, mpidr_el1
and x1, x1, #3
cbz x1, setup
halt:
# core affinity != 0, halt it
wfe
b halt
setup:
# store the desired EL1 stack pointer in x1
ldr x1, =_start
# use SP_ELx for Exception level ELx
msr SPsel, #1
# read the current exception level into x0 (ref: C5.2.1)
mrs x0, CurrentEL
and x0, x0, #0b1100
lsr x0, x0, #2
switch_to_el2:
# switch to EL2 if we're in EL3. otherwise switch to EL1
cmp x0, #2
beq switch_to_el1
# set-up SCR_EL3 (bits 0, 4, 5, 7, 8, 10) (A53: 4.3.42)
mov x0, #0x5b1
msr scr_el3, x0
# set-up SPSR_EL3 (bits 0, 3, 6, 7, 8, 9) (ref: C5.2.20)
mov x0, #0x3c9
msr spsr_el3, x0
# switch
adr x0, switch_to_el1
msr elr_el3, x0
eret
switch_to_el1:
# switch to EL1 if we're not already in EL1. otherwise continue with start
cmp x0, #1
beq set_stack
# set the stack-pointer for EL1
msr sp_el1, x1
# set-up HCR_EL2, enable AArch64 in EL1 (bits 1, 31) (ref: D10.2.45)
mov x0, #0x0002
movk x0, #0x8000, lsl #16
msr hcr_el2, x0
# don't trap accessing SVE registers (ref: D10.2.30)
msr cptr_el2, xzr
# enable floating point and SVE (SIMD) (bits 20, 21) (ref: D10.2.29)
mrs x0, cpacr_el1
orr x0, x0, #(0x3 << 20)
msr cpacr_el1, x0
# Set SCTLR to known state (RES1: 11, 20, 22, 23, 28, 29) (ref: D10.2.100)
mov x0, #0x0800
movk x0, #0x30d0, lsl #16
msr sctlr_el1, x0
# set-up SPSR_EL2 (bits 0, 2, 6, 7, 8, 9) (ref: C5.2.19)
mov x0, #0x3c5
msr spsr_el2, x0
# enable CNTP for EL1/EL0 (ref: D7.5.2, D7.5.13)
# NOTE: This doesn't actually enable the counter stream.
mrs x0, cnthctl_el2
orr x0, x0, #3
msr cnthctl_el2, x0
msr cntvoff_el2, xzr
# switch
adr x0, set_stack
msr elr_el2, x0
eret
set_stack:
# set the current stack pointer
mov sp, x1
zero_bss:
# load the start address and number of bytes in BSS section
ldr x1, =sbss
ldr x2, =__bss_length
zero_bss_loop:
# zero out the BSS section, 64-bits at a time
cbz x2, zero_bss_loop_end
str xzr, [x1], #8
sub x2, x2, #8
cbnz x2, zero_bss_loop
zero_bss_loop_end:
b _start
.section .text.entry
.globl _start
_start:
# jump to rust_main, which shouldn't return. halt if it does
bl rust_main
b halt