?? autoconf.c
字號:
uhp->uh_map = (struct map *) malloc((u_long)(UAMSIZ * sizeof (struct map)), M_DEVBUF, M_NOWAIT); if (uhp->uh_map == 0) panic("no mem for unibus map"); bzero((caddr_t)uhp->uh_map, (unsigned)(UAMSIZ * sizeof (struct map))); ubainitmaps(uhp); /* * Initialize space for the UNIBUS interrupt vectors. * On the 8600, can't use first slot in UNIvec * (the vectors for the second SBI overlap it); * move each set of vectors forward. */#if VAX8600 if (cpu == VAX_8600) uhp->uh_vec = UNIvec[numuba + 1]; else#endif uhp->uh_vec = UNIvec[numuba]; for (i = 0; i < 128; i++) uhp->uh_vec[i] = scbentry(&catcher[i], SCB_ISTACK); /* * Set last free interrupt vector for devices with * programmable interrupt vectors. Use is to decrement * this number and use result as interrupt vector. */ uhp->uh_lastiv = 0x200;#ifdef DWBUA if (uhp->uh_type == DWBUA) BUA(vubp)->bua_offset = (int)uhp->uh_vec - (int)&scb[0];#endif#ifdef DW780 if (uhp->uh_type == DW780) { vubp->uba_sr = vubp->uba_sr; vubp->uba_cr = UBACR_IFS|UBACR_BRIE; }#endif /* * First configure devices that have unibus memory, * allowing them to allocate the correct map registers. */ ubameminit(numuba); /* * Grab some memory to record the umem address space we allocate, * so we can be sure not to place two devices at the same address. * * We could use just 1/8 of this (we only want a 1 bit flag) but * we are going to give it back anyway, and that would make the * code here bigger (which we can't give back), so ... * * One day, someone will make a unibus with something other than * an 8K i/o address space, & screw this totally. */ ualloc = (caddr_t)malloc((u_long)(8 * 1024), M_TEMP, M_NOWAIT); if (ualloc == (caddr_t)0) panic("no mem for unifind"); bzero(ualloc, 8*1024); /* * Map the first page of UNIBUS i/o * space to the first page of memory * for devices which will need to dma * output to produce an interrupt. */ *(int *)(&uhp->uh_mr[0]) = UBAMR_MRV;#define ubaddr(uhp, off) (u_short *)((int)(uhp)->uh_iopage + ubdevreg(off)) /* * Check each unibus mass storage controller. * For each one which is potentially on this uba, * see if it is really there, and if it is record it and * then go looking for slaves. */ for (um = ubminit; udp = um->um_driver; um++) { if (um->um_ubanum != numuba && um->um_ubanum != '?' || um->um_alive) continue; addr = (u_short)um->um_addr; /* * use the particular address specified first, * or if it is given as "0", of there is no device * at that address, try all the standard addresses * in the driver til we find it */ for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) { if (ualloc[ubdevreg(addr)]) continue; reg = ubaddr(uhp, addr); if (badaddr((caddr_t)reg, 2)) continue;#ifdef DW780 if (uhp->uh_type == DW780 && vubp->uba_sr) { vubp->uba_sr = vubp->uba_sr; continue; }#endif cvec = 0x200; rcvec = 0x200; i = (*udp->ud_probe)(reg, um->um_ctlr, um);#ifdef DW780 if (uhp->uh_type == DW780 && vubp->uba_sr) { vubp->uba_sr = vubp->uba_sr; continue; }#endif if (i == 0) continue; printf("%s%d at uba%d csr %o ", udp->ud_mname, um->um_ctlr, numuba, addr); if (rcvec == 0) { printf("zero vector\n"); continue; } if (rcvec == 0x200) { printf("didn't interrupt\n"); continue; } printf("vec %o, ipl %x\n", rcvec, rbr); csralloc(ualloc, addr, i); um->um_alive = 1; um->um_ubanum = numuba; um->um_hd = uhp; um->um_addr = (caddr_t)reg; udp->ud_minfo[um->um_ctlr] = um; for (rcvec /= 4, ivec = um->um_intr; *ivec; rcvec++, ivec++) uhp->uh_vec[rcvec] = scbentry(*ivec, SCB_ISTACK); for (ui = ubdinit; ui->ui_driver; ui++) { int t; if (ui->ui_driver != udp || ui->ui_alive || ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' || ui->ui_ubanum != numuba && ui->ui_ubanum != '?') continue; t = ui->ui_ctlr; ui->ui_ctlr = um->um_ctlr; if ((*udp->ud_slave)(ui, reg) == 0) ui->ui_ctlr = t; else { ui->ui_alive = 1; ui->ui_ubanum = numuba; ui->ui_hd = uhp; ui->ui_addr = (caddr_t)reg; ui->ui_physaddr = pumem + ubdevreg(addr); if (ui->ui_dk && dkn < DK_NDRIVE) ui->ui_dk = dkn++; else ui->ui_dk = -1; ui->ui_mi = um; /* ui_type comes from driver */ udp->ud_dinfo[ui->ui_unit] = ui; printf("%s%d at %s%d slave %d", udp->ud_dname, ui->ui_unit, udp->ud_mname, um->um_ctlr, ui->ui_slave); (*udp->ud_attach)(ui); printf("\n"); } } break; } } /* * Now look for non-mass storage peripherals. */ for (ui = ubdinit; udp = ui->ui_driver; ui++) { if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' || ui->ui_alive || ui->ui_slave != -1) continue; addr = (u_short)ui->ui_addr; for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) { if (ualloc[ubdevreg(addr)]) continue; reg = ubaddr(uhp, addr); if (badaddr((caddr_t)reg, 2)) continue;#ifdef DW780 if (uhp->uh_type == DW780 && vubp->uba_sr) { vubp->uba_sr = vubp->uba_sr; continue; }#endif rcvec = 0x200; cvec = 0x200; i = (*udp->ud_probe)(reg, ui);#ifdef DW780 if (uhp->uh_type == DW780 && vubp->uba_sr) { vubp->uba_sr = vubp->uba_sr; continue; }#endif if (i == 0) continue; printf("%s%d at uba%d csr %o ", ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr); if (rcvec == 0) { printf("zero vector\n"); continue; } if (rcvec == 0x200) { printf("didn't interrupt\n"); continue; } printf("vec %o, ipl %x\n", rcvec, rbr); csralloc(ualloc, addr, i); ui->ui_hd = uhp; for (rcvec /= 4, ivec = ui->ui_intr; *ivec; rcvec++, ivec++) uhp->uh_vec[rcvec] = scbentry(*ivec, SCB_ISTACK); ui->ui_alive = 1; ui->ui_ubanum = numuba; ui->ui_addr = (caddr_t)reg; ui->ui_physaddr = pumem + ubdevreg(addr); ui->ui_dk = -1; /* ui_type comes from driver */ udp->ud_dinfo[ui->ui_unit] = ui; (*udp->ud_attach)(ui); break; } }#ifdef DW780 if (uhp->uh_type == DW780) uhp->uh_uba->uba_cr = UBACR_IFS | UBACR_BRIE | UBACR_USEFIE | UBACR_SUEFIE | (uhp->uh_uba->uba_cr & 0x7c000000);#endif numuba++;#ifdef AUTO_DEBUG printf("Unibus allocation map"); for (i = 0; i < 8*1024; ) { register n, m; if ((i % 128) == 0) { printf("\n%6o:", i); for (n = 0; n < 128; n++) if (ualloc[i+n]) break; if (n == 128) { i += 128; continue; } } for (n = m = 0; n < 16; n++) { m <<= 1; m |= ualloc[i++]; } printf(" %4x", m); } printf("\n");#endif free(ualloc, M_TEMP);}#endif /* NUBA *//* * Mark addresses starting at "addr" and continuing * "size" bytes as allocated in the map "ualloc". * Warn if the new allocation overlaps a previous allocation. */staticcsralloc(ualloc, addr, size) caddr_t ualloc; u_short addr; register int size;{ register caddr_t p; int warned = 0; p = &ualloc[ubdevreg(addr+size)]; while (--size >= 0) { if (*--p && !warned) { printf( "WARNING: device registers overlap those for a previous device!\n"); warned = 1; } *p = 1; }}/* * Make an IO register area accessible at physical address physa * by mapping kernel ptes starting at pte. */ioaccess(physa, pte, size) caddr_t physa; register struct pte *pte; int size;{ register int i = btoc(size); register unsigned v = btop(physa); do *(int *)pte++ = PG_V|PG_KW|v++; while (--i > 0); mtpr(TBIA, 0);}/* * Configure swap space and related parameters. */swapconf(){ register struct swdevt *swp; register int nblks; for (swp = swdevt; swp->sw_dev != NODEV; swp++) if (bdevsw[major(swp->sw_dev)].d_psize) { nblks = (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev); if (nblks != -1 && (swp->sw_nblks == 0 || swp->sw_nblks > nblks)) swp->sw_nblks = nblks; } dumpconf();}#define DOSWAP /* Change swdevt, argdev, and dumpdev too */u_long bootdev; /* should be dev_t, but not until 32 bits */static char devname[][2] = { 'h','p', /* 0 = hp */ 0,0, /* 1 = ht */ 'u','p', /* 2 = up */ 'r','k', /* 3 = hk */ 0,0, /* 4 = sw */ 0,0, /* 5 = tm */ 0,0, /* 6 = ts */ 0,0, /* 7 = mt */ 0,0, /* 8 = tu */ 'r','a', /* 9 = ra */ 0,0, /* 10 = ut */ 'r','b', /* 11 = rb */ 0,0, /* 12 = uu */ 0,0, /* 13 = rx */ 'r','l', /* 14 = rl */ 0,0, /* 15 = tmscp */ 'k','r', /* 16 = ra on kdb50 */};#define PARTITIONMASK 0x7#define PARTITIONSHIFT 3/* * Attempt to find the device from which we were booted. * If we can do so, and not instructed not to do so, * change rootdev to correspond to the load device. */setroot(){ int majdev, mindev, unit, part, controller, adaptor; dev_t temp, orootdev; struct swdevt *swp; if (boothowto & RB_DFLTROOT || (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) return; majdev = B_TYPE(bootdev); if (majdev >= sizeof(devname) / sizeof(devname[0])) return; adaptor = B_ADAPTOR(bootdev); controller = B_CONTROLLER(bootdev); part = B_PARTITION(bootdev); unit = B_UNIT(bootdev); if (majdev == 0) { /* MBA device */#if NMBA > 0 register struct mba_device *mbap; int mask;/* * The MBA number used at boot time is not necessarily the same as the * MBA number used by the kernel. In order to change the rootdev we need to * convert the boot MBA number to the kernel MBA number. The address space * for an MBA used by the boot code is 0x20010000 + 0x2000 * MBA_number * on the 78? and 86?0, 0xf28000 + 0x2000 * MBA_number on the 750. * Therefore we can search the mba_hd table for the MBA that has the physical * address corresponding to the boot MBA number. */#define PHYSADRSHFT 13#define PHYSMBAMASK780 0x7#define PHYSMBAMASK750 0x3 switch (cpu) { case VAX_780: case VAX_8600: default: mask = PHYSMBAMASK780; break; case VAX_750: mask = PHYSMBAMASK750; break; } for (mbap = mbdinit; mbap->mi_driver; mbap++) if (mbap->mi_alive && mbap->mi_drive == unit && (((long)mbap->mi_hd->mh_physmba >> PHYSADRSHFT) & mask) == adaptor) break; if (mbap->mi_driver == 0) return; mindev = mbap->mi_unit;#else return;#endif } else { register struct uba_device *ubap; for (ubap = ubdinit; ubap->ui_driver; ubap++) if (ubap->ui_alive && ubap->ui_slave == unit && ubap->ui_ctlr == controller && ubap->ui_ubanum == adaptor && ubap->ui_driver->ud_dname[0] == devname[majdev][0] && ubap->ui_driver->ud_dname[1] == devname[majdev][1]) break; if (ubap->ui_driver == 0) return; mindev = ubap->ui_unit; } mindev = (mindev << PARTITIONSHIFT) + part; orootdev = rootdev; rootdev = makedev(majdev, mindev); /* * If the original rootdev is the same as the one * just calculated, don't need to adjust the swap configuration. */ if (rootdev == orootdev) return; printf("Changing root device to %c%c%d%c\n", devname[majdev][0], devname[majdev][1], mindev >> PARTITIONSHIFT, part + 'a');#ifdef DOSWAP mindev &= ~PARTITIONMASK; for (swp = swdevt; swp->sw_dev != NODEV; swp++) { if (majdev == major(swp->sw_dev) && mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) { temp = swdevt[0].sw_dev; swdevt[0].sw_dev = swp->sw_dev; swp->sw_dev = temp; break; } } if (swp->sw_dev == NODEV) return; /* * If argdev and dumpdev were the same as the old primary swap * device, move them to the new primary swap device. */ if (temp == dumpdev) dumpdev = swdevt[0].sw_dev; if (temp == argdev) argdev = swdevt[0].sw_dev;#endif}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -