diff options
Diffstat (limited to 'os/boot/puma/ebsit.trap.c')
| -rw-r--r-- | os/boot/puma/ebsit.trap.c | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/os/boot/puma/ebsit.trap.c b/os/boot/puma/ebsit.trap.c new file mode 100644 index 00000000..f95c0418 --- /dev/null +++ b/os/boot/puma/ebsit.trap.c @@ -0,0 +1,206 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "ebsit.h" +#include "dat.h" +#include "fns.h" + +#include "ureg.h" + +int inpanic; + +#define CSR ((ushort *) 0x2000000) + + +typedef struct Irqctlr { + uint addr; + uint enabled; + struct { + void (*r)(Ureg*, void*); + void *a; + } h[16]; +} Irqctlr; + +static Irqctlr irqctlr; + +void +csrset( int bit ) +{ +static ushort *csr_val = 0x8c; + + *csr_val ^= (1 << bit); + putcsr(*csr_val); +} + +void +intrinit( void ) +{ +int offset; +ulong op; + + + irqctlr.addr = 1; + irqctlr.enabled = 0; + + /* Reset Exception */ + offset = ((((ulong) _vsvccall) - 0x0)-8) >> 2; + op = ( 0xea << 24 ) | offset; + *((ulong *) 0x0) = op; + + /* Undefined Instruction Exception */ + offset = ((((ulong) _vundcall) - 0x4)-8) >> 2; + op = ( 0xea << 24 ) | offset; + *((ulong *) 0x4) = op; + + /* SWI Exception */ + offset = ((((ulong) _vsvccall) - 0x8)-8) >> 2; + op = ( 0xea << 24 ) | offset; + *((ulong *) 0x8) = op; + + /* Prefetch Abort Exception */ + offset = ((((ulong) _vpabcall) - 0xc)-8) >> 2; + op = ( 0xea << 24 ) | offset; + *((ulong *) 0xc) = op; + + /* Data Abort Exception */ + offset = ((((ulong) _vdabcall) - 0x10)-8) >> 2; + op = ( 0xea << 24 ) | offset; + *((ulong *) 0x10) = op; + + /* IRQ Exception */ + offset = ((((ulong) _virqcall) - 0x18)-8) >> 2; + op = ( 0xea << 24 ) | offset; + *((ulong *) 0x18) = op; + + +} + +void +intrenable(uint addr, int bit, void (*r)(Ureg*, void*), void* a) +{ + int i; + USED(addr); + for(i = 0; i < 16; i++) + { + if((bit & (1<<i)) == 0) + continue; + irqctlr.h[i].r = r; + irqctlr.h[i].a = a; + irqctlr.enabled |= (1<<i); + if (i < 7) + csrset(i); + } + return; +} + +int lucifer; /* Global to store the last CSR (eric) */ + +static void +interrupt(Ureg* ureg) +{ + int i, mask; + + mask = *CSR; + lucifer = mask; /* eric */ + if(irqctlr.enabled == 0){ + + return; + } + for(i = 0; i < 16; i++) + { + + if((irqctlr.enabled & (1<<i)) == 0) + continue; + if(( mask & (1 << i)) == 0) + continue; + if (!irqctlr.h[i].r) + continue; + (irqctlr.h[i].r)(ureg, irqctlr.h[i].a); + mask &= ~(1 << i); + } + + if ((mask) && (mask < 0x90)) /* ignore non-maskable interrupts */ + { + print("unknown or unhandled interrupt\n"); + panic("unknown or unhandled interrupt: mask=%ux",mask); + } + +} + +static void +dumpregs(Ureg* ureg) +{ + print("PSR %8.8uX type %2.2uX PC %8.8uX LINK %8.8uX\n", + ureg->psr, ureg->type, ureg->pc, ureg->link); + print("R14 %8.8uX R13 %8.8uX R12 %8.8uX R11 %8.8uX R10 %8.8uX\n", + ureg->r14, ureg->r13, ureg->r12, ureg->r11, ureg->r10); + print("R9 %8.8uX R8 %8.8uX R7 %8.8uX R6 %8.8uX R5 %8.8uX\n", + ureg->r9, ureg->r8, ureg->r7, ureg->r6, ureg->r5); + print("R4 %8.8uX R3 %8.8uX R2 %8.8uX R1 %8.8uX R0 %8.8uX\n", + ureg->r4, ureg->r3, ureg->r2, ureg->r1, ureg->r0); + print("Last Interrupt's CSR: %8.8uX\n",lucifer); + print("CPSR %8.8uX SPSR %8.8uX\n", cpsrr(), spsrr()); +} + +void +dumpstack(void) +{ +} + +void +exception(Ureg* ureg) +{ + static Ureg old_ureg; + uint far =0; + uint fsr =0; + + static lasttype = 0; + + LOWBAT; + + USED(far, fsr); + + lasttype = ureg->type; + + /* + * All interrupts/exceptions should be resumed at ureg->pc-4, + * except for Data Abort which resumes at ureg->pc-8. + */ + + if(ureg->type == (PsrMabt+1)) + ureg->pc -= 8; + else + ureg->pc -= 4; + + switch(ureg->type){ + + case PsrMfiq: /* (Fast) */ + print("Fast\n"); + print("We should never be here\n"); + while(1); + + case PsrMirq: /* Interrupt Request */ + interrupt(ureg); + break; + + case PsrMund: /* Undefined instruction */ + print("Undefined instruction\n"); + case PsrMsvc: /* Jump through 0, SWI or reserved trap */ + print("SWI/SVC trap\n"); + case PsrMabt: /* Prefetch abort */ + print("Prefetch Abort\n"); + case PsrMabt+1: /* Data abort */ + print("Data Abort\n"); + + + default: + dumpregs(ureg); + /* panic("exception %uX\n", ureg->type); */ + break; + } + + LOWBAT; /* Low bat off after interrupt */ + + splhi(); + +} |
