summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i960/rxgen960/startup/fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/i960/rxgen960/startup/fault.c')
-rw-r--r--c/src/lib/libbsp/i960/rxgen960/startup/fault.c322
1 files changed, 322 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/i960/rxgen960/startup/fault.c b/c/src/lib/libbsp/i960/rxgen960/startup/fault.c
new file mode 100644
index 0000000000..02373c3260
--- /dev/null
+++ b/c/src/lib/libbsp/i960/rxgen960/startup/fault.c
@@ -0,0 +1,322 @@
+/*-------------------------------------*/
+/* fault.c */
+/* Last change : 13. 7.95 */
+/*-------------------------------------*/
+#include "prcb.h"
+#include "i960.h"
+#include "flttbl.h"
+#include "fault.h"
+#include "asmstub.h"
+#include <stdio.h>
+#include <string.h>
+
+extern void romFaultStart(void);
+
+/*-------------------------------------*/
+ /* Table of user-registered fault handler entry.
+ */
+typedef struct {
+ UserFaultHandler hndl; /* Handler itself. */
+ int cnt; /* Handler is valid for cnt times. */
+} UserFaultEntry;
+ /* Table itself.
+ */
+static UserFaultEntry userFaultTable[] = {
+ {0, 0}, /* Parallel */
+ {0, 0}, /* Trace */
+ {0, 0}, /* Operation */
+ {0, 0}, /* Arithmetic */
+ {0, 0}, /* Reserved */
+ {0, 0}, /* Constraint */
+ {0, 0}, /* Reserved */
+ {0, 0}, /* Protection */
+ {0, 0}, /* Reserved */
+ {0, 0} /* Type */
+};
+ /* Number of Faults.
+ */
+#define FaultNmbr (sizeof(userFaultTable)/sizeof(UserFaultEntry))
+
+int faultRegister(int fault, UserFaultHandler hndl, int cnt)
+{
+ static unsigned int faultNewCheckSum(void);
+ int rsl = 0;
+
+ if (0 <= fault && fault <= FaultNmbr) {
+ /* Register handler.
+ */
+ userFaultTable[fault].hndl = hndl;
+ userFaultTable[fault].cnt = cnt;
+ /* Checksum has changed.
+ */
+ faultCheckSum = faultNewCheckSum();
+ rsl = 1;
+ }
+ return rsl;
+}
+int faultOk(int fault)
+{
+ static unsigned int faultNewCheckSum(void);
+ int rsl = 0;
+
+ if (0 <= fault && fault <= FaultNmbr) {
+ /* Fault handler recovered successfully.
+ * Can use it at least once more.
+ */
+ userFaultTable[fault].cnt ++;
+ /* Check sum has changed.
+ */
+#ifdef 0
+ faultCheckSum = faultNewCheckSum();
+#endif
+ faultCheckSum ++;
+ rsl = 1;
+ }
+ return rsl;
+}
+void faultBad(int invokedFromRom,
+ unsigned int inst, unsigned int * faultBuffer,
+ unsigned int type, unsigned int sbtp)
+{
+ static void faultInfo(int invokedFromRom,
+ unsigned int inst, unsigned int * faultBuffer,
+ unsigned int type, unsigned int sbtp);
+
+ /* Close the mem channel nicely.
+ */
+/* memChnlI960Fault();*/
+ /* Give some panic message.
+ */
+ faultInfo(invokedFromRom, inst, faultBuffer, type, sbtp);
+ /* At this point RAM is repaired. Do
+ * whatever you want.
+ */
+# ifdef 0
+ if (OsfIsUp) {
+ asm_exit(romFaultStart, & ram_prcb);
+ }
+ else {
+ asm_exit(romStart, & ram_prcb);
+ }
+# endif
+ asm_exit(romFaultStart, & ram_prcb);
+}
+void faultGood(unsigned int inst, unsigned int * faultBuffer,
+ unsigned int type, unsigned int sbtp)
+{
+ static unsigned int faultNewCheckSum(void);
+
+ if (userFaultTable[type].hndl != 0 && userFaultTable[type].cnt > 0) {
+ /* This is done to avoid the situation when
+ * handler causes a fault and, thus, infinite recursion.
+ */
+ userFaultTable[type].cnt --;
+ /* Check sum has changed.
+ */
+#ifdef 0
+ faultCheckSum = faultNewCheckSum();
+#endif
+ faultCheckSum --;
+ /* Invoke handler.
+ */
+ (* userFaultTable[type].hndl)(inst, faultBuffer, type, sbtp);
+ /* If this returns => fault is bad.
+ */
+ }
+ faultBad(0, inst, faultBuffer, type, sbtp);
+}
+static unsigned int faultNewCheckSum(void)
+{
+ unsigned int * f = faultStart;
+ unsigned int * l = faultEnd;
+ unsigned int sum;
+
+ for (sum = 0; f < l; f ++) {
+ sum += * f;
+ }
+ return sum;
+}
+static void faultInfo(int invokedFromRom,
+ unsigned int inst, unsigned int * faultBuffer,
+ unsigned int type, unsigned int sbtp)
+{
+ char * typeStr;
+ char * sbtpStr;
+ static char * faultParallelSbtpStr(unsigned int);
+ static char * faultTraceSbtpStr(unsigned int);
+ static char * faultOperationSbtpStr(unsigned int);
+ static char * faultArithmeticSbtpStr(unsigned int);
+ static char * faultReservedSbtpStr(unsigned int);
+ static char * faultConstraintSbtpStr(unsigned int);
+ static char * faultProtectionSbtpStr(unsigned int);
+ static char * faultTypeSbtpStr(unsigned int);
+ static char * faultUnknownSbtpStr(unsigned int);
+ static struct {
+ char * name;
+ char * (* sbtpStr)(unsigned int);
+ } faultInfo[] = {
+ {"Parallel", faultParallelSbtpStr},
+ {"Trace", faultTraceSbtpStr},
+ {"Operation", faultOperationSbtpStr},
+ {"Arithmetic", faultArithmeticSbtpStr},
+ {"Reserved", faultReservedSbtpStr},
+ {"Constraint", faultConstraintSbtpStr},
+ {"Reserved", faultReservedSbtpStr},
+ {"Protection", faultProtectionSbtpStr},
+ {"Reserved", faultReservedSbtpStr},
+ {"Type", faultTypeSbtpStr},
+ {"Unknown", faultUnknownSbtpStr}
+ };
+ unsigned int ix;
+
+/* console_set_channel(CHANNEL_B);*/
+ ix = type >= FaultNmbr ? FaultNmbr : type;
+ typeStr = faultInfo[ix].name;
+ sbtpStr = (* faultInfo[ix].sbtpStr)(sbtp);
+ printf("\nFault at 0x%08x: %s[%s]\n",
+ faultBuffer[IP_REGNUM], typeStr, sbtpStr);
+ printf("Bad instruction: 0x%08x\n", inst);
+ printf("AC=0x%08x PC=0x%08x\n",
+ faultBuffer[ACW_REGNUM],
+ faultBuffer[PCW_REGNUM]);
+ printf("g0=0x%08x g1=0x%08x g2=0x%08x g3=0x%08x\n",
+ faultBuffer[G0_REGNUM+0], faultBuffer[G0_REGNUM+1],
+ faultBuffer[G0_REGNUM+2], faultBuffer[G0_REGNUM+3]);
+ printf("g4=0x%08x g5=0x%08x g6=0x%08x g7=0x%08x\n",
+ faultBuffer[G0_REGNUM+4], faultBuffer[G0_REGNUM+5],
+ faultBuffer[G0_REGNUM+6], faultBuffer[G0_REGNUM+7]);
+ printf("g8=0x%08x g9=0x%08x gA=0x%08x gB=0x%08x\n",
+ faultBuffer[G0_REGNUM+8], faultBuffer[G0_REGNUM+9],
+ faultBuffer[G0_REGNUM+10], faultBuffer[G0_REGNUM+11]);
+ printf("gC=0x%08x gD=0x%08x gE=0x%08x gF=0x%08x\n",
+ faultBuffer[G0_REGNUM+12], faultBuffer[G0_REGNUM+13],
+ faultBuffer[G0_REGNUM+14], faultBuffer[G0_REGNUM+15]);
+ printf("r0=0x%08x r1=0x%08x r2=0x%08x r3=0x%08x\n",
+ faultBuffer[R0_REGNUM+0], faultBuffer[R0_REGNUM+1],
+ faultBuffer[R0_REGNUM+2], faultBuffer[R0_REGNUM+3]);
+ printf("r4=0x%08x r5=0x%08x r6=0x%08x r7=0x%08x\n",
+ faultBuffer[R0_REGNUM+4], faultBuffer[R0_REGNUM+5],
+ faultBuffer[R0_REGNUM+6], faultBuffer[R0_REGNUM+7]);
+ printf("r8=0x%08x r9=0x%08x rA=0x%08x rB=0x%08x\n",
+ faultBuffer[R0_REGNUM+8], faultBuffer[R0_REGNUM+9],
+ faultBuffer[R0_REGNUM+10], faultBuffer[R0_REGNUM+11]);
+ printf("rC=0x%08x rD=0x%08x rE=0x%08x rF=0x%08x\n",
+ faultBuffer[R0_REGNUM+12], faultBuffer[R0_REGNUM+13],
+ faultBuffer[R0_REGNUM+14], faultBuffer[R0_REGNUM+15]);
+ if (invokedFromRom) {
+ printf("RAM image damaged. No chance to recover\n");
+ }
+ else {
+ printf("RAM image not damaged. Still no recovery\n");
+ }
+}
+static char * faultParallelSbtpStr(unsigned int sbtp)
+{
+ static char buf[10];
+
+ sprintf(buf, "%d", sbtp);
+ return buf;
+}
+static char * faultTraceSbtpStr(unsigned int sbtp)
+{
+ static char buf[256];
+ int notEmpty;
+
+ buf[0] = '\0';
+ notEmpty = 0;
+ if (sbtp & 0x2) {
+ strcat(buf, "Instruction");
+ notEmpty = 1;
+ }
+ if (sbtp & 0x4) {
+ if (notEmpty) strcat(buf, ":");
+ strcat(buf, "Branch");
+ notEmpty = 1;
+ }
+ if (sbtp & 0x8) {
+ if (notEmpty) strcat(buf, ":");
+ strcat(buf, "Call");
+ notEmpty = 1;
+ }
+ if (sbtp & 0x10) {
+ if (notEmpty) strcat(buf, ":");
+ strcat(buf, "Return");
+ notEmpty = 1;
+ }
+ if (sbtp & 0x20) {
+ if (notEmpty) strcat(buf, ":");
+ strcat(buf, "Prereturn");
+ notEmpty = 1;
+ }
+ if (sbtp & 0x40) {
+ if (notEmpty) strcat(buf, ":");
+ strcat(buf, "Supervisor");
+ notEmpty = 1;
+ }
+ if (sbtp & 0x80) {
+ if (notEmpty) strcat(buf, ":");
+ strcat(buf, "Breakpoint");
+ notEmpty = 1;
+ }
+ if (! notEmpty) {
+ strcat(buf, "Unknown");
+ }
+ return buf;
+}
+static char * faultOperationSbtpStr(unsigned int sbtp)
+{
+ char * rsl;
+
+ if (sbtp == 0x1) rsl = "Invalid Opcode";
+ else if (sbtp == 0x2) rsl = "Unimplemented";
+ else if (sbtp == 0x3) rsl = "Unaligned";
+ else if (sbtp == 0x4) rsl = "Invalid Operand";
+ else rsl = "Unknown";
+ return rsl;
+}
+static char * faultArithmeticSbtpStr(unsigned int sbtp)
+{
+ char * rsl;
+
+ if (sbtp == 0x1) rsl = "Integer Overflow";
+ else if (sbtp == 0x2) rsl = "Arithmetic Zero-Divide";
+ else rsl = "Unknown";
+ return rsl;
+}
+static char * faultReservedSbtpStr(unsigned int sbtp)
+{
+ return "Unknown";
+}
+static char * faultConstraintSbtpStr(unsigned int sbtp)
+{
+ char * rsl;
+
+ if (sbtp == 0x1) rsl = "Constraint Range";
+ else if (sbtp == 0x2) rsl = "Priveleged";
+ else rsl = "Unknown";
+ return rsl;
+}
+static char * faultProtectionSbtpStr(unsigned int sbtp)
+{
+ char * rsl;
+
+ if (sbtp == 0x1) rsl = "Length";
+ else rsl = "Unknown";
+ return rsl;
+}
+static char * faultTypeSbtpStr(unsigned int sbtp)
+{
+ char * rsl;
+
+ if (sbtp == 0x1) rsl = "Type Mismatch";
+ else rsl = "Unknown";
+ return rsl;
+}
+static char * faultUnknownSbtpStr(unsigned int sbtp)
+{
+ return "Unknown";
+}
+/*-------------*/
+/* End of file */
+/*-------------*/
+