File size: 6,054 Bytes
829b19c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | # SPDX-License-Identifier: AGPL-3.0-or-later
# Copyright 2025 Ahmad Ali Parr / SnapKitty οΏ½ https://github.com/SNAPKITTYWEST/phaser-ags
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# PHASER AGS β RV32I boot assembly (complete, no stubs)
#
# Full boot sequence + trap entry/exit with context switch.
# Supports M-mode operation with per-process kernel stacks.
# Context switch: trapDispatch returns the frame pointer to
# restore (may differ from entry if a switch occurred).
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
.section .text.boot, "ax"
.globl _start
.type _start, @function
_start:
# ββ M-mode entry: disable all interrupts ββ
csrw mstatus, zero
csrw mie, zero
csrw mideleg, zero
csrw medeleg, zero
# ββ Install trap vector ββ
la t0, trap_vector
csrw mtvec, t0
# ββ Kernel stack ββ
la sp, __stack_top
# ββ Global pointer for linker relaxation ββ
.option push
.option norelax
la gp, __global_pointer$
.option pop
# ββ Zero BSS ββ
la t0, __bss_start
la t1, __bss_end
1: bgeu t0, t1, 2f
sd zero, 0(t0)
addi t0, t0, 8
j 1b
2:
# ββ Set initial mscratch to kernel stack top ββ
# (first trap uses this as the context save area)
csrw mscratch, sp
# ββ Flush instruction cache ββ
fence.i
# ββ Enter Zig kernel ββ
call kernelMain
# ββ kernelMain must not return; halt if it does ββ
3: wfi
j 3b
.size _start, . - _start
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# TRAP VECTOR β Full context save/restore + context switch
#
# Layout on kernel stack (264 bytes):
# [0] prev_ctx β previous mscratch (for nested traps)
# [8] x1 ra [16] x5 t0 [24] x6 t1
# [32] x7 t2 [40] x10 a0 [48] x11 a1
# [56] x12 a2 [64] x13 a3 [72] x14 a4
# [80] x15 a5 [88] x16 a6 [96] x17 a7
# [104] x8 s0/fp [112] x9 s1 [120] x18 s2
# [128] x19 s3 [136] x20 s4 [144] x21 s5
# [152] x22 s6 [160] x23 s7 [168] x24 s8
# [176] x25 s9 [184] x26 s10 [192] x27 s11
# [200] x28 t3 [208] x29 t4 [216] x30 t5
# [224] x31 t6 [232] mepc [240] mstatus
# [248] mcause [256] mtval
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
.section .text.trap, "ax"
.globl trap_vector
.type trap_vector, @function
trap_vector:
# ββ Swap sp with mscratch ββ
# If trap from M-mode: sp was kernel sp, mscratch = same
# If first trap: mscratch = initial stack, sp = whatever
csrrw sp, mscratch, sp
# ββ Allocate trap frame on kernel stack ββ
addi sp, sp, -264
# ββ Save all integer registers ββ
sd x1, 8(sp)
sd x5, 16(sp)
sd x6, 24(sp)
sd x7, 32(sp)
sd x10, 40(sp)
sd x11, 48(sp)
sd x12, 56(sp)
sd x13, 64(sp)
sd x14, 72(sp)
sd x15, 80(sp)
sd x16, 88(sp)
sd x17, 96(sp)
sd x8, 104(sp)
sd x9, 112(sp)
sd x18, 120(sp)
sd x19, 128(sp)
sd x20, 136(sp)
sd x21, 144(sp)
sd x22, 152(sp)
sd x23, 160(sp)
sd x24, 168(sp)
sd x25, 176(sp)
sd x26, 184(sp)
sd x27, 192(sp)
sd x28, 200(sp)
sd x29, 208(sp)
sd x30, 216(sp)
sd x31, 224(sp)
# ββ Save CSRs ββ
csrr t0, mepc
sd t0, 232(sp)
csrr t0, mstatus
sd t0, 240(sp)
csrr t0, mcause
sd t0, 248(sp)
csrr t0, mtval
sd t0, 256(sp)
# ββ Save previous mscratch (was in sp before csrrw) ββ
# The old sp (pre-swap) is now in mscratch.
csrr t0, mscratch
sd t0, 0(sp)
# ββ Set mscratch to current kernel stack ββ
csrw mscratch, sp
# ββ Call Zig trap handler ββ
mv a0, sp
call trapDispatch
# ββ a0 = trap frame pointer to restore ββ
# May differ from entry sp if context switch occurred
mv sp, a0
# ββ Restore CSRs ββ
ld t0, 232(sp)
csrw mepc, t0
ld t0, 240(sp)
csrw mstatus, t0
# ββ Restore previous mscratch ββ
ld t0, 0(sp)
csrw mscratch, t0
# ββ Restore all integer registers ββ
ld x1, 8(sp)
ld x5, 16(sp)
ld x6, 24(sp)
ld x7, 32(sp)
ld x10, 40(sp)
ld x11, 48(sp)
ld x12, 56(sp)
ld x13, 64(sp)
ld x14, 72(sp)
ld x15, 80(sp)
ld x16, 88(sp)
ld x17, 96(sp)
ld x8, 104(sp)
ld x9, 112(sp)
ld x18, 120(sp)
ld x19, 128(sp)
ld x20, 136(sp)
ld x21, 144(sp)
ld x22, 152(sp)
ld x23, 160(sp)
ld x24, 168(sp)
ld x25, 176(sp)
ld x26, 184(sp)
ld x27, 192(sp)
ld x28, 200(sp)
ld x29, 208(sp)
ld x30, 216(sp)
ld x31, 224(sp)
# ββ Deallocate trap frame ββ
addi sp, sp, 264
# ββ Return from trap ββ
mret
.size trap_vector, . - trap_vector
|