summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i960/rxgen960/startup/flttbl.c
blob: dc555846190122c8264007ab518ed53ecfcce7a0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*-------------------------------------*/
/* flttbl.c                            */
/* Last change :  3.11.94              */
/*-------------------------------------*/  
#include "i960.h"
#include "string.h"
#include "sctns.h"
#include "fault.h"
#include "asmfault.h"
#include "flttbl.h"
/*-------------------------------------*/
  /* Fault Table. It (as well as all the rest of the
   * code of this file will always stay in ROM, so
   * that it wouldn't be destroyed by silly user code.
   * Thus, at least faults will be always caugth,
   */
FaultTblEntry faultTbl[] = {
  {faultHndlEntry + LOCAL_FH, LOCAL_FW},            /* Parallel */
  {faultHndlEntry + LOCAL_FH, LOCAL_FW},            /* Trace */
  {faultHndlEntry + LOCAL_FH, LOCAL_FW},            /* Operation */ 
  {faultHndlEntry + LOCAL_FH, LOCAL_FW},            /* Arithmetic */ 
  {0, 0},                       		          /* Reserved */ 
  {faultHndlEntry + LOCAL_FH, LOCAL_FW},            /* Constraint */ 
  {0, 0},                                           /* Reserved */
  {faultHndlEntry + LOCAL_FH, LOCAL_FW},            /* Protection */
  {0, 0},                                           /* Reserved */
  {faultHndlEntry + LOCAL_FH, LOCAL_FW}            /* Type */
};

void fltTblInit(void)
{
  static unsigned int fltTblCheckSum(void);

  faultCheckSum = fltTblCheckSum();
}
static unsigned int fltTblCheckSum(void)
{
  unsigned int * f = faultStart;
  unsigned int * l = faultEnd; 
  unsigned int sum;
  
  for (sum = 0; f < l; f ++)  {
    sum += * f;
  }
  return sum;
}
void faultTblHandler(unsigned int * fp, unsigned int * faultBuffer)
{
  unsigned int * ip;
  struct typeWord {
    unsigned int sbtp : 8;
    unsigned int : 8;
    unsigned int type : 8;
    unsigned int : 8;
  } tw;
  unsigned int type;
  unsigned int sbtp;
  unsigned int ac;
  unsigned int pc;
  unsigned int inst;

  char nib;
  unsigned int i;

    /* Address of faulting instruction.
     */
  ip = (unsigned int *) fp[-1]; 
    /* Type/Subtype word.
     */

  /* put address of faulting instruction to console */
  kkprintf("Fault: %x\n", ip);
 
  tw = * (struct typeWord *) & fp[-2];  
    /* Type and subtype.
     */
  type = tw.type;
  sbtp = tw.sbtp; 
    /* Arithmetic controls.
     */
  ac = fp[-3]; 
    /* Process controls.
     */
  pc = fp[-4];    
    /* Global and local registers are in faultBuffer
     * already. Save the rest. Change RIP to IP.
     */
  faultBuffer[IP_REGNUM] = (unsigned int) ip;
  faultBuffer[ACW_REGNUM] = ac;
  faultBuffer[PCW_REGNUM] = pc;  
    /* Bad instruction itself. We do
     * this here since it may be repaired (by copying from PROM).
     */
  inst = * ip; 
    /* Now, to handling.
     */
  if (faultCheckSum != fltTblCheckSum())  {
      /* RAM-based fault repair stuff
       * is broken. No chance to recover.
       * Repair RAM memory which is
       * destroyed by silly user.
       */
    copyCodeToRom(); 
      /* And call RAM-based fault handler.
       */
    faultBad(1, inst, faultBuffer, type, sbtp);
  } 
  else  {
      /* There exist a chance to recover.
       */
    faultGood(inst, faultBuffer, type, sbtp);  
  }
}
/*-------------*/
/* End of file */
/*-------------*/