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