1 /* 2 * kmc.c from 5.0 (on ihwld) hacked for 4.2 3 * Bob Van Valzah 2/7/84 4 */ 5 6 /* @(#)kmc.c 1.3 */ 7 /* 8 * KMC11 microprocessor driver 9 */ 10 11 #include "kmc.h" 12 #if NKMC > 0 13 14 #include "sys/param.h" 15 #include "sys/ioctl.h" 16 #include "sys/tty.h" 17 #include "sys/kmcreg.h" 18 #include "sys/buf.h" 19 #include "sys/user.h" 20 #include "sys/syslog.h" 21 #include "../uba/ubavar.h" 22 #include "sys/uio.h" 23 24 #ifdef DATAKIT 25 #include "dkitkmc.h" 26 #endif 27 #ifdef RJE 28 #include "vpm.h" 29 #endif 30 31 #define ushort u_short 32 33 int kmc_cnt = NKMC; 34 35 struct kmc { 36 struct clist k_inq; 37 short k_stat; 38 char k_type; 39 short k_arg[3]; 40 int (*k_rint)(); 41 int (*k_init)(); 42 int (*k_reset)(); 43 } kmc[NKMC]; 44 45 #define KMC11A 1 46 #define KMC11B 2 47 #define KASIZE 1024 48 #define KBSIZE 4096 49 50 #define RUN (1<<7) 51 #define MCLR (1<<6) 52 #define CWRT (1<<5) 53 #define LUB (1<<4) 54 #define LUA (1<<3) 55 #define ROMO (1<<2) 56 #define ROMI (1<<1) 57 #define STEP (1<<0) 58 59 #define RDYO 0200 60 #define RDYI 020 61 #define RQI 0200 62 #define IEI 01 63 #define IEO 020 64 65 #define STYPE 017 66 #define SRUN 020 67 #define SRINT 040 68 #define SOPEN 0100 69 #define SLOAD 0200 70 #define SINIT 0400 71 #define SRESET 01000 72 73 74 struct kmcdevice { 75 union { 76 char b[8]; 77 unsigned short w[4]; 78 } un; 79 }; 80 81 #define bsel0 un.b[0] 82 #define bsel1 un.b[1] 83 #define bsel2 un.b[2] 84 #define bsel3 un.b[3] 85 #define bsel4 un.b[4] 86 #define bsel5 un.b[5] 87 #define bsel6 un.b[6] 88 #define bsel7 un.b[7] 89 #define sel0 un.w[0] 90 #define sel2 un.w[1] 91 #define sel4 un.w[2] 92 #define sel6 un.w[3] 93 94 int rkmcdebug = 0; 95 96 int kmcprobe(), kmcattach(), kmcxint(); 97 struct uba_device *kmcdinfo[NKMC]; 98 99 u_short kmcstd[] = { 0 }; 100 struct uba_driver kmcdriver = 101 { kmcprobe, 0, kmcattach, 0, kmcstd, "kmc", kmcdinfo }; 102 103 kmcprobe(reg) 104 caddr_t reg; 105 { register int br, cvec; /* don't touch */ 106 register struct kmcdevice *kp = (struct kmcdevice *)reg; 107 register s; 108 109 #ifdef lint 110 br = 0; cvec = br; br = cvec; 111 #endif 112 s = spl7(); 113 kp->bsel1 = MCLR; 114 splx(s); 115 kp->bsel1 = ROMI; 116 kp->sel4 = 0200; /* bus request */ 117 kp->sel6 = 0121111; /* mov csr4,obr */ 118 kp->bsel1 = ROMI|STEP; 119 DELAY(50); 120 kp->bsel1 = 0; 121 return(1); 122 } 123 124 kmcattach(ui) 125 register struct uba_device *ui; 126 { 127 switch(ui->ui_flags & 03) { 128 #if NVPM>0 129 case 0: 130 vpminit(ui); 131 break; 132 #endif 133 #if NDKITKMC>0 134 case 1: 135 dkkmc_attach(ui); 136 break; 137 #endif 138 default: 139 log(LOG_ERR, "kmc%d: no protocol %d\n", ui->ui_unit, 140 ui->ui_flags); 141 break; 142 } 143 } 144 145 /*ARGSUSED*/ 146 kmcopen(dev, flag) 147 { 148 register struct kmcdevice *kp; 149 register struct kmc *tp; 150 register sav; 151 152 dev = minor(dev); 153 if (dev>=kmc_cnt || (tp = &kmc[dev])->k_stat&SOPEN) { 154 return (ENXIO); 155 } 156 tp->k_stat |= SOPEN; 157 if (tp->k_type==0) { 158 kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr); 159 kp->bsel1 = ROMO; 160 kp->sel4 = 0; 161 sav = kp->sel6; 162 kp->sel6 = ~sav; 163 if (kp->sel6 != sav) { 164 tp->k_type = KMC11B; 165 kp->sel6 = sav; 166 } else 167 tp->k_type = KMC11A; 168 kp->bsel1 = 0; 169 } 170 return (0); 171 } 172 173 kmcclose(dev) 174 { 175 dev = minor(dev); 176 kmc[dev].k_stat &= ~SOPEN; 177 } 178 179 kmcread(dev, uio) 180 dev_t dev; 181 struct uio *uio; 182 { 183 register struct kmcdevice *kp; 184 register ad; 185 register int error = 0; 186 int dsize; 187 ushort sav; 188 189 dev = minor(dev); 190 if (kmc[dev].k_stat&SRUN) 191 return (0); 192 dsize = (kmc[dev].k_type==KMC11A)?KASIZE:KBSIZE; 193 kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr); 194 kp->bsel1 = 0; 195 do { 196 ad = uio->uio_offset; 197 if (ad<dsize*2) { 198 if (ad&1) { 199 return (ENXIO); 200 } 201 ad >>= 1; 202 kp->bsel1 = ROMO; 203 kp->sel4 = ad; 204 if ((error=ureadc(kp->bsel6, uio)) < 0) 205 break; 206 if ((error=ureadc(kp->bsel7, uio)) < 0) 207 break; 208 kp->bsel1 = 0; 209 } else if (ad -= dsize*2, ad<dsize) { 210 kp->bsel1 = ROMO; 211 kp->sel4 = 0; 212 sav = kp->sel6; 213 kp->bsel1 = ROMI; 214 kp->sel6 = 010000|(ad&0377); /* mov ad,mar */ 215 kp->bsel1 = ROMI|STEP; 216 kp->bsel1 = ROMI; 217 kp->sel6 = 04000|((ad>>8)&0377); /* mov %ad,%mar */ 218 kp->bsel1 = ROMI|STEP; 219 kp->bsel1 = ROMI; 220 kp->sel6 = 055222; /* mov mem,csr2|mar++ */ 221 kp->bsel1 = ROMI|STEP; 222 if ((error=ureadc(kp->bsel2, uio)) < 0) 223 break; 224 kp->bsel1 = ROMI; 225 kp->sel6 = sav; 226 kp->bsel1 = 0; 227 } else 228 break; 229 } while (!error && uio->uio_resid); 230 return (error); 231 } 232 233 kmcwrite(dev, uio) 234 dev_t dev; 235 struct uio *uio; 236 { 237 register struct kmcdevice *kp; 238 register ad; 239 int dsize; 240 short ins; 241 ushort sav; 242 243 dev = minor(dev); 244 if (kmc[dev].k_stat&SRUN) 245 return (0); 246 dsize = (kmc[dev].k_type==KMC11A)?KASIZE:KBSIZE; 247 kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr); 248 kp->bsel1 = 0; 249 while (uio->uio_resid) { 250 ad = uio->uio_offset; 251 if (ad<dsize*2) { 252 if (ad&1) { 253 return (ENXIO); 254 } 255 kp->bsel1 = ROMO; 256 kp->sel4 = ad>>1; 257 lobyte(ins) = uwritec(uio); 258 hibyte(ins) = uwritec(uio); 259 kp->sel6 = ins; 260 kp->bsel1 |= CWRT; 261 kp->bsel1 = 0; 262 } else if (ad -= dsize*2, ad<dsize) { 263 kp->bsel1 = ROMO; 264 kp->sel4 = 0; 265 sav = kp->sel6; 266 kp->bsel1 = ROMI; 267 kp->sel6 = 010000|(ad&0377); /* mov ad,mar */ 268 kp->bsel1 = ROMI|STEP; 269 kp->bsel1 = ROMI; 270 kp->sel6 = 04000|((ad>>8)&0377); /* mov %ad,%mar */ 271 kp->bsel1 = ROMI|STEP; 272 kp->bsel1 = ROMI; 273 kp->bsel2 = uwritec(uio); 274 kp->sel6 = 0136440; /* mov csr2,mem|mar++ */ 275 kp->bsel1 = ROMI|STEP; 276 kp->bsel1 = ROMI; 277 kp->sel6 = sav; 278 kp->bsel1 = 0; 279 } else 280 break; 281 } 282 return (0); 283 } 284 285 /*ARGSUSED*/ 286 kmcioctl(dev, cmd, kk, mode) 287 dev_t dev; 288 struct kmcntl *kk; 289 { 290 register struct kmcdevice *kp; 291 register struct kmc *tp; 292 short csr[4]; 293 ushort sav; 294 295 if (rkmcdebug) log(LOG_ERR, "kmcioctl: cmd=%d, kk->kmd=%d, kk->kcsr=0x%x, kk->kval=%d\n", 296 cmd, kk->kmd, kk->kcsr, kk->kval); 297 dev = minor(dev); 298 if (cmd != KCSETA) { 299 return (EINVAL); 300 } 301 kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr); 302 tp = &kmc[dev]; 303 switch (kk->kmd) { 304 case KMCLR: 305 case KRESET: 306 spl7(); 307 kp->bsel1 = MCLR; 308 spl0(); 309 case KSTOP: 310 tp->k_stat &= ~SRUN; 311 kp->bsel1 = 0; 312 if (kk->kmd == KRESET) { 313 tp->k_stat = 0; 314 while(getc(&tp->k_inq) >= 0) ; 315 if (tp->k_stat&SINIT) 316 (*tp->k_init)(dev); 317 } 318 return (0); 319 case KMS: 320 if (tp->k_stat&SRUN) 321 break; 322 kp->bsel1 = ROMI|ROMO; 323 sav = kp->sel6; 324 kp->bsel1 = ROMI; 325 kp->sel6 = kk->kval; 326 kp->bsel1 = ROMI|STEP; 327 kp->bsel1 = ROMI; 328 kp->sel6 = sav; 329 kp->bsel1 = 0; 330 goto lcsr; 331 case KSTEP: 332 if (tp->k_stat&SRUN) 333 break; 334 kp->bsel1 |= STEP; 335 kp->bsel1 = 0; 336 case KCSR: 337 lcsr: 338 csr[0] = kp->sel0; 339 csr[1] = kp->sel2; 340 csr[2] = kp->sel4; 341 csr[3] = kp->sel6; 342 if (copyout((caddr_t)csr, (caddr_t)kk->kcsr, sizeof csr)) 343 return (EFAULT); 344 return (0); 345 case KWRCR: 346 if (tp->k_stat&SRINT) 347 break; 348 kp->sel6 = kk->kval; 349 return (0); 350 case KRUN: 351 if (tp->k_stat&SRUN) 352 break; 353 tp->k_stat &= ~STYPE; 354 tp->k_stat |= (kk->kval&STYPE)|SRUN; 355 kp->bsel1 |= RUN; 356 if (tp->k_stat&SRINT) { 357 spl5(); 358 kmcrint(dev); 359 spl0(); 360 } 361 if (tp->k_stat&SRESET) 362 (*tp->k_reset)(dev); 363 return (0); 364 case KLU: 365 kp->bsel1 = kk->kval&(LUA|LUB); 366 return (0); 367 } 368 if (rkmcdebug) log(LOG_ERR, "kmcioctl: EIO exit, tp->k_stat=0x%x\n", tp->k_stat); 369 return (EIO); 370 } 371 372 kmcrint(dev) 373 { 374 register struct kmcdevice *kp; 375 register struct kmc *tp; 376 377 dev = minor(dev); 378 kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr); 379 tp = &kmc[dev]; 380 kp->sel0 &= ~IEI; 381 while (kp->sel2&RDYI) { 382 if ((tp->k_stat&SLOAD) || 383 q_to_b(&tp->k_inq, (char *)tp->k_arg, sizeof(tp->k_arg)) == sizeof(tp->k_arg)) { 384 kp->sel2 = tp->k_arg[0]|RDYI; 385 kp->sel4 = tp->k_arg[1]; 386 kp->sel6 = tp->k_arg[2]; 387 tp->k_stat &= ~SLOAD; 388 } else { 389 log(LOG_ERR, "Bad kmc %d load\n", dev); 390 } 391 if (tp->k_inq.c_cc==0) { 392 kp->sel0 &= ~RQI; 393 kp->sel2 &= ~RDYI; 394 return; 395 } 396 kp->sel2 &= ~RDYI; 397 } 398 if ((tp->k_stat&SLOAD) || tp->k_inq.c_cc) 399 kp->sel0 |= IEI|RQI; 400 } 401 402 kmcxint(dev) 403 { 404 register struct kmcdevice *kp; 405 register struct kmc *tp; 406 int p1, p2, p3, p4; 407 408 dev = minor(dev); 409 kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr); 410 tp = &kmc[dev]; 411 kp->sel0 &= ~IEO; 412 while(kp->sel2&RDYO) { 413 p1 = (dev<<6)|(kp->bsel3&077); 414 p2 = kp->bsel2&017; 415 p3 = kp->sel4; 416 p4 = kp->sel6; 417 kp->sel2 &= ~RDYO; 418 if (tp->k_stat&SRINT) 419 (*tp->k_rint)(p1, p2, p3, p4); 420 } 421 kp->sel0 |= IEO; 422 } 423 424 kmcload(dev, p1, p2, p3) 425 { 426 register struct kmcdevice *kp; 427 register struct kmc *tp; 428 register unit; 429 register sps; 430 431 dev = minor(dev); 432 unit = (dev>>6)&03; 433 tp = &kmc[unit]; 434 if (!(tp->k_stat&SRUN)) 435 return(-1); 436 kp = ((struct kmcdevice *)kmcdinfo[unit]->ui_addr); /* RAV unit is suspect */ 437 sps = spl5(); 438 if (tp->k_stat&SLOAD) { 439 b_to_q((char *)tp->k_arg, sizeof(tp->k_arg), &tp->k_inq); 440 tp->k_stat &= ~SLOAD; 441 } 442 kp->sel0 |= RQI; 443 tp->k_arg[0] = (p1&017)|((dev&077)<<8); 444 tp->k_arg[1] = p2; 445 tp->k_arg[2] = p3; 446 if (tp->k_inq.c_cc) 447 b_to_q((char *)tp->k_arg, sizeof(tp->k_arg), &tp->k_inq); 448 else 449 tp->k_stat |= SLOAD; 450 kmcrint(unit); 451 splx(sps); 452 return(tp->k_inq.c_cc); 453 } 454 455 kmcset(dev, type, rint) 456 int (*rint)(); 457 { 458 register struct kmcdevice *kp; 459 register struct kmc *tp; 460 register unit; 461 462 dev = minor(dev); 463 unit = (dev>>6)&03; 464 kp = ((struct kmcdevice *)kmcdinfo[unit]->ui_addr); /* RAV unit is suspect */ 465 tp = &kmc[unit]; 466 if ((tp->k_stat&(STYPE|SRUN|SOPEN))!=((type&STYPE)|SRUN)) 467 return (1); 468 tp->k_stat |= SRINT; 469 tp->k_rint = rint; 470 kp->sel0 |= IEO; 471 return(0); 472 } 473 474 kmcdclr(dev) 475 register dev; 476 { 477 register struct kmc *tp; 478 register struct kmcdevice *kp; 479 480 dev = minor(dev); 481 if (dev < 0 || dev >= kmc_cnt) 482 return; 483 tp = &kmc[dev]; 484 while (getc(&tp->k_inq) >= 0) ; 485 kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr); 486 kp->sel0 = 0; 487 kp->sel2 = 0; 488 } 489 490 kmcreset(dev) 491 { 492 register struct kmc *tp; 493 register struct kmcdevice *kp; 494 register s; 495 496 dev = minor(dev); 497 tp = &kmc[dev]; 498 kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr); 499 s = spl7(); 500 kp->bsel1 = MCLR; 501 splx(s); 502 kp->bsel1 = 0; 503 tp->k_stat = 0; 504 while(getc(&tp->k_inq)>=0); 505 } 506 507 kmcifset(dev, init) 508 int (*init)(); 509 { 510 register struct kmc *tp; 511 register unit; 512 513 dev = minor(dev); 514 unit = (dev>>6)&03; 515 if (unit < 0 || unit >= kmc_cnt) 516 return; 517 tp = &kmc[unit]; 518 if (init==NULL) { 519 tp->k_init = NULL; 520 tp->k_stat &= ~SINIT; 521 } else { 522 tp->k_init = init; 523 tp->k_stat |= SINIT; 524 } 525 } 526 527 kmcrfset(dev, reset) 528 int (*reset)(); 529 { 530 register struct kmc *tp; 531 register unit; 532 533 dev = minor(dev); 534 unit = (dev>>6)&03; 535 if (unit < 0 || unit >= kmc_cnt) 536 return; 537 tp = &kmc[unit]; 538 if (reset==NULL) { 539 tp->k_reset = NULL; 540 tp->k_stat &= ~SRESET; 541 } else { 542 tp->k_reset = reset; 543 tp->k_stat |= SRESET; 544 } 545 } 546 #endif 547