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 1676b4a122SPekka Enberg uint8_t thr; 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; 2646aa8d69SPekka Enberg }; 2746aa8d69SPekka Enberg 28*c6a69c61SPekka Enberg static struct serial8250_device devices[1] = { 29*c6a69c61SPekka Enberg /* ttyS0 */ 30*c6a69c61SPekka Enberg [0] = { 31*c6a69c61SPekka Enberg .iobase = 0x3f8, 32e557eef9SPekka Enberg .irq = 4, 33e557eef9SPekka Enberg 346d620acbSCyrill Gorcunov .lsr = UART_LSR_TEMT | UART_LSR_THRE, 35*c6a69c61SPekka Enberg }, 3646aa8d69SPekka Enberg }; 3746aa8d69SPekka Enberg 3876b4a122SPekka Enberg static int read_char(int fd) 3976b4a122SPekka Enberg { 4076b4a122SPekka Enberg int c; 4176b4a122SPekka Enberg 4276b4a122SPekka Enberg if (read(fd, &c, 1) < 0) 4376b4a122SPekka Enberg return -1; 4476b4a122SPekka Enberg 4576b4a122SPekka Enberg return c; 4676b4a122SPekka Enberg } 4776b4a122SPekka Enberg 4876b4a122SPekka Enberg static bool is_readable(int fd) 4976b4a122SPekka Enberg { 506d54df74SCyrill Gorcunov struct pollfd pollfd = (struct pollfd) { 5176b4a122SPekka Enberg .fd = fd, 5276b4a122SPekka Enberg .events = POLLIN, 5376b4a122SPekka Enberg }; 5476b4a122SPekka Enberg 556d54df74SCyrill Gorcunov return poll(&pollfd, 1, 0) > 0; 5676b4a122SPekka Enberg } 5776b4a122SPekka Enberg 58*c6a69c61SPekka Enberg /* 59*c6a69c61SPekka Enberg * Interrupts are injected for ttyS0 only. 60*c6a69c61SPekka Enberg */ 618bb34e0dSPekka Enberg void serial8250__interrupt(struct kvm *self) 628bb34e0dSPekka Enberg { 63*c6a69c61SPekka Enberg struct serial8250_device *dev = &devices[0]; 64934c193bSPekka Enberg uint8_t new_iir; 65934c193bSPekka Enberg 66*c6a69c61SPekka Enberg dev->iir = UART_IIR_NO_INT; 67934c193bSPekka Enberg 68934c193bSPekka Enberg /* No interrupts enabled. Exit... */ 69*c6a69c61SPekka Enberg if (!(dev->ier & (UART_IER_THRI|UART_IER_RDI))) 70934c193bSPekka Enberg return; 71934c193bSPekka Enberg 72934c193bSPekka Enberg new_iir = 0; 73934c193bSPekka Enberg 74934c193bSPekka Enberg /* We're always good for guest sending data. */ 75*c6a69c61SPekka Enberg if (dev->ier & UART_IER_THRI) 76934c193bSPekka Enberg new_iir |= UART_IIR_THRI; 77934c193bSPekka Enberg 78934c193bSPekka Enberg /* Is there input in stdin to send to the guest? */ 79*c6a69c61SPekka Enberg if (!(dev->lsr & UART_LSR_DR) && is_readable(fileno(stdin))) { 8076b4a122SPekka Enberg int c; 8176b4a122SPekka Enberg 8276b4a122SPekka Enberg c = read_char(fileno(stdin)); 8376b4a122SPekka Enberg if (c >= 0) { 84*c6a69c61SPekka Enberg dev->thr = c; 85*c6a69c61SPekka Enberg dev->lsr |= UART_LSR_DR; 86934c193bSPekka Enberg new_iir |= UART_IIR_RDI; 8776b4a122SPekka Enberg } 8876b4a122SPekka Enberg } 8976b4a122SPekka Enberg 90934c193bSPekka Enberg /* Only send an IRQ if there's work to do. */ 91934c193bSPekka Enberg if (new_iir) { 92*c6a69c61SPekka Enberg dev->iir = new_iir; 93*c6a69c61SPekka Enberg kvm__irq_line(self, dev->irq, 0); 94*c6a69c61SPekka Enberg kvm__irq_line(self, dev->irq, 1); 95e557eef9SPekka Enberg } 968bb34e0dSPekka Enberg } 978bb34e0dSPekka Enberg 98*c6a69c61SPekka Enberg static struct serial8250_device *find_device(uint16_t port) 99*c6a69c61SPekka Enberg { 100*c6a69c61SPekka Enberg unsigned int i; 101*c6a69c61SPekka Enberg 102*c6a69c61SPekka Enberg for (i = 0; i < ARRAY_SIZE(devices); i++) { 103*c6a69c61SPekka Enberg struct serial8250_device *dev = &devices[i]; 104*c6a69c61SPekka Enberg 105*c6a69c61SPekka Enberg if (dev->iobase == (port & ~0x7)) 106*c6a69c61SPekka Enberg return dev; 107*c6a69c61SPekka Enberg } 108*c6a69c61SPekka Enberg return NULL; 109*c6a69c61SPekka Enberg } 110*c6a69c61SPekka Enberg 11146aa8d69SPekka Enberg static bool serial8250_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 11213a7760fSPekka Enberg { 113*c6a69c61SPekka Enberg struct serial8250_device *dev; 114*c6a69c61SPekka Enberg uint16_t offset; 11546aa8d69SPekka Enberg 116*c6a69c61SPekka Enberg dev = find_device(port); 117*c6a69c61SPekka Enberg if (!dev) 118*c6a69c61SPekka Enberg return false; 119*c6a69c61SPekka Enberg 120*c6a69c61SPekka Enberg offset = port - dev->iobase; 121*c6a69c61SPekka Enberg 122*c6a69c61SPekka Enberg if (dev->lcr & UART_LCR_DLAB) { 12346aa8d69SPekka Enberg switch (offset) { 1244e49b05bSCyrill Gorcunov case UART_DLL: 125*c6a69c61SPekka Enberg dev->dll = ioport__read8(data); 12646aa8d69SPekka Enberg break; 1274e49b05bSCyrill Gorcunov case UART_DLM: 128*c6a69c61SPekka Enberg dev->dlm = ioport__read8(data); 12946aa8d69SPekka Enberg break; 1304e49b05bSCyrill Gorcunov case UART_FCR: 131*c6a69c61SPekka Enberg dev->fcr = ioport__read8(data); 13246aa8d69SPekka Enberg break; 1334e49b05bSCyrill Gorcunov case UART_LCR: 134*c6a69c61SPekka Enberg dev->lcr = ioport__read8(data); 13546aa8d69SPekka Enberg break; 13646aa8d69SPekka Enberg default: 13746aa8d69SPekka Enberg return false; 13846aa8d69SPekka Enberg } 13946aa8d69SPekka Enberg } else { 14046aa8d69SPekka Enberg switch (offset) { 1414e49b05bSCyrill Gorcunov case UART_TX: { 14213a7760fSPekka Enberg char *p = data; 143f2d8dc88SCyrill Gorcunov int i; 14413a7760fSPekka Enberg 145f2d8dc88SCyrill Gorcunov while (count--) { 146f2d8dc88SCyrill Gorcunov for (i = 0; i < size; i++) 147b7475544SPekka Enberg fprintf(stdout, "%c", *p++); 1485b9d0b58SAsias He } 149b7475544SPekka Enberg fflush(stdout); 150e557eef9SPekka Enberg 15146aa8d69SPekka Enberg break; 15246aa8d69SPekka Enberg } 1534e49b05bSCyrill Gorcunov case UART_IER: 154*c6a69c61SPekka Enberg dev->ier = ioport__read8(data); 15546aa8d69SPekka Enberg break; 1564e49b05bSCyrill Gorcunov case UART_FCR: 157*c6a69c61SPekka Enberg dev->fcr = ioport__read8(data); 15846aa8d69SPekka Enberg break; 1594e49b05bSCyrill Gorcunov case UART_LCR: 160*c6a69c61SPekka Enberg dev->lcr = ioport__read8(data); 16146aa8d69SPekka Enberg break; 1624e49b05bSCyrill Gorcunov case UART_MCR: 163*c6a69c61SPekka Enberg dev->mcr = ioport__read8(data); 16446aa8d69SPekka Enberg break; 1654e49b05bSCyrill Gorcunov case UART_SCR: 166*c6a69c61SPekka Enberg dev->scr = ioport__read8(data); 16746aa8d69SPekka Enberg break; 16846aa8d69SPekka Enberg default: 16946aa8d69SPekka Enberg return false; 17046aa8d69SPekka Enberg } 17146aa8d69SPekka Enberg } 17213a7760fSPekka Enberg 17313a7760fSPekka Enberg return true; 17413a7760fSPekka Enberg } 17513a7760fSPekka Enberg 17646aa8d69SPekka Enberg static bool serial8250_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 17725af6674SPekka Enberg { 178*c6a69c61SPekka Enberg struct serial8250_device *dev; 179*c6a69c61SPekka Enberg uint16_t offset; 18046aa8d69SPekka Enberg 181*c6a69c61SPekka Enberg dev = find_device(port); 182*c6a69c61SPekka Enberg if (!dev) 183*c6a69c61SPekka Enberg return false; 184*c6a69c61SPekka Enberg 185*c6a69c61SPekka Enberg offset = port - dev->iobase; 186*c6a69c61SPekka Enberg 187*c6a69c61SPekka Enberg if (dev->lcr & UART_LCR_DLAB) 18846aa8d69SPekka Enberg return false; 18946aa8d69SPekka Enberg 19046aa8d69SPekka Enberg switch (offset) { 1914e49b05bSCyrill Gorcunov case UART_TX: 192*c6a69c61SPekka Enberg if (dev->lsr & UART_LSR_DR) { 193*c6a69c61SPekka Enberg dev->lsr &= ~UART_LSR_DR; 194*c6a69c61SPekka Enberg ioport__write8(data, dev->thr); 19576b4a122SPekka Enberg } 19646aa8d69SPekka Enberg break; 1974e49b05bSCyrill Gorcunov case UART_IER: 198*c6a69c61SPekka Enberg ioport__write8(data, dev->ier); 19946aa8d69SPekka Enberg break; 2004e49b05bSCyrill Gorcunov case UART_IIR: 201*c6a69c61SPekka Enberg ioport__write8(data, dev->iir); 20246aa8d69SPekka Enberg break; 2034e49b05bSCyrill Gorcunov case UART_LCR: 204*c6a69c61SPekka Enberg ioport__write8(data, dev->lcr); 20546aa8d69SPekka Enberg break; 2064e49b05bSCyrill Gorcunov case UART_MCR: 207*c6a69c61SPekka Enberg ioport__write8(data, dev->mcr); 20846aa8d69SPekka Enberg break; 2094e49b05bSCyrill Gorcunov case UART_LSR: 210*c6a69c61SPekka Enberg ioport__write8(data, dev->lsr); 21146aa8d69SPekka Enberg break; 2124e49b05bSCyrill Gorcunov case UART_MSR: 2139a7428ddSPekka Enberg ioport__write8(data, UART_MSR_CTS); 21446aa8d69SPekka Enberg break; 2154e49b05bSCyrill Gorcunov case UART_SCR: 216*c6a69c61SPekka Enberg ioport__write8(data, dev->scr); 21746aa8d69SPekka Enberg break; 21846aa8d69SPekka Enberg default: 21946aa8d69SPekka Enberg return false; 22025af6674SPekka Enberg } 22125af6674SPekka Enberg 22213a7760fSPekka Enberg return true; 22313a7760fSPekka Enberg } 22413a7760fSPekka Enberg 22546aa8d69SPekka Enberg static struct ioport_operations serial8250_ops = { 22646aa8d69SPekka Enberg .io_in = serial8250_in, 22746aa8d69SPekka Enberg .io_out = serial8250_out, 228a93ec68bSPekka Enberg }; 229a93ec68bSPekka Enberg 230899fe063SPekka Enberg void serial8250__init(void) 23113a7760fSPekka Enberg { 232*c6a69c61SPekka Enberg unsigned int i; 233*c6a69c61SPekka Enberg 234*c6a69c61SPekka Enberg for (i = 0; i < ARRAY_SIZE(devices); i++) { 235*c6a69c61SPekka Enberg struct serial8250_device *dev = &devices[i]; 236*c6a69c61SPekka Enberg 237*c6a69c61SPekka Enberg ioport__register(dev->iobase, &serial8250_ops, 8); 238*c6a69c61SPekka Enberg } 23913a7760fSPekka Enberg } 240