add 730
[unix-history] / usr / src / sys / vax / vax / autoconf.c
index 752cd41..8af2252 100644 (file)
@@ -1,7 +1,22 @@
-/*     autoconf.c      4.22    81/03/06        */
+/*     autoconf.c      4.29    81/03/21        */
 
 /*
 
 /*
- * Initialize the devices for the current machine.
+ * Setup the system to run on the current machine.
+ *
+ * Configure() is called at boot time and initializes the uba and mba
+ * device tables and the memory controller monitoring.  Available
+ * devices are determined (from possibilities mentioned in ioconf.c),
+ * and the drivers are initialized.
+ *
+ * N.B.: A lot of the conditionals based on processor type say
+ *     #if VAX780
+ * and
+ *     #if VAX750
+ * which may be incorrect after more processors are introduced if they
+ * are like either of these machines.
+ *
+ * TODO:
+ *     use pcpu info about whether a ubasr exists
  */
 
 #include "mba.h"
  */
 
 #include "mba.h"
 #include "../h/nexus.h"
 #include "../h/pte.h"
 #include "../h/buf.h"
 #include "../h/nexus.h"
 #include "../h/pte.h"
 #include "../h/buf.h"
-#include "../h/mba.h"
+#include "../h/mbareg.h"
+#include "../h/mbavar.h"
 #include "../h/dk.h"
 #include "../h/vm.h"
 #include "../h/dk.h"
 #include "../h/vm.h"
-#include "../h/uba.h"
+#include "../h/ubareg.h"
+#include "../h/ubavar.h"
 #include "../h/mtpr.h"
 #include "../h/cpu.h"
 #include "../h/scb.h"
 #include "../h/mem.h"
 
 #include "../h/mtpr.h"
 #include "../h/cpu.h"
 #include "../h/scb.h"
 #include "../h/mem.h"
 
-int    cold;
+/*
+ * The following several variables are related to
+ * the configuration process, and are used in initializing
+ * the machine.
+ */
+int    cold;           /* if 1, still working on cold-start */
 int    nexnum;         /* current nexus number */
 int    nexnum;         /* current nexus number */
-int    dkn;            /* number of dk numbers assigned so far */
+int    dkn;            /* number of iostat dk numbers assigned so far */
 
 
+/*
+ * Addresses of the (locore) routines which bootstrap us from
+ * hardware traps to C code.  Filled into the system control block
+ * as necessary.
+ */
 #if NMBA > 0
 int    (*mbaintv[4])() =       { Xmba0int, Xmba1int, Xmba2int, Xmba3int };
 #endif
 #if VAX780
 int    (*ubaintv[4])() =       { Xua0int, Xua1int, Xua2int, Xua3int };
 #if NMBA > 0
 int    (*mbaintv[4])() =       { Xmba0int, Xmba1int, Xmba2int, Xmba3int };
 #endif
 #if VAX780
 int    (*ubaintv[4])() =       { Xua0int, Xua1int, Xua2int, Xua3int };
-caddr_t        umaddr780[4] = {
-       (caddr_t) 0x2013e000, (caddr_t) 0x2017e000,
-       (caddr_t) 0x201be000, (caddr_t) 0x201fe000
-};
-#endif
-
-#if VAX780
-char   nexflt_bits[] = NEXFLT_BITS;
-#endif
-
-#if VAX780
-int    c780();
-#endif
-#if VAX750
-int    c750();
 #endif
 
 #endif
 
