1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-11-17 23:22:49 +02:00
iris/entry.S
2009-05-11 00:28:12 +02:00

231 lines
4.0 KiB
ArmAsm

// The kernel stack.
.lcomm kernel_stack, KERNEL_STACK_SIZE
.globl __start
.globl run_idle
.set noat
.set noreorder
#define EntryLo0 2
#define EntryLo1 3
#define EntryHi 10
#define Random 1
#define Index 0
#define PageMask 5
#define Wired 6
#define Config 16
#define Status 12
#define Cause 13
#define Compare 11
#define save_regs \
sw $k0, -0x180($zero) ;\
lw $k0, -0x184($zero) ;\
sw $at, 12($k0) ;\
sw $k1, 108($k0) ;\
lw $k1, -0x180($zero) ;\
sw $k1, 104($k0) ;\
sw $v0, 16($k0) ;\
sw $v1, 20($k0) ;\
sw $t0, 40($k0) ;\
sw $sp, 84($k0) ;\
sw $fp, 88($k0) ;\
sw $ra, 92($k0) ;\
lw $gp, -12($zero) ;\
la $sp, kernel_stack + KERNEL_STACK_SIZE ;\
move $a0, $k0 ;\
la $ra, kernel_exit ;\
bal save_args
#define restore_regs \
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) ;\
sw $k1, -0x180($zero) ;\
lw $k1, 108($k0) ;\
sw $k0, -0x184($zero) ;\
lw $k0, -0x180($zero)
addr_000:
// TLB refill
// TODO: this should probably be assembly-only for speed reasons
li $a0, 0xffff0000
la $t9, panic
jr $t9
save_regs
mfc0 $a1, $EntryHi
la $t9, tlb_refill
jr $t9
nop
.fill 0x100 - (. - addr_000)
addr_100:
// Cache error
// TODO
li $a0, 0xaaaa0000
la $t9, panic
jr $t9
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
save_regs
la $t9, exception
jr $t9
nop
.fill 0x200 - (. - addr_000)
addr_200:
// Interrupt
// TODO
li $a0, 0x0a0f0000
la $t9, panic
jr $t9
save_regs
la $t9, interrupt
jr $t9
nop
.fill 0x280 - (. - addr_000)
// space for save_regs.
.word 0
.word 0
start_idle:
b .
nop
.word idle_page
.word 0x80000000 // A pointer to the current page.
__start:
bal 1f
nop
.word _gp
// For some reason the disassembler considers everything
// after __start non-code until the next label. So I add a label.
start_hack:
1: lw $gp, 0($ra)
la $sp, kernel_stack + KERNEL_STACK_SIZE
// Disable interrupts during bootstrap.
mtc0 $zero, $Status
// TODO: flush cache
// Set kseg0 cachable.
li $k0, 0x3
mtc0 $k0, $Config, 0
// Clear .bss
la $a0, _edata
la $a1, _end
1: sw $zero, 0($a0)
bne $a1, $a0, 1b
addu $a0, 4
// Set timer to a defined value
mtc0 $zero, $Compare, 0
// Use the interrupt vector for interrupts
li $k0, 1 << 23
mtc0 $k0, $Cause
li $a0, 0xff0a0000
la $t9, panic
jr $t9
// clear the tlb, hardwire page 0 to 0xffffffff
// and soft-wire it to (0x294 << 20) + (0x290 << 10)
// (for the idle task).
// this address doesn't reach the tlb, so it can't trigger exceptions.
mtc0 $zero, $PageMask
mtc0 $zero, $EntryLo0
mtc0 $zero, $EntryLo1
li $t0, 0x80000000
// There are 32 tlb entries.
addi $a0, $zero, 31
1: mtc0 $t0, $EntryHi
mtc0 $a0, $Index
tlbwi
addiu $t0, $t0, 1 << 13
bgtz $a0, 1b
addiu $a0, $a0, -1
la $t9, init
jalr $t9
nop
sw $gp, -12($zero)
save_args:
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)
sw $gp, 80($k0)
j $ra
run_idle:
move $k0, $a0
move $k1, $gp
// Prepare enabling interrupts and switching to user mode.
// The command is executed in the delay slot of the jump.
li $t0, 0xff11
// Now it's acceptable to receive an exception. Jump to kuseg,
// thereby generating a tlb_refill exception (which is handled).
// The address is the virtual address where the idle task is.
la $t9, ((0x294 << 20) + (0x290 << 10) + 0x288)
jr $t9
mtc0 $t0, $Status
kernel_exit:
move $k0, $v0
restore_regs
eret