|
|
1.1 ! root 1: /* autoconf.c 1.3 81/10/07 */ ! 2: /* autoconf.c 4.31 81/07/05 */ ! 3: ! 4: /* ! 5: * Setup the system to run on the current machine. ! 6: * ! 7: * Configure() is called at boot time and initializes the uba and mba ! 8: * device tables and the memory controller monitoring. Available ! 9: * devices are determined (from possibilities mentioned in ioconf.c), ! 10: * and the drivers are initialized. ! 11: * ! 12: * N.B.: A lot of the conditionals based on processor type say ! 13: * #if VAX780 ! 14: * and ! 15: * #if VAX750 ! 16: * which may be incorrect after more processors are introduced if they ! 17: * are like either of these machines. ! 18: * ! 19: * TODO: ! 20: * use pcpu info about whether a ubasr exists ! 21: */ ! 22: ! 23: #include "mba.h" ! 24: ! 25: #include "../h/param.h" ! 26: #include "../h/systm.h" ! 27: #include "../h/map.h" ! 28: #include "../h/nexus.h" ! 29: #include "../h/pte.h" ! 30: #include "../h/buf.h" ! 31: #include "../h/mbareg.h" ! 32: #include "../h/mbavar.h" ! 33: #include "../h/dk.h" ! 34: #include "../h/vm.h" ! 35: #include "../h/ubareg.h" ! 36: #include "../h/ubavar.h" ! 37: #include "../h/mtpr.h" ! 38: #include "../h/cpu.h" ! 39: #include "../h/scb.h" ! 40: #include "../h/mem.h" ! 41: ! 42: /* ! 43: * The following several variables are related to ! 44: * the configuration process, and are used in initializing ! 45: * the machine. ! 46: */ ! 47: int cold; /* if 1, still working on cold-start */ ! 48: int nexnum; /* current nexus number */ ! 49: int dkn; /* number of iostat dk numbers assigned so far */ ! 50: ! 51: /* ! 52: * Addresses of the (locore) routines which bootstrap us from ! 53: * hardware traps to C code. Filled into the system control block ! 54: * as necessary. ! 55: */ ! 56: #if NMBA > 0 ! 57: int (*mbaintv[4])() = { Xmba0int, Xmba1int, Xmba2int, Xmba3int }; ! 58: #endif ! 59: #if VAX780 ! 60: int (*ubaintv[4])() = { Xua0int, Xua1int, Xua2int, Xua3int }; ! 61: #endif ! 62: ! 63: /* ! 64: * This allocates the space for the per-uba information, ! 65: * such as buffered data path usage. ! 66: */ ! 67: struct uba_hd uba_hd[MAXNUBA]; ! 68: ! 69: /* ! 70: * Determine mass storage and memory configuration for a machine. ! 71: * Get cpu type, and then switch out to machine specific procedures ! 72: * which will probe adaptors to see what is out there. ! 73: */ ! 74: configure() ! 75: { ! 76: union cpusid cpusid; ! 77: register struct percpu *ocp; ! 78: register int *ip; ! 79: extern char Sysbase[]; ! 80: ! 81: cpusid.cpusid = mfpr(SID); ! 82: for (ocp = percpu; ocp->pc_cputype; ocp++) ! 83: if (ocp->pc_cputype == cpusid.cpuany.cp_type) { ! 84: probenexus(ocp); ! 85: /* ! 86: * Write protect the scb. It is strange ! 87: * that this code is here, but this is as soon ! 88: * as we are done mucking with it, and the ! 89: * write-enable was done in assembly language ! 90: * to which we will never return. ! 91: */ ! 92: ip = (int *)Sysmap; *ip &= ~PG_PROT; *ip |= PG_KR; ! 93: mtpr(TBIS, Sysbase); ! 94: #if GENERIC ! 95: setconf(); ! 96: #endif ! 97: cold = 0; ! 98: memenable(); ! 99: return; ! 100: } ! 101: printf("cpu type %d not configured\n", cpusid.cpuany.cp_type); ! 102: asm("halt"); ! 103: } ! 104: ! 105: /* ! 106: * Probe nexus space, finding the interconnects ! 107: * and setting up and probing mba's and uba's for devices. ! 108: */ ! 109: /*ARGSUSED*/ ! 110: probenexus(pcpu) ! 111: register struct percpu *pcpu; ! 112: { ! 113: register struct nexus *nxv; ! 114: struct nexus *nxp = pcpu->pc_nexbase; ! 115: union nexcsr nexcsr; ! 116: int i; ! 117: ! 118: nexnum = 0, nxv = nexus; ! 119: for (; nexnum < pcpu->pc_nnexus; nexnum++, nxp++, nxv++) { ! 120: nxaccess(nxp, Nexmap[nexnum]); ! 121: if (badaddr((caddr_t)nxv, 4)) ! 122: continue; ! 123: if (pcpu->pc_nextype && pcpu->pc_nextype[nexnum] != NEX_ANY) ! 124: nexcsr.nex_csr = pcpu->pc_nextype[nexnum]; ! 125: else ! 126: nexcsr = nxv->nexcsr; ! 127: if (nexcsr.nex_csr&NEX_APD) ! 128: continue; ! 129: switch (nexcsr.nex_type) { ! 130: ! 131: case NEX_MBA: ! 132: printf("mba%d at tr%d\n", nummba, nexnum); ! 133: if (nummba >= NMBA) { ! 134: printf("%d mba's", nummba); ! 135: goto unconfig; ! 136: } ! 137: #if NMBA > 0 ! 138: mbafind(nxv, nxp); ! 139: nummba++; ! 140: #endif ! 141: break; ! 142: ! 143: case NEX_UBA0: ! 144: case NEX_UBA1: ! 145: case NEX_UBA2: ! 146: case NEX_UBA3: ! 147: printf("uba%d at tr%d\n", numuba, nexnum); ! 148: #if VAX750 /* temp until this is fixed right */ ! 149: if (numuba > 0) { ! 150: #else ! 151: if (numuba >= 4) { ! 152: #endif ! 153: printf("%d uba's", numuba); ! 154: goto unsupp; ! 155: } ! 156: #if VAX780 ! 157: if (cpu == VAX_780) ! 158: setscbnex(ubaintv[numuba]); ! 159: #endif ! 160: i = nexcsr.nex_type - NEX_UBA0; ! 161: unifind((struct uba_regs *)nxv, (struct uba_regs *)nxp, ! 162: umem[i], pcpu->pc_umaddr[i], UMEMmap[i]); ! 163: #if VAX780 ! 164: if (cpu == VAX_780) ! 165: ((struct uba_regs *)nxv)->uba_cr = ! 166: UBACR_IFS|UBACR_BRIE| ! 167: UBACR_USEFIE|UBACR_SUEFIE; ! 168: #endif ! 169: numuba++; ! 170: break; ! 171: ! 172: case NEX_DR32: ! 173: /* there can be more than one... are there other codes??? */ ! 174: printf("dr32"); ! 175: goto unsupp; ! 176: ! 177: case NEX_MEM4: ! 178: case NEX_MEM4I: ! 179: case NEX_MEM16: ! 180: case NEX_MEM16I: ! 181: printf("mcr%d at tr%d\n", nmcr, nexnum); ! 182: if (nmcr >= 4) { ! 183: printf("5 mcr's"); ! 184: goto unsupp; ! 185: } ! 186: mcraddr[nmcr++] = (struct mcr *)nxv; ! 187: break; ! 188: ! 189: case NEX_MPM0: ! 190: case NEX_MPM1: ! 191: case NEX_MPM2: ! 192: case NEX_MPM3: ! 193: printf("mpm"); ! 194: goto unsupp; ! 195: ! 196: default: ! 197: printf("nexus type %x", nexcsr.nex_type); ! 198: unsupp: ! 199: printf(" unsupported (at tr %d)\n", nexnum); ! 200: continue; ! 201: unconfig: ! 202: printf(" not configured\n"); ! 203: continue; ! 204: } ! 205: } ! 206: #if VAX780 ! 207: if (cpu == VAX_780) ! 208: { int ubawatch(); timeout(ubawatch, (caddr_t)0, hz); } ! 209: #endif ! 210: } ! 211: ! 212: #if NMBA > 0 ! 213: struct mba_device *mbaconfig(); ! 214: /* ! 215: * Find devices attached to a particular mba ! 216: * and look for each device found in the massbus ! 217: * initialization tables. ! 218: */ ! 219: mbafind(nxv, nxp) ! 220: struct nexus *nxv, *nxp; ! 221: { ! 222: register struct mba_regs *mdp; ! 223: register struct mba_drv *mbd; ! 224: register struct mba_device *mi; ! 225: register struct mba_slave *ms; ! 226: int dn, dt; ! 227: struct mba_device fnd; ! 228: ! 229: mdp = (struct mba_regs *)nxv; ! 230: mba_hd[nummba].mh_mba = mdp; ! 231: mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp; ! 232: setscbnex(mbaintv[nummba]); ! 233: fnd.mi_mba = mdp; ! 234: fnd.mi_mbanum = nummba; ! 235: for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) { ! 236: dt = mbd->mbd_dt & 0xffff; ! 237: if (dt == 0) ! 238: continue; ! 239: if (dt == MBDT_MOH) ! 240: continue; ! 241: fnd.mi_drive = dn; ! 242: if ((mi = mbaconfig(&fnd, dt)) && (dt & MBDT_TAP)) { ! 243: for (ms = mbsinit; ms->ms_driver; ms++) ! 244: if (ms->ms_driver == mi->mi_driver && ms->ms_alive == 0 && ! 245: (ms->ms_ctlr == mi->mi_unit || ms->ms_ctlr=='?')) { ! 246: if ((*ms->ms_driver->md_slave)(mi, ms)) { ! 247: printf("%s%d at %s%d slave %d\n", ! 248: ms->ms_driver->md_sname, ! 249: ms->ms_unit, ! 250: mi->mi_driver->md_dname, ! 251: mi->mi_unit, ! 252: ms->ms_slave); ! 253: ms->ms_alive = 1; ! 254: ms->ms_ctlr = mi->mi_unit; ! 255: } ! 256: } ! 257: } ! 258: } ! 259: mdp->mba_cr = MBCR_INIT; ! 260: mdp->mba_cr = MBCR_IE; ! 261: } ! 262: ! 263: /* ! 264: * Have found a massbus device; ! 265: * see if it is in the configuration table. ! 266: * If so, fill in its data. ! 267: */ ! 268: struct mba_device * ! 269: mbaconfig(ni, type) ! 270: register struct mba_device *ni; ! 271: register int type; ! 272: { ! 273: register struct mba_device *mi; ! 274: register short *tp; ! 275: register struct mba_hd *mh; ! 276: ! 277: for (mi = mbdinit; mi->mi_driver; mi++) { ! 278: if (mi->mi_alive) ! 279: continue; ! 280: tp = mi->mi_driver->md_type; ! 281: for (mi->mi_type = 0; *tp; tp++, mi->mi_type++) ! 282: if (*tp == (type&MBDT_TYPE)) ! 283: goto found; ! 284: continue; ! 285: found: ! 286: #define match(fld) (ni->fld == mi->fld || mi->fld == '?') ! 287: if (!match(mi_drive) || !match(mi_mbanum)) ! 288: continue; ! 289: printf("%s%d at mba%d drive %d", ! 290: mi->mi_driver->md_dname, mi->mi_unit, ! 291: ni->mi_mbanum, ni->mi_drive); ! 292: printf("\n"); ! 293: mi->mi_alive = 1; ! 294: mh = &mba_hd[ni->mi_mbanum]; ! 295: mi->mi_hd = mh; ! 296: mh->mh_mbip[ni->mi_drive] = mi; ! 297: mh->mh_ndrive++; ! 298: mi->mi_mba = ni->mi_mba; ! 299: mi->mi_drv = &mi->mi_mba->mba_drv[ni->mi_drive]; ! 300: mi->mi_driver->md_info[mi->mi_unit] = mi; ! 301: mi->mi_mbanum = ni->mi_mbanum; ! 302: mi->mi_drive = ni->mi_drive; ! 303: if (mi->mi_dk && dkn < DK_NDRIVE) ! 304: mi->mi_dk = dkn++; ! 305: else ! 306: mi->mi_dk = -1; ! 307: (*mi->mi_driver->md_attach)(mi); ! 308: return (mi); ! 309: } ! 310: return (0); ! 311: } ! 312: #endif ! 313: ! 314: /* ! 315: * Fixctlrmask fixes the masks of the driver ctlr routines ! 316: * which otherwise save r10 and r11 where the interrupt and br ! 317: * level are passed through. ! 318: */ ! 319: fixctlrmask() ! 320: { ! 321: register struct uba_ctlr *um; ! 322: register struct uba_device *ui; ! 323: register struct uba_driver *ud; ! 324: #define phys(a,b) ((b)(((int)(a))&0x7fffffff)) ! 325: ! 326: for (um = ubminit; ud = phys(um->um_driver, struct uba_driver *); um++) ! 327: *phys(ud->ud_probe, short *) &= ~0xc00; ! 328: for (ui = ubdinit; ud = phys(ui->ui_driver, struct uba_driver *); ui++) ! 329: *phys(ud->ud_probe, short *) &= ~0xc00; ! 330: } ! 331: ! 332: /* ! 333: * Find devices on a UNIBUS. ! 334: * Uses per-driver routine to set <br,cvec> into <r11,r10>, ! 335: * and then fills in the tables, with help from a per-driver ! 336: * slave initialization routine. ! 337: */ ! 338: unifind(vubp, pubp, vumem, pumem, memmap) ! 339: struct uba_regs *vubp, *pubp; ! 340: caddr_t vumem, pumem; ! 341: struct pte *memmap; ! 342: { ! 343: #ifndef lint ! 344: register int br, cvec; /* MUST BE r11, r10 */ ! 345: #else ! 346: /* ! 347: * Lint doesn't realize that these ! 348: * can be initialized asynchronously ! 349: * when devices interrupt. ! 350: */ ! 351: register int br = 0, cvec = 0; ! 352: #endif ! 353: register struct uba_device *ui; ! 354: register struct uba_ctlr *um; ! 355: u_short *reg, addr; ! 356: struct uba_hd *uhp; ! 357: struct uba_driver *udp; ! 358: int i, (**ivec)(), haveubasr = 0; ! 359: ! 360: /* ! 361: * Initialize the UNIBUS, by freeing the map ! 362: * registers and the buffered data path registers ! 363: */ ! 364: uhp = &uba_hd[numuba]; ! 365: uhp->uh_map = (struct map *)calloc(UAMSIZ * sizeof (struct map)); ! 366: #ifdef ETHERNET ! 367: rminit(uhp->uh_map, NUBMREG-64, 1, "uba", UAMSIZ); ! 368: #endif ETHERNET ! 369: rminit(uhp->uh_map, NUBMREG, 1, "uba", UAMSIZ); ! 370: switch (cpu) { ! 371: #if VAX780 ! 372: case VAX_780: ! 373: uhp->uh_bdpfree = (1<<NBDP780) - 1; ! 374: haveubasr = 1; ! 375: break; ! 376: #endif ! 377: #if VAX750 ! 378: case VAX_750: ! 379: uhp->uh_bdpfree = (1<<NBDP750) - 1; ! 380: break; ! 381: #endif ! 382: #if VAX7ZZ ! 383: case VAX_7ZZ: ! 384: break; ! 385: #endif ! 386: } ! 387: ! 388: /* ! 389: * Save virtual and physical addresses ! 390: * of adaptor, and allocate and initialize ! 391: * the UNIBUS interrupt vector. ! 392: */ ! 393: uhp->uh_uba = vubp; ! 394: uhp->uh_physuba = pubp; ! 395: /* HAVE TO DO SOMETHING SPECIAL FOR SECOND UNIBUS ON COMETS HERE */ ! 396: if (numuba == 0) ! 397: uhp->uh_vec = UNIvec; ! 398: else ! 399: uhp->uh_vec = (int(**)())calloc(512); ! 400: for (i = 0; i < 128; i++) ! 401: uhp->uh_vec[i] = ! 402: scbentry(&catcher[i*2], SCB_ISTACK); ! 403: /* ! 404: * Set last free interrupt vector for devices with ! 405: * programmable interrupt vectors. Use is to decrement ! 406: * this number and use result as interrupt vector. ! 407: */ ! 408: uhp->uh_lastiv = 0x200; ! 409: ! 410: /* THIS IS A CHEAT: USING THE FACT THAT UMEM and NEXI ARE SAME SIZE */ ! 411: nxaccess((struct nexus *)pumem, memmap); ! 412: #ifdef ETHERNET ! 413: if(numuba == 0) { /*****EC ON UBA0 ONLY!!!*****/ ! 414: extern struct pte ECmap[]; ! 415: ecaccess((struct nexus *)(pumem-(24*1024)), ECmap); ! 416: } ! 417: #endif ETHERNET ! 418: #if VAX780 ! 419: if (haveubasr) { ! 420: vubp->uba_sr = vubp->uba_sr; ! 421: vubp->uba_cr = UBACR_IFS|UBACR_BRIE; ! 422: } ! 423: #endif ! 424: ! 425: /* ! 426: * Map the first page of UNIBUS i/o ! 427: * space to the first page of memory ! 428: * for devices which will need to dma ! 429: * output to produce an interrupt. ! 430: */ ! 431: *(int *)(&vubp->uba_map[0]) = UBAMR_MRV; ! 432: ! 433: #define ubaddr(off) (u_short *)((int)vumem + ((off)&0x1fff)) ! 434: /* ! 435: * Check each unibus mass storage controller. ! 436: * For each one which is potentially on this uba, ! 437: * see if it is really there, and if it is record it and ! 438: * then go looking for slaves. ! 439: */ ! 440: for (um = ubminit; udp = um->um_driver; um++) { ! 441: if (um->um_ubanum != numuba && um->um_ubanum != '?') ! 442: continue; ! 443: addr = (u_short)um->um_addr; ! 444: reg = ubaddr(addr); ! 445: if (badaddr((caddr_t)reg, 2)) { ! 446: printf("uba%d %s%d badaddr\n", numuba, udp->ud_mname, ! 447: um->um_ctlr); ! 448: continue; ! 449: } ! 450: #if VAX780 ! 451: if (haveubasr && vubp->uba_sr) { ! 452: vubp->uba_sr = vubp->uba_sr; ! 453: continue; ! 454: } ! 455: #endif ! 456: cvec = 0x200; ! 457: i = (*udp->ud_probe)(reg, um->um_ctlr); ! 458: #ifdef CHAOS ! 459: /* ! 460: ** Since the cold-boot-time stray interrupt catcher in ! 461: ** locore.s leaves the processor at the priority level ! 462: ** of the interrupt (yes, even after the rei), we must ! 463: ** restore it here. ! 464: */ ! 465: (void) spl0(); ! 466: #endif CHAOS ! 467: #if VAX780 ! 468: if (haveubasr && vubp->uba_sr) { ! 469: vubp->uba_sr = vubp->uba_sr; ! 470: continue; ! 471: } ! 472: #endif ! 473: if (i == 0) ! 474: continue; ! 475: printf("%s%d uba%d csr %o ", ! 476: udp->ud_mname, um->um_ctlr, numuba, addr); ! 477: if (cvec == 0) { ! 478: printf("zero vector\n"); ! 479: continue; ! 480: } ! 481: if (cvec == 0x200) { ! 482: printf("didn't interrupt\n"); ! 483: continue; ! 484: } ! 485: printf("vec 0%o ipl x%x\n", cvec, br); ! 486: um->um_alive = 1; ! 487: um->um_ubanum = numuba; ! 488: um->um_hd = &uba_hd[numuba]; ! 489: um->um_addr = (caddr_t)reg; ! 490: udp->ud_minfo[um->um_ctlr] = um; ! 491: for (ivec = um->um_intr; *ivec; ivec++) { ! 492: um->um_hd->uh_vec[cvec/4] = ! 493: scbentry(*ivec, SCB_ISTACK); ! 494: cvec += 4; ! 495: } ! 496: for (ui = ubdinit; ui->ui_driver; ui++) { ! 497: if (ui->ui_driver != udp || ui->ui_alive || ! 498: ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' || ! 499: ui->ui_ubanum != numuba && ui->ui_ubanum != '?') ! 500: continue; ! 501: if ((*udp->ud_slave)(ui, reg)) { ! 502: ui->ui_alive = 1; ! 503: ui->ui_ctlr = um->um_ctlr; ! 504: ui->ui_ubanum = numuba; ! 505: ui->ui_hd = &uba_hd[numuba]; ! 506: ui->ui_addr = (caddr_t)reg; ! 507: ui->ui_physaddr = pumem + (addr&0x1fff); ! 508: if (ui->ui_dk && dkn < DK_NDRIVE) ! 509: ui->ui_dk = dkn++; ! 510: else ! 511: ui->ui_dk = -1; ! 512: ui->ui_mi = um; ! 513: /* ui_type comes from driver */ ! 514: udp->ud_dinfo[ui->ui_unit] = ui; ! 515: printf("%s%d at %s%d sl%d ", ! 516: udp->ud_dname, ui->ui_unit, ! 517: udp->ud_mname, um->um_ctlr, ui->ui_slave); ! 518: (*udp->ud_attach)(ui); ! 519: } ! 520: } ! 521: } ! 522: /* ! 523: * Now look for non-mass storage peripherals. ! 524: */ ! 525: for (ui = ubdinit; udp = ui->ui_driver; ui++) { ! 526: if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' || ! 527: ui->ui_alive || ui->ui_slave != -1) ! 528: continue; ! 529: addr = (u_short)ui->ui_addr; ! 530: reg = ubaddr(addr); ! 531: if (badaddr((caddr_t)reg, 2)) { ! 532: printf("%s%d not found at uba%d csr %o\n", ! 533: ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr); ! 534: continue; ! 535: } ! 536: #if VAX780 ! 537: if (haveubasr && vubp->uba_sr) { ! 538: vubp->uba_sr = vubp->uba_sr; ! 539: continue; ! 540: } ! 541: #endif ! 542: cvec = 0x200; ! 543: i = (*udp->ud_probe)(reg, um->um_ctlr); ! 544: #ifdef CHAOS ! 545: /* ! 546: ** Since the cold-boot-time stray interrupt catcher in ! 547: ** locore.s leaves the processor at the priority level ! 548: ** of the interrupt (yes, even after the rei), we must ! 549: ** restore it here. ! 550: */ ! 551: (void) spl0(); ! 552: #endif CHAOS ! 553: #if VAX780 ! 554: if (haveubasr && vubp->uba_sr) { ! 555: vubp->uba_sr = vubp->uba_sr; ! 556: continue; ! 557: } ! 558: #endif ! 559: if (i == 0) ! 560: continue; ! 561: printf("%s%d at uba%d csr %o ", ! 562: ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr); ! 563: if (cvec == 0) { ! 564: printf("zero vector\n"); ! 565: continue; ! 566: } ! 567: if (cvec == 0x200) { ! 568: printf("didn't interrupt\n"); ! 569: continue; ! 570: } ! 571: printf("vec 0%o ipl x%x\n", cvec, br); ! 572: ui->ui_hd = &uba_hd[numuba]; ! 573: for (ivec = ui->ui_intr; *ivec; ivec++) { ! 574: ui->ui_hd->uh_vec[cvec/4] = ! 575: scbentry(*ivec, SCB_ISTACK); ! 576: cvec += 4; ! 577: } ! 578: ui->ui_alive = 1; ! 579: ui->ui_ubanum = numuba; ! 580: ui->ui_addr = (caddr_t)reg; ! 581: ui->ui_physaddr = pumem + (addr&0x1fff); ! 582: ui->ui_dk = -1; ! 583: /* ui_type comes from driver */ ! 584: udp->ud_dinfo[ui->ui_unit] = ui; ! 585: (*udp->ud_attach)(ui); ! 586: } ! 587: } ! 588: ! 589: setscbnex(fn) ! 590: int (*fn)(); ! 591: { ! 592: register struct scb *scbp = &scb; ! 593: ! 594: scbp->scb_ipl14[nexnum] = scbp->scb_ipl15[nexnum] = ! 595: scbp->scb_ipl16[nexnum] = scbp->scb_ipl17[nexnum] = ! 596: scbentry(fn, SCB_ISTACK); ! 597: } ! 598: ! 599: /* ! 600: * Make a nexus accessible at physical address phys ! 601: * by mapping kernel ptes starting at pte. ! 602: * ! 603: * WE LEAVE ALL NEXI MAPPED; THIS IS PERHAPS UNWISE ! 604: * SINCE MISSING NEXI DONT RESPOND. BUT THEN AGAIN ! 605: * PRESENT NEXI DONT RESPOND TO ALL OF THEIR ADDRESS SPACE. ! 606: */ ! 607: nxaccess(physa, pte) ! 608: struct nexus *physa; ! 609: register struct pte *pte; ! 610: { ! 611: register int i = btop(sizeof (struct nexus)); ! 612: register unsigned v = btop(physa); ! 613: ! 614: do ! 615: *(int *)pte++ = PG_V|PG_KW|v++; ! 616: while (--i > 0); ! 617: mtpr(TBIA, 0); ! 618: } ! 619: #ifdef ETHERNET ! 620: ecaccess(physa, pte) ! 621: struct nexus *physa; ! 622: register struct pte *pte; ! 623: { ! 624: register int i = 64; ! 625: register unsigned v = btop(physa); ! 626: ! 627: do ! 628: *(int *)pte++ = PG_V | PG_KW | v++; ! 629: while(--i); ! 630: } ! 631: #endif ETHERNET
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.