1 /* $NetBSD: zs.c,v 1.34 2002/03/21 01:19:41 eeh Exp $ */ 2 3 /*- 4 * Copyright (c) 1996 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Gordon W. Ross. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Zilog Z8530 Dual UART driver (machine-dependent part) 41 * 42 * Runs two serial lines per chip using slave drivers. 43 * Plain tty/async lines use the zs_async slave. 44 * Sun keyboard/mouse uses the zs_kbd/zs_ms slaves. 45 */ 46 47 #include "opt_ddb.h" 48 #include "opt_kgdb.h" 49 50 #include <sys/param.h> 51 #include <sys/systm.h> 52 #include <sys/conf.h> 53 #include <sys/device.h> 54 #include <sys/file.h> 55 #include <sys/ioctl.h> 56 #include <sys/kernel.h> 57 #include <sys/proc.h> 58 #include <sys/tty.h> 59 #include <sys/time.h> 60 #include <sys/syslog.h> 61 62 #include <machine/autoconf.h> 63 #include <machine/openfirm.h> 64 #include <machine/conf.h> 65 #include <machine/cpu.h> 66 #include <machine/eeprom.h> 67 #include <machine/psl.h> 68 #include <machine/z8530var.h> 69 70 #include <dev/cons.h> 71 #include <dev/ic/z8530reg.h> 72 #include <dev/sun/kbd_ms_ttyvar.h> 73 #include <ddb/db_output.h> 74 75 #include <sparc64/dev/cons.h> 76 77 #include "kbd.h" /* NKBD */ 78 #include "ms.h" /* NMS */ 79 #include "zs.h" /* NZS */ 80 81 /* Make life easier for the initialized arrays here. */ 82 #if NZS < 3 83 #undef NZS 84 #define NZS 3 85 #endif 86 87 /* 88 * Some warts needed by z8530tty.c - 89 * The default parity REALLY needs to be the same as the PROM uses, 90 * or you can not see messages done with printf during boot-up... 91 */ 92 int zs_def_cflag = (CREAD | CS8 | HUPCL); 93 int zs_major = 12; 94 95 /* 96 * The Sun provides a 4.9152 MHz clock to the ZS chips. 97 */ 98 #define PCLK (9600 * 512) /* PCLK pin input clock rate */ 99 100 #define ZS_DELAY() 101 102 /* The layout of this is hardware-dependent (padding, order). */ 103 struct zschan { 104 volatile u_char zc_csr; /* ctrl,status, and indirect access */ 105 u_char zc_xxx0; 106 volatile u_char zc_data; /* data */ 107 u_char zc_xxx1; 108 }; 109 struct zsdevice { 110 /* Yes, they are backwards. */ 111 struct zschan zs_chan_b; 112 struct zschan zs_chan_a; 113 }; 114 115 /* ZS channel used as the console device (if any) */ 116 void *zs_conschan_get, *zs_conschan_put; 117 118 /* Saved PROM mappings */ 119 static struct zsdevice *zsaddr[NZS]; 120 121 static u_char zs_init_reg[16] = { 122 0, /* 0: CMD (reset, etc.) */ 123 0, /* 1: No interrupts yet. */ 124 0, /* 2: IVECT */ 125 ZSWR3_RX_8 | ZSWR3_RX_ENABLE, 126 ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP, 127 ZSWR5_TX_8 | ZSWR5_TX_ENABLE, 128 0, /* 6: TXSYNC/SYNCLO */ 129 0, /* 7: RXSYNC/SYNCHI */ 130 0, /* 8: alias for data port */ 131 ZSWR9_MASTER_IE | ZSWR9_NO_VECTOR, 132 0, /*10: Misc. TX/RX control bits */ 133 ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD, 134 ((PCLK/32)/9600)-2, /*12: BAUDLO (default=9600) */ 135 0, /*13: BAUDHI (default=9600) */ 136 ZSWR14_BAUD_ENA | ZSWR14_BAUD_FROM_PCLK, 137 ZSWR15_BREAK_IE, 138 }; 139 140 /* Console ops */ 141 static int zscngetc __P((dev_t)); 142 static void zscnputc __P((dev_t, int)); 143 static void zscnpollc __P((dev_t, int)); 144 145 struct consdev zs_consdev = { 146 NULL, 147 NULL, 148 zscngetc, 149 zscnputc, 150 zscnpollc, 151 NULL, 152 }; 153 154 155 /**************************************************************** 156 * Autoconfig 157 ****************************************************************/ 158 159 /* Definition of the driver for autoconfig. */ 160 static int zs_match_mainbus __P((struct device *, struct cfdata *, void *)); 161 static void zs_attach_mainbus __P((struct device *, struct device *, void *)); 162 163 static void zs_attach __P((struct zsc_softc *, struct zsdevice *, int)); 164 static int zs_print __P((void *, const char *name)); 165 166 /* Do we really need this ? */ 167 struct cfattach zs_ca = { 168 sizeof(struct zsc_softc), zs_match_mainbus, zs_attach_mainbus 169 }; 170 171 struct cfattach zs_mainbus_ca = { 172 sizeof(struct zsc_softc), zs_match_mainbus, zs_attach_mainbus 173 }; 174 175 extern struct cfdriver zs_cd; 176 extern int stdinnode; 177 extern int fbnode; 178 179 /* Interrupt handlers. */ 180 int zscheckintr __P((void *)); 181 static int zshard __P((void *)); 182 static void zssoft __P((void *)); 183 184 static int zs_get_speed __P((struct zs_chanstate *)); 185 186 /* Console device support */ 187 static int zs_console_flags __P((int, int, int)); 188 189 /* Power management hooks */ 190 int zs_enable __P((struct zs_chanstate *)); 191 void zs_disable __P((struct zs_chanstate *)); 192 193 /* 194 * Is the zs chip present? 195 */ 196 static int 197 zs_match_mainbus(parent, cf, aux) 198 struct device *parent; 199 struct cfdata *cf; 200 void *aux; 201 { 202 struct sbus_attach_args *sa = aux; 203 204 if (strcmp(cf->cf_driver->cd_name, sa->sa_name) != 0) 205 return (0); 206 207 return (1); 208 } 209 210 static void 211 zs_attach_mainbus(parent, self, aux) 212 struct device *parent; 213 struct device *self; 214 void *aux; 215 { 216 struct zsc_softc *zsc = (void *) self; 217 struct sbus_attach_args *sa = aux; 218 bus_space_handle_t bh; 219 int zs_unit = zsc->zsc_dev.dv_unit; 220 221 if (sa->sa_nintr == 0) { 222 printf(" no interrupt lines\n"); 223 return; 224 } 225 226 /* Use the mapping setup by the Sun PROM if possible. */ 227 if (zsaddr[zs_unit] == NULL) { 228 /* Only map registers once. */ 229 if (sa->sa_npromvaddrs) { 230 /* 231 * We're converting from a 32-bit pointer to a 64-bit 232 * pointer. Since the 32-bit entity is negative, but 233 * the kernel is still mapped into the lower 4GB 234 * range, this needs to be zero-extended. 235 * 236 * XXXXX If we map the kernel and devices into the 237 * high 4GB range, this needs to be changed to 238 * sign-extend the address. 239 */ 240 sparc_promaddr_to_handle(sa->sa_bustag, 241 sa->sa_promvaddrs[0], &bh); 242 243 } else { 244 245 if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, 246 sa->sa_offset, 247 sa->sa_size, 248 BUS_SPACE_MAP_LINEAR, 249 &bh) != 0) { 250 printf("%s @ sbus: cannot map registers\n", 251 self->dv_xname); 252 return; 253 } 254 } 255 zsaddr[zs_unit] = (struct zsdevice *) 256 bus_space_vaddr(sa->sa_bustag, bh); 257 } 258 zsc->zsc_bustag = sa->sa_bustag; 259 zsc->zsc_dmatag = sa->sa_dmatag; 260 zsc->zsc_promunit = PROM_getpropint(sa->sa_node, "slave", -2); 261 zsc->zsc_node = sa->sa_node; 262 zs_attach(zsc, zsaddr[zs_unit], sa->sa_pri); 263 } 264 265 /* 266 * Attach a found zs. 267 * 268 * USE ROM PROPERTIES port-a-ignore-cd AND port-b-ignore-cd FOR 269 * SOFT CARRIER, AND keyboard PROPERTY FOR KEYBOARD/MOUSE? 270 */ 271 static void 272 zs_attach(zsc, zsd, pri) 273 struct zsc_softc *zsc; 274 struct zsdevice *zsd; 275 int pri; 276 { 277 struct zsc_attach_args zsc_args; 278 struct zs_chanstate *cs; 279 int s, channel, softpri = PIL_TTY; 280 281 if (zsd == NULL) { 282 printf("configuration incomplete\n"); 283 return; 284 } 285 286 printf(" softpri %d\n", softpri); 287 288 /* 289 * Initialize software state for each channel. 290 */ 291 for (channel = 0; channel < 2; channel++) { 292 struct zschan *zc; 293 struct device *child; 294 extern struct cfdriver zstty_cd; /* in ioconf.c */ 295 296 zsc_args.channel = channel; 297 cs = &zsc->zsc_cs_store[channel]; 298 zsc->zsc_cs[channel] = cs; 299 300 cs->cs_channel = channel; 301 cs->cs_private = NULL; 302 cs->cs_ops = &zsops_null; 303 cs->cs_brg_clk = PCLK / 16; 304 305 zc = (channel == 0) ? &zsd->zs_chan_a : &zsd->zs_chan_b; 306 307 zsc_args.consdev = NULL; 308 zsc_args.hwflags = zs_console_flags(zsc->zsc_promunit, 309 zsc->zsc_node, 310 channel); 311 312 if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE) { 313 zsc_args.hwflags |= ZS_HWFLAG_USE_CONSDEV; 314 zsc_args.consdev = &zs_consdev; 315 } 316 317 if ((zsc_args.hwflags & ZS_HWFLAG_CONSOLE_INPUT) != 0) { 318 zs_conschan_get = zc; 319 } 320 if ((zsc_args.hwflags & ZS_HWFLAG_CONSOLE_OUTPUT) != 0) { 321 zs_conschan_put = zc; 322 } 323 324 /* Children need to set cn_dev, etc */ 325 cs->cs_reg_csr = &zc->zc_csr; 326 cs->cs_reg_data = &zc->zc_data; 327 328 bcopy(zs_init_reg, cs->cs_creg, 16); 329 bcopy(zs_init_reg, cs->cs_preg, 16); 330 331 /* XXX: Consult PROM properties for this?! */ 332 cs->cs_defspeed = zs_get_speed(cs); 333 cs->cs_defcflag = zs_def_cflag; 334 335 /* Make these correspond to cs_defcflag (-crtscts) */ 336 cs->cs_rr0_dcd = ZSRR0_DCD; 337 cs->cs_rr0_cts = 0; 338 cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS; 339 cs->cs_wr5_rts = 0; 340 341 /* 342 * Clear the master interrupt enable. 343 * The INTENA is common to both channels, 344 * so just do it on the A channel. 345 */ 346 if (channel == 0) { 347 zs_write_reg(cs, 9, 0); 348 } 349 350 /* 351 * Look for a child driver for this channel. 352 * The child attach will setup the hardware. 353 */ 354 if (!(child = 355 config_found(&zsc->zsc_dev, (void *)&zsc_args, zs_print))) { 356 /* No sub-driver. Just reset it. */ 357 u_char reset = (channel == 0) ? 358 ZSWR9_A_RESET : ZSWR9_B_RESET; 359 s = splzs(); 360 zs_write_reg(cs, 9, reset); 361 splx(s); 362 } 363 #if (NKBD > 0) || (NMS > 0) 364 /* 365 * If this was a zstty it has a keyboard 366 * property on it we need to attach the 367 * sunkbd and sunms line disciplines. 368 */ 369 if (child 370 && (child->dv_cfdata->cf_driver == &zstty_cd) 371 && (PROM_getproplen(zsc->zsc_node, "keyboard") == 0)) { 372 struct kbd_ms_tty_attach_args kma; 373 struct zstty_softc { 374 /* The following are the only fields we need here */ 375 struct device zst_dev; 376 struct tty *zst_tty; 377 struct zs_chanstate *zst_cs; 378 } *zst = (struct zstty_softc *)child; 379 struct tty *tp; 380 381 kma.kmta_tp = tp = zst->zst_tty; 382 kma.kmta_dev = tp->t_dev; 383 kma.kmta_consdev = zsc_args.consdev; 384 385 /* Attach 'em if we got 'em. */ 386 #if (NKBD > 0) 387 if (channel == 0) { 388 kma.kmta_name = "keyboard"; 389 config_found(child, (void *)&kma, NULL); 390 } 391 #endif 392 #if (NMS > 0) 393 if (channel == 1) { 394 kma.kmta_name = "mouse"; 395 config_found(child, (void *)&kma, NULL); 396 } 397 #endif 398 } 399 #endif 400 } 401 402 /* 403 * Now safe to install interrupt handlers. Note the arguments 404 * to the interrupt handlers aren't used. Note, we only do this 405 * once since both SCCs interrupt at the same level and vector. 406 */ 407 bus_intr_establish(zsc->zsc_bustag, pri, IPL_SERIAL, 0, zshard, zsc); 408 if (!(zsc->zsc_softintr = softintr_establish(softpri, zssoft, zsc))) 409 panic("zsattach: could not establish soft interrupt\n"); 410 411 evcnt_attach_dynamic(&zsc->zsc_intrcnt, EVCNT_TYPE_INTR, NULL, 412 zsc->zsc_dev.dv_xname, "intr"); 413 414 415 /* 416 * Set the master interrupt enable and interrupt vector. 417 * (common to both channels, do it on A) 418 */ 419 cs = zsc->zsc_cs[0]; 420 s = splhigh(); 421 /* interrupt vector */ 422 zs_write_reg(cs, 2, zs_init_reg[2]); 423 /* master interrupt control (enable) */ 424 zs_write_reg(cs, 9, zs_init_reg[9]); 425 splx(s); 426 427 } 428 429 static int 430 zs_print(aux, name) 431 void *aux; 432 const char *name; 433 { 434 struct zsc_attach_args *args = aux; 435 436 if (name != NULL) 437 printf("%s: ", name); 438 439 if (args->channel != -1) 440 printf(" channel %d", args->channel); 441 442 return (UNCONF); 443 } 444 445 /* Deprecate this? */ 446 static volatile int zssoftpending; 447 448 static int 449 zshard(arg) 450 void *arg; 451 { 452 struct zsc_softc *zsc = (struct zsc_softc *)arg; 453 int rr3, rval; 454 455 rval = 0; 456 while ((rr3 = zsc_intr_hard(zsc))) { 457 /* Count up the interrupts. */ 458 rval |= rr3; 459 zsc->zsc_intrcnt.ev_count++; 460 } 461 if (((zsc->zsc_cs[0] && zsc->zsc_cs[0]->cs_softreq) || 462 (zsc->zsc_cs[1] && zsc->zsc_cs[1]->cs_softreq)) && 463 zsc->zsc_softintr) { 464 zssoftpending = PIL_TTY; 465 softintr_schedule(zsc->zsc_softintr); 466 } 467 return (rval); 468 } 469 470 int 471 zscheckintr(arg) 472 void *arg; 473 { 474 struct zsc_softc *zsc; 475 int unit, rval; 476 477 rval = 0; 478 for (unit = 0; unit < zs_cd.cd_ndevs; unit++) { 479 480 zsc = zs_cd.cd_devs[unit]; 481 if (zsc == NULL) 482 continue; 483 rval = (zshard((void *)zsc) || rval); 484 } 485 return (rval); 486 } 487 488 489 /* 490 * We need this only for TTY_DEBUG purposes. 491 */ 492 static void 493 zssoft(arg) 494 void *arg; 495 { 496 struct zsc_softc *zsc = (struct zsc_softc *)arg; 497 int s; 498 499 /* Make sure we call the tty layer at spltty. */ 500 s = spltty(); 501 zssoftpending = 0; 502 (void)zsc_intr_soft(zsc); 503 #ifdef TTY_DEBUG 504 { 505 struct zstty_softc *zst0 = zsc->zsc_cs[0]->cs_private; 506 struct zstty_softc *zst1 = zsc->zsc_cs[1]->cs_private; 507 if (zst0->zst_overflows || zst1->zst_overflows ) { 508 struct trapframe *frame = (struct trapframe *)arg; 509 510 printf("zs silo overflow from %p\n", 511 (long)frame->tf_pc); 512 } 513 } 514 #endif 515 splx(s); 516 } 517 518 519 /* 520 * Compute the current baud rate given a ZS channel. 521 */ 522 static int 523 zs_get_speed(cs) 524 struct zs_chanstate *cs; 525 { 526 int tconst; 527 528 tconst = zs_read_reg(cs, 12); 529 tconst |= zs_read_reg(cs, 13) << 8; 530 return (TCONST_TO_BPS(cs->cs_brg_clk, tconst)); 531 } 532 533 /* 534 * MD functions for setting the baud rate and control modes. 535 */ 536 int 537 zs_set_speed(cs, bps) 538 struct zs_chanstate *cs; 539 int bps; /* bits per second */ 540 { 541 int tconst, real_bps; 542 543 if (bps == 0) 544 return (0); 545 546 #ifdef DIAGNOSTIC 547 if (cs->cs_brg_clk == 0) 548 panic("zs_set_speed"); 549 #endif 550 551 tconst = BPS_TO_TCONST(cs->cs_brg_clk, bps); 552 if (tconst < 0) 553 return (EINVAL); 554 555 /* Convert back to make sure we can do it. */ 556 real_bps = TCONST_TO_BPS(cs->cs_brg_clk, tconst); 557 558 /* XXX - Allow some tolerance here? */ 559 if (real_bps != bps) 560 return (EINVAL); 561 562 cs->cs_preg[12] = tconst; 563 cs->cs_preg[13] = tconst >> 8; 564 565 /* Caller will stuff the pending registers. */ 566 return (0); 567 } 568 569 int 570 zs_set_modes(cs, cflag) 571 struct zs_chanstate *cs; 572 int cflag; /* bits per second */ 573 { 574 int s; 575 576 /* 577 * Output hardware flow control on the chip is horrendous: 578 * if carrier detect drops, the receiver is disabled, and if 579 * CTS drops, the transmitter is stoped IN MID CHARACTER! 580 * Therefore, NEVER set the HFC bit, and instead use the 581 * status interrupt to detect CTS changes. 582 */ 583 s = splzs(); 584 cs->cs_rr0_pps = 0; 585 if ((cflag & (CLOCAL | MDMBUF)) != 0) { 586 cs->cs_rr0_dcd = 0; 587 if ((cflag & MDMBUF) == 0) 588 cs->cs_rr0_pps = ZSRR0_DCD; 589 } else 590 cs->cs_rr0_dcd = ZSRR0_DCD; 591 if ((cflag & CRTSCTS) != 0) { 592 cs->cs_wr5_dtr = ZSWR5_DTR; 593 cs->cs_wr5_rts = ZSWR5_RTS; 594 cs->cs_rr0_cts = ZSRR0_CTS; 595 } else if ((cflag & CDTRCTS) != 0) { 596 cs->cs_wr5_dtr = 0; 597 cs->cs_wr5_rts = ZSWR5_DTR; 598 cs->cs_rr0_cts = ZSRR0_CTS; 599 } else if ((cflag & MDMBUF) != 0) { 600 cs->cs_wr5_dtr = 0; 601 cs->cs_wr5_rts = ZSWR5_DTR; 602 cs->cs_rr0_cts = ZSRR0_DCD; 603 } else { 604 cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS; 605 cs->cs_wr5_rts = 0; 606 cs->cs_rr0_cts = 0; 607 } 608 splx(s); 609 610 /* Caller will stuff the pending registers. */ 611 return (0); 612 } 613 614 615 /* 616 * Read or write the chip with suitable delays. 617 */ 618 619 u_char 620 zs_read_reg(cs, reg) 621 struct zs_chanstate *cs; 622 u_char reg; 623 { 624 u_char val; 625 626 *cs->cs_reg_csr = reg; 627 ZS_DELAY(); 628 val = *cs->cs_reg_csr; 629 ZS_DELAY(); 630 return (val); 631 } 632 633 void 634 zs_write_reg(cs, reg, val) 635 struct zs_chanstate *cs; 636 u_char reg, val; 637 { 638 *cs->cs_reg_csr = reg; 639 ZS_DELAY(); 640 *cs->cs_reg_csr = val; 641 ZS_DELAY(); 642 } 643 644 u_char 645 zs_read_csr(cs) 646 struct zs_chanstate *cs; 647 { 648 u_char val; 649 650 val = *cs->cs_reg_csr; 651 ZS_DELAY(); 652 return (val); 653 } 654 655 void zs_write_csr(cs, val) 656 struct zs_chanstate *cs; 657 u_char val; 658 { 659 *cs->cs_reg_csr = val; 660 ZS_DELAY(); 661 } 662 663 u_char zs_read_data(cs) 664 struct zs_chanstate *cs; 665 { 666 u_char val; 667 668 val = *cs->cs_reg_data; 669 ZS_DELAY(); 670 return (val); 671 } 672 673 void zs_write_data(cs, val) 674 struct zs_chanstate *cs; 675 u_char val; 676 { 677 *cs->cs_reg_data = val; 678 ZS_DELAY(); 679 } 680 681 /**************************************************************** 682 * Console support functions (Sun specific!) 683 * Note: this code is allowed to know about the layout of 684 * the chip registers, and uses that to keep things simple. 685 * XXX - I think I like the mvme167 code better. -gwr 686 ****************************************************************/ 687 688 extern void Debugger __P((void)); 689 690 /* 691 * Handle user request to enter kernel debugger. 692 */ 693 void 694 zs_abort(cs) 695 struct zs_chanstate *cs; 696 { 697 volatile struct zschan *zc = zs_conschan_get; 698 int rr0; 699 700 /* Wait for end of break to avoid PROM abort. */ 701 /* XXX - Limit the wait? */ 702 do { 703 rr0 = zc->zc_csr; 704 ZS_DELAY(); 705 } while (rr0 & ZSRR0_BREAK); 706 707 #if defined(KGDB) 708 zskgdb(cs); 709 #elif defined(DDB) 710 { 711 extern int db_active; 712 713 if (!db_active) 714 Debugger(); 715 else 716 /* Debugger is probably hozed */ 717 callrom(); 718 } 719 #else 720 printf("stopping on keyboard abort\n"); 721 callrom(); 722 #endif 723 } 724 725 726 /* 727 * Polled input char. 728 */ 729 int 730 zs_getc(arg) 731 void *arg; 732 { 733 volatile struct zschan *zc = arg; 734 int s, c, rr0; 735 736 s = splhigh(); 737 /* Wait for a character to arrive. */ 738 do { 739 rr0 = zc->zc_csr; 740 ZS_DELAY(); 741 } while ((rr0 & ZSRR0_RX_READY) == 0); 742 743 c = zc->zc_data; 744 ZS_DELAY(); 745 splx(s); 746 747 /* 748 * This is used by the kd driver to read scan codes, 749 * so don't translate '\r' ==> '\n' here... 750 */ 751 return (c); 752 } 753 754 /* 755 * Polled output char. 756 */ 757 void 758 zs_putc(arg, c) 759 void *arg; 760 int c; 761 { 762 volatile struct zschan *zc = arg; 763 int s, rr0; 764 765 s = splhigh(); 766 767 /* Wait for transmitter to become ready. */ 768 do { 769 rr0 = zc->zc_csr; 770 ZS_DELAY(); 771 } while ((rr0 & ZSRR0_TX_READY) == 0); 772 773 /* 774 * Send the next character. 775 * Now you'd think that this could be followed by a ZS_DELAY() 776 * just like all the other chip accesses, but it turns out that 777 * the `transmit-ready' interrupt isn't de-asserted until 778 * some period of time after the register write completes 779 * (more than a couple instructions). So to avoid stray 780 * interrupts we put in the 2us delay regardless of cpu model. 781 */ 782 zc->zc_data = c; 783 delay(2); 784 785 splx(s); 786 } 787 788 /*****************************************************************/ 789 790 791 792 793 /* 794 * Polled console input putchar. 795 */ 796 static int 797 zscngetc(dev) 798 dev_t dev; 799 { 800 return (zs_getc(zs_conschan_get)); 801 } 802 803 /* 804 * Polled console output putchar. 805 */ 806 static void 807 zscnputc(dev, c) 808 dev_t dev; 809 int c; 810 { 811 zs_putc(zs_conschan_put, c); 812 } 813 814 int swallow_zsintrs; 815 816 static void 817 zscnpollc(dev, on) 818 dev_t dev; 819 int on; 820 { 821 /* 822 * Need to tell zs driver to acknowledge all interrupts or we get 823 * annoying spurious interrupt messages. This is because mucking 824 * with spl() levels during polling does not prevent interrupts from 825 * being generated. 826 */ 827 828 if (on) swallow_zsintrs++; 829 else swallow_zsintrs--; 830 } 831 832 int 833 zs_console_flags(promunit, node, channel) 834 int promunit; 835 int node; 836 int channel; 837 { 838 int cookie, flags = 0; 839 u_int chosen; 840 char buf[255]; 841 842 /* 843 * We'll just to the OBP grovelling down here since that's 844 * the only type of firmware we support. 845 */ 846 chosen = OF_finddevice("/chosen"); 847 848 /* Default to channel 0 if there are no explicit prom args */ 849 cookie = 0; 850 if (node == OF_instance_to_package(OF_stdin())) { 851 if (OF_getprop(chosen, "input-device", buf, sizeof(buf)) != -1) { 852 853 if (!strcmp("ttyb", buf)) 854 cookie = 1; 855 } 856 857 if (channel == cookie) 858 flags |= ZS_HWFLAG_CONSOLE_INPUT; 859 } 860 861 if (node == OF_instance_to_package(OF_stdout())) { 862 if (OF_getprop(chosen, "output-device", buf, sizeof(buf)) != -1) { 863 864 if (!strcmp("ttyb", buf)) 865 cookie = 1; 866 } 867 868 if (channel == cookie) 869 flags |= ZS_HWFLAG_CONSOLE_OUTPUT; 870 } 871 872 return (flags); 873 } 874 875