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