1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2012 NetApp, Inc. 5 * Copyright (c) 2013 Neel Natu <neel@freebsd.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/types.h> 31 #include <dev/ic/ns16550.h> 32 #ifndef WITHOUT_CAPSICUM 33 #include <sys/capsicum.h> 34 #include <capsicum_helpers.h> 35 #endif 36 37 #include <machine/vmm_snapshot.h> 38 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <assert.h> 42 #include <err.h> 43 #include <errno.h> 44 #include <fcntl.h> 45 #include <termios.h> 46 #include <unistd.h> 47 #include <stdbool.h> 48 #include <string.h> 49 #include <pthread.h> 50 #include <sysexits.h> 51 52 #include "mevent.h" 53 #include "uart_emul.h" 54 #include "debug.h" 55 56 #define COM1_BASE 0x3F8 57 #define COM1_IRQ 4 58 #define COM2_BASE 0x2F8 59 #define COM2_IRQ 3 60 #define COM3_BASE 0x3E8 61 #define COM3_IRQ 4 62 #define COM4_BASE 0x2E8 63 #define COM4_IRQ 3 64 65 #define DEFAULT_RCLK 1843200 66 #define DEFAULT_BAUD 115200 67 68 #define FCR_RX_MASK 0xC0 69 70 #define MCR_OUT1 0x04 71 #define MCR_OUT2 0x08 72 73 #define MSR_DELTA_MASK 0x0f 74 75 #ifndef REG_SCR 76 #define REG_SCR com_scr 77 #endif 78 79 #define FIFOSZ 16 80 81 static bool uart_stdio; /* stdio in use for i/o */ 82 static struct termios tio_stdio_orig; 83 84 static struct { 85 int baseaddr; 86 int irq; 87 bool inuse; 88 } uart_lres[] = { 89 { COM1_BASE, COM1_IRQ, false}, 90 { COM2_BASE, COM2_IRQ, false}, 91 { COM3_BASE, COM3_IRQ, false}, 92 { COM4_BASE, COM4_IRQ, false}, 93 }; 94 95 #define UART_NLDEVS (sizeof(uart_lres) / sizeof(uart_lres[0])) 96 97 struct fifo { 98 uint8_t buf[FIFOSZ]; 99 int rindex; /* index to read from */ 100 int windex; /* index to write to */ 101 int num; /* number of characters in the fifo */ 102 int size; /* size of the fifo */ 103 }; 104 105 struct ttyfd { 106 bool opened; 107 int rfd; /* fd for reading */ 108 int wfd; /* fd for writing, may be == rfd */ 109 }; 110 111 struct uart_softc { 112 pthread_mutex_t mtx; /* protects all softc elements */ 113 uint8_t data; /* Data register (R/W) */ 114 uint8_t ier; /* Interrupt enable register (R/W) */ 115 uint8_t lcr; /* Line control register (R/W) */ 116 uint8_t mcr; /* Modem control register (R/W) */ 117 uint8_t lsr; /* Line status register (R/W) */ 118 uint8_t msr; /* Modem status register (R/W) */ 119 uint8_t fcr; /* FIFO control register (W) */ 120 uint8_t scr; /* Scratch register (R/W) */ 121 122 uint8_t dll; /* Baudrate divisor latch LSB */ 123 uint8_t dlh; /* Baudrate divisor latch MSB */ 124 125 struct fifo rxfifo; 126 struct mevent *mev; 127 128 struct ttyfd tty; 129 bool thre_int_pending; /* THRE interrupt pending */ 130 131 void *arg; 132 uart_intr_func_t intr_assert; 133 uart_intr_func_t intr_deassert; 134 }; 135 136 static void uart_drain(int fd, enum ev_type ev, void *arg); 137 138 static void 139 ttyclose(void) 140 { 141 142 tcsetattr(STDIN_FILENO, TCSANOW, &tio_stdio_orig); 143 } 144 145 static void 146 ttyopen(struct ttyfd *tf) 147 { 148 struct termios orig, new; 149 150 tcgetattr(tf->rfd, &orig); 151 new = orig; 152 cfmakeraw(&new); 153 new.c_cflag |= CLOCAL; 154 tcsetattr(tf->rfd, TCSANOW, &new); 155 if (uart_stdio) { 156 tio_stdio_orig = orig; 157 atexit(ttyclose); 158 } 159 raw_stdio = 1; 160 } 161 162 static int 163 ttyread(struct ttyfd *tf) 164 { 165 unsigned char rb; 166 167 if (read(tf->rfd, &rb, 1) == 1) 168 return (rb); 169 else 170 return (-1); 171 } 172 173 static void 174 ttywrite(struct ttyfd *tf, unsigned char wb) 175 { 176 177 (void)write(tf->wfd, &wb, 1); 178 } 179 180 static void 181 rxfifo_reset(struct uart_softc *sc, int size) 182 { 183 char flushbuf[32]; 184 struct fifo *fifo; 185 ssize_t nread; 186 int error; 187 188 fifo = &sc->rxfifo; 189 bzero(fifo, sizeof(struct fifo)); 190 fifo->size = size; 191 192 if (sc->tty.opened) { 193 /* 194 * Flush any unread input from the tty buffer. 195 */ 196 while (1) { 197 nread = read(sc->tty.rfd, flushbuf, sizeof(flushbuf)); 198 if (nread != sizeof(flushbuf)) 199 break; 200 } 201 202 /* 203 * Enable mevent to trigger when new characters are available 204 * on the tty fd. 205 */ 206 error = mevent_enable(sc->mev); 207 assert(error == 0); 208 } 209 } 210 211 static int 212 rxfifo_available(struct uart_softc *sc) 213 { 214 struct fifo *fifo; 215 216 fifo = &sc->rxfifo; 217 return (fifo->num < fifo->size); 218 } 219 220 static int 221 rxfifo_putchar(struct uart_softc *sc, uint8_t ch) 222 { 223 struct fifo *fifo; 224 int error; 225 226 fifo = &sc->rxfifo; 227 228 if (fifo->num < fifo->size) { 229 fifo->buf[fifo->windex] = ch; 230 fifo->windex = (fifo->windex + 1) % fifo->size; 231 fifo->num++; 232 if (!rxfifo_available(sc)) { 233 if (sc->tty.opened) { 234 /* 235 * Disable mevent callback if the FIFO is full. 236 */ 237 error = mevent_disable(sc->mev); 238 assert(error == 0); 239 } 240 } 241 return (0); 242 } else 243 return (-1); 244 } 245 246 static int 247 rxfifo_getchar(struct uart_softc *sc) 248 { 249 struct fifo *fifo; 250 int c, error, wasfull; 251 252 wasfull = 0; 253 fifo = &sc->rxfifo; 254 if (fifo->num > 0) { 255 if (!rxfifo_available(sc)) 256 wasfull = 1; 257 c = fifo->buf[fifo->rindex]; 258 fifo->rindex = (fifo->rindex + 1) % fifo->size; 259 fifo->num--; 260 if (wasfull) { 261 if (sc->tty.opened) { 262 error = mevent_enable(sc->mev); 263 assert(error == 0); 264 } 265 } 266 return (c); 267 } else 268 return (-1); 269 } 270 271 static int 272 rxfifo_numchars(struct uart_softc *sc) 273 { 274 struct fifo *fifo = &sc->rxfifo; 275 276 return (fifo->num); 277 } 278 279 static void 280 uart_opentty(struct uart_softc *sc) 281 { 282 283 ttyopen(&sc->tty); 284 sc->mev = mevent_add(sc->tty.rfd, EVF_READ, uart_drain, sc); 285 assert(sc->mev != NULL); 286 } 287 288 static uint8_t 289 modem_status(uint8_t mcr) 290 { 291 uint8_t msr; 292 293 if (mcr & MCR_LOOPBACK) { 294 /* 295 * In the loopback mode certain bits from the MCR are 296 * reflected back into MSR. 297 */ 298 msr = 0; 299 if (mcr & MCR_RTS) 300 msr |= MSR_CTS; 301 if (mcr & MCR_DTR) 302 msr |= MSR_DSR; 303 if (mcr & MCR_OUT1) 304 msr |= MSR_RI; 305 if (mcr & MCR_OUT2) 306 msr |= MSR_DCD; 307 } else { 308 /* 309 * Always assert DCD and DSR so tty open doesn't block 310 * even if CLOCAL is turned off. 311 */ 312 msr = MSR_DCD | MSR_DSR; 313 } 314 assert((msr & MSR_DELTA_MASK) == 0); 315 316 return (msr); 317 } 318 319 /* 320 * The IIR returns a prioritized interrupt reason: 321 * - receive data available 322 * - transmit holding register empty 323 * - modem status change 324 * 325 * Return an interrupt reason if one is available. 326 */ 327 static int 328 uart_intr_reason(struct uart_softc *sc) 329 { 330 331 if ((sc->lsr & LSR_OE) != 0 && (sc->ier & IER_ERLS) != 0) 332 return (IIR_RLS); 333 else if (rxfifo_numchars(sc) > 0 && (sc->ier & IER_ERXRDY) != 0) 334 return (IIR_RXTOUT); 335 else if (sc->thre_int_pending && (sc->ier & IER_ETXRDY) != 0) 336 return (IIR_TXRDY); 337 else if ((sc->msr & MSR_DELTA_MASK) != 0 && (sc->ier & IER_EMSC) != 0) 338 return (IIR_MLSC); 339 else 340 return (IIR_NOPEND); 341 } 342 343 static void 344 uart_reset(struct uart_softc *sc) 345 { 346 uint16_t divisor; 347 348 divisor = DEFAULT_RCLK / DEFAULT_BAUD / 16; 349 sc->dll = divisor; 350 sc->dlh = divisor >> 16; 351 sc->msr = modem_status(sc->mcr); 352 353 rxfifo_reset(sc, 1); /* no fifo until enabled by software */ 354 } 355 356 /* 357 * Toggle the COM port's intr pin depending on whether or not we have an 358 * interrupt condition to report to the processor. 359 */ 360 static void 361 uart_toggle_intr(struct uart_softc *sc) 362 { 363 uint8_t intr_reason; 364 365 intr_reason = uart_intr_reason(sc); 366 367 if (intr_reason == IIR_NOPEND) 368 (*sc->intr_deassert)(sc->arg); 369 else 370 (*sc->intr_assert)(sc->arg); 371 } 372 373 static void 374 uart_drain(int fd, enum ev_type ev, void *arg) 375 { 376 struct uart_softc *sc; 377 int ch; 378 379 sc = arg; 380 381 assert(fd == sc->tty.rfd); 382 assert(ev == EVF_READ); 383 384 /* 385 * This routine is called in the context of the mevent thread 386 * to take out the softc lock to protect against concurrent 387 * access from a vCPU i/o exit 388 */ 389 pthread_mutex_lock(&sc->mtx); 390 391 if ((sc->mcr & MCR_LOOPBACK) != 0) { 392 (void) ttyread(&sc->tty); 393 } else { 394 while (rxfifo_available(sc) && 395 ((ch = ttyread(&sc->tty)) != -1)) { 396 rxfifo_putchar(sc, ch); 397 } 398 uart_toggle_intr(sc); 399 } 400 401 pthread_mutex_unlock(&sc->mtx); 402 } 403 404 void 405 uart_write(struct uart_softc *sc, int offset, uint8_t value) 406 { 407 int fifosz; 408 uint8_t msr; 409 410 pthread_mutex_lock(&sc->mtx); 411 412 /* 413 * Take care of the special case DLAB accesses first 414 */ 415 if ((sc->lcr & LCR_DLAB) != 0) { 416 if (offset == REG_DLL) { 417 sc->dll = value; 418 goto done; 419 } 420 421 if (offset == REG_DLH) { 422 sc->dlh = value; 423 goto done; 424 } 425 } 426 427 switch (offset) { 428 case REG_DATA: 429 if (sc->mcr & MCR_LOOPBACK) { 430 if (rxfifo_putchar(sc, value) != 0) 431 sc->lsr |= LSR_OE; 432 } else if (sc->tty.opened) { 433 ttywrite(&sc->tty, value); 434 } /* else drop on floor */ 435 sc->thre_int_pending = true; 436 break; 437 case REG_IER: 438 /* Set pending when IER_ETXRDY is raised (edge-triggered). */ 439 if ((sc->ier & IER_ETXRDY) == 0 && (value & IER_ETXRDY) != 0) 440 sc->thre_int_pending = true; 441 /* 442 * Apply mask so that bits 4-7 are 0 443 * Also enables bits 0-3 only if they're 1 444 */ 445 sc->ier = value & 0x0F; 446 break; 447 case REG_FCR: 448 /* 449 * When moving from FIFO and 16450 mode and vice versa, 450 * the FIFO contents are reset. 451 */ 452 if ((sc->fcr & FCR_ENABLE) ^ (value & FCR_ENABLE)) { 453 fifosz = (value & FCR_ENABLE) ? FIFOSZ : 1; 454 rxfifo_reset(sc, fifosz); 455 } 456 457 /* 458 * The FCR_ENABLE bit must be '1' for the programming 459 * of other FCR bits to be effective. 460 */ 461 if ((value & FCR_ENABLE) == 0) { 462 sc->fcr = 0; 463 } else { 464 if ((value & FCR_RCV_RST) != 0) 465 rxfifo_reset(sc, FIFOSZ); 466 467 sc->fcr = value & 468 (FCR_ENABLE | FCR_DMA | FCR_RX_MASK); 469 } 470 break; 471 case REG_LCR: 472 sc->lcr = value; 473 break; 474 case REG_MCR: 475 /* Apply mask so that bits 5-7 are 0 */ 476 sc->mcr = value & 0x1F; 477 msr = modem_status(sc->mcr); 478 479 /* 480 * Detect if there has been any change between the 481 * previous and the new value of MSR. If there is 482 * then assert the appropriate MSR delta bit. 483 */ 484 if ((msr & MSR_CTS) ^ (sc->msr & MSR_CTS)) 485 sc->msr |= MSR_DCTS; 486 if ((msr & MSR_DSR) ^ (sc->msr & MSR_DSR)) 487 sc->msr |= MSR_DDSR; 488 if ((msr & MSR_DCD) ^ (sc->msr & MSR_DCD)) 489 sc->msr |= MSR_DDCD; 490 if ((sc->msr & MSR_RI) != 0 && (msr & MSR_RI) == 0) 491 sc->msr |= MSR_TERI; 492 493 /* 494 * Update the value of MSR while retaining the delta 495 * bits. 496 */ 497 sc->msr &= MSR_DELTA_MASK; 498 sc->msr |= msr; 499 break; 500 case REG_LSR: 501 /* 502 * Line status register is not meant to be written to 503 * during normal operation. 504 */ 505 break; 506 case REG_MSR: 507 /* 508 * As far as I can tell MSR is a read-only register. 509 */ 510 break; 511 case REG_SCR: 512 sc->scr = value; 513 break; 514 default: 515 break; 516 } 517 518 done: 519 uart_toggle_intr(sc); 520 pthread_mutex_unlock(&sc->mtx); 521 } 522 523 uint8_t 524 uart_read(struct uart_softc *sc, int offset) 525 { 526 uint8_t iir, intr_reason, reg; 527 528 pthread_mutex_lock(&sc->mtx); 529 530 /* 531 * Take care of the special case DLAB accesses first 532 */ 533 if ((sc->lcr & LCR_DLAB) != 0) { 534 if (offset == REG_DLL) { 535 reg = sc->dll; 536 goto done; 537 } 538 539 if (offset == REG_DLH) { 540 reg = sc->dlh; 541 goto done; 542 } 543 } 544 545 switch (offset) { 546 case REG_DATA: 547 reg = rxfifo_getchar(sc); 548 break; 549 case REG_IER: 550 reg = sc->ier; 551 break; 552 case REG_IIR: 553 iir = (sc->fcr & FCR_ENABLE) ? IIR_FIFO_MASK : 0; 554 555 intr_reason = uart_intr_reason(sc); 556 557 /* 558 * Deal with side effects of reading the IIR register 559 */ 560 if (intr_reason == IIR_TXRDY) 561 sc->thre_int_pending = false; 562 563 iir |= intr_reason; 564 565 reg = iir; 566 break; 567 case REG_LCR: 568 reg = sc->lcr; 569 break; 570 case REG_MCR: 571 reg = sc->mcr; 572 break; 573 case REG_LSR: 574 /* Transmitter is always ready for more data */ 575 sc->lsr |= LSR_TEMT | LSR_THRE; 576 577 /* Check for new receive data */ 578 if (rxfifo_numchars(sc) > 0) 579 sc->lsr |= LSR_RXRDY; 580 else 581 sc->lsr &= ~LSR_RXRDY; 582 583 reg = sc->lsr; 584 585 /* The LSR_OE bit is cleared on LSR read */ 586 sc->lsr &= ~LSR_OE; 587 break; 588 case REG_MSR: 589 /* 590 * MSR delta bits are cleared on read 591 */ 592 reg = sc->msr; 593 sc->msr &= ~MSR_DELTA_MASK; 594 break; 595 case REG_SCR: 596 reg = sc->scr; 597 break; 598 default: 599 reg = 0xFF; 600 break; 601 } 602 603 done: 604 uart_toggle_intr(sc); 605 pthread_mutex_unlock(&sc->mtx); 606 607 return (reg); 608 } 609 610 int 611 uart_legacy_alloc(int which, int *baseaddr, int *irq) 612 { 613 614 if (which < 0 || which >= (int)UART_NLDEVS || uart_lres[which].inuse) 615 return (-1); 616 617 uart_lres[which].inuse = true; 618 *baseaddr = uart_lres[which].baseaddr; 619 *irq = uart_lres[which].irq; 620 621 return (0); 622 } 623 624 struct uart_softc * 625 uart_init(uart_intr_func_t intr_assert, uart_intr_func_t intr_deassert, 626 void *arg) 627 { 628 struct uart_softc *sc; 629 630 sc = calloc(1, sizeof(struct uart_softc)); 631 632 sc->arg = arg; 633 sc->intr_assert = intr_assert; 634 sc->intr_deassert = intr_deassert; 635 636 pthread_mutex_init(&sc->mtx, NULL); 637 638 uart_reset(sc); 639 640 return (sc); 641 } 642 643 static int 644 uart_stdio_backend(struct uart_softc *sc) 645 { 646 #ifndef WITHOUT_CAPSICUM 647 cap_rights_t rights; 648 cap_ioctl_t cmds[] = { TIOCGETA, TIOCSETA, TIOCGWINSZ }; 649 #endif 650 651 if (uart_stdio) 652 return (-1); 653 654 sc->tty.rfd = STDIN_FILENO; 655 sc->tty.wfd = STDOUT_FILENO; 656 sc->tty.opened = true; 657 658 if (fcntl(sc->tty.rfd, F_SETFL, O_NONBLOCK) != 0) 659 return (-1); 660 if (fcntl(sc->tty.wfd, F_SETFL, O_NONBLOCK) != 0) 661 return (-1); 662 663 #ifndef WITHOUT_CAPSICUM 664 cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ); 665 if (caph_rights_limit(sc->tty.rfd, &rights) == -1) 666 errx(EX_OSERR, "Unable to apply rights for sandbox"); 667 if (caph_ioctls_limit(sc->tty.rfd, cmds, nitems(cmds)) == -1) 668 errx(EX_OSERR, "Unable to apply rights for sandbox"); 669 #endif 670 671 uart_stdio = true; 672 673 return (0); 674 } 675 676 static int 677 uart_tty_backend(struct uart_softc *sc, const char *path) 678 { 679 #ifndef WITHOUT_CAPSICUM 680 cap_rights_t rights; 681 cap_ioctl_t cmds[] = { TIOCGETA, TIOCSETA, TIOCGWINSZ }; 682 #endif 683 int fd; 684 685 fd = open(path, O_RDWR | O_NONBLOCK); 686 if (fd < 0) 687 return (-1); 688 689 if (!isatty(fd)) { 690 close(fd); 691 return (-1); 692 } 693 694 sc->tty.rfd = sc->tty.wfd = fd; 695 sc->tty.opened = true; 696 697 #ifndef WITHOUT_CAPSICUM 698 cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ, CAP_WRITE); 699 if (caph_rights_limit(fd, &rights) == -1) 700 errx(EX_OSERR, "Unable to apply rights for sandbox"); 701 if (caph_ioctls_limit(fd, cmds, nitems(cmds)) == -1) 702 errx(EX_OSERR, "Unable to apply rights for sandbox"); 703 #endif 704 705 return (0); 706 } 707 708 int 709 uart_set_backend(struct uart_softc *sc, const char *device) 710 { 711 int retval; 712 713 if (device == NULL) 714 return (0); 715 716 if (strcmp("stdio", device) == 0) 717 retval = uart_stdio_backend(sc); 718 else 719 retval = uart_tty_backend(sc, device); 720 if (retval == 0) 721 uart_opentty(sc); 722 723 return (retval); 724 } 725 726 #ifdef BHYVE_SNAPSHOT 727 int 728 uart_snapshot(struct uart_softc *sc, struct vm_snapshot_meta *meta) 729 { 730 int ret; 731 732 SNAPSHOT_VAR_OR_LEAVE(sc->data, meta, ret, done); 733 SNAPSHOT_VAR_OR_LEAVE(sc->ier, meta, ret, done); 734 SNAPSHOT_VAR_OR_LEAVE(sc->lcr, meta, ret, done); 735 SNAPSHOT_VAR_OR_LEAVE(sc->mcr, meta, ret, done); 736 SNAPSHOT_VAR_OR_LEAVE(sc->lsr, meta, ret, done); 737 SNAPSHOT_VAR_OR_LEAVE(sc->msr, meta, ret, done); 738 SNAPSHOT_VAR_OR_LEAVE(sc->fcr, meta, ret, done); 739 SNAPSHOT_VAR_OR_LEAVE(sc->scr, meta, ret, done); 740 741 SNAPSHOT_VAR_OR_LEAVE(sc->dll, meta, ret, done); 742 SNAPSHOT_VAR_OR_LEAVE(sc->dlh, meta, ret, done); 743 744 SNAPSHOT_VAR_OR_LEAVE(sc->rxfifo.rindex, meta, ret, done); 745 SNAPSHOT_VAR_OR_LEAVE(sc->rxfifo.windex, meta, ret, done); 746 SNAPSHOT_VAR_OR_LEAVE(sc->rxfifo.num, meta, ret, done); 747 SNAPSHOT_VAR_OR_LEAVE(sc->rxfifo.size, meta, ret, done); 748 SNAPSHOT_BUF_OR_LEAVE(sc->rxfifo.buf, sizeof(sc->rxfifo.buf), 749 meta, ret, done); 750 751 sc->thre_int_pending = 1; 752 753 done: 754 return (ret); 755 } 756 #endif 757