|
|
1.1 ! root 1: /* ! 2: * KMC11 microprocessor driver ! 3: */ ! 4: #include "kmc.h" ! 5: #if NKMC > 0 ! 6: /* this driver supports ONE kmc ONLY */ ! 7: /* it should be modified to support only kmc11b's too */ ! 8: ! 9: /* nonstandard crap */ ! 10: typedef unsigned short ushort; ! 11: #define lobyte(X) (((unsigned char *)&X)[0]) ! 12: #define hibyte(X) (((unsigned char *)&X)[1]) ! 13: ! 14: #include "../h/param.h" ! 15: #include "../h/systm.h" ! 16: #include "../h/kmc.h" ! 17: #include "../h/pte.h" ! 18: #include "../h/map.h" ! 19: #include "../h/buf.h" ! 20: #include "../h/ubareg.h" ! 21: #include "../h/ubavar.h" ! 22: #include "../h/conf.h" ! 23: #include "../h/dir.h" ! 24: #include "../h/user.h" ! 25: ! 26: struct kmc { ! 27: char k_stat; ! 28: char k_type; ! 29: } kmc[NKMC]; ! 30: ! 31: #define KMC11A 1 ! 32: #define KMC11B 2 ! 33: #define KASIZE 1024 ! 34: #define KBSIZE 4096 ! 35: ! 36: #define RUN (1<<7) ! 37: #define MCLR (1<<6) ! 38: #define CWRT (1<<5) ! 39: #define LUB (1<<4) ! 40: #define LUA (1<<3) ! 41: #define ROMO (1<<2) ! 42: #define ROMI (1<<1) ! 43: #define STEP (1<<0) ! 44: ! 45: #define RDYO 0200 ! 46: #define RDYI 020 ! 47: #define RQI 0200 ! 48: #define IEI 01 ! 49: #define IEO 020 ! 50: ! 51: #define STYPE 017 ! 52: #define SRUN 020 ! 53: #define SRINT 040 ! 54: #define SOPEN 0100 ! 55: ! 56: struct device { ! 57: union { ! 58: char b[8]; ! 59: ushort w[4]; ! 60: } un; ! 61: }; ! 62: ! 63: #define bsel0 un.b[0] ! 64: #define bsel1 un.b[1] ! 65: #define bsel2 un.b[2] ! 66: #define bsel3 un.b[3] ! 67: #define bsel4 un.b[4] ! 68: #define bsel5 un.b[5] ! 69: #define bsel6 un.b[6] ! 70: #define bsel7 un.b[7] ! 71: #define sel0 un.w[0] ! 72: #define sel2 un.w[1] ! 73: #define sel4 un.w[2] ! 74: #define sel6 un.w[3] ! 75: ! 76: int kmcwritten; ! 77: int kmcprobe(), kmcattach(), kmcxint(); ! 78: struct uba_device *kmcdinfo[NKMC]; ! 79: unsigned short kmcstd[] = { 0}; ! 80: struct uba_driver kmcdriver = { ! 81: kmcprobe, 0, kmcattach, 0, kmcstd, "kmc", kmcdinfo ! 82: }; ! 83: ! 84: int (*kdirint)(); ! 85: int (*kdixint)(); ! 86: ! 87: kmcprobe(reg) ! 88: caddr_t reg; ! 89: { register int br, cvec; /* don't touch */ ! 90: register struct device *kp = (struct device *)reg; ! 91: register s; ! 92: ! 93: #ifdef lint ! 94: br = 0; cvec = br; br = cvec; ! 95: #endif ! 96: s = spl7(); ! 97: kp->bsel1 = MCLR; ! 98: splx(s); ! 99: kp->bsel1 = ROMI; ! 100: kp->sel4 = 0200; /* bus request */ ! 101: kp->sel6 = 0121111; /* mov csr4,obr */ ! 102: kp->bsel1 = ROMI|STEP; ! 103: DELAY(50); ! 104: kp->bsel1 = 0; ! 105: return(1); ! 106: } ! 107: ! 108: kmcattach(ui) ! 109: register struct uba_device *ui; ! 110: {} ! 111: ! 112: kmcopen(dev, flag) ! 113: dev_t dev; ! 114: { register struct device *kp; ! 115: register struct kmc *tp; ! 116: register sav; ! 117: ! 118: dev = minor(dev); ! 119: if (dev>=NKMC || (tp = &kmc[dev])->k_stat&SOPEN) { ! 120: u.u_error = ENXIO; ! 121: return; ! 122: } ! 123: kmcwritten = 0; ! 124: tp->k_stat |= SOPEN; ! 125: if (tp->k_type==0) { ! 126: kp = ((struct device *)kmcdinfo[dev]->ui_addr); ! 127: kp->bsel1 = ROMO; ! 128: kp->sel4 = 0; ! 129: sav = kp->sel6; ! 130: kp->sel6 = ~sav; ! 131: if (kp->sel6 != sav) { ! 132: tp->k_type = KMC11B; ! 133: kp->sel6 = sav; ! 134: } else ! 135: tp->k_type = KMC11A; ! 136: kp->bsel1 = 0; ! 137: } ! 138: } ! 139: ! 140: kmcclose(dev) ! 141: dev_t dev; ! 142: { ! 143: dev = minor(dev); ! 144: if(dev >= NKMC) ! 145: return; ! 146: kmc[dev].k_stat &= ~SOPEN; ! 147: if (kmcwritten) ! 148: kdireload(); ! 149: } ! 150: ! 151: kmcread(dev) ! 152: dev_t dev; ! 153: { register struct device *kp; ! 154: register ad; ! 155: int dsize; ! 156: ushort sav; ! 157: ! 158: dev = minor(dev); ! 159: if(dev >= NKMC) { ! 160: u.u_error = ENXIO; ! 161: return; ! 162: } ! 163: if (kmc[dev].k_stat&SRUN) ! 164: return; ! 165: dsize = (kmc[dev].k_type==KMC11A)?KASIZE:KBSIZE; ! 166: kp = ((struct device *)kmcdinfo[dev]->ui_addr); ! 167: kp->bsel1 = 0; ! 168: do { ! 169: ad = u.u_offset; ! 170: if (ad<dsize*2) { ! 171: if (ad&1) { ! 172: u.u_error = ENXIO; ! 173: break; ! 174: } ! 175: ad >>= 1; ! 176: kp->bsel1 = ROMO; ! 177: kp->sel4 = ad; ! 178: passc(kp->bsel6); ! 179: passc(kp->bsel7); ! 180: kp->bsel1 = 0; ! 181: } else if (ad -= dsize*2, ad<dsize) { ! 182: kp->bsel1 = ROMO; ! 183: kp->sel4 = 0; ! 184: sav = kp->sel6; ! 185: kp->bsel1 = ROMI; ! 186: kp->sel6 = 010000|(ad&0377); /* mov ad,mar */ ! 187: kp->bsel1 = ROMI|STEP; ! 188: kp->bsel1 = ROMI; ! 189: kp->sel6 = 04000|((ad>>8)&0377); /* mov %ad,%mar */ ! 190: kp->bsel1 = ROMI|STEP; ! 191: kp->bsel1 = ROMI; ! 192: kp->sel6 = 055222; /* mov mem,csr2|mar++ */ ! 193: kp->bsel1 = ROMI|STEP; ! 194: passc(kp->bsel2); ! 195: kp->bsel1 = ROMI; ! 196: kp->sel6 = sav; ! 197: kp->bsel1 = 0; ! 198: } else ! 199: break; ! 200: } while (u.u_error==0 && u.u_count); ! 201: } ! 202: ! 203: kmcwrite(dev) ! 204: dev_t dev; ! 205: { register struct device *kp; ! 206: register ad; ! 207: int dsize; ! 208: short ins; ! 209: ushort sav; ! 210: ! 211: dev = minor(dev); ! 212: if(dev >= NKMC) { ! 213: u.u_error = ENXIO; ! 214: return; ! 215: } ! 216: if (kmc[dev].k_stat&SRUN) ! 217: return; ! 218: dsize = (kmc[dev].k_type==KMC11A)?KASIZE:KBSIZE; ! 219: kp = ((struct device *)kmcdinfo[dev]->ui_addr); ! 220: kp->bsel1 = 0; ! 221: kmcwritten = 1; ! 222: while (u.u_error==0 && u.u_count) { ! 223: ad = u.u_offset; ! 224: if (ad<dsize*2) { ! 225: if (ad&1) { ! 226: u.u_error = ENXIO; ! 227: break; ! 228: } ! 229: kp->bsel1 = ROMO; ! 230: kp->sel4 = ad>>1; ! 231: lobyte(ins) = cpass(); ! 232: hibyte(ins) = cpass(); ! 233: kp->sel6 = ins; ! 234: kp->bsel1 |= CWRT; ! 235: kp->bsel1 = 0; ! 236: } else if (ad -= dsize*2, ad<dsize) { ! 237: kp->bsel1 = ROMO; ! 238: kp->sel4 = 0; ! 239: sav = kp->sel6; ! 240: kp->bsel1 = ROMI; ! 241: kp->sel6 = 010000|(ad&0377); /* mov ad,mar */ ! 242: kp->bsel1 = ROMI|STEP; ! 243: kp->bsel1 = ROMI; ! 244: kp->sel6 = 04000|((ad>>8)&0377); /* mov %ad,%mar */ ! 245: kp->bsel1 = ROMI|STEP; ! 246: kp->bsel1 = ROMI; ! 247: kp->bsel2 = cpass(); ! 248: kp->sel6 = 0136440; /* mov csr2,mem|mar++ */ ! 249: kp->bsel1 = ROMI|STEP; ! 250: kp->bsel1 = ROMI; ! 251: kp->sel6 = sav; ! 252: kp->bsel1 = 0; ! 253: } else ! 254: break; ! 255: } ! 256: } ! 257: ! 258: kmcioctl(dev, cmd, arg, mode) ! 259: caddr_t arg; ! 260: dev_t dev; ! 261: { register struct device *kp; ! 262: register struct kmc *tp; ! 263: struct kmcntl kk; ! 264: short csr[4]; ! 265: ushort sav; ! 266: ! 267: dev = minor(dev); ! 268: if (cmd != KCSETA) { ! 269: u.u_error = EINVAL; ! 270: return; ! 271: } ! 272: if(dev >= NKMC) { ! 273: u.u_error = ENXIO; ! 274: return; ! 275: } ! 276: if (copyin(arg, &kk, sizeof(kk))) { ! 277: u.u_error = EFAULT; ! 278: return; ! 279: } ! 280: kp = ((struct device *)kmcdinfo[dev]->ui_addr); ! 281: tp = &kmc[dev]; ! 282: switch (kk.kmd) { ! 283: case KMCLR: ! 284: case KRESET: ! 285: spl7(); ! 286: kp->bsel1 = MCLR; ! 287: spl0(); ! 288: case KSTOP: ! 289: tp->k_stat &= ~SRUN; ! 290: kp->bsel1 = 0; ! 291: if (kk.kmd == KRESET) { ! 292: tp->k_stat = 0; ! 293: /* flush here */ ! 294: } ! 295: return; ! 296: case KMS: ! 297: if (tp->k_stat&SRUN) ! 298: break; ! 299: kp->bsel1 = ROMI|ROMO; ! 300: sav = kp->sel6; ! 301: kp->bsel1 = ROMI; ! 302: kp->sel6 = kk.kval; ! 303: kp->bsel1 = ROMI|STEP; ! 304: kp->bsel1 = ROMI; ! 305: kp->sel6 = sav; ! 306: kp->bsel1 = 0; ! 307: goto lcsr; ! 308: case KSTEP: ! 309: if (tp->k_stat&SRUN) ! 310: break; ! 311: kp->bsel1 |= STEP; ! 312: kp->bsel1 = 0; ! 313: case KCSR: ! 314: lcsr: ! 315: csr[0] = kp->sel0; ! 316: csr[1] = kp->sel2; ! 317: csr[2] = kp->sel4; ! 318: csr[3] = kp->sel6; ! 319: if (copyout(csr, kk.kcsr, sizeof csr)) ! 320: u.u_error = EFAULT; ! 321: return; ! 322: case KWRCR: ! 323: if (tp->k_stat&SRINT) ! 324: break; ! 325: kp->sel6 = kk.kval; ! 326: return; ! 327: case KRUN: ! 328: if (tp->k_stat&SRUN) ! 329: break; ! 330: tp->k_stat &= ~STYPE; ! 331: tp->k_stat |= (kk.kval&STYPE)|SRUN; ! 332: kp->bsel1 |= RUN; ! 333: if (tp->k_stat&SRINT) { ! 334: spl5(); ! 335: kmcrint(dev); ! 336: spl0(); ! 337: } ! 338: return; ! 339: case KLU: ! 340: kp->bsel1 = kk.kval&(LUA|LUB); ! 341: return; ! 342: } ! 343: u.u_error = EIO; ! 344: } ! 345: ! 346: kmcrint(dev) ! 347: dev_t dev; ! 348: { ! 349: if (kdirint) ! 350: (*kdirint)(); ! 351: } ! 352: ! 353: kmcxint(dev) ! 354: { ! 355: if (kdixint) ! 356: (*kdixint)(); ! 357: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.