|
|
1.1 root 1: /*
2: * general UNIBUS map setup routines
3: */
4:
5: #include "sys/param.h"
6: #include "sys/ubaddr.h"
7: #include "sys/map.h"
8: #include "sys/uba.h"
9: #include "sys/buf.h"
10: #include "sys/stream.h"
11: #include "sys/vmmac.h"
12: #include "sys/pte.h"
13:
14: extern struct uba uba[];
15: extern struct block cblock[];
16: extern struct buf *cblkbuf[];
17: extern int blkcnt, blkbcnt;
18:
19: extern uaddr_t ubmsetmap();
20:
21: /*
22: * init data structures:
23: * grab a place to store map for the stream buffers
24: */
25:
26: ubmstart(u)
27: int u;
28: {
29: register struct uba *ub;
30: register struct buf *bp;
31:
32: ub = &uba[u];
33: if ((bp = geteblk()) == NULL)
34: return (0);
35: if ((blkbcnt*sizeof(ubm_t) + blkbcnt*sizeof(uaddr_t)) > bp->b_bcount) {
36: printf("ub%d: too many stream bufs\n", u);
37: brelse(bp);
38: return (0);
39: }
40: clrbuf(bp);
41: ub->sbmap = (ubm_t *)bp->b_un.b_addr;
42: ub->sbaddr = (uaddr_t *)(ub->sbmap + blkbcnt);
43: ub->shmap = 0;
44: return (1);
45: }
46:
47: /*
48: * after hardware reset:
49: * clear out junk for stream data
50: */
51: ubminit(u)
52: int u;
53: {
54: register struct uba *ub;
55: register int i;
56:
57: ub = &uba[u];
58: for (i = 0; i < blkbcnt; i++)
59: if (ub->sbmap[i]) {
60: ubmfree(u, ub->sbmap[i]);
61: ub->sbmap[i] = 0;
62: }
63: if (ub->shmap) {
64: ubmfree(u, ub->shmap);
65: ub->shmap = 0;
66: }
67: }
68:
69: /*
70: * general map-allocation routine
71: */
72:
73: ubm_t
74: ubmalloc(u, size, flag)
75: int u;
76: int size;
77: register int flag;
78: {
79: register struct uba *ub;
80: int base, nreg, path;
81: int s;
82:
83: ub = &uba[u];
84: nreg = btoc(size);
85: if ((flag & UPAG) == 0)
86: nreg++; /* allow for alignment */
87: nreg++; /* allow for endmarker for DW780 */
88: s = spl6();
89: while ((base = rmalloc(ub->map, nreg)) == 0) {
90: if ((flag & USLP) == 0)
91: return (0);
92: ub->flags |= UBMWANT;
93: sleep((caddr_t)ub->map, PZERO);
94: }
95: splx(s);
96: if (flag & UBDP)
97: path = ubmapath(u);
98: else
99: path = 0;
100: return ((base<<UMFIRST) | ((nreg-UMSZERO)<<UMSIZE) | (path<<UMDP));
101: }
102:
103: ubmfree(u, um)
104: ubm_t um;
105: {
106: register struct uba *ub;
107: register int path;
108: register int s;
109:
110: if (um == NOMAP)
111: return;
112: ub = &uba[u];
113: s = spl6();
114: if ((path = ubmpath(um)) != 0) {
115: ubmflush(u, path);
116: ub->path |= 1<<path;
117: }
118: rmfree(ub->map, ubmsize(um), ubmfirst(um));
119: if (ub->flags & UBMWANT) {
120: wakeup((caddr_t)ub->map);
121: ub->flags &=~ UBMWANT;
122: }
123: splx(s);
124: }
125:
126: /*
127: * general-purpose address mapper
128: * for kernel address space
129: * don't use this if there's a better choice below
130: */
131:
132: uaddr_t
133: ubmaddr(u, cp, size, um)
134: int u;
135: caddr_t cp;
136: ubm_t um;
137: int size;
138: {
139: register int off;
140:
141: off = (int)cp & PGOFSET;
142: return (ubmsetmap(u, &Sysmap[btop((int)cp & ~KSTART)],
143: btoc(size + off), um) + off);
144: }
145:
146: /*
147: * allocate/set maps for various kinds of object
148: * ubmxxx returns a map sufficient for the object;
149: * ubadxxx sets the map, and returns a unibus-space address
150: * sometimes ubmxxx will return NOMAP,
151: * which means the space was pre-mapped (and any data path will be ignored)
152: */
153:
154:
155: /*
156: * io buffers
157: */
158:
159: ubm_t
160: ubmbuf(u, bp, flags)
161: int u;
162: register struct buf *bp;
163: int flags;
164: {
165:
166: if ((bp->b_flags & B_PHYS) == 0)
167: flags |= UPAG;
168: return (ubmalloc(u, bp->b_bcount, flags));
169: }
170:
171: uaddr_t
172: ubadbuf(u, bp, um)
173: int u;
174: register struct buf *bp;
175: ubm_t um;
176: {
177: register int off;
178:
179: off = (int)bp->b_un.b_addr & PGOFSET;
180: return (ubmsetmap(u, btopte(bp), btoc(bp->b_bcount + off), um) + off);
181: }
182:
183: /*
184: * stream blocks
185: * headers (and the tiny bit of data in them) pre-mapped
186: * the rest of the data mapped a buf at a time, when first touched
187: */
188:
189: ubm_t
190: ubmblk(u, bp, flags)
191: int u;
192: register struct block *bp;
193: int flags;
194: {
195: register int i;
196: register struct uba *ub;
197: register struct buf *bf;
198:
199: ub = &uba[u];
200: flags &=~ UBDP;
201: if ((i = bp->bufix) == NOBUFIX) { /* data all in the header */
202: if (ub->shmap)
203: return (NOMAP);
204: if ((ub->shmap = ubmalloc(u, blkcnt*sizeof(struct block), flags)) == 0)
205: return (0);
206: ub->shaddr = ubmaddr(u, (char *)cblock, blkcnt*sizeof(struct block), ub->shmap);
207: return (NOMAP);
208: }
209: if (ub->sbmap[i]) /* this buf already mapped */
210: return (NOMAP);
211: bf = cblkbuf[i];
212: if ((ub->sbmap[i] = ubmbuf(u, bf, flags)) == 0)
213: return (0);
214: ub->sbaddr[i] = ubmsetmap(u, btopte(bf), btoc(bf->b_bcount), ub->sbmap[i]);
215: return (NOMAP);
216: }
217:
218: /*
219: * ubadwptr returns the unibus address of the write pointer
220: * ubadrptr for the read pointer
221: */
222:
223: uaddr_t
224: ubadwptr(u, bp, um)
225: int u;
226: register struct block *bp;
227: ubm_t um;
228: {
229: register struct uba *ub;
230: register int i;
231:
232: ub = &uba[u];
233: if ((i = bp->bufix) == NOBUFIX)
234: return ((uaddr_t)(bp->wptr-(u_char *)cblock + (int)ub->shaddr));
235: if (ub->sbmap[i] == 0)
236: panic("ubadwptr");
237: return (ub->sbaddr[i]+bp->wptr-(u_char *)cblkbuf[i]->b_un.b_addr);
238: }
239:
240: uaddr_t
241: ubadrptr(u, bp, um)
242: int u;
243: register struct block *bp;
244: ubm_t um;
245: {
246: register struct uba *ub;
247: register int i;
248:
249: ub = &uba[u];
250: if ((i = bp->bufix) == NOBUFIX)
251: return ((uaddr_t)(bp->rptr-(u_char *)cblock + (int)ub->shaddr));
252: if (ub->sbmap[i] == 0)
253: panic("ubadrptr");
254: return (ub->sbaddr[i]+bp->rptr-(u_char *)cblkbuf[i]->b_un.b_addr);
255: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.