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 56*a428f72eSPekka Enberg #define SYSRQ_PENDING_NONE 0 57*a428f72eSPekka Enberg #define SYSRQ_PENDING_BREAK 1 58*a428f72eSPekka Enberg #define SYSRQ_PENDING_CMD 2 59*a428f72eSPekka Enberg 60*a428f72eSPekka Enberg static int sysrq_pending; 61*a428f72eSPekka Enberg 62*a428f72eSPekka Enberg static void serial8250__sysrq(struct kvm *self, struct serial8250_device *dev) 63*a428f72eSPekka Enberg { 64*a428f72eSPekka Enberg switch (sysrq_pending) { 65*a428f72eSPekka Enberg case SYSRQ_PENDING_BREAK: 66*a428f72eSPekka Enberg dev->lsr |= UART_LSR_DR | UART_LSR_BI; 67*a428f72eSPekka Enberg 68*a428f72eSPekka Enberg sysrq_pending = SYSRQ_PENDING_CMD; 69*a428f72eSPekka Enberg break; 70*a428f72eSPekka Enberg case SYSRQ_PENDING_CMD: 71*a428f72eSPekka Enberg dev->rbr = 'p'; 72*a428f72eSPekka Enberg dev->lsr |= UART_LSR_DR; 73*a428f72eSPekka Enberg 74*a428f72eSPekka Enberg sysrq_pending = SYSRQ_PENDING_NONE; 75*a428f72eSPekka Enberg break; 76*a428f72eSPekka Enberg } 77*a428f72eSPekka Enberg } 78*a428f72eSPekka 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 86*a428f72eSPekka Enberg if (sysrq_pending) { 87*a428f72eSPekka Enberg serial8250__sysrq(self, dev); 88*a428f72eSPekka Enberg return; 89*a428f72eSPekka Enberg } 90*a428f72eSPekka 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 125*a428f72eSPekka Enberg void serial8250__inject_sysrq(struct kvm *self) 126*a428f72eSPekka Enberg { 127*a428f72eSPekka Enberg sysrq_pending = SYSRQ_PENDING_BREAK; 128*a428f72eSPekka Enberg } 129*a428f72eSPekka 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; 187369c01c0SPekka Enberg if (!(dev->mcr & UART_MCR_LOOP)) { 18805d1a2a6SAsias He term_putc(CONSOLE_8250, addr, size * count); 189369c01c0SPekka Enberg } 190133bedc1SPekka Enberg dev->iir = UART_IIR_NO_INT; 19146aa8d69SPekka Enberg break; 19246aa8d69SPekka Enberg } 193369c01c0SPekka Enberg case UART_FCR: 194369c01c0SPekka Enberg dev->fcr = ioport__read8(data); 195369c01c0SPekka Enberg break; 1964e49b05bSCyrill Gorcunov case UART_IER: 197369c01c0SPekka Enberg dev->ier = ioport__read8(data) & 0x3f; 19846aa8d69SPekka Enberg break; 199369c01c0SPekka Enberg case UART_LCR: 200369c01c0SPekka Enberg dev->lcr = ioport__read8(data); 201369c01c0SPekka Enberg break; 202369c01c0SPekka Enberg case UART_MCR: 203369c01c0SPekka Enberg dev->mcr = ioport__read8(data); 204369c01c0SPekka Enberg break; 205369c01c0SPekka Enberg case UART_LSR: 206369c01c0SPekka Enberg /* Factory test */ 207369c01c0SPekka Enberg break; 208369c01c0SPekka Enberg case UART_MSR: 209369c01c0SPekka Enberg /* Not used */ 210369c01c0SPekka Enberg break; 211369c01c0SPekka Enberg case UART_SCR: 212369c01c0SPekka Enberg dev->scr = ioport__read8(data); 213369c01c0SPekka Enberg break; 214369c01c0SPekka Enberg default: 215369c01c0SPekka Enberg return false; 21646aa8d69SPekka Enberg } 21746aa8d69SPekka Enberg } 21813a7760fSPekka Enberg return true; 21913a7760fSPekka Enberg } 22013a7760fSPekka Enberg 22146aa8d69SPekka Enberg static bool serial8250_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 22225af6674SPekka Enberg { 223c6a69c61SPekka Enberg struct serial8250_device *dev; 224c6a69c61SPekka Enberg uint16_t offset; 22546aa8d69SPekka Enberg 226c6a69c61SPekka Enberg dev = find_device(port); 227c6a69c61SPekka Enberg if (!dev) 228c6a69c61SPekka Enberg return false; 229c6a69c61SPekka Enberg 230c6a69c61SPekka Enberg offset = port - dev->iobase; 231c6a69c61SPekka Enberg 23219a2bb7dSPekka Enberg if (dev->lcr & UART_LCR_DLAB) { 23319a2bb7dSPekka Enberg switch (offset) { 23419a2bb7dSPekka Enberg case UART_DLL: 23519a2bb7dSPekka Enberg ioport__write8(data, dev->dll); 23619a2bb7dSPekka Enberg return true; 23719a2bb7dSPekka Enberg case UART_DLM: 23819a2bb7dSPekka Enberg ioport__write8(data, dev->dlm); 23919a2bb7dSPekka Enberg return true; 240369c01c0SPekka Enberg default: 241369c01c0SPekka Enberg break; 24219a2bb7dSPekka Enberg } 24319a2bb7dSPekka Enberg } else { 24446aa8d69SPekka Enberg switch (offset) { 245251cf9a6SPekka Enberg case UART_RX: 246251cf9a6SPekka Enberg ioport__write8(data, dev->rbr); 247369c01c0SPekka Enberg dev->lsr &= ~UART_LSR_DR; 248369c01c0SPekka Enberg dev->iir = UART_IIR_NO_INT; 24919a2bb7dSPekka Enberg return true; 2504e49b05bSCyrill Gorcunov case UART_IER: 251c6a69c61SPekka Enberg ioport__write8(data, dev->ier); 25219a2bb7dSPekka Enberg return true; 253369c01c0SPekka Enberg default: 254369c01c0SPekka Enberg break; 25519a2bb7dSPekka Enberg } 25619a2bb7dSPekka Enberg } 25719a2bb7dSPekka Enberg 25819a2bb7dSPekka Enberg switch (offset) { 259369c01c0SPekka Enberg case UART_IIR: { 260369c01c0SPekka Enberg uint8_t iir = dev->iir; 261369c01c0SPekka Enberg 262369c01c0SPekka Enberg if (dev->fcr & UART_FCR_ENABLE_FIFO) 263369c01c0SPekka Enberg iir |= 0xc0; 264369c01c0SPekka Enberg 265369c01c0SPekka Enberg ioport__write8(data, iir); 26646aa8d69SPekka Enberg break; 267369c01c0SPekka Enberg } 2684e49b05bSCyrill Gorcunov case UART_LCR: 269c6a69c61SPekka Enberg ioport__write8(data, dev->lcr); 27046aa8d69SPekka Enberg break; 2714e49b05bSCyrill Gorcunov case UART_MCR: 272c6a69c61SPekka Enberg ioport__write8(data, dev->mcr); 27346aa8d69SPekka Enberg break; 2744e49b05bSCyrill Gorcunov case UART_LSR: 275c6a69c61SPekka Enberg ioport__write8(data, dev->lsr); 276369c01c0SPekka Enberg dev->lsr &= ~(UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_BI); 27746aa8d69SPekka Enberg break; 2784e49b05bSCyrill Gorcunov case UART_MSR: 279369c01c0SPekka Enberg ioport__write8(data, dev->msr); 28046aa8d69SPekka Enberg break; 2814e49b05bSCyrill Gorcunov case UART_SCR: 282369c01c0SPekka Enberg ioport__write8(data, dev->scr); 28346aa8d69SPekka Enberg break; 284369c01c0SPekka Enberg default: 285369c01c0SPekka Enberg return false; 28625af6674SPekka Enberg } 28713a7760fSPekka Enberg return true; 28813a7760fSPekka Enberg } 28913a7760fSPekka Enberg 29046aa8d69SPekka Enberg static struct ioport_operations serial8250_ops = { 29146aa8d69SPekka Enberg .io_in = serial8250_in, 29246aa8d69SPekka Enberg .io_out = serial8250_out, 293a93ec68bSPekka Enberg }; 294a93ec68bSPekka Enberg 295bc4b0ffeSPekka Enberg static void serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev) 296bc4b0ffeSPekka Enberg { 297bc4b0ffeSPekka Enberg ioport__register(dev->iobase, &serial8250_ops, 8); 298bc4b0ffeSPekka Enberg kvm__irq_line(kvm, dev->irq, 0); 299bc4b0ffeSPekka Enberg } 300bc4b0ffeSPekka Enberg 301bc4b0ffeSPekka Enberg void serial8250__init(struct kvm *kvm) 30213a7760fSPekka Enberg { 303c6a69c61SPekka Enberg unsigned int i; 304c6a69c61SPekka Enberg 305c6a69c61SPekka Enberg for (i = 0; i < ARRAY_SIZE(devices); i++) { 306c6a69c61SPekka Enberg struct serial8250_device *dev = &devices[i]; 307c6a69c61SPekka Enberg 308bc4b0ffeSPekka Enberg serial8250__device_init(kvm, dev); 309c6a69c61SPekka Enberg } 31013a7760fSPekka Enberg } 311