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 rbr; /* receive buffer */ 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 static void serial8250__receive(struct kvm *self, struct serial8250_device *dev) 75 { 76 int c; 77 78 if (dev->lsr & UART_LSR_DR) 79 return; 80 81 if (!is_readable(fileno(stdin))) 82 return; 83 84 c = read_char(fileno(stdin)); 85 if (c < 0) 86 return; 87 88 dev->rbr = c; 89 dev->lsr |= UART_LSR_DR; 90 } 91 92 /* 93 * Interrupts are injected for ttyS0 only. 94 */ 95 void serial8250__interrupt(struct kvm *self) 96 { 97 struct serial8250_device *dev = &devices[0]; 98 uint8_t new_iir; 99 100 dev->iir = UART_IIR_NO_INT; 101 102 /* No interrupts enabled. Exit... */ 103 if (!(dev->ier & (UART_IER_THRI|UART_IER_RDI))) 104 return; 105 106 serial8250__receive(self, dev); 107 108 new_iir = 0; 109 110 if (dev->lsr & UART_LSR_DR) 111 new_iir |= UART_IIR_RDI; 112 else if (dev->ier & UART_IER_THRI) 113 new_iir |= UART_IIR_THRI; 114 115 /* Only send an IRQ if there's work to do. */ 116 if (new_iir) { 117 dev->counter = 0; 118 dev->iir = new_iir; 119 kvm__irq_line(self, dev->irq, 0); 120 kvm__irq_line(self, dev->irq, 1); 121 } 122 } 123 124 static struct serial8250_device *find_device(uint16_t port) 125 { 126 unsigned int i; 127 128 for (i = 0; i < ARRAY_SIZE(devices); i++) { 129 struct serial8250_device *dev = &devices[i]; 130 131 if (dev->iobase == (port & ~0x7)) 132 return dev; 133 } 134 return NULL; 135 } 136 137 static bool serial8250_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 138 { 139 struct serial8250_device *dev; 140 uint16_t offset; 141 142 dev = find_device(port); 143 if (!dev) 144 return false; 145 146 offset = port - dev->iobase; 147 148 /* LSR is factory test and MSR is not used for writes */ 149 if (offset == UART_LSR || offset == UART_MSR) 150 return true; 151 152 /* FCR, LCR, MCR, and SCR have the same meaning regardless of DLAB */ 153 switch (offset) { 154 case UART_FCR: 155 dev->fcr = ioport__read8(data); 156 return true; 157 case UART_LCR: 158 dev->lcr = ioport__read8(data); 159 return true; 160 case UART_MCR: 161 dev->mcr = ioport__read8(data); 162 return true; 163 case UART_SCR: 164 dev->scr = ioport__read8(data); 165 return true; 166 default: 167 break; 168 } 169 170 if (dev->lcr & UART_LCR_DLAB) { 171 switch (offset) { 172 case UART_DLL: 173 dev->dll = ioport__read8(data); 174 break; 175 case UART_DLM: 176 dev->dlm = ioport__read8(data); 177 break; 178 } 179 } else { 180 switch (offset) { 181 case UART_TX: { 182 char *p = data; 183 int i; 184 185 while (count--) { 186 for (i = 0; i < size; i++) 187 fprintf(stdout, "%c", *p++); 188 } 189 fflush(stdout); 190 191 if (dev->counter++ > 10) 192 dev->iir = UART_IIR_NO_INT; 193 194 break; 195 } 196 case UART_IER: 197 dev->ier = ioport__read8(data); 198 break; 199 } 200 } 201 202 return true; 203 } 204 205 static bool serial8250_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 206 { 207 struct serial8250_device *dev; 208 uint16_t offset; 209 210 dev = find_device(port); 211 if (!dev) 212 return false; 213 214 offset = port - dev->iobase; 215 216 /* DLAB only changes the meaning of the first two registers */ 217 if (dev->lcr & UART_LCR_DLAB) { 218 switch (offset) { 219 case UART_DLL: 220 ioport__write8(data, dev->dll); 221 return true; 222 case UART_DLM: 223 ioport__write8(data, dev->dlm); 224 return true; 225 } 226 } else { 227 switch (offset) { 228 case UART_RX: 229 if (dev->lsr & UART_LSR_DR) { 230 dev->iir = UART_IIR_NO_INT; 231 232 dev->lsr &= ~UART_LSR_DR; 233 ioport__write8(data, dev->rbr); 234 } 235 return true; 236 case UART_IER: 237 ioport__write8(data, dev->ier); 238 return true; 239 } 240 } 241 242 /* All other registers have the same meaning regardless of DLAB */ 243 switch (offset) { 244 case UART_IIR: 245 dev->iir &= 0x3f; /* no FIFO for 8250 */ 246 ioport__write8(data, dev->iir); 247 break; 248 case UART_LCR: 249 ioport__write8(data, dev->lcr); 250 break; 251 case UART_MCR: 252 ioport__write8(data, dev->mcr); 253 break; 254 case UART_LSR: 255 ioport__write8(data, dev->lsr); 256 break; 257 case UART_MSR: 258 ioport__write8(data, UART_MSR_CTS); 259 break; 260 case UART_SCR: 261 /* No SCR for 8250 */ 262 ioport__write8(data, 0); 263 break; 264 } 265 266 return true; 267 } 268 269 static struct ioport_operations serial8250_ops = { 270 .io_in = serial8250_in, 271 .io_out = serial8250_out, 272 }; 273 274 void serial8250__init(void) 275 { 276 unsigned int i; 277 278 for (i = 0; i < ARRAY_SIZE(devices); i++) { 279 struct serial8250_device *dev = &devices[i]; 280 281 ioport__register(dev->iobase, &serial8250_ops, 8); 282 } 283 } 284