-struct percpu percpu[] = {
-#if VAX780
-       c780, VAX_780,
-#endif
-#if VAX750
-       c750, VAX_750,
-#endif
-};
-#define        NCPU    (sizeof(percpu)/sizeof(struct percpu))
+/*
+ * This allocates the space for the per-uba information,
+ * such as buffered data path usage.
+ */
+struct uba_hd uba_hd[MAXNUBA];
 
 /*
  * Determine mass storage and memory configuration for a machine.
 
 /*
  * Determine mass storage and memory configuration for a machine.
@@ -66,80 +74,93 @@ configure()
 {
        union cpusid cpusid;
        register struct percpu *ocp;
 {
        union cpusid cpusid;
        register struct percpu *ocp;
-       register int i, *ip;
+       register int *ip;
        extern char Sysbase[];
 
        cpusid.cpusid = mfpr(SID);
        extern char Sysbase[];
 
        cpusid.cpusid = mfpr(SID);
-       for (ocp = percpu; ocp < &percpu[NCPU]; ocp++)
+       for (ocp = percpu; ocp->pc_cputype; ocp++)
                if (ocp->pc_cputype == cpusid.cpuany.cp_type) {
                if (ocp->pc_cputype == cpusid.cpuany.cp_type) {
-                       (*ocp->pc_config)(ocp);
-#if VAXANY
-                       setconf();
-#endif
+                       probenexus(ocp);
+                       /*
+                        * Write protect the scb.  It is strange
+                        * that this code is here, but this is as soon
+                        * as we are done mucking with it, and the
+                        * write-enable was done in assembly language
+                        * to which we will never return.
+                        */
                        ip = (int *)Sysmap; *ip &= ~PG_PROT; *ip |= PG_KR;
                        mtpr(TBIS, Sysbase);
                        ip = (int *)Sysmap; *ip &= ~PG_PROT; *ip |= PG_KR;
                        mtpr(TBIS, Sysbase);
+#if GENERIC
+                       setconf();
+#endif
                        cold = 0;
                        memenable();
                        return;
                }
                        cold = 0;
                        memenable();
                        return;
                }
-       printf("cpu type %d unsupported\n", cpusid.cpuany.cp_type);
+       printf("cpu type %d not configured\n", cpusid.cpuany.cp_type);
        asm("halt");
 }
 
        asm("halt");
 }
 
-#if VAX780
 /*
 /*
- * Build configuration table for a 780, by looking
- * at the things (mbas and ubas) in the nexus slots
- * and initialzing each appropriately.
+ * Probe nexus space, finding the interconnects
+ * and setting up and probing mba's and uba's for devices.
  */
  */
