|
|
1.1 root 1: #include "u.h"
2: #include "../port/lib.h"
3: #include "mem.h"
4: #include "dat.h"
5: #include "fns.h"
6: #include "ureg.h"
7: #include "../port/error.h"
8:
9: #define FORMAT(ur) ((((ur)->vo)>>12)&0xF)
10: #define OFFSET(ur) (((ur)->vo)&0xFFF)
11:
12:
13: struct FFrame
14: {
15: ushort ireg0; /* internal register */
16: ushort ssw; /* special status word */
17: ushort ipsc; /* instr. pipe stage c */
18: ushort ipsb; /* instr. pipe stage b */
19: ulong addr; /* data cycle fault address */
20: ushort ireg1; /* internal register */
21: ushort ireg2; /* internal register */
22: ulong dob; /* data output buffer */
23: ushort ireg3[4]; /* more stuff */
24: ulong baddr; /* stage b address */
25: ushort ireg4[26]; /* more more stuff */
26: };
27:
28: /*
29: * SSW bits
30: */
31: #define RW 0x0040 /* read/write for data cycle */
32: #define FC 0x8000 /* fault on stage C of instruction pipe */
33: #define FB 0x4000 /* fault on stage B of instruction pipe */
34: #define RC 0x2000 /* rerun flag for stage C of instruction pipe */
35: #define RB 0x1000 /* rerun flag for stage B of instruction pipe */
36: #define DF 0x0100 /* fault/rerun flag for data cycle */
37: #define RM 0x0080 /* read-modify-write on data cycle */
38: #define READ 0x0040
39: #define WRITE 0x0000
40: #define SIZ 0x0030 /* size code for data cycle */
41: #define FC2 0x0004 /* address space for data cycle */
42: #define FC1 0x0002
43: #define FC0 0x0001
44:
45: void
46: fault68020(Ureg *ur, FFrame *f)
47: {
48: ulong addr, badvaddr;
49: int user, read, insyscall;
50: char buf[ERRLEN];
51:
52: if(u == 0){
53: dumpregs(ur);
54: panic("fault u==0 pc=%lux", ur->pc);
55: }
56: insyscall = u->p->insyscall;
57: u->p->insyscall = 1;
58: addr = 0; /* set */
59: if(f->ssw & DF)
60: addr = f->addr;
61: else if(FORMAT(ur) == 0xA){
62: if(f->ssw & FC)
63: addr = ur->pc+2;
64: else if(f->ssw & FB)
65: addr = ur->pc+4;
66: else
67: panic("prefetch pagefault");
68: }else if(FORMAT(ur) == 0xB){
69: if(f->ssw & FC)
70: addr = f->baddr-2;
71: else if(f->ssw & FB)
72: addr = f->baddr;
73: else
74: panic("prefetch pagefault");
75: }else
76: panic("prefetch format");
77:
78: addr &= VAMASK;
79: badvaddr = addr;
80: addr &= ~(BY2PG-1);
81: user = !(ur->sr&SUPER);
82: if(user)
83: u->dbgreg = ur;
84:
85: if(f->ssw & DF)
86: read = (f->ssw&READ) && !(f->ssw&RM);
87: else
88: read = f->ssw&(FB|FC);
89:
90: /* print("fault pc=%lux addr=%lux read %d\n", ur->pc, badvaddr, read); /**/
91:
92: if(fault(addr, read) < 0){
93: if(user){
94: sprint(buf, "sys: trap: fault %s addr=0x%lux",
95: read? "read" : "write", badvaddr);
96: postnote(u->p, 1, buf, NDebug);
97: notify(ur);
98: return;
99: }
100: dumpregs(ur);
101: panic("fault: 0x%lux", badvaddr);
102: }
103: u->p->insyscall = insyscall;
104: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.