change ubaalloc macros to allow 2047 map registers on Q-bus,
[unix-history] / usr / src / sys / vax / uba / uba.c
CommitLineData
da7c5cc6 1/*
0880b18e 2 * Copyright (c) 1982, 1986 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
b00a6fef 6 * @(#)uba.c 7.6 (Berkeley) %G%
da7c5cc6 7 */
961945a8
SL
8
9#include "../machine/pte.h"
c14fd247 10
ff360633
JB
11#include "param.h"
12#include "systm.h"
13#include "map.h"
14#include "buf.h"
15#include "vm.h"
16#include "dir.h"
17#include "user.h"
18#include "proc.h"
19#include "conf.h"
8e4980c8 20#include "dkstat.h"
ff360633 21#include "kernel.h"
b7333467 22
896962b1
BJ
23#include "../vax/cpu.h"
24#include "../vax/mtpr.h"
25#include "../vax/nexus.h"
ff360633
JB
26#include "ubareg.h"
27#include "ubavar.h"
896962b1 28
63503d24 29#ifdef DW780
5af3f3f7
BJ
30char ubasr_bits[] = UBASR_BITS;
31#endif
32
8011f5df
MK
33#define spluba spl7 /* IPL 17 */
34
861488c5
KB
35#define BDPMASK 0xf0000000 /* see ubavar.h */
36
b7333467
BJ
37/*
38 * Do transfer on device argument. The controller
39 * and uba involved are implied by the device.
40 * We queue for resource wait in the uba code if necessary.
41 * We return 1 if the transfer was started, 0 if it was not.
861488c5
KB
42 *
43 * The onq argument must be zero iff the device is not on the
44 * queue for this UBA. If onq is set, the device must be at the
45 * head of the queue. In any case, if the transfer is started,
46 * the device will be off the queue, and if not, it will be on.
47 *
48 * Drivers that allocate one BDP and hold it for some time should
49 * set ud_keepbdp. In this case um_bdp tells which BDP is allocated
50 * to the controller, unless it is zero, indicating that the controller
51 * does not now have a BDP.
b7333467 52 */
861488c5 53ubaqueue(ui, onq)
5ab42896 54 register struct uba_device *ui;
861488c5 55 int onq;
b7333467 56{
5ab42896 57 register struct uba_ctlr *um = ui->ui_mi;
b7333467 58 register struct uba_hd *uh;
861488c5 59 register struct uba_driver *ud;
b7333467
BJ
60 register int s, unit;
61
62 uh = &uba_hd[um->um_ubanum];
861488c5 63 ud = um->um_driver;
8011f5df 64 s = spluba();
861488c5
KB
65 /*
66 * Honor exclusive BDP use requests.
67 */
68 if (ud->ud_xclu && uh->uh_users > 0 || uh->uh_xclu)
0801d37f 69 goto rwait;
861488c5
KB
70 if (ud->ud_keepbdp) {
71 /*
72 * First get just a BDP (though in fact it comes with
73 * one map register too).
74 */
75 if (um->um_bdp == 0) {
76 um->um_bdp = uballoc(um->um_ubanum,
77 (caddr_t)0, 0, UBA_NEEDBDP|UBA_CANTWAIT);
78 if (um->um_bdp == 0)
79 goto rwait;
80 }
81 /* now share it with this transfer */
82 um->um_ubinfo = ubasetup(um->um_ubanum,
83 um->um_tab.b_actf->b_actf,
84 um->um_bdp|UBA_HAVEBDP|UBA_CANTWAIT);
85 } else
86 um->um_ubinfo = ubasetup(um->um_ubanum,
87 um->um_tab.b_actf->b_actf, UBA_NEEDBDP|UBA_CANTWAIT);
0801d37f
BJ
88 if (um->um_ubinfo == 0)
89 goto rwait;
0801d37f 90 uh->uh_users++;
861488c5 91 if (ud->ud_xclu)
0801d37f 92 uh->uh_xclu = 1;
b7333467
BJ
93 splx(s);
94 if (ui->ui_dk >= 0) {
95 unit = ui->ui_dk;
96 dk_busy |= 1<<unit;
cc7ff771
BJ
97 dk_xfer[unit]++;
98 dk_wds[unit] += um->um_tab.b_actf->b_actf->b_bcount>>6;
b7333467 99 }
861488c5 100 if (onq)
b7333467 101 uh->uh_actf = ui->ui_forw;
861488c5 102 (*ud->ud_dgo)(um);
b7333467 103 return (1);
0801d37f 104rwait:
861488c5 105 if (!onq) {
0801d37f
BJ
106 ui->ui_forw = NULL;
107 if (uh->uh_actf == NULL)
108 uh->uh_actf = ui;
109 else
110 uh->uh_actl->ui_forw = ui;
111 uh->uh_actl = ui;
112 }
113 splx(s);
114 return (0);
115}
116
117ubadone(um)
5ab42896 118 register struct uba_ctlr *um;
0801d37f
BJ
119{
120 register struct uba_hd *uh = &uba_hd[um->um_ubanum];
121
28ca05a9 122 if (um->um_driver->ud_xclu)
0801d37f
BJ
123 uh->uh_xclu = 0;
124 uh->uh_users--;
861488c5
KB
125 if (um->um_driver->ud_keepbdp)
126 um->um_ubinfo &= ~BDPMASK; /* keep BDP for misers */
0801d37f 127 ubarelse(um->um_ubanum, &um->um_ubinfo);
b7333467 128}
c14fd247
BJ
129
130/*
3f3a34c3
BJ
131 * Allocate and setup UBA map registers, and bdp's
132 * Flags says whether bdp is needed, whether the caller can't
133 * wait (e.g. if the caller is at interrupt level).
c14fd247 134 *
b7333467 135 * Return value:
c14fd247
BJ
136 * Bits 0-8 Byte offset
137 * Bits 9-17 Start map reg. no.
138 * Bits 18-27 No. mapping reg's
139 * Bits 28-31 BDP no.
140 */
3f3a34c3 141ubasetup(uban, bp, flags)
b0a4a8c6
MK
142 int uban;
143 register struct buf *bp;
144 register int flags;
c14fd247 145{
3f3a34c3 146 register struct uba_hd *uh = &uba_hd[uban];
b0a4a8c6
MK
147 register struct pte *pte, *io;
148 register int npf;
553d288e 149 int pfnum, temp;
b0a4a8c6 150 int reg, bdp;
c14fd247 151 unsigned v;
c14fd247
BJ
152 struct proc *rp;
153 int a, o, ubinfo;
154
63503d24
MK
155#ifdef DW730
156 if (uh->uh_type == DW730)
157 flags &= ~UBA_NEEDBDP;
158#endif
159#ifdef QBA
160 if (uh->uh_type == QBA)
a3812a04
BJ
161 flags &= ~UBA_NEEDBDP;
162#endif
c14fd247
BJ
163 o = (int)bp->b_un.b_addr & PGOFSET;
164 npf = btoc(bp->b_bcount + o) + 1;
8011f5df 165 a = spluba();
5d30e870 166 while ((reg = rmalloc(uh->uh_map, (long)npf)) == 0) {
dd56673b
BJ
167 if (flags & UBA_CANTWAIT) {
168 splx(a);
3f3a34c3 169 return (0);
dd56673b 170 }
3f3a34c3 171 uh->uh_mrwant++;
174d2438 172 sleep((caddr_t)&uh->uh_mrwant, PSWP);
c14fd247 173 }
ee0fdd94
MK
174 if ((flags & UBA_NEED16) && reg + npf > 128) {
175 /*
176 * Could hang around and try again (if we can ever succeed).
177 * Won't help any current device...
178 */
179 rmfree(uh->uh_map, (long)npf, (long)reg);
180 splx(a);
181 return (0);
182 }
c14fd247 183 bdp = 0;
3f3a34c3 184 if (flags & UBA_NEEDBDP) {
8011f5df 185 while ((bdp = ffs((long)uh->uh_bdpfree)) == 0) {
3f3a34c3 186 if (flags & UBA_CANTWAIT) {
5d30e870 187 rmfree(uh->uh_map, (long)npf, (long)reg);
dd56673b 188 splx(a);
3f3a34c3
BJ
189 return (0);
190 }
191 uh->uh_bdpwant++;
174d2438 192 sleep((caddr_t)&uh->uh_bdpwant, PSWP);
c14fd247 193 }
658110d5 194 uh->uh_bdpfree &= ~(1 << (bdp-1));
64614526
BJ
195 } else if (flags & UBA_HAVEBDP)
196 bdp = (flags >> 28) & 0xf;
c14fd247 197 splx(a);
658110d5 198 reg--;
c14fd247 199 ubinfo = (bdp << 28) | (npf << 18) | (reg << 9) | o;
5ab42896 200 temp = (bdp << 21) | UBAMR_MRV;
c14fd247 201 if (bdp && (o & 01))
5ab42896 202 temp |= UBAMR_BO;
309cfbf4 203 if ((bp->b_flags & B_PHYS) == 0)
b0a4a8c6 204 pte = kvtopte(bp->b_un.b_addr);
309cfbf4
BJ
205 else if (bp->b_flags & B_PAGET)
206 pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)];
b0a4a8c6
MK
207 else {
208 rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc;
209 v = btop(bp->b_un.b_addr);
210 if (bp->b_flags & B_UAREA)
211 pte = &rp->p_addr[v];
212 else
213 pte = vtopte(rp, v);
214 }
63503d24 215 io = &uh->uh_mr[reg];
b0a4a8c6 216 while (--npf > 0) {
553d288e
KM
217 pfnum = pte->pg_pfnum;
218 if (pfnum == 0)
309cfbf4 219 panic("uba zero uentry");
553d288e
KM
220 pte++;
221 *(int *)io++ = pfnum | temp;
c14fd247 222 }
b0a4a8c6 223 *(int *)io = 0;
c14fd247
BJ
224 return (ubinfo);
225}
226
c14fd247 227/*
b7333467 228 * Non buffer setup interface... set up a buffer and call ubasetup.
c14fd247 229 */
3f3a34c3 230uballoc(uban, addr, bcnt, flags)
a0eab615 231 int uban;
c14fd247 232 caddr_t addr;
a0eab615 233 int bcnt, flags;
c14fd247 234{
89e0f717 235 struct buf ubabuf;
c14fd247 236
c14fd247
BJ
237 ubabuf.b_un.b_addr = addr;
238 ubabuf.b_flags = B_BUSY;
239 ubabuf.b_bcount = bcnt;
89e0f717 240 /* that's all the fields ubasetup() needs */
3f3a34c3 241 return (ubasetup(uban, &ubabuf, flags));
c14fd247
BJ
242}
243
b28deaf8 244/*
b7333467
BJ
245 * Release resources on uba uban, and then unblock resource waiters.
246 * The map register parameter is by value since we need to block
247 * against uba resets on 11/780's.
b28deaf8 248 */
3f3a34c3 249ubarelse(uban, amr)
b28deaf8 250 int *amr;
c14fd247 251{
3f3a34c3 252 register struct uba_hd *uh = &uba_hd[uban];
b7333467 253 register int bdp, reg, npf, s;
b28deaf8 254 int mr;
c14fd247 255
b7333467
BJ
256 /*
257 * Carefully see if we should release the space, since
258 * it may be released asynchronously at uba reset time.
259 */
8011f5df 260 s = spluba();
b28deaf8
BJ
261 mr = *amr;
262 if (mr == 0) {
b7333467
BJ
263 /*
264 * A ubareset() occurred before we got around
265 * to releasing the space... no need to bother.
266 */
267 splx(s);
b28deaf8
BJ
268 return;
269 }
88149598 270 *amr = 0;
c14fd247
BJ
271 bdp = (mr >> 28) & 0x0f;
272 if (bdp) {
63503d24 273 switch (uh->uh_type) {
b0a4a8c6
MK
274#ifdef DWBUA
275 case DWBUA:
276 BUA(uh->uh_uba)->bua_dpr[bdp] |= BUADPR_PURGE;
277 break;
278#endif
63503d24
MK
279#ifdef DW780
280 case DW780:
5ab42896 281 uh->uh_uba->uba_dpr[bdp] |= UBADPR_BNE;
5aa9d5ea
RE
282 break;
283#endif
63503d24
MK
284#ifdef DW750
285 case DW750:
5ab42896
BJ
286 uh->uh_uba->uba_dpr[bdp] |=
287 UBADPR_PURGE|UBADPR_NXM|UBADPR_UCE;
5aa9d5ea
RE
288 break;
289#endif
63503d24
MK
290 default:
291 break;
5aa9d5ea 292 }
b7333467 293 uh->uh_bdpfree |= 1 << (bdp-1); /* atomic */
3f3a34c3
BJ
294 if (uh->uh_bdpwant) {
295 uh->uh_bdpwant = 0;
174d2438 296 wakeup((caddr_t)&uh->uh_bdpwant);
c14fd247
BJ
297 }
298 }
b7333467
BJ
299 /*
300 * Put back the registers in the resource map.
ee0fdd94
MK
301 * The map code must not be reentered,
302 * nor can the registers be freed twice.
303 * Unblock interrupts once this is done.
b7333467 304 */
c14fd247
BJ
305 npf = (mr >> 18) & 0x3ff;
306 reg = ((mr >> 9) & 0x1ff) + 1;
5d30e870 307 rmfree(uh->uh_map, (long)npf, (long)reg);
b7333467
BJ
308 splx(s);
309
310 /*
311 * Wakeup sleepers for map registers,
312 * and also, if there are processes blocked in dgo(),
313 * give them a chance at the UNIBUS.
314 */
3f3a34c3
BJ
315 if (uh->uh_mrwant) {
316 uh->uh_mrwant = 0;
174d2438 317 wakeup((caddr_t)&uh->uh_mrwant);
c14fd247 318 }
861488c5 319 while (uh->uh_actf && ubaqueue(uh->uh_actf, 1))
b7333467 320 ;
c14fd247
BJ
321}
322
27bf6b55 323ubapurge(um)
5ab42896 324 register struct uba_ctlr *um;
27bf6b55
BJ
325{
326 register struct uba_hd *uh = um->um_hd;
327 register int bdp = (um->um_ubinfo >> 28) & 0x0f;
328
63503d24 329 switch (uh->uh_type) {
b0a4a8c6
MK
330#ifdef DWBUA
331 case DWBUA:
332 BUA(uh->uh_uba)->bua_dpr[bdp] |= BUADPR_PURGE;
333 break;
334#endif
63503d24
MK
335#ifdef DW780
336 case DW780:
5ab42896 337 uh->uh_uba->uba_dpr[bdp] |= UBADPR_BNE;
27bf6b55
BJ
338 break;
339#endif
63503d24
MK
340#ifdef DW750
341 case DW750:
5ab42896 342 uh->uh_uba->uba_dpr[bdp] |= UBADPR_PURGE|UBADPR_NXM|UBADPR_UCE;
27bf6b55
BJ
343 break;
344#endif
63503d24
MK
345 default:
346 break;
27bf6b55
BJ
347 }
348}
349
9305c2b9
BJ
350ubainitmaps(uhp)
351 register struct uba_hd *uhp;
352{
353
63503d24
MK
354 rminit(uhp->uh_map, (long)uhp->uh_memsize, (long)1, "uba", UAMSIZ);
355 switch (uhp->uh_type) {
b0a4a8c6
MK
356#ifdef DWBUA
357 case DWBUA:
358 uhp->uh_bdpfree = (1<<NBDPBUA) - 1;
359 break;
360#endif
63503d24
MK
361#ifdef DW780
362 case DW780:
9305c2b9
BJ
363 uhp->uh_bdpfree = (1<<NBDP780) - 1;
364 break;
365#endif
63503d24
MK
366#ifdef DW750
367 case DW750:
9305c2b9
BJ
368 uhp->uh_bdpfree = (1<<NBDP750) - 1;
369 break;
370#endif
63503d24 371 default:
9305c2b9 372 break;
9305c2b9
BJ
373 }
374}
375
b7333467
BJ
376/*
377 * Generate a reset on uba number uban. Then
378 * call each device in the character device table,
379 * giving it a chance to clean up so as to be able to continue.
380 */
3f3a34c3 381ubareset(uban)
b7333467 382 int uban;
2e74ef16 383{
2e74ef16 384 register struct cdevsw *cdp;
a3cb8f60 385 register struct uba_hd *uh = &uba_hd[uban];
49c84d3f 386 int s;
2e74ef16 387
8011f5df 388 s = spluba();
a3cb8f60
BJ
389 uh->uh_users = 0;
390 uh->uh_zvcnt = 0;
391 uh->uh_xclu = 0;
a3cb8f60
BJ
392 uh->uh_actf = uh->uh_actl = 0;
393 uh->uh_bdpwant = 0;
394 uh->uh_mrwant = 0;
9305c2b9 395 ubainitmaps(uh);
a3cb8f60
BJ
396 wakeup((caddr_t)&uh->uh_bdpwant);
397 wakeup((caddr_t)&uh->uh_mrwant);
5ab42896
BJ
398 printf("uba%d: reset", uban);
399 ubainit(uh->uh_uba);
ee0fdd94 400 ubameminit(uban);
512bbccd 401 for (cdp = cdevsw; cdp < cdevsw + nchrdev; cdp++)
3f3a34c3 402 (*cdp->d_reset)(uban);
4c3f4cb1 403 ifubareset(uban);
2e74ef16 404 printf("\n");
4ea0bfc4 405 splx(s);
2e74ef16 406}
3f3a34c3 407
b7333467
BJ
408/*
409 * Init a uba. This is called with a pointer
410 * rather than a virtual address since it is called
411 * by code which runs with memory mapping disabled.
412 * In these cases we really don't need the interrupts
413 * enabled, but since we run with ipl high, we don't care
414 * if they are, they will never happen anyways.
63503d24 415 * SHOULD GET POINTER TO UBA_HD INSTEAD OF UBA.
b7333467 416 */
5aa9d5ea
RE
417ubainit(uba)
418 register struct uba_regs *uba;
3f3a34c3 419{
63503d24 420 register struct uba_hd *uhp;
b0a4a8c6 421#ifdef QBA
63503d24 422 int isphys = 0;
b0a4a8c6 423#endif
3f3a34c3 424
63503d24
MK
425 for (uhp = uba_hd; uhp < uba_hd + numuba; uhp++) {
426 if (uhp->uh_uba == uba)
427 break;
428 if (uhp->uh_physuba == uba) {
b0a4a8c6 429#ifdef QBA
63503d24 430 isphys++;
b0a4a8c6 431#endif
63503d24
MK
432 break;
433 }
434 }
435 if (uhp >= uba_hd + numuba) {
436 printf("init unknown uba\n");
437 return;
438 }
439
440 switch (uhp->uh_type) {
b0a4a8c6
MK
441#ifdef DWBUA
442 case DWBUA:
443 BUA(uba)->bua_csr |= BUACSR_UPI;
444 /* give devices time to recover from power fail */
445 DELAY(500000);
446 break;
447#endif
63503d24
MK
448#ifdef DW780
449 case DW780:
5ab42896
BJ
450 uba->uba_cr = UBACR_ADINIT;
451 uba->uba_cr = UBACR_IFS|UBACR_BRIE|UBACR_USEFIE|UBACR_SUEFIE;
452 while ((uba->uba_cnfgr & UBACNFGR_UBIC) == 0)
453 ;
454 break;
455#endif
63503d24
MK
456#ifdef DW750
457 case DW750:
a3812a04 458#endif
63503d24
MK
459#ifdef DW730
460 case DW730:
fed9edca 461#endif
63503d24
MK
462#ifdef QBA
463 case QBA:
9d2503c6 464#endif
63503d24 465#if DW750 || DW730 || QBA
fed9edca
BJ
466 mtpr(IUR, 0);
467 /* give devices time to recover from power fail */
468/* THIS IS PROBABLY UNNECESSARY */
469 DELAY(500000);
470/* END PROBABLY UNNECESSARY */
63503d24
MK
471#ifdef QBA
472 /*
473 * Re-enable local memory access
474 * from the Q-bus.
475 */
476 if (uhp->uh_type == QBA) {
477 if (isphys)
478 *((char *)QIOPAGE630 + QIPCR) = Q_LMEAE;
479 else
480 *(uhp->uh_iopage + QIPCR) = Q_LMEAE;
481 }
482#endif QBA
5ab42896 483 break;
63503d24 484#endif DW750 || DW730 || QBA
5ab42896 485 }
3f3a34c3
BJ
486}
487
63503d24 488#ifdef DW780
3e04ba6a
BJ
489int ubawedgecnt = 10;
490int ubacrazy = 500;
ee0fdd94 491int zvcnt_max = 5000; /* in 8 sec */
b7333467 492/*
46bfb00b
JB
493 * This routine is called by the locore code to process a UBA
494 * error on an 11/780 or 8600. The arguments are passed
b7333467
BJ
495 * on the stack, and value-result (through some trickery).
496 * In particular, the uvec argument is used for further
497 * uba processing so the result aspect of it is very important.
498 * It must not be declared register.
499 */
5aa9d5ea 500/*ARGSUSED*/
ee0fdd94 501ubaerror(uban, uh, ipl, uvec, uba)
3f3a34c3
BJ
502 register int uban;
503 register struct uba_hd *uh;
ee0fdd94 504 int ipl, uvec;
3f3a34c3
BJ
505 register struct uba_regs *uba;
506{
507 register sr, s;
508
509 if (uvec == 0) {
45d4a789
MK
510 /*
511 * Declare dt as unsigned so that negative values
512 * are handled as >8 below, in case time was set back.
513 */
514 u_long dt = time.tv_sec - uh->uh_zvtime;
515
516 uh->uh_zvtotal++;
ee0fdd94 517 if (dt > 8) {
45d4a789 518 uh->uh_zvtime = time.tv_sec;
ee0fdd94
MK
519 uh->uh_zvcnt = 0;
520 }
521 if (++uh->uh_zvcnt > zvcnt_max) {
522 printf("uba%d: too many zero vectors (%d in <%d sec)\n",
523 uban, uh->uh_zvcnt, dt + 1);
524 printf("\tIPL 0x%x\n\tcnfgr: %b Adapter Code: 0x%x\n",
525 ipl, uba->uba_cnfgr&(~0xff), UBACNFGR_BITS,
526 uba->uba_cnfgr&0xff);
527 printf("\tsr: %b\n\tdcr: %x (MIC %sOK)\n",
528 uba->uba_sr, ubasr_bits, uba->uba_dcr,
529 (uba->uba_dcr&0x8000000)?"":"NOT ");
3f3a34c3
BJ
530 ubareset(uban);
531 }
3f3a34c3
BJ
532 return;
533 }
534 if (uba->uba_cnfgr & NEX_CFGFLT) {
5af3f3f7
BJ
535 printf("uba%d: sbi fault sr=%b cnfgr=%b\n",
536 uban, uba->uba_sr, ubasr_bits,
d2f165e5 537 uba->uba_cnfgr, NEXFLT_BITS);
3f3a34c3
BJ
538 ubareset(uban);
539 uvec = 0;
540 return;
541 }
542 sr = uba->uba_sr;
8011f5df 543 s = spluba();
ec28fe15
BJ
544 printf("uba%d: uba error sr=%b fmer=%x fubar=%o\n",
545 uban, uba->uba_sr, ubasr_bits, uba->uba_fmer, 4*uba->uba_fubar);
3f3a34c3
BJ
546 splx(s);
547 uba->uba_sr = sr;
5ab42896 548 uvec &= UBABRRVR_DIV;
3e04ba6a
BJ
549 if (++uh->uh_errcnt % ubawedgecnt == 0) {
550 if (uh->uh_errcnt > ubacrazy)
551 panic("uba crazy");
552 printf("ERROR LIMIT ");
553 ubareset(uban);
554 uvec = 0;
555 return;
556 }
3f3a34c3
BJ
557 return;
558}
559#endif
1c1f6ecf 560
ee0fdd94
MK
561/*
562 * Look for devices with unibus memory, allow them to configure, then disable
563 * map registers as necessary. Called during autoconfiguration and ubareset.
564 * The device ubamem routine returns 0 on success, 1 on success if it is fully
565 * configured (has no csr or interrupt, so doesn't need to be probed),
566 * and -1 on failure.
567 */
568ubameminit(uban)
569{
570 register struct uba_device *ui;
571 register struct uba_hd *uh = &uba_hd[uban];
572 caddr_t umembase = umem[uban] + 0x3e000, addr;
573#define ubaoff(off) ((int)(off) & 0x1fff)
574
575 uh->uh_lastmem = 0;
576 for (ui = ubdinit; ui->ui_driver; ui++) {
577 if (ui->ui_ubanum != uban && ui->ui_ubanum != '?')
578 continue;
579 if (ui->ui_driver->ud_ubamem) {
580 /*
581 * During autoconfiguration, need to fudge ui_addr.
582 */
583 addr = ui->ui_addr;
584 ui->ui_addr = umembase + ubaoff(addr);
585 switch ((*ui->ui_driver->ud_ubamem)(ui, uban)) {
586 case 1:
587 ui->ui_alive = 1;
588 /* FALLTHROUGH */
589 case 0:
590 ui->ui_ubanum = uban;
591 break;
592 }
593 ui->ui_addr = addr;
594 }
595 }
63503d24 596#ifdef DW780
ee0fdd94 597 /*
63503d24 598 * On a DW780, throw away any map registers disabled by rounding
ee0fdd94
MK
599 * the map disable in the configuration register
600 * up to the next 8K boundary, or below the last unibus memory.
601 */
63503d24 602 if (uh->uh_type == DW780) {
ee0fdd94
MK
603 register i;
604
605 i = btop(((uh->uh_lastmem + 8191) / 8192) * 8192);
606 while (i)
607 (void) rmget(uh->uh_map, 1, i--);
608 }
609#endif
610}
611
1c1f6ecf 612/*
002dfe8e
SL
613 * Allocate UNIBUS memory. Allocates and initializes
614 * sufficient mapping registers for access. On a 780,
615 * the configuration register is setup to disable UBA
616 * response on DMA transfers to addresses controlled
617 * by the disabled mapping registers.
63503d24 618 * On a DW780, should only be called from ubameminit, or in ascending order
ee0fdd94
MK
619 * from 0 with 8K-sized and -aligned addresses; freeing memory that isn't
620 * the last unibus memory would free unusable map registers.
621 * Doalloc is 1 to allocate, 0 to deallocate.
1c1f6ecf 622 */
002dfe8e
SL
623ubamem(uban, addr, npg, doalloc)
624 int uban, addr, npg, doalloc;
1c1f6ecf
BF
625{
626 register struct uba_hd *uh = &uba_hd[uban];
002dfe8e 627 register int a;
ee0fdd94 628 int s;
1c1f6ecf 629
ee0fdd94 630 a = (addr >> 9) + 1;
8011f5df 631 s = spluba();
ee0fdd94
MK
632 if (doalloc)
633 a = rmget(uh->uh_map, npg, a);
634 else
635 rmfree(uh->uh_map, (long)npg, (long)a);
636 splx(s);
1c1f6ecf 637 if (a) {
002dfe8e
SL
638 register int i, *m;
639
63503d24 640 m = (int *)&uh->uh_mr[a - 1];
002dfe8e 641 for (i = 0; i < npg; i++)
1c1f6ecf 642 *m++ = 0; /* All off, especially 'valid' */
ee0fdd94
MK
643 i = addr + npg * 512;
644 if (doalloc && i > uh->uh_lastmem)
645 uh->uh_lastmem = i;
646 else if (doalloc == 0 && i == uh->uh_lastmem)
647 uh->uh_lastmem = addr;
63503d24 648#ifdef DW780
002dfe8e
SL
649 /*
650 * On a 780, set up the map register disable
651 * field in the configuration register. Beware
ee0fdd94
MK
652 * of callers that request memory ``out of order''
653 * or in sections other than 8K multiples.
654 * Ubameminit handles such requests properly, however.
002dfe8e 655 */
63503d24 656 if (uh->uh_type == DW780) {
ee0fdd94
MK
657 i = uh->uh_uba->uba_cr &~ 0x7c000000;
658 i |= ((uh->uh_lastmem + 8191) / 8192) << 26;
659 uh->uh_uba->uba_cr = i;
a26646de
BF
660 }
661#endif
1c1f6ecf 662 }
002dfe8e 663 return (a);
1c1f6ecf 664}
8e61f556 665
413f33da 666#include "ik.h"
37ccce8f
JG
667#include "vs.h"
668#if NIK > 0 || NVS > 0
8e61f556
SL
669/*
670 * Map a virtual address into users address space. Actually all we
671 * do is turn on the user mode write protection bits for the particular
672 * page of memory involved.
673 */
674maptouser(vaddress)
675 caddr_t vaddress;
676{
677
b0a4a8c6 678 kvtopte(vaddress)->pg_prot = (PG_UW >> 27);
8e61f556
SL
679}
680
681unmaptouser(vaddress)
682 caddr_t vaddress;
683{
684
b0a4a8c6 685 kvtopte(vaddress)->pg_prot = (PG_KW >> 27);
8e61f556 686}
3b1e560f 687#endif