|
|
1.1 root 1: /*
2: * code to take a crash dump
3: * on a disk attached to a KDB50 on some VAXBI machine
4: * assume buses are, in general, already initialized
5: */
6:
7: #include "sys/param.h"
8: #include "sys/mscp.h"
9: #include "sys/biic.h"
10:
11: /*
12: * pieces of unit number
13: */
14:
15: #define UNIT(d) ((d)&0xff)
16: #define NODE(d) (((d)>>8)&0xf)
17: #define BI(d) (((d)>>12)&0xf)
18:
19: /*
20: * hardware parameters
21: */
22:
23: #define PHYS(x) ((long)(x)&~KSTART)
24:
25: struct device {
26: short bdxx; /* unused */
27: short bdip;
28: short bdsar;
29: short bdsaw;
30: };
31:
32: /*
33: * bits in bdsa
34: */
35:
36: #define ERR 0100000
37: #define STEP4 040000
38: #define STEP3 020000
39: #define STEP2 010000
40: #define STEP1 04000
41:
42: #define GO 01 /* step4 ok */
43:
44: /*
45: * bits in ring pointers
46: */
47:
48: #define DPOWN 0x80000000 /* port owns descriptor */
49:
50: #define BDACSIZE 50 /* size of a command packet, says KDB50 */
51:
52: struct bdcmd {
53: short uc_len; /* length of message */
54: char uc_tc; /* type, credits */
55: char uc_cid; /* connection id */
56: struct mscmd uc_p;
57: char junk[BDACSIZE-sizeof(struct mscmd)];
58: };
59:
60: struct bdrsp {
61: short ur_len; /* length of message */
62: char ur_tc; /* type, credits */
63: char ur_cid; /* connection id */
64: struct msend ur_p;
65: };
66:
67: static struct bdx {
68: short ud__r0; /* reserved (ugh) */
69: char ud__r1;
70: char ud_bdp; /* path to purge */
71: short ud_cmdint; /* flag for command interrupt */
72: short ud_rspint; /* flag for response interrupt */
73: long ud_rsp; /* response pointer ring */
74: long ud_cmd; /* command pointer ring */
75: struct bdcmd ud_cp; /* the only command packet */
76: struct bdrsp ud_rp; /* the only response packet */
77: } bdx;
78:
79: #define CHUNK 20 /* number of blocks to write at once */
80:
81: static struct biic *bdxaddr();
82: static bdxinit(), bdxsend();
83:
84: bddump(unit, low, size)
85: int unit;
86: daddr_t low, size;
87: {
88: register struct bdx *up;
89: extern int physmem;
90: struct biic *addr;
91:
92: if (size > physmem)
93: size = physmem;
94: addr = bdxaddr(BI(unit), NODE(unit));
95: if (bdxinit(addr))
96: return (1);
97: unit = UNIT(unit);
98: up = (struct bdx *)PHYS(&bdx);
99: up->ud_cp.uc_p.m_unit = unit;
100: up->ud_cp.uc_p.m_opcd = OPONL;
101: if (bdxsend(addr))
102: return (1);
103: printf("onl ok\n");
104: up->ud_cp.uc_p.m_opcd = OPWR;
105: up->ud_cp.uc_p.m_bcnt = size * NBPG;
106: *(long *)&up->ud_cp.uc_p.m_buff = 0;
107: up->ud_cp.uc_p.m_lbn = low;
108: return (bdxsend(addr));
109: }
110:
111: static struct biic *
112: bdxaddr(bi, node)
113: {
114: return ((struct biic *)(0x20000000 + (bi * 0x2000000) + (node * 0x2000)));
115: }
116:
117: static
118: bdxinit(bp)
119: register struct biic *bp;
120: {
121: register struct bdx *up;
122: register struct device *rp;
123:
124: up = (struct bdx *)PHYS(&bdx);
125: up->ud_cmd = 0;
126: up->ud_rsp = 0;
127: bp->biintr = 0; /* no interrupts */
128: bp->bicsr |= BINRST;
129: rp = (struct device *)&bp->bigpr0;
130: while ((rp->bdsar & (ERR|STEP1)) == 0)
131: ;
132: if (rp->bdsar & ERR)
133: return (1);
134: rp->bdsaw = ERR; /* no vector, no IE, ring size 1, 1 */
135: while ((rp->bdsar & (ERR|STEP2)) == 0)
136: ;
137: if (rp->bdsar & ERR)
138: return (1);
139: rp->bdsaw = (short)&up->ud_rsp; /* low order part */
140: while ((rp->bdsar & (ERR|STEP3)) == 0)
141: ;
142: if (rp->bdsar & ERR)
143: return (1);
144: rp->bdsaw = ((long)&up->ud_rsp)>>16; /* high order part */
145: while ((rp->bdsar & (ERR|STEP4)) == 0)
146: ;
147: if (rp->bdsar & ERR)
148: return (1);
149: rp->bdsaw = GO;
150: return (0);
151: }
152:
153: static
154: bdxsend(bp)
155: struct biic *bp;
156: {
157: register struct bdx *up;
158: register int x;
159: struct device *rp;
160: static int ref;
161:
162: rp = (struct device *)&bp->bigpr0;
163: up = (struct bdx *)PHYS(&bdx);
164: up->ud_cp.uc_p.m_crf = ++ref;
165: up->ud_cp.uc_len = BDACSIZE;
166: up->ud_rp.ur_len = sizeof(struct msend);
167: up->ud_rsp = (long)&up->ud_rp.ur_p|DPOWN;
168: up->ud_cmd = (long)&up->ud_cp.uc_p|DPOWN;
169: x = rp->bdip;
170: for (;;) {
171: while (up->ud_rsp & DPOWN)
172: ;
173: if (up->ud_rp.ur_p.m_crf == ref)
174: break;
175: up->ud_rsp |= DPOWN;
176: }
177: if ((up->ud_rp.ur_p.m_sts & STMSK) != STSUC) {
178: printf("bd err %o opc %o\n", up->ud_rp.ur_p.m_sts,
179: up->ud_cp.uc_p.m_opcd);
180: return (1);
181: }
182: return (0);
183: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.