BSD 4_1_snap development
[unix-history] / sys / dev / mem.c
CommitLineData
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
22mmread(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 }
81fault:
82 u.u_error = EFAULT;
83 return;
84}
85
86mmwrite(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 }
139fault:
140 u.u_error = EFAULT;
141 return;
142}
143
144/*
145 * UNIBUS Address Space <--> User Space transfer
146 */
147UNIcpy(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}