|
|
1.1 root 1: /* mem.c 4.1 11/9/80 */
2:
3: /*
4: * Memory special file
5: * minor device 0 is physical memory
6: * minor device 1 is kernel memory
7: * minor device 2 is EOF/RATHOLE
8: * minor device 3 is unibus memory (addressed by shorts)
9: */
10:
11: #include "../h/param.h"
12: #include "../h/dir.h"
13: #include "../h/user.h"
14: #include "../h/conf.h"
15: #include "../h/buf.h"
16: #include "../h/systm.h"
17: #include "../h/pte.h"
18: #include "../h/mtpr.h"
19: #include "../h/vm.h"
20: #include "../h/cmap.h"
21:
22: mmread(dev)
23: {
24: register int o;
25: register unsigned c, v;
26:
27: switch (minor(dev)) {
28:
29: case 0:
30: while (u.u_count != 0 && u.u_error == 0) {
31: if (fubyte(u.u_base) == -1)
32: goto fault;
33: v = btop(u.u_offset);
34: if (v >= physmem)
35: goto fault;
36: *(int *)mmap = v | (PG_V | PG_KR);
37: mtpr(TBIS, vmmap);
38: o = (int)u.u_offset & PGOFSET;
39: c = min((unsigned)(NBPG - o), u.u_count);
40: c = min(c, (unsigned)(NBPG - ((int)u.u_base&PGOFSET)));
41: if (copyout((caddr_t)&vmmap[o], u.u_base, c))
42: goto fault;
43: u.u_count -= c;
44: u.u_base += c;
45: u.u_offset += c;
46: }
47: return;
48:
49: case 1:
50: if (u.u_uid != 0) {
51: if ((caddr_t)u.u_offset < (caddr_t)&umbabeg &&
52: (caddr_t)u.u_offset + u.u_count >= (caddr_t)&umbabeg)
53: goto fault;
54: if ((caddr_t)u.u_offset >= (caddr_t)&umbabeg &&
55: (caddr_t)u.u_offset < (caddr_t)&umbaend)
56: goto fault;
57: }
58: if (!kernacc((caddr_t)u.u_offset, u.u_count, B_READ))
59: goto fault;
60: if (copyout((caddr_t)u.u_offset, u.u_base, u.u_count))
61: goto fault;
62: c = u.u_count;
63: u.u_count = 0;
64: u.u_base += c;
65: u.u_offset += c;
66: return;
67:
68: case 2:
69: return;
70:
71: case 3:
72: if (!kernacc((caddr_t)u.u_offset, u.u_count, B_READ))
73: goto fault;
74: if (!useracc(u.u_base, u.u_count, B_WRITE))
75: goto fault;
76: UNIcpy((caddr_t)u.u_offset, u.u_base, u.u_count, B_READ);
77: c = u.u_count;
78: u.u_count = 0;
79: u.u_base += c;
80: u.u_offset += c;
81: return;
82: }
83: fault:
84: u.u_error = EFAULT;
85: return;
86: }
87:
88: mmwrite(dev)
89: {
90: register int o;
91: register unsigned c, v;
92:
93: switch (minor(dev)) {
94:
95: case 0:
96: while (u.u_count != 0 && u.u_error == 0) {
97: if (fubyte(u.u_base) == -1)
98: goto fault;
99: v = btop(u.u_offset);
100: if (v >= physmem)
101: goto fault;
102: *(int *)mmap = v | (PG_V | PG_KW);
103: mtpr(TBIS, vmmap);
104: o = (int)u.u_offset & PGOFSET;
105: c = min((unsigned)(NBPG - o), u.u_count);
106: c = min(c, (unsigned)(NBPG - ((int)u.u_base&PGOFSET)));
107: if (copyin(u.u_base, (caddr_t)&vmmap[o], c))
108: goto fault;
109: u.u_count -= c;
110: u.u_base += c;
111: u.u_offset += c;
112: }
113: return;
114:
115: case 1:
116: if (!kernacc((caddr_t)u.u_offset, u.u_count, B_WRITE))
117: goto fault;
118: if (copyin(u.u_base, (caddr_t)u.u_offset, u.u_count))
119: goto fault;
120: u.u_base += u.u_count;
121: u.u_offset += u.u_count;
122: u.u_count = 0;
123: return;
124:
125: case 2:
126: u.u_offset += u.u_count;
127: u.u_count = 0;
128: return;
129:
130: case 3:
131: if (!kernacc((caddr_t)u.u_offset, u.u_count, B_WRITE))
132: goto fault;
133: if (!useracc(u.u_base, u.u_count, B_READ))
134: goto fault;
135: UNIcpy((caddr_t)u.u_offset, u.u_base, u.u_count, B_WRITE);
136: u.u_base += u.u_count;
137: u.u_offset += u.u_count;
138: u.u_count = 0;
139: return;
140: }
141: fault:
142: u.u_error = EFAULT;
143: return;
144: }
145:
146: /*
147: * UNIBUS Address Space <--> User Space transfer
148: */
149: UNIcpy(uniadd, usradd, bknt, direct)
150: caddr_t uniadd, usradd;
151: unsigned bknt;
152: {
153: register short *from, *to;
154: register int i;
155:
156: if (direct == B_READ) {
157: from = (short *) uniadd;
158: to = (short *) usradd;
159: } else {
160: from = (short *) usradd;
161: to = (short *) uniadd;
162: }
163: for (i = (bknt>>1); i > 0; i--)
164: *to++ = *from++;
165: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.