seems to work with csdel0 and csdel2 set to 500
[unix-history] / usr / src / sys / vax / uba / uba.c
CommitLineData
f86df66c 1/* uba.c 3.2 %G% */
c14fd247
BJ
2
3#include "../h/param.h"
4#include "../h/map.h"
5#include "../h/pte.h"
6#include "../h/uba.h"
7#include "../h/buf.h"
8#include "../h/dir.h"
9#include "../h/user.h"
10#include "../h/proc.h"
11#include "../h/vm.h"
12
13/*
14 * Allocate as many contiguous UBA mapping registers
15 * as are necessary to do transfer of bcnt bytes
16 * to/from location baddr. Wait for enough map registers.
17 *
18 * Bdpflg is non-zero if a "buffered data path" (BDP) is
19 * to be used, else 0 -> use direct data path (DDP). Return
20 *
21 * Bits 0-8 Byte offset
22 * Bits 9-17 Start map reg. no.
23 * Bits 18-27 No. mapping reg's
24 * Bits 28-31 BDP no.
25 */
26ubasetup(bp, bdpflg)
27struct buf *bp;
28{
29 register int temp, i;
30 int npf, reg, bdp;
31 unsigned v;
32 register struct pte *pte, *io;
33 struct proc *rp;
34 int a, o, ubinfo;
35
36 v = btop(bp->b_un.b_addr);
37 o = (int)bp->b_un.b_addr & PGOFSET;
38 npf = btoc(bp->b_bcount + o) + 1;
39 a = spl6();
40 while ((reg = malloc(ubamap, npf)) == 0) {
41 umrwant++;
42 sleep((caddr_t)ubamap, PSWP);
43 }
44 reg--;
45 bdp = 0;
46 if (bdpflg)
47 while ((bdp = malloc(bdpmap, 1)) == 0) {
48 bdpwant++;
49 sleep((caddr_t)bdpmap, PSWP);
50 }
51 splx(a);
52 ubinfo = (bdp << 28) | (npf << 18) | (reg << 9) | o;
53 io = &(((struct uba_regs *)UBA0)->uba_map[reg]);
54 temp = (bdp << 21) | MRV;
55 rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc;
56 if (bdp && (o & 01))
57 temp |= BO;
58 if (bp->b_flags & B_UAREA) {
59 for (i = UPAGES - bp->b_bcount / NBPG; i < UPAGES; i++) {
60 if (rp->p_addr[i].pg_pfnum == 0)
61 panic("uba: zero upage");
62 *(int *)io++ = rp->p_addr[i].pg_pfnum | temp;
63 }
64 } else if ((bp->b_flags & B_PHYS) == 0) {
65 v &= 0x1fffff; /* drop to physical addr */
66 while (--npf != 0)
67 *(int *)io++ = v++ | temp;
68 } else {
69 if (bp->b_flags & B_PAGET)
70 pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)];
71 else
72 pte = vtopte(rp, v);
73 while (--npf != 0) {
74 if (pte->pg_pfnum == 0)
75 panic("uba zero uentry");
76 *(int *)io++ = pte++->pg_pfnum | temp;
77 }
78 }
79 *(int *)io++ = 0;
80 return (ubinfo);
81}
82
83struct buf ubabuf;
84/*
85 * Non buffer unibus interface... set up a buffer and call ubasetup.
86 */
87uballoc(addr, bcnt, bdpflg)
88 caddr_t addr;
89 unsigned short bcnt;
90{
91 register int a, ubinfo;
92
93 a = spl6();
94 while (ubabuf.b_flags & B_BUSY) {
95 ubabuf.b_flags |= B_WANTED;
96 sleep((caddr_t)&ubabuf, PRIUBA);
97 }
98 ubabuf.b_un.b_addr = addr;
99 ubabuf.b_flags = B_BUSY;
100 ubabuf.b_bcount = bcnt;
101 splx(a);
102 ubinfo = ubasetup(&ubabuf, bdpflg);
103 ubabuf.b_flags &= ~B_BUSY;
104 if (ubabuf.b_flags & B_WANTED)
105 wakeup((caddr_t)&ubabuf);
106 return (ubinfo);
107}
108
109ubafree(mr)
110 int mr;
111{
112 register int bdp, reg, npf, a;
113
114 a = spl6();
115 bdp = (mr >> 28) & 0x0f;
116 if (bdp) {
117 ((struct uba_regs *)UBA0)->uba_dpr[bdp] |= BNE; /* purge */
118 mfree(bdpmap, 1, bdp);
119 if (bdpwant) {
120 bdpwant = 0;
121 wakeup((caddr_t)bdpmap);
122 }
123 }
124 npf = (mr >> 18) & 0x3ff;
125 reg = ((mr >> 9) & 0x1ff) + 1;
126 mfree(ubamap, npf, reg);
127 if (umrwant) {
128 umrwant = 0;
129 wakeup((caddr_t)ubamap);
130 }
131 splx(a);
132}
133
134ubainit()
135{
136
137 mfree(ubamap, 496, 1);
138 mfree(bdpmap, 15, 1);
139}