|
|
1.1 root 1: /*
2: * code to take a crash dump
3: * on a disk attached to an SMD disk controller
4: * assumes UP at standard address
5: * (but so does the boot code)
6: * calls up.c (unfortunately) to figure out disk geometry
7: */
8:
9: #include "sys/param.h"
10: #include "sys/up.h"
11:
12: /*
13: * hardware parameters
14: */
15:
16: #define PHYS(x) ((long)(x)&~KSTART)
17: #define UBMAP ((long *)0xf30800) /* unibus map */
18: #define UBREG 0xfc0000 /* addr 0 in unibus space */
19: #define UP ((struct device *)(0776700+UBREG))
20:
21: #define MRV 0x80000000 /* map register valid bit */
22:
23: #define CHUNK 8 /* write this many sectors at once */
24: #define SECSIZE 512 /* size of a sector */
25:
26: /*
27: * hardware registers
28: */
29:
30: struct device
31: {
32: u_short upcs1; /* control and status register 1 */
33: short upwc; /* word count register */
34: u_short upba; /* UNIBUS address register */
35: u_short upda; /* desired address register */
36: u_short upcs2; /* control and status register 2 */
37: u_short upds; /* drive status */
38: u_short uper1; /* error register 1 */
39: u_short upas; /* attention summary */
40: u_short upla; /* look ahead */
41: u_short updb; /* data buffer */
42: u_short upmr; /* maintenance */
43: u_short updt; /* drive type */
44: u_short upsn; /* serial number */
45: u_short upof; /* offset register */
46: u_short updc; /* desired cylinder address register */
47: u_short uphr; /* holding register */
48: u_short upmr2; /* maintenance register 2 */
49: u_short uper2; /* error register 2 */
50: u_short upec1; /* burst error bit position */
51: u_short upec2; /* burst error bit pattern */
52: };
53:
54: /*
55: * upcs1
56: */
57:
58: #define UP_SC 0100000 /* special condition */
59: #define UP_TRE 0040000 /* transfer error */
60: #define UP_RDY 0000200 /* controller ready */
61: #define UP_GO 0000001
62:
63: #define UP_DCLR 010 /* drive clear */
64: #define UP_PRESET 020 /* read-in preset */
65: #define UP_WCOM 060 /* write */
66:
67: /*
68: * upcs2
69: */
70: #define UPCS2_CLR 0000040 /* controller clear */
71:
72: /*
73: * upof
74: */
75: #define UPOF_FMT22 0010000 /* 16 bit format */
76:
77: static upxtype;
78: extern struct upst upst[];
79:
80: static upxwrite(), upxinit();
81:
82: updump(unit, low, size)
83: int unit;
84: daddr_t low, size;
85: {
86: register long p;
87: register int i;
88: extern int physmem;
89:
90: if (size > physmem)
91: size = physmem;
92: size -= CHUNK-1;
93: if (upxinit(UP, unit))
94: return (1);
95: for (p = 0; p < size; p += CHUNK) {
96: for (i = 0; i < CHUNK; i++)
97: UBMAP[i] = MRV|(p+i);
98: if (upxwrite(UP, unit, low+p))
99: return (1);
100: }
101: return (0);
102: }
103:
104: /*
105: * clear the controller and reset it
106: * hereafter, upcs2 has the unit number we want (we assume)
107: */
108: static
109: upxinit(rp, unit)
110: register struct device *rp;
111: int unit;
112: {
113:
114: rp->upcs2 = UPCS2_CLR;
115: if ((upxtype = uputype(rp, unit)) < 0) {
116: printf("updump: can't init\n");
117: return (1);
118: }
119: rp->upcs1 = UP_PRESET|UP_GO;
120: rp->upof = UPOF_FMT22;
121: return (0);
122: }
123:
124: static
125: upxwrite(rp, unit, bno)
126: register struct device *rp;
127: int unit;
128: register long bno;
129: {
130: register struct upst *sp;
131: register int ts; /* track and sector */
132:
133: sp = &upst[upxtype];
134: ts = bno % sp->nsect;
135: bno /= sp->nsect;
136: ts |= (bno%sp->ntrak)<<8;
137: bno /= sp->ntrak;
138: rp->updc = bno;
139: rp->upda = ts;
140: rp->upwc = -(CHUNK*SECSIZE)/2;
141: rp->upba = 0;
142: rp->upcs1 = UP_WCOM|UP_GO;
143: while ((rp->upcs1 & UP_RDY) == 0)
144: ;
145: if (rp->upcs1 & (UP_TRE|UP_SC))
146: return (1);
147: return (0);
148: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.