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