rm spaces in printfs
[unix-history] / usr / src / sys / tahoe / tahoe / autoconf.c
CommitLineData
35b2d0b1 1/* autoconf.c 1.11 87/01/04 */
a747139c
SL
2
3/*
4 * Setup the system to run on the current machine.
5 *
6 * Configure() is called at boot time and initializes the vba
7 * device tables and the memory controller monitoring. Available
8 * devices are determined (from possibilities mentioned in ioconf.c),
9 * and the drivers are initialized.
a747139c 10 */
a55e280b
SL
11#include "../tahoe/pte.h"
12#include "../tahoe/mem.h"
13#include "../tahoe/mtpr.h"
56ad8000
SL
14#include "../tahoe/scb.h"
15
16#include "vba.h"
a747139c 17
a55e280b
SL
18#include "param.h"
19#include "systm.h"
20#include "map.h"
21#include "buf.h"
dee91660 22#include "dkstat.h"
a55e280b
SL
23#include "vm.h"
24#include "conf.h"
25#include "dmap.h"
dee91660 26#include "reboot.h"
a55e280b
SL
27
28#include "../tahoevba/vbavar.h"
741dff62 29#include "../tahoevba/vbaparam.h"
a747139c
SL
30
31/*
32 * The following several variables are related to
33 * the configuration process, and are used in initializing
34 * the machine.
35 */
36int dkn; /* number of iostat dk numbers assigned so far */
56ad8000
SL
37int cold; /* cold start flag initialized in locore.s */
38
39/*
741dff62 40 * This allocates the space for the per-vba information.
56ad8000
SL
41 */
42struct vba_hd vba_hd[NVBA];
a747139c
SL
43
44/*
92b4b695 45 * Determine i/o configuration for a machine.
a747139c
SL
46 */
47configure()
48{
49 register int *ip;
a55e280b 50 extern caddr_t Sysbase;
a747139c 51
7a9210cc 52 vbafind(numvba, (caddr_t)&vmem, VMEMmap);
56ad8000 53 numvba++;
a747139c
SL
54 /*
55 * Write protect the scb. It is strange
56 * that this code is here, but this is as soon
57 * as we are done mucking with it, and the
58 * write-enable was done in assembly language
59 * to which we will never return.
60 */
61 ip = (int *)&Sysmap[2]; *ip &= ~PG_PROT; *ip |= PG_KR;
a55e280b 62 mtpr(TBIS, Sysbase+2*NBPG);
a747139c 63#if GENERIC
dee91660
SL
64 if ((boothowto & RB_ASKNAME) == 0)
65 setroot();
a747139c 66 setconf();
dee91660
SL
67#else
68 setroot();
a747139c 69#endif
dee91660
SL
70 /*
71 * Configure swap area and related system
72 * parameter based on device(s) used.
73 */
a747139c 74 swapconf();
56ad8000 75 cold = 0;
a747139c
SL
76}
77
a747139c
SL
78/*
79 * Make the controllers accessible at physical address phys
80 * by mapping kernel ptes starting at pte.
81 */
741dff62 82vbaccess(pte, iobase, n)
a747139c 83 register struct pte *pte;
a55e280b
SL
84 caddr_t iobase;
85 register int n;
a747139c 86{
a747139c
SL
87 register unsigned v = btop(iobase);
88
89 do
90 *(int *)pte++ = PG_V|PG_KW|v++;
a55e280b
SL
91 while (--n > 0);
92 mtpr(TBIA, 0);
a747139c
SL
93}
94
56ad8000
SL
95/*
96 * Fixctlrmask fixes the masks of the driver ctlr routines
97 * which otherwise save r11 and r12 where the interrupt and br
98 * level are passed through.
99 */
100fixctlrmask()
101{
102 register struct vba_ctlr *vm;
103 register struct vba_device *vi;
104 register struct vba_driver *vd;
105#define phys(a,b) ((b)(((int)(a))&~0xc0000000))
106
107 vm = phys(vbminit, struct vba_ctlr *);
108 for (; vd = phys(vm->um_driver, struct vba_driver *); vm++)
109 *phys(vd->ud_probe, short *) &= ~0x1800;
110 vi = phys(vbdinit, struct vba_device *);
111 for (; vd = phys(vi->ui_driver, struct vba_driver *); vi++)
112 *phys(vd->ud_probe, short *) &= ~0x1800;
113}
a747139c
SL
114
115/*
56ad8000 116 * Find devices on the VERSAbus.
a747139c
SL
117 * Uses per-driver routine to see who is on the bus
118 * and then fills in the tables, with help from a per-driver
119 * slave initialization routine.
120 */
a55e280b
SL
121vbafind(vban, vumem, memmap)
122 int vban;
741dff62
SL
123 caddr_t vumem;
124 struct pte memmap[];
a747139c 125{
56ad8000 126 register int br, cvec; /* must be r12, r11 */
a747139c
SL
127 register struct vba_device *ui;
128 register struct vba_ctlr *um;
129 u_short *reg;
56ad8000
SL
130 long addr, *ap;
131 struct vba_hd *vhp;
a747139c 132 struct vba_driver *udp;
56ad8000 133 int i, (**ivec)();
92b4b695 134 caddr_t valloc, zmemall();
7a9210cc 135 extern long catcher[SCB_LASTIV*2];
a747139c 136
56ad8000
SL
137#ifdef lint
138 br = 0; cvec = 0;
139#endif
140 vhp = &vba_hd[vban];
a747139c
SL
141 /*
142 * Make the controllers accessible at physical address phys
143 * by mapping kernel ptes starting at pte.
144 */
7a9210cc 145 vbaccess(memmap, (caddr_t)VBIOBASE, VBIOSIZE);
92b4b695 146 printf("vba%d at %x\n", vban, VBIOBASE);
56ad8000
SL
147 /*
148 * Setup scb device entries to point into catcher array.
149 */
150 for (i = 0; i < SCB_LASTIV; i++)
151 scb.scb_devint[i] = (int (*)())&catcher[i*2];
152 /*
153 * Set last free interrupt vector for devices with
154 * programmable interrupt vectors. Use is to decrement
155 * this number and use result as interrupt vector.
156 */
157 vhp->vh_lastiv = SCB_LASTIV;
92b4b695
SL
158 /*
159 * Grab some memory to record the address space we allocate,
160 * so we can be sure not to place two devices at the same address.
161 *
162 * We could use just 1/8 of this (we only want a 1 bit flag) but
163 * we are going to give it back anyway, and that would make the
164 * code here bigger (which we can't give back), so ...
165 */
166 valloc = zmemall(memall, ctob(VBIOSIZE));
167 if (valloc == (caddr_t)0)
168 panic("no mem for vbafind");
a747139c 169
a747139c
SL
170 /*
171 * Check each VERSAbus mass storage controller.
172 * For each one which is potentially on this vba,
173 * see if it is really there, and if it is record it and
174 * then go looking for slaves.
175 */
7a9210cc 176#define vbaddr(off) (u_short *)(vumem + vboff(off))
a747139c 177 for (um = vbminit; udp = um->um_driver; um++) {
a55e280b 178 if (um->um_vbanum != vban && um->um_vbanum != '?')
a747139c 179 continue;
56ad8000
SL
180 /*
181 * Use the particular address specified first,
182 * or if it is given as "0", if there is no device
183 * at that address, try all the standard addresses
184 * in the driver until we find it.
185 */
a747139c 186 addr = (long)um->um_addr;
56ad8000 187 for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
92b4b695
SL
188 if (VBIOMAPPED(addr)) {
189 if (valloc[vboff(addr)])
190 continue;
191 reg = vbaddr(addr);
192 } else
193 reg = (u_short *)addr;
56ad8000
SL
194 um->um_hd = vhp;
195 cvec = SCB_LASTIV, cold &= ~0x2;
196 i = (*udp->ud_probe)(reg, um);
197 cold |= 0x2;
a747139c
SL
198 if (i == 0)
199 continue;
56ad8000 200 printf("%s%d at vba%d csr %x ",
a55e280b 201 udp->ud_mname, um->um_ctlr, vban, addr);
56ad8000
SL
202 if (cvec < 0 && vhp->vh_lastiv == cvec) {
203 printf("no space for vector(s)\n");
204 continue;
205 }
206 if (cvec == SCB_LASTIV) {
207 printf("didn't interrupt\n");
208 continue;
209 }
210 printf("vec %x, ipl %x\n", cvec, br);
92b4b695 211 csralloc(valloc, addr, i);
a747139c 212 um->um_alive = 1;
a55e280b 213 um->um_vbanum = vban;
a747139c
SL
214 um->um_addr = (caddr_t)reg;
215 udp->ud_minfo[um->um_ctlr] = um;
56ad8000 216 for (ivec = um->um_intr; *ivec; ivec++)
61d2e29d 217 ((long *)&scb)[cvec++] = (long)*ivec;
a747139c
SL
218 for (ui = vbdinit; ui->ui_driver; ui++) {
219 if (ui->ui_driver != udp || ui->ui_alive ||
220 ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' ||
a55e280b 221 ui->ui_vbanum != vban && ui->ui_vbanum != '?')
a747139c
SL
222 continue;
223 if ((*udp->ud_slave)(ui, reg)) {
224 ui->ui_alive = 1;
225 ui->ui_ctlr = um->um_ctlr;
a55e280b 226 ui->ui_vbanum = vban;
a747139c 227 ui->ui_addr = (caddr_t)reg;
92b4b695 228 ui->ui_physaddr = (caddr_t)addr;
a747139c
SL
229 if (ui->ui_dk && dkn < DK_NDRIVE)
230 ui->ui_dk = dkn++;
231 else
232 ui->ui_dk = -1;
233 ui->ui_mi = um;
56ad8000 234 ui->ui_hd = vhp;
a747139c
SL
235 /* ui_type comes from driver */
236 udp->ud_dinfo[ui->ui_unit] = ui;
35b2d0b1 237 printf("%s%d at %s%d slave %d",
a747139c
SL
238 udp->ud_dname, ui->ui_unit,
239 udp->ud_mname, um->um_ctlr,
240 ui->ui_slave);
241 (*udp->ud_attach)(ui);
e0283bca 242 printf("\n");
a747139c
SL
243 }
244 }
56ad8000
SL
245 break;
246 }
a747139c
SL
247 }
248 /*
249 * Now look for non-mass storage peripherals.
250 */
251 for (ui = vbdinit; udp = ui->ui_driver; ui++) {
a55e280b 252 if (ui->ui_vbanum != vban && ui->ui_vbanum != '?' ||
a747139c
SL
253 ui->ui_alive || ui->ui_slave != -1)
254 continue;
255 addr = (long)ui->ui_addr;
56ad8000 256 for (ap = udp->ud_addr; addr || (addr = *ap++); addr = 0) {
92b4b695
SL
257 if (VBIOMAPPED(addr)) {
258 if (valloc[vboff(addr)])
259 continue;
260 reg = vbaddr(addr);
261 } else
262 reg = (u_short *)addr;
56ad8000
SL
263 ui->ui_hd = vhp;
264 cvec = SCB_LASTIV, cold &= ~0x2;
265 i = (*udp->ud_probe)(reg, ui);
266 cold |= 0x2;
a747139c
SL
267 if (i == 0)
268 continue;
56ad8000 269 printf("%s%d at vba%d csr %x ",
a55e280b 270 ui->ui_driver->ud_dname, ui->ui_unit, vban, addr);
92b4b695
SL
271 if (ui->ui_intr) {
272 if (cvec < 0 && vhp->vh_lastiv == cvec) {
273 printf("no space for vector(s)\n");
274 continue;
275 }
276 if (cvec == SCB_LASTIV) {
277 printf("didn't interrupt\n");
278 continue;
279 }
280 printf("vec %x, ipl %x\n", cvec, br);
281 for (ivec = ui->ui_intr; *ivec; ivec++)
282 ((long *)&scb)[cvec++] = (long)*ivec;
283 } else
284 printf("no interrupts\n");
285 csralloc(valloc, addr, i);
a747139c 286 ui->ui_alive = 1;
a55e280b 287 ui->ui_vbanum = vban;
a747139c 288 ui->ui_addr = (caddr_t)reg;
92b4b695 289 ui->ui_physaddr = (caddr_t)addr;
a747139c
SL
290 ui->ui_dk = -1;
291 /* ui_type comes from driver */
292 udp->ud_dinfo[ui->ui_unit] = ui;
293 (*udp->ud_attach)(ui);
56ad8000
SL
294 break;
295 }
a747139c 296 }
92b4b695
SL
297 wmemfree(valloc, ctob(VBIOSIZE));
298}
299
300/*
301 * Mark addresses starting at addr and continuing
302 * size bytes as allocated in the map.
303 * Warn if the new allocation overlaps a previous allocation.
304 */
305csralloc(valloc, addr, size)
7a9210cc
SL
306 caddr_t valloc;
307 long addr;
92b4b695
SL
308 register int size;
309{
310 register caddr_t p;
311 int warned = 0;
312
313 if (!VBIOMAPPED(addr))
314 return;
315 p = &valloc[vboff(addr+size)];
316 while (--size >= 0) {
317 if (*--p && !warned) {
318 printf(
319 "WARNING: device registers overlap those for a previous device\n");
320 warned = 1;
321 }
322 *p = 1;
323 }
a747139c
SL
324}
325
741dff62
SL
326/*
327 * Tahoe VERSAbus adapator support routines.
328 */
329
330caddr_t vbcur = (caddr_t)&vbbase;
331int vbx = 0;
332/*
333 * Allocate page tables for mapping intermediate i/o buffers.
334 * Called by device drivers during autoconfigure.
335 */
336vbmapalloc(npf, ppte, putl)
337 int npf;
338 struct pte **ppte;
339 caddr_t *putl;
340{
341
342 if (vbcur + npf*NBPG >= (caddr_t)&vbend)
343 panic("vbmapalloc");
344 *ppte = &VBmap[vbx];
345 *putl = vbcur;
346 vbx += npf;
347 vbcur += npf*NBPG;
348}
349
350caddr_t vbmcur = (caddr_t)&vmem1;
351int vbmx = 0;
352/*
353 * Allocate page tables and map VERSAbus i/o space.
354 * Called by device drivers during autoconfigure.
355 */
356vbmemalloc(npf, addr, ppte, putl)
357 int npf;
358 caddr_t addr;
359 struct pte **ppte;
360 caddr_t *putl;
361{
362
363 if (vbmcur + npf*NBPG >= (caddr_t)&vmemend)
364 panic("vbmemalloc");
365 *ppte = &VMEMmap1[vbmx];
366 *putl = vbmcur;
367 vbmx += npf;
368 vbmcur += npf*NBPG;
369 vbaccess(*ppte, addr, npf); /* map i/o space */
370}
371
a747139c
SL
372/*
373 * Configure swap space and related parameters.
374 */
375swapconf()
376{
377 register struct swdevt *swp;
378 register int nblks;
379
56ad8000
SL
380 for (swp = swdevt; swp->sw_dev; swp++)
381 if (bdevsw[major(swp->sw_dev)].d_psize) {
a747139c
SL
382 nblks =
383 (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
56ad8000
SL
384 if (swp->sw_nblks == 0 || swp->sw_nblks > nblks)
385 swp->sw_nblks = nblks;
386 }
a747139c 387 if (dumplo == 0 && bdevsw[major(dumpdev)].d_psize)
56ad8000 388 dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) - physmem;
a747139c
SL
389 if (dumplo < 0)
390 dumplo = 0;
a747139c 391}
dee91660
SL
392
393#define DOSWAP /* change swdevt, argdev, and dumpdev too */
394u_long bootdev; /* should be dev_t, but not until 32 bits */
395
396static char devname[][2] = {
397 0,0, /* 0 = ud */
398 'd','k', /* 1 = vd */
399 0,0, /* 2 = xp */
400};
401
402#define PARTITIONMASK 0x7
403#define PARTITIONSHIFT 3
404
405/*
406 * Attempt to find the device from which we were booted.
407 * If we can do so, and not instructed not to do so,
408 * change rootdev to correspond to the load device.
409 */
410setroot()
411{
412 int majdev, mindev, unit, part, adaptor;
413 dev_t temp, orootdev;
414 struct swdevt *swp;
415
416 if (boothowto & RB_DFLTROOT ||
417 (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
418 return;
419 majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
420 if (majdev > sizeof(devname) / sizeof(devname[0]))
421 return;
422 adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
423 part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
424 unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
425 /*
426 * Search Versabus devices.
427 *
428 * WILL HAVE TO DISTINGUISH VME/VERSABUS SOMETIME
429 */
430 {
431 register struct vba_device *vbap;
432
433 for (vbap = vbdinit; vbap->ui_driver; vbap++)
434 if (vbap->ui_alive && vbap->ui_slave == unit &&
435 vbap->ui_vbanum == adaptor &&
dee91660
SL
436 vbap->ui_driver->ud_dname[0] == devname[majdev][0] &&
437 vbap->ui_driver->ud_dname[1] == devname[majdev][1])
dee91660
SL
438 break;
439 if (vbap->ui_driver == 0)
440 return;
441 mindev = vbap->ui_unit;
442 }
443 mindev = (mindev << PARTITIONSHIFT) + part;
444 orootdev = rootdev;
445 rootdev = makedev(majdev, mindev);
446 /*
447 * If the original rootdev is the same as the one
448 * just calculated, don't need to adjust the swap configuration.
449 */
450 if (rootdev == orootdev)
451 return;
452 printf("changing root device to %c%c%d%c\n",
453 devname[majdev][0], devname[majdev][1],
454 mindev >> PARTITIONSHIFT, part + 'a');
455#ifdef DOSWAP
456 mindev &= ~PARTITIONMASK;
457 for (swp = swdevt; swp->sw_dev; swp++) {
458 if (majdev == major(swp->sw_dev) &&
459 mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
460 temp = swdevt[0].sw_dev;
461 swdevt[0].sw_dev = swp->sw_dev;
462 swp->sw_dev = temp;
463 break;
464 }
465 }
466 if (swp->sw_dev == 0)
467 return;
468 /*
469 * If argdev and dumpdev were the same as the old primary swap
470 * device, move them to the new primary swap device.
471 */
472 if (temp == dumpdev)
473 dumpdev = swdevt[0].sw_dev;
474 if (temp == argdev)
475 argdev = swdevt[0].sw_dev;
476#endif
477}