.file "kernel.s" .equ stack_ptr, 0x7FFFEFFC .equ baudrate, 0x0D .equ sys_led_port, 0xA0000000 .equ sys_uart_baud, 0xA0000009 .equ sys_uart_stat, 0xA0000008 .equ sys_uart_data, 0xA0000004 .equ sys_timer_sec, 0xA0000014 .equ sys_timer_usec, 0xA0000010 .section .kdata,"a" .align 2 _k_stack: .space 256, 0 _k_msg1: .asciiz "Exception at " _k_msg2: .asciiz "EPC : " _k_msg3: .asciiz "Cause : " _k_msg4: .asciiz "Status : " _k_msg5: .asciiz "BadVAddr : " _k_crlf: .asciiz "\r\n" _k_hextbl: .ascii "0123456789ABCDEF" .section .ktext,"ax" .align 2 .globl _kputs .macro kpush reg addiu $sp, 4 sw \reg, 0($sp) .endm .macro kpop reg lw \reg, 0($sp) addiu $sp, -4 .endm _exc_handler: sw $sp, _k_stack la $sp, _k_stack kpush $8 kpush $9 kpush $10 kpush $11 kpush $12 kpush $31 .set noreorder # # Get BadVAddr # mfc0 $10, $8 # kpush $10 # # Get Status # mfc0 $10, $12 # kpush $10 # # Get Cause # mfc0 $10, $13 # kpush $10 # srl $10, 29 # andi $11, $10, 4 # # Get EPC # mfc0 $10, $14 # kpush $10 # # # Get real EPC # addu $10, $11 # kpush $10 # # # set uart # la $26, sys_uart_baud # addiu $27, $0, baudrate # sb $27, 0($26) # # # Print CRLF # la $11, _k_crlf # jal _kputs # nop # # # Print real EPC # la $11, _k_msg1 # jal _kputs # nop # kpop $10 # jal _kprint_word # nop # la $11, _k_crlf # jal _kputs # nop # # # Print EPC # la $11, _k_msg2 # jal _kputs # nop # kpop $10 # jal _kprint_word # nop # la $11, _k_crlf # jal _kputs # nop # # # Print Cause # la $11, _k_msg3 # jal _kputs # nop # kpop $10 # jal _kprint_word # nop # la $11, _k_crlf # jal _kputs # nop # # # Print Status # la $11, _k_msg4 # jal _kputs # nop # kpop $10 # jal _kprint_word # nop # la $11, _k_crlf # jal _kputs # nop # # # Print BadVAddr # la $11, _k_msg5 # jal _kputs # nop # kpop $10 # jal _kprint_word # nop # la $11, _k_crlf # jal _kputs # nop # # Set Error LED and ExcCode LEDs # Get Cause # mfc0 $26, $13 # la $27, sys_led_port # srl $26, 2 # andi $26, 0x000F # or $26, $27 # sw $26, 0($27) # wait for all interrupts = 0 #$w4x: mfc0 $26, $13 # mfc0 $27, $12 # srl $26, 8 # srl $27, 8 # and $26, $27 # bnez $26, $w4x # Get return address mfc0 $26, $14 $no_int: kpop $31 kpop $12 kpop $11 kpop $10 kpop $9 kpop $8 lw $sp, _k_stack # Return jr $26 rfe .set reorder # word = $10 _kprint_word: .set noreorder kpush $31 kpush $10 srl $10, 16 jal _kprint_halfword nop kpop $10 jal _kprint_halfword nop kpop $31 jr $31 nop .set noreorder # halfword = $10 _kprint_halfword: .set noreorder kpush $31 kpush $10 srl $10, 8 jal _kprint_byte nop kpop $10 jal _kprint_byte nop kpop $31 jr $31 nop .set noreorder # byte = $10 _kprint_byte: .set noreorder kpush $31 kpush $10 srl $10, 4 jal _kprint_nibble nop kpop $10 jal _kprint_nibble nop kpop $31 jr $31 nop .set noreorder _kprint_nibble: .set noreorder kpush $31 kpush $10 la $12, _k_hextbl andi $10, 0xF addu $12, $10 lbu $10, 0($12) jal _ksaus nop kpop $10 kpop $31 jr $31 nop .set noreorder # char = $10 _ksaus: .set noreorder la $8, sys_uart_stat lbu $8, 0($8) la $9, sys_uart_data andi $8, 0x02 bnez $8, _ksaus nop j $31 sb $10, 0($9) .set reorder _kputs: .set noreorder kpush $11 kpush $31 $kpl: lbu $10, 0($11) addiu $11, 1 blez $10, $kpex nop jal _ksaus nop j $kpl nop $kpex: kpop $31 kpop $11 jr $31 nop .set reorder