| [258] | 1 | /************************************************************************************ |
|---|
| [742] | 2 | * This file contains the two entry points in the GIET_VM code: |
|---|
| 3 | * - the _init entry point (from the boot code) is 0x80000000 |
|---|
| 4 | * - the _giet entry point (from user applications) is 0x80000180 |
|---|
| 5 | * => The base address of the segment containing this code MUST be 0x80000000. |
|---|
| [258] | 6 | * |
|---|
| [742] | 7 | * The _giet uses two arrays of functions: |
|---|
| [258] | 8 | * - the _cause_vector[16] array defines the 16 causes to enter the GIET |
|---|
| 9 | * it is initialized in th exc_handler.c file |
|---|
| [267] | 10 | * - the _syscall_vector[64] array defines the 64 system calls entry points |
|---|
| [258] | 11 | * it is initialised in the sys_handler.c file |
|---|
| 12 | ***********************************************************************************/ |
|---|
| 13 | |
|---|
| 14 | .section .giet, "ax", @progbits |
|---|
| 15 | |
|---|
| 16 | /* |
|---|
| [742] | 17 | * INIT entry point (at address 0x80000000) |
|---|
| 18 | */ |
|---|
| 19 | |
|---|
| 20 | .func _init |
|---|
| 21 | .type _init, %function |
|---|
| 22 | |
|---|
| 23 | _init: |
|---|
| 24 | la $26, _kernel_init |
|---|
| 25 | jr $26 /* jump to _kernel_init */ |
|---|
| 26 | |
|---|
| 27 | .endfunc |
|---|
| 28 | .size _init, .-_init |
|---|
| 29 | |
|---|
| 30 | .space 0x170 /* the _entry function occupies 16 bytes */ |
|---|
| 31 | |
|---|
| 32 | /* |
|---|
| [258] | 33 | * GIET Entry point (at address 0x80000180) |
|---|
| 34 | */ |
|---|
| 35 | |
|---|
| 36 | .func _giet |
|---|
| 37 | .type _giet, %function |
|---|
| 38 | |
|---|
| 39 | _giet: |
|---|
| 40 | mfc0 $27, $13 /* $27 <= Cause register */ |
|---|
| [798] | 41 | andi $27, $27, 0x3c /* $27 <= XCODE*4 */ |
|---|
| 42 | beq $27, $0, do_jump /* jump if interrupt */ |
|---|
| 43 | addiu $26, $0, 0x20 |
|---|
| 44 | beq $27, $26, do_jump /* jump if syscall */ |
|---|
| [802] | 45 | |
|---|
| 46 | /* |
|---|
| 47 | * exception: save registers into stack for future display by exception handler |
|---|
| 48 | */ |
|---|
| 49 | |
|---|
| [798] | 50 | addiu $27, $29, -38*4 |
|---|
| [802] | 51 | sw $29, (29*4)($27) /* save $29 */ |
|---|
| [798] | 52 | or $29, $27, $0 |
|---|
| 53 | |
|---|
| 54 | .set noat |
|---|
| [802] | 55 | sw $1, (1*4)($29) /* save $1 */ |
|---|
| [798] | 56 | .set at |
|---|
| [802] | 57 | sw $2, (2*4)($29) /* save $2 */ |
|---|
| 58 | sw $3, (3*4)($29) /* save $3 */ |
|---|
| 59 | sw $4, (4*4)($29) /* save $4 */ |
|---|
| 60 | sw $5, (5*4)($29) /* save $5 */ |
|---|
| 61 | sw $6, (6*4)($29) /* save $6 */ |
|---|
| 62 | sw $7, (7*4)($29) /* save $7 */ |
|---|
| 63 | sw $8, (8*4)($29) /* save $8 */ |
|---|
| 64 | sw $9, (9*4)($29) /* save $9 */ |
|---|
| 65 | sw $10, (10*4)($29) /* save $10 */ |
|---|
| 66 | sw $11, (11*4)($29) /* save $11 */ |
|---|
| 67 | sw $12, (12*4)($29) /* save $12 */ |
|---|
| 68 | sw $13, (13*4)($29) /* save $13 */ |
|---|
| 69 | sw $14, (14*4)($29) /* save $14 */ |
|---|
| 70 | sw $15, (15*4)($29) /* save $15 */ |
|---|
| 71 | sw $16, (16*4)($29) /* save $16 */ |
|---|
| 72 | sw $17, (17*4)($29) /* save $17 */ |
|---|
| 73 | sw $18, (18*4)($29) /* save $18 */ |
|---|
| 74 | sw $19, (19*4)($29) /* save $19 */ |
|---|
| 75 | sw $20, (20*4)($29) /* save $20 */ |
|---|
| 76 | sw $21, (21*4)($29) /* save $21 */ |
|---|
| 77 | sw $22, (22*4)($29) /* save $22 */ |
|---|
| 78 | sw $23, (23*4)($29) /* save $23 */ |
|---|
| 79 | sw $24, (24*4)($29) /* save $24 */ |
|---|
| 80 | sw $25, (25*4)($29) /* save $25 */ |
|---|
| 81 | sw $28, (28*4)($29) /* save $28 */ |
|---|
| 82 | sw $30, (30*4)($29) /* save $30 */ |
|---|
| 83 | sw $31, (31*4)($29) /* save $31 */ |
|---|
| 84 | mflo $14 /* LO */ |
|---|
| 85 | mfhi $15 /* HI */ |
|---|
| 86 | mfc0 $16, $14 /* EPC */ |
|---|
| 87 | mfc0 $17, $13 /* CR */ |
|---|
| 88 | mfc0 $18, $12 /* SR */ |
|---|
| 89 | mfc0 $19, $8 /* BVAR */ |
|---|
| 90 | sw $14, (35*4)($29) /* save LO */ |
|---|
| 91 | sw $15, (36*4)($29) /* save HI */ |
|---|
| [798] | 92 | sw $16, (32*4)($29) /* Save EPC */ |
|---|
| 93 | sw $17, (33*4)($29) /* Save CR */ |
|---|
| 94 | sw $18, (34*4)($29) /* Save SR */ |
|---|
| [802] | 95 | sw $19, (37*4)($29) /* save BVAR */ |
|---|
| 96 | or $4, $0, $27 /* $4 <= regs_table */ |
|---|
| [798] | 97 | |
|---|
| 98 | do_jump: |
|---|
| 99 | mfc0 $27, $13 /* $27 <= Cause register */ |
|---|
| 100 | andi $27, $27, 0x3c /* $27 <= XCODE*4 */ |
|---|
| 101 | la $26, _cause_vector /* $26 <= _cause_vector */ |
|---|
| 102 | addu $26, $26, $27 /* $26 <= &_cause_vector[XCODE] */ |
|---|
| 103 | lw $26, 0($26) /* $26 <= _cause_vector[XCODE] */ |
|---|
| 104 | jr $26 /* Jump to handler indexed by XCODE */ |
|---|
| [258] | 105 | |
|---|
| 106 | .endfunc |
|---|
| 107 | .size _giet, .-_giet |
|---|
| 108 | |
|---|
| 109 | /* |
|---|
| [742] | 110 | * *** Syscall Handler *** |
|---|
| [258] | 111 | * |
|---|
| 112 | * A system call is handled as a special function call. |
|---|
| 113 | * - $2 contains the system call index (< 64). |
|---|
| 114 | * - $3 is used to store the syscall address |
|---|
| 115 | * - $4, $5, $6, $7 contain the arguments values. |
|---|
| [346] | 116 | * - The return address (EPC) and the (SR) are saved in the stack. |
|---|
| [258] | 117 | * - Interrupts are enabled before branching to the syscall. |
|---|
| 118 | * - All syscalls must return to the syscall handler. |
|---|
| 119 | * - $2, $3, $4, $5, $6, $7 as well as $26 & $27 can be modified. |
|---|
| 120 | * |
|---|
| [346] | 121 | * In case of undefined system call, an error message displays |
|---|
| 122 | * the value of EPC on the kernel TTY, and the user program is killed. |
|---|
| [258] | 123 | */ |
|---|
| 124 | |
|---|
| 125 | .globl _sys_handler |
|---|
| 126 | .func _sys_handler |
|---|
| 127 | .type _sys_handler, %function |
|---|
| 128 | |
|---|
| 129 | _sys_handler: |
|---|
| [346] | 130 | addiu $29, $29, -24 /* 2 slots for SR & EPC, 4 slots for args */ |
|---|
| 131 | mfc0 $27, $14 /* $27 <= EPC */ |
|---|
| 132 | addiu $27, $27, 4 /* increment EPC for return address */ |
|---|
| 133 | sw $27, 20($29) /* save EPC in the stack */ |
|---|
| 134 | mfc0 $27, $12 /* $27 <= SR */ |
|---|
| 135 | sw $27, 16($29) /* save SR in the stack */ |
|---|
| [258] | 136 | |
|---|
| [346] | 137 | andi $26, $2, 0x3F /* $26 <= syscall index (i < 64) */ |
|---|
| 138 | sll $26, $26, 2 /* $26 <= index * 4 */ |
|---|
| 139 | la $27, _syscall_vector /* $27 <= &_syscall_vector[0] */ |
|---|
| 140 | addu $27, $27, $26 /* $27 <= &_syscall_vector[i] */ |
|---|
| 141 | lw $3, 0($27) /* $3 <= syscall address */ |
|---|
| 142 | li $27, 0xFFFFFFED /* Mask for UM & EXL bits */ |
|---|
| 143 | mfc0 $26, $12 /* $26 <= SR */ |
|---|
| 144 | and $26, $26, $27 /* UM = 0 / EXL = 0 */ |
|---|
| 145 | mtc0 $26, $12 /* interrupt enabled */ |
|---|
| 146 | jalr $3 /* jump to the proper syscall */ |
|---|
| [258] | 147 | |
|---|
| [346] | 148 | mtc0 $0, $12 /* SR <= 0 : interrupt disabled */ |
|---|
| 149 | lw $26, 16($29) /* $26 <= SR from stack */ |
|---|
| 150 | mtc0 $26, $12 /* restore SR */ |
|---|
| 151 | lw $26, 20($29) /* $26 <= EPC from stack */ |
|---|
| 152 | mtc0 $26, $14 /* restore EPC */ |
|---|
| 153 | addiu $29, $29, 24 /* restore stack pointer */ |
|---|
| 154 | eret /* exit GIET */ |
|---|
| [258] | 155 | |
|---|
| 156 | .endfunc |
|---|
| 157 | .size _sys_handler, .-_sys_handler |
|---|
| 158 | |
|---|
| 159 | /* |
|---|
| 160 | * *** Interrupt Handler *** |
|---|
| 161 | * |
|---|
| 162 | * This simple interrupt handler cannot be interrupted. |
|---|
| 163 | * |
|---|
| 164 | * All non persistant registers, such as $1 to $15, and $24 to $25, as well as |
|---|
| 165 | * register $31 and EPC, are saved in the interrupted program stack, before |
|---|
| 166 | * calling the Interrupt Service Routine. These registers can be used by the |
|---|
| 167 | * ISR code. |
|---|
| 168 | */ |
|---|
| 169 | |
|---|
| 170 | .globl _int_handler |
|---|
| 171 | .func _int_handler |
|---|
| 172 | .type _int_handler, %function |
|---|
| 173 | |
|---|
| 174 | _int_handler: |
|---|
| 175 | addiu $29, $29, -25*4 /* stack space reservation (21 registers to |
|---|
| 176 | save and 4 free words to call function) */ |
|---|
| 177 | .set noat |
|---|
| 178 | sw $1, 4*4($29) /* save $1 */ |
|---|
| 179 | .set at |
|---|
| 180 | sw $2, 5*4($29) /* save $2 */ |
|---|
| 181 | sw $3, 6*4($29) /* save $3 */ |
|---|
| 182 | sw $4, 7*4($29) /* save $4 */ |
|---|
| 183 | sw $5, 8*4($29) /* save $5 */ |
|---|
| 184 | sw $6, 9*4($29) /* save $6 */ |
|---|
| 185 | sw $7, 10*4($29) /* save $7 */ |
|---|
| 186 | sw $8, 11*4($29) /* save $8 */ |
|---|
| 187 | sw $9, 12*4($29) /* save $9 */ |
|---|
| 188 | sw $10, 13*4($29) /* save $10 */ |
|---|
| 189 | sw $11, 14*4($29) /* save $11 */ |
|---|
| 190 | sw $12, 15*4($29) /* save $12 */ |
|---|
| 191 | sw $13, 16*4($29) /* save $13 */ |
|---|
| 192 | sw $14, 17*4($29) /* save $14 */ |
|---|
| 193 | sw $15, 18*4($29) /* save $15 */ |
|---|
| 194 | sw $24, 19*4($29) /* save $24 */ |
|---|
| 195 | sw $25, 20*4($29) /* save $25 */ |
|---|
| 196 | sw $31, 21*4($29) /* save $31 */ |
|---|
| 197 | mflo $26 |
|---|
| 198 | sw $26, 22*4($29) /* save LO */ |
|---|
| 199 | mfhi $26 |
|---|
| 200 | sw $26, 23*4($29) /* save HI */ |
|---|
| 201 | mfc0 $27, $14 |
|---|
| 202 | sw $27, 24*4($29) /* save EPC */ |
|---|
| 203 | |
|---|
| 204 | la $26, _irq_demux |
|---|
| 205 | jalr $26 /* jump to a C function to find the proper ISR */ |
|---|
| 206 | |
|---|
| 207 | restore: |
|---|
| 208 | .set noat |
|---|
| 209 | lw $1, 4*4($29) /* restore $1 */ |
|---|
| 210 | .set at |
|---|
| 211 | lw $2, 4*5($29) /* restore $2 */ |
|---|
| 212 | lw $3, 4*6($29) /* restore $3 */ |
|---|
| 213 | lw $4, 4*7($29) /* restore $4 */ |
|---|
| 214 | lw $5, 4*8($29) /* restore $5 */ |
|---|
| 215 | lw $6, 4*9($29) /* restore $6 */ |
|---|
| 216 | lw $7, 4*10($29) /* restore $7 */ |
|---|
| 217 | lw $8, 4*11($29) /* restore $8 */ |
|---|
| 218 | lw $9, 4*12($29) /* restore $9 */ |
|---|
| 219 | lw $10, 4*13($29) /* restore $10 */ |
|---|
| 220 | lw $11, 4*14($29) /* restore $11 */ |
|---|
| 221 | lw $12, 4*15($29) /* restore $12 */ |
|---|
| 222 | lw $13, 4*16($29) /* restore $13 */ |
|---|
| 223 | lw $14, 4*17($29) /* restore $14 */ |
|---|
| 224 | lw $15, 4*18($29) /* restore $15 */ |
|---|
| 225 | lw $24, 4*19($29) /* restore $24 */ |
|---|
| 226 | lw $25, 4*20($29) /* restore $25 */ |
|---|
| 227 | lw $31, 4*21($29) /* restore $31 */ |
|---|
| 228 | lw $26, 4*22($29) |
|---|
| 229 | mtlo $26 /* restore LO */ |
|---|
| 230 | lw $26, 4*23($29) |
|---|
| 231 | mthi $26 /* restore HI */ |
|---|
| 232 | lw $27, 4*24($29) /* return address (EPC) */ |
|---|
| 233 | addiu $29, $29, 25*4 /* restore stack pointer */ |
|---|
| 234 | mtc0 $27, $14 /* restore EPC */ |
|---|
| 235 | eret /* exit GIET */ |
|---|
| 236 | |
|---|
| 237 | .endfunc |
|---|
| 238 | .size _int_handler, .-_int_handler |
|---|
| 239 | |
|---|