|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution is only permitted until one year after the first shipment ! 6: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and ! 7: * binary forms are permitted provided that: (1) source distributions retain ! 8: * this entire copyright notice and comment, and (2) distributions including ! 9: * binaries display the following acknowledgement: This product includes ! 10: * software developed by the University of California, Berkeley and its ! 11: * contributors'' in the documentation or other materials provided with the ! 12: * distribution and in all advertising materials mentioning features or use ! 13: * of this software. Neither the name of the University nor the names of ! 14: * its contributors may be used to endorse or promote products derived from ! 15: * this software without specific prior written permission. ! 16: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 17: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 18: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 19: * ! 20: * @(#)uba.c 7.9 (Berkeley) 6/28/90 ! 21: */ ! 22: ! 23: #include "param.h" ! 24: #include "systm.h" ! 25: #include "map.h" ! 26: #include "buf.h" ! 27: #include "vm.h" ! 28: #include "user.h" ! 29: #include "proc.h" ! 30: #include "conf.h" ! 31: #include "dkstat.h" ! 32: #include "kernel.h" ! 33: ! 34: #include "../vax/pte.h" ! 35: #include "../vax/cpu.h" ! 36: #include "../vax/mtpr.h" ! 37: #include "../vax/nexus.h" ! 38: #include "ubareg.h" ! 39: #include "ubavar.h" ! 40: ! 41: #ifdef DW780 ! 42: char ubasr_bits[] = UBASR_BITS; ! 43: #endif ! 44: ! 45: #define spluba spl7 /* IPL 17 */ ! 46: ! 47: /* ! 48: * Do transfer on device argument. The controller ! 49: * and uba involved are implied by the device. ! 50: * We queue for resource wait in the uba code if necessary. ! 51: * We return 1 if the transfer was started, 0 if it was not. ! 52: * ! 53: * The onq argument must be zero iff the device is not on the ! 54: * queue for this UBA. If onq is set, the device must be at the ! 55: * head of the queue. In any case, if the transfer is started, ! 56: * the device will be off the queue, and if not, it will be on. ! 57: * ! 58: * Drivers that allocate one BDP and hold it for some time should ! 59: * set ud_keepbdp. In this case um_bdp tells which BDP is allocated ! 60: * to the controller, unless it is zero, indicating that the controller ! 61: * does not now have a BDP. ! 62: */ ! 63: ubaqueue(ui, onq) ! 64: register struct uba_device *ui; ! 65: int onq; ! 66: { ! 67: register struct uba_ctlr *um = ui->ui_mi; ! 68: register struct uba_hd *uh; ! 69: register struct uba_driver *ud; ! 70: register int s, unit; ! 71: ! 72: uh = &uba_hd[um->um_ubanum]; ! 73: ud = um->um_driver; ! 74: s = spluba(); ! 75: /* ! 76: * Honor exclusive BDP use requests. ! 77: */ ! 78: if (ud->ud_xclu && uh->uh_users > 0 || uh->uh_xclu) ! 79: goto rwait; ! 80: if (ud->ud_keepbdp) { ! 81: /* ! 82: * First get just a BDP (though in fact it comes with ! 83: * one map register too). ! 84: */ ! 85: if (um->um_bdp == 0) { ! 86: um->um_bdp = uballoc(um->um_ubanum, ! 87: (caddr_t)0, 0, UBA_NEEDBDP|UBA_CANTWAIT); ! 88: if (um->um_bdp == 0) ! 89: goto rwait; ! 90: } ! 91: /* now share it with this transfer */ ! 92: um->um_ubinfo = ubasetup(um->um_ubanum, ! 93: um->um_tab.b_actf->b_actf, ! 94: um->um_bdp|UBA_HAVEBDP|UBA_CANTWAIT); ! 95: } else ! 96: um->um_ubinfo = ubasetup(um->um_ubanum, ! 97: um->um_tab.b_actf->b_actf, UBA_NEEDBDP|UBA_CANTWAIT); ! 98: if (um->um_ubinfo == 0) ! 99: goto rwait; ! 100: uh->uh_users++; ! 101: if (ud->ud_xclu) ! 102: uh->uh_xclu = 1; ! 103: splx(s); ! 104: if (ui->ui_dk >= 0) { ! 105: unit = ui->ui_dk; ! 106: dk_busy |= 1<<unit; ! 107: dk_xfer[unit]++; ! 108: dk_wds[unit] += um->um_tab.b_actf->b_actf->b_bcount>>6; ! 109: } ! 110: if (onq) ! 111: uh->uh_actf = ui->ui_forw; ! 112: (*ud->ud_dgo)(um); ! 113: return (1); ! 114: rwait: ! 115: if (!onq) { ! 116: ui->ui_forw = NULL; ! 117: if (uh->uh_actf == NULL) ! 118: uh->uh_actf = ui; ! 119: else ! 120: uh->uh_actl->ui_forw = ui; ! 121: uh->uh_actl = ui; ! 122: } ! 123: splx(s); ! 124: return (0); ! 125: } ! 126: ! 127: ubadone(um) ! 128: register struct uba_ctlr *um; ! 129: { ! 130: register struct uba_hd *uh = &uba_hd[um->um_ubanum]; ! 131: ! 132: if (um->um_driver->ud_xclu) ! 133: uh->uh_xclu = 0; ! 134: uh->uh_users--; ! 135: if (um->um_driver->ud_keepbdp) ! 136: um->um_ubinfo &= ~BDPMASK; /* keep BDP for misers */ ! 137: ubarelse(um->um_ubanum, &um->um_ubinfo); ! 138: } ! 139: ! 140: /* ! 141: * Allocate and setup UBA map registers, and bdp's ! 142: * Flags says whether bdp is needed, whether the caller can't ! 143: * wait (e.g. if the caller is at interrupt level). ! 144: * Return value encodes map register plus page offset, ! 145: * bdp number and number of map registers. ! 146: */ ! 147: ubasetup(uban, bp, flags) ! 148: int uban; ! 149: register struct buf *bp; ! 150: register int flags; ! 151: { ! 152: register struct uba_hd *uh = &uba_hd[uban]; ! 153: register struct pte *pte, *io; ! 154: register int npf; ! 155: int pfnum, temp; ! 156: int reg, bdp; ! 157: unsigned v; ! 158: struct proc *rp; ! 159: int a, o, ubinfo; ! 160: ! 161: #ifdef DW730 ! 162: if (uh->uh_type == DW730) ! 163: flags &= ~UBA_NEEDBDP; ! 164: #endif ! 165: #ifdef QBA ! 166: if (uh->uh_type == QBA) ! 167: flags &= ~UBA_NEEDBDP; ! 168: #endif ! 169: o = (int)bp->b_un.b_addr & PGOFSET; ! 170: npf = btoc(bp->b_bcount + o) + 1; ! 171: if (npf > UBA_MAXNMR) ! 172: panic("uba xfer too big"); ! 173: a = spluba(); ! 174: while ((reg = rmalloc(uh->uh_map, (long)npf)) == 0) { ! 175: if (flags & UBA_CANTWAIT) { ! 176: splx(a); ! 177: return (0); ! 178: } ! 179: uh->uh_mrwant++; ! 180: sleep((caddr_t)&uh->uh_mrwant, PSWP); ! 181: } ! 182: if ((flags & UBA_NEED16) && reg + npf > 128) { ! 183: /* ! 184: * Could hang around and try again (if we can ever succeed). ! 185: * Won't help any current device... ! 186: */ ! 187: rmfree(uh->uh_map, (long)npf, (long)reg); ! 188: splx(a); ! 189: return (0); ! 190: } ! 191: bdp = 0; ! 192: if (flags & UBA_NEEDBDP) { ! 193: while ((bdp = ffs((long)uh->uh_bdpfree)) == 0) { ! 194: if (flags & UBA_CANTWAIT) { ! 195: rmfree(uh->uh_map, (long)npf, (long)reg); ! 196: splx(a); ! 197: return (0); ! 198: } ! 199: uh->uh_bdpwant++; ! 200: sleep((caddr_t)&uh->uh_bdpwant, PSWP); ! 201: } ! 202: uh->uh_bdpfree &= ~(1 << (bdp-1)); ! 203: } else if (flags & UBA_HAVEBDP) ! 204: bdp = (flags >> 28) & 0xf; ! 205: splx(a); ! 206: reg--; ! 207: ubinfo = UBAI_INFO(o, reg, npf, bdp); ! 208: temp = (bdp << 21) | UBAMR_MRV; ! 209: if (bdp && (o & 01)) ! 210: temp |= UBAMR_BO; ! 211: if ((bp->b_flags & B_PHYS) == 0) ! 212: pte = kvtopte(bp->b_un.b_addr); ! 213: else if (bp->b_flags & B_PAGET) ! 214: pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)]; ! 215: else { ! 216: rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc; ! 217: v = btop(bp->b_un.b_addr); ! 218: if (bp->b_flags & B_UAREA) ! 219: pte = &rp->p_addr[v]; ! 220: else ! 221: pte = vtopte(rp, v); ! 222: } ! 223: io = &uh->uh_mr[reg]; ! 224: while (--npf > 0) { ! 225: pfnum = pte->pg_pfnum; ! 226: if (pfnum == 0) ! 227: panic("uba zero uentry"); ! 228: pte++; ! 229: *(int *)io++ = pfnum | temp; ! 230: } ! 231: *(int *)io = 0; ! 232: return (ubinfo); ! 233: } ! 234: ! 235: /* ! 236: * Non buffer setup interface... set up a buffer and call ubasetup. ! 237: */ ! 238: uballoc(uban, addr, bcnt, flags) ! 239: int uban; ! 240: caddr_t addr; ! 241: int bcnt, flags; ! 242: { ! 243: struct buf ubabuf; ! 244: ! 245: ubabuf.b_un.b_addr = addr; ! 246: ubabuf.b_flags = B_BUSY; ! 247: ubabuf.b_bcount = bcnt; ! 248: /* that's all the fields ubasetup() needs */ ! 249: return (ubasetup(uban, &ubabuf, flags)); ! 250: } ! 251: ! 252: /* ! 253: * Release resources on uba uban, and then unblock resource waiters. ! 254: * The map register parameter is by value since we need to block ! 255: * against uba resets on 11/780's. ! 256: */ ! 257: ubarelse(uban, amr) ! 258: int *amr; ! 259: { ! 260: register struct uba_hd *uh = &uba_hd[uban]; ! 261: register int bdp, reg, npf, s; ! 262: int mr; ! 263: ! 264: /* ! 265: * Carefully see if we should release the space, since ! 266: * it may be released asynchronously at uba reset time. ! 267: */ ! 268: s = spluba(); ! 269: mr = *amr; ! 270: if (mr == 0) { ! 271: /* ! 272: * A ubareset() occurred before we got around ! 273: * to releasing the space... no need to bother. ! 274: */ ! 275: splx(s); ! 276: return; ! 277: } ! 278: *amr = 0; ! 279: bdp = UBAI_BDP(mr); ! 280: if (bdp) { ! 281: switch (uh->uh_type) { ! 282: #ifdef DWBUA ! 283: case DWBUA: ! 284: BUA(uh->uh_uba)->bua_dpr[bdp] |= BUADPR_PURGE; ! 285: break; ! 286: #endif ! 287: #ifdef DW780 ! 288: case DW780: ! 289: uh->uh_uba->uba_dpr[bdp] |= UBADPR_BNE; ! 290: break; ! 291: #endif ! 292: #ifdef DW750 ! 293: case DW750: ! 294: uh->uh_uba->uba_dpr[bdp] |= ! 295: UBADPR_PURGE|UBADPR_NXM|UBADPR_UCE; ! 296: break; ! 297: #endif ! 298: default: ! 299: break; ! 300: } ! 301: uh->uh_bdpfree |= 1 << (bdp-1); /* atomic */ ! 302: if (uh->uh_bdpwant) { ! 303: uh->uh_bdpwant = 0; ! 304: wakeup((caddr_t)&uh->uh_bdpwant); ! 305: } ! 306: } ! 307: /* ! 308: * Put back the registers in the resource map. ! 309: * The map code must not be reentered, ! 310: * nor can the registers be freed twice. ! 311: * Unblock interrupts once this is done. ! 312: */ ! 313: npf = UBAI_NMR(mr); ! 314: reg = UBAI_MR(mr) + 1; ! 315: rmfree(uh->uh_map, (long)npf, (long)reg); ! 316: splx(s); ! 317: ! 318: /* ! 319: * Wakeup sleepers for map registers, ! 320: * and also, if there are processes blocked in dgo(), ! 321: * give them a chance at the UNIBUS. ! 322: */ ! 323: if (uh->uh_mrwant) { ! 324: uh->uh_mrwant = 0; ! 325: wakeup((caddr_t)&uh->uh_mrwant); ! 326: } ! 327: while (uh->uh_actf && ubaqueue(uh->uh_actf, 1)) ! 328: ; ! 329: } ! 330: ! 331: ubapurge(um) ! 332: register struct uba_ctlr *um; ! 333: { ! 334: register struct uba_hd *uh = um->um_hd; ! 335: register int bdp = UBAI_BDP(um->um_ubinfo); ! 336: ! 337: switch (uh->uh_type) { ! 338: #ifdef DWBUA ! 339: case DWBUA: ! 340: BUA(uh->uh_uba)->bua_dpr[bdp] |= BUADPR_PURGE; ! 341: break; ! 342: #endif ! 343: #ifdef DW780 ! 344: case DW780: ! 345: uh->uh_uba->uba_dpr[bdp] |= UBADPR_BNE; ! 346: break; ! 347: #endif ! 348: #ifdef DW750 ! 349: case DW750: ! 350: uh->uh_uba->uba_dpr[bdp] |= UBADPR_PURGE|UBADPR_NXM|UBADPR_UCE; ! 351: break; ! 352: #endif ! 353: default: ! 354: break; ! 355: } ! 356: } ! 357: ! 358: ubainitmaps(uhp) ! 359: register struct uba_hd *uhp; ! 360: { ! 361: ! 362: if (uhp->uh_memsize > UBA_MAXMR) ! 363: uhp->uh_memsize = UBA_MAXMR; ! 364: rminit(uhp->uh_map, (long)uhp->uh_memsize, (long)1, "uba", UAMSIZ); ! 365: switch (uhp->uh_type) { ! 366: #ifdef DWBUA ! 367: case DWBUA: ! 368: uhp->uh_bdpfree = (1<<NBDPBUA) - 1; ! 369: break; ! 370: #endif ! 371: #ifdef DW780 ! 372: case DW780: ! 373: uhp->uh_bdpfree = (1<<NBDP780) - 1; ! 374: break; ! 375: #endif ! 376: #ifdef DW750 ! 377: case DW750: ! 378: uhp->uh_bdpfree = (1<<NBDP750) - 1; ! 379: break; ! 380: #endif ! 381: default: ! 382: break; ! 383: } ! 384: } ! 385: ! 386: /* ! 387: * Generate a reset on uba number uban. Then ! 388: * call each device in the character device table, ! 389: * giving it a chance to clean up so as to be able to continue. ! 390: */ ! 391: ubareset(uban) ! 392: int uban; ! 393: { ! 394: register struct cdevsw *cdp; ! 395: register struct uba_hd *uh = &uba_hd[uban]; ! 396: int s; ! 397: ! 398: s = spluba(); ! 399: uh->uh_users = 0; ! 400: uh->uh_zvcnt = 0; ! 401: uh->uh_xclu = 0; ! 402: uh->uh_actf = uh->uh_actl = 0; ! 403: uh->uh_bdpwant = 0; ! 404: uh->uh_mrwant = 0; ! 405: ubainitmaps(uh); ! 406: wakeup((caddr_t)&uh->uh_bdpwant); ! 407: wakeup((caddr_t)&uh->uh_mrwant); ! 408: printf("uba%d: reset", uban); ! 409: ubainit(uh->uh_uba); ! 410: ubameminit(uban); ! 411: for (cdp = cdevsw; cdp < cdevsw + nchrdev; cdp++) ! 412: (*cdp->d_reset)(uban); ! 413: ifubareset(uban); ! 414: printf("\n"); ! 415: splx(s); ! 416: } ! 417: ! 418: /* ! 419: * Init a uba. This is called with a pointer ! 420: * rather than a virtual address since it is called ! 421: * by code which runs with memory mapping disabled. ! 422: * In these cases we really don't need the interrupts ! 423: * enabled, but since we run with ipl high, we don't care ! 424: * if they are, they will never happen anyways. ! 425: * SHOULD GET POINTER TO UBA_HD INSTEAD OF UBA. ! 426: */ ! 427: ubainit(uba) ! 428: register struct uba_regs *uba; ! 429: { ! 430: register struct uba_hd *uhp; ! 431: #ifdef QBA ! 432: int isphys = 0; ! 433: #endif ! 434: ! 435: for (uhp = uba_hd; uhp < uba_hd + numuba; uhp++) { ! 436: if (uhp->uh_uba == uba) ! 437: break; ! 438: if (uhp->uh_physuba == uba) { ! 439: #ifdef QBA ! 440: isphys++; ! 441: #endif ! 442: break; ! 443: } ! 444: } ! 445: if (uhp >= uba_hd + numuba) { ! 446: printf("init unknown uba\n"); ! 447: return; ! 448: } ! 449: ! 450: switch (uhp->uh_type) { ! 451: #ifdef DWBUA ! 452: case DWBUA: ! 453: BUA(uba)->bua_csr |= BUACSR_UPI; ! 454: /* give devices time to recover from power fail */ ! 455: DELAY(500000); ! 456: break; ! 457: #endif ! 458: #ifdef DW780 ! 459: case DW780: ! 460: uba->uba_cr = UBACR_ADINIT; ! 461: uba->uba_cr = UBACR_IFS|UBACR_BRIE|UBACR_USEFIE|UBACR_SUEFIE; ! 462: while ((uba->uba_cnfgr & UBACNFGR_UBIC) == 0) ! 463: ; ! 464: break; ! 465: #endif ! 466: #ifdef DW750 ! 467: case DW750: ! 468: #endif ! 469: #ifdef DW730 ! 470: case DW730: ! 471: #endif ! 472: #ifdef QBA ! 473: case QBA: ! 474: #endif ! 475: #if DW750 || DW730 || QBA ! 476: mtpr(IUR, 0); ! 477: /* give devices time to recover from power fail */ ! 478: /* THIS IS PROBABLY UNNECESSARY */ ! 479: DELAY(500000); ! 480: /* END PROBABLY UNNECESSARY */ ! 481: #ifdef QBA ! 482: /* ! 483: * Re-enable local memory access ! 484: * from the Q-bus. ! 485: */ ! 486: if (uhp->uh_type == QBA) { ! 487: if (isphys) ! 488: *((char *)QIOPAGE630 + QIPCR) = Q_LMEAE; ! 489: else ! 490: *(uhp->uh_iopage + QIPCR) = Q_LMEAE; ! 491: } ! 492: #endif QBA ! 493: break; ! 494: #endif DW750 || DW730 || QBA ! 495: } ! 496: } ! 497: ! 498: #ifdef QBA ! 499: /* ! 500: * Determine the interrupt priority of a Q-bus ! 501: * peripheral. The device probe routine must spl6(), ! 502: * attempt to make the device request an interrupt, ! 503: * delaying as necessary, then call this routine ! 504: * before resetting the device. ! 505: */ ! 506: qbgetpri() ! 507: { ! 508: int pri; ! 509: extern int cvec; ! 510: ! 511: for (pri = 0x17; pri > 0x14; ) { ! 512: if (cvec && cvec != 0x200) /* interrupted at pri */ ! 513: break; ! 514: pri--; ! 515: splx(pri - 1); ! 516: } ! 517: (void) spl0(); ! 518: return (pri); ! 519: } ! 520: #endif ! 521: ! 522: #ifdef DW780 ! 523: int ubawedgecnt = 10; ! 524: int ubacrazy = 500; ! 525: int zvcnt_max = 5000; /* in 8 sec */ ! 526: /* ! 527: * This routine is called by the locore code to process a UBA ! 528: * error on an 11/780 or 8600. The arguments are passed ! 529: * on the stack, and value-result (through some trickery). ! 530: * In particular, the uvec argument is used for further ! 531: * uba processing so the result aspect of it is very important. ! 532: * It must not be declared register. ! 533: */ ! 534: /*ARGSUSED*/ ! 535: ubaerror(uban, uh, ipl, uvec, uba) ! 536: register int uban; ! 537: register struct uba_hd *uh; ! 538: int ipl, uvec; ! 539: register struct uba_regs *uba; ! 540: { ! 541: register sr, s; ! 542: ! 543: if (uvec == 0) { ! 544: /* ! 545: * Declare dt as unsigned so that negative values ! 546: * are handled as >8 below, in case time was set back. ! 547: */ ! 548: u_long dt = time.tv_sec - uh->uh_zvtime; ! 549: ! 550: uh->uh_zvtotal++; ! 551: if (dt > 8) { ! 552: uh->uh_zvtime = time.tv_sec; ! 553: uh->uh_zvcnt = 0; ! 554: } ! 555: if (++uh->uh_zvcnt > zvcnt_max) { ! 556: printf("uba%d: too many zero vectors (%d in <%d sec)\n", ! 557: uban, uh->uh_zvcnt, dt + 1); ! 558: printf("\tIPL 0x%x\n\tcnfgr: %b Adapter Code: 0x%x\n", ! 559: ipl, uba->uba_cnfgr&(~0xff), UBACNFGR_BITS, ! 560: uba->uba_cnfgr&0xff); ! 561: printf("\tsr: %b\n\tdcr: %x (MIC %sOK)\n", ! 562: uba->uba_sr, ubasr_bits, uba->uba_dcr, ! 563: (uba->uba_dcr&0x8000000)?"":"NOT "); ! 564: ubareset(uban); ! 565: } ! 566: return; ! 567: } ! 568: if (uba->uba_cnfgr & NEX_CFGFLT) { ! 569: printf("uba%d: sbi fault sr=%b cnfgr=%b\n", ! 570: uban, uba->uba_sr, ubasr_bits, ! 571: uba->uba_cnfgr, NEXFLT_BITS); ! 572: ubareset(uban); ! 573: uvec = 0; ! 574: return; ! 575: } ! 576: sr = uba->uba_sr; ! 577: s = spluba(); ! 578: printf("uba%d: uba error sr=%b fmer=%x fubar=%o\n", ! 579: uban, uba->uba_sr, ubasr_bits, uba->uba_fmer, 4*uba->uba_fubar); ! 580: splx(s); ! 581: uba->uba_sr = sr; ! 582: uvec &= UBABRRVR_DIV; ! 583: if (++uh->uh_errcnt % ubawedgecnt == 0) { ! 584: if (uh->uh_errcnt > ubacrazy) ! 585: panic("uba crazy"); ! 586: printf("ERROR LIMIT "); ! 587: ubareset(uban); ! 588: uvec = 0; ! 589: return; ! 590: } ! 591: return; ! 592: } ! 593: #endif ! 594: ! 595: /* ! 596: * Look for devices with unibus memory, allow them to configure, then disable ! 597: * map registers as necessary. Called during autoconfiguration and ubareset. ! 598: * The device ubamem routine returns 0 on success, 1 on success if it is fully ! 599: * configured (has no csr or interrupt, so doesn't need to be probed), ! 600: * and -1 on failure. ! 601: */ ! 602: ubameminit(uban) ! 603: { ! 604: register struct uba_device *ui; ! 605: register struct uba_hd *uh = &uba_hd[uban]; ! 606: caddr_t umembase = umem[uban] + 0x3e000, addr; ! 607: #define ubaoff(off) ((int)(off) & 0x1fff) ! 608: ! 609: uh->uh_lastmem = 0; ! 610: for (ui = ubdinit; ui->ui_driver; ui++) { ! 611: if (ui->ui_ubanum != uban && ui->ui_ubanum != '?') ! 612: continue; ! 613: if (ui->ui_driver->ud_ubamem) { ! 614: /* ! 615: * During autoconfiguration, need to fudge ui_addr. ! 616: */ ! 617: addr = ui->ui_addr; ! 618: ui->ui_addr = umembase + ubaoff(addr); ! 619: switch ((*ui->ui_driver->ud_ubamem)(ui, uban)) { ! 620: case 1: ! 621: ui->ui_alive = 1; ! 622: /* FALLTHROUGH */ ! 623: case 0: ! 624: ui->ui_ubanum = uban; ! 625: break; ! 626: } ! 627: ui->ui_addr = addr; ! 628: } ! 629: } ! 630: #ifdef DW780 ! 631: /* ! 632: * On a DW780, throw away any map registers disabled by rounding ! 633: * the map disable in the configuration register ! 634: * up to the next 8K boundary, or below the last unibus memory. ! 635: */ ! 636: if (uh->uh_type == DW780) { ! 637: register i; ! 638: ! 639: i = btop(((uh->uh_lastmem + 8191) / 8192) * 8192); ! 640: while (i) ! 641: (void) rmget(uh->uh_map, 1, i--); ! 642: } ! 643: #endif ! 644: } ! 645: ! 646: /* ! 647: * Allocate UNIBUS memory. Allocates and initializes ! 648: * sufficient mapping registers for access. On a 780, ! 649: * the configuration register is setup to disable UBA ! 650: * response on DMA transfers to addresses controlled ! 651: * by the disabled mapping registers. ! 652: * On a DW780, should only be called from ubameminit, or in ascending order ! 653: * from 0 with 8K-sized and -aligned addresses; freeing memory that isn't ! 654: * the last unibus memory would free unusable map registers. ! 655: * Doalloc is 1 to allocate, 0 to deallocate. ! 656: */ ! 657: ubamem(uban, addr, npg, doalloc) ! 658: int uban, addr, npg, doalloc; ! 659: { ! 660: register struct uba_hd *uh = &uba_hd[uban]; ! 661: register int a; ! 662: int s; ! 663: ! 664: a = (addr >> 9) + 1; ! 665: s = spluba(); ! 666: if (doalloc) ! 667: a = rmget(uh->uh_map, npg, a); ! 668: else ! 669: rmfree(uh->uh_map, (long)npg, (long)a); ! 670: splx(s); ! 671: if (a) { ! 672: register int i, *m; ! 673: ! 674: m = (int *)&uh->uh_mr[a - 1]; ! 675: for (i = 0; i < npg; i++) ! 676: *m++ = 0; /* All off, especially 'valid' */ ! 677: i = addr + npg * 512; ! 678: if (doalloc && i > uh->uh_lastmem) ! 679: uh->uh_lastmem = i; ! 680: else if (doalloc == 0 && i == uh->uh_lastmem) ! 681: uh->uh_lastmem = addr; ! 682: #ifdef DW780 ! 683: /* ! 684: * On a 780, set up the map register disable ! 685: * field in the configuration register. Beware ! 686: * of callers that request memory ``out of order'' ! 687: * or in sections other than 8K multiples. ! 688: * Ubameminit handles such requests properly, however. ! 689: */ ! 690: if (uh->uh_type == DW780) { ! 691: i = uh->uh_uba->uba_cr &~ 0x7c000000; ! 692: i |= ((uh->uh_lastmem + 8191) / 8192) << 26; ! 693: uh->uh_uba->uba_cr = i; ! 694: } ! 695: #endif ! 696: } ! 697: return (a); ! 698: } ! 699: ! 700: #include "ik.h" ! 701: #include "vs.h" ! 702: #if NIK > 0 || NVS > 0 ! 703: /* ! 704: * Map a virtual address into users address space. Actually all we ! 705: * do is turn on the user mode write protection bits for the particular ! 706: * page of memory involved. ! 707: */ ! 708: maptouser(vaddress) ! 709: caddr_t vaddress; ! 710: { ! 711: ! 712: kvtopte(vaddress)->pg_prot = (PG_UW >> 27); ! 713: } ! 714: ! 715: unmaptouser(vaddress) ! 716: caddr_t vaddress; ! 717: { ! 718: ! 719: kvtopte(vaddress)->pg_prot = (PG_KW >> 27); ! 720: } ! 721: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.