Commit | Line | Data |
---|---|---|
01395141 C |
1 | /* mem.c 4.3 81/03/08 */ |
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 ((caddr_t)u.u_offset < (caddr_t)&umbabeg && | |
51 | (caddr_t)u.u_offset + u.u_count >= (caddr_t)&umbabeg) | |
52 | goto fault; | |
53 | if ((caddr_t)u.u_offset >= (caddr_t)&umbabeg && | |
54 | (caddr_t)u.u_offset < (caddr_t)&umbaend) | |
55 | goto fault; | |
56 | if (!kernacc((caddr_t)u.u_offset, u.u_count, B_READ)) | |
57 | goto fault; | |
58 | if (copyout((caddr_t)u.u_offset, u.u_base, u.u_count)) | |
59 | goto fault; | |
60 | c = u.u_count; | |
61 | u.u_count = 0; | |
62 | u.u_base += c; | |
63 | u.u_offset += c; | |
64 | return; | |
65 | ||
66 | case 2: | |
67 | return; | |
68 | ||
69 | case 3: | |
70 | if (!kernacc((caddr_t)u.u_offset, u.u_count, B_READ)) | |
71 | goto fault; | |
72 | if (!useracc(u.u_base, u.u_count, B_WRITE)) | |
73 | goto fault; | |
74 | UNIcpy((caddr_t)u.u_offset, u.u_base, u.u_count, B_READ); | |
75 | c = u.u_count; | |
76 | u.u_count = 0; | |
77 | u.u_base += c; | |
78 | u.u_offset += c; | |
79 | return; | |
80 | } | |
81 | fault: | |
82 | u.u_error = EFAULT; | |
83 | return; | |
84 | } | |
85 | ||
86 | mmwrite(dev) | |
87 | { | |
88 | register int o; | |
89 | register unsigned c, v; | |
90 | ||
91 | switch (minor(dev)) { | |
92 | ||
93 | case 0: | |
94 | while (u.u_count != 0 && u.u_error == 0) { | |
95 | if (fubyte(u.u_base) == -1) | |
96 | goto fault; | |
97 | v = btop(u.u_offset); | |
98 | if (v >= physmem) | |
99 | goto fault; | |
100 | *(int *)mmap = v | (PG_V | PG_KW); | |
101 | mtpr(TBIS, vmmap); | |
102 | o = (int)u.u_offset & PGOFSET; | |
103 | c = min((unsigned)(NBPG - o), u.u_count); | |
104 | c = min(c, (unsigned)(NBPG - ((int)u.u_base&PGOFSET))); | |
105 | if (copyin(u.u_base, (caddr_t)&vmmap[o], c)) | |
106 | goto fault; | |
107 | u.u_count -= c; | |
108 | u.u_base += c; | |
109 | u.u_offset += c; | |
110 | } | |
111 | return; | |
112 | ||
113 | case 1: | |
114 | if (!kernacc((caddr_t)u.u_offset, u.u_count, B_WRITE)) | |
115 | goto fault; | |
116 | if (copyin(u.u_base, (caddr_t)u.u_offset, u.u_count)) | |
117 | goto fault; | |
118 | u.u_base += u.u_count; | |
119 | u.u_offset += u.u_count; | |
120 | u.u_count = 0; | |
121 | return; | |
122 | ||
123 | case 2: | |
124 | u.u_offset += u.u_count; | |
125 | u.u_count = 0; | |
126 | return; | |
127 | ||
128 | case 3: | |
129 | if (!kernacc((caddr_t)u.u_offset, u.u_count, B_WRITE)) | |
130 | goto fault; | |
131 | if (!useracc(u.u_base, u.u_count, B_READ)) | |
132 | goto fault; | |
133 | UNIcpy((caddr_t)u.u_offset, u.u_base, u.u_count, B_WRITE); | |
134 | u.u_base += u.u_count; | |
135 | u.u_offset += u.u_count; | |
136 | u.u_count = 0; | |
137 | return; | |
138 | } | |
139 | fault: | |
140 | u.u_error = EFAULT; | |
141 | return; | |
142 | } | |
143 | ||
144 | /* | |
145 | * UNIBUS Address Space <--> User Space transfer | |
146 | */ | |
147 | UNIcpy(uniadd, usradd, bknt, direct) | |
148 | caddr_t uniadd, usradd; | |
149 | unsigned bknt; | |
150 | { | |
151 | register short *from, *to; | |
152 | register int i; | |
153 | ||
154 | if (direct == B_READ) { | |
155 | from = (short *) uniadd; | |
156 | to = (short *) usradd; | |
157 | } else { | |
158 | from = (short *) usradd; | |
159 | to = (short *) uniadd; | |
160 | } | |
161 | for (i = (bknt>>1); i > 0; i--) | |
162 | *to++ = *from++; | |
163 | } |