-c780(pcpu)
+/*ARGSUSED*/
+probenexus(pcpu)
        register struct percpu *pcpu;
 {
        register struct nexus *nxv;
        register struct percpu *pcpu;
 {
        register struct nexus *nxv;
-       register struct uba_hd *uhp;
-       struct nexus *nxp = NEX780;
+       struct nexus *nxp = pcpu->pc_nexbase;
        union nexcsr nexcsr;
        union nexcsr nexcsr;
-       int i, ubawatch();
+       int i;
        
        
-       for (nexnum = 0,nxv = nexus; nexnum < NNEX780; nexnum++,nxp++,nxv++) {
-               nxaccess((caddr_t)nxp, Nexmap[nexnum]);
+       nexnum = 0, nxv = nexus;
+       for (; nexnum < pcpu->pc_nnexus; nexnum++, nxp++, nxv++) {
+               nxaccess(nxp, Nexmap[nexnum]);
                if (badaddr((caddr_t)nxv, 4))
                        continue;
                if (badaddr((caddr_t)nxv, 4))
                        continue;
-               nexcsr = nxv->nexcsr;
+               if (pcpu->pc_nextype && pcpu->pc_nextype[nexnum] != NEX_ANY)
+                       nexcsr.nex_csr = pcpu->pc_nextype[nexnum];
+               else
+                       nexcsr = nxv->nexcsr;
                if (nexcsr.nex_csr&NEX_APD)
                        continue;
                switch (nexcsr.nex_type) {
 
                case NEX_MBA:
                if (nexcsr.nex_csr&NEX_APD)
                        continue;
                switch (nexcsr.nex_type) {
 
                case NEX_MBA:
-#if NMBA > 0
                        printf("mba%d at tr%d\n", nummba, nexnum);
                        if (nummba >= NMBA) {
                        printf("mba%d at tr%d\n", nummba, nexnum);
                        if (nummba >= NMBA) {
-                               printf("%d mba's not configured\n", nummba+1);
-                               continue;
+                               printf("%d mba's", nummba);
+                               goto unconfig;
                        }
                        }
+#if NMBA > 0
                        mbafind(nxv, nxp);
                        nummba++;
                        mbafind(nxv, nxp);
                        nummba++;
-                       break;
-#else
-                       printf("mba's");
-                       goto unsupp;
 #endif
 #endif
+                       break;
 
                case NEX_UBA0:
                case NEX_UBA1:
                case NEX_UBA2:
                case NEX_UBA3:
 
                case NEX_UBA0:
                case NEX_UBA1:
                case NEX_UBA2:
                case NEX_UBA3:
+                       printf("uba%d at tr%d\n", numuba, nexnum);
                        if (numuba >= 4) {
                                printf("5 uba's");
                                goto unsupp;
                        }
                        if (numuba >= 4) {
                                printf("5 uba's");
                                goto unsupp;
                        }
-                       printf("uba%d at tr%d\n", numuba, nexnum);
-                       setscbnex(nexnum, ubaintv[numuba]);
+#if VAX780
+                       if (cpu == VAX_780)
+                               setscbnex(ubaintv[numuba]);
+#endif
                        i = nexcsr.nex_type - NEX_UBA0;
                        unifind((struct uba_regs *)nxv, (struct uba_regs *)nxp,
                        i = nexcsr.nex_type - NEX_UBA0;
                        unifind((struct uba_regs *)nxv, (struct uba_regs *)nxp,
-                           umem[i], umaddr780[i]);
-                       ((struct uba_regs *)nxv)->uba_cr =
-                           UBA_IFS|UBA_BRIE|UBA_USEFIE|UBA_SUEFIE;
+                           umem[i], pcpu->pc_umaddr[i]);
+#if VAX780
+                       if (cpu == VAX_780)
+                               ((struct uba_regs *)nxv)->uba_cr =
+                                   UBACR_IFS|UBACR_BRIE|
+                                   UBACR_USEFIE|UBACR_SUEFIE;
+#endif
                        numuba++;
                        break;
 
                        numuba++;
                        break;
 
@@ -152,11 +173,11 @@ c780(pcpu)
                case NEX_MEM4I:
                case NEX_MEM16:
                case NEX_MEM16I:
                case NEX_MEM4I:
                case NEX_MEM16:
                case NEX_MEM16I:
+                       printf("mcr%d at tr%d\n", nmcr, nexnum);
                        if (nmcr >= 4) {
                        if (nmcr >= 4) {
-                               printf("%d mcr's", 4);
+                               printf("5 mcr's");
                                goto unsupp;
                        }
                                goto unsupp;
                        }
-                       printf("mcr%d at tr%d\n", nmcr, nexnum);
                        mcraddr[nmcr++] = (struct mcr *)nxv;
                        break;
 
                        mcraddr[nmcr++] = (struct mcr *)nxv;
                        break;
 
@@ -172,49 +193,19 @@ c780(pcpu)
 unsupp:
                        printf(" unsupported (at tr %d)\n", nexnum);
                        continue;
 unsupp:
                        printf(" unsupported (at tr %d)\n", nexnum);
                        continue;
-               }
-       }
-       timeout(ubawatch, 0, hz);
-}
-#endif
-
-#if VAX750
-/*
- * Configure a 750.  There are four possible mba's,
- * one standard UNIBUS, and a memory controller.
- */
-c750(pcpu)
-       struct percpu *pcpu;
-{
-       register struct nexus *nxv = nexus;
-       struct nexus *nxp = NEX750;
-
-       printf("mcr at %x\n", MCR_750);
-       nxaccess((caddr_t)MCR_750, Nexmap[nexnum]);
-       mcraddr[nmcr++] = (struct mcr *)nxv;
-#if NMBA > 0
-       for (nexnum = 0; nexnum < NNEX750; nexnum++, nxp++, nxv++) {
-               nxaccess((caddr_t)nxp, Nexmap[nexnum]);
-               if (badaddr((caddr_t)nxv, 4))
+unconfig:
+                       printf(" not configured\n");
                        continue;
                        continue;
-               printf("mba%d at %x\n", nummba, nxp);
-               if (nummba >= NMBA)
-                       printf("%d mba's not configured\n", nummba+1);
-               else {
-                       mbafind(nxv, nxp);
-                       nummba++;
                }
        }
                }
        }
+#if VAX780
+       if (cpu == VAX_780)
+               { int ubawatch(); timeout(ubawatch, (caddr_t)0, hz); }
 #endif
 #endif
-       printf("uba at %x\n", nxp);
-       nxaccess((caddr_t)nxp, Nexmap[nexnum++]);
-       unifind((struct uba_regs *)nxv++, (struct uba_regs *)nxp,
-           umem[0], UMEM750);
-       numuba = 1;
 }
 }
