github.com/usbarmory/tamago@v0.0.0-20240508072735-8612bbe1e454/arm/exception.s (about) 1 // ARM processor support 2 // https://github.com/usbarmory/tamago 3 // 4 // Copyright (c) WithSecure Corporation 5 // https://foundry.withsecure.com 6 // 7 // Use of this source code is governed by the license 8 // that can be found in the LICENSE file. 9 10 #include "go_asm.h" 11 #include "textflag.h" 12 13 // func set_exc_stack(addr uint32) 14 TEXT ·set_exc_stack(SB),NOSPLIT,$0-4 15 MOVW addr+0(FP), R0 16 17 // Set FIQ mode SP 18 WORD $0xe321f0d1 // msr CPSR_c, 0xd1 19 MOVW R0, R13 20 21 // Set IRQ mode SP 22 WORD $0xe321f0d2 // msr CPSR_c, 0xd2 23 MOVW R0, R13 24 25 // Set Supervisor mode SP 26 WORD $0xe321f0d3 // msr CPSR_c, 0xd3 27 MOVW R0, R13 28 29 // Set Monitor mode SP 30 WORD $0xe321f0d6 // msr CPSR_c, 0xd6 31 MOVW R0, R13 32 33 // Set Abort mode SP 34 WORD $0xe321f0d7 // msr CPSR_c, 0xd7 35 MOVW R0, R13 36 37 // Set Undefined mode SP 38 WORD $0xe321f0db // msr CPSR_c, 0xdb 39 MOVW R0, R13 40 41 // Return to System mode 42 WORD $0xe321f0df // msr CPSR_c, 0xdf 43 44 RET 45 46 // func set_vbar(addr uint32) 47 TEXT ·set_vbar(SB),NOSPLIT,$0-4 48 MOVW addr+0(FP), R0 49 MCR 15, 0, R0, C12, C0, 0 50 RET 51 52 // func set_mvbar(addr uint32) 53 TEXT ·set_mvbar(SB),NOSPLIT,$0-4 54 MOVW addr+0(FP), R0 55 MCR 15, 0, R0, C12, C0, 1 56 RET 57 58 #define EXCEPTION(OFFSET, FN, LROFFSET, RN, SAVE_SIZE) \ 59 /* restore stack pointer */ \ 60 WORD $0xe105d200 /* mrs sp, SP_usr */ \ 61 \ 62 /* remove exception specific LR offset */ \ 63 SUB $LROFFSET, R14, R14 \ 64 \ 65 /* save caller registers */ \ 66 MOVM.DB.W [R0-RN, R14], (R13) /* push {r0-rN, r14} */ \ 67 \ 68 /* restore g in case this mode banks them */ \ 69 MOVW $SAVE_SIZE, R0 \ 70 CMP $44, R0 \ 71 B.GT 6(PC) \ 72 WORD $0xe10f0000 /* mrs r0, CPSR */ \ 73 WORD $0xe321f0db /* msr CPSR_c, 0xdb */ \ 74 MOVW g, R1 \ 75 WORD $0xe129f000 /* msr CPSR, r0 */ \ 76 MOVW R1, g \ 77 \ 78 /* call exception handler on g0 */ \ 79 MOVW $OFFSET, R0 \ 80 MOVW $FN(SB), R1 \ 81 MOVW $SAVE_SIZE, R2 \ 82 MOVW R14, R3 \ 83 CALL runtime·CallOnG0(SB) \ 84 \ 85 /* restore registers */ \ 86 MOVM.IA.W (R13), [R0-RN, R14] /* pop {r0-rN, r14} */ \ 87 \ 88 /* restore PC from LR and mode */ \ 89 MOVW.S R14, R15 90 91 TEXT ·resetHandler(SB),NOSPLIT|NOFRAME,$0 92 EXCEPTION(const_RESET, ·systemException, 0, R12, 56) 93 94 TEXT ·undefinedHandler(SB),NOSPLIT|NOFRAME,$0 95 EXCEPTION(const_UNDEFINED, ·systemException, 4, R12, 56) 96 97 TEXT ·supervisorHandler(SB),NOSPLIT|NOFRAME,$0 98 EXCEPTION(const_SUPERVISOR, ·systemException, 0, R12, 56) 99 100 TEXT ·prefetchAbortHandler(SB),NOSPLIT|NOFRAME,$0 101 EXCEPTION(const_PREFETCH_ABORT, ·systemException, 4, R12, 56) 102 103 TEXT ·dataAbortHandler(SB),NOSPLIT|NOFRAME,$0 104 EXCEPTION(const_DATA_ABORT, ·systemException, 8, R12, 56) 105 106 TEXT ·irqHandler(SB),NOSPLIT|NOFRAME,$0 107 /* remove exception specific LR offset */ 108 SUB $4, R14, R14 109 110 /* save caller registers */ 111 MOVM.DB.W [R0-R12, R14], (R13) // push {r0-r12, r14} 112 113 /* wake up IRQ handling goroutine */ 114 MOVW ·irqHandlerG(SB), R0 115 MOVW ·irqHandlerP(SB), R1 116 CMP $0, R0 117 B.EQ done 118 CMP $0, R1 119 B.EQ done 120 CALL runtime·WakeG(SB) 121 122 /* the IRQ handling goroutine is expected to unmask IRQs */ 123 WORD $0xe14f0000 // mrs r0, SPSR 124 ORR $1<<7, R0 // mask IRQs 125 WORD $0xe169f000 // msr SPSR, r0 126 done: 127 /* restore registers */ 128 MOVM.IA.W (R13), [R0-R12, R14] // pop {r0-r12, r14} 129 130 /* restore PC from LR and mode */ 131 MOVW.S R14, R15 132 133 TEXT ·fiqHandler(SB),NOSPLIT|NOFRAME,$0 134 EXCEPTION(const_FIQ, ·systemException, 4, R7, 36) 135 136 TEXT ·nullHandler(SB),NOSPLIT|NOFRAME,$0 137 MOVW.S R14, R15