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