-#endif
 
 #if NMBA > 0
 
 #if NMBA > 0
+struct mba_device *mbaconfig();
 /*
  * Find devices attached to a particular mba
  * and look for each device found in the massbus
 /*
  * Find devices attached to a particular mba
  * and look for each device found in the massbus
@@ -225,13 +216,15 @@ mbafind(nxv, nxp)
 {
        register struct mba_regs *mdp;
        register struct mba_drv *mbd;
 {
        register struct mba_regs *mdp;
        register struct mba_drv *mbd;
-       int dn, dt, sn, ds;
-       struct mba_info fnd;
+       register struct mba_device *mi;
+       register struct mba_slave *ms;
+       int dn, dt;
+       struct mba_device fnd;
 
        mdp = (struct mba_regs *)nxv;
        mba_hd[nummba].mh_mba = mdp;
        mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp;
 
        mdp = (struct mba_regs *)nxv;
        mba_hd[nummba].mh_mba = mdp;
        mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp;
-       setscbnex(nexnum, mbaintv[nummba]);
+       setscbnex(mbaintv[nummba]);
        fnd.mi_mba = mdp;
        fnd.mi_mbanum = nummba;
        for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) {
        fnd.mi_mba = mdp;
        fnd.mi_mbanum = nummba;
        for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) {
@@ -245,22 +238,29 @@ mbafind(nxv, nxp)
                if (dt == MBDT_MOH)
                        continue;
                fnd.mi_drive = dn;
                if (dt == MBDT_MOH)
                        continue;
                fnd.mi_drive = dn;
-               if (dt & MBDT_TAP) {
-                       for (sn = 0; sn < 8; sn++) {
-                               mbd->mbd_tc = sn;
+               if ((mi = mbaconfig(&fnd, dt)) && (dt & MBDT_TAP)) {
+                       for (ms = mbsinit; ms->ms_driver; ms++)
+                       if (ms->ms_driver == mi->mi_driver && ms->ms_alive == 0 && 
+                           (ms->ms_ctlr == mi->mi_unit || ms->ms_ctlr=='?')) {
+                               mbd->mbd_tc = ms->ms_slave;
                                dt = mbd->mbd_dt;
                                dt = mbd->mbd_dt;
-                               if ((dt & MBDT_SPR) == 0)
-                                       continue;
-                               fnd.mi_slave = sn;
-                               mbaconfig(&fnd, dt);
+                               if (dt & MBDT_SPR) {
+                                       printf("%s%d at %s%d slave %d\n",
+                                           ms->ms_driver->md_sname,
+                                           ms->ms_unit,
+                                           mi->mi_driver->md_dname,
+                                           mi->mi_unit,
+                                           ms->ms_slave);
+                                       ms->ms_alive = 1;
+                                       ms->ms_ctlr = mi->mi_unit;
+                                       (*ms->ms_driver->md_slave)
+                                           (mi, ms);
+                               }
                        }
                        }
-               } else {
-                       fnd.mi_slave = -1;
-                       mbaconfig(&fnd, dt);
                }
        }
                }
        }
-       mdp->mba_cr = MBAINIT;
-       mdp->mba_cr = MBAIE;
+       mdp->mba_cr = MBCR_INIT;
+       mdp->mba_cr = MBCR_IE;
 }
 
 /*
 }
 
 /*
@@ -268,15 +268,16 @@ mbafind(nxv, nxp)
  * see if it is in the configuration table.
  * If so, fill in its data.
  */
  * see if it is in the configuration table.
  * If so, fill in its data.
  */
+struct mba_device *
 mbaconfig(ni, type)
 mbaconfig(ni, type)
