summaryrefslogtreecommitdiff
path: root/os/mpc/trap.c
diff options
context:
space:
mode:
authorKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
committerKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
commit78ee7d5717807e6ac779293d0d3c78341de6130a (patch)
treea43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/mpc/trap.c
parentbdaf46cf45bbb59261da245d548a179d95a42768 (diff)
Move existing boards into subdits split per arch
Diffstat (limited to 'os/mpc/trap.c')
-rw-r--r--os/mpc/trap.c554
1 files changed, 0 insertions, 554 deletions
diff --git a/os/mpc/trap.c b/os/mpc/trap.c
deleted file mode 100644
index 843d7ad4..00000000
--- a/os/mpc/trap.c
+++ /dev/null
@@ -1,554 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "ureg.h"
-#include "io.h"
-#include "../port/error.h"
-
-
-enum
-{
- Maxhandler= MaxVector /* max number of interrupt handlers */
-};
-
-typedef struct Handler Handler;
-struct Handler
-{
- void (*r)(Ureg*, void*);
- void *arg;
- char name[KNAMELEN];
- Handler *next;
- ulong nintr;
- ulong ticks;
- int maxtick;
-};
-
-struct
-{
- Handler *ivec[MaxVector];
- Handler h[Maxhandler];
- int free;
- Handler* freelist;
-} halloc;
-
-Instr BREAK = 0x7fe00008;
-int (*breakhandler)(Ureg*, Proc*);
-
-void kernfault(Ureg*, int);
-
-char *excname[] =
-{
- "reserved 0",
- "system reset",
- "machine check",
- "data access",
- "instruction access",
- "external interrupt",
- "alignment",
- "program exception",
- "floating-point unavailable",
- "decrementer",
- "i/o controller interface error",
- "reserved B",
- "system call",
- "trace trap",
- "floating point assist",
- "reserved F",
- "software emulation",
- "ITLB miss",
- "DTLB miss",
- "ITLB error",
- "DTLB error",
- "reserved 15",
- "reserved 16",
- "reserved 17",
- "reserved 18",
- "reserved 19",
- "reserved 1A",
- "reserved 1B",
- "data breakpoint",
- "instruction breakpoint",
- "peripheral breakpoint",
- "development port",
- /* the following are made up on a program exception */
- "floating point exception", /* 20: FPEXC */
- "illegal instruction", /* 21 */
- "privileged instruction", /* 22 */
- "trap", /* 23 */
- "illegal operation", /* 24 */
- "breakpoint", /* 25 */
-};
-
-char *fpcause[] =
-{
- "inexact operation",
- "division by zero",
- "underflow",
- "overflow",
- "invalid operation",
-};
-char *fpexcname(Ureg*, ulong, char*);
-#define FPEXPMASK 0xfff80300 /* Floating exception bits in fpscr */
-
-
-char *regname[]={
- "CAUSE", "SRR1",
- "PC", "GOK",
- "LR", "CR",
- "XER", "CTR",
- "R0", "R1",
- "R2", "R3",
- "R4", "R5",
- "R6", "R7",
- "R8", "R9",
- "R10", "R11",
- "R12", "R13",
- "R14", "R15",
- "R16", "R17",
- "R18", "R19",
- "R20", "R21",
- "R22", "R23",
- "R24", "R25",
- "R26", "R27",
- "R28", "R29",
- "R30", "R31",
-};
-
-void
-sethvec(int v, void (*r)(void))
-{
- ulong *vp, pa, o;
-
- vp = (ulong*)KADDR(v);
- vp[0] = 0x7c1043a6; /* MOVW R0, SPR(SPRG0) */
- vp[1] = 0x7c0802a6; /* MOVW LR, R0 */
- vp[2] = 0x7c1243a6; /* MOVW R0, SPR(SPRG2) */
- pa = PADDR(r);
- o = pa >> 25;
- if(o != 0 && o != 0x7F){
- /* a branch too far: running from ROM */
- vp[3] = (15<<26)|(pa>>16); /* MOVW $r&~0xFFFF, R0 */
- vp[4] = (24<<26)|(pa&0xFFFF); /* OR $r&0xFFFF, R0 */
- vp[5] = 0x7c0803a6; /* MOVW R0, LR */
- vp[6] = 0x4e800021; /* BL (LR) */
- }else
- vp[3] = (18<<26)|(pa&0x3FFFFFC)|3; /* bla */
- dcflush(vp, 8*sizeof(ulong));
-}
-
-void
-sethvec2(int v, void (*r)(void))
-{
- ulong *vp;
-
- vp = (ulong*)KADDR(v);
- vp[0] = (18<<26)|((ulong)r&~KSEGM)|2; /* ba */
- dcflush(vp, sizeof(*vp));
-}
-
-void
-trap(Ureg *ur)
-{
- int ecode, s;
- ulong w;
- char buf[ERRMAX];
-
- ecode = ur->cause >> 8;
- if(ecode < 0 || ecode >= 0x1F)
- ecode = 0x1F;
- switch(ecode){
- case CDEC:
- clockintr(ur);
- preemption(1);
- break;
-
- case CMCHECK:
- case CDSI:
- case CISI:
- case CIMISS:
- case CDMISS:
- case CITLBE:
- case CDTLBE:
- faultpower(ur);
- break;
-
- case CEMU:
- if(up == nil)
- goto Default;
- if((ulong)(ur+1) != ur->r1)
- panic("fp emu stack");
- spllo();
- if(waserror()){
- if(up->type == Interp)
- disfault(ur, up->env->errstr);
- panic("%s", up->env->errstr);
- }
- if(fpipower(ur) == 0){
- splhi();
- poperror();
- print("pc=#%lux op=#%8.8lux\n", ur->pc, *(ulong*)ur->pc);
- goto Default;
- }
- poperror();
- break;
-
- case CPROG:
- if(ur->status & (1<<19)) {
- ecode = 0x20;
- w = ur->pc;
- if(ur->status & (1<<16))
- w += 4;
- if(*(ulong*)w == 0x7fe00008){ /* tw 31,0,0 */
- if(breakhandler){
- s = (*breakhandler)(ur, up);
- if(s == BrkSched){
- if(up){
- up->preempted = 0;
- sched();
- splhi();
- }
- }else if(s == BrkNoSched){
- if(up){
- up->preempted = 1; /* stop it being preempted until next instruction */
- up->dbgreg = 0;
- }
- }
- break;
- }
- ecode = 0x1D; /* breakpoint */
- }
- }
- if(ur->status & (1<<18))
- ecode = 0x21;
- if(ur->status & (1<<17))
- ecode = 0x22;
- /* FALL THROUGH */
-
- Default:
- default:
- if(up && up->type == Interp) {
- spllo();
- snprint(buf, sizeof buf, "sys: trap: %s pc=0x%lux", excname[ecode], ur->pc);
- error(buf);
- break;
- }
- print("kernel %s pc=0x%lux\n", excname[ecode], ur->pc);
- dumpregs(ur);
- dumpstack();
- if(m->machno == 0)
- spllo();
- exit(1);
- }
-
- splhi();
-}
-
-void
-spurious(Ureg *ur, void *a)
-{
- USED(a);
- print("SPURIOUS interrupt pc=0x%lux cause=0x%lux\n",
- ur->pc, ur->cause);
- panic("bad interrupt");
-}
-
-#define LEV(n) (((n)<<1)|1)
-#define IRQ(n) (((n)<<1)|0)
-
-Lock veclock;
-
-void
-trapinit(void)
-{
- int i;
- IMM *io;
-
-
- io = m->iomem;
- io->simask = 0; /* mask all */
- io->siel = ~0; /* edge sensitive, wake on all */
- io->cicr = 0; /* disable CPM interrupts */
- io->cipr = ~0; /* clear all interrupts */
- io->cimr = 0; /* mask all events */
- io->cicr = (0xE1<<16)|(CPIClevel<<13)|(0x1F<<8);
- io->cicr |= 1 << 7; /* enable */
- io->tbscrk = KEEP_ALIVE_KEY;
- io->tbscr = 1; /* TBE */
- io->simask |= 1<<(31-LEV(CPIClevel)); /* CPM's level */
- io->tbk = KEEP_ALIVE_KEY;
- eieio();
- putdec(~0);
-
- /*
- * set all exceptions to trap
- */
- for(i = 0x0; i < 0x3000; i += 0x100)
- sethvec(i, trapvec);
-
- sethvec(CEI<<8, intrvec);
- //sethvec2(CIMISS<<8, itlbmiss);
- //sethvec2(CDMISS<<8, dtlbmiss);
-}
-
-void
-intrenable(int v, void (*r)(Ureg*, void*), void *arg, int, char *name)
-{
- Handler *h;
- IMM *io;
-
- v -= VectorPIC;
- if(v < 0 || v >= nelem(halloc.ivec))
- panic("intrenable(%d)", v+VectorPIC);
- ilock(&veclock);
- if((h = halloc.freelist) == nil){
- if(halloc.free >= Maxhandler){
- iunlock(&veclock);
- panic("out of interrupt handlers");
- }
- h = &halloc.h[halloc.free++];
- }else
- halloc.freelist = h->next;
- h->r = r;
- h->arg = arg;
- strncpy(h->name, name, KNAMELEN-1);
- h->name[KNAMELEN-1] = 0;
- h->next = halloc.ivec[v];
- halloc.ivec[v] = h;
-
- /*
- * enable corresponding interrupt in SIU/CPM
- */
-
- eieio();
- io = m->iomem;
- if(v >= VectorCPIC){
- v -= VectorCPIC;
- io->cimr |= 1<<(v&0x1F);
- }
- else if(v >= VectorIRQ)
- io->simask |= 1<<(31-IRQ(v&7));
- else
- io->simask |= 1<<(31-LEV(v));
- eieio();
- iunlock(&veclock);
-}
-
-static void
-irqdisable(int v)
-{
- IMM *io;
-
- io = m->iomem;
- if(v >= VectorCPIC){
- v -= VectorCPIC;
- io->cimr &= ~(1<<(v&0x1F));
- }
- else if(v >= VectorIRQ)
- io->simask &= ~(1<<(31-IRQ(v&7)));
- else
- io->simask &= ~(1<<(31-LEV(v)));
-}
-
-void
-intrdisable(int v, void (*r)(Ureg*, void*), void *arg, int, char *name)
-{
- Handler *h, **hp;
-
- v -= VectorPIC;
- if(v < 0 || v >= nelem(halloc.ivec))
- panic("intrenable(%d)", v+VectorPIC);
- ilock(&veclock);
- for(hp = &halloc.ivec[v]; (h = *hp) != nil; hp = &h->next)
- if(h->r == r && h->arg == arg && strcmp(h->name, name) == 0){
- *hp = h->next;
- h->next = halloc.freelist;
- halloc.freelist = h;
- break;
- }
- if(halloc.ivec[v] == nil)
- irqdisable(v);
- iunlock(&veclock);
-}
-
-/*
- * called directly by l.s:/intrvec. on a multiprocessor we'd need to lock veclock.
- */
-void
-intr(Ureg *ur)
-{
- int b, v;
- IMM *io;
- Handler *h;
- long t0;
- Proc *oup;
-
- ur->cause &= ~0xff;
- io = m->iomem;
- b = io->sivec>>2;
- v = b>>1;
- if(b & 1) {
- if(v == CPIClevel){
- io->civr = 1;
- eieio();
- v = VectorCPIC+(io->civr>>11);
- }
- }else{
- v += VectorIRQ;
- if(io->siel & (1<<(31-b))){
- io->sipend |= 1<<(31-b);
- eieio();
- }
- }
-
- ur->cause |= v;
- h = halloc.ivec[v];
- if(h == nil){
- iprint("unknown interrupt %d pc=0x%lux\n", v, ur->pc);
- irqdisable(v);
- return;
- }
-
- /*
- * call the interrupt handlers
- */
- oup = up;
- up = nil; /* no process at interrupt level */
- do {
- h->nintr++;
- t0 = getdec();
- (*h->r)(ur, h->arg);
- t0 -= getdec();
- h->ticks += t0;
- if(h->maxtick < t0)
- h->maxtick = t0;
- h = h->next;
- } while(h != nil);
- if(v >= VectorCPIC)
- io->cisr |= 1<<(v-VectorCPIC);
- eieio();
- up = oup;
- preemption(0);
-}
-
-int
-intrstats(char *buf, int bsize)
-{
- Handler *h;
- int i, n;
-
- n = 0;
- for(i=0; i<nelem(halloc.ivec) && n < bsize; i++)
- if((h = halloc.ivec[i]) != nil && h->nintr)
- n += snprint(buf+n, bsize-n, "%3d %lud %lud %ud\n", i, h->nintr, h->ticks, h->maxtick);
- return n;
-}
-
-char*
-fpexcname(Ureg *ur, ulong fpscr, char *buf)
-{
- int i;
- char *s;
- ulong fppc;
-
- fppc = ur->pc;
- s = 0;
- fpscr >>= 3; /* trap enable bits */
- fpscr &= (fpscr>>22); /* anded with exceptions */
- for(i=0; i<5; i++)
- if(fpscr & (1<<i))
- s = fpcause[i];
- if(s == 0)
- return "no floating point exception";
- sprint(buf, "%s fppc=0x%lux", s, fppc);
- return buf;
-}
-
-#define KERNPC(x) (KTZERO<(ulong)(x)&&(ulong)(x)<(ulong)etext)
-
-void
-kernfault(Ureg *ur, int code)
-{
- Label l;
-
- print("panic: kfault %s dar=0x%lux\n", excname[code], getdar());
- print("u=0x%lux status=0x%lux pc=0x%lux sp=0x%lux\n",
- up, ur->status, ur->pc, ur->sp);
- dumpregs(ur);
- l.sp = ur->sp;
- l.pc = ur->pc;
- dumpstack();
- setpri(PriBackground); /* Let the debugger in */
- for(;;)
- sched();
-}
-
-void
-dumpstack(void)
-{
- ulong l, v;
- int i;
-
- if(up == 0)
- return;
- i = 0;
- for(l=(ulong)&l; l<(ulong)(up->kstack+KSTACK); l+=4){
- v = *(ulong*)l;
- if(KTZERO < v && v < (ulong)etext){
- print("%lux=%lux, ", l, v);
- if(i++ == 4){
- print("\n");
- i = 0;
- }
- }
- }
-}
-
-void
-dumpregs(Ureg *ur)
-{
- int i;
- ulong *l;
- if(up) {
- print("registers for %s %ld\n", up->text, up->pid);
- if(ur->usp < (ulong)up->kstack ||
- ur->usp > (ulong)up->kstack+KSTACK)
- print("invalid stack ptr\n");
- }
- else
- print("registers for kernel\n");
-
- l = &ur->cause;
- for(i=0; i<sizeof regname/sizeof(char*); i+=2, l+=2)
- print("%s\t%.8lux\t%s\t%.8lux\n", regname[i], l[0], regname[i+1], l[1]);
-}
-
-static void
-linkproc(void)
-{
- spllo();
- (*up->kpfun)(up->arg);
- pexit("", 0);
-}
-
-void
-kprocchild(Proc *p, void (*func)(void*), void *arg)
-{
- p->sched.pc = (ulong)linkproc;
- p->sched.sp = (ulong)p->kstack+KSTACK;
-
- p->kpfun = func;
- p->arg = arg;
-}
-
-void
-setpanic(void)
-{
- consoleprint = 1;
-}
-
-void
-dumplongs(char*, ulong*, int)
-{
-}