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; 2546aa8d69SPekka Enberg uint8_t scr; 26133bedc1SPekka Enberg 27133bedc1SPekka Enberg uint8_t counter; 2846aa8d69SPekka Enberg }; 2946aa8d69SPekka Enberg 30e62c18deSPekka Enberg static struct serial8250_device devices[] = { 31c6a69c61SPekka Enberg /* ttyS0 */ 32c6a69c61SPekka Enberg [0] = { 33c6a69c61SPekka Enberg .iobase = 0x3f8, 34e557eef9SPekka Enberg .irq = 4, 35e557eef9SPekka Enberg 366d620acbSCyrill Gorcunov .lsr = UART_LSR_TEMT | UART_LSR_THRE, 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 (dev->lsr & UART_LSR_DR) 79251cf9a6SPekka Enberg return; 80251cf9a6SPekka Enberg 81251cf9a6SPekka Enberg if (!is_readable(fileno(stdin))) 82251cf9a6SPekka Enberg return; 83251cf9a6SPekka Enberg 84251cf9a6SPekka Enberg c = read_char(fileno(stdin)); 85251cf9a6SPekka Enberg if (c < 0) 86251cf9a6SPekka Enberg return; 87251cf9a6SPekka 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 uint8_t new_iir; 99934c193bSPekka Enberg 100c6a69c61SPekka Enberg dev->iir = UART_IIR_NO_INT; 101934c193bSPekka Enberg 102934c193bSPekka Enberg /* No interrupts enabled. Exit... */ 103c6a69c61SPekka Enberg if (!(dev->ier & (UART_IER_THRI|UART_IER_RDI))) 104934c193bSPekka Enberg return; 105934c193bSPekka Enberg 106251cf9a6SPekka Enberg serial8250__receive(self, dev); 107251cf9a6SPekka Enberg 108934c193bSPekka Enberg new_iir = 0; 109934c193bSPekka Enberg 110251cf9a6SPekka Enberg if (dev->lsr & UART_LSR_DR) 111934c193bSPekka Enberg new_iir |= UART_IIR_RDI; 112251cf9a6SPekka Enberg else if (dev->ier & UART_IER_THRI) 113251cf9a6SPekka Enberg new_iir |= UART_IIR_THRI; 11476b4a122SPekka Enberg 115934c193bSPekka Enberg /* Only send an IRQ if there's work to do. */ 116934c193bSPekka Enberg if (new_iir) { 1170bc4cf78SPekka Enberg dev->counter = 0; 118c6a69c61SPekka Enberg dev->iir = new_iir; 119c6a69c61SPekka Enberg kvm__irq_line(self, dev->irq, 0); 120c6a69c61SPekka Enberg kvm__irq_line(self, dev->irq, 1); 121e557eef9SPekka Enberg } 1228bb34e0dSPekka Enberg } 1238bb34e0dSPekka Enberg 124c6a69c61SPekka Enberg static struct serial8250_device *find_device(uint16_t port) 125c6a69c61SPekka Enberg { 126c6a69c61SPekka Enberg unsigned int i; 127c6a69c61SPekka Enberg 128c6a69c61SPekka Enberg for (i = 0; i < ARRAY_SIZE(devices); i++) { 129c6a69c61SPekka Enberg struct serial8250_device *dev = &devices[i]; 130c6a69c61SPekka Enberg 131c6a69c61SPekka Enberg if (dev->iobase == (port & ~0x7)) 132c6a69c61SPekka Enberg return dev; 133c6a69c61SPekka Enberg } 134c6a69c61SPekka Enberg return NULL; 135c6a69c61SPekka Enberg } 136c6a69c61SPekka Enberg 13746aa8d69SPekka Enberg static bool serial8250_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 13813a7760fSPekka Enberg { 139c6a69c61SPekka Enberg struct serial8250_device *dev; 140c6a69c61SPekka Enberg uint16_t offset; 14146aa8d69SPekka Enberg 142c6a69c61SPekka Enberg dev = find_device(port); 143c6a69c61SPekka Enberg if (!dev) 144c6a69c61SPekka Enberg return false; 145c6a69c61SPekka Enberg 146c6a69c61SPekka Enberg offset = port - dev->iobase; 147c6a69c61SPekka Enberg 148*19a2bb7dSPekka Enberg /* LSR is factory test and MSR is not used for writes */ 149*19a2bb7dSPekka Enberg if (offset == UART_LSR || offset == UART_MSR) 150*19a2bb7dSPekka Enberg return true; 151*19a2bb7dSPekka Enberg 152*19a2bb7dSPekka Enberg /* FCR, LCR, MCR, and SCR have the same meaning regardless of DLAB */ 153*19a2bb7dSPekka Enberg switch (offset) { 154*19a2bb7dSPekka Enberg case UART_FCR: 155*19a2bb7dSPekka Enberg dev->fcr = ioport__read8(data); 156*19a2bb7dSPekka Enberg return true; 157*19a2bb7dSPekka Enberg case UART_LCR: 158*19a2bb7dSPekka Enberg dev->lcr = ioport__read8(data); 159*19a2bb7dSPekka Enberg return true; 160*19a2bb7dSPekka Enberg case UART_MCR: 161*19a2bb7dSPekka Enberg dev->mcr = ioport__read8(data); 162*19a2bb7dSPekka Enberg return true; 163*19a2bb7dSPekka Enberg case UART_SCR: 164*19a2bb7dSPekka Enberg dev->scr = ioport__read8(data); 165*19a2bb7dSPekka Enberg return true; 166*19a2bb7dSPekka Enberg default: 167*19a2bb7dSPekka Enberg break; 168*19a2bb7dSPekka Enberg } 169*19a2bb7dSPekka Enberg 170c6a69c61SPekka Enberg if (dev->lcr & UART_LCR_DLAB) { 17146aa8d69SPekka Enberg switch (offset) { 1724e49b05bSCyrill Gorcunov case UART_DLL: 173c6a69c61SPekka Enberg dev->dll = ioport__read8(data); 17446aa8d69SPekka Enberg break; 1754e49b05bSCyrill Gorcunov case UART_DLM: 176c6a69c61SPekka Enberg dev->dlm = ioport__read8(data); 17746aa8d69SPekka Enberg break; 17846aa8d69SPekka Enberg } 17946aa8d69SPekka Enberg } else { 18046aa8d69SPekka Enberg switch (offset) { 1814e49b05bSCyrill Gorcunov case UART_TX: { 18213a7760fSPekka Enberg char *p = data; 183f2d8dc88SCyrill Gorcunov int i; 18413a7760fSPekka Enberg 185f2d8dc88SCyrill Gorcunov while (count--) { 186f2d8dc88SCyrill Gorcunov for (i = 0; i < size; i++) 187b7475544SPekka Enberg fprintf(stdout, "%c", *p++); 1885b9d0b58SAsias He } 189b7475544SPekka Enberg fflush(stdout); 190e557eef9SPekka Enberg 1910bc4cf78SPekka Enberg if (dev->counter++ > 10) 192133bedc1SPekka Enberg dev->iir = UART_IIR_NO_INT; 193133bedc1SPekka Enberg 19446aa8d69SPekka Enberg break; 19546aa8d69SPekka Enberg } 1964e49b05bSCyrill Gorcunov case UART_IER: 197c6a69c61SPekka Enberg dev->ier = ioport__read8(data); 19846aa8d69SPekka Enberg break; 19946aa8d69SPekka Enberg } 20046aa8d69SPekka Enberg } 20113a7760fSPekka Enberg 20213a7760fSPekka Enberg return true; 20313a7760fSPekka Enberg } 20413a7760fSPekka Enberg 20546aa8d69SPekka Enberg static bool serial8250_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 20625af6674SPekka Enberg { 207c6a69c61SPekka Enberg struct serial8250_device *dev; 208c6a69c61SPekka Enberg uint16_t offset; 20946aa8d69SPekka Enberg 210c6a69c61SPekka Enberg dev = find_device(port); 211c6a69c61SPekka Enberg if (!dev) 212c6a69c61SPekka Enberg return false; 213c6a69c61SPekka Enberg 214c6a69c61SPekka Enberg offset = port - dev->iobase; 215c6a69c61SPekka Enberg 216*19a2bb7dSPekka Enberg /* DLAB only changes the meaning of the first two registers */ 217*19a2bb7dSPekka Enberg if (dev->lcr & UART_LCR_DLAB) { 218*19a2bb7dSPekka Enberg switch (offset) { 219*19a2bb7dSPekka Enberg case UART_DLL: 220*19a2bb7dSPekka Enberg ioport__write8(data, dev->dll); 221*19a2bb7dSPekka Enberg return true; 222*19a2bb7dSPekka Enberg case UART_DLM: 223*19a2bb7dSPekka Enberg ioport__write8(data, dev->dlm); 224*19a2bb7dSPekka Enberg return true; 225*19a2bb7dSPekka Enberg } 226*19a2bb7dSPekka Enberg } else { 22746aa8d69SPekka Enberg switch (offset) { 228251cf9a6SPekka Enberg case UART_RX: 229c6a69c61SPekka Enberg if (dev->lsr & UART_LSR_DR) { 230133bedc1SPekka Enberg dev->iir = UART_IIR_NO_INT; 231133bedc1SPekka Enberg 232c6a69c61SPekka Enberg dev->lsr &= ~UART_LSR_DR; 233251cf9a6SPekka Enberg ioport__write8(data, dev->rbr); 23476b4a122SPekka Enberg } 235*19a2bb7dSPekka Enberg return true; 2364e49b05bSCyrill Gorcunov case UART_IER: 237c6a69c61SPekka Enberg ioport__write8(data, dev->ier); 238*19a2bb7dSPekka Enberg return true; 239*19a2bb7dSPekka Enberg } 240*19a2bb7dSPekka Enberg } 241*19a2bb7dSPekka Enberg 242*19a2bb7dSPekka Enberg /* All other registers have the same meaning regardless of DLAB */ 243*19a2bb7dSPekka Enberg switch (offset) { 2444e49b05bSCyrill Gorcunov case UART_IIR: 245855a6371SCyrill Gorcunov dev->iir &= 0x3f; /* no FIFO for 8250 */ 246c6a69c61SPekka Enberg ioport__write8(data, dev->iir); 24746aa8d69SPekka Enberg break; 2484e49b05bSCyrill Gorcunov case UART_LCR: 249c6a69c61SPekka Enberg ioport__write8(data, dev->lcr); 25046aa8d69SPekka Enberg break; 2514e49b05bSCyrill Gorcunov case UART_MCR: 252c6a69c61SPekka Enberg ioport__write8(data, dev->mcr); 25346aa8d69SPekka Enberg break; 2544e49b05bSCyrill Gorcunov case UART_LSR: 255c6a69c61SPekka Enberg ioport__write8(data, dev->lsr); 25646aa8d69SPekka Enberg break; 2574e49b05bSCyrill Gorcunov case UART_MSR: 2589a7428ddSPekka Enberg ioport__write8(data, UART_MSR_CTS); 25946aa8d69SPekka Enberg break; 2604e49b05bSCyrill Gorcunov case UART_SCR: 261855a6371SCyrill Gorcunov /* No SCR for 8250 */ 262855a6371SCyrill Gorcunov ioport__write8(data, 0); 26346aa8d69SPekka Enberg break; 26425af6674SPekka Enberg } 26525af6674SPekka Enberg 26613a7760fSPekka Enberg return true; 26713a7760fSPekka Enberg } 26813a7760fSPekka Enberg 26946aa8d69SPekka Enberg static struct ioport_operations serial8250_ops = { 27046aa8d69SPekka Enberg .io_in = serial8250_in, 27146aa8d69SPekka Enberg .io_out = serial8250_out, 272a93ec68bSPekka Enberg }; 273a93ec68bSPekka Enberg 274899fe063SPekka Enberg void serial8250__init(void) 27513a7760fSPekka Enberg { 276c6a69c61SPekka Enberg unsigned int i; 277c6a69c61SPekka Enberg 278c6a69c61SPekka Enberg for (i = 0; i < ARRAY_SIZE(devices); i++) { 279c6a69c61SPekka Enberg struct serial8250_device *dev = &devices[i]; 280c6a69c61SPekka Enberg 281c6a69c61SPekka Enberg ioport__register(dev->iobase, &serial8250_ops, 8); 282c6a69c61SPekka Enberg } 28313a7760fSPekka Enberg } 284