summaryrefslogtreecommitdiff
path: root/boards/qemu-virt
diff options
context:
space:
mode:
Diffstat (limited to 'boards/qemu-virt')
-rw-r--r--boards/qemu-virt/qemu-virt.s64
1 files changed, 44 insertions, 20 deletions
diff --git a/boards/qemu-virt/qemu-virt.s b/boards/qemu-virt/qemu-virt.s
index a2618d2..5c58153 100644
--- a/boards/qemu-virt/qemu-virt.s
+++ b/boards/qemu-virt/qemu-virt.s
@@ -1,14 +1,15 @@
-.section .text.start
-
.extern main
.extern CONSOLE_STRICT_FLUSH
+.section .text.start
+
.global _start
.type _start, STT_FUNC
_start:
- # Have harts other than 0 spin until hart0 wakes them up.
- csrr a0, mhartid
- c.bnez a0, wait_for_hart0
+ # Have harts other than 0 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.
la t0, console_strict_flush
@@ -18,16 +19,47 @@ _start:
# Set up hart0's stack.
la sp, hart0_initial_stack_top
- # Call hart0_boot with the address of the DeviceTree.
+ # Put the address of the DeviceTree into the first argument position
+ # for hart0_boot.
c.mv a0, a1
- call hart0_boot
- # Fall through to a spin loop.
+
+ # The rest of this function is to get out of machine mode and into
+ # 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.
+ csrr t0, mstatus
+ li t1, ~(0b11 << 11)
+ and t0, t0, t1
+ li t1, (0b01 << 11)
+ or t0, t0, t1
+ csrw 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
+
+ # Delegate all exceptions and interrupts to the Supervisor level.
+ 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.
+ csrw satp, zero
+
+ mret
.size _start, . - _start
-.type halt, STT_FUNC
-halt:
- j halt
-.size halt, . - halt
+.section .text
+
+.type wait_for_hart0, STT_FUNC
+wait_for_hart0:
+ # TODO
+ wfi
+ j wait_for_hart0
+.size wait_for_hart0, . - wait_for_hart0
.section .text
@@ -44,11 +76,3 @@ console_strict_flush:
2:
ret
.size console_strict_flush, . - console_strict_flush
-
-.section .text
-
-.type wait_for_hart0, STT_FUNC
-wait_for_hart0:
- # TODO
- j halt
-.size wait_for_hart0, . - wait_for_hart0