/*-------------------------------------*/
|
/*-------------------------------------*/
|
/* flttbl.c */
|
/* flttbl.c */
|
/* Last change : 3.11.94 */
|
/* Last change : 3.11.94 */
|
/*-------------------------------------*/
|
/*-------------------------------------*/
|
/*
|
/*
|
* $Id: flttbl.c,v 1.2 2001-09-27 11:59:59 chris Exp $
|
* $Id: flttbl.c,v 1.2 2001-09-27 11:59:59 chris Exp $
|
*/
|
*/
|
|
|
#include "i960.h"
|
#include "i960.h"
|
#include "string.h"
|
#include "string.h"
|
#include "sctns.h"
|
#include "sctns.h"
|
#include "fault.h"
|
#include "fault.h"
|
#include "asmfault.h"
|
#include "asmfault.h"
|
#include "flttbl.h"
|
#include "flttbl.h"
|
/*-------------------------------------*/
|
/*-------------------------------------*/
|
/* Fault Table. It (as well as all the rest of the
|
/* Fault Table. It (as well as all the rest of the
|
* code of this file will always stay in ROM, so
|
* code of this file will always stay in ROM, so
|
* that it wouldn't be destroyed by silly user code.
|
* that it wouldn't be destroyed by silly user code.
|
* Thus, at least faults will be always caugth,
|
* Thus, at least faults will be always caugth,
|
*/
|
*/
|
FaultTblEntry faultTbl[] = {
|
FaultTblEntry faultTbl[] = {
|
{faultHndlEntry + LOCAL_FH, LOCAL_FW}, /* Parallel */
|
{faultHndlEntry + LOCAL_FH, LOCAL_FW}, /* Parallel */
|
{faultHndlEntry + LOCAL_FH, LOCAL_FW}, /* Trace */
|
{faultHndlEntry + LOCAL_FH, LOCAL_FW}, /* Trace */
|
{faultHndlEntry + LOCAL_FH, LOCAL_FW}, /* Operation */
|
{faultHndlEntry + LOCAL_FH, LOCAL_FW}, /* Operation */
|
{faultHndlEntry + LOCAL_FH, LOCAL_FW}, /* Arithmetic */
|
{faultHndlEntry + LOCAL_FH, LOCAL_FW}, /* Arithmetic */
|
{0, 0}, /* Reserved */
|
{0, 0}, /* Reserved */
|
{faultHndlEntry + LOCAL_FH, LOCAL_FW}, /* Constraint */
|
{faultHndlEntry + LOCAL_FH, LOCAL_FW}, /* Constraint */
|
{0, 0}, /* Reserved */
|
{0, 0}, /* Reserved */
|
{faultHndlEntry + LOCAL_FH, LOCAL_FW}, /* Protection */
|
{faultHndlEntry + LOCAL_FH, LOCAL_FW}, /* Protection */
|
{0, 0}, /* Reserved */
|
{0, 0}, /* Reserved */
|
{faultHndlEntry + LOCAL_FH, LOCAL_FW} /* Type */
|
{faultHndlEntry + LOCAL_FH, LOCAL_FW} /* Type */
|
};
|
};
|
|
|
void fltTblInit(void)
|
void fltTblInit(void)
|
{
|
{
|
static unsigned int fltTblCheckSum(void);
|
static unsigned int fltTblCheckSum(void);
|
|
|
faultCheckSum = fltTblCheckSum();
|
faultCheckSum = fltTblCheckSum();
|
}
|
}
|
static unsigned int fltTblCheckSum(void)
|
static unsigned int fltTblCheckSum(void)
|
{
|
{
|
unsigned int * f = faultStart;
|
unsigned int * f = faultStart;
|
unsigned int * l = faultEnd;
|
unsigned int * l = faultEnd;
|
unsigned int sum;
|
unsigned int sum;
|
|
|
for (sum = 0; f < l; f ++) {
|
for (sum = 0; f < l; f ++) {
|
sum += * f;
|
sum += * f;
|
}
|
}
|
return sum;
|
return sum;
|
}
|
}
|
void faultTblHandler(unsigned int * fp, unsigned int * faultBuffer)
|
void faultTblHandler(unsigned int * fp, unsigned int * faultBuffer)
|
{
|
{
|
unsigned int * ip;
|
unsigned int * ip;
|
struct typeWord {
|
struct typeWord {
|
unsigned int sbtp : 8;
|
unsigned int sbtp : 8;
|
unsigned int : 8;
|
unsigned int : 8;
|
unsigned int type : 8;
|
unsigned int type : 8;
|
unsigned int : 8;
|
unsigned int : 8;
|
} tw;
|
} tw;
|
unsigned int type;
|
unsigned int type;
|
unsigned int sbtp;
|
unsigned int sbtp;
|
unsigned int ac;
|
unsigned int ac;
|
unsigned int pc;
|
unsigned int pc;
|
unsigned int inst;
|
unsigned int inst;
|
|
|
char nib;
|
char nib;
|
unsigned int i;
|
unsigned int i;
|
|
|
/* Address of faulting instruction.
|
/* Address of faulting instruction.
|
*/
|
*/
|
ip = (unsigned int *) fp[-1];
|
ip = (unsigned int *) fp[-1];
|
/* Type/Subtype word.
|
/* Type/Subtype word.
|
*/
|
*/
|
|
|
/* put address of faulting instruction to console */
|
/* put address of faulting instruction to console */
|
kkprintf("Fault: %x\n", ip);
|
kkprintf("Fault: %x\n", ip);
|
|
|
tw = * (struct typeWord *) & fp[-2];
|
tw = * (struct typeWord *) & fp[-2];
|
/* Type and subtype.
|
/* Type and subtype.
|
*/
|
*/
|
type = tw.type;
|
type = tw.type;
|
sbtp = tw.sbtp;
|
sbtp = tw.sbtp;
|
/* Arithmetic controls.
|
/* Arithmetic controls.
|
*/
|
*/
|
ac = fp[-3];
|
ac = fp[-3];
|
/* Process controls.
|
/* Process controls.
|
*/
|
*/
|
pc = fp[-4];
|
pc = fp[-4];
|
/* Global and local registers are in faultBuffer
|
/* Global and local registers are in faultBuffer
|
* already. Save the rest. Change RIP to IP.
|
* already. Save the rest. Change RIP to IP.
|
*/
|
*/
|
faultBuffer[IP_REGNUM] = (unsigned int) ip;
|
faultBuffer[IP_REGNUM] = (unsigned int) ip;
|
faultBuffer[ACW_REGNUM] = ac;
|
faultBuffer[ACW_REGNUM] = ac;
|
faultBuffer[PCW_REGNUM] = pc;
|
faultBuffer[PCW_REGNUM] = pc;
|
/* Bad instruction itself. We do
|
/* Bad instruction itself. We do
|
* this here since it may be repaired (by copying from PROM).
|
* this here since it may be repaired (by copying from PROM).
|
*/
|
*/
|
inst = * ip;
|
inst = * ip;
|
/* Now, to handling.
|
/* Now, to handling.
|
*/
|
*/
|
if (faultCheckSum != fltTblCheckSum()) {
|
if (faultCheckSum != fltTblCheckSum()) {
|
/* RAM-based fault repair stuff
|
/* RAM-based fault repair stuff
|
* is broken. No chance to recover.
|
* is broken. No chance to recover.
|
* Repair RAM memory which is
|
* Repair RAM memory which is
|
* destroyed by silly user.
|
* destroyed by silly user.
|
*/
|
*/
|
copyCodeToRom();
|
copyCodeToRom();
|
/* And call RAM-based fault handler.
|
/* And call RAM-based fault handler.
|
*/
|
*/
|
faultBad(1, inst, faultBuffer, type, sbtp);
|
faultBad(1, inst, faultBuffer, type, sbtp);
|
}
|
}
|
else {
|
else {
|
/* There exist a chance to recover.
|
/* There exist a chance to recover.
|
*/
|
*/
|
faultGood(inst, faultBuffer, type, sbtp);
|
faultGood(inst, faultBuffer, type, sbtp);
|
}
|
}
|
}
|
}
|
/*-------------*/
|
/*-------------*/
|
/* End of file */
|
/* End of file */
|
/*-------------*/
|
/*-------------*/
|
|
|
|
|