// The kernel stack. .lcomm kernel_stack, KERNEL_STACK_SIZE .globl run_idle .set noat #define EntryLo0 2 #define EntryLo1 3 #define EntryHi 10 #define Random 1 #define Index 0 #define Status 12 addr_000: // TLB refill // TODO: this should probably be assembly-only for speed reasons li $a0, 0xffff0000 la $t9, panic jr $t9 nop sw $ra, -0x188($zero) bal save_regs la $t9, tlb_refill jr $t9 nop .fill 0x100 - (. - addr_000) addr_100: // Cache error // TODO li $a0, 0xaaaa0000 la $t9, panic jr $t9 nop sw $ra, -0x188($zero) bal save_regs la $t9, cache_error jr $t9 nop .fill 0x180 - (. - addr_000) addr_180: // General exception // TODO //li $a0, 0xaaff0000 la $t9, panic jr $t9 nop sw $ra, -0x188($zero) bal save_regs la $t9, exception jr $t9 nop .fill 0x200 - (. - addr_000) addr_200: // Interrupt // TODO li $a0, 0x0a0f0000 la $t9, panic jr $t9 nop sw $ra, -0x188($zero) bal save_regs la $t9, interrupt jr $t9 nop .fill 0x280 - (. - addr_000) - 16 // space for save_regs: k0; current Thread; ra; gp .word 0 .word 0 .word 0 .word _gp .word idle_page // 280 .word 0x80000000 // 284 A pointer to the current page. start_idle: // 288 // Wait for the next interrupt, then the first thread will be scheduled. // It is impractical to try to call schedule, because for that the // idle task would need to own capabilities. mfc0 $a0, $9 syscall 1: wait b 1b nop kernel_exit: move $k0, $v0 lw $v0, 96($k0) lw $v1, 100($k0) mthi $v0 mtlo $v1 lw $v0, 16($k0) lw $v1, 20($k0) lw $a0, 24($k0) lw $a1, 28($k0) lw $a2, 32($k0) lw $a3, 36($k0) lw $t0, 40($k0) lw $t1, 44($k0) lw $t2, 48($k0) lw $t3, 52($k0) lw $t4, 56($k0) lw $t5, 60($k0) lw $t6, 64($k0) lw $t7, 68($k0) lw $t8, 72($k0) lw $t9, 76($k0) lw $gp, 80($k0) lw $sp, 84($k0) lw $fp, 88($k0) lw $ra, 92($k0) lw $at, 12($k0) lw $k1, 104($k0) // Real $k0 sw $k1, -0x190($zero) lw $k1, 108($k0) sw $k0, -0x18c($zero) lw $k0, -0x190($zero) eret save_regs: sw $k0, -0x190($zero) lw $k0, -0x18c($zero) sw $at, 12($k0) sw $gp, 80($k0) sw $sp, 84($k0) sw $fp, 88($k0) sw $k1, 108($k0) lw $k1, -0x190($zero) sw $k1, 104($k0) // Real $k0 lw $k1, -0x188($zero) sw $k1, 92($k0) // Real $ra sw $v0, 16($k0) sw $v1, 20($k0) sw $a0, 24($k0) sw $a1, 28($k0) sw $a2, 32($k0) sw $a3, 36($k0) sw $t1, 44($k0) sw $t2, 48($k0) sw $t3, 52($k0) sw $t4, 56($k0) sw $t5, 60($k0) sw $t6, 64($k0) sw $t7, 68($k0) sw $t8, 72($k0) sw $t9, 76($k0) mfhi $v0 mflo $v1 sw $v0, 96($k0) sw $v1, 100($k0) lw $gp, -0x184($zero) la $sp, kernel_stack + KERNEL_STACK_SIZE move $t9, $ra la $ra, kernel_exit jr $t9 move $a0, $k0