|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.