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