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