|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)mem.c 1.1 86/02/03 Copyr 1985 Sun Micro";
3: #endif
4:
5: /*
6: * Copyright (c) 1985 by Sun Microsystems, Inc.
7: */
8:
9: /*
10: * Memory special file
11: */
12:
13: #include "../h/param.h"
14: #include "../h/dir.h"
15: #include "../h/user.h"
16: #include "../h/conf.h"
17: #include "../h/buf.h"
18: #include "../h/systm.h"
19: #include "../h/vm.h"
20: #include "../h/cmap.h"
21:
22: #include "../machine/pte.h"
23: #include "../machine/mmu.h"
24: #include "../machine/cpu.h"
25: #include "../machine/eeprom.h"
26:
27: #define M_MEM 0 /* /dev/mem - physical main memory */
28: #define M_KMEM 1 /* /dev/kmem - virtual kernel memory & I/O */
29: #define M_NULL 2 /* /dev/null - EOF & Rathole */
30: #define M_MBMEM 3 /* /dev/mbmem - (not supported) */
31: #define M_MBIO 4 /* /dev/mbio - (not supported) */
32: #define M_VME16D16 5 /* /dev/vme16d16 - VME 16bit addr/16bit data */
33: #define M_VME24D16 6 /* /dev/vme24d16 - VME 24bit addr/16bit data */
34: #define M_VME32D16 7 /* /dev/vme32d16 - VME 32bit addr/16bit data */
35: #define M_VME16D32 8 /* /dev/vme16d32 - VME 16bit addr/32bit data */
36: #define M_VME24D32 9 /* /dev/vme24d32 - VME 24bit addr/32bit data */
37: #define M_VME32D32 10 /* /dev/vme32d32 - VME 32bit addr/32bit data */
38: #define M_EEPROM 11 /* /dev/eeprom - on board eeprom device */
39: #define M_KMEMR 12 /* /dev/kmemr - public part of kernel memory
40: * (read only) */
41:
42: /*
43: * Check bus type memory spaces for accessibility on this machine
44: */
45: mmopen(dev, flag)
46: dev_t dev;
47: {
48: switch (minor(dev)) {
49: case M_MEM:
50: case M_KMEM:
51: case M_KMEMR:
52: case M_NULL:
53: /* standard devices */
54: break;
55:
56: case M_EEPROM:
57: /* all Sun-3 machines must have EEPROM */
58: break;
59:
60: case M_VME16D16:
61: case M_VME24D16:
62: case M_VME32D16:
63: case M_VME16D32:
64: case M_VME24D32:
65: case M_VME32D32:
66: /* SUN3_50 is the only Sun-3 machine w/o VMEbus */
67: if (cpu == CPU_SUN3_50) {
68: u.u_error = EINVAL;
69: return;
70: }
71: break;
72:
73: case M_MBMEM:
74: case M_MBIO:
75: default:
76: /* Unsupported or unknown type */
77: u.u_error = EINVAL;
78: return;
79: }
80: return;
81: }
82:
83: mmread(dev)
84: dev_t dev;
85: {
86: mmrw(dev, B_READ);
87: }
88:
89: mmwrite(dev)
90: dev_t dev;
91: {
92: mmrw(dev, B_WRITE);
93: }
94:
95: mmrw(dev, rw)
96: dev_t dev;
97: {
98: register int o;
99: register u_int c, v;
100: register struct iovec *iov;
101: int error = 0;
102: int pgsp;
103:
104: while (u.u_count > 0 && u.u_error == 0) {
105: switch (minor(dev)) {
106:
107: case M_MEM:
108: v = btop(u.u_offset);
109: if (v >= physmem)
110: goto fault;
111: mapin(mmap, btop(vmmap), v, 1, PG_V | PG_KR);
112: o = (int)u.u_offset & PGOFSET;
113: c = min((u_int)(NBPG - o), u.u_count);
114: c = min(c, (u_int)(NBPG -((int)u.u_base&PGOFSET)));
115: iomove((caddr_t)&vmmap[o], c, rw);
116: break;
117:
118: case M_KMEM:
119: c = u.u_count;
120: if (kernacc((caddr_t)u.u_offset, c, rw))
121: iomove((caddr_t)u.u_offset, c, rw);
122: else
123: mmpeekio(rw, (caddr_t)u.u_offset, (int)c);
124: break;
125:
126: case M_KMEMR:
127: if (rw == B_WRITE)
128: goto fault;
129: c = u.u_count;
130: if ((u_long)u.u_offset < (u_long)KERNELBASE)
131: goto fault;
132: if (!kernacc((caddr_t)u.u_offset, c, B_READ))
133: goto fault;
134: iomove((caddr_t)u.u_offset, c, rw);
135: break;
136:
137: case M_NULL:
138: if (rw == B_WRITE) {
139: u.u_offset += u.u_count;
140: u.u_count = 0;
141: }
142: return;
143:
144: case M_EEPROM:
145: mmeeprom(rw, (caddr_t)u.u_offset, u.u_count);
146: break;
147:
148: case M_VME16D16:
149: if (u.u_offset >= VME16_SIZE)
150: goto fault;
151: v = u.u_offset + VME16_BASE;
152: pgsp = PGT_VME_D16;
153: goto vme;
154:
155: case M_VME16D32:
156: if (u.u_offset >= VME16_SIZE)
157: goto fault;
158: v = u.u_offset + VME16_BASE;
159: pgsp = PGT_VME_D32;
160: goto vme;
161:
162: case M_VME24D16:
163: if (u.u_offset >= VME24_SIZE)
164: goto fault;
165: v = u.u_offset + VME24_BASE;
166: pgsp = PGT_VME_D16;
167: goto vme;
168:
169: case M_VME24D32:
170: if (u.u_offset >= VME24_SIZE)
171: goto fault;
172: v = u.u_offset + VME24_BASE;
173: pgsp = PGT_VME_D32;
174: goto vme;
175:
176: case M_VME32D16:
177: pgsp = PGT_VME_D16;
178: goto vme;
179:
180: case M_VME32D32:
181: pgsp = PGT_VME_D32;
182: /* FALL THROUGH */
183:
184: vme:
185: v = btop(v);
186:
187: mapin(mmap, btop(vmmap), pgsp | v, 1,
188: rw == B_WRITE ? PG_V|PG_KW : PG_V|PG_KR);
189: o = (int)u.u_offset & PGOFSET;
190: c = min((u_int)(NBPG - o), u.u_count);
191: mmpeekio(rw, &vmmap[o], (int)c);
192: break;
193:
194: }
195: }
196: return;
197: fault:
198: u.u_error = EFAULT;
199: return;
200: }
201:
202: mmpeekio(rw, addr, len)
203: caddr_t addr;
204: int len;
205: {
206: register int c, o;
207: short sh;
208: char cm;
209:
210: while (len > 0) {
211: if ((len|(int)addr) & 1) {
212: c = sizeof (char);
213: if (rw == B_READ) {
214: if ((o = peekc(addr)) == -1)
215: goto fault;
216: cm = o;
217: }
218: iomove((caddr_t)&cm, c, rw);
219: if (u.u_error)
220: return;
221: if (rw == B_WRITE && pokec(addr, c))
222: goto fault;
223: } else {
224: c = sizeof (short);
225: if (rw == B_READ) {
226: if ((o = peek((short *)addr)) == -1)
227: goto fault;
228: sh = o;
229: }
230: iomove((caddr_t)&sh, c, rw);
231: if (u.u_error)
232: return;
233: if (rw == B_WRITE && poke((short *)addr, sh))
234: goto fault;
235: }
236: addr += c;
237: len -= c;
238: }
239: return;
240: fault:
241: u.u_error = EFAULT;
242: return;
243: }
244:
245: /*
246: * If eeprombusy is true, then the eeprom has just
247: * been written to and cannot be read or written
248: * until the required 10 MS has passed. It is
249: * assumed that the only way the EEPROM is written
250: * is thru the mmeeprom routine.
251: */
252: int eeprombusy = 0;
253:
254: mmeepromclear()
255: {
256:
257: eeprombusy = 0;
258: wakeup((caddr_t)&eeprombusy);
259: }
260:
261: mmeeprom(rw, addr, len)
262: caddr_t addr;
263: int len;
264: {
265: int o, oo;
266: int s;
267: char c;
268:
269: if ((int)addr > EEPROM_SIZE)
270: return (EFAULT);
271:
272: while (len > 0) {
273: if ((int)addr == EEPROM_SIZE)
274: goto fault; /* EOF */
275:
276: s = splclock();
277: while (eeprombusy)
278: sleep((caddr_t)&eeprombusy, PUSER);
279: (void) splx(s);
280:
281: if (rw == B_WRITE) {
282: iomove((caddr_t)&c, 1, rw);
283: if (u.u_error)
284: return;
285: o = c;
286: if ((oo = peekc(EEPROM_ADDR + addr)) == -1)
287: goto fault;
288: /*
289: * Check to make sure that the data is actually
290: * changing before committing to doing the write.
291: * This avoids the unneeded eeprom lock out
292: * and reduces the number of times the eeprom
293: * is actually written to.
294: */
295: if (o != oo) {
296: if (pokec(EEPROM_ADDR + addr, (char)o))
297: goto fault;
298: /*
299: * Block out access to the eeprom for
300: * two clock ticks (longer than > 10 MS).
301: */
302: eeprombusy = 1;
303: timeout(mmeepromclear, (caddr_t)0, 2);
304: }
305: } else {
306: if ((o = peekc(EEPROM_ADDR + addr)) == -1)
307: goto fault;
308: c = o;
309: iomove((caddr_t)&c, 1, rw);
310: if (u.u_error)
311: return;
312: }
313: addr += sizeof (char);
314: len -= sizeof (char);
315: }
316: return;
317: fault:
318: u.u_error = EFAULT;
319: return;
320: }
1.1.1.2 ! root 321:
! 322: /*ARGSUSED*/
! 323: mmmmap(dev, off, prot)
! 324: dev_t dev;
! 325: off_t off;
! 326: {
! 327: int pf;
! 328:
! 329: switch (minor(dev)) {
! 330:
! 331: case M_MEM:
! 332: pf = btop(off);
! 333: if (pf < physmem)
! 334: return (PGT_OBMEM | pf);
! 335: break;
! 336:
! 337: case M_VME16D16:
! 338: if (off >= VME16_SIZE)
! 339: break;
! 340: return (PGT_VME_D16 | btop(off + VME16_BASE));
! 341:
! 342: case M_VME16D32:
! 343: if (off >= VME16_SIZE)
! 344: break;
! 345: return (PGT_VME_D32 | btop(off + VME16_BASE));
! 346:
! 347: case M_VME24D16:
! 348: if (off >= VME24_SIZE)
! 349: break;
! 350: return (PGT_VME_D16 | btop(off + VME24_BASE));
! 351:
! 352: case M_VME24D32:
! 353: if (off >= VME24_SIZE)
! 354: break;
! 355: return (PGT_VME_D32 | btop(off + VME24_BASE));
! 356:
! 357: case M_VME32D16:
! 358: return (PGT_VME_D16 | btop(off));
! 359:
! 360: case M_VME32D32:
! 361: return (PGT_VME_D32 | btop(off));
! 362:
! 363: }
! 364: return (-1);
! 365: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.