1 /* $NetBSD: zs.c,v 1.84 2008/06/13 13:11:42 cegger 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.84 2008/06/13 13:11:42 cegger Exp $"); 42 43 #include "opt_kgdb.h" 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/conf.h> 48 #include <sys/device.h> 49 #include <sys/file.h> 50 #include <sys/ioctl.h> 51 #include <sys/kernel.h> 52 #include <sys/proc.h> 53 #include <sys/tty.h> 54 #include <sys/time.h> 55 #include <sys/syslog.h> 56 #include <sys/cpu.h> 57 #include <sys/intr.h> 58 59 #include <uvm/uvm_extern.h> 60 61 #include <machine/autoconf.h> 62 #include <machine/mon.h> 63 #include <machine/z8530var.h> 64 65 #include <sun3/sun3/machdep.h> 66 #ifdef _SUN3X_ 67 #include <sun3/sun3x/obio.h> 68 #else 69 #include <sun3/sun3/obio.h> 70 #endif 71 #include <sun3/dev/zs_cons.h> 72 73 #include <dev/cons.h> 74 #include <dev/ic/z8530reg.h> 75 76 #include "ioconf.h" 77 #include "kbd.h" /* NKBD */ 78 #include "zsc.h" /* NZSC */ 79 #define NZS NZSC 80 81 /* Make life easier for the initialized arrays here. */ 82 #if NZS < 2 83 #undef NZS 84 #define NZS 2 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 94 /* 95 * The Sun3 provides a 4.9152 MHz clock to the ZS chips. 96 */ 97 #define PCLK (9600 * 512) /* PCLK pin input clock rate */ 98 99 /* 100 * Define interrupt levels. 101 */ 102 #define ZSHARD_PRI 6 /* Wired on the CPU board... */ 103 #define ZSSOFT_PRI _IPL_SOFT_LEVEL3 /* Want tty pri (4) but this is OK. */ 104 105 #define ZS_DELAY() delay(2) 106 107 /* The layout of this is hardware-dependent (padding, order). */ 108 struct zschan { 109 volatile uint8_t zc_csr; /* ctrl,status, and indirect access */ 110 uint8_t zc_xxx0; 111 volatile uint8_t zc_data; /* data */ 112 uint8_t zc_xxx1; 113 }; 114 struct zsdevice { 115 /* Yes, they are backwards. */ 116 struct zschan zs_chan_b; 117 struct zschan zs_chan_a; 118 }; 119 120 121 /* Default OBIO addresses. */ 122 static int zs_physaddr[NZS] = { 123 OBIO_ZS_KBD_MS, 124 OBIO_ZS_TTY_AB }; 125 126 /* Saved PROM mappings */ 127 static struct zsdevice *zsaddr[NZS]; 128 129 /* Flags from cninit() */ 130 static int zs_hwflags[NZS][2]; 131 132 /* Default speed for each channel */ 133 static int zs_defspeed[NZS][2] = { 134 { 1200, /* keyboard */ 135 1200 }, /* mouse */ 136 { 9600, /* ttya */ 137 9600 }, /* ttyb */ 138 }; 139 140 static uint8_t zs_init_reg[16] = { 141 0, /* 0: CMD (reset, etc.) */ 142 0, /* 1: No interrupts yet. */ 143 0x18 + ZSHARD_PRI, /* IVECT */ 144 ZSWR3_RX_8 | ZSWR3_RX_ENABLE, 145 ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP, 146 ZSWR5_TX_8 | ZSWR5_TX_ENABLE, 147 0, /* 6: TXSYNC/SYNCLO */ 148 0, /* 7: RXSYNC/SYNCHI */ 149 0, /* 8: alias for data port */ 150 ZSWR9_MASTER_IE, 151 0, /*10: Misc. TX/RX control bits */ 152 ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD, 153 ((PCLK/32)/9600)-2, /*12: BAUDLO (default=9600) */ 154 0, /*13: BAUDHI (default=9600) */ 155 ZSWR14_BAUD_ENA | ZSWR14_BAUD_FROM_PCLK, 156 ZSWR15_BREAK_IE, 157 }; 158 159 160 /* Find PROM mappings (for console support). */ 161 void 162 zs_init(void) 163 { 164 vaddr_t va; 165 int i; 166 167 for (i = 0; i < NZS; i++) { 168 if (find_prom_map(zs_physaddr[i], PMAP_OBIO, 169 sizeof(struct zschan), &va) == 0) 170 zsaddr[i] = (void *)va; 171 } 172 } 173 174 struct zschan * 175 zs_get_chan_addr(int zs_unit, int channel) 176 { 177 struct zsdevice *addr; 178 struct zschan *zc; 179 180 if (zs_unit >= NZS) 181 return NULL; 182 addr = zsaddr[zs_unit]; 183 if (addr == NULL) 184 return NULL; 185 if (channel == 0) { 186 zc = &addr->zs_chan_a; 187 } else { 188 zc = &addr->zs_chan_b; 189 } 190 return (zc); 191 } 192 193 194 /**************************************************************** 195 * Autoconfig 196 ****************************************************************/ 197 198 /* Definition of the driver for autoconfig. */ 199 static int zs_match(device_t, cfdata_t, void *); 200 static void zs_attach(device_t, device_t, void *); 201 static int zs_print(void *, const char *); 202 203 CFATTACH_DECL_NEW(zsc, sizeof(struct zsc_softc), 204 zs_match, zs_attach, NULL, NULL); 205 206 static int zshard(void *); 207 static int zs_get_speed(struct zs_chanstate *); 208 209 210 /* 211 * Is the zs chip present? 212 */ 213 static int 214 zs_match(device_t parent, cfdata_t cf, void *aux) 215 { 216 struct confargs *ca = aux; 217 int unit; 218 void *va; 219 220 /* 221 * This driver only supports its wired-in mappings, 222 * because the console support depends on those. 223 */ 224 if (ca->ca_paddr == zs_physaddr[0]) { 225 unit = 0; 226 } else if (ca->ca_paddr == zs_physaddr[1]) { 227 unit = 1; 228 } else { 229 return (0); 230 } 231 232 /* Make sure zs_init() found mappings. */ 233 va = zsaddr[unit]; 234 if (va == NULL) 235 return (0); 236 237 /* This returns -1 on a fault (bus error). */ 238 if (peek_byte(va) == -1) 239 return (0); 240 241 /* Default interrupt priority (always splbio==2) */ 242 if (ca->ca_intpri == -1) 243 ca->ca_intpri = ZSHARD_PRI; 244 245 return (1); 246 } 247 248 /* 249 * Attach a found zs. 250 * 251 * Match slave number to zs unit number, so that misconfiguration will 252 * not set up the keyboard as ttya, etc. 253 */ 254 static void 255 zs_attach(device_t parent, device_t self, void *aux) 256 { 257 struct zsc_softc *zsc = device_private(self); 258 struct confargs *ca = aux; 259 struct zsc_attach_args zsc_args; 260 volatile struct zschan *zc; 261 struct zs_chanstate *cs; 262 int s, zs_unit, channel; 263 static int didintr; 264 265 zsc->zsc_dev = self; 266 zs_unit = device_unit(self); 267 268 aprint_normal(": (softpri %d)\n", ZSSOFT_PRI); 269 270 /* Use the mapping setup by the Sun PROM. */ 271 if (zsaddr[zs_unit] == NULL) 272 panic("zs_attach: zs%d not mapped", zs_unit); 273 274 /* 275 * Initialize software state for each channel. 276 */ 277 for (channel = 0; channel < 2; channel++) { 278 zsc_args.channel = channel; 279 zsc_args.hwflags = zs_hwflags[zs_unit][channel]; 280 cs = &zsc->zsc_cs_store[channel]; 281 zsc->zsc_cs[channel] = cs; 282 283 zs_lock_init(cs); 284 cs->cs_channel = channel; 285 cs->cs_private = NULL; 286 cs->cs_ops = &zsops_null; 287 cs->cs_brg_clk = PCLK / 16; 288 289 zc = zs_get_chan_addr(zs_unit, channel); 290 cs->cs_reg_csr = &zc->zc_csr; 291 cs->cs_reg_data = &zc->zc_data; 292 293 memcpy(cs->cs_creg, zs_init_reg, 16); 294 memcpy(cs->cs_preg, zs_init_reg, 16); 295 296 /* XXX: Get these from the EEPROM instead? */ 297 /* XXX: See the mvme167 code. Better. */ 298 if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE) 299 cs->cs_defspeed = zs_get_speed(cs); 300 else 301 cs->cs_defspeed = zs_defspeed[zs_unit][channel]; 302 cs->cs_defcflag = zs_def_cflag; 303 304 /* Make these correspond to cs_defcflag (-crtscts) */ 305 cs->cs_rr0_dcd = ZSRR0_DCD; 306 cs->cs_rr0_cts = 0; 307 cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS; 308 cs->cs_wr5_rts = 0; 309 310 /* 311 * Clear the master interrupt enable. 312 * The INTENA is common to both channels, 313 * so just do it on the A channel. 314 */ 315 if (channel == 0) { 316 zs_write_reg(cs, 9, 0); 317 } 318 319 /* 320 * Look for a child driver for this channel. 321 * The child attach will setup the hardware. 322 */ 323 if (!config_found(self, (void *)&zsc_args, zs_print)) { 324 /* No sub-driver. Just reset it. */ 325 uint8_t reset = (channel == 0) ? 326 ZSWR9_A_RESET : ZSWR9_B_RESET; 327 s = splhigh(); 328 zs_write_reg(cs, 9, reset); 329 splx(s); 330 } 331 } 332 333 /* 334 * Now safe to install interrupt handlers. Note the arguments 335 * to the interrupt handlers aren't used. Note, we only do this 336 * once since both SCCs interrupt at the same level and vector. 337 */ 338 if (!didintr) { 339 didintr = 1; 340 isr_add_autovect(zshard, NULL, ca->ca_intpri); 341 } 342 zsc->zs_si = softint_establish(SOFTINT_SERIAL, 343 (void (*)(void *))zsc_intr_soft, zsc); 344 /* XXX; evcnt_attach() ? */ 345 346 /* 347 * Set the master interrupt enable and interrupt vector. 348 * (common to both channels, do it on A) 349 */ 350 cs = zsc->zsc_cs[0]; 351 s = splhigh(); 352 /* interrupt vector */ 353 zs_write_reg(cs, 2, zs_init_reg[2]); 354 /* master interrupt control (enable) */ 355 zs_write_reg(cs, 9, zs_init_reg[9]); 356 splx(s); 357 358 /* 359 * XXX: L1A hack - We would like to be able to break into 360 * the debugger during the rest of autoconfiguration, so 361 * lower interrupts just enough to let zs interrupts in. 362 * This is done after both zs devices are attached. 363 */ 364 if (zs_unit == 1) { 365 (void)spl5(); /* splzs - 1 */ 366 } 367 } 368 369 static int 370 zs_print(void *aux, const char *name) 371 { 372 struct zsc_attach_args *args = aux; 373 374 if (name != NULL) 375 aprint_normal("%s: ", name); 376 377 if (args->channel != -1) 378 aprint_normal(" channel %d", args->channel); 379 380 return UNCONF; 381 } 382 383 /* 384 * Our ZS chips all share a common, autovectored interrupt, 385 * so we have to look at all of them on each interrupt. 386 */ 387 static int 388 zshard(void *arg) 389 { 390 struct zsc_softc *zsc; 391 int unit, rval, softreq; 392 393 rval = 0; 394 for (unit = 0; unit < zsc_cd.cd_ndevs; unit++) { 395 zsc = device_lookup_private(&zsc_cd, unit); 396 if (zsc == NULL) 397 continue; 398 rval |= zsc_intr_hard(zsc); 399 softreq = zsc->zsc_cs[0]->cs_softreq; 400 softreq |= zsc->zsc_cs[1]->cs_softreq; 401 if (softreq) 402 softint_schedule(zsc->zs_si); 403 } 404 405 return (rval); 406 } 407 408 /* 409 * Compute the current baud rate given a ZS channel. 410 */ 411 static int 412 zs_get_speed(struct zs_chanstate *cs) 413 { 414 int tconst; 415 416 tconst = zs_read_reg(cs, 12); 417 tconst |= zs_read_reg(cs, 13) << 8; 418 return (TCONST_TO_BPS(cs->cs_brg_clk, tconst)); 419 } 420 421 /* 422 * MD functions for setting the baud rate and control modes. 423 */ 424 int 425 zs_set_speed(struct zs_chanstate *cs, int bps) 426 { 427 int tconst, real_bps; 428 429 if (bps == 0) 430 return (0); 431 432 #ifdef DIAGNOSTIC 433 if (cs->cs_brg_clk == 0) 434 panic("zs_set_speed"); 435 #endif 436 437 tconst = BPS_TO_TCONST(cs->cs_brg_clk, bps); 438 if (tconst < 0) 439 return (EINVAL); 440 441 /* Convert back to make sure we can do it. */ 442 real_bps = TCONST_TO_BPS(cs->cs_brg_clk, tconst); 443 444 /* XXX - Allow some tolerance here? */ 445 if (real_bps != bps) 446 return (EINVAL); 447 448 cs->cs_preg[12] = tconst; 449 cs->cs_preg[13] = tconst >> 8; 450 451 /* Caller will stuff the pending registers. */ 452 return (0); 453 } 454 455 int 456 zs_set_modes(struct zs_chanstate *cs, int cflag /* bits per second */) 457 { 458 int s; 459 460 /* 461 * Output hardware flow control on the chip is horrendous: 462 * if carrier detect drops, the receiver is disabled, and if 463 * CTS drops, the transmitter is stoped IN MID CHARACTER! 464 * Therefore, NEVER set the HFC bit, and instead use the 465 * status interrupt to detect CTS changes. 466 */ 467 s = splzs(); 468 cs->cs_rr0_pps = 0; 469 if ((cflag & (CLOCAL | MDMBUF)) != 0) { 470 cs->cs_rr0_dcd = 0; 471 if ((cflag & MDMBUF) == 0) 472 cs->cs_rr0_pps = ZSRR0_DCD; 473 } else 474 cs->cs_rr0_dcd = ZSRR0_DCD; 475 if ((cflag & CRTSCTS) != 0) { 476 cs->cs_wr5_dtr = ZSWR5_DTR; 477 cs->cs_wr5_rts = ZSWR5_RTS; 478 cs->cs_rr0_cts = ZSRR0_CTS; 479 } else if ((cflag & MDMBUF) != 0) { 480 cs->cs_wr5_dtr = 0; 481 cs->cs_wr5_rts = ZSWR5_DTR; 482 cs->cs_rr0_cts = ZSRR0_DCD; 483 } else { 484 cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS; 485 cs->cs_wr5_rts = 0; 486 cs->cs_rr0_cts = 0; 487 } 488 splx(s); 489 490 /* Caller will stuff the pending registers. */ 491 return (0); 492 } 493 494 495 /* 496 * Read or write the chip with suitable delays. 497 */ 498 499 uint8_t 500 zs_read_reg(struct zs_chanstate *cs, uint8_t reg) 501 { 502 uint8_t val; 503 504 *cs->cs_reg_csr = reg; 505 ZS_DELAY(); 506 val = *cs->cs_reg_csr; 507 ZS_DELAY(); 508 return val; 509 } 510 511 void 512 zs_write_reg(struct zs_chanstate *cs, uint8_t reg, uint8_t val) 513 { 514 *cs->cs_reg_csr = reg; 515 ZS_DELAY(); 516 *cs->cs_reg_csr = val; 517 ZS_DELAY(); 518 } 519 520 uint8_t 521 zs_read_csr(struct zs_chanstate *cs) 522 { 523 uint8_t val; 524 525 val = *cs->cs_reg_csr; 526 ZS_DELAY(); 527 return val; 528 } 529 530 void 531 zs_write_csr(struct zs_chanstate *cs, uint8_t val) 532 { 533 *cs->cs_reg_csr = val; 534 ZS_DELAY(); 535 } 536 537 uint8_t 538 zs_read_data(struct zs_chanstate *cs) 539 { 540 uint8_t val; 541 542 val = *cs->cs_reg_data; 543 ZS_DELAY(); 544 return val; 545 } 546 547 void 548 zs_write_data(struct zs_chanstate *cs, uint8_t val) 549 { 550 *cs->cs_reg_data = val; 551 ZS_DELAY(); 552 } 553 554 /**************************************************************** 555 * Console support functions (Sun3 specific!) 556 * Note: this code is allowed to know about the layout of 557 * the chip registers, and uses that to keep things simple. 558 * XXX - I think I like the mvme167 code better. -gwr 559 ****************************************************************/ 560 561 void *zs_conschan; 562 563 /* 564 * Handle user request to enter kernel debugger. 565 */ 566 void 567 zs_abort(struct zs_chanstate *cs) 568 { 569 volatile struct zschan *zc = zs_conschan; 570 int rr0; 571 572 /* Wait for end of break to avoid PROM abort. */ 573 /* XXX - Limit the wait? */ 574 do { 575 rr0 = zc->zc_csr; 576 ZS_DELAY(); 577 } while (rr0 & ZSRR0_BREAK); 578 579 /* This is always available on the Sun3. */ 580 Debugger(); 581 } 582 583 /* 584 * Polled input char. 585 */ 586 int 587 zs_getc(void *arg) 588 { 589 volatile struct zschan *zc = arg; 590 int s, c, rr0; 591 592 s = splhigh(); 593 /* Wait for a character to arrive. */ 594 do { 595 rr0 = zc->zc_csr; 596 ZS_DELAY(); 597 } while ((rr0 & ZSRR0_RX_READY) == 0); 598 599 c = zc->zc_data; 600 ZS_DELAY(); 601 splx(s); 602 603 /* 604 * This is used by the kd driver to read scan codes, 605 * so don't translate '\r' ==> '\n' here... 606 */ 607 return (c); 608 } 609 610 /* 611 * Polled output char. 612 */ 613 void 614 zs_putc(void *arg, int c) 615 { 616 volatile struct zschan *zc = arg; 617 int s, rr0; 618 619 s = splhigh(); 620 /* Wait for transmitter to become ready. */ 621 do { 622 rr0 = zc->zc_csr; 623 ZS_DELAY(); 624 } while ((rr0 & ZSRR0_TX_READY) == 0); 625 626 zc->zc_data = c; 627 ZS_DELAY(); 628 splx(s); 629 } 630 631 /*****************************************************************/ 632 633 static void zscninit(struct consdev *); 634 static int zscngetc(dev_t); 635 static void zscnputc(dev_t, int); 636 637 /* 638 * Console table shared by ttya, ttyb 639 */ 640 struct consdev consdev_tty = { 641 nullcnprobe, 642 zscninit, 643 zscngetc, 644 zscnputc, 645 nullcnpollc, 646 NULL, 647 }; 648 649 static void 650 zscninit(struct consdev *cn) 651 { 652 } 653 654 /* 655 * Polled console input putchar. 656 */ 657 static int 658 zscngetc(dev_t dev) 659 { 660 return (zs_getc(zs_conschan)); 661 } 662 663 /* 664 * Polled console output putchar. 665 */ 666 static void 667 zscnputc(dev_t dev, int c) 668 { 669 zs_putc(zs_conschan, c); 670 } 671 672 /*****************************************************************/ 673 674 static void prom_cninit(struct consdev *); 675 static int prom_cngetc(dev_t); 676 static void prom_cnputc(dev_t, int); 677 678 /* 679 * The console is set to this one initially, 680 * which lets us use the PROM until consinit() 681 * is called to select a real console. 682 */ 683 struct consdev consdev_prom = { 684 nullcnprobe, 685 prom_cninit, 686 prom_cngetc, 687 prom_cnputc, 688 nullcnpollc, 689 }; 690 691 /* 692 * The console table pointer is statically initialized 693 * to point to the PROM (output only) table, so that 694 * early calls to printf will work. 695 */ 696 struct consdev *cn_tab = &consdev_prom; 697 698 void 699 nullcnprobe(struct consdev *cn) 700 { 701 } 702 703 static void 704 prom_cninit(struct consdev *cn) 705 { 706 } 707 708 /* 709 * PROM console input putchar. 710 * (dummy - this is output only) 711 */ 712 static int 713 prom_cngetc(dev_t dev) 714 { 715 return (0); 716 } 717 718 /* 719 * PROM console output putchar. 720 */ 721 static void 722 prom_cnputc(dev_t dev, int c) 723 { 724 (*romVectorPtr->putChar)(c & 0x7f); 725 } 726 727 /*****************************************************************/ 728 729 extern struct consdev consdev_kd; 730 731 static struct { 732 int zs_unit, channel; 733 } zstty_conf[NZS*2] = { 734 /* XXX: knowledge from the config file here... */ 735 { 1, 0 }, /* ttya */ 736 { 1, 1 }, /* ttyb */ 737 { 0, 0 }, /* ttyc */ 738 { 0, 1 }, /* ttyd */ 739 }; 740 741 static const char *prom_inSrc_name[] = { 742 "keyboard/display", 743 "ttya", "ttyb", 744 "ttyc", "ttyd" }; 745 746 /* 747 * This function replaces sys/dev/cninit.c 748 * Determine which device is the console using 749 * the PROM "input source" and "output sink". 750 */ 751 void 752 cninit(void) 753 { 754 struct sunromvec *v; 755 struct zschan *zc; 756 struct consdev *cn; 757 int channel, zs_unit, zstty_unit; 758 uint8_t inSource, outSink; 759 extern const struct cdevsw zstty_cdevsw; 760 761 /* Get the zs driver ready for console duty. */ 762 zs_init(); 763 764 v = romVectorPtr; 765 inSource = *v->inSource; 766 outSink = *v->outSink; 767 if (inSource != outSink) { 768 mon_printf("cninit: mismatched PROM output selector\n"); 769 } 770 771 switch (inSource) { 772 default: 773 mon_printf("cninit: invalid inSource=%d\n", inSource); 774 sunmon_abort(); 775 inSource = 0; 776 /* fall through */ 777 778 case 0: /* keyboard/display */ 779 #if NKBD > 0 780 zs_unit = 0; 781 channel = 0; 782 cn = &consdev_kd; 783 /* Set cn_dev, cn_pri in kd.c */ 784 break; 785 #else /* NKBD */ 786 mon_printf("cninit: kdb/display not configured\n"); 787 sunmon_abort(); 788 inSource = 1; 789 /* fall through */ 790 #endif /* NKBD */ 791 792 case 1: /* ttya */ 793 case 2: /* ttyb */ 794 case 3: /* ttyc (rewired keyboard connector) */ 795 case 4: /* ttyd (rewired mouse connector) */ 796 zstty_unit = inSource - 1; 797 zs_unit = zstty_conf[zstty_unit].zs_unit; 798 channel = zstty_conf[zstty_unit].channel; 799 cn = &consdev_tty; 800 cn->cn_dev = makedev(cdevsw_lookup_major(&zstty_cdevsw), 801 zstty_unit); 802 cn->cn_pri = CN_REMOTE; 803 break; 804 805 } 806 /* Now that inSource has been validated, print it. */ 807 mon_printf("console is %s\n", prom_inSrc_name[inSource]); 808 809 zc = zs_get_chan_addr(zs_unit, channel); 810 if (zc == NULL) { 811 mon_printf("cninit: zs not mapped.\n"); 812 return; 813 } 814 zs_conschan = zc; 815 zs_hwflags[zs_unit][channel] = ZS_HWFLAG_CONSOLE; 816 cn_tab = cn; 817 (*cn->cn_init)(cn); 818 #ifdef KGDB 819 zs_kgdb_init(); 820 #endif 821 } 822