.extern main .extern CONSOLE_STRICT_FLUSH .section .text.start .global _start .type _start, STT_FUNC _start: ## Have harts other than hart0 spin until hart0 wakes them up. As a ## side effect, load every hart's thread pointer register with MHARTID. csrr tp, mhartid bnez tp, wait_for_hart0 ## Set up hart0's stack. la sp, hart0_initial_stack_top ## Write a canary to hart0's stack. li t0, 0xdead0bad0defaced la t1, hart0_initial_stack sd t0, (t1) ## Put the address of the DeviceTree into the first argument position ## for hart0_boot. c.mv a0, a1 ### Set up trap handling. ## Set MENVCFG.STCE, to enable the Sstc extension, which will allow us ## to delegate timer interrupts to Supervisor mode. li t0, 1<<63 csrs menvcfg, t0 ## Set MCOUNTEREN.{CY, TM, IR} to 1, enabling Supervisor mode accesses ## to the cycle, time, stimecmp, and instret MSRs. li t0, 0b111 csrs mcounteren, t0 ## Set MIE.{SSIE, STIE, SEIE} to 1, enabling software, timer, and ## exception traps in Supervisor mode. li t0, 0b1000100010 csrs mie, t0 ## Delegate all exceptions to Supervisor mode. li t0, 0xffff csrw medeleg, t0 csrw mideleg, t0 ### Go from Machine mode to Supervisor mode by fictitiously returning from a ### trap. ## First, set MSTATUS.MPP to Supervisor, so that when we execute mret, ## the privilege level will lower to Supervisor. li t0, 0b11 << 11 csrc mstatus, t0 li t0, 0b01 << 11 csrs mstatus, t0 ## Next, set MEPC to the address of hart0_boot, so that when we execute ## mret, execution will continue there. la t0, hart0_boot csrw mepc, t0 ## Set SATP.MODE to Bare, and clear the rest of the bits. This disables ## paging in Supervisor mode. csrw satp, zero ## Set PMP0CFG.{R, W, X} to 1, PMP0CFG.A to TOR, and PMP0ADDR to the ## maximum value. This allows supervisor mode to access all of physical ## memory. li t0, (0b01 << 3) | 0b111 csrw pmpcfg0, t0 li t0, -1 csrw pmpaddr0, t0 ## Jump to supervisor mode. mret .size _start, . - _start .section .text .type wait_for_hart0, STT_FUNC wait_for_hart0: # TODO wfi j wait_for_hart0 .size wait_for_hart0, . - wait_for_hart0