📄 autoconf.c
字号:
* 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. * When that happens we should add a new field to cpusw for it. */ KM_ALLOC(ualloc, caddr_t, DEVSPACESIZE, KM_TEMP, KM_CLEAR | KM_NOWAIT); if (ualloc == (caddr_t)0) panic("no mem for unifind"); /* * Map the first page of BUS i/o space to the first page of memory * for devices which will need to dma output to produce an interrupt. */ if( cpu != MVAX_I ) { KM_ALLOC(tempio, caddr_t, 1024, KM_TEMP, KM_CLEAR | KM_NOWAIT); if(tempio == (caddr_t)0 ) panic("no mem for probe i/o"); if( (ubinfo = uballoc( numuba, tempio, 1024, 0)) & 0x3ffff ) panic("probe i/o space not at bus virtual address 0"); }#define ubaoff(off) ((off)&0x1fff)#define ubaddr(off) (u_short *)((int)vumem + umemsize +(ubaoff(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 (uhp->uba_type&UBABLA) { if (um->um_ubanum != numuba || um->um_alive) continue; } else if (um->um_ubanum != numuba && um->um_ubanum != '?'|| um->um_alive) continue; addr = (u_short)um->um_addr; /* check for VAXSTAR driver (allow 18 bits addr) */ if (((int)um->um_addr) & 0xfffc0000) continue; /* * 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 (uhp->uba_type&(UBABDA|UBAXMI)) if (addr>0x0ff) continue; /* clear uba csr */ if (haveubasr) ubacsrcheck(vubp,uhp); if (ualloc[ubaoff(addr)]) continue; reg = ubaddr(addr); if (BADADDR((caddr_t)reg, 2)) continue; if (haveubasr && ubacsrcheck(vubp,uhp)) continue; cvec = 0x200; i = (*udp->ud_probe)(reg, um->um_ctlr); if (haveubasr && ubacsrcheck(vubp,uhp)) continue; if (i == 0) continue; um->um_ubanum = numuba; um->um_adpt = adpt_num; um->um_nexus = nexus_num; config_fillin(um); printf(" csr %o ",addr); if (cvec == 0) { printf("zero vector\n"); continue; } if (cvec == 0x200) { printf("didn't interrupt\n"); continue; } while (--i >= 0) ualloc[ubaoff(addr+i)] = 1; printf("vec %o, ipl %x\n", cvec, br); um->um_alive = 1; um->um_hd = &uba_hd[numuba]; um->um_addr = (caddr_t)reg; um->um_physaddr = (char *)svtophy(um->um_addr); udp->ud_minfo[um->um_ctlr] = um; for (ivec = um->um_intr; *ivec; ivec++) { um->um_hd->uh_vec[cvec/4] = scbentry(*ivec, SCB_ISTACK); cvec += 4; } for (ui = ubdinit; ui->ui_driver; ui++) { 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; savectlr = ui->ui_ctlr; ui->ui_ctlr = um->um_ctlr; if ((*udp->ud_slave)(ui, reg)) { ui->ui_alive = 1; ui->ui_ctlr = um->um_ctlr; ui->ui_ubanum = numuba; ui->ui_adpt = adpt_num; ui->ui_nexus = nexus_num; ui->ui_hd = &uba_hd[numuba]; ui->ui_addr = (caddr_t)reg; ui->ui_physaddr = pdevaddr + ubaoff(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\n", ui->ui_devname, ui->ui_unit, udp->ud_mname, um->um_ctlr, ui->ui_slave); (*udp->ud_attach)(ui); } else ui->ui_ctlr = savectlr; } break; } } if ((uhp->uba_type &(UBABDA|UBABLA|UBAXMI)) == 0) /* * 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; /* check for VAXSTAR driver (allow 18 bits addr) */ if (((int)ui->ui_addr) & 0xfffc0000) continue; for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) { if (haveubasr) ubacsrcheck(vubp,uhp);; if (ualloc[ubaoff(addr)]) continue; reg = ubaddr(addr); if (BADADDR((caddr_t)reg, 2)) continue; if (haveubasr && ubacsrcheck(vubp,uhp)) continue; cvec = 0x200; i = (*udp->ud_probe)(reg); if (haveubasr && ubacsrcheck(vubp,uhp)) continue; if (i == 0) continue; ui->ui_adpt = adpt_num; ui->ui_nexus = nexus_num; ui->ui_ubanum = numuba; config_fillin(ui); printf(" csr %o ", addr); if (cvec == 0) { printf("zero vector\n"); continue; } if (cvec == 0x200) { printf("didn't interrupt\n"); continue; } printf("vec %o, ipl %x\n", cvec, br); while (--i >= 0) ualloc[ubaoff(addr+i)] = 1; ui->ui_hd = &uba_hd[numuba]; for (ivec = ui->ui_intr; *ivec; ivec++) { ui->ui_hd->uh_vec[cvec/4] = scbentry(*ivec, SCB_ISTACK); cvec += 4; } ui->ui_alive = 1; ui->ui_addr = (caddr_t)reg; ui->ui_physaddr = pdevaddr + ubaoff(addr); ui->ui_dk = -1; /* ui_type comes from driver */ udp->ud_dinfo[ui->ui_unit] = ui; (*udp->ud_attach)(ui); break; } }#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 resources. We free the bus map register but it's unlikely * that it will ever be used again due to the fact that it only * maps two pages. */ KM_FREE(ualloc, KM_TEMP); if( cpu != MVAX_I ){ KM_FREE(tempio, KM_TEMP); ubarelse(numuba, &ubinfo); }}setscbnex(fn,nexnum) int (*fn)(); int nexnum;{ register struct scb *scbp = &scb; register num = nexnum % 16; scbp = (struct scb *) ((int)scbp + (0x200 * ioanum)); scbp->scb_ipl14[num] = scbp->scb_ipl15[num] = scbp->scb_ipl16[num] = scbp->scb_ipl17[num] = scbentry(fn, SCB_ISTACK);}/* * Make a nexus accessible at physical address phys * by mapping kernel ptes starting at pte. * * WE LEAVE ALL NEXI MAPPED; THIS IS PERHAPS UNWISE * SINCE MISSING NEXI DONT RESPOND. BUT THEN AGAIN * PRESENT NEXI DONT RESPOND TO ALL OF THEIR ADDRESS SPACE. */nxaccess(physa, pte, nexsize) struct nexus *physa; register struct pte *pte; int nexsize;{ register int i = btop(nexsize); register unsigned v = btop(physa); do *(int *)pte++ = PG_V|PG_KW|v++; while (--i > 0); mtpr(TBIA, 0);}ubaaccess(pumem, pte, umemsize, mode) caddr_t pumem; register struct pte *pte; int umemsize; unsigned int mode;{ register int i = btop(umemsize); register unsigned v = btop(pumem); do *(int *)pte++ = mode|v++; while (--i > 0); mtpr(TBIA, 0);}extern struct config_adpt config_adpt[];struct config_adpt *ni_port_adpt;config_fillin(um) register struct uba_ctlr *um;{ register struct config_adpt *aptr; register int bitype = 0; register int xmitype = 0; for( aptr = &config_adpt[0]; aptr->p_name; aptr++) { if (aptr->c_name == ((char *)um->um_driver) && um->um_ctlr == aptr->c_num && ((aptr->c_type == 'C') || (aptr->c_type == 'D'))) { aptr->c_ptr = (caddr_t) um; /* if conected to NEXUS...done */ if (strcmp(aptr->p_name,"nexus") == 0) return; if (strcmp(aptr->p_name,"ibus") == 0) { aptr->p_num = um->um_adpt; } if (strcmp(aptr->p_name,"vaxbi") == 0) { aptr->p_num = um->um_adpt; bitype = 1; } if (strcmp(aptr->p_name,"xmi") == 0) { aptr->p_num = um->um_adpt; xmitype = 1; } if (strcmp(aptr->p_name,"uba") == 0) { aptr->p_num = um->um_ubanum; } if (strcmp(aptr->p_name,"aie") == 0) { ni_port_adpt = aptr; } config_find_adpt(aptr,um); printf("%s%d at %s%d", um->um_ctlrname, aptr->c_num, aptr->p_name, aptr->p_num); if (bitype|xmitype) printf(" node %d",um->um_nexus); } }}is_adapt_configured(name, number)char *name;int number;{ register struct config_adpt *p_adpt; for( p_adpt = &config_adpt[0]; p_adpt->p_name; p_adpt++) { if ((strcmp(p_adpt->c_name,name) == 0) && (p_adpt->c_num == number)) { return(1); } } return(0);}config_set_alive(name, number, busnum, nexusnum)char *name;int number;int busnum;int nexusnum;{ register struct config_adpt *p_adpt; for( p_adpt = &config_adpt[0]; p_adpt->p_name; p_adpt++) { if ((strcmp(p_adpt->c_name,name) == 0) && (p_adpt->c_num == number)) { p_adpt->c_ptr = (caddr_t) CONFIG_ALIVE; p_adpt->c_bus_num = busnum; p_adpt->c_nexus_num = nexusnum; return; } }}config_find_adpt(c_adpt,um) register struct uba_ctlr *um;register struct config_adpt *c_adpt;{ register struct config_adpt *p_adpt; register int bitype = 0; register int xmitype = 0; for( p_adpt = &config_adpt[0]; p_adpt->p_name; p_adpt++) { if (p_adpt->c_type == 'A' && (strcmp(p_adpt->c_name,c_adpt->p_name) == 0) && (p_adpt->c_num == c_adpt->p_num)) { /* if conected to NEXUS...done */ if ((strcmp(p_adpt->p_name,"nexus") == 0) || (strcmp(p_adpt->c_name,"uba") == 0)) return; if (strcmp(p_adpt->p_name,"uba") == 0) { p_adpt->p_num = um->um_ubanum; } if (strcmp(p_adpt->p_name,"vaxbi") == 0) { bitype = 1; p_adpt->p_num = um->um_adpt; } if (strcmp(p_adpt->p_name,"xmi") == 0) { xmitype = 1; p_adpt->p_num = um->um_adpt; } if (strcmp(p_adpt->p_name,"ibus") == 0) { p_adpt->p_num = um->um_adpt; } config_find_adpt(p_adpt,um); if (!(p_adpt->c_ptr)) { p_adpt->c_ptr = (caddr_t) CONFIG_ALIVE; printf("%s%d at %s%d", p_adpt->c_name, p_adpt->c_num, p_adpt->p_name, p_adpt->p_num); if (bitype|xmitype) printf(" node %d \n",um->um_nexus); else printf("\n"); } return; } } } strcmp(s,t) register char *s, *t;{ while (*s == *t++) { if (*s++ == '\0'){ return(0); } } return(1);}/* this routine matches a um or ui structure with the proper adapter structure and returns whether it is alive or not. This routine is called by both BI and XMI */is_adapt_alive(um) register struct uba_ctlr *um;{ register struct config_adpt *aptr; register int bitype = 0; register struct config_adpt *p_adpt; for( aptr = &config_adpt[0]; aptr->p_name; aptr++) { if (aptr->c_name == ((char *)um->um_driver) && um->um_ctlr == aptr->c_num && ((aptr->c_type == 'C') || (aptr->c_type == 'D'))) { if (strcmp(aptr->p_name,"aie")==0) { for(p_adpt = &config_adpt[0]; p_adpt->p_name; p_adpt++) { if (p_adpt->c_type == 'A' && (strcmp(p_adpt->c_name,aptr->p_name) == 0) && (p_adpt->c_num == aptr->p_num)) { if (p_adpt->c_ptr) return(1); else return(0); } } } else { if (aptr->c_ptr) return(1); else return(0); } } } return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -