|
|
1.1 root 1: #include "xylog.h"
2: #include "pte.h"
3:
4:
5: /* This table contains drive type for each
6: drive attached to Xylogic controller.
7: e.g Drive 0 is EAGLE type. This info. is
8: configuration dependent.
9: */
10:
11: #define DUMMY EAGLE
12: struct DTYPE dtype[MAXXYDRIVES] = {
13: EAGLE,DUMMY,DUMMY,DUMMY
14: };
15:
16: struct TYPEPAR typepar[2] = {
17: 20,46,842,"Eagle",
18: 0,0,0,""
19: };
20:
21: extern long unused, IOinit;
22: struct Xreg *Xyreg;
23: struct IOPB xiopb;
24: long Xdone=0;
25: long ForMat = 1;
26:
27: xylog()
28: { register long r12;
29: long oldvec;
30:
31: writes("\n ** Xylogics test **\n");
32: m_xy(); /* Map register I/O address */
33:
34: /* Set handler for Xylogics interrupt */
35: asm("movab xyhdlr,r12");
36: set_handler(XYVEC,&oldvec,r12);
37:
38: if (xy_reset()) { /* Reset controller */
39: writes("\nXylogic controller is at ");
40: writeh(XBASE+XOFFS);
41: }
42: else {
43: writes("\nXylogic not found...\n");
44: return(0); }
45: xy_ex(); /* Exercise controller */
46: return(1);
47: }
48:
49: xy_ex()
50: { register long ix, stat;
51: register struct TYPEPAR *tp;
52: char Buff[NBPG];
53:
54: for(ix=0;ix<MAXXYDRIVES;ix++) setdr(dtype[ix].type);
55: if (ForMat) Form(0);
56: tp = &typepar[0];
57: for (ix=0;ix<NBPG;ix++) Buff[ix] = 0xab;
58: /* Write last sector */
59: stat = xyop(0,XYWRITE,1,tp->nocyls-1,tp->noheads-1,tp->nosecs-1,Buff);
60: if (stat) { writes("\nWrite error ... \n");
61: return; }
62: for (ix=0;ix<NBPG;ix++) Buff[ix] = 0;
63: /* Read last sector */
64: stat = xyop(0,XYREAD,1,tp->nocyls-1,tp->noheads-1,tp->nosecs-1,Buff);
65: if (stat) { writes("\nRead error ... \n");
66: return; }
67: for (ix=0;ix<512;ix++) {
68: if (Buff[ix] != 0xab) {
69: writes("\ncompare error, expect "); writeh(0xab);
70: writes(" ,actual "); writeh(Buff[ix]&0xff);
71: writes(" ,address "); writeh(&Buff[ix]);
72: }
73: }
74: }
75:
76: Form(devno)
77: long devno;
78: { register long cyl, trak;
79: struct TYPEPAR *tp;
80:
81: tp = &typepar[devno];
82: writes("\nFormating drive "); writeh(devno); writes(" ...\n");
83: for (cyl=0; cyl < tp->nocyls-1; cyl++) {
84: if (format(devno,cyl)) {
85: writes("\nformat error ...\n");
86: return;
87: }
88: writed(cyl);
89: }
90: writes("\nFormat completed ...\n");
91: }
92:
93:
94: setdr(type)
95: long type;
96: { struct IOPB *iop;
97:
98: iop = &xiopb;
99: iop->comm = SETDRIVE | IEN | AUD;
100: iop->imode = IEI;
101: iop->stat1 = iop->stat2 = iop->throt = (char)0;
102: iop->devno = (type&0x3) << 7;
103: iop->headr = typepar[type].noheads -1;
104: iop->secadr = typepar[type].nosecs -1;
105: iop->calow = (char)((typepar[type].nocyls -1) & 0xff);
106: iop->cahig = (char)(((typepar[type].nocyls-1) >> 8) & 0x3);
107: iop->hoffs = (char)0;
108: if (xygo(iop))
109: writes("\nset drive error..\n");
110: else writes("\nset drive completed.\n");
111: }
112:
113: format(devno,cyl)
114: long devno, cyl;
115: { struct IOPB *iop;
116: register long nosecs;
117:
118: iop = &xiopb;
119: iop->comm = XFORMAT | IEN | AUD;
120: iop->imode = IEI;
121: iop->stat1 = iop->stat2 = iop->throt = (char)0;
122: iop->devno = devno | ((dtype[devno].type & 3) << 7);
123: iop->headr = 0;
124: iop->secadr = 0;
125: iop->calow = (char)(cyl & 0xff);
126: iop->cahig = (char)((cyl & 0x300) >> 8);
127: nosecs = typepar[devno].nosecs * typepar[devno].noheads;
128: iop->sclow = (char)(nosecs & 0xff);
129: iop->schig = (char)((nosecs >> 8) & 0xff);
130: return(xygo(iop));
131: }
132:
133: xyop(devno,op,len,cyl,head,sec,buf)
134: long devno, cyl, len, head, sec;
135: char op, *buf;
136: { struct IOPB *iop;
137: register long nosecs;
138:
139: iop = &xiopb;
140: iop->comm = op | IEN | AUD;
141: iop->imode = IEI;
142: iop->stat1 = iop->stat2 = iop->throt = (char)0;
143: iop->devno = devno | ((dtype[devno].type & 3) << 7);
144: iop->headr = head;
145: iop->secadr = sec;
146: iop->calow = (char)(cyl & 0xff);
147: iop->cahig = (char)((cyl & 0x300) >> 8);
148: iop->sclow = (char)(len & 0xff);
149: iop->schig = (char)((len >> 8) & 0xff);
150: iop->dalow = (char)((long)buf & 0xff);
151: iop->dahig = (char)(((long)buf >> 8) & 0xff);
152: iop->drlow = (char)(((long)buf >> 16)&0xff);
153: iop->drhig = 0;
154: return(xygo(iop));
155: }
156:
157: /* Map register I/O address of Xylogics controller
158: */
159: m_xy()
160: { register long r12;
161: long phys_pg, pte, old_pte, which1;
162:
163: /* physical page of Xylogics' registers in IO space */
164: phys_pg = ((XBASE+IOBASE) >> PGSHIFT) & 0x3fffff;
165: /* Virtual address of Xylogics IO registers */
166: Xyreg = (struct Xreg *)((unused << PGSHIFT) + XOFFS);
167: pte = phys_pg | PG_KW | PG_V | PG_NC;
168: fix_pte(SBR,unused,&old_pte,pte);
169: unused++;
170: pte = (phys_pg+1) | PG_KW | PG_V | PG_NC;
171: fix_pte(SBR,unused,&old_pte,pte);
172: asm("mfpr $SLR,r12");
173: r12 += 2;
174: asm("mtpr r12,$SLR");
175: unused++;
176: }
177:
178:
179: xy_reset()
180: { char c, movib();
181: register long cnt;
182:
183: movib(&Xyreg->crr); /* Reset controller by reading this register */
184: cnt = 0xff0;
185: while (!((movib(&Xyreg->csr)) & DRDY)) {
186: DELAY(0xff00);
187: if (--cnt <= 0) { writes("\nReset time out..\n");
188: return(0); }
189: }
190: return(1);
191: }
192:
193:
194: /* All ready to go,issue command to Xylogic
195: */
196: xygo(iopb)
197: struct IOPB *iopb;
198: { register long r12;
199:
200: r12 = (long)iopb;
201: if (!xyrdy()) return(1);
202: movob(&Xyreg->adlow,(char)(r12 & 0xff));
203: movob(&Xyreg->adhig,(char)((r12&0xff00)>>8));
204: movob(&Xyreg->relow,(char)((r12&0xff0000)>>16));
205: movob(&Xyreg->rehig,(char)0);
206: movob(&Xyreg->csr,(char)(GBSY|ADRM));
207: return(waitxy()); /* Return 0 if cmd O.K else error status */
208: }
209:
210: xyrdy()
211: { register cnt;
212: char movib();
213: cnt = 0xfff0;
214: while ((movib(&Xyreg->csr))&0x80) {
215: if (--cnt == 0) {
216: writes("\nXY not ready time out !\n");
217: return(0);
218: }
219: }
220: return(1);
221: }
222:
223: waitxy()
224: { register long cnt;
225: Xdone = 0;
226: cnt = 0xff00;
227: while (!Xdone) {
228: DELAY(0xff00);
229: if (--cnt == 0) {
230: writes("\ntime out on Xylogic..\n");
231: return(1);
232: }
233: }
234: if (Xdone==2) return(Xdone);
235: else return(0);
236: }
237:
238:
239: movob(addr,byte)
240: char *addr, byte;
241: { register long r12;
242:
243: r12 = (long)addr;
244: asm("movob 11(fp),(r12)");
245: DELAY(80);
246: }
247:
248: char movib(addr)
249: char *addr;
250: { register long r12, r11;
251:
252: r12 = (long)addr;
253: asm("movob (r12),r11");
254: DELAY(80);
255: return((char)r11);
256: }
257:
258: mk32(adr,rel)
259: long adr, rel;
260: { register long a32;
261:
262: a32 = (adr&0xffff) | ((rel&0xffff)<<16);
263: return(a32&0xffffff);
264: }
265:
266: /* Xylogics interrupt handler
267: */
268: xyintr()
269: { char err, movib();
270: register long r12;
271:
272: err = movib(&Xyreg->csr); /* Get error code from CSR */
273: r12 = (long)&xiopb; /* Uncache 1st longword in IOPB */
274: uncache(r12); uncache(r12+4);
275: if ((err & (ERR|DERR)) || (((long)xiopb.stat1) & XS_ERR)) {
276: movob(&Xyreg->csr,IPND|ERR); /* Clear interrupt,error */
277: writes("\nXy hard error, csr "); writeh(((long)err)&0xff);
278: writes("\niopb_stat2 "); writeh(((long)xiopb.stat2)&0xff);
279: return(0);
280: }
281: movob(&Xyreg->csr,IPND); /* Clear interrupt */
282: return(1);
283: }
284:
285:
286: Xyhdr()
287: {
288: asm(".align 2");
289: asm("xyhdlr:");
290: asm("svpctx");
291: if (xyintr()) Xdone = 1;
292: else Xdone = 2; /* Command error */
293: asm("ldpctx");
294: asm("rei");
295: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.