2009-05-11 01:28:12 +03:00
|
|
|
// The kernel stack.
|
|
|
|
.lcomm kernel_stack, KERNEL_STACK_SIZE
|
|
|
|
|
|
|
|
.globl run_idle
|
|
|
|
.set noat
|
|
|
|
|
2009-05-19 00:18:23 +03:00
|
|
|
#define Index 0
|
|
|
|
#define Random 1
|
2009-05-11 01:28:12 +03:00
|
|
|
#define EntryLo0 2
|
|
|
|
#define EntryLo1 3
|
2009-05-23 21:55:31 +03:00
|
|
|
#define BadVAddr 8
|
2009-05-11 01:28:12 +03:00
|
|
|
#define EntryHi 10
|
|
|
|
#define Status 12
|
2009-05-19 00:18:23 +03:00
|
|
|
#define EPC 14
|
|
|
|
|
|
|
|
// register save positions in Thread
|
|
|
|
#define SAVE_PC (5 * 4)
|
|
|
|
#define SAVE_SP (SAVE_PC + 4)
|
|
|
|
#define SAVE_AT (SAVE_SP + 4)
|
|
|
|
#define SAVE_V0 (SAVE_AT + 4)
|
|
|
|
#define SAVE_V1 (SAVE_V0 + 4)
|
|
|
|
#define SAVE_A0 (SAVE_V1 + 4)
|
|
|
|
#define SAVE_A1 (SAVE_A0 + 4)
|
|
|
|
#define SAVE_A2 (SAVE_A1 + 4)
|
|
|
|
#define SAVE_A3 (SAVE_A2 + 4)
|
|
|
|
#define SAVE_T0 (SAVE_A3 + 4)
|
|
|
|
#define SAVE_T1 (SAVE_T0 + 4)
|
|
|
|
#define SAVE_T2 (SAVE_T1 + 4)
|
|
|
|
#define SAVE_T3 (SAVE_T2 + 4)
|
|
|
|
#define SAVE_T4 (SAVE_T3 + 4)
|
|
|
|
#define SAVE_T5 (SAVE_T4 + 4)
|
|
|
|
#define SAVE_T6 (SAVE_T5 + 4)
|
|
|
|
#define SAVE_T7 (SAVE_T6 + 4)
|
|
|
|
#define SAVE_T8 (SAVE_T7 + 4)
|
|
|
|
#define SAVE_T9 (SAVE_T8 + 4)
|
2009-05-22 23:48:49 +03:00
|
|
|
#define SAVE_S0 (SAVE_T9 + 4)
|
|
|
|
#define SAVE_S1 (SAVE_S0 + 4)
|
|
|
|
#define SAVE_S2 (SAVE_S1 + 4)
|
|
|
|
#define SAVE_S3 (SAVE_S2 + 4)
|
|
|
|
#define SAVE_S4 (SAVE_S3 + 4)
|
|
|
|
#define SAVE_S5 (SAVE_S4 + 4)
|
|
|
|
#define SAVE_S6 (SAVE_S5 + 4)
|
|
|
|
#define SAVE_S7 (SAVE_S6 + 4)
|
|
|
|
#define SAVE_GP (SAVE_S7 + 4)
|
2009-05-19 00:18:23 +03:00
|
|
|
#define SAVE_FP (SAVE_GP + 4)
|
|
|
|
#define SAVE_RA (SAVE_FP + 4)
|
|
|
|
#define SAVE_HI (SAVE_RA + 4)
|
|
|
|
#define SAVE_LO (SAVE_HI + 4)
|
|
|
|
#define SAVE_K0 (SAVE_LO + 4)
|
|
|
|
#define SAVE_K1 (SAVE_K0 + 4)
|
2009-05-11 01:28:12 +03:00
|
|
|
|
|
|
|
addr_000:
|
|
|
|
// TLB refill
|
|
|
|
// TODO: this should probably be assembly-only for speed reasons
|
2009-05-22 23:48:49 +03:00
|
|
|
sw $ra, -0xd88($zero)
|
2009-05-14 21:31:47 +03:00
|
|
|
bal save_regs
|
2009-05-11 01:28:12 +03:00
|
|
|
la $t9, tlb_refill
|
|
|
|
jr $t9
|
|
|
|
nop
|
|
|
|
.fill 0x100 - (. - addr_000)
|
|
|
|
addr_100:
|
|
|
|
// Cache error
|
2009-05-22 23:48:49 +03:00
|
|
|
sw $ra, -0xd88($zero)
|
2009-05-14 21:31:47 +03:00
|
|
|
bal save_regs
|
2009-05-11 01:28:12 +03:00
|
|
|
la $t9, cache_error
|
|
|
|
jr $t9
|
|
|
|
nop
|
|
|
|
.fill 0x180 - (. - addr_000)
|
|
|
|
addr_180:
|
|
|
|
// General exception
|
2009-05-22 23:48:49 +03:00
|
|
|
sw $ra, -0xd88($zero)
|
2009-05-14 21:31:47 +03:00
|
|
|
bal save_regs
|
2009-05-11 01:28:12 +03:00
|
|
|
la $t9, exception
|
|
|
|
jr $t9
|
|
|
|
nop
|
|
|
|
.fill 0x200 - (. - addr_000)
|
|
|
|
addr_200:
|
|
|
|
// Interrupt
|
2009-05-22 23:48:49 +03:00
|
|
|
sw $ra, -0xd88($zero)
|
2009-05-14 21:31:47 +03:00
|
|
|
bal save_regs
|
2009-05-11 01:28:12 +03:00
|
|
|
la $t9, interrupt
|
|
|
|
jr $t9
|
|
|
|
nop
|
2009-05-14 21:31:47 +03:00
|
|
|
.fill 0x280 - (. - addr_000) - 16
|
2009-05-11 01:28:12 +03:00
|
|
|
|
2009-05-14 21:31:47 +03:00
|
|
|
// space for save_regs: k0; current Thread; ra; gp
|
2009-05-22 23:48:49 +03:00
|
|
|
.word 0 // -d90 == k0
|
|
|
|
.word idle // -d8c == current
|
|
|
|
.word 0 // -d88 == ra
|
|
|
|
.word _gp // -d84 == gp
|
2009-05-11 01:28:12 +03:00
|
|
|
|
2009-05-14 21:31:47 +03:00
|
|
|
.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.
|
2009-05-22 23:48:49 +03:00
|
|
|
move $v0, $zero
|
2009-05-14 21:31:47 +03:00
|
|
|
syscall
|
2009-05-23 21:55:31 +03:00
|
|
|
nop
|
2009-05-14 21:31:47 +03:00
|
|
|
1: wait
|
|
|
|
b 1b
|
|
|
|
nop
|
2009-05-11 01:28:12 +03:00
|
|
|
|
2009-05-19 00:18:23 +03:00
|
|
|
// TODO: save only fragile registers now, the rest on task switch.
|
2009-05-14 21:31:47 +03:00
|
|
|
kernel_exit:
|
2009-05-19 00:18:23 +03:00
|
|
|
lw $k0, SAVE_PC($v0)
|
|
|
|
mtc0 $k0, $EPC
|
|
|
|
lw $k0, SAVE_LO($v0)
|
|
|
|
lw $k1, SAVE_HI($v0)
|
|
|
|
mtlo $k0
|
|
|
|
mthi $k1
|
|
|
|
lw $v1, SAVE_V1($v0)
|
|
|
|
lw $a0, SAVE_A0($v0)
|
|
|
|
lw $a1, SAVE_A1($v0)
|
|
|
|
lw $a2, SAVE_A2($v0)
|
|
|
|
lw $a3, SAVE_A3($v0)
|
|
|
|
lw $t0, SAVE_T0($v0)
|
|
|
|
lw $t1, SAVE_T1($v0)
|
|
|
|
lw $t2, SAVE_T2($v0)
|
|
|
|
lw $t3, SAVE_T3($v0)
|
|
|
|
lw $t4, SAVE_T4($v0)
|
|
|
|
lw $t5, SAVE_T5($v0)
|
|
|
|
lw $t6, SAVE_T6($v0)
|
|
|
|
lw $t7, SAVE_T7($v0)
|
|
|
|
lw $t8, SAVE_T8($v0)
|
|
|
|
lw $t9, SAVE_T9($v0)
|
2009-05-22 23:48:49 +03:00
|
|
|
lw $s0, SAVE_S0($v0)
|
|
|
|
lw $s1, SAVE_S1($v0)
|
|
|
|
lw $s2, SAVE_S2($v0)
|
|
|
|
lw $s3, SAVE_S3($v0)
|
|
|
|
lw $s4, SAVE_S4($v0)
|
|
|
|
lw $s5, SAVE_S5($v0)
|
|
|
|
lw $s6, SAVE_S6($v0)
|
|
|
|
lw $s7, SAVE_S7($v0)
|
2009-05-19 00:18:23 +03:00
|
|
|
lw $fp, SAVE_FP($v0)
|
|
|
|
lw $ra, SAVE_RA($v0)
|
|
|
|
lw $at, SAVE_AT($v0)
|
|
|
|
lw $k0, SAVE_K0($v0)
|
|
|
|
lw $k1, SAVE_V0($v0)
|
2009-05-22 23:48:49 +03:00
|
|
|
sw $k1, -0xd90($zero)
|
2009-05-19 00:18:23 +03:00
|
|
|
lw $k1, SAVE_K1($v0)
|
2009-05-22 23:48:49 +03:00
|
|
|
sw $v0, -0xd8c($zero)
|
2009-05-23 21:55:31 +03:00
|
|
|
|
|
|
|
lw $sp, SAVE_SP($v0)
|
2009-05-22 23:48:49 +03:00
|
|
|
lw $gp, SAVE_GP($v0)
|
|
|
|
lw $v0, -0xd90($zero)
|
2009-05-14 21:31:47 +03:00
|
|
|
eret
|
2009-05-11 01:28:12 +03:00
|
|
|
|
2009-05-14 21:31:47 +03:00
|
|
|
save_regs:
|
2009-05-22 23:48:49 +03:00
|
|
|
sw $k0, -0xd90($zero)
|
|
|
|
lw $k0, -0xd8c($zero)
|
|
|
|
|
2009-05-19 00:18:23 +03:00
|
|
|
sw $at, SAVE_AT($k0)
|
|
|
|
sw $gp, SAVE_GP($k0)
|
|
|
|
sw $sp, SAVE_SP($k0)
|
|
|
|
sw $fp, SAVE_FP($k0)
|
2009-05-11 01:28:12 +03:00
|
|
|
|
2009-05-19 00:18:23 +03:00
|
|
|
sw $k1, SAVE_K1($k0)
|
2009-05-22 23:48:49 +03:00
|
|
|
lw $k1, -0xd90($zero)
|
2009-05-19 00:18:23 +03:00
|
|
|
sw $k1, SAVE_K0($k0)
|
2009-05-11 01:28:12 +03:00
|
|
|
|
2009-05-22 23:48:49 +03:00
|
|
|
lw $k1, -0xd88($zero)
|
2009-05-19 00:18:23 +03:00
|
|
|
sw $k1, SAVE_RA($k0)
|
|
|
|
sw $v0, SAVE_V0($k0)
|
|
|
|
sw $v1, SAVE_V1($k0)
|
|
|
|
sw $a0, SAVE_A0($k0)
|
|
|
|
sw $a1, SAVE_A1($k0)
|
|
|
|
sw $a2, SAVE_A2($k0)
|
|
|
|
sw $a3, SAVE_A3($k0)
|
|
|
|
sw $t0, SAVE_T0($k0)
|
|
|
|
sw $t1, SAVE_T1($k0)
|
|
|
|
sw $t2, SAVE_T2($k0)
|
|
|
|
sw $t3, SAVE_T3($k0)
|
|
|
|
sw $t4, SAVE_T4($k0)
|
|
|
|
sw $t5, SAVE_T5($k0)
|
|
|
|
sw $t6, SAVE_T6($k0)
|
|
|
|
sw $t7, SAVE_T7($k0)
|
|
|
|
sw $t8, SAVE_T8($k0)
|
|
|
|
sw $t9, SAVE_T9($k0)
|
2009-05-22 23:48:49 +03:00
|
|
|
sw $s0, SAVE_S0($k0)
|
|
|
|
sw $s1, SAVE_S1($k0)
|
|
|
|
sw $s2, SAVE_S2($k0)
|
|
|
|
sw $s3, SAVE_S3($k0)
|
|
|
|
sw $s4, SAVE_S4($k0)
|
|
|
|
sw $s5, SAVE_S5($k0)
|
|
|
|
sw $s6, SAVE_S6($k0)
|
|
|
|
sw $s7, SAVE_S7($k0)
|
2009-05-14 21:31:47 +03:00
|
|
|
mfhi $v0
|
|
|
|
mflo $v1
|
2009-05-19 00:18:23 +03:00
|
|
|
sw $v0, SAVE_HI($k0)
|
|
|
|
sw $v1, SAVE_LO($k0)
|
|
|
|
mfc0 $k1, $EPC
|
|
|
|
sw $k1, SAVE_PC($k0)
|
2009-05-11 01:28:12 +03:00
|
|
|
|
2009-05-22 23:48:49 +03:00
|
|
|
lw $gp, -0xd84($zero)
|
2009-05-14 21:31:47 +03:00
|
|
|
la $sp, kernel_stack + KERNEL_STACK_SIZE
|
|
|
|
move $t9, $ra
|
|
|
|
la $ra, kernel_exit
|
|
|
|
jr $t9
|
2009-05-23 21:55:31 +03:00
|
|
|
nop
|
2009-05-22 23:48:49 +03:00
|
|
|
|
|
|
|
.globl thread0
|
|
|
|
.globl thread1
|
|
|
|
.globl thread2
|
|
|
|
.balign 0x1000
|
2009-05-23 21:55:31 +03:00
|
|
|
thread0:
|
2009-05-22 23:48:49 +03:00
|
|
|
.incbin "thread0"
|
|
|
|
.balign 0x1000
|
2009-05-23 21:55:31 +03:00
|
|
|
thread1:
|
2009-05-22 23:48:49 +03:00
|
|
|
.incbin "thread1"
|
|
|
|
thread2:
|