-       register struct mba_info *ni;
+       register struct mba_device *ni;
        register int type;
 {
        register int type;
 {
-       register struct mba_info *mi;
+       register struct mba_device *mi;
        register short *tp;
        register struct mba_hd *mh;
 
        register short *tp;
        register struct mba_hd *mh;
 
-       for (mi = mbinit; mi->mi_driver; mi++) {
+       for (mi = mbdinit; mi->mi_driver; mi++) {
                if (mi->mi_alive)
                        continue;
                tp = mi->mi_driver->md_type;
                if (mi->mi_alive)
                        continue;
                tp = mi->mi_driver->md_type;
@@ -286,12 +287,11 @@ mbaconfig(ni, type)
                continue;
 found:
 #define        match(fld)      (ni->fld == mi->fld || mi->fld == '?')
                continue;
 found:
 #define        match(fld)      (ni->fld == mi->fld || mi->fld == '?')
-               if (!match(mi_slave) || !match(mi_drive) || !match(mi_mbanum))
+               if (!match(mi_drive) || !match(mi_mbanum))
                        continue;
                        continue;
-               printf("%c%d at mba%d drive %d",
-                   mi->mi_name, mi->mi_unit, ni->mi_mbanum, ni->mi_drive);
-               if (type & MBDT_TAP)
-                       printf(" slave %d", ni->mi_slave);
+               printf("%s%d at mba%d drive %d",
+                   mi->mi_driver->md_dname, mi->mi_unit,
+                   ni->mi_mbanum, ni->mi_drive);
                printf("\n");
                mi->mi_alive = 1;
                mh = &mba_hd[ni->mi_mbanum];
                printf("\n");
                mi->mi_alive = 1;
                mh = &mba_hd[ni->mi_mbanum];
@@ -303,13 +303,14 @@ found:
                mi->mi_driver->md_info[mi->mi_unit] = mi;
                mi->mi_mbanum = ni->mi_mbanum;
                mi->mi_drive = ni->mi_drive;
                mi->mi_driver->md_info[mi->mi_unit] = mi;
                mi->mi_mbanum = ni->mi_mbanum;
                mi->mi_drive = ni->mi_drive;
-               mi->mi_slave = ni->mi_slave;
                if (mi->mi_dk && dkn < DK_NDRIVE)
                        mi->mi_dk = dkn++;
                else
                        mi->mi_dk = -1;
                if (mi->mi_dk && dkn < DK_NDRIVE)
                        mi->mi_dk = dkn++;
                else
                        mi->mi_dk = -1;
-               (*mi->mi_driver->md_dkinit)(mi);
+               (*mi->mi_driver->md_attach)(mi);
+               return (mi);
        }
        }
+       return (0);
 }
 #endif
 
 }
 #endif
 
