|
|
1.1 ! root 1: /* ! 2: * KMC11 microprocessor driver ! 3: * quasi-general-purpose: ! 4: * the code here is for downloading and controlling the kmc ! 5: * dealing with particular downloaded code ! 6: * will usually mean writing another driver ! 7: * which, alas, must generally have magic knowledge of ! 8: * struct kmc and the device registers ! 9: * ! 10: * the caller is expected to fill in ! 11: * k_rint, k_xint, k_reset if it cares ! 12: */ ! 13: ! 14: #define lobyte(X) (((unsigned char *)&X)[0]) ! 15: #define hibyte(X) (((unsigned char *)&X)[1]) ! 16: ! 17: #include "sys/param.h" ! 18: #include "sys/kmc.h" ! 19: #include "sys/ubaddr.h" ! 20: #include "sys/conf.h" ! 21: #include "sys/user.h" ! 22: ! 23: extern struct kmc kmc[]; ! 24: extern struct ubaddr kmcaddr[]; ! 25: extern int kmccnt; ! 26: ! 27: #define KMC11A 1 ! 28: #define KMC11B 2 ! 29: #define KASIZE 1024 ! 30: #define KBSIZE 4096 ! 31: ! 32: #define RUN (1<<7) ! 33: #define MCLR (1<<6) ! 34: #define CWRT (1<<5) ! 35: #define LUB (1<<4) ! 36: #define LUA (1<<3) ! 37: #define ROMO (1<<2) ! 38: #define ROMI (1<<1) ! 39: #define STEP (1<<0) ! 40: ! 41: #define RDYO 0200 ! 42: #define RDYI 020 ! 43: #define RQI 0200 ! 44: #define IEI 01 ! 45: #define IEO 020 ! 46: ! 47: #define STYPE 017 ! 48: #define SRUN 020 ! 49: #define SRINT 040 ! 50: #define SOPEN 0100 ! 51: ! 52: struct device { ! 53: union { ! 54: char b[8]; ! 55: u_short w[4]; ! 56: } un; ! 57: }; ! 58: ! 59: #define bsel0 un.b[0] ! 60: #define bsel1 un.b[1] ! 61: #define bsel2 un.b[2] ! 62: #define bsel3 un.b[3] ! 63: #define bsel4 un.b[4] ! 64: #define bsel5 un.b[5] ! 65: #define bsel6 un.b[6] ! 66: #define bsel7 un.b[7] ! 67: #define sel0 un.w[0] ! 68: #define sel2 un.w[1] ! 69: #define sel4 un.w[2] ! 70: #define sel6 un.w[3] ! 71: ! 72: int kmcopen(), kmcclose(), kmcread(), kmcwrite(), kmcioctl(); ! 73: struct cdevsw kmccdev = cdinit(kmcopen, kmcclose, kmcread, kmcwrite, kmcioctl); ! 74: ! 75: kmcopen(dev, flag) ! 76: dev_t dev; ! 77: { register struct device *kp; ! 78: register struct kmc *tp; ! 79: register sav; ! 80: ! 81: dev = minor(dev); ! 82: if (dev>=kmccnt || (tp = &kmc[dev])->k_stat&SOPEN) { ! 83: u.u_error = ENXIO; ! 84: return; ! 85: } ! 86: if ((kp = (struct device *)ubaddr(&kmcaddr[dev])) == 0 ! 87: || ubbadaddr(kmcaddr[dev].ubno, kp, sizeof(short))) { ! 88: printf("kmc%d absent\n", dev); ! 89: u.u_error = ENXIO; ! 90: return; ! 91: } ! 92: tp->k_addr = kp; ! 93: tp->k_written = 0; ! 94: tp->k_stat |= SOPEN; ! 95: if (tp->k_type==0) { ! 96: kp->bsel1 = ROMO; ! 97: kp->sel4 = 0; ! 98: sav = kp->sel6; ! 99: kp->sel6 = ~sav; ! 100: if (kp->sel6 != sav) { ! 101: tp->k_type = KMC11B; ! 102: kp->sel6 = sav; ! 103: } else ! 104: tp->k_type = KMC11A; ! 105: kp->bsel1 = 0; ! 106: } ! 107: } ! 108: ! 109: kmcclose(dev) ! 110: dev_t dev; ! 111: { ! 112: register struct kmc *tp; ! 113: ! 114: tp = &kmc[minor(dev)]; ! 115: tp->k_stat &= ~SOPEN; ! 116: if (tp->k_written && tp->k_reset) ! 117: (*tp->k_reset)(minor(dev)); ! 118: } ! 119: ! 120: kmcread(dev) ! 121: register dev_t dev; ! 122: { register struct device *kp; ! 123: register ad; ! 124: int dsize; ! 125: u_short sav; ! 126: ! 127: dev = minor(dev); ! 128: if (kmc[dev].k_stat&SRUN) ! 129: return; ! 130: dsize = (kmc[dev].k_type==KMC11A)?KASIZE:KBSIZE; ! 131: kp = kmc[dev].k_addr; ! 132: kp->bsel1 = 0; ! 133: do { ! 134: ad = Ltol(u.u_offset); ! 135: if (ad<dsize*2) { ! 136: if (ad&1) { ! 137: u.u_error = ENXIO; ! 138: break; ! 139: } ! 140: ad >>= 1; ! 141: kp->bsel1 = ROMO; ! 142: kp->sel4 = ad; ! 143: passc(kp->bsel6); ! 144: passc(kp->bsel7); ! 145: kp->bsel1 = 0; ! 146: } else if (ad -= dsize*2, ad<dsize) { ! 147: kp->bsel1 = ROMO; ! 148: kp->sel4 = 0; ! 149: sav = kp->sel6; ! 150: kp->bsel1 = ROMI; ! 151: kp->sel6 = 010000|(ad&0377); /* mov ad,mar */ ! 152: kp->bsel1 = ROMI|STEP; ! 153: kp->bsel1 = ROMI; ! 154: kp->sel6 = 04000|((ad>>8)&0377); /* mov %ad,%mar */ ! 155: kp->bsel1 = ROMI|STEP; ! 156: kp->bsel1 = ROMI; ! 157: kp->sel6 = 055222; /* mov mem,csr2|mar++ */ ! 158: kp->bsel1 = ROMI|STEP; ! 159: passc(kp->bsel2); ! 160: kp->bsel1 = ROMI; ! 161: kp->sel6 = sav; ! 162: kp->bsel1 = 0; ! 163: } else ! 164: break; ! 165: } while (u.u_error==0 && u.u_count); ! 166: } ! 167: ! 168: kmcwrite(dev) ! 169: register dev_t dev; ! 170: { register struct device *kp; ! 171: register ad; ! 172: int dsize; ! 173: short ins; ! 174: u_short sav; ! 175: ! 176: dev = minor(dev); ! 177: if (kmc[dev].k_stat&SRUN) ! 178: return; ! 179: dsize = (kmc[dev].k_type==KMC11A)?KASIZE:KBSIZE; ! 180: kp = kmc[dev].k_addr; ! 181: kp->bsel1 = 0; ! 182: kmc[dev].k_written = 1; ! 183: while (u.u_error==0 && u.u_count) { ! 184: ad = Ltol(u.u_offset); ! 185: if (ad<dsize*2) { ! 186: if (ad&1) { ! 187: u.u_error = ENXIO; ! 188: break; ! 189: } ! 190: kp->bsel1 = ROMO; ! 191: kp->sel4 = ad>>1; ! 192: lobyte(ins) = cpass(); ! 193: hibyte(ins) = cpass(); ! 194: kp->sel6 = ins; ! 195: kp->bsel1 |= CWRT; ! 196: kp->bsel1 = 0; ! 197: } else if (ad -= dsize*2, ad<dsize) { ! 198: kp->bsel1 = ROMO; ! 199: kp->sel4 = 0; ! 200: sav = kp->sel6; ! 201: kp->bsel1 = ROMI; ! 202: kp->sel6 = 010000|(ad&0377); /* mov ad,mar */ ! 203: kp->bsel1 = ROMI|STEP; ! 204: kp->bsel1 = ROMI; ! 205: kp->sel6 = 04000|((ad>>8)&0377); /* mov %ad,%mar */ ! 206: kp->bsel1 = ROMI|STEP; ! 207: kp->bsel1 = ROMI; ! 208: kp->bsel2 = cpass(); ! 209: kp->sel6 = 0136440; /* mov csr2,mem|mar++ */ ! 210: kp->bsel1 = ROMI|STEP; ! 211: kp->bsel1 = ROMI; ! 212: kp->sel6 = sav; ! 213: kp->bsel1 = 0; ! 214: } else ! 215: break; ! 216: } ! 217: } ! 218: ! 219: kmcioctl(dev, cmd, arg, mode) ! 220: caddr_t arg; ! 221: register dev_t dev; ! 222: { register struct device *kp; ! 223: register struct kmc *tp; ! 224: struct kmcntl kk; ! 225: short csr[4]; ! 226: u_short sav; ! 227: ! 228: dev = minor(dev); ! 229: if (cmd != KCSETA) { ! 230: u.u_error = EINVAL; ! 231: return; ! 232: } ! 233: if (copyin(arg, &kk, sizeof(kk))) { ! 234: u.u_error = EFAULT; ! 235: return; ! 236: } ! 237: tp = &kmc[dev]; ! 238: kp = tp->k_addr; ! 239: switch (kk.kmd) { ! 240: case KMCLR: ! 241: case KRESET: ! 242: spl7(); ! 243: kp->bsel1 = MCLR; ! 244: spl0(); ! 245: case KSTOP: ! 246: tp->k_stat &= ~SRUN; ! 247: kp->bsel1 = 0; ! 248: if (kk.kmd == KRESET) { ! 249: tp->k_stat = 0; ! 250: /* flush here */ ! 251: } ! 252: return; ! 253: case KMS: ! 254: if (tp->k_stat&SRUN) ! 255: break; ! 256: kp->bsel1 = ROMI|ROMO; ! 257: sav = kp->sel6; ! 258: kp->bsel1 = ROMI; ! 259: kp->sel6 = kk.kval; ! 260: kp->bsel1 = ROMI|STEP; ! 261: kp->bsel1 = ROMI; ! 262: kp->sel6 = sav; ! 263: kp->bsel1 = 0; ! 264: goto lcsr; ! 265: case KSTEP: ! 266: if (tp->k_stat&SRUN) ! 267: break; ! 268: kp->bsel1 |= STEP; ! 269: kp->bsel1 = 0; ! 270: case KCSR: ! 271: lcsr: ! 272: csr[0] = kp->sel0; ! 273: csr[1] = kp->sel2; ! 274: csr[2] = kp->sel4; ! 275: csr[3] = kp->sel6; ! 276: if (copyout(csr, kk.kcsr, sizeof csr)) ! 277: u.u_error = EFAULT; ! 278: return; ! 279: case KWRCR: ! 280: if (tp->k_stat&SRINT) ! 281: break; ! 282: kp->sel6 = kk.kval; ! 283: return; ! 284: case KRUN: ! 285: if (tp->k_stat&SRUN) ! 286: break; ! 287: tp->k_stat &= ~STYPE; ! 288: tp->k_stat |= (kk.kval&STYPE)|SRUN; ! 289: kp->bsel1 |= RUN; ! 290: if (tp->k_stat&SRINT) { ! 291: spl5(); ! 292: kmc0int(dev); ! 293: spl0(); ! 294: } ! 295: return; ! 296: case KLU: ! 297: kp->bsel1 = kk.kval&(LUA|LUB); ! 298: return; ! 299: } ! 300: u.u_error = EIO; ! 301: } ! 302: ! 303: kmc0int(dev) ! 304: { ! 305: register int (*p)(); ! 306: ! 307: if ((p = kmc[dev].k_rint) != 0) ! 308: (*p)(dev); ! 309: } ! 310: ! 311: kmc1int(dev) ! 312: { ! 313: register int (*p)(); ! 314: ! 315: if ((p = kmc[dev].k_xint) != 0) ! 316: (*p)(dev); ! 317: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.