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