|
|
1.1 ! root 1: #include "u.h" ! 2: #include "../port/lib.h" ! 3: #include "mem.h" ! 4: #include "dat.h" ! 5: #include "fns.h" ! 6: #include "io.h" ! 7: #include "../port/error.h" ! 8: ! 9: #include "devtab.h" ! 10: ! 11: #define ROMADDR 0x40000000 ! 12: #define ROMSIZE ((256*1024)/8) ! 13: ! 14: #define P_qlock(sel) if(sel >= 0){\ ! 15: qlock(&portpage);\ ! 16: PORTSELECT = portpage.select = sel;\ ! 17: }else ! 18: ! 19: #define P_qunlock(sel) if(sel >= 0){\ ! 20: qunlock(&portpage);\ ! 21: }else ! 22: ! 23: #define P_oper(sel, inst) P_qlock(sel); inst; P_qunlock(sel) ! 24: #define P_read(sel, addr, val, type) P_oper(sel, val = *(type *)(PORT+addr)) ! 25: #define P_write(sel, addr, val, type) P_oper(sel, *(type *)(PORT+addr) = val) ! 26: ! 27: enum ! 28: { ! 29: Qdir, ! 30: Qdata, ! 31: Qrom ! 32: }; ! 33: ! 34: Dirtab portdir[]={ ! 35: "data", {Qdata}, 0, 0666, ! 36: "rom", {Qrom}, ROMSIZE, 0444, ! 37: }; ! 38: ! 39: #define NPORT (sizeof portdir/sizeof(Dirtab)) ! 40: ! 41: #define Nportservice 8 ! 42: static int (*portservice[Nportservice])(void); ! 43: Portpage portpage; ! 44: static Lock intrlock; ! 45: ! 46: int ! 47: portprobe(char *what, int select, int addr, int rw, long val) ! 48: { ! 49: int time; ! 50: if (!conf.portispaged) ! 51: return 0; ! 52: P_qlock(select); ! 53: switch (rw) { ! 54: case -1: ! 55: val = *(uchar *)(PORT+addr); ! 56: break; ! 57: case -2: ! 58: val = *(ushort *)(PORT+addr); ! 59: break; ! 60: case -4: ! 61: val = *(long *)(PORT+addr); ! 62: break; ! 63: case 1: ! 64: *(uchar *)(PORT+addr) = val; ! 65: break; ! 66: case 2: ! 67: *(ushort *)(PORT+addr) = val; ! 68: break; ! 69: case 4: ! 70: *(long *)(PORT+addr) = val; ! 71: break; ! 72: default: ! 73: panic("portprobe"); ! 74: } ! 75: time = PORTSELECT & 0x1f; ! 76: P_qunlock(select); ! 77: if (what) { ! 78: print("%s at %d, %d", what, select, addr); ! 79: print("%s", time & 0x10 ? " -- NOT FOUND\n" : "\n"); ! 80: } ! 81: if (time & 0x10) ! 82: return -1; ! 83: return val; ! 84: } ! 85: ! 86: void ! 87: portreset(void) ! 88: { ! 89: portpage.select = -1; ! 90: lock(&portpage); ! 91: unlock(&portpage); ! 92: } ! 93: ! 94: void ! 95: portinit(void) ! 96: { ! 97: } ! 98: ! 99: Chan * ! 100: portattach(char *param) ! 101: { ! 102: return devattach('x', param); ! 103: } ! 104: ! 105: Chan * ! 106: portclone(Chan *c, Chan *nc) ! 107: { ! 108: return devclone(c, nc); ! 109: } ! 110: ! 111: int ! 112: portwalk(Chan *c, char *name) ! 113: { ! 114: return devwalk(c, name, portdir, NPORT, devgen); ! 115: } ! 116: ! 117: void ! 118: portstat(Chan *c, char *db) ! 119: { ! 120: devstat(c, db, portdir, NPORT, devgen); ! 121: } ! 122: ! 123: Chan * ! 124: portopen(Chan *c, int omode) ! 125: { ! 126: return devopen(c, omode, portdir, NPORT, devgen); ! 127: } ! 128: ! 129: void ! 130: portcreate(Chan *c, char *name, int omode, ulong perm) ! 131: { ! 132: USED(c, name, omode, perm); ! 133: error(Eperm); ! 134: } ! 135: ! 136: void ! 137: portclose(Chan *c) ! 138: { ! 139: USED(c); ! 140: } ! 141: ! 142: long ! 143: portread(Chan *c, char *a, long n, ulong offset) ! 144: { ! 145: long s, k; ! 146: if (n == 0) ! 147: return 0; ! 148: switch (c->qid.path & ~CHDIR) { ! 149: case Qdir: ! 150: return devdirread(c, a, n, portdir, NPORT, devgen); ! 151: case Qdata: ! 152: if (!conf.portispaged || (s = offset >> PORTSHIFT) > 0xff) ! 153: s = -1; ! 154: k = offset % PORTSIZE; ! 155: P_qlock(s); ! 156: switch ((int)n) { ! 157: case 1: ! 158: *a = PORT[k]; break; ! 159: case 2: ! 160: *(short *)a = *(short *)(PORT+k); break; ! 161: case 4: ! 162: *(long *)a = *(long *)(PORT+k); break; ! 163: default: ! 164: P_qunlock(s); ! 165: error(Ebadarg); ! 166: } ! 167: P_qunlock(s); ! 168: break; ! 169: case Qrom: ! 170: if(offset >= ROMSIZE) ! 171: return 0; ! 172: if(offset+n > ROMSIZE) ! 173: n = ROMSIZE - offset; ! 174: memmove(a, ((char*)ROMADDR)+offset, n); ! 175: return n; ! 176: break; ! 177: default: ! 178: panic("portread"); ! 179: } ! 180: return n; ! 181: } ! 182: ! 183: long ! 184: portwrite(Chan *c, char *a, long n, ulong offset) ! 185: { ! 186: long s, k; ! 187: if (n == 0) ! 188: return 0; ! 189: switch ((int)c->qid.path) { ! 190: case Qdata: ! 191: if (!conf.portispaged || (s = offset >> PORTSHIFT) > 0xff) ! 192: s = -1; ! 193: k = offset % PORTSIZE; ! 194: P_qlock(s); ! 195: switch ((int)n) { ! 196: case 1: ! 197: PORT[k] = *a; break; ! 198: case 2: ! 199: *(short *)(PORT+k) = *(short *)a; ! 200: break; ! 201: case 4: ! 202: *(long *)(PORT+k) = *(long *)a; ! 203: break; ! 204: default: ! 205: P_qunlock(s); ! 206: error(Ebadarg); ! 207: } ! 208: P_qunlock(s); ! 209: break; ! 210: default: ! 211: panic("portwrite"); ! 212: } ! 213: return n; ! 214: } ! 215: ! 216: void ! 217: portremove(Chan *c) ! 218: { ! 219: USED(c); ! 220: error(Eperm); ! 221: } ! 222: ! 223: void ! 224: portwstat(Chan *c, char *dp) ! 225: { ! 226: USED(c, dp); ! 227: error(Eperm); ! 228: } ! 229: ! 230: void ! 231: addportintr(int (*f)(void)) ! 232: { ! 233: int s = splhi(); ! 234: int (**p)(void); ! 235: ! 236: lock(&intrlock); ! 237: for (p=portservice; *p; p++) ! 238: if (*p == f) ! 239: goto out; ! 240: if (p >= &portservice[Nportservice-1]) ! 241: panic("addportintr"); ! 242: *p = f; ! 243: out: ! 244: unlock(&intrlock); ! 245: splx(s); ! 246: } ! 247: ! 248: void ! 249: devportintr(void) ! 250: { ! 251: int (**p)(void); ! 252: int i = 0; ! 253: ! 254: for (p=portservice; *p; p++) ! 255: i |= (**p)(); ! 256: ! 257: if (!i) ! 258: /*putstring("spurious portintr\n");*/ ! 259: panic("portintr"); ! 260: if (portpage.select >= 0) ! 261: PORTSELECT = portpage.select; ! 262: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.