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 "# );