|
|
1.1 root 1: /*
2: * code to take a crash dump
3: * on a disk attached to a KDA50 or RQDXn on a MicroVAX II
4: * assumes uda at the standard address on unibus 0
5: * (but so does the boot code)
6: */
7:
8: #include "sys/param.h"
9: #include "sys/mscp.h"
10:
11: /*
12: * hardware parameters
13: */
14:
15: #define PHYS(x) ((long)(x)&~KSTART)
16: #define UBMAP ((long *)0x20088000) /* Q-bus map */
17: #define UBREG (0x20000000-0760000) /* addr 0 in Q-bus space */
18: #define UDA ((struct device *)(0772150+UBREG))
19: #define ICR (*(short *)0x20001f40)
20: #define LMEAE 040 /* allow DMA */
21:
22: #define MRV 0x80000000 /* map register valid bit */
23:
24: #define CHUNK 8 /* write this many sectors at once */
25:
26: struct device {
27: short udip;
28: short udsa;
29: };
30:
31: /*
32: * bits in udsa
33: */
34:
35: #define ERR 0100000
36: #define STEP4 040000
37: #define STEP3 020000
38: #define STEP2 010000
39: #define STEP1 04000
40:
41: #define GO 01 /* step4 ok */
42:
43: /*
44: * bits in ring pointers
45: */
46:
47: #define DPOWN 0x80000000 /* port owns descriptor */
48:
49: struct udcmd {
50: short uc_len; /* length of message */
51: char uc_tc; /* type, credits */
52: char uc_cid; /* connection id */
53: struct mscmd uc_p;
54: };
55:
56: struct udrsp {
57: short ur_len; /* length of message */
58: char ur_tc; /* type, credits */
59: char ur_cid; /* connection id */
60: struct msend ur_p;
61: };
62:
63: static struct udx {
64: short ud__r0; /* reserved (ugh) */
65: char ud__r1;
66: char ud_bdp; /* path to purge */
67: short ud_cmdint; /* flag for command interrupt */
68: short ud_rspint; /* flag for response interrupt */
69: long ud_rsp; /* response pointer ring */
70: long ud_cmd; /* command pointer ring */
71: struct udcmd ud_cp; /* the only command packet */
72: struct udrsp ud_rp; /* the only response packet */
73: } udx;
74: static long udxbase;
75: static udxinit(), udxsend();
76:
77: /*
78: * struct udx (above) is mapped into pages 0 and 1 of unibus space
79: * the memory we want to transfer goes into page 2 and above
80: */
81:
82: uddump(unit, low, size)
83: int unit;
84: daddr_t low, size;
85: {
86: register struct udx *up;
87: register long p;
88: register int i;
89: extern int physmem;
90:
91: if (size > physmem)
92: size = physmem;
93: if (udxinit(UDA)) {
94: printf("init bad %o\n", UDA->udsa);
95: return (1);
96: }
97: up = (struct udx *)PHYS(&udx);
98: up->ud_cp.uc_p.m_unit = unit;
99: up->ud_cp.uc_p.m_opcd = OPONL;
100: if (udxsend(UDA))
101: return (1);
102: up->ud_cp.uc_p.m_opcd = OPWR;
103: up->ud_cp.uc_p.m_bcnt = NBPG*CHUNK;
104: *(long *)&up->ud_cp.uc_p.m_buff = (2*NBPG);
105: for (p = 0; p < size; p += CHUNK) {
106: for (i = 0; i < CHUNK; i++)
107: UBMAP[i+2] = MRV|(p+i);
108: up->ud_cp.uc_p.m_lbn = low + p;
109: if (udxsend(UDA))
110: return (1);
111: }
112: return (0);
113: }
114:
115: static
116: udxinit(rp)
117: register struct device *rp;
118: {
119: register struct udx *up;
120:
121: ICR |= LMEAE;
122: up = (struct udx *)PHYS(&udx);
123: UBMAP[0] = ((long)up/NBPG)|MRV;
124: UBMAP[1] = (((long)up/NBPG)+1)|MRV;
125: udxbase = (long)up & ~PGOFSET;
126: up->ud_cmd = 0;
127: up->ud_rsp = 0;
128: rp->udip = 0; /* reset */
129: while ((rp->udsa & (ERR|STEP1)) == 0)
130: ;
131: if (rp->udsa & ERR)
132: return (1);
133: rp->udsa = ERR; /* no vector, no IE, ring size 1, 1 */
134: while ((rp->udsa & (ERR|STEP2)) == 0)
135: ;
136: if (rp->udsa & ERR)
137: return (1);
138: rp->udsa = ((long)&up->ud_rsp - udxbase); /* low order part */
139: while ((rp->udsa & (ERR|STEP3)) == 0)
140: ;
141: if (rp->udsa & ERR)
142: return (1);
143: rp->udsa = 0; /* high order part */
144: while ((rp->udsa & (ERR|STEP4)) == 0)
145: ;
146: if (rp->udsa & ERR)
147: return (1);
148: rp->udsa = GO;
149: return (0);
150: }
151:
152: static
153: udxsend(rp)
154: struct device *rp;
155: {
156: register struct udx *up;
157: register int x;
158: static int ref;
159:
160: up = (struct udx *)PHYS(&udx);
161: up->ud_cp.uc_p.m_crf = ++ref;
162: up->ud_cp.uc_len = sizeof(struct mscmd);
163: up->ud_rp.ur_len = sizeof(struct msend);
164: up->ud_rsp = ((long)&up->ud_rp.ur_p - udxbase)|DPOWN;
165: up->ud_cmd = ((long)&up->ud_cp.uc_p - udxbase)|DPOWN;
166: x = rp->udip;
167: for (;;) {
168: while (up->ud_rsp & DPOWN)
169: ;
170: if (up->ud_rp.ur_p.m_crf == ref)
171: break;
172: up->ud_rsp |= DPOWN;
173: }
174: if ((up->ud_rp.ur_p.m_sts & STMSK) != STSUC) {
175: printf("ud err %o opc %o\n", up->ud_rp.ur_p.m_sts,
176: up->ud_cp.uc_p.m_opcd);
177: return (1);
178: }
179: return (0);
180: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.