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