/* ** CSPPC233Fix_wos.c ** ** An Instruction Access Exception handler, which tries to recover from ** a hardware bug on CSPPC/233 cards by fixing the trashed LR register. ** ** Written by Frank Wille . ** This code is PUBLIC DOMAIN. ** */ #include #include #include #include #include #include static int sigExcept; /* exception notification signal */ static struct EXCContext EC; /* copy of exception context */ static struct TaskPPC *thisTask; /* this task */ static struct TaskPPC *excTask; /* excepting task */ ULONG IAccessException(struct EXCContext *); /* This line is vbcc-specific, the rest should be portable (to Storm-C, for example). Although I doubt that gcc-WarpOS would work, because the exception handler should be PowerOpen-ABI). */ ULONG r2(void) = "\tmr\tr3,r2"; /* gets TOC-pointer */ main() { static ULONG cnt=0; struct TagItem ti[8]; void *xhdl; ULONG sigmsk; if ((sigExcept = AllocSignalPPC(-1)) >= 0) { thisTask = FindTaskPPC(NULL); /* install a global handler for Instruction Access Exceptions */ ti[0].ti_Tag = EXCATTR_CODE; ti[0].ti_Data = (ULONG)IAccessException; ti[1].ti_Tag = EXCATTR_DATA; ti[1].ti_Data = r2(); ti[2].ti_Tag = EXCATTR_EXCID; ti[2].ti_Data = EXCF_IACCESS; ti[3].ti_Tag = EXCATTR_FLAGS; ti[3].ti_Data = EXCF_GLOBAL | EXCF_LARGECONTEXT; ti[4].ti_Tag = EXCATTR_PRI; ti[4].ti_Data = 127; ti[5].ti_Tag = EXCATTR_NAME; ti[5].ti_Data = (ULONG)"Trashed-LR bug fix for CSPPC/233"; ti[6].ti_Tag = TAG_DONE; if (xhdl = SetExcHandler(ti)) { printf("Instruction Access exception handler installed.\n" "Press CTRL-C to quit.\n"); do { /* wait for an exception or the signal to quit (CTRL-C) */ sigmsk = WaitPPC((1L<tp_Task.tc_Node.ln_Name); } } while (!(sigmsk & (1L<ec_UPC.ec_SRR0 == ec->ec_LR && (ec->ec_LR & 0xf0000000) != 0) { CopyMemPPC(ec,&EC,sizeof(struct EXCContext)); /* save exception ctxt. */ ec->ec_UPC.ec_SRR0 &= 0x0fffffff; /* fix PC and LR */ ec->ec_LR &= 0x0fffffff; excTask = FindTaskPPC(NULL); SignalPPC(thisTask,1L<