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