diff options
author | Nathan Ringo <nathan@remexre.com> | 2024-08-25 12:39:54 -0500 |
---|---|---|
committer | Nathan Ringo <nathan@remexre.com> | 2024-08-25 12:39:54 -0500 |
commit | f1897c47a8f03955b76d521d1843a25123bd65a2 (patch) | |
tree | c007ff756fdf432cdcf81c2df897a73cea94464a | |
parent | a150739a5ec13e69efe5cbedd018265e3d1f6faf (diff) |
[boards/qemu-virt] Set up timer interrupts.
-rw-r--r-- | boards/qemu-virt/qemu-virt.s | 69 |
1 files changed, 42 insertions, 27 deletions
diff --git a/boards/qemu-virt/qemu-virt.s b/boards/qemu-virt/qemu-virt.s index 063e67c..b9544be 100644 --- a/boards/qemu-virt/qemu-virt.s +++ b/boards/qemu-virt/qemu-virt.s @@ -6,58 +6,73 @@ .global _start .type _start, STT_FUNC _start: - # Have harts other than 0 spin until hart0 wakes them up. As a side - # effect, load every hart's thread pointer register with MHARTID. + ## 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 console_strict_flush. + ## Set up console_strict_flush. la t0, console_strict_flush la t1, CONSOLE_STRICT_FLUSH sd t0, (t1) - # Set up hart0's stack. + ## Set up hart0's stack. la sp, hart0_initial_stack_top - # Put the address of the DeviceTree into the first argument position - # for hart0_boot. + ## Put the address of the DeviceTree into the first argument position + ## for hart0_boot. c.mv a0, a1 - # The rest of this function is to get out of machine mode and into - # supervisor mode by fictitiously returning from a trap. +### Set up trap handling. - # First, set MSTATUS.MPP to Supervisor, so that when we execute mret, - # the privilege level will lower to Supervisor. - csrr t0, mstatus - li t1, ~(0b11 << 11) - and t0, t0, t1 - li t1, (0b01 << 11) - or t0, t0, t1 - csrw mstatus, t0 + ## 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 - # 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 MCOUNTEREN.{CY, TM, IR} to 1, enabling Supervisor mode accesses + ## to the cycle, time, stimecmp, and instret MSRs. + li t0, 0b111 + csrs mcounteren, t0 - # Delegate all exceptions and interrupts to the Supervisor level. + ## 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 - # Set SATP.MODE to Bare, and clear the rest of the bits. This disables - # paging in Supervisor mode. +### 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. + ## 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. + ## Jump to supervisor mode. mret .size _start, . - _start |