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