1 #include "kvm/8250-serial.h" 2 3 #include "kvm/ioport.h" 4 #include "kvm/util.h" 5 #include "kvm/kvm.h" 6 7 #include <linux/serial_reg.h> 8 9 #include <stdbool.h> 10 #include <poll.h> 11 12 struct serial8250_device { 13 uint16_t iobase; 14 uint8_t irq; 15 16 uint8_t thr; 17 uint8_t dll; 18 uint8_t dlm; 19 uint8_t iir; 20 uint8_t ier; 21 uint8_t fcr; 22 uint8_t lcr; 23 uint8_t mcr; 24 uint8_t lsr; 25 uint8_t scr; 26 27 uint8_t counter; 28 }; 29 30 static struct serial8250_device devices[] = { 31 /* ttyS0 */ 32 [0] = { 33 .iobase = 0x3f8, 34 .irq = 4, 35 36 .lsr = UART_LSR_TEMT | UART_LSR_THRE, 37 }, 38 /* ttyS1 */ 39 [1] = { 40 .iobase = 0x2f8, 41 .irq = 3, 42 43 .iir = UART_IIR_NO_INT, 44 }, 45 /* ttyS2 */ 46 [2] = { 47 .iobase = 0x3e8, 48 .irq = 4, 49 50 .iir = UART_IIR_NO_INT, 51 }, 52 }; 53 54 static int read_char(int fd) 55 { 56 int c; 57 58 if (read(fd, &c, 1) < 0) 59 return -1; 60 61 return c; 62 } 63 64 static bool is_readable(int fd) 65 { 66 struct pollfd pollfd = (struct pollfd) { 67 .fd = fd, 68 .events = POLLIN, 69 }; 70 71 return poll(&pollfd, 1, 0) > 0; 72 } 73 74 /* 75 * Interrupts are injected for ttyS0 only. 76 */ 77 void serial8250__interrupt(struct kvm *self) 78 { 79 struct serial8250_device *dev = &devices[0]; 80 uint8_t new_iir; 81 82 dev->iir = UART_IIR_NO_INT; 83 84 /* No interrupts enabled. Exit... */ 85 if (!(dev->ier & (UART_IER_THRI|UART_IER_RDI))) 86 return; 87 88 new_iir = 0; 89 90 /* We're always good for guest sending data. */ 91 if (dev->ier & UART_IER_THRI) 92 new_iir |= UART_IIR_THRI; 93 94 /* Is there input in stdin to send to the guest? */ 95 if (!(dev->lsr & UART_LSR_DR) && is_readable(fileno(stdin))) { 96 int c; 97 98 c = read_char(fileno(stdin)); 99 if (c >= 0) { 100 dev->thr = c; 101 dev->lsr |= UART_LSR_DR; 102 new_iir |= UART_IIR_RDI; 103 } 104 } 105 106 /* Only send an IRQ if there's work to do. */ 107 if (new_iir) { 108 dev->iir = new_iir; 109 kvm__irq_line(self, dev->irq, 0); 110 kvm__irq_line(self, dev->irq, 1); 111 } 112 } 113 114 static struct serial8250_device *find_device(uint16_t port) 115 { 116 unsigned int i; 117 118 for (i = 0; i < ARRAY_SIZE(devices); i++) { 119 struct serial8250_device *dev = &devices[i]; 120 121 if (dev->iobase == (port & ~0x7)) 122 return dev; 123 } 124 return NULL; 125 } 126 127 static bool serial8250_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 128 { 129 struct serial8250_device *dev; 130 uint16_t offset; 131 132 dev = find_device(port); 133 if (!dev) 134 return false; 135 136 offset = port - dev->iobase; 137 138 if (dev->lcr & UART_LCR_DLAB) { 139 switch (offset) { 140 case UART_DLL: 141 dev->dll = ioport__read8(data); 142 break; 143 case UART_DLM: 144 dev->dlm = ioport__read8(data); 145 break; 146 case UART_FCR: 147 dev->fcr = ioport__read8(data); 148 break; 149 case UART_LCR: 150 dev->lcr = ioport__read8(data); 151 break; 152 default: 153 return false; 154 } 155 } else { 156 switch (offset) { 157 case UART_TX: { 158 char *p = data; 159 int i; 160 161 while (count--) { 162 for (i = 0; i < size; i++) 163 fprintf(stdout, "%c", *p++); 164 } 165 fflush(stdout); 166 167 if (dev->counter++ > 10) { 168 dev->iir = UART_IIR_NO_INT; 169 dev->counter = 0; 170 } 171 172 break; 173 } 174 case UART_IER: 175 dev->ier = ioport__read8(data); 176 break; 177 case UART_FCR: 178 dev->fcr = ioport__read8(data); 179 break; 180 case UART_LCR: 181 dev->lcr = ioport__read8(data); 182 break; 183 case UART_MCR: 184 dev->mcr = ioport__read8(data); 185 break; 186 case UART_SCR: 187 dev->scr = ioport__read8(data); 188 break; 189 default: 190 return false; 191 } 192 } 193 194 return true; 195 } 196 197 static bool serial8250_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 198 { 199 struct serial8250_device *dev; 200 uint16_t offset; 201 202 dev = find_device(port); 203 if (!dev) 204 return false; 205 206 offset = port - dev->iobase; 207 208 if (dev->lcr & UART_LCR_DLAB) 209 return false; 210 211 switch (offset) { 212 case UART_TX: 213 if (dev->lsr & UART_LSR_DR) { 214 dev->iir = UART_IIR_NO_INT; 215 216 dev->lsr &= ~UART_LSR_DR; 217 ioport__write8(data, dev->thr); 218 } 219 break; 220 case UART_IER: 221 ioport__write8(data, dev->ier); 222 break; 223 case UART_IIR: 224 ioport__write8(data, dev->iir); 225 break; 226 case UART_LCR: 227 ioport__write8(data, dev->lcr); 228 break; 229 case UART_MCR: 230 ioport__write8(data, dev->mcr); 231 break; 232 case UART_LSR: 233 ioport__write8(data, dev->lsr); 234 break; 235 case UART_MSR: 236 ioport__write8(data, UART_MSR_CTS); 237 break; 238 case UART_SCR: 239 ioport__write8(data, dev->scr); 240 break; 241 default: 242 return false; 243 } 244 245 return true; 246 } 247 248 static struct ioport_operations serial8250_ops = { 249 .io_in = serial8250_in, 250 .io_out = serial8250_out, 251 }; 252 253 void serial8250__init(void) 254 { 255 unsigned int i; 256 257 for (i = 0; i < ARRAY_SIZE(devices); i++) { 258 struct serial8250_device *dev = &devices[i]; 259 260 ioport__register(dev->iobase, &serial8250_ops, 8); 261 } 262 } 263