@@ -320,8 +321,8 @@ found:
  */
 fixctlrmask()
 {
  */
 fixctlrmask()
 {
-       register struct uba_minfo *um;
-       register struct uba_dinfo *ui;
+       register struct uba_ctlr *um;
+       register struct uba_device *ui;
        register struct uba_driver *ud;
 #define        phys(a,b) ((b)(((int)(a))&0x7fffffff))
 
        register struct uba_driver *ud;
 #define        phys(a,b) ((b)(((int)(a))&0x7fffffff))
 
@@ -341,10 +342,19 @@ unifind(vubp, pubp, vumem, pumem)
        struct uba_regs *vubp, *pubp;
        caddr_t vumem, pumem;
 {
        struct uba_regs *vubp, *pubp;
        caddr_t vumem, pumem;
 {
+#ifndef lint
        register int br, cvec;                  /* MUST BE r11, r10 */
        register int br, cvec;                  /* MUST BE r11, r10 */
-       register struct uba_dinfo *ui;
-       register struct uba_minfo *um;
-       u_short *umem = (u_short *)vumem, *sp, *reg, addr;
+#else
+       /*
+        * Lint doesn't realize that these
+        * can be initialized asynchronously
+        * when devices interrupt.
+        */
+       register int br = 0, cvec = 0;
+#endif
+       register struct uba_device *ui;
+       register struct uba_ctlr *um;
+       u_short *reg, addr;
        struct uba_hd *uhp;
        struct uba_driver *udp;
        int i, (**ivec)(), haveubasr = 0;
        struct uba_hd *uhp;
        struct uba_driver *udp;
        int i, (**ivec)(), haveubasr = 0;
@@ -367,6 +377,10 @@ unifind(vubp, pubp, vumem, pumem)
        case VAX_750:
                uhp->uh_bdpfree = (1<<NBDP750) - 1;
                break;
        case VAX_750:
                uhp->uh_bdpfree = (1<<NBDP750) - 1;
                break;
+#endif
+#if VAX730
+       case VAX_730:
+               break;
 #endif
        }
 
 #endif
        }
 
@@ -377,6 +391,7 @@ unifind(vubp, pubp, vumem, pumem)
         */
        uhp->uh_uba = vubp;
        uhp->uh_physuba = pubp;
         */
        uhp->uh_uba = vubp;
        uhp->uh_physuba = pubp;
+/* HAVE TO DO SOMETHING SPECIAL FOR SECOND UNIBUS ON COMETS HERE */
        if (numuba == 0)
                uhp->uh_vec = UNIvec;
        else
        if (numuba == 0)
                uhp->uh_vec = UNIvec;
        else
@@ -384,11 +399,12 @@ unifind(vubp, pubp, vumem, pumem)
        for (i = 0; i < 128; i++)
                uhp->uh_vec[i] =
                    scbentry(&catcher[i*2], SCB_ISTACK);
        for (i = 0; i < 128; i++)
                uhp->uh_vec[i] =
                    scbentry(&catcher[i*2], SCB_ISTACK);
+       /* THIS IS A CHEAT: USING THE FACT THAT UMEM and NEXI ARE SAME SIZE */
        nxaccess((struct nexus *)pumem, UMEMmap[numuba]);
 #if VAX780
        if (haveubasr) {
                vubp->uba_sr = vubp->uba_sr;
        nxaccess((struct nexus *)pumem, UMEMmap[numuba]);
 #if VAX780
        if (haveubasr) {
                vubp->uba_sr = vubp->uba_sr;
-               vubp->uba_cr = UBA_IFS|UBA_BRIE;
+               vubp->uba_cr = UBACR_IFS|UBACR_BRIE;
        }
 #endif
        /*
        }
 #endif
        /*
@@ -397,7 +413,7 @@ unifind(vubp, pubp, vumem, pumem)
         * for devices which will need to dma
         * output to produce an interrupt.
         */
         * for devices which will need to dma
         * output to produce an interrupt.
         */
-       *(int *)(&vubp->uba_map[0]) = UBA_MRV;
+       *(int *)(&vubp->uba_map[0]) = UBAMR_MRV;
 
 #define        ubaddr(off)     (u_short *)((int)vumem + ((off)&0x1fff))
        /*
 
 #define        ubaddr(off)     (u_short *)((int)vumem + ((off)&0x1fff))
        /*
@@ -531,8 +547,8 @@ unifind(vubp, pubp, vumem, pumem)
        }
 }
 
        }
 }
 
-setscbnex(nexnum, fn)
-       int nexnum, (*fn)();
+setscbnex(fn)
+       int (*fn)();
 {
        register struct scb *scbp = &scb;
 
 {
        register struct scb *scbp = &scb;
 
@@ -550,14 +566,14 @@ setscbnex(nexnum, fn)
  * PRESENT NEXI DONT RESPOND TO ALL OF THEIR ADDRESS SPACE.
  */
 nxaccess(physa, pte)
  * PRESENT NEXI DONT RESPOND TO ALL OF THEIR ADDRESS SPACE.
  */
 nxaccess(physa, pte)
-       caddr_t physa;
+       struct nexus *physa;
        register struct pte *pte;
 {
        register struct pte *pte;
 {
-       register int cnt = btop(sizeof (struct nexus));
+       register int i = btop(sizeof (struct nexus));
        register unsigned v = btop(physa);
        
        do
                *(int *)pte++ = PG_V|PG_KW|v++;
        register unsigned v = btop(physa);
        
        do
                *(int *)pte++ = PG_V|PG_KW|v++;
-       while (--cnt > 0);
+       while (--i > 0);
        mtpr(TBIA, 0);
 }
        mtpr(TBIA, 0);
 }