2009-02-09 21:15:56 +00:00
|
|
|
// EE core interrupt and exception handlers
|
|
|
|
// most functions here can only use $at, $k0, and $k1
|
|
|
|
// [made by] [RO]man, zerofrog
|
|
|
|
|
|
|
|
#include "eekernel.h"
|
|
|
|
#include "eeirq.h"
|
|
|
|
|
|
|
|
|
|
|
|
#define LOAD_KERNELSTACK \
|
|
|
|
"lui $sp, %hi(g_kernelstackend)\n" \
|
|
|
|
"addiu $sp, %lo(g_kernelstackend)\n"
|
|
|
|
|
|
|
|
__asm__(".org 0x0000");
|
|
|
|
|
|
|
|
__asm__(".set noreorder");
|
|
|
|
void CpuException0() {
|
|
|
|
__asm__ (
|
|
|
|
"lui $26, %hi(SavedT9)\n"
|
|
|
|
"sd $25, %lo(SavedT9)($26)\n"
|
|
|
|
|
|
|
|
"mfc0 $25, $13\n"
|
|
|
|
"andi $25, 0x7C\n"
|
|
|
|
"lui $26, %hi(VCRTable)\n"
|
|
|
|
"addu $26, $25\n"
|
|
|
|
"lw $26, %lo(VCRTable)($26)\n"
|
|
|
|
|
|
|
|
"lui $25, %hi(SavedT9)\n"
|
|
|
|
"jr $26\n"
|
|
|
|
"ld $25, %lo(SavedT9)($25)\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
__asm__(".org 0x0180");
|
|
|
|
|
|
|
|
__asm__(".set noreorder");
|
|
|
|
void CpuException() {
|
|
|
|
__asm__ (
|
|
|
|
"lui $26, %hi(SavedT9)\n"
|
|
|
|
"sd $25, %lo(SavedT9)($26)\n"
|
|
|
|
|
|
|
|
"mfc0 $25, $13\n"
|
|
|
|
"andi $25, 0x7C\n"
|
|
|
|
"lui $26, %hi(VCRTable)\n"
|
|
|
|
"addu $26, $25\n"
|
|
|
|
"lw $26, %lo(VCRTable)($26)\n"
|
|
|
|
|
|
|
|
"lui $25, %hi(SavedT9)\n"
|
|
|
|
"jr $26\n"
|
|
|
|
"ld $25, %lo(SavedT9)($25)\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
__asm__(".org 0x0200");
|
|
|
|
|
|
|
|
__asm__(".set noreorder");
|
|
|
|
__asm__(".set noat");
|
|
|
|
void CpuException2() {
|
|
|
|
__asm__ (
|
|
|
|
"lui $26, %hi(SavedSP)\n"
|
|
|
|
"sq $sp, %lo(SavedSP)($26)\n"
|
|
|
|
"lui $26, %hi(SavedRA)\n"
|
|
|
|
"sq $31, %lo(SavedRA)($26)\n"
|
|
|
|
"lui $26, %hi(SavedAT)\n"
|
|
|
|
"sq $1, %lo(SavedAT)($26)\n"
|
|
|
|
|
|
|
|
"mfc0 $1, $13\n"
|
|
|
|
"mfc0 $26, $14\n"
|
|
|
|
"and $1, $26\n"
|
|
|
|
"srl $1, 8\n"
|
|
|
|
"andi $1, 0xFF\n"
|
|
|
|
|
|
|
|
"plzcw $26, $1\n"
|
|
|
|
"andi $26, 0xFF\n"
|
|
|
|
"ori $1, $0, 0x1E\n"
|
|
|
|
"subu $1, $26\n"
|
|
|
|
"sll $1, 2\n"
|
|
|
|
"lui $26, %hi(VIntTable)\n"
|
|
|
|
"addu $26, $25\n"
|
|
|
|
"lw $26, %lo(VIntTable)($26)\n"
|
|
|
|
"jr $26\n"
|
|
|
|
"nop\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern char call_used_regs[];
|
|
|
|
extern char fixed_regs[];
|
|
|
|
|
|
|
|
__asm__(".org 0x0280");
|
|
|
|
__asm__(".set noreorder");
|
|
|
|
|
|
|
|
void SyscException()
|
|
|
|
{
|
|
|
|
const register int code __asm__("$3"); // $v1
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
if (code < 0) {
|
|
|
|
__asm__(
|
|
|
|
"addiu $sp, -0x10\n"
|
|
|
|
"sw $31, 0($sp)\n"
|
|
|
|
"mfc0 $26, $14\n"
|
|
|
|
"addiu $26, 4\n"
|
|
|
|
"sw $26, 4($sp)\n"
|
|
|
|
"mtc0 $26, $14\n"
|
|
|
|
"sync\n");
|
|
|
|
|
|
|
|
table_SYSCALL[-code]();
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
__asm__(
|
|
|
|
"lw $26, 4($sp)\n"
|
|
|
|
"lw $31, 0($sp)\n"
|
|
|
|
"addiu $sp, 0x10\n"
|
|
|
|
"mtc0 $26, $14\n"
|
|
|
|
"sync\n"
|
|
|
|
"eret\n"
|
|
|
|
"nop\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (code == 0x7c) {
|
|
|
|
_Deci2Call();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
__asm__(
|
|
|
|
"lui $26, %hi(SavedSP)\n"
|
|
|
|
"sq $sp, %lo(SavedSP)($26)\n"
|
|
|
|
"lui $26, %hi(SavedRA)\n"
|
|
|
|
"sq $31, %lo(SavedRA)($26)\n"
|
|
|
|
"lui $26, %hi(SavedAT)\n"
|
|
|
|
"sq $1, %lo(SavedAT)($26)\n"
|
|
|
|
|
|
|
|
"mfc0 $1, $12\n"
|
|
|
|
"addiu $26, $0, 0xFFE4\n"
|
|
|
|
"and $1, $26\n"
|
|
|
|
"mtc0 $1, $12\n"
|
|
|
|
"sync\n"
|
|
|
|
|
|
|
|
"move $26, $sp\n"
|
|
|
|
LOAD_KERNELSTACK
|
|
|
|
"addiu $sp, -0x10\n"
|
|
|
|
"sw $31, 0($sp)\n"
|
|
|
|
"sw $26, 4($sp)\n"
|
|
|
|
"mfc0 $26, $14\n"
|
|
|
|
"addiu $26, 4\n"
|
|
|
|
"sw $26, 8($sp)\n"
|
|
|
|
"mtc0 $26, $14\n"
|
|
|
|
"sync\n");
|
|
|
|
|
|
|
|
table_SYSCALL[code]();
|
|
|
|
|
|
|
|
__asm__(
|
|
|
|
"lw $26, 8($sp)\n"
|
|
|
|
"lw $31, 0($sp)\n"
|
|
|
|
"lw $sp, 4($sp)\n"
|
|
|
|
"mtc0 $26, $14\n"
|
|
|
|
"sync\n"
|
|
|
|
|
|
|
|
"mfc0 $26, $12\n"
|
|
|
|
"ori $26, 0x13\n"
|
|
|
|
"mtc0 $26, $12\n"
|
|
|
|
"sync\n"
|
|
|
|
"eret\n"
|
|
|
|
"nop\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
void _Deci2Call() {
|
|
|
|
__puts("_Deci2Call called\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
void __ThreadHandler();
|
|
|
|
|
|
|
|
void INTCException() {
|
|
|
|
u32 code;
|
|
|
|
u32 temp;
|
|
|
|
|
|
|
|
code = INTC_STAT & INTC_MASK;
|
|
|
|
if (code & 0xC0) {
|
|
|
|
int VpuStat;
|
|
|
|
|
|
|
|
__asm__("cfc2 %0, $29\n" : "=r"(VpuStat) : );
|
|
|
|
if (VpuStat & 0x202) {
|
|
|
|
__asm__(
|
|
|
|
".set noat\n"
|
|
|
|
"lui $26, %hi(SavedAT)\n"
|
|
|
|
"lq $1, %lo(SavedAT)($26)\n"
|
|
|
|
".set at\n");
|
|
|
|
__exception();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
__asm__ (
|
|
|
|
"mfc0 $26, $14\n"
|
|
|
|
"li $27, 0xFFFFFFE4\n"
|
|
|
|
"and $26, $27\n"
|
|
|
|
"mtc0 $26, $14\n"
|
|
|
|
"sync\n"
|
|
|
|
|
|
|
|
LOAD_KERNELSTACK
|
|
|
|
"addiu $sp, -0x10\n"
|
|
|
|
"mfc0 $26, $14\n"
|
|
|
|
"sw $26, 0($sp)\n"
|
|
|
|
);
|
|
|
|
saveContext2();
|
|
|
|
|
|
|
|
__asm__ (
|
|
|
|
"plzcw %0, %1"
|
2010-04-25 00:31:27 +00:00
|
|
|
: "=r"(temp) : "r"(code)
|
2009-02-09 21:15:56 +00:00
|
|
|
);
|
|
|
|
temp = 0x1e - (temp & 0xff);
|
|
|
|
INTC_STAT = 1 << temp;
|
|
|
|
threadStatus = 0;
|
|
|
|
|
|
|
|
INTCTable[temp](temp);
|
|
|
|
|
|
|
|
restoreContext2();
|
|
|
|
|
|
|
|
__asm__ (
|
|
|
|
".set noat\n"
|
|
|
|
"lw $26, 0($sp)\n"
|
|
|
|
"mtc0 $26, $14\n"
|
|
|
|
"lui $26, %hi(SavedSP)\n"
|
|
|
|
"lq $sp, %lo(SavedSP)($26)\n"
|
|
|
|
"lui $26, %hi(SavedRA)\n"
|
|
|
|
"lq $31, %lo(SavedRA)($26)\n"
|
|
|
|
"lui $26, %hi(SavedAT)\n"
|
|
|
|
"lq $1, %lo(SavedAT)($26)\n"
|
|
|
|
".set at\n"
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!threadStatus) {
|
|
|
|
__asm__ (
|
|
|
|
"mfc0 $26, $12\n"
|
|
|
|
"ori $26, 0x13\n"
|
|
|
|
"mtc0 $26, $12\n"
|
|
|
|
"sync\n"
|
|
|
|
"eret\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
__asm__(LOAD_KERNELSTACK);
|
|
|
|
threadStatus = 0;
|
|
|
|
|
|
|
|
__ThreadHandler();
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
//800004C0
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
void DMACException() {
|
|
|
|
unsigned int code;
|
|
|
|
unsigned int temp;
|
|
|
|
|
|
|
|
code = (DMAC_STAT >> 16) | 0x8000;
|
|
|
|
code&= DMAC_STAT & 0xFFFF;
|
|
|
|
if (code & 0x80) {
|
|
|
|
//__printf("%s: code & 0x80\n", __FUNCTION__);
|
|
|
|
__asm__(
|
|
|
|
".set noat\n"
|
|
|
|
"lui $26, %hi(SavedAT)\n"
|
|
|
|
"lq $1, %lo(SavedAT)($26)\n"
|
|
|
|
".set at\n");
|
|
|
|
__exception1();
|
|
|
|
}
|
|
|
|
__asm__ (
|
|
|
|
"mfc0 $26, $14\n"
|
|
|
|
"li $27, 0xFFFFFFE4\n"
|
|
|
|
"and $26, $27\n"
|
|
|
|
"mtc0 $26, $14\n"
|
|
|
|
"sync\n"
|
|
|
|
|
|
|
|
LOAD_KERNELSTACK
|
|
|
|
"addiu $sp, -0x10\n"
|
|
|
|
"mfc0 $26, $14\n"
|
|
|
|
"sw $26, 0($sp)\n"
|
|
|
|
);
|
|
|
|
saveContext2();
|
|
|
|
|
|
|
|
__asm__ (
|
|
|
|
"plzcw %0, %1"
|
2010-04-25 00:31:27 +00:00
|
|
|
: "=r"(temp) : "r"(code)
|
2009-02-09 21:15:56 +00:00
|
|
|
);
|
|
|
|
temp = 0x1e - (temp & 0xff);
|
|
|
|
DMAC_STAT = 1 << temp;
|
|
|
|
threadStatus = 0;
|
|
|
|
|
|
|
|
DMACTable[temp](temp);
|
|
|
|
|
|
|
|
restoreContext2();
|
|
|
|
|
|
|
|
__asm__ (
|
|
|
|
".set noat\n"
|
|
|
|
"lw $26, 0($sp)\n"
|
|
|
|
"mtc0 $26, $14\n"
|
|
|
|
"lui $26, %hi(SavedSP)\n"
|
|
|
|
"lq $sp, %lo(SavedSP)($26)\n"
|
|
|
|
"lui $26, %hi(SavedRA)\n"
|
|
|
|
"lq $31, %lo(SavedRA)($26)\n"
|
|
|
|
"lui $26, %hi(SavedAT)\n"
|
|
|
|
"lq $1, %lo(SavedAT)($26)\n"
|
|
|
|
".set at\n"
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!threadStatus) {
|
|
|
|
__asm__ (
|
|
|
|
"mfc0 $26, $12\n"
|
|
|
|
"ori $26, 0x13\n"
|
|
|
|
"mtc0 $26, $12\n"
|
|
|
|
"sync\n"
|
|
|
|
"eret\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
__asm__(LOAD_KERNELSTACK);
|
|
|
|
threadStatus = 0;
|
|
|
|
|
|
|
|
__ThreadHandler();
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
//80000600
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
void TIMERException()
|
|
|
|
{
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
//80000700
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
void setINTCHandler(int n, void (*phandler)(int))
|
|
|
|
{
|
|
|
|
INTCTable[n] = phandler;
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
//80000780
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
void setDMACHandler(int n, void (*phandler)(int))
|
|
|
|
{
|
|
|
|
DMACTable[n] = phandler;
|
|
|
|
}
|