|
|
1.1 root 1: /*
2: * code to take a crash dump
3: * on a disk attached to a UDA50 on a 780
4: * your choice of a couple of unibus adapters,
5: * a couple of common uda addresses
6: * (wretched nonstandard alice)
7: */
8:
9: #include "sys/param.h"
10: #include "sys/mscp.h"
11:
12: /*
13: * hardware parameters
14: */
15:
16: #define PHYS(x) ((long)(x)&~KSTART)
17:
18: /*
19: * `unit' number is really unit, controller, unibus adapter
20: * one hopes that controller and adapter will usually be 0
21: */
22: #define UUNIT(d) ((d)&0xff)
23: #define UCTL(d) (((d)>>8)&0xf)
24: #define UUBA(d) (((d)>>12)&0xf)
25:
26: #define MAXUBA 2
27: static struct {
28: long reg; /* addr 0 in unibus space */
29: long adp; /* adapter registers */
30: } udxuba[MAXUBA] = {
31: {0x20100000, 0x20006000}, /* first unibus */
32: {0x20140000, 0x20008000}, /* second unibus */
33: };
34: #define UBMAP (0x800/4) /* offset to map regs */
35: #define CNFGR 0
36: #define UACR 1
37: #define ADINIT 01 /* UACR - adapter init */
38: #define UBIC 0x10000 /* CNFGR - init complete */
39:
40: #define MAXUDA 2
41: static long udxaddr[MAXUDA] = {
42: 0772150, 0772160
43: };
44:
45: #define MRV 0x80000000 /* map register valid bit */
46:
47: #define CHUNK 8 /* write this many sectors at once */
48:
49: struct device {
50: short udip;
51: short udsa;
52: };
53:
54: /*
55: * bits in udsa
56: */
57:
58: #define ERR 0100000
59: #define STEP4 040000
60: #define STEP3 020000
61: #define STEP2 010000
62: #define STEP1 04000
63:
64: #define GO 01 /* step4 ok */
65:
66: /*
67: * bits in ring pointers
68: */
69:
70: #define DPOWN 0x80000000 /* port owns descriptor */
71:
72: struct udcmd {
73: short uc_len; /* length of message */
74: char uc_tc; /* type, credits */
75: char uc_cid; /* connection id */
76: struct mscmd uc_p;
77: };
78:
79: struct udrsp {
80: short ur_len; /* length of message */
81: char ur_tc; /* type, credits */
82: char ur_cid; /* connection id */
83: struct msend ur_p;
84: };
85:
86: static struct udx {
87: short ud__r0; /* reserved (ugh) */
88: char ud__r1;
89: char ud_bdp; /* path to purge */
90: short ud_cmdint; /* flag for command interrupt */
91: short ud_rspint; /* flag for response interrupt */
92: long ud_rsp; /* response pointer ring */
93: long ud_cmd; /* command pointer ring */
94: struct udcmd ud_cp; /* the only command packet */
95: struct udrsp ud_rp; /* the only response packet */
96: } udx;
97: static long udxbase;
98: static udxinit(), udxsend();
99:
100: /*
101: * struct udx (above) is mapped into pages 0 and 1 of unibus space
102: * the memory we want to transfer goes into page 2 and above
103: */
104:
105: uddump(unit, low, size)
106: int unit;
107: daddr_t low, size;
108: {
109: register struct udx *up;
110: register long p;
111: register int i;
112: register long *ubmap;
113: register struct device *udaddr;
114: extern int physmem;
115:
116: if (size > physmem)
117: size = physmem;
118: if ((i = UUBA(unit)) >= MAXUBA)
119: return (1);
120: ubmap = (long *)udxuba[i].adp;
121: ubmap[UACR] = ADINIT;
122: while ((ubmap[CNFGR] & UBIC) == 0)
123: ;
124: ubmap += UBMAP;
125: if (UCTL(unit) >= MAXUDA)
126: return (1);
127: udaddr = (struct device *)(udxuba[i].reg + udxaddr[UCTL(unit)]);
128: unit = UUNIT(unit);
129: if (udxinit(udaddr, ubmap))
130: return (1);
131: up = (struct udx *)PHYS(&udx);
132: up->ud_cp.uc_p.m_unit = unit;
133: up->ud_cp.uc_p.m_opcd = OPONL;
134: if (udxsend(udaddr))
135: return (1);
136: up->ud_cp.uc_p.m_opcd = OPWR;
137: up->ud_cp.uc_p.m_bcnt = NBPG*CHUNK;
138: *(long *)&up->ud_cp.uc_p.m_buff = (2*NBPG);
139: for (p = 0; p < size; p += CHUNK) {
140: for (i = 0; i < CHUNK; i++)
141: ubmap[i+2] = MRV|(p+i);
142: up->ud_cp.uc_p.m_lbn = low + p;
143: if (udxsend(udaddr))
144: return (1);
145: }
146: return (0);
147: }
148:
149: static
150: udxinit(rp, map)
151: register struct device *rp;
152: register long *map;
153: {
154: register struct udx *up;
155:
156: up = (struct udx *)PHYS(&udx);
157: map[0] = ((long)up/NBPG)|MRV;
158: map[1] = (((long)up/NBPG)+1)|MRV;
159: udxbase = (long)up & ~PGOFSET;
160: up->ud_cmd = 0;
161: up->ud_rsp = 0;
162: rp->udip = 0; /* reset */
163: while ((rp->udsa & (ERR|STEP1)) == 0)
164: ;
165: if (rp->udsa & ERR)
166: goto bad;
167: rp->udsa = ERR; /* no vector, no IE, ring size 1, 1 */
168: while ((rp->udsa & (ERR|STEP2)) == 0)
169: ;
170: if (rp->udsa & ERR)
171: goto bad;
172: rp->udsa = ((long)&up->ud_rsp - udxbase); /* low order part */
173: while ((rp->udsa & (ERR|STEP3)) == 0)
174: ;
175: if (rp->udsa & ERR)
176: goto bad;
177: rp->udsa = 0; /* high order part */
178: while ((rp->udsa & (ERR|STEP4)) == 0)
179: ;
180: if (rp->udsa & ERR)
181: goto bad;
182: rp->udsa = GO;
183: return (0);
184: bad:
185: printf("sa %o\n", rp->udsa & 0xffff);
186: return (1);
187: }
188:
189: static
190: udxsend(rp)
191: struct device *rp;
192: {
193: register struct udx *up;
194: register int x;
195: static int ref;
196:
197: up = (struct udx *)PHYS(&udx);
198: up->ud_cp.uc_p.m_crf = ++ref;
199: up->ud_cp.uc_len = sizeof(struct mscmd);
200: up->ud_rp.ur_len = sizeof(struct msend);
201: up->ud_rsp = ((long)&up->ud_rp.ur_p - udxbase)|DPOWN;
202: up->ud_cmd = ((long)&up->ud_cp.uc_p - udxbase)|DPOWN;
203: x = rp->udip;
204: for (;;) {
205: while (up->ud_rsp & DPOWN)
206: ;
207: if (up->ud_rp.ur_p.m_crf == ref)
208: break;
209: up->ud_rsp |= DPOWN;
210: }
211: if ((up->ud_rp.ur_p.m_sts & STMSK) != STSUC) {
212: printf("ud err %o opc %o\n", up->ud_rp.ur_p.m_sts,
213: up->ud_cp.uc_p.m_opcd);
214: return (1);
215: }
216: return (0);
217: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.