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