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