[158] | 1 | /************************************************************************************ |
---|
| 2 | * GIET: Interruption/Exception/Trap Handler for MIPS32 processor |
---|
| 3 | * |
---|
| 4 | * The base address of the segment containing this code MUST be 0x80000000, in |
---|
| 5 | * order to have the entry point at address 0x80000180!!! All messages are |
---|
| 6 | * printed on the TTY corresponding to the task&processor identifiers. |
---|
| 7 | * |
---|
| 8 | * It uses two arrays of functions: |
---|
| 9 | * - the _cause_vector[16] array defines the 16 causes to enter the GIET |
---|
| 10 | * it is initialized in th exc_handler.c file |
---|
| 11 | * - the _syscall_vector[32] array defines the 32 system calls entry points |
---|
| 12 | * it is initialised in the sys_handler.c file |
---|
| 13 | ***********************************************************************************/ |
---|
| 14 | |
---|
| 15 | .section .giet, "ax", @progbits |
---|
| 16 | .space 0x180 |
---|
| 17 | |
---|
| 18 | /* |
---|
| 19 | * GIET Entry point (at address 0x80000180) |
---|
| 20 | */ |
---|
| 21 | |
---|
| 22 | .func _giet |
---|
| 23 | .type _giet, %function |
---|
| 24 | |
---|
| 25 | _giet: |
---|
| 26 | mfc0 $27, $13 /* $27 <= Cause register */ |
---|
| 27 | la $26, _cause_vector /* $26 <= _cause_vector */ |
---|
[165] | 28 | andi $27, $27, 0x3c /* $27 <= XCODE*4 */ |
---|
| 29 | addu $26, $26, $27 /* $26 <= &_cause_vector[XCODE] */ |
---|
[158] | 30 | lw $26, ($26) /* $26 <= _cause_vector[XCODE] */ |
---|
| 31 | jr $26 /* Jump indexed by XCODE */ |
---|
| 32 | |
---|
| 33 | .endfunc |
---|
| 34 | .size _giet, .-_giet |
---|
| 35 | |
---|
| 36 | /* |
---|
| 37 | * *** System Call Handler *** |
---|
| 38 | * |
---|
| 39 | * A system call is handled as a special function call. |
---|
| 40 | * - $2 contains the system call index (< 16). |
---|
| 41 | * - $3 is used to store the syscall address |
---|
| 42 | * - $4, $5, $6, $7 contain the arguments values. |
---|
| 43 | * - The return address (EPC) and the SR are saved in the stack. |
---|
| 44 | * - Interrupts are enabled before branching to the syscall. |
---|
| 45 | * - All syscalls must return to the syscall handler. |
---|
| 46 | * - $2, $3, $4, $5, $6, $7 as well as $26 & $27 can be modified. |
---|
| 47 | * |
---|
| 48 | * In case of undefined system call, an error message displays the value of EPC |
---|
| 49 | * on the TTY corresponding to the processor, and the user program is killed. |
---|
| 50 | */ |
---|
| 51 | |
---|
| 52 | .globl _sys_handler |
---|
| 53 | .func _sys_handler |
---|
| 54 | .type _sys_handler, %function |
---|
| 55 | |
---|
| 56 | _sys_handler: |
---|
| 57 | addiu $29, $29, -24 /* 2 slots for SR&EPC, 4 slots for args passing */ |
---|
| 58 | mfc0 $26, $12 /* load SR */ |
---|
| 59 | sw $26, 16($29) /* save it in the stack */ |
---|
| 60 | mfc0 $27, $14 /* load EPC */ |
---|
| 61 | addiu $27, $27, 4 /* increment EPC for return address */ |
---|
| 62 | sw $27, 20($29) /* save it in the stack */ |
---|
| 63 | |
---|
| 64 | andi $26, $2, 0x1F /* $26 <= syscall index (i < 32) */ |
---|
| 65 | sll $26, $26, 2 /* $26 <= index * 4 */ |
---|
| 66 | la $27, _syscall_vector /* $27 <= &_syscall_vector[0] */ |
---|
| 67 | addu $27, $27, $26 /* $27 <= &_syscall_vector[i] */ |
---|
| 68 | lw $3, 0($27) /* $3 <= syscall address */ |
---|
| 69 | |
---|
| 70 | li $27, 0xFFFFFFED /* Mask for UM & EXL bits */ |
---|
| 71 | mfc0 $26, $12 /* $26 <= SR */ |
---|
| 72 | and $26, $26, $27 /* UM = 0 / EXL = 0 */ |
---|
| 73 | mtc0 $26, $12 /* interrupt enabled */ |
---|
| 74 | jalr $3 /* jump to the proper syscall */ |
---|
| 75 | mtc0 $0, $12 /* interrupt disbled */ |
---|
| 76 | |
---|
| 77 | lw $26, 16($29) /* load SR from stack */ |
---|
| 78 | mtc0 $26, $12 /* restore SR */ |
---|
| 79 | lw $26, 20($29) /* load EPC from stack */ |
---|
| 80 | mtc0 $26, $14 /* restore EPC */ |
---|
| 81 | addiu $29, $29, 24 /* restore stack pointer */ |
---|
| 82 | eret /* exit GIET */ |
---|
| 83 | |
---|
| 84 | .endfunc |
---|
| 85 | .size _sys_handler, .-_sys_handler |
---|
| 86 | |
---|
| 87 | /* |
---|
| 88 | * *** Interrupt Handler *** |
---|
| 89 | * |
---|
| 90 | * This simple interrupt handler cannot be interrupted. |
---|
| 91 | * |
---|
| 92 | * All non persistant registers, such as $1 to $15, and $24 to $25, as well as |
---|
| 93 | * register $31 and EPC, are saved in the interrupted program stack, before |
---|
| 94 | * calling the Interrupt Service Routine. These registers can be used by the |
---|
| 95 | * ISR code. |
---|
| 96 | */ |
---|
| 97 | |
---|
| 98 | .globl _int_handler |
---|
| 99 | .func _int_handler |
---|
| 100 | .type _int_handler, %function |
---|
| 101 | |
---|
| 102 | _int_handler: |
---|
[219] | 103 | addiu $29, $29, -25*4 /* stack space reservation (21 registers to |
---|
[158] | 104 | save and 4 free words to call function) */ |
---|
| 105 | .set noat |
---|
| 106 | sw $1, 4*4($29) /* save $1 */ |
---|
| 107 | .set at |
---|
| 108 | sw $2, 5*4($29) /* save $2 */ |
---|
| 109 | sw $3, 6*4($29) /* save $3 */ |
---|
| 110 | sw $4, 7*4($29) /* save $4 */ |
---|
| 111 | sw $5, 8*4($29) /* save $5 */ |
---|
| 112 | sw $6, 9*4($29) /* save $6 */ |
---|
| 113 | sw $7, 10*4($29) /* save $7 */ |
---|
| 114 | sw $8, 11*4($29) /* save $8 */ |
---|
| 115 | sw $9, 12*4($29) /* save $9 */ |
---|
| 116 | sw $10, 13*4($29) /* save $10 */ |
---|
| 117 | sw $11, 14*4($29) /* save $11 */ |
---|
| 118 | sw $12, 15*4($29) /* save $12 */ |
---|
| 119 | sw $13, 16*4($29) /* save $13 */ |
---|
| 120 | sw $14, 17*4($29) /* save $14 */ |
---|
| 121 | sw $15, 18*4($29) /* save $15 */ |
---|
| 122 | sw $24, 19*4($29) /* save $24 */ |
---|
| 123 | sw $25, 20*4($29) /* save $25 */ |
---|
| 124 | sw $31, 21*4($29) /* save $31 */ |
---|
[219] | 125 | mflo $26 |
---|
| 126 | sw $26, 22*4($29) /* save LO */ |
---|
| 127 | mfhi $26 |
---|
| 128 | sw $26, 23*4($29) /* save HI */ |
---|
[158] | 129 | mfc0 $27, $14 |
---|
[219] | 130 | sw $27, 24*4($29) /* save EPC */ |
---|
[158] | 131 | |
---|
[189] | 132 | la $26, _irq_demux |
---|
[158] | 133 | jalr $26 /* jump to a C function to find the proper ISR */ |
---|
| 134 | |
---|
| 135 | restore: |
---|
| 136 | .set noat |
---|
| 137 | lw $1, 4*4($29) /* restore $1 */ |
---|
| 138 | .set at |
---|
| 139 | lw $2, 4*5($29) /* restore $2 */ |
---|
| 140 | lw $3, 4*6($29) /* restore $3 */ |
---|
| 141 | lw $4, 4*7($29) /* restore $4 */ |
---|
| 142 | lw $5, 4*8($29) /* restore $5 */ |
---|
| 143 | lw $6, 4*9($29) /* restore $6 */ |
---|
| 144 | lw $7, 4*10($29) /* restore $7 */ |
---|
| 145 | lw $8, 4*11($29) /* restore $8 */ |
---|
| 146 | lw $9, 4*12($29) /* restore $9 */ |
---|
| 147 | lw $10, 4*13($29) /* restore $10 */ |
---|
| 148 | lw $11, 4*14($29) /* restore $11 */ |
---|
| 149 | lw $12, 4*15($29) /* restore $12 */ |
---|
| 150 | lw $13, 4*16($29) /* restore $13 */ |
---|
| 151 | lw $14, 4*17($29) /* restore $14 */ |
---|
| 152 | lw $15, 4*18($29) /* restore $15 */ |
---|
| 153 | lw $24, 4*19($29) /* restore $24 */ |
---|
| 154 | lw $25, 4*20($29) /* restore $25 */ |
---|
| 155 | lw $31, 4*21($29) /* restore $31 */ |
---|
[219] | 156 | lw $26, 4*22($29) |
---|
| 157 | mtlo $26 /* restore LO */ |
---|
| 158 | lw $26, 4*23($29) |
---|
| 159 | mthi $26 /* restore HI */ |
---|
| 160 | lw $27, 4*24($29) /* return address (EPC) */ |
---|
| 161 | addiu $29, $29, 25*4 /* restore stack pointer */ |
---|
[158] | 162 | mtc0 $27, $14 /* restore EPC */ |
---|
| 163 | eret /* exit GIET */ |
---|
| 164 | |
---|
| 165 | .endfunc |
---|
| 166 | .size _int_handler, .-_int_handler |
---|
| 167 | |
---|