|
|
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: * @(#)autoconf.c 7.1 (Berkeley) 6/6/86
7: */
8:
9: /*
10: * Setup the system to run on the current machine.
11: *
12: * Configure() is called at boot time and initializes the uba and mba
13: * device tables and the memory controller monitoring. Available
14: * devices are determined (from possibilities mentioned in ioconf.c),
15: * and the drivers are initialized.
16: */
17:
18: #include "mba.h"
19: #include "uba.h"
20:
21: #include "pte.h"
22:
23: #include "param.h"
24: #include "systm.h"
25: #include "map.h"
26: #include "buf.h"
27: #include "dk.h"
28: #include "vm.h"
29: #include "conf.h"
30: #include "dmap.h"
31: #include "reboot.h"
32:
33: #include "cpu.h"
34: #include "mem.h"
35: #include "mtpr.h"
36: #include "nexus.h"
37: #include "scb.h"
38: #include "ioa.h"
39: #include "../vaxmba/mbareg.h"
40: #include "../vaxmba/mbavar.h"
41: #include "../vaxuba/ubareg.h"
42: #include "../vaxuba/ubavar.h"
43:
44: /*
45: * The following several variables are related to
46: * the configuration process, and are used in initializing
47: * the machine.
48: */
49: int cold; /* if 1, still working on cold-start */
50: int nexnum; /* current nexus number */
51: int nsbi; /* current sbi number */
52: int dkn; /* number of iostat dk numbers assigned so far */
53: int cpuspeed = 1; /* relative cpu speed */
54:
55: /*
56: * Addresses of the (locore) routines which bootstrap us from
57: * hardware traps to C code. Filled into the system control block
58: * as necessary.
59: */
60: #if NMBA > 0
61: int (*mbaintv[4])() = { Xmba0int, Xmba1int, Xmba2int, Xmba3int };
62: #if NMBA > 4
63: Need to expand the table for more than 4 massbus adaptors
64: #endif
65: #endif
66: #if defined(VAX780) || defined(VAX8600)
67: int (*ubaintv[])() =
68: {
69: Xua0int, Xua1int, Xua2int, Xua3int,
70: #if NUBA > 4
71: Xua4int, Xua5int, Xua6int, Xua7int,
72: #endif
73: #if NUBA > 8
74: Need to expand the table for more than 8 unibus adaptors
75: #endif
76: };
77: #endif
78:
79: /*
80: * This allocates the space for the per-uba information,
81: * such as buffered data path usage.
82: */
83: struct uba_hd uba_hd[NUBA];
84:
85: /*
86: * Determine mass storage and memory configuration for a machine.
87: * Get cpu type, and then switch out to machine specific procedures
88: * which will probe adaptors to see what is out there.
89: */
90: configure()
91: {
92: union cpusid cpusid;
93: register struct percpu *ocp;
94: register int *ip;
95: extern char Sysbase[];
96:
97: cpusid.cpusid = mfpr(SID);
98: for (ocp = percpu; ocp->pc_cputype; ocp++)
99: if (ocp->pc_cputype == cpusid.cpuany.cp_type) {
100: cpuspeed = ocp->pc_cpuspeed;
101: probeio(ocp);
102: /*
103: * Write protect the scb and UNIBUS interrupt vectors.
104: * It is strange that this code is here, but this is
105: * as soon as we are done mucking with it, and the
106: * write-enable was done in assembly language
107: * to which we will never return.
108: */
109: ip = (int *)Sysmap + 1; *ip &= ~PG_PROT; *ip |= PG_KR;
110: ip++; *ip &= ~PG_PROT; *ip |= PG_KR;
111: #if NUBA > 1
112: ip++; *ip &= ~PG_PROT; *ip |= PG_KR;
113: #endif
114: mtpr(TBIS, Sysbase);
115: #if GENERIC
116: if ((boothowto & RB_ASKNAME) == 0)
117: setroot();
118: setconf();
119: #else
120: setroot();
121: #endif
122: /*
123: * Configure swap area and related system
124: * parameter based on device(s) used.
125: */
126: swapconf();
127: cold = 0;
128: memenable();
129: return;
130: }
131: printf("cpu type %d not configured\n", cpusid.cpuany.cp_type);
132: asm("halt");
133: }
134:
135: /*
136: * Probe the main IO bus(es).
137: * The percpu structure gives us a handle on the addresses and/or types.
138: */
139: probeio(pcpu)
140: register struct percpu *pcpu;
141: {
142: register struct iobus *iob;
143: int ioanum;
144:
145: ioanum = 0;
146: for (iob = pcpu->pc_io; ioanum < pcpu->pc_nioa; ioanum++, iob++) {
147:
148: switch (iob->io_type) {
149:
150: #if VAX780 || VAX750 || VAX730 || VAX630
151: case IO_SBI780:
152: case IO_CMI750:
153: case IO_XXX730:
154: case IO_QBUS:
155: probenexi((struct nexusconnect *)iob->io_details);
156: break;
157: #endif
158:
159: #if VAX8600
160: case IO_ABUS:
161: probe_Abus(ioanum, iob);
162: break;
163: #endif
164: default:
165: if (iob->io_addr) {
166: printf(
167: "IO adaptor %d, type %d, at address 0x%x is unsupported\n",
168: ioanum, iob->io_type, iob->io_addr);
169: } else
170: printf("IO adaptor %d, type %d, is unsupported\n",
171: ioanum, iob->io_type);
172: break;
173: }
174: }
175: }
176:
177: #if VAX8600
178: probe_Abus(ioanum, iob)
179: register struct iobus *iob;
180: {
181: register struct ioa *ioap;
182: union ioacsr ioacsr;
183: int type;
184: struct sbia_regs *sbiaregs;
185:
186: ioap = &ioa[ioanum];
187: ioaccess(iob->io_addr, Ioamap[ioanum], iob->io_size);
188: if (badaddr((caddr_t)ioap, 4))
189: return;
190: ioacsr.ioa_csr = ioap->ioacsr.ioa_csr;
191: type = ioacsr.ioa_type & IOA_TYPMSK;
192:
193: switch (type) {
194:
195: case IOA_SBIA:
196: printf("SBIA%d at IO adaptor %d address 0x%x\n",
197: nsbi, ioanum, iob->io_addr);
198: probenexi((struct nexusconnect *)iob->io_details);
199: nsbi++;
200: sbiaregs = (struct sbia_regs *)ioap;
201: sbiaregs->sbi_errsum = -1;
202: sbiaregs->sbi_error = 0x1000;
203: sbiaregs->sbi_fltsts = 0xc0000;
204: break;
205:
206: default:
207: printf("IOA%d at address 0x%x is unsupported (type = 0x%x)\n",
208: ioanum, iob->io_addr, ioacsr.ioa_type);
209: break;
210: }
211: }
212: #endif
213:
214: /*
215: * Probe nexus space, finding the interconnects
216: * and setting up and probing mba's and uba's for devices.
217: */
218: /*ARGSUSED*/
219: probenexi(pnc)
220: register struct nexusconnect *pnc;
221: {
222: register struct nexus *nxv;
223: struct nexus *nxp = pnc->psb_nexbase;
224: union nexcsr nexcsr;
225: int i;
226:
227: nexnum = 0, nxv = &nexus[nsbi * NNEXSBI];
228: for (; nexnum < pnc->psb_nnexus; nexnum++, nxp++, nxv++) {
229: ioaccess((caddr_t)nxp, Nexmap[nsbi * NNEXSBI + nexnum],
230: sizeof(struct nexus));
231: if (badaddr((caddr_t)nxv, 4))
232: continue;
233: if (pnc->psb_nextype && pnc->psb_nextype[nexnum] != NEX_ANY)
234: nexcsr.nex_csr = pnc->psb_nextype[nexnum];
235: else
236: nexcsr = nxv->nexcsr;
237: if (nexcsr.nex_csr&NEX_APD)
238: continue;
239: switch (nexcsr.nex_type) {
240:
241: case NEX_MBA:
242: printf("mba%d at tr%d\n", nummba, nexnum);
243: if (nummba >= NMBA) {
244: printf("%d mba's", nummba++);
245: goto unconfig;
246: }
247: #if NMBA > 0
248: mbafind(nxv, nxp);
249: nummba++;
250: #endif
251: break;
252:
253: case NEX_UBA0:
254: case NEX_UBA1:
255: case NEX_UBA2:
256: case NEX_UBA3:
257: printf("uba%d at tr%d\n", numuba, nexnum);
258: #if VAX750
259: if (numuba >= 2 && cpu == VAX_750) {
260: printf("More than 2 UBA's");
261: goto unsupp;
262: }
263: #endif
264: if (numuba >= NUBA) {
265: printf("%d uba's", ++numuba);
266: goto unconfig;
267: }
268: #if defined(VAX780) || defined(VAX8600)
269: if ((cpu == VAX_780) || (cpu == VAX_8600))
270: setscbnex(ubaintv[numuba]);
271: #endif
272: i = nexcsr.nex_type - NEX_UBA0;
273: unifind((struct uba_regs *)nxv, (struct uba_regs *)nxp,
274: umem[numuba], pnc->psb_umaddr[i], UMEMmap[numuba],
275: pnc->psb_haveubasr);
276: #if defined(VAX780) || defined(VAX8600)
277: if ((cpu == VAX_780) || (cpu == VAX_8600))
278: ((struct uba_regs *)nxv)->uba_cr =
279: UBACR_IFS|UBACR_BRIE|
280: UBACR_USEFIE|UBACR_SUEFIE|
281: (((struct uba_regs *)nxv)->uba_cr&0x7c000000);
282: #endif
283: numuba++;
284: break;
285:
286: case NEX_DR32:
287: /* there can be more than one... are there other codes??? */
288: printf("dr32");
289: goto unsupp;
290:
291: case NEX_MEM4:
292: case NEX_MEM4I:
293: case NEX_MEM16:
294: case NEX_MEM16I:
295: printf("mcr%d at tr%d\n", nmcr, nexnum);
296: if (nmcr >= 4) {
297: printf("5 mcr's");
298: goto unsupp;
299: }
300: switch (cpu) {
301: case VAX_780:
302: mcrtype[nmcr] = M780C;
303: break;
304: case VAX_750:
305: mcrtype[nmcr] = M750;
306: break;
307: case VAX_730:
308: mcrtype[nmcr] = M730;
309: break;
310: }
311: mcraddr[nmcr++] = (struct mcr *)nxv;
312: break;
313:
314: case NEX_MEM64I:
315: case NEX_MEM64L:
316: case NEX_MEM64LI:
317: case NEX_MEM256I:
318: case NEX_MEM256L:
319: case NEX_MEM256LI:
320: printf("mcr%d (el) at tr%d\n", nmcr, nexnum);
321: if (nmcr >= 4) {
322: printf("5 mcr's");
323: goto unsupp;
324: }
325: if (cpu == VAX_780)
326: mcrtype[nmcr] = M780EL;
327: mcraddr[nmcr++] = (struct mcr *)nxv;
328: if (nexcsr.nex_type != NEX_MEM64I &&
329: nexcsr.nex_type != NEX_MEM256I)
330: break;
331: /* fall into ... */
332:
333: case NEX_MEM64U:
334: case NEX_MEM64UI:
335: case NEX_MEM256U:
336: case NEX_MEM256UI:
337: printf("mcr%d (eu) at tr%d\n", nmcr, nexnum);
338: if (nmcr >= 4) {
339: printf("5 mcr's");
340: goto unsupp;
341: }
342: if (cpu == VAX_780)
343: mcrtype[nmcr] = M780EU;
344: mcraddr[nmcr++] = (struct mcr *)nxv;
345: break;
346:
347: case NEX_MPM0:
348: case NEX_MPM1:
349: case NEX_MPM2:
350: case NEX_MPM3:
351: printf("mpm");
352: goto unsupp;
353:
354: case NEX_CI:
355: printf("ci");
356: goto unsupp;
357:
358: default:
359: printf("nexus type %x", nexcsr.nex_type);
360: unsupp:
361: printf(" unsupported (at tr %d)\n", nexnum);
362: continue;
363: unconfig:
364: printf(" not configured\n");
365: continue;
366: }
367: }
368: if (nummba > NMBA)
369: nummba = NMBA;
370: if (numuba > NUBA)
371: numuba = NUBA;
372: }
373:
374: #if NMBA > 0
375: struct mba_device *mbaconfig();
376: /*
377: * Find devices attached to a particular mba
378: * and look for each device found in the massbus
379: * initialization tables.
380: */
381: mbafind(nxv, nxp)
382: struct nexus *nxv, *nxp;
383: {
384: register struct mba_regs *mdp;
385: register struct mba_drv *mbd;
386: register struct mba_device *mi;
387: register struct mba_slave *ms;
388: int dn, dt, sn;
389: struct mba_device fnd;
390:
391: mdp = (struct mba_regs *)nxv;
392: mba_hd[nummba].mh_mba = mdp;
393: mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp;
394: setscbnex(mbaintv[nummba]);
395: fnd.mi_mba = mdp;
396: fnd.mi_mbanum = nummba;
397: for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) {
398: if ((mbd->mbd_ds&MBDS_DPR) == 0)
399: continue;
400: mdp->mba_sr |= MBSR_NED; /* si kludge */
401: dt = mbd->mbd_dt & 0xffff;
402: if (dt == 0)
403: continue;
404: if (mdp->mba_sr&MBSR_NED)
405: continue; /* si kludge */
406: if (dt == MBDT_MOH)
407: continue;
408: fnd.mi_drive = dn;
409: #define qeq(a, b) ( a == b || a == '?' )
410: if ((mi = mbaconfig(&fnd, dt)) && (dt & MBDT_TAP))
411: for (sn = 0; sn < 8; sn++) {
412: mbd->mbd_tc = sn;
413: for (ms = mbsinit; ms->ms_driver; ms++)
414: if (ms->ms_driver == mi->mi_driver &&
415: ms->ms_alive == 0 &&
416: qeq(ms->ms_ctlr, mi->mi_unit) &&
417: qeq(ms->ms_slave, sn) &&
418: (*ms->ms_driver->md_slave)(mi, ms, sn)) {
419: printf("%s%d at %s%d slave %d\n"
420: , ms->ms_driver->md_sname
421: , ms->ms_unit
422: , mi->mi_driver->md_dname
423: , mi->mi_unit
424: , sn
425: );
426: ms->ms_alive = 1;
427: ms->ms_ctlr = mi->mi_unit;
428: ms->ms_slave = sn;
429: }
430: }
431: }
432: mdp->mba_cr = MBCR_INIT;
433: mdp->mba_cr = MBCR_IE;
434: }
435:
436: /*
437: * Have found a massbus device;
438: * see if it is in the configuration table.
439: * If so, fill in its data.
440: */
441: struct mba_device *
442: mbaconfig(ni, type)
443: register struct mba_device *ni;
444: register int type;
445: {
446: register struct mba_device *mi;
447: register short *tp;
448: register struct mba_hd *mh;
449:
450: for (mi = mbdinit; mi->mi_driver; mi++) {
451: if (mi->mi_alive)
452: continue;
453: tp = mi->mi_driver->md_type;
454: for (mi->mi_type = 0; *tp; tp++, mi->mi_type++)
455: if (*tp == (type&MBDT_TYPE))
456: goto found;
457: continue;
458: found:
459: #define match(fld) (ni->fld == mi->fld || mi->fld == '?')
460: if (!match(mi_drive) || !match(mi_mbanum))
461: continue;
462: printf("%s%d at mba%d drive %d\n",
463: mi->mi_driver->md_dname, mi->mi_unit,
464: ni->mi_mbanum, ni->mi_drive);
465: mi->mi_alive = 1;
466: mh = &mba_hd[ni->mi_mbanum];
467: mi->mi_hd = mh;
468: mh->mh_mbip[ni->mi_drive] = mi;
469: mh->mh_ndrive++;
470: mi->mi_mba = ni->mi_mba;
471: mi->mi_drv = &mi->mi_mba->mba_drv[ni->mi_drive];
472: mi->mi_mbanum = ni->mi_mbanum;
473: mi->mi_drive = ni->mi_drive;
474: /*
475: * If drive has never been seen before,
476: * give it a dkn for statistics.
477: */
478: if (mi->mi_driver->md_info[mi->mi_unit] == 0) {
479: mi->mi_driver->md_info[mi->mi_unit] = mi;
480: if (mi->mi_dk && dkn < DK_NDRIVE)
481: mi->mi_dk = dkn++;
482: else
483: mi->mi_dk = -1;
484: }
485: (*mi->mi_driver->md_attach)(mi);
486: return (mi);
487: }
488: return (0);
489: }
490: #endif
491:
492: /*
493: * Fixctlrmask fixes the masks of the driver ctlr routines
494: * which otherwise save r10 and r11 where the interrupt and br
495: * level are passed through.
496: */
497: fixctlrmask()
498: {
499: register struct uba_ctlr *um;
500: register struct uba_device *ui;
501: register struct uba_driver *ud;
502: #define phys(a,b) ((b)(((int)(a))&0x7fffffff))
503:
504: for (um = ubminit; ud = phys(um->um_driver, struct uba_driver *); um++)
505: *phys(ud->ud_probe, short *) &= ~0xc00;
506: for (ui = ubdinit; ud = phys(ui->ui_driver, struct uba_driver *); ui++)
507: *phys(ud->ud_probe, short *) &= ~0xc00;
508: }
509:
510: /*
511: * Find devices on a UNIBUS.
512: * Uses per-driver routine to set <br,cvec> into <r11,r10>,
513: * and then fills in the tables, with help from a per-driver
514: * slave initialization routine.
515: */
516: unifind(vubp, pubp, vumem, pumem, memmap, haveubasr)
517: struct uba_regs *vubp, *pubp;
518: caddr_t vumem, pumem;
519: struct pte *memmap;
520: int haveubasr;
521: {
522: #ifndef lint
523: register int br, cvec; /* MUST BE r11, r10 */
524: #else
525: /*
526: * Lint doesn't realize that these
527: * can be initialized asynchronously
528: * when devices interrupt.
529: */
530: register int br = 0, cvec = 0;
531: #endif
532: register struct uba_device *ui;
533: register struct uba_ctlr *um;
534: u_short *reg, *ap, addr;
535: struct uba_hd *uhp;
536: struct uba_driver *udp;
537: int i, (**ivec)();
538: caddr_t ualloc, zmemall();
539: extern int catcher[256];
540:
541: #if VAX630
542: /*
543: * The map registers start right at 20088000 on the
544: * ka630, so we have to subtract out the 2k offset to make the
545: * pointers work..
546: */
547: if (cpu == VAX_630) {
548: vubp = (struct uba_regs *)(((u_long)vubp)-0x800);
549: pubp = (struct uba_regs *)(((u_long)pubp)-0x800);
550: }
551: #endif
552: /*
553: * Initialize the UNIBUS, by freeing the map
554: * registers and the buffered data path registers
555: */
556: uhp = &uba_hd[numuba];
557: uhp->uh_map = (struct map *)calloc(UAMSIZ * sizeof (struct map));
558: ubainitmaps(uhp);
559:
560: /*
561: * Save virtual and physical addresses
562: * of adaptor, and allocate and initialize
563: * the UNIBUS interrupt vector.
564: */
565: uhp->uh_uba = vubp;
566: uhp->uh_physuba = pubp;
567: /*
568: * On the 8600, can't use UNIvec;
569: * the vectors for the second SBI overlap it.
570: */
571: if (cpu == VAX_8600)
572: uhp->uh_vec = (int(**)())calloc(512);
573: else if (numuba == 0)
574: uhp->uh_vec = UNIvec;
575: #if NUBA > 1
576: else if (numuba == 1)
577: uhp->uh_vec = UNI1vec;
578: else
579: uhp->uh_vec = (int(**)())calloc(512);
580: #endif
581: for (i = 0; i < 128; i++)
582: uhp->uh_vec[i] =
583: scbentry(&catcher[i*2], SCB_ISTACK);
584: /*
585: * Set last free interrupt vector for devices with
586: * programmable interrupt vectors. Use is to decrement
587: * this number and use result as interrupt vector.
588: */
589: uhp->uh_lastiv = 0x200;
590:
591: #if VAX630
592: /*
593: * Kludge time again. The q22 memory and device reg. address spaces
594: * are not physically contiguous, so we need 2 loops to map them
595: * into contiguous virtual space.
596: */
597: if (cpu == VAX_630) {
598: ioaccess(pumem, memmap, (UBAPAGES-16)*NBPG);
599: ioaccess(0x20000000, memmap+(UBAPAGES-16), 16*NBPG);
600: } else
601: #endif
602: ioaccess(pumem, memmap, UBAPAGES * NBPG);
603: #if defined(VAX780) || defined(VAX8600)
604: if (haveubasr) {
605: vubp->uba_sr = vubp->uba_sr;
606: vubp->uba_cr = UBACR_IFS|UBACR_BRIE;
607: }
608: #endif
609: /*
610: * First configure devices that have unibus memory,
611: * allowing them to allocate the correct map registers.
612: */
613: ubameminit(numuba);
614: /*
615: * Grab some memory to record the umem address space we allocate,
616: * so we can be sure not to place two devices at the same address.
617: *
618: * We could use just 1/8 of this (we only want a 1 bit flag) but
619: * we are going to give it back anyway, and that would make the
620: * code here bigger (which we can't give back), so ...
621: *
622: * One day, someone will make a unibus with something other than
623: * an 8K i/o address space, & screw this totally.
624: */
625: ualloc = zmemall(memall, 8*1024);
626: if (ualloc == (caddr_t)0)
627: panic("no mem for unifind");
628:
629: /*
630: * Map the first page of UNIBUS i/o
631: * space to the first page of memory
632: * for devices which will need to dma
633: * output to produce an interrupt.
634: */
635: *(int *)(&vubp->uba_map[0]) = UBAMR_MRV;
636:
637: #define ubaoff(off) ((off)&0x1fff)
638: #define ubaddr(off) (u_short *)((int)vumem + (ubaoff(off)|0x3e000))
639: /*
640: * Check each unibus mass storage controller.
641: * For each one which is potentially on this uba,
642: * see if it is really there, and if it is record it and
643: * then go looking for slaves.
644: */
645: for (um = ubminit; udp = um->um_driver; um++) {
646: if (um->um_ubanum != numuba && um->um_ubanum != '?')
647: continue;
648: addr = (u_short)um->um_addr;
649: /*
650: * use the particular address specified first,
651: * or if it is given as "0", of there is no device
652: * at that address, try all the standard addresses
653: * in the driver til we find it
654: */
655: for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
656:
657: if (ualloc[ubaoff(addr)])
658: continue;
659: reg = ubaddr(addr);
660: if (badaddr((caddr_t)reg, 2))
661: continue;
662: #if defined(VAX780) || defined(VAX8600)
663: if (haveubasr && vubp->uba_sr) {
664: vubp->uba_sr = vubp->uba_sr;
665: continue;
666: }
667: #endif
668: cvec = 0x200;
669: i = (*udp->ud_probe)(reg, um->um_ctlr, um);
670: #if defined(VAX780) || defined(VAX8600)
671: if (haveubasr && vubp->uba_sr) {
672: vubp->uba_sr = vubp->uba_sr;
673: continue;
674: }
675: #endif
676: if (i == 0)
677: continue;
678: printf("%s%d at uba%d csr %o ",
679: udp->ud_mname, um->um_ctlr, numuba, addr);
680: if (cvec == 0) {
681: printf("zero vector\n");
682: continue;
683: }
684: if (cvec == 0x200) {
685: printf("didn't interrupt\n");
686: continue;
687: }
688: printf("vec %o, ipl %x\n", cvec, br);
689: um->um_alive = 1;
690: um->um_ubanum = numuba;
691: um->um_hd = &uba_hd[numuba];
692: um->um_addr = (caddr_t)reg;
693: udp->ud_minfo[um->um_ctlr] = um;
694: for (ivec = um->um_intr; *ivec; ivec++) {
695: um->um_hd->uh_vec[cvec/4] =
696: scbentry(*ivec, SCB_ISTACK);
697: cvec += 4;
698: }
699: for (ui = ubdinit; ui->ui_driver; ui++) {
700: if (ui->ui_driver != udp || ui->ui_alive ||
701: ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' ||
702: ui->ui_ubanum != numuba && ui->ui_ubanum != '?')
703: continue;
704: if ((*udp->ud_slave)(ui, reg)) {
705: ui->ui_alive = 1;
706: ui->ui_ctlr = um->um_ctlr;
707: ui->ui_ubanum = numuba;
708: ui->ui_hd = &uba_hd[numuba];
709: ui->ui_addr = (caddr_t)reg;
710: ui->ui_physaddr = pumem + ubdevreg(addr);
711: if (ui->ui_dk && dkn < DK_NDRIVE)
712: ui->ui_dk = dkn++;
713: else
714: ui->ui_dk = -1;
715: ui->ui_mi = um;
716: /* ui_type comes from driver */
717: udp->ud_dinfo[ui->ui_unit] = ui;
718: printf("%s%d at %s%d slave %d\n",
719: udp->ud_dname, ui->ui_unit,
720: udp->ud_mname, um->um_ctlr, ui->ui_slave);
721: (*udp->ud_attach)(ui);
722: }
723: }
724: break;
725: }
726: }
727: /*
728: * Now look for non-mass storage peripherals.
729: */
730: for (ui = ubdinit; udp = ui->ui_driver; ui++) {
731: if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' ||
732: ui->ui_alive || ui->ui_slave != -1)
733: continue;
734: addr = (u_short)ui->ui_addr;
735:
736: for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
737:
738: if (ualloc[ubaoff(addr)])
739: continue;
740: reg = ubaddr(addr);
741: if (badaddr((caddr_t)reg, 2))
742: continue;
743: #if defined(VAX780) || defined(VAX8600)
744: if (haveubasr && vubp->uba_sr) {
745: vubp->uba_sr = vubp->uba_sr;
746: continue;
747: }
748: #endif
749: cvec = 0x200;
750: i = (*udp->ud_probe)(reg, ui);
751: #if defined(VAX780) || defined(VAX8600)
752: if (haveubasr && vubp->uba_sr) {
753: vubp->uba_sr = vubp->uba_sr;
754: continue;
755: }
756: #endif
757: if (i == 0)
758: continue;
759: printf("%s%d at uba%d csr %o ",
760: ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr);
761: if (cvec == 0) {
762: printf("zero vector\n");
763: continue;
764: }
765: if (cvec == 0x200) {
766: printf("didn't interrupt\n");
767: continue;
768: }
769: printf("vec %o, ipl %x\n", cvec, br);
770: while (--i >= 0)
771: ualloc[ubaoff(addr+i)] = 1;
772: ui->ui_hd = &uba_hd[numuba];
773: for (ivec = ui->ui_intr; *ivec; ivec++) {
774: ui->ui_hd->uh_vec[cvec/4] =
775: scbentry(*ivec, SCB_ISTACK);
776: cvec += 4;
777: }
778: ui->ui_alive = 1;
779: ui->ui_ubanum = numuba;
780: ui->ui_addr = (caddr_t)reg;
781: ui->ui_physaddr = pumem + ubdevreg(addr);
782: ui->ui_dk = -1;
783: /* ui_type comes from driver */
784: udp->ud_dinfo[ui->ui_unit] = ui;
785: (*udp->ud_attach)(ui);
786: break;
787: }
788: }
789:
790: #ifdef AUTO_DEBUG
791: printf("Unibus allocation map");
792: for (i = 0; i < 8*1024; ) {
793: register n, m;
794:
795: if ((i % 128) == 0) {
796: printf("\n%6o:", i);
797: for (n = 0; n < 128; n++)
798: if (ualloc[i+n])
799: break;
800: if (n == 128) {
801: i += 128;
802: continue;
803: }
804: }
805:
806: for (n = m = 0; n < 16; n++) {
807: m <<= 1;
808: m |= ualloc[i++];
809: }
810:
811: printf(" %4x", m);
812: }
813: printf("\n");
814: #endif
815:
816: wmemfree(ualloc, 8*1024);
817: }
818:
819: setscbnex(fn)
820: int (*fn)();
821: {
822: register struct scb *scbp = &scb;
823:
824: scbp = (struct scb *)((caddr_t)scbp + nsbi * 512);
825: scbp->scb_ipl14[nexnum] = scbp->scb_ipl15[nexnum] =
826: scbp->scb_ipl16[nexnum] = scbp->scb_ipl17[nexnum] =
827: scbentry(fn, SCB_ISTACK);
828: }
829:
830: /*
831: * Make an IO register area accessible at physical address physa
832: * by mapping kernel ptes starting at pte.
833: */
834: ioaccess(physa, pte, size)
835: caddr_t physa;
836: register struct pte *pte;
837: int size;
838: {
839: register int i = btop(size);
840: register unsigned v = btop(physa);
841:
842: do
843: *(int *)pte++ = PG_V|PG_KW|v++;
844: while (--i > 0);
845: mtpr(TBIA, 0);
846: }
847:
848: /*
849: * Configure swap space and related parameters.
850: */
851: swapconf()
852: {
853: register struct swdevt *swp;
854: register int nblks;
855:
856: for (swp = swdevt; swp->sw_dev; swp++) {
857: if (bdevsw[major(swp->sw_dev)].d_psize) {
858: nblks =
859: (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
860: if (swp->sw_nblks == 0 || swp->sw_nblks > nblks)
861: swp->sw_nblks = nblks;
862: }
863: }
864: if (!cold) /* in case called for mba device */
865: return;
866: if (dumplo == 0 && bdevsw[major(dumpdev)].d_psize)
867: dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) - physmem;
868: if (dumplo < 0)
869: dumplo = 0;
870: }
871:
872: #define DOSWAP /* Change swdevt, argdev, and dumpdev too */
873: u_long bootdev; /* should be dev_t, but not until 32 bits */
874:
875: static char devname[][2] = {
876: 'h','p', /* 0 = hp */
877: 0,0, /* 1 = ht */
878: 'u','p', /* 2 = up */
879: 'r','k', /* 3 = hk */
880: 0,0, /* 4 = sw */
881: 0,0, /* 5 = tm */
882: 0,0, /* 6 = ts */
883: 0,0, /* 7 = mt */
884: 0,0, /* 8 = tu */
885: 'r','a', /* 9 = ra */
886: 0,0, /* 10 = ut */
887: 'r','b', /* 11 = rb */
888: 0,0, /* 12 = uu */
889: 0,0, /* 13 = rx */
890: 'r','l', /* 14 = rl */
891: };
892:
893: #define PARTITIONMASK 0x7
894: #define PARTITIONSHIFT 3
895:
896: /*
897: * Attempt to find the device from which we were booted.
898: * If we can do so, and not instructed not to do so,
899: * change rootdev to correspond to the load device.
900: */
901: setroot()
902: {
903: int majdev, mindev, unit, part, adaptor;
904: dev_t temp, orootdev;
905: struct swdevt *swp;
906:
907: if (boothowto & RB_DFLTROOT ||
908: (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
909: return;
910: majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
911: if (majdev > sizeof(devname) / sizeof(devname[0]))
912: return;
913: adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
914: part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
915: unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
916: if (majdev == 0) { /* MBA device */
917: #if NMBA > 0
918: register struct mba_device *mbap;
919: int mask;
920:
921: /*
922: * The MBA number used at boot time is not necessarily the same as the
923: * MBA number used by the kernel. In order to change the rootdev we need to
924: * convert the boot MBA number to the kernel MBA number. The address space
925: * for an MBA used by the boot code is 0x20010000 + 0x2000 * MBA_number
926: * on the 78? and 86?0, 0xf28000 + 0x2000 * MBA_number on the 750.
927: * Therefore we can search the mba_hd table for the MBA that has the physical
928: * address corresponding to the boot MBA number.
929: */
930: #define PHYSADRSHFT 13
931: #define PHYSMBAMASK780 0x7
932: #define PHYSMBAMASK750 0x3
933:
934: switch (cpu) {
935:
936: case VAX_780:
937: case VAX_8600:
938: default:
939: mask = PHYSMBAMASK780;
940: break;
941:
942: case VAX_750:
943: mask = PHYSMBAMASK750;
944: break;
945: }
946: for (mbap = mbdinit; mbap->mi_driver; mbap++)
947: if (mbap->mi_alive && mbap->mi_drive == unit &&
948: (((long)mbap->mi_hd->mh_physmba >> PHYSADRSHFT)
949: & mask) == adaptor)
950: break;
951: if (mbap->mi_driver == 0)
952: return;
953: mindev = mbap->mi_unit;
954: #else
955: return;
956: #endif
957: } else {
958: register struct uba_device *ubap;
959:
960: for (ubap = ubdinit; ubap->ui_driver; ubap++)
961: if (ubap->ui_alive && ubap->ui_slave == unit &&
962: ubap->ui_ubanum == adaptor &&
963: ubap->ui_driver->ud_dname[0] == devname[majdev][0] &&
964: ubap->ui_driver->ud_dname[1] == devname[majdev][1])
965: break;
966:
967: if (ubap->ui_driver == 0)
968: return;
969: mindev = ubap->ui_unit;
970: }
971: mindev = (mindev << PARTITIONSHIFT) + part;
972: orootdev = rootdev;
973: rootdev = makedev(majdev, mindev);
974: /*
975: * If the original rootdev is the same as the one
976: * just calculated, don't need to adjust the swap configuration.
977: */
978: if (rootdev == orootdev)
979: return;
980:
981: printf("Changing root device to %c%c%d%c\n",
982: devname[majdev][0], devname[majdev][1],
983: mindev >> PARTITIONSHIFT, part + 'a');
984:
985: #ifdef DOSWAP
986: mindev &= ~PARTITIONMASK;
987: for (swp = swdevt; swp->sw_dev; swp++) {
988: if (majdev == major(swp->sw_dev) &&
989: mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
990: temp = swdevt[0].sw_dev;
991: swdevt[0].sw_dev = swp->sw_dev;
992: swp->sw_dev = temp;
993: break;
994: }
995: }
996: if (swp->sw_dev == 0)
997: return;
998:
999: /*
1000: * If argdev and dumpdev were the same as the old primary swap
1001: * device, move them to the new primary swap device.
1002: */
1003: if (temp == dumpdev)
1004: dumpdev = swdevt[0].sw_dev;
1005: if (temp == argdev)
1006: argdev = swdevt[0].sw_dev;
1007: #endif
1008: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.