|
|
1.1 ! root 1: /* ! 2: * File: syscoh.c ! 3: * ! 4: * Purpose: Functions for the COHERENT-specific system call ! 5: * ! 6: * $Log: syscoh.c,v $ ! 7: * Revision 1.4 93/04/14 10:08:11 root ! 8: * r75 ! 9: * ! 10: * Revision 1.3 92/11/12 10:06:19 root ! 11: * Ker #68 ! 12: * ! 13: * Revision 1.2 92/11/09 17:11:25 root ! 14: * Just before adding vio segs. ! 15: * ! 16: * Revision 1.1 92/10/06 23:49:04 root ! 17: * Ker #64 ! 18: * ! 19: */ ! 20: ! 21: /* ! 22: * ---------------------------------------------------------------------- ! 23: * Includes. ! 24: */ ! 25: #include <sys/coherent.h> ! 26: #include <sys/con.h> ! 27: #include <errno.h> ! 28: ! 29: /* ! 30: * ---------------------------------------------------------------------- ! 31: * Definitions. ! 32: * Constants. ! 33: * Macros with argument lists. ! 34: * Typedefs. ! 35: * Enums. ! 36: */ ! 37: ! 38: /* ! 39: * ---------------------------------------------------------------------- ! 40: * Functions. ! 41: * Import Functions. ! 42: * Export Functions. ! 43: * Local Functions. ! 44: */ ! 45: int ucohcall(); ! 46: ! 47: static int devload(); ! 48: ! 49: /* ! 50: * ---------------------------------------------------------------------- ! 51: * Global Data. ! 52: * Import Variables. ! 53: * Export Variables. ! 54: * Local Variables. ! 55: */ ! 56: ! 57: /* ! 58: * ---------------------------------------------------------------------- ! 59: * Code. ! 60: */ ! 61: ! 62: /* ! 63: * Only allow this if running as superuser. ! 64: * ! 65: * a1 call type ! 66: * ---------- ---------- ! 67: * COH_PRINTF kernel printf ! 68: * COH_DEVLOAD call load() routine for device with major number a2 ! 69: * COH_SETBP a2=bp#,a3=addr,a4=type,a5=len; set kernel breakpoint ! 70: * COH_CLRBP a2=bp#; clear kernel breakpoint ! 71: * COH_REBOOT reboot ! 72: */ ! 73: ucohcall(a1,a2,a3,a4,a5,a6) ! 74: { ! 75: int ret = 0; ! 76: ! 77: if (!super()) { ! 78: SET_U_ERROR(EPERM, "cohcall, must be root"); ! 79: goto ucc_done; ! 80: } ! 81: ! 82: switch(a1) { ! 83: case COH_PRINTF: ! 84: printf(a2); ! 85: break; ! 86: case COH_DEVLOAD: ! 87: ret = devload(a2); ! 88: break; ! 89: case COH_SETBP: ! 90: ret = setbp(a2,a3,a4,a5); ! 91: break; ! 92: case COH_CLRBP: ! 93: ret = clrbp(a2); ! 94: break; ! 95: case COH_REBOOT: ! 96: ret = boot(); ! 97: break; ! 98: case COH_VIO: ! 99: ret = vio(a2,a3,a4,a5); ! 100: break; ! 101: case COH_SHM: ! 102: ret = coh_shm(a2,a3,a4,a5); ! 103: break; ! 104: case COH_WTEXT: ! 105: ret = cohWtext(a2,a3,a4); ! 106: break; ! 107: default: ! 108: SET_U_ERROR(EINVAL, "bad COH function"); ! 109: } ! 110: ucc_done: ! 111: return ret; ! 112: } ! 113: ! 114: /* ! 115: * Allow user to write to his own text segment. ! 116: */ ! 117: int ! 118: cohWtext(dest,src,numBytes) ! 119: { ! 120: if ((accdata(src, numBytes) ! 121: || accstack(src, numBytes) ! 122: || acctext(src, numBytes) ! 123: || accShm(src, numBytes)) ! 124: && acctext(dest, numBytes)) { ! 125: memcpy(dest, src, numBytes); ! 126: return 0; ! 127: } else ! 128: u.u_error = EINVAL; ! 129: } ! 130: ! 131: /* ! 132: * Test of shared memory support. ! 133: */ ! 134: int ! 135: coh_shm(x1, x2, x3, x4) ! 136: int x1, x2, x3, x4; ! 137: { ! 138: int index, base; ! 139: ! 140: switch (x1) { ! 141: case 0: ! 142: return shmAlloc(x2); ! 143: break; ! 144: case 1: ! 145: return shmFree(x2); ! 146: break; ! 147: case 2: ! 148: /* Since we are out of args, will use interface ! 149: * cohcall(COH_SHM, 2, numBytes, base+index, segp) ! 150: * to call shmAttach, using low bits of base to ! 151: * carry the index into p_shmsr. */ ! 152: ! 153: base = x3 & 0xFFFFF000; ! 154: index = x3 & 0x00000FFF; ! 155: if (index >= 0 && index < NSHMSEG) { ! 156: return shmAttach(index, x2, base, x4); ! 157: } else ! 158: SET_U_ERROR(EINVAL, "bad COH shm index"); ! 159: break; ! 160: case 3: ! 161: return shmDetach(x2); ! 162: break; ! 163: default: ! 164: SET_U_ERROR(EINVAL, "bad COH shm function"); ! 165: break; ! 166: } ! 167: return -1; ! 168: } ! 169: ! 170: /* ! 171: * Test of video io map support. ! 172: */ ! 173: int ! 174: vio(x1, x2, x3, x4) ! 175: int x1, x2, x3; ! 176: { ! 177: switch (x1) { ! 178: case 0: ! 179: return iomapOr(x2, x3); ! 180: break; ! 181: case 1: ! 182: return iomapAnd(x2, x3); ! 183: break; ! 184: case 2: ! 185: return kiopriv(x2, x3); ! 186: break; ! 187: case 3: ! 188: return mapPhysUser(x2, x3, x4); ! 189: break; ! 190: default: ! 191: SET_U_ERROR(EINVAL, "bad COH vio function"); ! 192: break; ! 193: } ! 194: return -1; ! 195: } ! 196: ! 197: /* ! 198: * Initialize a device. ! 199: */ ! 200: int ! 201: devload(maj_num) ! 202: int maj_num; ! 203: { ! 204: int ret = -1; ! 205: int mask = 1<<maj_num; ! 206: ! 207: if (dev_loaded & mask) { ! 208: SET_U_ERROR(EIO, "already loaded"); ! 209: goto dldone; ! 210: } ! 211: ! 212: if (drvl[maj_num].d_conp == 0) { ! 213: SET_U_ERROR(EIO, "no driver"); ! 214: goto dldone; ! 215: } ! 216: ! 217: if (drvl[maj_num].d_conp->c_load) { ! 218: (*drvl[maj_num].d_conp->c_load)(); ! 219: dev_loaded |= mask; ! 220: ret = 0; ! 221: } ! 222: dldone: ! 223: return ret; ! 224: } ! 225: ! 226: unsigned int DR0,DR1,DR2,DR3,DR7; ! 227: /* ! 228: * Set a kernel breakpoint. ! 229: */ ! 230: int ! 231: setbp(bp_num, addr, type, len) ! 232: unsigned int bp_num, addr, type, len; ! 233: { ! 234: /* Range check arguments. ! 235: * Update RAM images of writeable debug registers. ! 236: * Call routine (while in RING 1) which will cause GP fault. ! 237: * GP Fault handler (in RING 0) will copy RAM images to DR's. ! 238: */ ! 239: if (bp_num >= 4 || type >= 4 || len >= 4 || type == 2 || len == 2) { ! 240: SET_U_ERROR(EINVAL, "bad bp setting"); ! 241: return -1; ! 242: } ! 243: switch(bp_num) { ! 244: case 0: ! 245: DR0 = addr; ! 246: write_dr0(DR0); ! 247: DR7 |= ((type<<16)|(len<<18)|0x303); ! 248: break; ! 249: case 1: ! 250: DR1 = addr; ! 251: write_dr1(DR1); ! 252: DR7 |= ((type<<20)|(len<<22)|0x30C); ! 253: break; ! 254: case 2: ! 255: DR2 = addr; ! 256: write_dr2(DR2); ! 257: DR7 |= ((type<<24)|(len<<26)|0x330); ! 258: break; ! 259: case 3: ! 260: DR3 = addr; ! 261: write_dr3(DR3); ! 262: DR7 |= ((type<<28)|(len<<30)|0x3C0); ! 263: break; ! 264: } ! 265: write_dr7(DR7); ! 266: return 0; ! 267: } ! 268: ! 269: /* ! 270: * Clear a kernel breakpoint. ! 271: */ ! 272: int ! 273: clrbp(bp_num) ! 274: unsigned int bp_num; ! 275: { ! 276: /* Range check arguments. ! 277: * Update RAM images of writeable debug registers. ! 278: * Call routine (while in RING 1) which will cause GP fault. ! 279: * GP Fault handler (in RING 0) will copy RAM images to DR's. ! 280: */ ! 281: if (bp_num >= 4) { ! 282: SET_U_ERROR(EINVAL, "bad bp # to clear"); ! 283: return -1; ! 284: } ! 285: switch(bp_num) { ! 286: case 0: ! 287: DR7 &= ~0x3; ! 288: break; ! 289: case 1: ! 290: DR7 &= ~0xC; ! 291: break; ! 292: case 2: ! 293: DR7 &= ~0x30; ! 294: break; ! 295: case 3: ! 296: DR7 &= ~0xC0; ! 297: break; ! 298: } ! 299: if ((DR7 & 0xFF) == 0) ! 300: DR7 &= ~0x300; ! 301: write_dr7(DR7); ! 302: return 0; ! 303: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.