1899fe063SPekka Enberg #include "kvm/8250-serial.h" 213a7760fSPekka Enberg 313a7760fSPekka Enberg #include "kvm/ioport.h" 446aa8d69SPekka Enberg #include "kvm/util.h" 5e557eef9SPekka Enberg #include "kvm/kvm.h" 613a7760fSPekka Enberg 74e49b05bSCyrill Gorcunov #include <linux/serial_reg.h> 84e49b05bSCyrill Gorcunov 946aa8d69SPekka Enberg #include <stdbool.h> 1076b4a122SPekka Enberg #include <poll.h> 1113a7760fSPekka Enberg 1246aa8d69SPekka Enberg struct serial8250_device { 1346aa8d69SPekka Enberg uint16_t iobase; 14e557eef9SPekka Enberg uint8_t irq; 1576b4a122SPekka Enberg 16251cf9a6SPekka Enberg uint8_t rbr; /* receive buffer */ 1746aa8d69SPekka Enberg uint8_t dll; 1846aa8d69SPekka Enberg uint8_t dlm; 19e557eef9SPekka Enberg uint8_t iir; 2046aa8d69SPekka Enberg uint8_t ier; 2146aa8d69SPekka Enberg uint8_t fcr; 2246aa8d69SPekka Enberg uint8_t lcr; 2346aa8d69SPekka Enberg uint8_t mcr; 2476b4a122SPekka Enberg uint8_t lsr; 25*369c01c0SPekka Enberg uint8_t msr; 2646aa8d69SPekka Enberg uint8_t scr; 2746aa8d69SPekka Enberg }; 2846aa8d69SPekka Enberg 29e62c18deSPekka Enberg static struct serial8250_device devices[] = { 30c6a69c61SPekka Enberg /* ttyS0 */ 31c6a69c61SPekka Enberg [0] = { 32c6a69c61SPekka Enberg .iobase = 0x3f8, 33e557eef9SPekka Enberg .irq = 4, 34e557eef9SPekka Enberg 356d620acbSCyrill Gorcunov .lsr = UART_LSR_TEMT | UART_LSR_THRE, 36*369c01c0SPekka Enberg .iir = UART_IIR_NO_INT, 37c6a69c61SPekka Enberg }, 38e62c18deSPekka Enberg /* ttyS1 */ 39e62c18deSPekka Enberg [1] = { 40e62c18deSPekka Enberg .iobase = 0x2f8, 41e62c18deSPekka Enberg .irq = 3, 42133bedc1SPekka Enberg 43133bedc1SPekka Enberg .iir = UART_IIR_NO_INT, 44e62c18deSPekka Enberg }, 45e62c18deSPekka Enberg /* ttyS2 */ 46e62c18deSPekka Enberg [2] = { 47e62c18deSPekka Enberg .iobase = 0x3e8, 48e62c18deSPekka Enberg .irq = 4, 49133bedc1SPekka Enberg 50133bedc1SPekka Enberg .iir = UART_IIR_NO_INT, 51e62c18deSPekka Enberg }, 5246aa8d69SPekka Enberg }; 5346aa8d69SPekka Enberg 5476b4a122SPekka Enberg static int read_char(int fd) 5576b4a122SPekka Enberg { 5676b4a122SPekka Enberg int c; 5776b4a122SPekka Enberg 5876b4a122SPekka Enberg if (read(fd, &c, 1) < 0) 5976b4a122SPekka Enberg return -1; 6076b4a122SPekka Enberg 6176b4a122SPekka Enberg return c; 6276b4a122SPekka Enberg } 6376b4a122SPekka Enberg 6476b4a122SPekka Enberg static bool is_readable(int fd) 6576b4a122SPekka Enberg { 666d54df74SCyrill Gorcunov struct pollfd pollfd = (struct pollfd) { 6776b4a122SPekka Enberg .fd = fd, 6876b4a122SPekka Enberg .events = POLLIN, 6976b4a122SPekka Enberg }; 7076b4a122SPekka Enberg 716d54df74SCyrill Gorcunov return poll(&pollfd, 1, 0) > 0; 7276b4a122SPekka Enberg } 7376b4a122SPekka Enberg 74251cf9a6SPekka Enberg static void serial8250__receive(struct kvm *self, struct serial8250_device *dev) 75251cf9a6SPekka Enberg { 76251cf9a6SPekka Enberg int c; 77251cf9a6SPekka Enberg 78251cf9a6SPekka Enberg if (!is_readable(fileno(stdin))) 79251cf9a6SPekka Enberg return; 80251cf9a6SPekka Enberg 81251cf9a6SPekka Enberg c = read_char(fileno(stdin)); 82251cf9a6SPekka Enberg if (c < 0) 83251cf9a6SPekka Enberg return; 84251cf9a6SPekka Enberg 85*369c01c0SPekka Enberg if (dev->lsr & UART_LSR_DR) 86*369c01c0SPekka Enberg dev->lsr |= UART_LSR_OE; 87*369c01c0SPekka Enberg 88251cf9a6SPekka Enberg dev->rbr = c; 89251cf9a6SPekka Enberg dev->lsr |= UART_LSR_DR; 90251cf9a6SPekka Enberg } 91251cf9a6SPekka Enberg 92c6a69c61SPekka Enberg /* 93c6a69c61SPekka Enberg * Interrupts are injected for ttyS0 only. 94c6a69c61SPekka Enberg */ 958bb34e0dSPekka Enberg void serial8250__interrupt(struct kvm *self) 968bb34e0dSPekka Enberg { 97c6a69c61SPekka Enberg struct serial8250_device *dev = &devices[0]; 98934c193bSPekka Enberg 99251cf9a6SPekka Enberg serial8250__receive(self, dev); 100251cf9a6SPekka Enberg 101*369c01c0SPekka Enberg if (dev->ier & UART_IER_RDI && dev->lsr & UART_LSR_DR) 102*369c01c0SPekka Enberg dev->iir = UART_IIR_RDI; 103251cf9a6SPekka Enberg else if (dev->ier & UART_IER_THRI) 104*369c01c0SPekka Enberg dev->iir = UART_IIR_THRI; 105*369c01c0SPekka Enberg else 106*369c01c0SPekka Enberg dev->iir = UART_IIR_NO_INT; 10776b4a122SPekka Enberg 108*369c01c0SPekka Enberg if (dev->iir != UART_IIR_NO_INT) { 109c6a69c61SPekka Enberg kvm__irq_line(self, dev->irq, 0); 110c6a69c61SPekka Enberg kvm__irq_line(self, dev->irq, 1); 111e557eef9SPekka Enberg } 1128bb34e0dSPekka Enberg } 1138bb34e0dSPekka Enberg 114c6a69c61SPekka Enberg static struct serial8250_device *find_device(uint16_t port) 115c6a69c61SPekka Enberg { 116c6a69c61SPekka Enberg unsigned int i; 117c6a69c61SPekka Enberg 118c6a69c61SPekka Enberg for (i = 0; i < ARRAY_SIZE(devices); i++) { 119c6a69c61SPekka Enberg struct serial8250_device *dev = &devices[i]; 120c6a69c61SPekka Enberg 121c6a69c61SPekka Enberg if (dev->iobase == (port & ~0x7)) 122c6a69c61SPekka Enberg return dev; 123c6a69c61SPekka Enberg } 124c6a69c61SPekka Enberg return NULL; 125c6a69c61SPekka Enberg } 126c6a69c61SPekka Enberg 12746aa8d69SPekka Enberg static bool serial8250_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 12813a7760fSPekka Enberg { 129c6a69c61SPekka Enberg struct serial8250_device *dev; 130c6a69c61SPekka Enberg uint16_t offset; 13146aa8d69SPekka Enberg 132c6a69c61SPekka Enberg dev = find_device(port); 133c6a69c61SPekka Enberg if (!dev) 134c6a69c61SPekka Enberg return false; 135c6a69c61SPekka Enberg 136c6a69c61SPekka Enberg offset = port - dev->iobase; 137c6a69c61SPekka Enberg 138c6a69c61SPekka Enberg if (dev->lcr & UART_LCR_DLAB) { 13946aa8d69SPekka Enberg switch (offset) { 1404e49b05bSCyrill Gorcunov case UART_DLL: 141c6a69c61SPekka Enberg dev->dll = ioport__read8(data); 14246aa8d69SPekka Enberg break; 1434e49b05bSCyrill Gorcunov case UART_DLM: 144c6a69c61SPekka Enberg dev->dlm = ioport__read8(data); 14546aa8d69SPekka Enberg break; 146*369c01c0SPekka Enberg case UART_FCR: 147*369c01c0SPekka Enberg dev->fcr = ioport__read8(data); 148*369c01c0SPekka Enberg break; 149*369c01c0SPekka Enberg case UART_LCR: 150*369c01c0SPekka Enberg dev->lcr = ioport__read8(data); 151*369c01c0SPekka Enberg break; 152*369c01c0SPekka Enberg case UART_MCR: 153*369c01c0SPekka Enberg dev->mcr = ioport__read8(data); 154*369c01c0SPekka Enberg break; 155*369c01c0SPekka Enberg case UART_LSR: 156*369c01c0SPekka Enberg /* Factory test */ 157*369c01c0SPekka Enberg break; 158*369c01c0SPekka Enberg case UART_MSR: 159*369c01c0SPekka Enberg /* Not used */ 160*369c01c0SPekka Enberg break; 161*369c01c0SPekka Enberg case UART_SCR: 162*369c01c0SPekka Enberg dev->scr = ioport__read8(data); 163*369c01c0SPekka Enberg break; 164*369c01c0SPekka Enberg default: 165*369c01c0SPekka Enberg return false; 16646aa8d69SPekka Enberg } 16746aa8d69SPekka Enberg } else { 16846aa8d69SPekka Enberg switch (offset) { 1694e49b05bSCyrill Gorcunov case UART_TX: { 17013a7760fSPekka Enberg char *p = data; 171f2d8dc88SCyrill Gorcunov int i; 17213a7760fSPekka Enberg 173*369c01c0SPekka Enberg if (!(dev->mcr & UART_MCR_LOOP)) { 174f2d8dc88SCyrill Gorcunov while (count--) { 175f2d8dc88SCyrill Gorcunov for (i = 0; i < size; i++) 176b7475544SPekka Enberg fprintf(stdout, "%c", *p++); 1775b9d0b58SAsias He } 178b7475544SPekka Enberg fflush(stdout); 179*369c01c0SPekka Enberg } 180133bedc1SPekka Enberg dev->iir = UART_IIR_NO_INT; 18146aa8d69SPekka Enberg break; 18246aa8d69SPekka Enberg } 183*369c01c0SPekka Enberg case UART_FCR: 184*369c01c0SPekka Enberg dev->fcr = ioport__read8(data); 185*369c01c0SPekka Enberg break; 1864e49b05bSCyrill Gorcunov case UART_IER: 187*369c01c0SPekka Enberg dev->ier = ioport__read8(data) & 0x3f; 18846aa8d69SPekka Enberg break; 189*369c01c0SPekka Enberg case UART_LCR: 190*369c01c0SPekka Enberg dev->lcr = ioport__read8(data); 191*369c01c0SPekka Enberg break; 192*369c01c0SPekka Enberg case UART_MCR: 193*369c01c0SPekka Enberg dev->mcr = ioport__read8(data); 194*369c01c0SPekka Enberg break; 195*369c01c0SPekka Enberg case UART_LSR: 196*369c01c0SPekka Enberg /* Factory test */ 197*369c01c0SPekka Enberg break; 198*369c01c0SPekka Enberg case UART_MSR: 199*369c01c0SPekka Enberg /* Not used */ 200*369c01c0SPekka Enberg break; 201*369c01c0SPekka Enberg case UART_SCR: 202*369c01c0SPekka Enberg dev->scr = ioport__read8(data); 203*369c01c0SPekka Enberg break; 204*369c01c0SPekka Enberg default: 205*369c01c0SPekka Enberg return false; 20646aa8d69SPekka Enberg } 20746aa8d69SPekka Enberg } 20813a7760fSPekka Enberg return true; 20913a7760fSPekka Enberg } 21013a7760fSPekka Enberg 21146aa8d69SPekka Enberg static bool serial8250_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 21225af6674SPekka Enberg { 213c6a69c61SPekka Enberg struct serial8250_device *dev; 214c6a69c61SPekka Enberg uint16_t offset; 21546aa8d69SPekka Enberg 216c6a69c61SPekka Enberg dev = find_device(port); 217c6a69c61SPekka Enberg if (!dev) 218c6a69c61SPekka Enberg return false; 219c6a69c61SPekka Enberg 220c6a69c61SPekka Enberg offset = port - dev->iobase; 221c6a69c61SPekka Enberg 22219a2bb7dSPekka Enberg if (dev->lcr & UART_LCR_DLAB) { 22319a2bb7dSPekka Enberg switch (offset) { 22419a2bb7dSPekka Enberg case UART_DLL: 22519a2bb7dSPekka Enberg ioport__write8(data, dev->dll); 22619a2bb7dSPekka Enberg return true; 22719a2bb7dSPekka Enberg case UART_DLM: 22819a2bb7dSPekka Enberg ioport__write8(data, dev->dlm); 22919a2bb7dSPekka Enberg return true; 230*369c01c0SPekka Enberg default: 231*369c01c0SPekka Enberg break; 23219a2bb7dSPekka Enberg } 23319a2bb7dSPekka Enberg } else { 23446aa8d69SPekka Enberg switch (offset) { 235251cf9a6SPekka Enberg case UART_RX: 236251cf9a6SPekka Enberg ioport__write8(data, dev->rbr); 237*369c01c0SPekka Enberg dev->lsr &= ~UART_LSR_DR; 238*369c01c0SPekka Enberg dev->iir = UART_IIR_NO_INT; 23919a2bb7dSPekka Enberg return true; 2404e49b05bSCyrill Gorcunov case UART_IER: 241c6a69c61SPekka Enberg ioport__write8(data, dev->ier); 24219a2bb7dSPekka Enberg return true; 243*369c01c0SPekka Enberg default: 244*369c01c0SPekka Enberg break; 24519a2bb7dSPekka Enberg } 24619a2bb7dSPekka Enberg } 24719a2bb7dSPekka Enberg 24819a2bb7dSPekka Enberg switch (offset) { 249*369c01c0SPekka Enberg case UART_IIR: { 250*369c01c0SPekka Enberg uint8_t iir = dev->iir; 251*369c01c0SPekka Enberg 252*369c01c0SPekka Enberg if (dev->fcr & UART_FCR_ENABLE_FIFO) 253*369c01c0SPekka Enberg iir |= 0xc0; 254*369c01c0SPekka Enberg 255*369c01c0SPekka Enberg ioport__write8(data, iir); 25646aa8d69SPekka Enberg break; 257*369c01c0SPekka Enberg } 2584e49b05bSCyrill Gorcunov case UART_LCR: 259c6a69c61SPekka Enberg ioport__write8(data, dev->lcr); 26046aa8d69SPekka Enberg break; 2614e49b05bSCyrill Gorcunov case UART_MCR: 262c6a69c61SPekka Enberg ioport__write8(data, dev->mcr); 26346aa8d69SPekka Enberg break; 2644e49b05bSCyrill Gorcunov case UART_LSR: 265c6a69c61SPekka Enberg ioport__write8(data, dev->lsr); 266*369c01c0SPekka Enberg dev->lsr &= ~(UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_BI); 26746aa8d69SPekka Enberg break; 2684e49b05bSCyrill Gorcunov case UART_MSR: 269*369c01c0SPekka Enberg ioport__write8(data, dev->msr); 27046aa8d69SPekka Enberg break; 2714e49b05bSCyrill Gorcunov case UART_SCR: 272*369c01c0SPekka Enberg ioport__write8(data, dev->scr); 27346aa8d69SPekka Enberg break; 274*369c01c0SPekka Enberg default: 275*369c01c0SPekka Enberg return false; 27625af6674SPekka Enberg } 27713a7760fSPekka Enberg return true; 27813a7760fSPekka Enberg } 27913a7760fSPekka Enberg 28046aa8d69SPekka Enberg static struct ioport_operations serial8250_ops = { 28146aa8d69SPekka Enberg .io_in = serial8250_in, 28246aa8d69SPekka Enberg .io_out = serial8250_out, 283a93ec68bSPekka Enberg }; 284a93ec68bSPekka Enberg 285899fe063SPekka Enberg void serial8250__init(void) 28613a7760fSPekka Enberg { 287c6a69c61SPekka Enberg unsigned int i; 288c6a69c61SPekka Enberg 289c6a69c61SPekka Enberg for (i = 0; i < ARRAY_SIZE(devices); i++) { 290c6a69c61SPekka Enberg struct serial8250_device *dev = &devices[i]; 291c6a69c61SPekka Enberg 292c6a69c61SPekka Enberg ioport__register(dev->iobase, &serial8250_ops, 8); 293c6a69c61SPekka Enberg } 29413a7760fSPekka Enberg } 295