HelenOS sources
#
#
#
# - Redistributions of source code must retain the above copyright
# - Redistributions in binary form must reproduce the above copyright
# - The name of the author may not be used to endorse or promote products
#
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
#
#include <abi/asmtool.h>
#include <arch/asm/regname.h>
#include <arch/mm/page.h>
#include <arch/asm/boot.h>
#include <arch/stack.h>
#include <arch/istate_struct.h>
.text
.set noat
.set noreorder
#define REG_SAVE_MASK 0x1f
.macro FAKE_ABI_PROLOGUE
sub $sp, ISTATE_SIZE
sw $ra, ISTATE_OFFSET_EPC($sp)
.endm
.macro REGISTERS_STORE_AND_EXC_RESET r
sw $at, ISTATE_OFFSET_AT(\r)
sw $v0, ISTATE_OFFSET_V0(\r)
sw $v1, ISTATE_OFFSET_V1(\r)
sw $a0, ISTATE_OFFSET_A0(\r)
sw $a1, ISTATE_OFFSET_A1(\r)
sw $a2, ISTATE_OFFSET_A2(\r)
sw $a3, ISTATE_OFFSET_A3(\r)
sw $t0, ISTATE_OFFSET_T0(\r)
sw $t1, ISTATE_OFFSET_T1(\r)
sw $t2, ISTATE_OFFSET_T2(\r)
sw $t3, ISTATE_OFFSET_T3(\r)
sw $t4, ISTATE_OFFSET_T4(\r)
sw $t5, ISTATE_OFFSET_T5(\r)
sw $t6, ISTATE_OFFSET_T6(\r)
sw $t7, ISTATE_OFFSET_T7(\r)
sw $t8, ISTATE_OFFSET_T8(\r)
sw $t9, ISTATE_OFFSET_T9(\r)
sw $s0, ISTATE_OFFSET_S0(\r)
sw $s1, ISTATE_OFFSET_S1(\r)
sw $s2, ISTATE_OFFSET_S2(\r)
sw $s3, ISTATE_OFFSET_S3(\r)
sw $s4, ISTATE_OFFSET_S4(\r)
sw $s5, ISTATE_OFFSET_S5(\r)
sw $s6, ISTATE_OFFSET_S6(\r)
sw $s7, ISTATE_OFFSET_S7(\r)
sw $s8, ISTATE_OFFSET_S8(\r)
mflo $at
sw $at, ISTATE_OFFSET_LO(\r)
mfhi $at
sw $at, ISTATE_OFFSET_HI(\r)
sw $gp, ISTATE_OFFSET_GP(\r)
sw $ra, ISTATE_OFFSET_RA(\r)
sw $k0, ISTATE_OFFSET_KT0(\r)
sw $k1, ISTATE_OFFSET_KT1(\r)
mfc0 $t0, $status
mfc0 $t1, $epc
and $t2, $t0, REG_SAVE_MASK
li $t3, ~(REG_SAVE_MASK)
and $t0, $t0, $t3
sw $t2, ISTATE_OFFSET_STATUS(\r)
sw $t1, ISTATE_OFFSET_EPC(\r)
mtc0 $t0, $status
.endm
.macro REGISTERS_LOAD r
mfc0 $t0, $status
lw $t1, ISTATE_OFFSET_STATUS(\r)
li $t2, ~REG_SAVE_MASK
and $t0, $t0, $t2
or $t0, $t0, $t1
mtc0 $t0, $status
lw $v0, ISTATE_OFFSET_V0(\r)
lw $v1, ISTATE_OFFSET_V1(\r)
lw $a0, ISTATE_OFFSET_A0(\r)
lw $a1, ISTATE_OFFSET_A1(\r)
lw $a2, ISTATE_OFFSET_A2(\r)
lw $a3, ISTATE_OFFSET_A3(\r)
lw $t0, ISTATE_OFFSET_T0(\r)
lw $t1, ISTATE_OFFSET_T1(\r)
lw $t2, ISTATE_OFFSET_T2(\r)
lw $t3, ISTATE_OFFSET_T3(\r)
lw $t4, ISTATE_OFFSET_T4(\r)
lw $t5, ISTATE_OFFSET_T5(\r)
lw $t6, ISTATE_OFFSET_T6(\r)
lw $t7, ISTATE_OFFSET_T7(\r)
lw $t8, ISTATE_OFFSET_T8(\r)
lw $t9, ISTATE_OFFSET_T9(\r)
lw $gp, ISTATE_OFFSET_GP(\r)
lw $ra, ISTATE_OFFSET_RA(\r)
lw $k1, ISTATE_OFFSET_KT1(\r)
lw $at, ISTATE_OFFSET_LO(\r)
mtlo $at
lw $at, ISTATE_OFFSET_HI(\r)
mthi $at
lw $at, ISTATE_OFFSET_EPC(\r)
mtc0 $at, $epc
lw $at, ISTATE_OFFSET_AT(\r)
lw $sp, ISTATE_OFFSET_SP(\r)
.endm
.macro KERNEL_STACK_TO_K0
mfc0 $k0, $status
andi $k0, 0x10
beq $k0, $0, 1f
move $k0, $sp
la $k0, supervisor_sp
lw $k0, ($k0)
1:
.endm
.org 0x0
SYMBOL(kernel_image_start)
lui $sp, %hi(end_stack)
ori $sp, $sp, %lo(end_stack)
lui $gp, 0x8000
jal mips32_pre_main
addiu $sp, -ABI_STACK_FRAME
j main_bsp
nop
.space TEMP_STACK_SIZE
end_stack:
SYMBOL(tlb_refill_entry)
j tlb_refill_handler
nop
SYMBOL(cache_error_entry)
j cache_error_handler
nop
SYMBOL(exception_entry)
j exception_handler
nop
FAKE_ABI_PROLOGUE
exception_handler:
KERNEL_STACK_TO_K0
sub $k0, ISTATE_SIZE
sw $sp, ISTATE_OFFSET_SP($k0)
move $sp, $k0
mfc0 $k0, $cause
sra $k0, $k0, 0x2
andi $k0, $k0, 0x1f
sub $k0, 8
beqz $k0, syscall_shortcut
add $k0, 8
REGISTERS_STORE_AND_EXC_RESET $sp
move $a1, $sp
move $a0, $k0
jal exc_dispatch
addiu $sp, -ABI_STACK_FRAME
addiu $sp, ABI_STACK_FRAME
REGISTERS_LOAD $sp
eret
syscall_shortcut:
mfc0 $t3, $epc
mfc0 $t2, $status
sw $t3, ISTATE_OFFSET_EPC($sp)
and $t4, $t2, REG_SAVE_MASK
li $t5, ~(0x1f)
and $t2, $t2, $t5
ori $t2, $t2, 0x1
sw $t4, ISTATE_OFFSET_STATUS($sp)
mtc0 $t2, $status
sw $t0, ISTATE_OFFSET_T0($sp)
sw $t1, ISTATE_OFFSET_T1($sp)
jal syscall_handler
sw $v0, ISTATE_OFFSET_V0($sp)
mfc0 $t2, $status
lw $t3, ISTATE_OFFSET_STATUS($sp)
li $t4, ~REG_SAVE_MASK
and $t2, $t2, $t4
or $t2, $t2, $t3
mtc0 $t2, $status
lw $t2, ISTATE_OFFSET_EPC($sp)
addi $t2, $t2, 4
mtc0 $t2, $epc
lw $sp, ISTATE_OFFSET_SP($sp)
eret
FAKE_ABI_PROLOGUE
tlb_refill_handler:
KERNEL_STACK_TO_K0
sub $k0, ISTATE_SIZE
REGISTERS_STORE_AND_EXC_RESET $k0
sw $sp, ISTATE_OFFSET_SP($k0)
move $sp, $k0
move $a0, $sp
jal tlb_refill
addiu $sp, -ABI_STACK_FRAME
addiu $sp, ABI_STACK_FRAME
REGISTERS_LOAD $sp
eret
FAKE_ABI_PROLOGUE
cache_error_handler:
KERNEL_STACK_TO_K0
sub $k0, ISTATE_SIZE
REGISTERS_STORE_AND_EXC_RESET $k0
sw $sp, ISTATE_OFFSET_SP($k0)
move $sp, $k0
move $a0, $sp
jal cache_error
addiu $sp, -ABI_STACK_FRAME
addiu $sp, ABI_STACK_FRAME
REGISTERS_LOAD $sp
eret
FUNCTION_BEGIN(userspace_asm)
move $sp, $a0
xor $a0, $a0, $a0
xor $fp, $fp, $fp
xor $ra, $ra, $ra
eret
FUNCTION_END(userspace_asm)
HelenOS homepage, sources at GitHub