326 lines
5.1 KiB
C
326 lines
5.1 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "libsys.h"
|
|
#include "xcpt.h"
|
|
|
|
#define MAX_NUM_EXCEPTIONS 10
|
|
void *g_fp_badsubs[MAX_NUM_EXCEPTIONS];
|
|
|
|
void _exc_break(void)
|
|
{
|
|
__asm
|
|
(
|
|
".set noreorder\n"
|
|
"break 0x9\n"
|
|
".set reorder\n"
|
|
|
|
);
|
|
}
|
|
|
|
void _exc_syscall(UINT32 code, UINT32 arg)
|
|
{
|
|
__asm
|
|
(
|
|
"move $v0, %[code]\n"
|
|
"move $a0, %[arg]\n"
|
|
"syscall\n"
|
|
:
|
|
: [code] "r" (code), [arg] "r" (arg)
|
|
: "v0", "a0"
|
|
|
|
);
|
|
}
|
|
|
|
void _exc_arith(void)
|
|
{
|
|
__asm
|
|
(
|
|
".set noreorder\n"
|
|
" li $t0, 0x7FFFFFFF\n"
|
|
" addi $t1, $t0, 2\n"
|
|
".set reorder\n"
|
|
|
|
);
|
|
}
|
|
|
|
void _exc_store_err(void)
|
|
{
|
|
volatile int *pSrc = (int*)SYS_TIMER_SEC;
|
|
volatile int *pDst = (int*)0x80000001;
|
|
|
|
*pDst = *pSrc;
|
|
|
|
}
|
|
|
|
void _exc_load_err(void)
|
|
{
|
|
__asm
|
|
(
|
|
".set noreorder\n"
|
|
" li $t0, 0x80000000\n"
|
|
" li $t1, 0x80000000\n"
|
|
" lw $t1, 0($t1)\n"
|
|
" lw $t0, 2($t0)\n"
|
|
" lw $t1, 4($t0)\n"
|
|
"nop\n"
|
|
".set reorder\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
void _exc_kaddr_err(void)
|
|
{
|
|
__asm
|
|
(
|
|
".set noreorder\n"
|
|
" li $t0, 0x80000000\n"
|
|
" jr $t0\n"
|
|
"nop\n"
|
|
".set reorder\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
void _exc_dtlbl_err(void)
|
|
{
|
|
__asm
|
|
(
|
|
".set noreorder\n"
|
|
" li $t0, 0x00000000\n"
|
|
" lw $zero, 0($t0)\n"
|
|
"nop\n"
|
|
".set reorder\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
void _exc_dtlbs_err(void)
|
|
{
|
|
__asm
|
|
(
|
|
".set noreorder\n"
|
|
" li $t0, 0x00000000\n"
|
|
" sw $zero, 0($t0)\n"
|
|
".set reorder\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
void _exc_itlbl_err(void)
|
|
{
|
|
__asm
|
|
(
|
|
".set noreorder\n"
|
|
" li $t0, 0x80000000\n"
|
|
" jr $t0\n"
|
|
"nop\n"
|
|
".set reorder\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
void _exc_iaddr_daddr_err(void)
|
|
{
|
|
__asm
|
|
(
|
|
".set noreorder\n"
|
|
" li $t0, 0x80000003\n"
|
|
" li $t1, 0x80000002\n"
|
|
" jr $t0\n"
|
|
" lw $t1, 0($t1)\n"
|
|
"nop\n"
|
|
".set reorder\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
void _exc_daddr_iaddr_err(void)
|
|
{
|
|
__asm
|
|
(
|
|
".set noreorder\n"
|
|
" li $t0, 0x80000003\n"
|
|
" li $t1, 0x80000002\n"
|
|
" lw $t1, 0($t1)\n"
|
|
" jr $t0\n"
|
|
"nop\n"
|
|
".set reorder\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
void _exc_iaddr_err(void)
|
|
{
|
|
__asm
|
|
(
|
|
".set noreorder\n"
|
|
" li $t0, 0x80000003\n"
|
|
" jr $t0\n"
|
|
"nop\n"
|
|
".set reorder\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
void _exc_ri(void)
|
|
{
|
|
__asm
|
|
(
|
|
".set noreorder\n"
|
|
".word 0x9c563442\n"
|
|
".set reorder\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
void _exc_ibe(void)
|
|
{
|
|
__asm
|
|
(
|
|
".set noreorder\n"
|
|
" li $t1, 0x10000000\n"
|
|
" jr $t1\n"
|
|
"nop\n"
|
|
".set reorder\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
void _exc_dbe(void)
|
|
{
|
|
__asm
|
|
(
|
|
".set noreorder\n"
|
|
" li $t1, 0x10000000\n"
|
|
" lw $t0, 0($t1)\n"
|
|
"nop\n"
|
|
" jr $t0\n"
|
|
"nop\n"
|
|
".set reorder\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
void handler0(void)
|
|
{
|
|
sputs("Interrupt 0\n");
|
|
interrupt_clr(0);
|
|
}
|
|
|
|
void handler1(void)
|
|
{
|
|
sputs("Interrupt 1\n");
|
|
interrupt_clr(1);
|
|
}
|
|
|
|
int xcp_handler(struct xcptcontext * xcp)
|
|
{
|
|
sputs("----------------------------------------\n");
|
|
sputs("Exception Type: ");xcpt_exctype_print(xcp);sputs("\n");
|
|
sputs("----------------------------------------\n");
|
|
xcpt_registers_print(xcp);
|
|
sputs("\n");
|
|
|
|
if (xcpt_get_type(xcp) == EXC_INT)
|
|
{
|
|
interrupt_clr(0);
|
|
interrupt_clr(1);
|
|
}
|
|
else
|
|
{
|
|
// Skip instruction that caused exception
|
|
xcp->epc += 4;
|
|
if (xcp->cr & 0x80000000)
|
|
{
|
|
xcp->epc += 4;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
int buf[256];
|
|
int i, sel;
|
|
|
|
xcpt_register(EXC_INT, xcp_handler);
|
|
xcpt_register(EXC_RI, xcp_handler);
|
|
xcpt_register(EXC_OV, xcp_handler);
|
|
xcpt_register(EXC_BP, xcp_handler);
|
|
xcpt_register(EXC_SYSCALL, xcp_handler);
|
|
xcpt_register(EXC_TLBL, xcp_handler);
|
|
xcpt_register(EXC_TLBS, xcp_handler);
|
|
|
|
interrupt_register(0, handler0);
|
|
interrupt_enable(0);
|
|
interrupt_register(1, handler1);
|
|
interrupt_enable(1);
|
|
|
|
sputs("11 : SW-interrupt 0\n");
|
|
interrupt_set(0);
|
|
sputs("12 : SW-interrupt 1\n");
|
|
interrupt_set(1);
|
|
|
|
sputs(" 4 : Syscall\n");
|
|
_exc_syscall(4, (UINT32)((char*)"Hallo Syscall ("));
|
|
_exc_syscall(1, 12345678);
|
|
_exc_syscall(4, (UINT32)((char*)")\n"));
|
|
|
|
sputs(" 5 : Breakpoint\n");
|
|
_exc_break();
|
|
|
|
sputs(" 3 : Arithmetic overflow\n");
|
|
_exc_arith();
|
|
|
|
sputs(" 1 : Reserved instruction\n");
|
|
_exc_ri();
|
|
|
|
sputs(" 2 : DTLBS (BadVAddr = 0x00000000)\n");
|
|
_exc_dtlbs_err();
|
|
|
|
sputs(" 2 : DTLBL (BadVAddr = 0x00000000)\n");
|
|
_exc_dtlbl_err();
|
|
|
|
return 0;
|
|
|
|
sputs(" 2 : Privileged address (BadVAddr = 0x80000000)\n");
|
|
_exc_kaddr_err();
|
|
|
|
sputs(" 6 : Load error on instruction (BadVAddr = 0x40000003)\n");
|
|
_exc_iaddr_err();
|
|
|
|
sputs(" 7 : Load error on data (BadVAddr = 0x40000002)\n");
|
|
_exc_load_err();
|
|
|
|
sputs(" 8 : Store error on data (BadVAddr = 0x40000001)\n");
|
|
_exc_store_err();
|
|
|
|
// sputs(" 9 : Bus error on instruction\n");
|
|
// sputs("IBE: Exception not implemented in current CPU!\nPush reset to restart!\n");
|
|
// _exc_ibe();
|
|
|
|
// sputs("10 : Bus error on data\n");
|
|
// sputs("DBE: Exception not implemented in current CPU!\nPush reset to restart!\n");
|
|
// _exc_dbe();
|
|
|
|
sputs("13 : Load error on instruction and Load error on data (BadVAddr = 0x40000003)\n");
|
|
_exc_iaddr_daddr_err();
|
|
|
|
sputs("14 : Load error on data and Load error on instruction (BadVAddr = 0x40000002)\n");
|
|
_exc_daddr_iaddr_err();
|
|
|
|
return 0;
|
|
}
|