Files
k-os/crates/adapter-riscv/src/entry.rs

74 lines
1.5 KiB
Rust

use core::arch::global_asm;
// Entered with the MMU off at the physical address; the kernel is linked high.
// PC-relative code only: enable `boot_page_table` (RAM mapped low for the next
// instruction and high, MMIO high), then jump high and take the hart's stack.
global_asm!(
r#"
.section .text.entry
.globl _start
_start:
lla t2, start_high_address
j 1f
.globl _secondary_start
_secondary_start:
lla t2, secondary_high_address
1:
li t0, 8 # smp::MAX_HARTS
bgeu a0, t0, spin
mv s0, a0
lla t0, boot_page_table
srli t0, t0, 12
li t1, 8 << 60
or t0, t0, t1
csrw satp, t0
sfence.vma
ld t0, 0(t2)
jr t0
# sp = _stacks_start + (hart + 1) * smp::STACK_SLOT
start_high:
call hart_stack
mv a0, s0
call kmain
j spin
secondary_high:
call hart_stack
mv a0, s0
call kmain_secondary
j spin
hart_stack:
lla sp, _stacks_start
addi t0, s0, 1
li t1, 0x81000
mul t0, t0, t1
add sp, sp, t0
ret
spin:
wfi
j spin
.pushsection .rodata
.balign 8
start_high_address:
.quad start_high
secondary_high_address:
.quad secondary_high
.popsection
# Sv39 root of 1 GiB leaves; flags V|R|W|A|D = 0xc7, plus X = 0xcf.
.pushsection .data
.balign 4096
boot_page_table:
.quad 0
.quad 0
.quad 0x200000cf # [2] 0x8000_0000 -> RAM, for the jump only
.fill 253, 8, 0
.quad 0x000000c7 # [256] PHYS_OFFSET + 0 -> MMIO
.quad 0
.quad 0x200000cf # [258] PHYS_OFFSET + 0x8000_0000 -> RAM
.fill 253, 8, 0
.popsection
"#
);