|
|
1.1 root 1: /*
2: * these routines are written in C until the 386 compiler/assembler
3: * are available
4: *
5: * Copyright (c) Ciaran O'Donnell, Bievres (FRANCE), 1991
6: */
7:
8: #include <sys/debug.h>
9: #include <kernel/reg.h>
10:
11: #include <sys/coherent.h>
12: #include <sys/clist.h>
13: #include <sys/errno.h>
14: #include <sys/inode.h>
15: #include <sys/proc.h>
16: #include <sys/seg.h>
17: #include <signal.h>
18: #include <sys/uproc.h>
19: #include <sys/buf.h>
20:
21: #define min(a, b) ((a) < (b) ? (a) : (b))
22:
23: /*
24: * dmacopy()
25: *
26: * Copy "npage" 4 kbyte pages from phys addr "from" to phys addr "to".
27: */
28:
29: dmacopy(npage, from, to)
30: long npage;
31: cseg_t *from, *to;
32: {
33: int work = workAlloc (); /* Get a virtual click pair. */
34:
35: ASSERT (npage > 0);
36:
37: for (;;) {
38: ptable1_v [work] = * from ++ | SEG_SRW;
39: ptable1_v [work + 1] = * to ++ | SEG_SRW;
40: memcpy (ctob (work + 1), ctob (work), NBPC);
41:
42: if (-- npage == 0)
43: break;
44:
45: mmuupd (); /* flush paging TLB */
46: }
47:
48: workFree(work);
49: }
50:
51: /*
52: * dmaclear()
53: *
54: * Given a byte count, and a system global address, zero-fill the memory.
55: */
56:
57: void
58: dmaclear (nbytes, to)
59: long nbytes;
60: paddr_t to;
61: {
62: unsigned off;
63: int n;
64: cseg_t *base;
65: int work = workAlloc (); /* Get a virtual click pair. */
66:
67: off = to & (NBPC - 1);
68: base = & sysmem.u.pbase [btocrd (to)];
69: n = min (nbytes, NBPC - off);
70: ptable1_v [work] = * base ++ | SEG_SRW;
71:
72: memset (ctob (work) + off, 0, n);
73: nbytes -= n;
74:
75: while (nbytes > 0) {
76: n = min (nbytes, NBPC);
77: ptable1_v [work] = * base ++ | SEG_SRW;
78: mmuupd ();
79:
80: memset (ctob (work), 0, n);
81: nbytes -= n;
82: }
83:
84: workFree(work);
85: }
86:
87: /*
88: * dmain()
89: *
90: * Copy in "nbytes" from system global address "to" to kernel address
91: * "vaddr".
92: */
93: dmain(nbytes, to, vaddr)
94: long nbytes;
95: paddr_t to;
96: caddr_t vaddr;
97: {
98: unsigned off;
99: unsigned n, n1;
100: cseg_t* base;
101: int work = workAlloc (); /* Get a virtual click pair. */
102:
103: off = to & (NBPC - 1);
104: base = & sysmem.u.pbase [btocrd (to)];
105:
106: n = min (nbytes, NBPC - off);
107: ptable1_v [work] = * base ++ | SEG_SRW;
108:
109: memcpy (vaddr, ctob (work) + off, n);
110: vaddr += n;
111: nbytes -= n;
112:
113: while (nbytes > 0) {
114: n = min (nbytes, NBPC);
115: ptable1_v [work] = * base ++ | SEG_SRW;
116: mmuupd ();
117:
118: memcpy (vaddr, ctob (work), n);
119: vaddr += n;
120: nbytes -= n;
121: }
122:
123: workFree (work);
124: }
125:
126: /*
127: * dmaout()
128: *
129: * Copy out "nbytes" from kernel address "vaddr" to system global address
130: * "to".
131: */
132: dmaout(nbytes, to, vaddr)
133: long nbytes;
134: paddr_t to;
135: caddr_t vaddr;
136: {
137: unsigned off;
138: unsigned n, n1;
139: cseg_t *base;
140: int work = workAlloc (); /* Get a virtual click pair. */
141:
142: off = to & (NBPC - 1);
143: base = & sysmem.u.pbase [btocrd (to)];
144:
145: n = min (nbytes, NBPC - off);
146: ptable1_v [work] = * base ++ | SEG_SRW;
147:
148: memcpy (ctob (work) + off, vaddr, n);
149: vaddr += n;
150: nbytes -= n;
151:
152: while (nbytes > 0) {
153: n = min (nbytes, NBPC);
154: ptable1_v [work] = * base ++ | SEG_SRW;
155: mmuupd ();
156:
157: memcpy (ctob (work), vaddr, n);
158: vaddr += n;
159: nbytes -= n;
160: }
161:
162: workFree(work);
163: }
164:
165: /*
166: * dmaio2()
167: *
168: * Copy in "nbytes" from an I/O port "port" to the system global address
169: * "to".
170: */
171: dmaio2(nbytes, to, port)
172: long nbytes, port;
173: paddr_t to;
174: {
175: unsigned off;
176: int n;
177: cseg_t *base;
178: int work = workAlloc (); /* Get a virtual click pair. */
179:
180: off = to & (NBPC - 1);
181: base = & sysmem.u.pbase [btocrd (to)];
182:
183: n = min (nbytes, NBPC - off);
184: ptable1_v [work] = * base ++ | SEG_SRW;
185:
186: io2seg (n, ctob (work) + off, port);
187: nbytes -= n;
188:
189: while (nbytes > 0) {
190: n = min (nbytes, NBPC);
191: ptable1_v [work] = * base ++ | SEG_SRW;
192: mmuupd ();
193: io2seg(n, ctob (work), port);
194: nbytes -= n;
195: }
196:
197: workFree(work);
198: }
199:
200: /*
201: * dma2io()
202: *
203: * Copy out "nbytes" from the system global address "from" to an I/O port
204: * "port".
205: */
206: dma2io(nbytes, to, port)
207: long nbytes, port;
208: paddr_t to;
209: {
210: unsigned off;
211: int n;
212: cseg_t *base;
213: int work = workAlloc (); /* Get a virtual click pair. */
214:
215: off = to & (NBPC - 1);
216: base = & sysmem.u.pbase [btocrd (to)];
217:
218: n = min (nbytes, NBPC - off);
219: ptable1_v [work] = * base ++ | SEG_SRW;
220:
221: seg2io (n, ctob (work) + off, port);
222: nbytes -= n;
223:
224: while (nbytes > 0) {
225: n = min (nbytes, NBPC);
226: ptable1_v [work] = * base ++ | SEG_SRW;
227: mmuupd ();
228: seg2io (n, ctob (work), port);
229: nbytes -= n;
230: }
231:
232: workFree(work);
233: }
234:
235: /*
236: * pxcopy()
237: *
238: * copy "n" bytes of data at kernel address "v" from address "uo" in:
239: * system global address space (space & SEG_VIRT)
240: * physical memory ! (space & SEG_VIRT)
241: * Rights are determined by (space & ~ SEG_VIRT):
242: * "v" can be anywhere in kernel address space SEG_386_KD
243: * "v" must be an address accessible to the user SEG_386_UD
244: * Up to one click of data can be copied. No alignment restrictions
245: * on "uo" apply.
246: */
247: pxcopy(uo, v, n, space)
248: unsigned uo;
249: char *v;
250: register int n;
251: {
252: cseg_t * base;
253: int save;
254: int err;
255: int work;
256:
257: if (n > NBPC)
258: return 0;
259:
260: work = workAlloc ();
261:
262: if (space & SEG_VIRT) {
263: space &= ~ SEG_VIRT;
264: base = & sysmem.u.pbase [btocrd (uo)];
265: ptable1_v [work] = * base ++ | SEG_SRW;
266: ptable1_v [work + 1] = * base ++ | SEG_SRW;
267: } else {
268: ptable1_v [work] = (uo & ~ (NBPC - 1)) + SEG_SRW;
269: ptable1_v [work + 1] = (uo & ~ (NBPC - 1)) + NBPC + SEG_SRW;
270: }
271:
272: save = setspace (space);
273: err = kucopy (ctob (work) + (uo & (NBPC - 1)), v, n);
274: setspace (save);
275:
276: workFree (work);
277: return err;
278: }
279:
280:
281: /*
282: * xpcopy()
283: *
284: * copy "n" bytes of data from kernel address "v" to address "uo" in:
285: * system global address space (space&SEG_VIRT)
286: * physical memory !(space&SEG_VIRT)
287: * Rights are determined by (space&~SEG_VIRT):
288: * "v" can be anywhere in kernel address space SEG_386_KD
289: * "v" must be an address accessible to the user SEG_386_UD
290: * Up to one click of data can be copied. No alignment restrictions on "uo"
291: * apply.
292: */
293:
294: xpcopy(v, uo, n, space)
295: char *v;
296: unsigned uo;
297: register int n;
298: {
299: cseg_t * base;
300: int save;
301: int err;
302: int work;
303:
304: if (n > NBPC)
305: return 0;
306:
307: work = workAlloc ();
308:
309: if (space & SEG_VIRT) {
310: space &= ~ SEG_VIRT;
311: base = & sysmem.u.pbase [btocrd (uo)];
312: ptable1_v [work] = * base ++ | SEG_SRW;
313: ptable1_v [work + 1] = * base ++ | SEG_SRW;
314: } else {
315: ptable1_v [work] = (uo & ~ (NBPC - 1)) + SEG_SRW;
316: ptable1_v [work + 1] = (uo & ~ (NBPC - 1)) + NBPC + SEG_SRW;
317: }
318:
319: save = setspace (space);
320: err = ukcopy (v, ctob (work) + (uo & (NBPC - 1)), n);
321: setspace (save);
322:
323: workFree (work);
324: return err;
325: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.