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