purge so_addr and add PRU_SOCKADDR as replacement
[unix-history] / usr / src / sys / vax / vax / autoconf.c
CommitLineData
0cf493bf 1/* autoconf.c 4.34 82/03/31 */
327f6ec8 2
327f6ec8 3/*
d565635a
BJ
4 * Setup the system to run on the current machine.
5 *
6 * Configure() is called at boot time and initializes the uba and mba
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.
10 *
11 * N.B.: A lot of the conditionals based on processor type say
12 * #if VAX780
13 * and
14 * #if VAX750
15 * which may be incorrect after more processors are introduced if they
b17fedcd 16 * are like either of these machines.
81975711
BJ
17 *
18 * TODO:
19 * use pcpu info about whether a ubasr exists
327f6ec8
BJ
20 */
21
47fa50b1
BJ
22#include "mba.h"
23
327f6ec8 24#include "../h/param.h"
3f3a34c3 25#include "../h/systm.h"
327f6ec8
BJ
26#include "../h/map.h"
27#include "../h/nexus.h"
28#include "../h/pte.h"
29#include "../h/buf.h"
b721b0ed
BJ
30#include "../h/mbareg.h"
31#include "../h/mbavar.h"
8d2ea14f
BJ
32#include "../h/dk.h"
33#include "../h/vm.h"
b721b0ed
BJ
34#include "../h/ubareg.h"
35#include "../h/ubavar.h"
327f6ec8
BJ
36#include "../h/mtpr.h"
37#include "../h/cpu.h"
38#include "../h/scb.h"
3f3a34c3 39#include "../h/mem.h"
327f6ec8 40
d565635a
BJ
41/*
42 * The following several variables are related to
43 * the configuration process, and are used in initializing
44 * the machine.
45 */
46int cold; /* if 1, still working on cold-start */
327f6ec8 47int nexnum; /* current nexus number */
d565635a 48int dkn; /* number of iostat dk numbers assigned so far */
327f6ec8 49
d565635a
BJ
50/*
51 * Addresses of the (locore) routines which bootstrap us from
52 * hardware traps to C code. Filled into the system control block
53 * as necessary.
54 */
47fa50b1 55#if NMBA > 0
8d2ea14f 56int (*mbaintv[4])() = { Xmba0int, Xmba1int, Xmba2int, Xmba3int };
47fa50b1 57#endif
5aa9d5ea 58#if VAX780
8d2ea14f 59int (*ubaintv[4])() = { Xua0int, Xua1int, Xua2int, Xua3int };
5aa9d5ea 60#endif
d565635a
BJ
61
62/*
63 * This allocates the space for the per-uba information,
64 * such as buffered data path usage.
65 */
b721b0ed 66struct uba_hd uba_hd[MAXNUBA];
327f6ec8
BJ
67
68/*
69 * Determine mass storage and memory configuration for a machine.
70 * Get cpu type, and then switch out to machine specific procedures
71 * which will probe adaptors to see what is out there.
72 */
73configure()
74{
75 union cpusid cpusid;
3f3a34c3 76 register struct percpu *ocp;
a0eab615 77 register int *ip;
3e7ee2db 78 extern char Sysbase[];
327f6ec8
BJ
79
80 cpusid.cpusid = mfpr(SID);
b17fedcd 81 for (ocp = percpu; ocp->pc_cputype; ocp++)
3f3a34c3 82 if (ocp->pc_cputype == cpusid.cpuany.cp_type) {
b17fedcd 83 probenexus(ocp);
d565635a
BJ
84 /*
85 * Write protect the scb. It is strange
86 * that this code is here, but this is as soon
87 * as we are done mucking with it, and the
88 * write-enable was done in assembly language
89 * to which we will never return.
90 */
3e7ee2db
BJ
91 ip = (int *)Sysmap; *ip &= ~PG_PROT; *ip |= PG_KR;
92 mtpr(TBIS, Sysbase);
d565635a
BJ
93#if GENERIC
94 setconf();
95#endif
8d2ea14f 96 cold = 0;
c9e9b65b 97 memenable();
3f3a34c3
BJ
98 return;
99 }
d565635a 100 printf("cpu type %d not configured\n", cpusid.cpuany.cp_type);
327f6ec8
BJ
101 asm("halt");
102}
103
327f6ec8 104/*
b17fedcd
BJ
105 * Probe nexus space, finding the interconnects
106 * and setting up and probing mba's and uba's for devices.
327f6ec8 107 */
a0eab615 108/*ARGSUSED*/
b17fedcd 109probenexus(pcpu)
3f3a34c3 110 register struct percpu *pcpu;
327f6ec8
BJ
111{
112 register struct nexus *nxv;
b17fedcd 113 struct nexus *nxp = pcpu->pc_nexbase;
327f6ec8 114 union nexcsr nexcsr;
e83ccfd7 115 int i;
327f6ec8 116
b17fedcd
BJ
117 nexnum = 0, nxv = nexus;
118 for (; nexnum < pcpu->pc_nnexus; nexnum++, nxp++, nxv++) {
a0eab615 119 nxaccess(nxp, Nexmap[nexnum]);
327f6ec8
BJ
120 if (badaddr((caddr_t)nxv, 4))
121 continue;
b17fedcd
BJ
122 if (pcpu->pc_nextype && pcpu->pc_nextype[nexnum] != NEX_ANY)
123 nexcsr.nex_csr = pcpu->pc_nextype[nexnum];
124 else
125 nexcsr = nxv->nexcsr;
327f6ec8
BJ
126 if (nexcsr.nex_csr&NEX_APD)
127 continue;
327f6ec8
BJ
128 switch (nexcsr.nex_type) {
129
130 case NEX_MBA:
8d2ea14f 131 printf("mba%d at tr%d\n", nummba, nexnum);
a7e7fa7e 132 if (nummba >= NMBA) {
d565635a 133 printf("%d mba's", nummba);
a0eab615 134 goto unconfig;
a7e7fa7e 135 }
d565635a 136#if NMBA > 0
3f3a34c3 137 mbafind(nxv, nxp);
5aa9d5ea 138 nummba++;
47fa50b1 139#endif
d565635a 140 break;
327f6ec8
BJ
141
142 case NEX_UBA0:
143 case NEX_UBA1:
144 case NEX_UBA2:
145 case NEX_UBA3:
d565635a 146 printf("uba%d at tr%d\n", numuba, nexnum);
30d13fef
BJ
147 if (numuba >= 4) {
148 printf("5 uba's");
3f3a34c3
BJ
149 goto unsupp;
150 }
e83ccfd7
BJ
151#if VAX780
152 if (cpu == VAX_780)
153 setscbnex(ubaintv[numuba]);
154#endif
3f3a34c3 155 i = nexcsr.nex_type - NEX_UBA0;
30d13fef 156 unifind((struct uba_regs *)nxv, (struct uba_regs *)nxp,
35a9c797 157 umem[i], pcpu->pc_umaddr[i], UMEMmap[i]);
e83ccfd7 158#if VAX780
b17fedcd
BJ
159 if (cpu == VAX_780)
160 ((struct uba_regs *)nxv)->uba_cr =
161 UBACR_IFS|UBACR_BRIE|
162 UBACR_USEFIE|UBACR_SUEFIE;
e83ccfd7 163#endif
3f3a34c3 164 numuba++;
327f6ec8
BJ
165 break;
166
167 case NEX_DR32:
5aa9d5ea 168 /* there can be more than one... are there other codes??? */
327f6ec8
BJ
169 printf("dr32");
170 goto unsupp;
171
172 case NEX_MEM4:
173 case NEX_MEM4I:
174 case NEX_MEM16:
175 case NEX_MEM16I:
d565635a 176 printf("mcr%d at tr%d\n", nmcr, nexnum);
30d13fef 177 if (nmcr >= 4) {
d565635a 178 printf("5 mcr's");
3f3a34c3
BJ
179 goto unsupp;
180 }
181 mcraddr[nmcr++] = (struct mcr *)nxv;
327f6ec8
BJ
182 break;
183
184 case NEX_MPM0:
185 case NEX_MPM1:
186 case NEX_MPM2:
187 case NEX_MPM3:
188 printf("mpm");
189 goto unsupp;
190
191 default:
192 printf("nexus type %x", nexcsr.nex_type);
30d13fef 193unsupp:
3f3a34c3 194 printf(" unsupported (at tr %d)\n", nexnum);
327f6ec8 195 continue;
d565635a
BJ
196unconfig:
197 printf(" not configured\n");
198 continue;
327f6ec8
BJ
199 }
200 }
e83ccfd7 201#if VAX780
81975711
BJ
202 if (cpu == VAX_780)
203 { int ubawatch(); timeout(ubawatch, (caddr_t)0, hz); }
e83ccfd7 204#endif
327f6ec8 205}
30d13fef 206
47fa50b1 207#if NMBA > 0
b721b0ed 208struct mba_device *mbaconfig();
327f6ec8
BJ
209/*
210 * Find devices attached to a particular mba
211 * and look for each device found in the massbus
212 * initialization tables.
213 */
3f3a34c3 214mbafind(nxv, nxp)
30d13fef 215 struct nexus *nxv, *nxp;
327f6ec8
BJ
216{
217 register struct mba_regs *mdp;
218 register struct mba_drv *mbd;
b721b0ed
BJ
219 register struct mba_device *mi;
220 register struct mba_slave *ms;
a0eab615
BJ
221 int dn, dt;
222 struct mba_device fnd;
327f6ec8 223
3f3a34c3 224 mdp = (struct mba_regs *)nxv;
5aa9d5ea
RE
225 mba_hd[nummba].mh_mba = mdp;
226 mba_hd[nummba].mh_physmba = (struct mba_regs *)nxp;
a0eab615 227 setscbnex(mbaintv[nummba]);
327f6ec8 228 fnd.mi_mba = mdp;
5aa9d5ea 229 fnd.mi_mbanum = nummba;
327f6ec8 230 for (mbd = mdp->mba_drv, dn = 0; mbd < &mdp->mba_drv[8]; mbd++, dn++) {
0cf493bf
BJ
231 if ((mbd->mbd_ds&MBDS_DPR) == 0)
232 continue;
327f6ec8
BJ
233 dt = mbd->mbd_dt & 0xffff;
234 if (dt == 0)
235 continue;
327f6ec8
BJ
236 if (dt == MBDT_MOH)
237 continue;
238 fnd.mi_drive = dn;
b721b0ed
BJ
239 if ((mi = mbaconfig(&fnd, dt)) && (dt & MBDT_TAP)) {
240 for (ms = mbsinit; ms->ms_driver; ms++)
241 if (ms->ms_driver == mi->mi_driver && ms->ms_alive == 0 &&
242 (ms->ms_ctlr == mi->mi_unit || ms->ms_ctlr=='?')) {
03fc3890 243 if ((*ms->ms_driver->md_slave)(mi, ms)) {
b721b0ed
BJ
244 printf("%s%d at %s%d slave %d\n",
245 ms->ms_driver->md_sname,
246 ms->ms_unit,
247 mi->mi_driver->md_dname,
248 mi->mi_unit,
249 ms->ms_slave);
d565635a
BJ
250 ms->ms_alive = 1;
251 ms->ms_ctlr = mi->mi_unit;
b721b0ed 252 }
327f6ec8 253 }
327f6ec8
BJ
254 }
255 }
a0eab615
BJ
256 mdp->mba_cr = MBCR_INIT;
257 mdp->mba_cr = MBCR_IE;
327f6ec8
BJ
258}
259
260/*
261 * Have found a massbus device;
262 * see if it is in the configuration table.
263 * If so, fill in its data.
264 */
b721b0ed 265struct mba_device *
327f6ec8 266mbaconfig(ni, type)
b721b0ed 267 register struct mba_device *ni;
327f6ec8
BJ
268 register int type;
269{
b721b0ed 270 register struct mba_device *mi;
327f6ec8 271 register short *tp;
71236e46 272 register struct mba_hd *mh;
327f6ec8 273
b721b0ed 274 for (mi = mbdinit; mi->mi_driver; mi++) {
327f6ec8
BJ
275 if (mi->mi_alive)
276 continue;
277 tp = mi->mi_driver->md_type;
278 for (mi->mi_type = 0; *tp; tp++, mi->mi_type++)
295446f8 279 if (*tp == (type&MBDT_TYPE))
327f6ec8
BJ
280 goto found;
281 continue;
282found:
283#define match(fld) (ni->fld == mi->fld || mi->fld == '?')
b721b0ed 284 if (!match(mi_drive) || !match(mi_mbanum))
327f6ec8 285 continue;
b721b0ed
BJ
286 printf("%s%d at mba%d drive %d",
287 mi->mi_driver->md_dname, mi->mi_unit,
288 ni->mi_mbanum, ni->mi_drive);
295446f8 289 printf("\n");
327f6ec8 290 mi->mi_alive = 1;
71236e46
BJ
291 mh = &mba_hd[ni->mi_mbanum];
292 mi->mi_hd = mh;
293 mh->mh_mbip[ni->mi_drive] = mi;
294 mh->mh_ndrive++;
327f6ec8
BJ
295 mi->mi_mba = ni->mi_mba;
296 mi->mi_drv = &mi->mi_mba->mba_drv[ni->mi_drive];
297 mi->mi_driver->md_info[mi->mi_unit] = mi;
298 mi->mi_mbanum = ni->mi_mbanum;
299 mi->mi_drive = ni->mi_drive;
8d2ea14f
BJ
300 if (mi->mi_dk && dkn < DK_NDRIVE)
301 mi->mi_dk = dkn++;
302 else
303 mi->mi_dk = -1;
b721b0ed
BJ
304 (*mi->mi_driver->md_attach)(mi);
305 return (mi);
327f6ec8 306 }
b721b0ed 307 return (0);
327f6ec8 308}
47fa50b1 309#endif
327f6ec8 310
3f3a34c3 311/*
30d13fef
BJ
312 * Fixctlrmask fixes the masks of the driver ctlr routines
313 * which otherwise save r10 and r11 where the interrupt and br
314 * level are passed through.
315 */
316fixctlrmask()
317{
b721b0ed
BJ
318 register struct uba_ctlr *um;
319 register struct uba_device *ui;
30d13fef
BJ
320 register struct uba_driver *ud;
321#define phys(a,b) ((b)(((int)(a))&0x7fffffff))
322
323 for (um = ubminit; ud = phys(um->um_driver, struct uba_driver *); um++)
71236e46 324 *phys(ud->ud_probe, short *) &= ~0xc00;
30d13fef 325 for (ui = ubdinit; ud = phys(ui->ui_driver, struct uba_driver *); ui++)
71236e46 326 *phys(ud->ud_probe, short *) &= ~0xc00;
30d13fef
BJ
327}
328
329/*
330 * Find devices on a UNIBUS.
331 * Uses per-driver routine to set <br,cvec> into <r11,r10>,
332 * and then fills in the tables, with help from a per-driver
333 * slave initialization routine.
3f3a34c3 334 */
35a9c797 335unifind(vubp, pubp, vumem, pumem, memmap)
30d13fef
BJ
336 struct uba_regs *vubp, *pubp;
337 caddr_t vumem, pumem;
35a9c797 338 struct pte *memmap;
327f6ec8 339{
a0eab615 340#ifndef lint
30d13fef 341 register int br, cvec; /* MUST BE r11, r10 */
a0eab615
BJ
342#else
343 /*
344 * Lint doesn't realize that these
345 * can be initialized asynchronously
346 * when devices interrupt.
347 */
348 register int br = 0, cvec = 0;
349#endif
b721b0ed
BJ
350 register struct uba_device *ui;
351 register struct uba_ctlr *um;
a0eab615 352 u_short *reg, addr;
30d13fef 353 struct uba_hd *uhp;
327f6ec8 354 struct uba_driver *udp;
8d2ea14f 355 int i, (**ivec)(), haveubasr = 0;
30d13fef
BJ
356
357 /*
358 * Initialize the UNIBUS, by freeing the map
359 * registers and the buffered data path registers
360 */
361 uhp = &uba_hd[numuba];
362 uhp->uh_map = (struct map *)calloc(UAMSIZ * sizeof (struct map));
c84ff1f9 363 rminit(uhp->uh_map, NUBMREG, 1, "uba", UAMSIZ);
30d13fef
BJ
364 switch (cpu) {
365#if VAX780
366 case VAX_780:
8d2ea14f
BJ
367 uhp->uh_bdpfree = (1<<NBDP780) - 1;
368 haveubasr = 1;
30d13fef
BJ
369 break;
370#endif
371#if VAX750
372 case VAX_750:
8d2ea14f 373 uhp->uh_bdpfree = (1<<NBDP750) - 1;
30d13fef 374 break;
81975711 375#endif
d54f1867
BJ
376#if VAX7ZZ
377 case VAX_7ZZ:
81975711 378 break;
30d13fef
BJ
379#endif
380 }
327f6ec8 381
30d13fef
BJ
382 /*
383 * Save virtual and physical addresses
384 * of adaptor, and allocate and initialize
385 * the UNIBUS interrupt vector.
386 */
387 uhp->uh_uba = vubp;
388 uhp->uh_physuba = pubp;
e83ccfd7 389/* HAVE TO DO SOMETHING SPECIAL FOR SECOND UNIBUS ON COMETS HERE */
30d13fef
BJ
390 if (numuba == 0)
391 uhp->uh_vec = UNIvec;
392 else
393 uhp->uh_vec = (int(**)())calloc(512);
394 for (i = 0; i < 128; i++)
395 uhp->uh_vec[i] =
396 scbentry(&catcher[i*2], SCB_ISTACK);
64614526
BJ
397 /*
398 * Set last free interrupt vector for devices with
399 * programmable interrupt vectors. Use is to decrement
400 * this number and use result as interrupt vector.
401 */
402 uhp->uh_lastiv = 0x200;
403
a0eab615 404 /* THIS IS A CHEAT: USING THE FACT THAT UMEM and NEXI ARE SAME SIZE */
35a9c797 405 nxaccess((struct nexus *)pumem, memmap);
3f3a34c3 406#if VAX780
8d2ea14f 407 if (haveubasr) {
30d13fef 408 vubp->uba_sr = vubp->uba_sr;
b721b0ed 409 vubp->uba_cr = UBACR_IFS|UBACR_BRIE;
327f6ec8 410 }
327f6ec8 411#endif
30d13fef
BJ
412 /*
413 * Map the first page of UNIBUS i/o
414 * space to the first page of memory
415 * for devices which will need to dma
416 * output to produce an interrupt.
417 */
b721b0ed 418 *(int *)(&vubp->uba_map[0]) = UBAMR_MRV;
30d13fef
BJ
419
420#define ubaddr(off) (u_short *)((int)vumem + ((off)&0x1fff))
421 /*
422 * Check each unibus mass storage controller.
423 * For each one which is potentially on this uba,
424 * see if it is really there, and if it is record it and
425 * then go looking for slaves.
426 */
427 for (um = ubminit; udp = um->um_driver; um++) {
428 if (um->um_ubanum != numuba && um->um_ubanum != '?')
429 continue;
430 addr = (u_short)um->um_addr;
431 reg = ubaddr(addr);
432 if (badaddr((caddr_t)reg, 2))
327f6ec8 433 continue;
3f3a34c3 434#if VAX780
8d2ea14f
BJ
435 if (haveubasr && vubp->uba_sr) {
436 vubp->uba_sr = vubp->uba_sr;
437 continue;
30d13fef 438 }
327f6ec8 439#endif
30d13fef 440 cvec = 0x200;
71236e46 441 i = (*udp->ud_probe)(reg);
3f3a34c3 442#if VAX780
8d2ea14f
BJ
443 if (haveubasr && vubp->uba_sr) {
444 vubp->uba_sr = vubp->uba_sr;
445 continue;
30d13fef 446 }
327f6ec8 447#endif
30d13fef
BJ
448 if (i == 0)
449 continue;
8d2ea14f
BJ
450 printf("%s%d at uba%d csr %o ",
451 udp->ud_mname, um->um_ctlr, numuba, addr);
30d13fef
BJ
452 if (cvec == 0) {
453 printf("zero vector\n");
454 continue;
455 }
456 if (cvec == 0x200) {
457 printf("didn't interrupt\n");
458 continue;
459 }
8d2ea14f 460 printf("vec %o, ipl %x\n", cvec, br);
30d13fef
BJ
461 um->um_alive = 1;
462 um->um_ubanum = numuba;
463 um->um_hd = &uba_hd[numuba];
464 um->um_addr = (caddr_t)reg;
465 udp->ud_minfo[um->um_ctlr] = um;
466 for (ivec = um->um_intr; *ivec; ivec++) {
467 um->um_hd->uh_vec[cvec/4] =
468 scbentry(*ivec, SCB_ISTACK);
469 cvec += 4;
470 }
471 for (ui = ubdinit; ui->ui_driver; ui++) {
472 if (ui->ui_driver != udp || ui->ui_alive ||
473 ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?' ||
474 ui->ui_ubanum != numuba && ui->ui_ubanum != '?')
327f6ec8 475 continue;
8d2ea14f 476 if ((*udp->ud_slave)(ui, reg)) {
30d13fef
BJ
477 ui->ui_alive = 1;
478 ui->ui_ctlr = um->um_ctlr;
479 ui->ui_ubanum = numuba;
480 ui->ui_hd = &uba_hd[numuba];
481 ui->ui_addr = (caddr_t)reg;
482 ui->ui_physaddr = pumem + (addr&0x1fff);
8d2ea14f 483 if (ui->ui_dk && dkn < DK_NDRIVE)
0801d37f 484 ui->ui_dk = dkn++;
8d2ea14f
BJ
485 else
486 ui->ui_dk = -1;
30d13fef
BJ
487 ui->ui_mi = um;
488 /* ui_type comes from driver */
489 udp->ud_dinfo[ui->ui_unit] = ui;
8d2ea14f
BJ
490 printf("%s%d at %s%d slave %d\n",
491 udp->ud_dname, ui->ui_unit,
492 udp->ud_mname, um->um_ctlr, ui->ui_slave);
71236e46 493 (*udp->ud_attach)(ui);
327f6ec8 494 }
30d13fef
BJ
495 }
496 }
497 /*
498 * Now look for non-mass storage peripherals.
499 */
500 for (ui = ubdinit; udp = ui->ui_driver; ui++) {
501 if (ui->ui_ubanum != numuba && ui->ui_ubanum != '?' ||
502 ui->ui_alive || ui->ui_slave != -1)
503 continue;
504 addr = (u_short)ui->ui_addr;
505 reg = ubaddr(addr);
506 if (badaddr((caddr_t)reg, 2))
507 continue;
508#if VAX780
8d2ea14f
BJ
509 if (haveubasr && vubp->uba_sr) {
510 vubp->uba_sr = vubp->uba_sr;
511 continue;
30d13fef
BJ
512 }
513#endif
514 cvec = 0x200;
64614526 515 i = (*udp->ud_probe)(reg, um->um_ctlr);
30d13fef 516#if VAX780
8d2ea14f
BJ
517 if (haveubasr && vubp->uba_sr) {
518 vubp->uba_sr = vubp->uba_sr;
519 continue;
327f6ec8 520 }
30d13fef
BJ
521#endif
522 if (i == 0)
523 continue;
8d2ea14f
BJ
524 printf("%s%d at uba%d csr %o ",
525 ui->ui_driver->ud_dname, ui->ui_unit, numuba, addr);
30d13fef
BJ
526 if (cvec == 0) {
527 printf("zero vector\n");
528 continue;
529 }
530 if (cvec == 0x200) {
531 printf("didn't interrupt\n");
532 continue;
533 }
8d2ea14f 534 printf("vec %o, ipl %x\n", cvec, br);
30d13fef
BJ
535 ui->ui_hd = &uba_hd[numuba];
536 for (ivec = ui->ui_intr; *ivec; ivec++) {
537 ui->ui_hd->uh_vec[cvec/4] =
538 scbentry(*ivec, SCB_ISTACK);
539 cvec += 4;
540 }
541 ui->ui_alive = 1;
542 ui->ui_ubanum = numuba;
543 ui->ui_addr = (caddr_t)reg;
544 ui->ui_physaddr = pumem + (addr&0x1fff);
8d2ea14f 545 ui->ui_dk = -1;
30d13fef
BJ
546 /* ui_type comes from driver */
547 udp->ud_dinfo[ui->ui_unit] = ui;
71236e46 548 (*udp->ud_attach)(ui);
327f6ec8
BJ
549 }
550}
551
a0eab615
BJ
552setscbnex(fn)
553 int (*fn)();
327f6ec8 554{
71236e46 555 register struct scb *scbp = &scb;
327f6ec8 556
71236e46
BJ
557 scbp->scb_ipl14[nexnum] = scbp->scb_ipl15[nexnum] =
558 scbp->scb_ipl16[nexnum] = scbp->scb_ipl17[nexnum] =
327f6ec8
BJ
559 scbentry(fn, SCB_ISTACK);
560}
561
562/*
563 * Make a nexus accessible at physical address phys
564 * by mapping kernel ptes starting at pte.
565 *
566 * WE LEAVE ALL NEXI MAPPED; THIS IS PERHAPS UNWISE
567 * SINCE MISSING NEXI DONT RESPOND. BUT THEN AGAIN
568 * PRESENT NEXI DONT RESPOND TO ALL OF THEIR ADDRESS SPACE.
569 */
30d13fef 570nxaccess(physa, pte)
a0eab615 571 struct nexus *physa;
327f6ec8
BJ
572 register struct pte *pte;
573{
a0eab615 574 register int i = btop(sizeof (struct nexus));
30d13fef 575 register unsigned v = btop(physa);
327f6ec8
BJ
576
577 do
578 *(int *)pte++ = PG_V|PG_KW|v++;
a0eab615 579 while (--i > 0);
327f6ec8
BJ
580 mtpr(TBIA, 0);
581}