|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)uba.c 7.1 (Berkeley) 6/5/86
7: */
8:
9: #include "../machine/pte.h"
10:
11: #include "param.h"
12: #include "systm.h"
13: #include "map.h"
14: #include "buf.h"
15: #include "vm.h"
16: #include "dir.h"
17: #include "user.h"
18: #include "proc.h"
19: #include "conf.h"
20: #include "dk.h"
21: #include "kernel.h"
22:
23: #include "../vax/cpu.h"
24: #include "../vax/mtpr.h"
25: #include "../vax/nexus.h"
26: #include "ubareg.h"
27: #include "ubavar.h"
28:
29: #if defined(VAX780) || defined(VAX8600)
30: char ubasr_bits[] = UBASR_BITS;
31: #endif
32:
33: #define spluba spl7 /* IPL 17 */
34:
35: /*
36: * Do transfer on device argument. The controller
37: * and uba involved are implied by the device.
38: * We queue for resource wait in the uba code if necessary.
39: * We return 1 if the transfer was started, 0 if it was not.
40: * If you call this routine with the head of the queue for a
41: * UBA, it will automatically remove the device from the UBA
42: * queue before it returns. If some other device is given
43: * as argument, it will be added to the request queue if the
44: * request cannot be started immediately. This means that
45: * passing a device which is on the queue but not at the head
46: * of the request queue is likely to be a disaster.
47: */
48: ubago(ui)
49: register struct uba_device *ui;
50: {
51: register struct uba_ctlr *um = ui->ui_mi;
52: register struct uba_hd *uh;
53: register int s, unit;
54:
55: uh = &uba_hd[um->um_ubanum];
56: s = spluba();
57: if (um->um_driver->ud_xclu && uh->uh_users > 0 || uh->uh_xclu)
58: goto rwait;
59: um->um_ubinfo = ubasetup(um->um_ubanum, um->um_tab.b_actf->b_actf,
60: UBA_NEEDBDP|UBA_CANTWAIT);
61: if (um->um_ubinfo == 0)
62: goto rwait;
63: uh->uh_users++;
64: if (um->um_driver->ud_xclu)
65: uh->uh_xclu = 1;
66: splx(s);
67: if (ui->ui_dk >= 0) {
68: unit = ui->ui_dk;
69: dk_busy |= 1<<unit;
70: dk_xfer[unit]++;
71: dk_wds[unit] += um->um_tab.b_actf->b_actf->b_bcount>>6;
72: }
73: if (uh->uh_actf == ui)
74: uh->uh_actf = ui->ui_forw;
75: (*um->um_driver->ud_dgo)(um);
76: return (1);
77: rwait:
78: if (uh->uh_actf != ui) {
79: ui->ui_forw = NULL;
80: if (uh->uh_actf == NULL)
81: uh->uh_actf = ui;
82: else
83: uh->uh_actl->ui_forw = ui;
84: uh->uh_actl = ui;
85: }
86: splx(s);
87: return (0);
88: }
89:
90: ubadone(um)
91: register struct uba_ctlr *um;
92: {
93: register struct uba_hd *uh = &uba_hd[um->um_ubanum];
94:
95: if (um->um_driver->ud_xclu)
96: uh->uh_xclu = 0;
97: uh->uh_users--;
98: ubarelse(um->um_ubanum, &um->um_ubinfo);
99: }
100:
101: /*
102: * Allocate and setup UBA map registers, and bdp's
103: * Flags says whether bdp is needed, whether the caller can't
104: * wait (e.g. if the caller is at interrupt level).
105: *
106: * Return value:
107: * Bits 0-8 Byte offset
108: * Bits 9-17 Start map reg. no.
109: * Bits 18-27 No. mapping reg's
110: * Bits 28-31 BDP no.
111: */
112: ubasetup(uban, bp, flags)
113: struct buf *bp;
114: {
115: register struct uba_hd *uh = &uba_hd[uban];
116: int pfnum, temp;
117: int npf, reg, bdp;
118: unsigned v;
119: register struct pte *pte, *io;
120: struct proc *rp;
121: int a, o, ubinfo;
122:
123: #if defined(VAX730) || defined(VAX630)
124: if (cpu == VAX_730 || cpu == VAX_630)
125: flags &= ~UBA_NEEDBDP;
126: #endif
127: v = btop(bp->b_un.b_addr);
128: o = (int)bp->b_un.b_addr & PGOFSET;
129: npf = btoc(bp->b_bcount + o) + 1;
130: a = spluba();
131: while ((reg = rmalloc(uh->uh_map, (long)npf)) == 0) {
132: if (flags & UBA_CANTWAIT) {
133: splx(a);
134: return (0);
135: }
136: uh->uh_mrwant++;
137: sleep((caddr_t)&uh->uh_mrwant, PSWP);
138: }
139: if ((flags & UBA_NEED16) && reg + npf > 128) {
140: /*
141: * Could hang around and try again (if we can ever succeed).
142: * Won't help any current device...
143: */
144: rmfree(uh->uh_map, (long)npf, (long)reg);
145: splx(a);
146: return (0);
147: }
148: bdp = 0;
149: if (flags & UBA_NEEDBDP) {
150: while ((bdp = ffs((long)uh->uh_bdpfree)) == 0) {
151: if (flags & UBA_CANTWAIT) {
152: rmfree(uh->uh_map, (long)npf, (long)reg);
153: splx(a);
154: return (0);
155: }
156: uh->uh_bdpwant++;
157: sleep((caddr_t)&uh->uh_bdpwant, PSWP);
158: }
159: uh->uh_bdpfree &= ~(1 << (bdp-1));
160: } else if (flags & UBA_HAVEBDP)
161: bdp = (flags >> 28) & 0xf;
162: splx(a);
163: reg--;
164: ubinfo = (bdp << 28) | (npf << 18) | (reg << 9) | o;
165: temp = (bdp << 21) | UBAMR_MRV;
166: if (bdp && (o & 01))
167: temp |= UBAMR_BO;
168: rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc;
169: if ((bp->b_flags & B_PHYS) == 0)
170: pte = &Sysmap[btop(((int)bp->b_un.b_addr)&0x7fffffff)];
171: else if (bp->b_flags & B_UAREA)
172: pte = &rp->p_addr[v];
173: else if (bp->b_flags & B_PAGET)
174: pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)];
175: else
176: pte = vtopte(rp, v);
177: io = &uh->uh_uba->uba_map[reg];
178: while (--npf != 0) {
179: pfnum = pte->pg_pfnum;
180: if (pfnum == 0)
181: panic("uba zero uentry");
182: pte++;
183: *(int *)io++ = pfnum | temp;
184: }
185: *(int *)io++ = 0;
186: return (ubinfo);
187: }
188:
189: /*
190: * Non buffer setup interface... set up a buffer and call ubasetup.
191: */
192: uballoc(uban, addr, bcnt, flags)
193: int uban;
194: caddr_t addr;
195: int bcnt, flags;
196: {
197: struct buf ubabuf;
198:
199: ubabuf.b_un.b_addr = addr;
200: ubabuf.b_flags = B_BUSY;
201: ubabuf.b_bcount = bcnt;
202: /* that's all the fields ubasetup() needs */
203: return (ubasetup(uban, &ubabuf, flags));
204: }
205:
206: /*
207: * Release resources on uba uban, and then unblock resource waiters.
208: * The map register parameter is by value since we need to block
209: * against uba resets on 11/780's.
210: */
211: ubarelse(uban, amr)
212: int *amr;
213: {
214: register struct uba_hd *uh = &uba_hd[uban];
215: register int bdp, reg, npf, s;
216: int mr;
217:
218: /*
219: * Carefully see if we should release the space, since
220: * it may be released asynchronously at uba reset time.
221: */
222: s = spluba();
223: mr = *amr;
224: if (mr == 0) {
225: /*
226: * A ubareset() occurred before we got around
227: * to releasing the space... no need to bother.
228: */
229: splx(s);
230: return;
231: }
232: *amr = 0;
233: bdp = (mr >> 28) & 0x0f;
234: if (bdp) {
235: switch (cpu) {
236: #if defined(VAX780) || defined(VAX8600)
237: case VAX_8600:
238: case VAX_780:
239: uh->uh_uba->uba_dpr[bdp] |= UBADPR_BNE;
240: break;
241: #endif
242: #if VAX750
243: case VAX_750:
244: uh->uh_uba->uba_dpr[bdp] |=
245: UBADPR_PURGE|UBADPR_NXM|UBADPR_UCE;
246: break;
247: #endif
248: }
249: uh->uh_bdpfree |= 1 << (bdp-1); /* atomic */
250: if (uh->uh_bdpwant) {
251: uh->uh_bdpwant = 0;
252: wakeup((caddr_t)&uh->uh_bdpwant);
253: }
254: }
255: /*
256: * Put back the registers in the resource map.
257: * The map code must not be reentered,
258: * nor can the registers be freed twice.
259: * Unblock interrupts once this is done.
260: */
261: npf = (mr >> 18) & 0x3ff;
262: reg = ((mr >> 9) & 0x1ff) + 1;
263: rmfree(uh->uh_map, (long)npf, (long)reg);
264: splx(s);
265:
266: /*
267: * Wakeup sleepers for map registers,
268: * and also, if there are processes blocked in dgo(),
269: * give them a chance at the UNIBUS.
270: */
271: if (uh->uh_mrwant) {
272: uh->uh_mrwant = 0;
273: wakeup((caddr_t)&uh->uh_mrwant);
274: }
275: while (uh->uh_actf && ubago(uh->uh_actf))
276: ;
277: }
278:
279: ubapurge(um)
280: register struct uba_ctlr *um;
281: {
282: register struct uba_hd *uh = um->um_hd;
283: register int bdp = (um->um_ubinfo >> 28) & 0x0f;
284:
285: switch (cpu) {
286: #if defined(VAX780) || defined(VAX8600)
287: case VAX_8600:
288: case VAX_780:
289: uh->uh_uba->uba_dpr[bdp] |= UBADPR_BNE;
290: break;
291: #endif
292: #if VAX750
293: case VAX_750:
294: uh->uh_uba->uba_dpr[bdp] |= UBADPR_PURGE|UBADPR_NXM|UBADPR_UCE;
295: break;
296: #endif
297: }
298: }
299:
300: ubainitmaps(uhp)
301: register struct uba_hd *uhp;
302: {
303:
304: rminit(uhp->uh_map, (long)NUBMREG, (long)1, "uba", UAMSIZ);
305: switch (cpu) {
306: #if defined(VAX780) || defined(VAX8600)
307: case VAX_8600:
308: case VAX_780:
309: uhp->uh_bdpfree = (1<<NBDP780) - 1;
310: break;
311: #endif
312: #if VAX750
313: case VAX_750:
314: uhp->uh_bdpfree = (1<<NBDP750) - 1;
315: break;
316: #endif
317: #if defined(VAX730) || defined(VAX630)
318: case VAX_730:
319: case VAX_630:
320: break;
321: #endif
322: }
323: }
324:
325: /*
326: * Generate a reset on uba number uban. Then
327: * call each device in the character device table,
328: * giving it a chance to clean up so as to be able to continue.
329: */
330: ubareset(uban)
331: int uban;
332: {
333: register struct cdevsw *cdp;
334: register struct uba_hd *uh = &uba_hd[uban];
335: int s;
336:
337: s = spluba();
338: uh->uh_users = 0;
339: uh->uh_zvcnt = 0;
340: uh->uh_xclu = 0;
341: uh->uh_actf = uh->uh_actl = 0;
342: uh->uh_bdpwant = 0;
343: uh->uh_mrwant = 0;
344: ubainitmaps(uh);
345: wakeup((caddr_t)&uh->uh_bdpwant);
346: wakeup((caddr_t)&uh->uh_mrwant);
347: printf("uba%d: reset", uban);
348: ubainit(uh->uh_uba);
349: ubameminit(uban);
350: for (cdp = cdevsw; cdp < cdevsw + nchrdev; cdp++)
351: (*cdp->d_reset)(uban);
352: ifubareset(uban);
353: printf("\n");
354: splx(s);
355: }
356:
357: /*
358: * Init a uba. This is called with a pointer
359: * rather than a virtual address since it is called
360: * by code which runs with memory mapping disabled.
361: * In these cases we really don't need the interrupts
362: * enabled, but since we run with ipl high, we don't care
363: * if they are, they will never happen anyways.
364: */
365: ubainit(uba)
366: register struct uba_regs *uba;
367: {
368:
369: switch (cpu) {
370: #if defined(VAX780) || defined(VAX8600)
371: case VAX_8600:
372: case VAX_780:
373: uba->uba_cr = UBACR_ADINIT;
374: uba->uba_cr = UBACR_IFS|UBACR_BRIE|UBACR_USEFIE|UBACR_SUEFIE;
375: while ((uba->uba_cnfgr & UBACNFGR_UBIC) == 0)
376: ;
377: break;
378: #endif
379: #if VAX750
380: case VAX_750:
381: #endif
382: #if VAX730
383: case VAX_730:
384: #endif
385: #if VAX630
386: case VAX_630:
387: #endif
388: #if defined(VAX750) || defined(VAX730) || defined(VAX630)
389: mtpr(IUR, 0);
390: /* give devices time to recover from power fail */
391: /* THIS IS PROBABLY UNNECESSARY */
392: DELAY(500000);
393: /* END PROBABLY UNNECESSARY */
394: break;
395: #endif
396: }
397: }
398:
399: #if defined(VAX780) || defined(VAX8600)
400: int ubawedgecnt = 10;
401: int ubacrazy = 500;
402: int zvcnt_max = 5000; /* in 8 sec */
403: /*
404: * This routine is called by the locore code to process a UBA
405: * error on an 11/780 or 8600. The arguments are passed
406: * on the stack, and value-result (through some trickery).
407: * In particular, the uvec argument is used for further
408: * uba processing so the result aspect of it is very important.
409: * It must not be declared register.
410: */
411: /*ARGSUSED*/
412: ubaerror(uban, uh, ipl, uvec, uba)
413: register int uban;
414: register struct uba_hd *uh;
415: int ipl, uvec;
416: register struct uba_regs *uba;
417: {
418: register sr, s;
419:
420: if (uvec == 0) {
421: /*
422: * Declare dt as unsigned so that negative values
423: * are handled as >8 below, in case time was set back.
424: */
425: u_long dt = time.tv_sec - uh->uh_zvtime;
426:
427: uh->uh_zvtotal++;
428: if (dt > 8) {
429: uh->uh_zvtime = time.tv_sec;
430: uh->uh_zvcnt = 0;
431: }
432: if (++uh->uh_zvcnt > zvcnt_max) {
433: printf("uba%d: too many zero vectors (%d in <%d sec)\n",
434: uban, uh->uh_zvcnt, dt + 1);
435: printf("\tIPL 0x%x\n\tcnfgr: %b Adapter Code: 0x%x\n",
436: ipl, uba->uba_cnfgr&(~0xff), UBACNFGR_BITS,
437: uba->uba_cnfgr&0xff);
438: printf("\tsr: %b\n\tdcr: %x (MIC %sOK)\n",
439: uba->uba_sr, ubasr_bits, uba->uba_dcr,
440: (uba->uba_dcr&0x8000000)?"":"NOT ");
441: ubareset(uban);
442: }
443: return;
444: }
445: if (uba->uba_cnfgr & NEX_CFGFLT) {
446: printf("uba%d: sbi fault sr=%b cnfgr=%b\n",
447: uban, uba->uba_sr, ubasr_bits,
448: uba->uba_cnfgr, NEXFLT_BITS);
449: ubareset(uban);
450: uvec = 0;
451: return;
452: }
453: sr = uba->uba_sr;
454: s = spluba();
455: printf("uba%d: uba error sr=%b fmer=%x fubar=%o\n",
456: uban, uba->uba_sr, ubasr_bits, uba->uba_fmer, 4*uba->uba_fubar);
457: splx(s);
458: uba->uba_sr = sr;
459: uvec &= UBABRRVR_DIV;
460: if (++uh->uh_errcnt % ubawedgecnt == 0) {
461: if (uh->uh_errcnt > ubacrazy)
462: panic("uba crazy");
463: printf("ERROR LIMIT ");
464: ubareset(uban);
465: uvec = 0;
466: return;
467: }
468: return;
469: }
470: #endif
471:
472: /*
473: * Look for devices with unibus memory, allow them to configure, then disable
474: * map registers as necessary. Called during autoconfiguration and ubareset.
475: * The device ubamem routine returns 0 on success, 1 on success if it is fully
476: * configured (has no csr or interrupt, so doesn't need to be probed),
477: * and -1 on failure.
478: */
479: ubameminit(uban)
480: {
481: register struct uba_device *ui;
482: register struct uba_hd *uh = &uba_hd[uban];
483: caddr_t umembase = umem[uban] + 0x3e000, addr;
484: #define ubaoff(off) ((int)(off) & 0x1fff)
485:
486: uh->uh_lastmem = 0;
487: for (ui = ubdinit; ui->ui_driver; ui++) {
488: if (ui->ui_ubanum != uban && ui->ui_ubanum != '?')
489: continue;
490: if (ui->ui_driver->ud_ubamem) {
491: /*
492: * During autoconfiguration, need to fudge ui_addr.
493: */
494: addr = ui->ui_addr;
495: ui->ui_addr = umembase + ubaoff(addr);
496: switch ((*ui->ui_driver->ud_ubamem)(ui, uban)) {
497: case 1:
498: ui->ui_alive = 1;
499: /* FALLTHROUGH */
500: case 0:
501: ui->ui_ubanum = uban;
502: break;
503: }
504: ui->ui_addr = addr;
505: }
506: }
507: #if defined(VAX780) || defined(VAX8600)
508: /*
509: * On a 780, throw away any map registers disabled by rounding
510: * the map disable in the configuration register
511: * up to the next 8K boundary, or below the last unibus memory.
512: */
513: if ((cpu == VAX_780) || (cpu == VAX_8600)) {
514: register i;
515:
516: i = btop(((uh->uh_lastmem + 8191) / 8192) * 8192);
517: while (i)
518: (void) rmget(uh->uh_map, 1, i--);
519: }
520: #endif
521: }
522:
523: /*
524: * Allocate UNIBUS memory. Allocates and initializes
525: * sufficient mapping registers for access. On a 780,
526: * the configuration register is setup to disable UBA
527: * response on DMA transfers to addresses controlled
528: * by the disabled mapping registers.
529: * On a 780, should only be called from ubameminit, or in ascending order
530: * from 0 with 8K-sized and -aligned addresses; freeing memory that isn't
531: * the last unibus memory would free unusable map registers.
532: * Doalloc is 1 to allocate, 0 to deallocate.
533: */
534: ubamem(uban, addr, npg, doalloc)
535: int uban, addr, npg, doalloc;
536: {
537: register struct uba_hd *uh = &uba_hd[uban];
538: register int a;
539: int s;
540:
541: a = (addr >> 9) + 1;
542: s = spluba();
543: if (doalloc)
544: a = rmget(uh->uh_map, npg, a);
545: else
546: rmfree(uh->uh_map, (long)npg, (long)a);
547: splx(s);
548: if (a) {
549: register int i, *m;
550:
551: m = (int *)&uh->uh_uba->uba_map[a - 1];
552: for (i = 0; i < npg; i++)
553: *m++ = 0; /* All off, especially 'valid' */
554: i = addr + npg * 512;
555: if (doalloc && i > uh->uh_lastmem)
556: uh->uh_lastmem = i;
557: else if (doalloc == 0 && i == uh->uh_lastmem)
558: uh->uh_lastmem = addr;
559: #if defined(VAX780) || defined(VAX8600)
560: /*
561: * On a 780, set up the map register disable
562: * field in the configuration register. Beware
563: * of callers that request memory ``out of order''
564: * or in sections other than 8K multiples.
565: * Ubameminit handles such requests properly, however.
566: */
567: if ((cpu == VAX_780) || (cpu == VAX_8600)) {
568: i = uh->uh_uba->uba_cr &~ 0x7c000000;
569: i |= ((uh->uh_lastmem + 8191) / 8192) << 26;
570: uh->uh_uba->uba_cr = i;
571: }
572: #endif
573: }
574: return (a);
575: }
576:
577: #include "ik.h"
578: #include "vs.h"
579: #if NIK > 0 || NVS > 0
580: /*
581: * Map a virtual address into users address space. Actually all we
582: * do is turn on the user mode write protection bits for the particular
583: * page of memory involved.
584: */
585: maptouser(vaddress)
586: caddr_t vaddress;
587: {
588:
589: Sysmap[(((unsigned)(vaddress))-0x80000000) >> 9].pg_prot = (PG_UW>>27);
590: }
591:
592: unmaptouser(vaddress)
593: caddr_t vaddress;
594: {
595:
596: Sysmap[(((unsigned)(vaddress))-0x80000000) >> 9].pg_prot = (PG_KW>>27);
597: }
598: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.