1899fe063SPekka Enberg #include "kvm/8250-serial.h" 213a7760fSPekka Enberg 38eb47d29SSasha Levin #include "kvm/read-write.h" 413a7760fSPekka Enberg #include "kvm/ioport.h" 546aa8d69SPekka Enberg #include "kvm/util.h" 605d1a2a6SAsias He #include "kvm/term.h" 7e557eef9SPekka Enberg #include "kvm/kvm.h" 813a7760fSPekka Enberg 94e49b05bSCyrill Gorcunov #include <linux/serial_reg.h> 104e49b05bSCyrill Gorcunov 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; 25369c01c0SPekka 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 35369c01c0SPekka Enberg .iir = UART_IIR_NO_INT, 36bc4b0ffeSPekka Enberg .lsr = UART_LSR_TEMT | UART_LSR_THRE, 37bc4b0ffeSPekka Enberg .msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS, 38bc4b0ffeSPekka Enberg .mcr = UART_MCR_OUT2, 39c6a69c61SPekka Enberg }, 40e62c18deSPekka Enberg /* ttyS1 */ 41e62c18deSPekka Enberg [1] = { 42e62c18deSPekka Enberg .iobase = 0x2f8, 43e62c18deSPekka Enberg .irq = 3, 44133bedc1SPekka Enberg 45133bedc1SPekka Enberg .iir = UART_IIR_NO_INT, 46e62c18deSPekka Enberg }, 47e62c18deSPekka Enberg /* ttyS2 */ 48e62c18deSPekka Enberg [2] = { 49e62c18deSPekka Enberg .iobase = 0x3e8, 50e62c18deSPekka Enberg .irq = 4, 51133bedc1SPekka Enberg 52133bedc1SPekka Enberg .iir = UART_IIR_NO_INT, 53e62c18deSPekka Enberg }, 5446aa8d69SPekka Enberg }; 5546aa8d69SPekka Enberg 56a428f72eSPekka Enberg #define SYSRQ_PENDING_NONE 0 57a428f72eSPekka Enberg #define SYSRQ_PENDING_BREAK 1 58a428f72eSPekka Enberg #define SYSRQ_PENDING_CMD 2 59a428f72eSPekka Enberg 60a428f72eSPekka Enberg static int sysrq_pending; 61a428f72eSPekka Enberg 62a428f72eSPekka Enberg static void serial8250__sysrq(struct kvm *self, struct serial8250_device *dev) 63a428f72eSPekka Enberg { 64a428f72eSPekka Enberg switch (sysrq_pending) { 65a428f72eSPekka Enberg case SYSRQ_PENDING_BREAK: 66a428f72eSPekka Enberg dev->lsr |= UART_LSR_DR | UART_LSR_BI; 67a428f72eSPekka Enberg 68a428f72eSPekka Enberg sysrq_pending = SYSRQ_PENDING_CMD; 69a428f72eSPekka Enberg break; 70a428f72eSPekka Enberg case SYSRQ_PENDING_CMD: 71a428f72eSPekka Enberg dev->rbr = 'p'; 72a428f72eSPekka Enberg dev->lsr |= UART_LSR_DR; 73a428f72eSPekka Enberg 74a428f72eSPekka Enberg sysrq_pending = SYSRQ_PENDING_NONE; 75a428f72eSPekka Enberg break; 76a428f72eSPekka Enberg } 77a428f72eSPekka Enberg } 78a428f72eSPekka Enberg 79251cf9a6SPekka Enberg static void serial8250__receive(struct kvm *self, struct serial8250_device *dev) 80251cf9a6SPekka Enberg { 81251cf9a6SPekka Enberg int c; 82251cf9a6SPekka Enberg 83db34045cSPekka Enberg if (dev->lsr & UART_LSR_DR) 84db34045cSPekka Enberg return; 85db34045cSPekka Enberg 86a428f72eSPekka Enberg if (sysrq_pending) { 87a428f72eSPekka Enberg serial8250__sysrq(self, dev); 88a428f72eSPekka Enberg return; 89a428f72eSPekka Enberg } 90a428f72eSPekka Enberg 9105d1a2a6SAsias He if (!term_readable(CONSOLE_8250)) 92251cf9a6SPekka Enberg return; 93251cf9a6SPekka Enberg 9405d1a2a6SAsias He c = term_getc(CONSOLE_8250); 9505d1a2a6SAsias He 96251cf9a6SPekka Enberg if (c < 0) 97251cf9a6SPekka Enberg return; 98251cf9a6SPekka Enberg 99251cf9a6SPekka Enberg dev->rbr = c; 100251cf9a6SPekka Enberg dev->lsr |= UART_LSR_DR; 101251cf9a6SPekka Enberg } 102251cf9a6SPekka Enberg 103c6a69c61SPekka Enberg /* 104c6a69c61SPekka Enberg * Interrupts are injected for ttyS0 only. 105c6a69c61SPekka Enberg */ 10605d1a2a6SAsias He void serial8250__inject_interrupt(struct kvm *self) 1078bb34e0dSPekka Enberg { 108c6a69c61SPekka Enberg struct serial8250_device *dev = &devices[0]; 109934c193bSPekka Enberg 110251cf9a6SPekka Enberg serial8250__receive(self, dev); 111251cf9a6SPekka Enberg 112369c01c0SPekka Enberg if (dev->ier & UART_IER_RDI && dev->lsr & UART_LSR_DR) 113369c01c0SPekka Enberg dev->iir = UART_IIR_RDI; 114251cf9a6SPekka Enberg else if (dev->ier & UART_IER_THRI) 115369c01c0SPekka Enberg dev->iir = UART_IIR_THRI; 116369c01c0SPekka Enberg else 117369c01c0SPekka Enberg dev->iir = UART_IIR_NO_INT; 11876b4a122SPekka Enberg 119369c01c0SPekka Enberg if (dev->iir != UART_IIR_NO_INT) { 120c6a69c61SPekka Enberg kvm__irq_line(self, dev->irq, 0); 121c6a69c61SPekka Enberg kvm__irq_line(self, dev->irq, 1); 122e557eef9SPekka Enberg } 1238bb34e0dSPekka Enberg } 1248bb34e0dSPekka Enberg 125a428f72eSPekka Enberg void serial8250__inject_sysrq(struct kvm *self) 126a428f72eSPekka Enberg { 127a428f72eSPekka Enberg sysrq_pending = SYSRQ_PENDING_BREAK; 128a428f72eSPekka Enberg } 129a428f72eSPekka Enberg 130c6a69c61SPekka Enberg static struct serial8250_device *find_device(uint16_t port) 131c6a69c61SPekka Enberg { 132c6a69c61SPekka Enberg unsigned int i; 133c6a69c61SPekka Enberg 134c6a69c61SPekka Enberg for (i = 0; i < ARRAY_SIZE(devices); i++) { 135c6a69c61SPekka Enberg struct serial8250_device *dev = &devices[i]; 136c6a69c61SPekka Enberg 137c6a69c61SPekka Enberg if (dev->iobase == (port & ~0x7)) 138c6a69c61SPekka Enberg return dev; 139c6a69c61SPekka Enberg } 140c6a69c61SPekka Enberg return NULL; 141c6a69c61SPekka Enberg } 142c6a69c61SPekka Enberg 14346aa8d69SPekka Enberg static bool serial8250_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 14413a7760fSPekka Enberg { 145c6a69c61SPekka Enberg struct serial8250_device *dev; 146c6a69c61SPekka Enberg uint16_t offset; 14746aa8d69SPekka Enberg 148c6a69c61SPekka Enberg dev = find_device(port); 149c6a69c61SPekka Enberg if (!dev) 150c6a69c61SPekka Enberg return false; 151c6a69c61SPekka Enberg 152c6a69c61SPekka Enberg offset = port - dev->iobase; 153c6a69c61SPekka Enberg 154c6a69c61SPekka Enberg if (dev->lcr & UART_LCR_DLAB) { 15546aa8d69SPekka Enberg switch (offset) { 1564e49b05bSCyrill Gorcunov case UART_DLL: 157c6a69c61SPekka Enberg dev->dll = ioport__read8(data); 15846aa8d69SPekka Enberg break; 1594e49b05bSCyrill Gorcunov case UART_DLM: 160c6a69c61SPekka Enberg dev->dlm = ioport__read8(data); 16146aa8d69SPekka Enberg break; 162369c01c0SPekka Enberg case UART_FCR: 163369c01c0SPekka Enberg dev->fcr = ioport__read8(data); 164369c01c0SPekka Enberg break; 165369c01c0SPekka Enberg case UART_LCR: 166369c01c0SPekka Enberg dev->lcr = ioport__read8(data); 167369c01c0SPekka Enberg break; 168369c01c0SPekka Enberg case UART_MCR: 169369c01c0SPekka Enberg dev->mcr = ioport__read8(data); 170369c01c0SPekka Enberg break; 171369c01c0SPekka Enberg case UART_LSR: 172369c01c0SPekka Enberg /* Factory test */ 173369c01c0SPekka Enberg break; 174369c01c0SPekka Enberg case UART_MSR: 175369c01c0SPekka Enberg /* Not used */ 176369c01c0SPekka Enberg break; 177369c01c0SPekka Enberg case UART_SCR: 178369c01c0SPekka Enberg dev->scr = ioport__read8(data); 179369c01c0SPekka Enberg break; 180369c01c0SPekka Enberg default: 181369c01c0SPekka Enberg return false; 18246aa8d69SPekka Enberg } 18346aa8d69SPekka Enberg } else { 18446aa8d69SPekka Enberg switch (offset) { 1854e49b05bSCyrill Gorcunov case UART_TX: { 18605d1a2a6SAsias He char *addr = data; 187*0ea58e5bSPekka Enberg 188*0ea58e5bSPekka Enberg if (!(dev->mcr & UART_MCR_LOOP)) 18905d1a2a6SAsias He term_putc(CONSOLE_8250, addr, size * count); 190*0ea58e5bSPekka Enberg 191133bedc1SPekka Enberg dev->iir = UART_IIR_NO_INT; 19246aa8d69SPekka Enberg break; 19346aa8d69SPekka Enberg } 194369c01c0SPekka Enberg case UART_FCR: 195369c01c0SPekka Enberg dev->fcr = ioport__read8(data); 196369c01c0SPekka Enberg break; 1974e49b05bSCyrill Gorcunov case UART_IER: 198369c01c0SPekka Enberg dev->ier = ioport__read8(data) & 0x3f; 19946aa8d69SPekka Enberg break; 200369c01c0SPekka Enberg case UART_LCR: 201369c01c0SPekka Enberg dev->lcr = ioport__read8(data); 202369c01c0SPekka Enberg break; 203369c01c0SPekka Enberg case UART_MCR: 204369c01c0SPekka Enberg dev->mcr = ioport__read8(data); 205369c01c0SPekka Enberg break; 206369c01c0SPekka Enberg case UART_LSR: 207369c01c0SPekka Enberg /* Factory test */ 208369c01c0SPekka Enberg break; 209369c01c0SPekka Enberg case UART_MSR: 210369c01c0SPekka Enberg /* Not used */ 211369c01c0SPekka Enberg break; 212369c01c0SPekka Enberg case UART_SCR: 213369c01c0SPekka Enberg dev->scr = ioport__read8(data); 214369c01c0SPekka Enberg break; 215369c01c0SPekka Enberg default: 216369c01c0SPekka Enberg return false; 21746aa8d69SPekka Enberg } 21846aa8d69SPekka Enberg } 21913a7760fSPekka Enberg return true; 22013a7760fSPekka Enberg } 22113a7760fSPekka Enberg 22246aa8d69SPekka Enberg static bool serial8250_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 22325af6674SPekka Enberg { 224c6a69c61SPekka Enberg struct serial8250_device *dev; 225c6a69c61SPekka Enberg uint16_t offset; 22646aa8d69SPekka Enberg 227c6a69c61SPekka Enberg dev = find_device(port); 228c6a69c61SPekka Enberg if (!dev) 229c6a69c61SPekka Enberg return false; 230c6a69c61SPekka Enberg 231c6a69c61SPekka Enberg offset = port - dev->iobase; 232c6a69c61SPekka Enberg 23319a2bb7dSPekka Enberg if (dev->lcr & UART_LCR_DLAB) { 23419a2bb7dSPekka Enberg switch (offset) { 23519a2bb7dSPekka Enberg case UART_DLL: 23619a2bb7dSPekka Enberg ioport__write8(data, dev->dll); 23719a2bb7dSPekka Enberg return true; 23819a2bb7dSPekka Enberg case UART_DLM: 23919a2bb7dSPekka Enberg ioport__write8(data, dev->dlm); 24019a2bb7dSPekka Enberg return true; 241369c01c0SPekka Enberg default: 242369c01c0SPekka Enberg break; 24319a2bb7dSPekka Enberg } 24419a2bb7dSPekka Enberg } else { 24546aa8d69SPekka Enberg switch (offset) { 246251cf9a6SPekka Enberg case UART_RX: 247251cf9a6SPekka Enberg ioport__write8(data, dev->rbr); 248369c01c0SPekka Enberg dev->lsr &= ~UART_LSR_DR; 249369c01c0SPekka Enberg dev->iir = UART_IIR_NO_INT; 25019a2bb7dSPekka Enberg return true; 2514e49b05bSCyrill Gorcunov case UART_IER: 252c6a69c61SPekka Enberg ioport__write8(data, dev->ier); 25319a2bb7dSPekka Enberg return true; 254369c01c0SPekka Enberg default: 255369c01c0SPekka Enberg break; 25619a2bb7dSPekka Enberg } 25719a2bb7dSPekka Enberg } 25819a2bb7dSPekka Enberg 25919a2bb7dSPekka Enberg switch (offset) { 260369c01c0SPekka Enberg case UART_IIR: { 261369c01c0SPekka Enberg uint8_t iir = dev->iir; 262369c01c0SPekka Enberg 263369c01c0SPekka Enberg if (dev->fcr & UART_FCR_ENABLE_FIFO) 264369c01c0SPekka Enberg iir |= 0xc0; 265369c01c0SPekka Enberg 266369c01c0SPekka Enberg ioport__write8(data, iir); 26746aa8d69SPekka Enberg break; 268369c01c0SPekka Enberg } 2694e49b05bSCyrill Gorcunov case UART_LCR: 270c6a69c61SPekka Enberg ioport__write8(data, dev->lcr); 27146aa8d69SPekka Enberg break; 2724e49b05bSCyrill Gorcunov case UART_MCR: 273c6a69c61SPekka Enberg ioport__write8(data, dev->mcr); 27446aa8d69SPekka Enberg break; 2754e49b05bSCyrill Gorcunov case UART_LSR: 276c6a69c61SPekka Enberg ioport__write8(data, dev->lsr); 277369c01c0SPekka Enberg dev->lsr &= ~(UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_BI); 27846aa8d69SPekka Enberg break; 2794e49b05bSCyrill Gorcunov case UART_MSR: 280369c01c0SPekka Enberg ioport__write8(data, dev->msr); 28146aa8d69SPekka Enberg break; 2824e49b05bSCyrill Gorcunov case UART_SCR: 283369c01c0SPekka Enberg ioport__write8(data, dev->scr); 28446aa8d69SPekka Enberg break; 285369c01c0SPekka Enberg default: 286369c01c0SPekka Enberg return false; 28725af6674SPekka Enberg } 28813a7760fSPekka Enberg return true; 28913a7760fSPekka Enberg } 29013a7760fSPekka Enberg 29146aa8d69SPekka Enberg static struct ioport_operations serial8250_ops = { 29246aa8d69SPekka Enberg .io_in = serial8250_in, 29346aa8d69SPekka Enberg .io_out = serial8250_out, 294a93ec68bSPekka Enberg }; 295a93ec68bSPekka Enberg 296bc4b0ffeSPekka Enberg static void serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev) 297bc4b0ffeSPekka Enberg { 298bc4b0ffeSPekka Enberg ioport__register(dev->iobase, &serial8250_ops, 8); 299bc4b0ffeSPekka Enberg kvm__irq_line(kvm, dev->irq, 0); 300bc4b0ffeSPekka Enberg } 301bc4b0ffeSPekka Enberg 302bc4b0ffeSPekka Enberg void serial8250__init(struct kvm *kvm) 30313a7760fSPekka Enberg { 304c6a69c61SPekka Enberg unsigned int i; 305c6a69c61SPekka Enberg 306c6a69c61SPekka Enberg for (i = 0; i < ARRAY_SIZE(devices); i++) { 307c6a69c61SPekka Enberg struct serial8250_device *dev = &devices[i]; 308c6a69c61SPekka Enberg 309bc4b0ffeSPekka Enberg serial8250__device_init(kvm, dev); 310c6a69c61SPekka Enberg } 31113a7760fSPekka Enberg } 312