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