1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1991 The Regents of the University of California. 6 * Copyright (c) 1999 Michael Smith 7 * Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org> 8 * 9 * All rights reserved. 10 * 11 * This code is derived from software contributed to Berkeley by 12 * the Systems Programming Group of the University of Utah Computer 13 * Science Department. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 18 * 1. Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in the 22 * documentation and/or other materials provided with the distribution. 23 * 3. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 */ 39 40 #include <sys/cdefs.h> 41 #include "opt_ddb.h" 42 #include "opt_syscons.h" 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/lock.h> 47 #include <sys/mutex.h> 48 #include <sys/conf.h> 49 #include <sys/cons.h> 50 #include <sys/fcntl.h> 51 #include <sys/kbio.h> 52 #include <sys/kdb.h> 53 #include <sys/kernel.h> 54 #include <sys/malloc.h> 55 #include <sys/msgbuf.h> 56 #include <sys/namei.h> 57 #include <sys/priv.h> 58 #include <sys/proc.h> 59 #include <sys/queue.h> 60 #include <sys/reboot.h> 61 #include <sys/sysctl.h> 62 #include <sys/sbuf.h> 63 #include <sys/tslog.h> 64 #include <sys/tty.h> 65 #include <sys/uio.h> 66 #include <sys/vnode.h> 67 68 #include <ddb/ddb.h> 69 70 #include <dev/kbd/kbdreg.h> 71 72 #include <machine/cpu.h> 73 #include <machine/clock.h> 74 75 static MALLOC_DEFINE(M_TTYCONS, "tty console", "tty console handling"); 76 77 struct cn_device { 78 STAILQ_ENTRY(cn_device) cnd_next; 79 struct consdev *cnd_cn; 80 }; 81 82 #define CNDEVPATHMAX 32 83 #define CNDEVTAB_SIZE 4 84 static struct cn_device cn_devtab[CNDEVTAB_SIZE]; 85 static STAILQ_HEAD(, cn_device) cn_devlist = 86 STAILQ_HEAD_INITIALIZER(cn_devlist); 87 88 int cons_avail_mask = 0; /* Bit mask. Each registered low level console 89 * which is currently unavailable for inpit 90 * (i.e., if it is in graphics mode) will have 91 * this bit cleared. 92 */ 93 94 static int cn_mute; 95 SYSCTL_INT(_kern, OID_AUTO, consmute, CTLFLAG_RW, &cn_mute, 0, 96 "State of the console muting"); 97 98 static char *consbuf; /* buffer used by `consmsgbuf' */ 99 static struct callout conscallout; /* callout for outputting to constty */ 100 struct msgbuf consmsgbuf; /* message buffer for console tty */ 101 static bool console_pausing; /* pause after each line during probe */ 102 static const char console_pausestr[] = 103 "<pause; press any key to proceed to next line or '.' to end pause mode>"; 104 struct tty *constty; /* pointer to console "window" tty */ 105 static struct mtx constty_mtx; /* Mutex for constty assignment. */ 106 MTX_SYSINIT(constty_mtx, &constty_mtx, "constty_mtx", MTX_DEF); 107 static struct mtx cnputs_mtx; /* Mutex for cnputs(). */ 108 MTX_SYSINIT(cnputs_mtx, &cnputs_mtx, "cnputs_mtx", MTX_SPIN | MTX_NOWITNESS); 109 110 static void constty_timeout(void *arg); 111 112 static struct consdev cons_consdev; 113 DATA_SET(cons_set, cons_consdev); 114 SET_DECLARE(cons_set, struct consdev); 115 116 /* 117 * Stub for configurations that don't actually have a keyboard driver. Inclusion 118 * of kbd.c is contingent on any number of keyboard/console drivers being 119 * present in the kernel; rather than trying to catch them all, we'll just 120 * maintain this weak kbdinit that will be overridden by the strong version in 121 * kbd.c if it's present. 122 */ 123 __weak_symbol void 124 kbdinit(void) 125 { 126 127 } 128 129 void 130 cninit(void) 131 { 132 struct consdev *best_cn, *cn, **list; 133 134 TSENTER(); 135 /* 136 * Check if we should mute the console (for security reasons perhaps) 137 * It can be changes dynamically using sysctl kern.consmute 138 * once we are up and going. 139 * 140 */ 141 cn_mute = ((boothowto & (RB_MUTE 142 |RB_SINGLE 143 |RB_VERBOSE 144 |RB_ASKNAME)) == RB_MUTE); 145 146 /* 147 * Bring up the kbd layer just in time for cnprobe. Console drivers 148 * have a dependency on kbd being ready, so this fits nicely between the 149 * machdep callers of cninit() and MI probing/initialization of consoles 150 * here. 151 */ 152 kbdinit(); 153 154 /* 155 * Find the first console with the highest priority. 156 */ 157 best_cn = NULL; 158 SET_FOREACH(list, cons_set) { 159 cn = *list; 160 cnremove(cn); 161 /* Skip cons_consdev. */ 162 if (cn->cn_ops == NULL) 163 continue; 164 cn->cn_ops->cn_probe(cn); 165 if (cn->cn_pri == CN_DEAD) 166 continue; 167 if (best_cn == NULL || cn->cn_pri > best_cn->cn_pri) 168 best_cn = cn; 169 if (boothowto & RB_MULTIPLE) { 170 /* 171 * Initialize console, and attach to it. 172 */ 173 cn->cn_ops->cn_init(cn); 174 cnadd(cn); 175 } 176 } 177 if (best_cn == NULL) 178 return; 179 if ((boothowto & RB_MULTIPLE) == 0) { 180 best_cn->cn_ops->cn_init(best_cn); 181 cnadd(best_cn); 182 } 183 if (boothowto & RB_PAUSE) 184 console_pausing = true; 185 /* 186 * Make the best console the preferred console. 187 */ 188 cnselect(best_cn); 189 190 #ifdef EARLY_PRINTF 191 /* 192 * Release early console. 193 */ 194 early_putc = NULL; 195 #endif 196 TSEXIT(); 197 } 198 199 void 200 cninit_finish(void) 201 { 202 console_pausing = false; 203 } 204 205 /* add a new physical console to back the virtual console */ 206 int 207 cnadd(struct consdev *cn) 208 { 209 struct cn_device *cnd; 210 int i; 211 212 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) 213 if (cnd->cnd_cn == cn) 214 return (0); 215 for (i = 0; i < CNDEVTAB_SIZE; i++) { 216 cnd = &cn_devtab[i]; 217 if (cnd->cnd_cn == NULL) 218 break; 219 } 220 if (cnd->cnd_cn != NULL) 221 return (ENOMEM); 222 cnd->cnd_cn = cn; 223 if (cn->cn_name[0] == '\0') { 224 /* XXX: it is unclear if/where this print might output */ 225 printf("WARNING: console at %p has no name\n", cn); 226 } 227 STAILQ_INSERT_TAIL(&cn_devlist, cnd, cnd_next); 228 if (STAILQ_FIRST(&cn_devlist) == cnd) 229 ttyconsdev_select(cnd->cnd_cn->cn_name); 230 231 /* Add device to the active mask. */ 232 cnavailable(cn, (cn->cn_flags & CN_FLAG_NOAVAIL) == 0); 233 234 return (0); 235 } 236 237 void 238 cnremove(struct consdev *cn) 239 { 240 struct cn_device *cnd; 241 int i; 242 243 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) { 244 if (cnd->cnd_cn != cn) 245 continue; 246 if (STAILQ_FIRST(&cn_devlist) == cnd) 247 ttyconsdev_select(NULL); 248 STAILQ_REMOVE(&cn_devlist, cnd, cn_device, cnd_next); 249 cnd->cnd_cn = NULL; 250 251 /* Remove this device from available mask. */ 252 for (i = 0; i < CNDEVTAB_SIZE; i++) 253 if (cnd == &cn_devtab[i]) { 254 cons_avail_mask &= ~(1 << i); 255 break; 256 } 257 #if 0 258 /* 259 * XXX 260 * syscons gets really confused if console resources are 261 * freed after the system has initialized. 262 */ 263 if (cn->cn_term != NULL) 264 cn->cn_ops->cn_term(cn); 265 #endif 266 return; 267 } 268 } 269 270 void 271 cnselect(struct consdev *cn) 272 { 273 struct cn_device *cnd; 274 275 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) { 276 if (cnd->cnd_cn != cn) 277 continue; 278 if (cnd == STAILQ_FIRST(&cn_devlist)) 279 return; 280 STAILQ_REMOVE(&cn_devlist, cnd, cn_device, cnd_next); 281 STAILQ_INSERT_HEAD(&cn_devlist, cnd, cnd_next); 282 ttyconsdev_select(cnd->cnd_cn->cn_name); 283 return; 284 } 285 } 286 287 void 288 cnavailable(struct consdev *cn, int available) 289 { 290 int i; 291 292 for (i = 0; i < CNDEVTAB_SIZE; i++) { 293 if (cn_devtab[i].cnd_cn == cn) 294 break; 295 } 296 if (available) { 297 if (i < CNDEVTAB_SIZE) 298 cons_avail_mask |= (1 << i); 299 cn->cn_flags &= ~CN_FLAG_NOAVAIL; 300 } else { 301 if (i < CNDEVTAB_SIZE) 302 cons_avail_mask &= ~(1 << i); 303 cn->cn_flags |= CN_FLAG_NOAVAIL; 304 } 305 } 306 307 int 308 cnunavailable(void) 309 { 310 311 return (cons_avail_mask == 0); 312 } 313 314 /* 315 * sysctl_kern_console() provides output parseable in conscontrol(1). 316 */ 317 static int 318 sysctl_kern_console(SYSCTL_HANDLER_ARGS) 319 { 320 struct cn_device *cnd; 321 struct consdev *cp, **list; 322 char *p; 323 bool delete; 324 int error; 325 struct sbuf *sb; 326 327 sb = sbuf_new(NULL, NULL, CNDEVPATHMAX * 2, SBUF_AUTOEXTEND | 328 SBUF_INCLUDENUL); 329 if (sb == NULL) 330 return (ENOMEM); 331 sbuf_clear(sb); 332 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) 333 sbuf_printf(sb, "%s,", cnd->cnd_cn->cn_name); 334 sbuf_putc(sb, '/'); 335 SET_FOREACH(list, cons_set) { 336 cp = *list; 337 if (cp->cn_name[0] != '\0') 338 sbuf_printf(sb, "%s,", cp->cn_name); 339 } 340 sbuf_finish(sb); 341 error = sysctl_handle_string(oidp, sbuf_data(sb), sbuf_len(sb), req); 342 if (error == 0 && req->newptr != NULL) { 343 p = sbuf_data(sb); 344 error = ENXIO; 345 delete = false; 346 if (*p == '-') { 347 delete = true; 348 p++; 349 } 350 SET_FOREACH(list, cons_set) { 351 cp = *list; 352 if (strcmp(p, cp->cn_name) != 0) 353 continue; 354 if (delete) { 355 cnremove(cp); 356 error = 0; 357 } else { 358 error = cnadd(cp); 359 if (error == 0) 360 cnselect(cp); 361 } 362 break; 363 } 364 } 365 sbuf_delete(sb); 366 return (error); 367 } 368 369 SYSCTL_PROC(_kern, OID_AUTO, console, 370 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 0, 0, 371 sysctl_kern_console, "A", 372 "Console device control"); 373 374 void 375 cngrab(void) 376 { 377 struct cn_device *cnd; 378 struct consdev *cn; 379 380 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) { 381 cn = cnd->cnd_cn; 382 if (!kdb_active || !(cn->cn_flags & CN_FLAG_NODEBUG)) 383 cn->cn_ops->cn_grab(cn); 384 } 385 } 386 387 void 388 cnungrab(void) 389 { 390 struct cn_device *cnd; 391 struct consdev *cn; 392 393 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) { 394 cn = cnd->cnd_cn; 395 if (!kdb_active || !(cn->cn_flags & CN_FLAG_NODEBUG)) 396 cn->cn_ops->cn_ungrab(cn); 397 } 398 } 399 400 void 401 cnresume(void) 402 { 403 struct cn_device *cnd; 404 struct consdev *cn; 405 406 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) { 407 cn = cnd->cnd_cn; 408 if (cn->cn_ops->cn_resume != NULL) 409 cn->cn_ops->cn_resume(cn); 410 } 411 } 412 413 /* 414 * Low level console routines. 415 */ 416 int 417 cngetc(void) 418 { 419 int c; 420 421 if (cn_mute) 422 return (-1); 423 while ((c = cncheckc()) == -1) 424 cpu_spinwait(); 425 if (c == '\r') 426 c = '\n'; /* console input is always ICRNL */ 427 return (c); 428 } 429 430 int 431 cncheckc(void) 432 { 433 struct cn_device *cnd; 434 struct consdev *cn; 435 int c; 436 437 if (cn_mute) 438 return (-1); 439 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) { 440 cn = cnd->cnd_cn; 441 if (!kdb_active || !(cn->cn_flags & CN_FLAG_NODEBUG)) { 442 c = cn->cn_ops->cn_getc(cn); 443 if (c != -1) 444 return (c); 445 } 446 } 447 return (-1); 448 } 449 450 void 451 cngets(char *cp, size_t size, int visible) 452 { 453 char *lp, *end; 454 int c; 455 456 cngrab(); 457 458 lp = cp; 459 end = cp + size - 1; 460 for (;;) { 461 c = cngetc() & 0177; 462 switch (c) { 463 case '\n': 464 case '\r': 465 cnputc(c); 466 *lp = '\0'; 467 cnungrab(); 468 return; 469 case '\b': 470 case '\177': 471 if (lp > cp) { 472 if (visible) 473 cnputs("\b \b"); 474 lp--; 475 } 476 continue; 477 case '\0': 478 continue; 479 default: 480 if (lp < end) { 481 switch (visible) { 482 case GETS_NOECHO: 483 break; 484 case GETS_ECHOPASS: 485 cnputc('*'); 486 break; 487 default: 488 cnputc(c); 489 break; 490 } 491 *lp++ = c; 492 } 493 } 494 } 495 } 496 497 void 498 cnputc(int c) 499 { 500 struct cn_device *cnd; 501 struct consdev *cn; 502 const char *cp; 503 504 #ifdef EARLY_PRINTF 505 if (early_putc != NULL) { 506 if (c == '\n') 507 early_putc('\r'); 508 early_putc(c); 509 return; 510 } 511 #endif 512 513 if (cn_mute || c == '\0') 514 return; 515 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) { 516 cn = cnd->cnd_cn; 517 if (!kdb_active || !(cn->cn_flags & CN_FLAG_NODEBUG)) { 518 if (c == '\n') 519 cn->cn_ops->cn_putc(cn, '\r'); 520 cn->cn_ops->cn_putc(cn, c); 521 } 522 } 523 if (console_pausing && c == '\n' && !kdb_active) { 524 for (cp = console_pausestr; *cp != '\0'; cp++) 525 cnputc(*cp); 526 cngrab(); 527 if (cngetc() == '.') 528 console_pausing = false; 529 cnungrab(); 530 cnputc('\r'); 531 for (cp = console_pausestr; *cp != '\0'; cp++) 532 cnputc(' '); 533 cnputc('\r'); 534 } 535 } 536 537 void 538 cnputsn(const char *p, size_t n) 539 { 540 size_t i; 541 bool unlock_reqd = false; 542 543 if (mtx_initialized(&cnputs_mtx)) { 544 /* 545 * NOTE: Debug prints and/or witness printouts in 546 * console driver clients can cause the "cnputs_mtx" 547 * mutex to recurse. Simply return if that happens. 548 */ 549 if (mtx_owned(&cnputs_mtx)) 550 return; 551 mtx_lock_spin(&cnputs_mtx); 552 unlock_reqd = true; 553 } 554 555 for (i = 0; i < n; i++) 556 cnputc(p[i]); 557 558 if (unlock_reqd) 559 mtx_unlock_spin(&cnputs_mtx); 560 } 561 562 void 563 cnputs(const char *p) 564 { 565 cnputsn(p, strlen(p)); 566 } 567 568 static unsigned int consmsgbuf_size = 65536; 569 SYSCTL_UINT(_kern, OID_AUTO, consmsgbuf_size, CTLFLAG_RWTUN, &consmsgbuf_size, 570 0, "Console tty buffer size"); 571 572 /* 573 * Redirect console output to a tty. 574 */ 575 int 576 constty_set(struct tty *tp) 577 { 578 int size = consmsgbuf_size; 579 void *buf = NULL; 580 581 tty_assert_locked(tp); 582 if (constty == tp) 583 return (0); 584 if (constty != NULL) 585 return (EBUSY); 586 587 if (consbuf == NULL) { 588 tty_unlock(tp); 589 buf = malloc(size, M_TTYCONS, M_WAITOK); 590 tty_lock(tp); 591 } 592 mtx_lock(&constty_mtx); 593 if (constty != NULL) { 594 mtx_unlock(&constty_mtx); 595 free(buf, M_TTYCONS); 596 return (EBUSY); 597 } 598 if (consbuf == NULL) { 599 consbuf = buf; 600 msgbuf_init(&consmsgbuf, buf, size); 601 } else 602 free(buf, M_TTYCONS); 603 constty = tp; 604 mtx_unlock(&constty_mtx); 605 606 callout_init_mtx(&conscallout, tty_getlock(tp), 0); 607 constty_timeout(tp); 608 return (0); 609 } 610 611 /* 612 * Disable console redirection to a tty. 613 */ 614 int 615 constty_clear(struct tty *tp) 616 { 617 int c; 618 619 tty_assert_locked(tp); 620 if (constty != tp) 621 return (ENXIO); 622 callout_stop(&conscallout); 623 mtx_lock(&constty_mtx); 624 constty = NULL; 625 mtx_unlock(&constty_mtx); 626 while ((c = msgbuf_getchar(&consmsgbuf)) != -1) 627 cnputc(c); 628 /* We never free consbuf because it can still be in use. */ 629 return (0); 630 } 631 632 /* Times per second to check for pending console tty messages. */ 633 static int constty_wakeups_per_second = 15; 634 SYSCTL_INT(_kern, OID_AUTO, constty_wakeups_per_second, CTLFLAG_RW, 635 &constty_wakeups_per_second, 0, 636 "Times per second to check for pending console tty messages"); 637 638 static void 639 constty_timeout(void *arg) 640 { 641 struct tty *tp = arg; 642 int c; 643 644 tty_assert_locked(tp); 645 while ((c = msgbuf_getchar(&consmsgbuf)) != -1) { 646 if (tty_putchar(tp, c) < 0) { 647 constty_clear(tp); 648 return; 649 } 650 } 651 callout_reset_sbt(&conscallout, SBT_1S / constty_wakeups_per_second, 652 0, constty_timeout, tp, C_PREL(1)); 653 } 654 655 /* 656 * Sysbeep(), if we have hardware for it 657 */ 658 659 #ifdef HAS_TIMER_SPKR 660 661 static bool beeping; 662 static struct callout beeping_timer; 663 664 static void 665 sysbeepstop(void *chan) 666 { 667 668 timer_spkr_release(); 669 beeping = false; 670 } 671 672 int 673 sysbeep(int pitch, sbintime_t duration) 674 { 675 676 if (timer_spkr_acquire()) { 677 if (!beeping) { 678 /* Something else owns it. */ 679 return (EBUSY); 680 } 681 } 682 timer_spkr_setfreq(pitch); 683 if (!beeping) { 684 beeping = true; 685 callout_reset_sbt(&beeping_timer, duration, 0, sysbeepstop, 686 NULL, C_PREL(5)); 687 } 688 return (0); 689 } 690 691 static void 692 sysbeep_init(void *unused) 693 { 694 695 callout_init(&beeping_timer, 1); 696 } 697 SYSINIT(sysbeep, SI_SUB_SOFTINTR, SI_ORDER_ANY, sysbeep_init, NULL); 698 #else 699 700 /* 701 * No hardware, no sound 702 */ 703 704 int 705 sysbeep(int pitch __unused, sbintime_t duration __unused) 706 { 707 708 return (ENODEV); 709 } 710 711 #endif 712 713 /* 714 * Temporary support for sc(4) to vt(4) transition. 715 */ 716 static unsigned vty_prefer; 717 static char vty_name[16]; 718 SYSCTL_STRING(_kern, OID_AUTO, vty, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, vty_name, 719 0, "Console vty driver"); 720 721 int 722 vty_enabled(unsigned vty) 723 { 724 static unsigned vty_selected = 0; 725 726 if (vty_selected == 0) { 727 TUNABLE_STR_FETCH("kern.vty", vty_name, sizeof(vty_name)); 728 do { 729 #if defined(DEV_SC) 730 if (strcmp(vty_name, "sc") == 0) { 731 vty_selected = VTY_SC; 732 break; 733 } 734 #endif 735 #if defined(DEV_VT) 736 if (strcmp(vty_name, "vt") == 0) { 737 vty_selected = VTY_VT; 738 break; 739 } 740 #endif 741 if (vty_prefer != 0) { 742 vty_selected = vty_prefer; 743 break; 744 } 745 #if defined(DEV_VT) 746 vty_selected = VTY_VT; 747 #elif defined(DEV_SC) 748 vty_selected = VTY_SC; 749 #endif 750 } while (0); 751 752 if (vty_selected == VTY_VT) 753 strcpy(vty_name, "vt"); 754 else if (vty_selected == VTY_SC) 755 strcpy(vty_name, "sc"); 756 } 757 return ((vty_selected & vty) != 0); 758 } 759 760 void 761 vty_set_preferred(unsigned vty) 762 { 763 764 vty_prefer = vty; 765 #if !defined(DEV_SC) 766 vty_prefer &= ~VTY_SC; 767 #endif 768 #if !defined(DEV_VT) 769 vty_prefer &= ~VTY_VT; 770 #endif 771 } 772