entry.S (2446B)
1 // Copyright 2022, Brian Swetland <swetland@frotz.net> 2 // Licensed under the Apache License, Version 2.0 3 4 #include <hw/riscv.h> 5 6 // This exception handler is conservative and stores *all* 7 // the general registers on the stack on exception entry. 8 // 9 // This allows the exception handler to easily inspect and 10 // modify the previous register state. 11 // 12 // A more efficient handler could only store the callee-save 13 // registers (that would otherwise be possibly clobbered by 14 // the C code it calls into), and trust that the others would 15 // be saved and restored as needed, further down the call chain. 16 17 .globl mach_exception_entry 18 mach_exception_entry: 19 // swap active sp with value in MSCRATCH (exception stack) 20 // interupts have been disabled on exception entry 21 csrrw sp, mscratch, sp 22 23 // allocate space for eframe_t 24 addi sp, sp, - (32 * 4) 25 26 // save the tframe_t 27 sw ra, 0x00(sp) 28 sw t0, 0x04(sp) 29 sw t1, 0x08(sp) 30 sw t2, 0x0C(sp) 31 sw t3, 0x10(sp) 32 sw t4, 0x14(sp) 33 sw t5, 0x18(sp) 34 sw t6, 0x1C(sp) 35 sw a0, 0x20(sp) 36 sw a1, 0x24(sp) 37 sw a2, 0x28(sp) 38 sw a3, 0x2C(sp) 39 sw a4, 0x30(sp) 40 sw a5, 0x34(sp) 41 sw a6, 0x38(sp) 42 sw a7, 0x3C(sp) 43 44 // save the cframe_t 45 csrr t0, mepc 46 csrr t1, mscratch 47 sw t0, 0x40(sp) // pc 48 sw t1, 0x44(sp) // sp 49 sw gp, 0x48(sp) 50 sw tp, 0x4C(sp) 51 sw s0, 0x50(sp) 52 sw s1, 0x54(sp) 53 sw s2, 0x58(sp) 54 sw s3, 0x5C(sp) 55 sw s4, 0x60(sp) 56 sw s5, 0x64(sp) 57 sw s6, 0x68(sp) 58 sw s7, 0x6C(sp) 59 sw s8, 0x70(sp) 60 sw s9, 0x74(sp) 61 sw s10, 0x78(sp) 62 sw s11, 0x7C(sp) 63 64 // call into C handler 65 mv a0, sp 66 jal mach_exception_handler 67 68 // restore trap sp to mscratch 69 addi t0, sp, (32 * 4) 70 csrw mscratch, t0 71 72 // return pc goes into mepc for mret 73 lw t1, 0x40(sp) // pc 74 csrw mepc, t1 75 76 // restore registers from cframe_t 77 lw gp, 0x48(sp) 78 lw tp, 0x4C(sp) 79 lw s0, 0x50(sp) 80 lw s1, 0x54(sp) 81 lw s2, 0x58(sp) 82 lw s3, 0x5C(sp) 83 lw s4, 0x60(sp) 84 lw s5, 0x64(sp) 85 lw s6, 0x68(sp) 86 lw s7, 0x6C(sp) 87 lw s8, 0x70(sp) 88 lw s9, 0x74(sp) 89 lw s10, 0x78(sp) 90 lw s11, 0x7C(sp) 91 92 // restore registers from tframe_t 93 lw ra, 0x00(sp) 94 lw t0, 0x04(sp) 95 lw t1, 0x08(sp) 96 lw t2, 0x0C(sp) 97 lw t3, 0x10(sp) 98 lw t4, 0x14(sp) 99 lw t5, 0x18(sp) 100 lw t6, 0x1C(sp) 101 lw a0, 0x20(sp) 102 lw a1, 0x24(sp) 103 lw a2, 0x28(sp) 104 lw a3, 0x2C(sp) 105 lw a4, 0x30(sp) 106 lw a5, 0x34(sp) 107 lw a6, 0x38(sp) 108 lw a7, 0x3C(sp) 109 110 // restore previous sp last 111 lw sp, 0x44(sp) 112 113 // return from exception 114 mret 115 116 .globl exit_mode_m // a0, a1, pc, sp 117 exit_mode_m: 118 csrw mepc, a2 119 mv sp, a3 120 mret