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