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/term.h" 7 #include "kvm/kvm.h" 8 9 #include <linux/serial_reg.h> 10 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 void serial8250__receive(struct kvm *self, struct serial8250_device *dev) 57 { 58 int c; 59 60 if (dev->lsr & UART_LSR_DR) 61 return; 62 63 if (!term_readable(CONSOLE_8250)) 64 return; 65 66 c = term_getc(CONSOLE_8250); 67 68 if (c < 0) 69 return; 70 71 dev->rbr = c; 72 dev->lsr |= UART_LSR_DR; 73 } 74 75 /* 76 * Interrupts are injected for ttyS0 only. 77 */ 78 void serial8250__inject_interrupt(struct kvm *self) 79 { 80 struct serial8250_device *dev = &devices[0]; 81 82 serial8250__receive(self, dev); 83 84 if (dev->ier & UART_IER_RDI && dev->lsr & UART_LSR_DR) 85 dev->iir = UART_IIR_RDI; 86 else if (dev->ier & UART_IER_THRI) 87 dev->iir = UART_IIR_THRI; 88 else 89 dev->iir = UART_IIR_NO_INT; 90 91 if (dev->iir != UART_IIR_NO_INT) { 92 kvm__irq_line(self, dev->irq, 0); 93 kvm__irq_line(self, dev->irq, 1); 94 } 95 } 96 97 static struct serial8250_device *find_device(uint16_t port) 98 { 99 unsigned int i; 100 101 for (i = 0; i < ARRAY_SIZE(devices); i++) { 102 struct serial8250_device *dev = &devices[i]; 103 104 if (dev->iobase == (port & ~0x7)) 105 return dev; 106 } 107 return NULL; 108 } 109 110 static bool serial8250_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 111 { 112 struct serial8250_device *dev; 113 uint16_t offset; 114 115 dev = find_device(port); 116 if (!dev) 117 return false; 118 119 offset = port - dev->iobase; 120 121 if (dev->lcr & UART_LCR_DLAB) { 122 switch (offset) { 123 case UART_DLL: 124 dev->dll = ioport__read8(data); 125 break; 126 case UART_DLM: 127 dev->dlm = ioport__read8(data); 128 break; 129 case UART_FCR: 130 dev->fcr = ioport__read8(data); 131 break; 132 case UART_LCR: 133 dev->lcr = ioport__read8(data); 134 break; 135 case UART_MCR: 136 dev->mcr = ioport__read8(data); 137 break; 138 case UART_LSR: 139 /* Factory test */ 140 break; 141 case UART_MSR: 142 /* Not used */ 143 break; 144 case UART_SCR: 145 dev->scr = ioport__read8(data); 146 break; 147 default: 148 return false; 149 } 150 } else { 151 switch (offset) { 152 case UART_TX: { 153 char *addr = data; 154 if (!(dev->mcr & UART_MCR_LOOP)) { 155 term_putc(CONSOLE_8250, addr, size * count); 156 } 157 dev->iir = UART_IIR_NO_INT; 158 break; 159 } 160 case UART_FCR: 161 dev->fcr = ioport__read8(data); 162 break; 163 case UART_IER: 164 dev->ier = ioport__read8(data) & 0x3f; 165 break; 166 case UART_LCR: 167 dev->lcr = ioport__read8(data); 168 break; 169 case UART_MCR: 170 dev->mcr = ioport__read8(data); 171 break; 172 case UART_LSR: 173 /* Factory test */ 174 break; 175 case UART_MSR: 176 /* Not used */ 177 break; 178 case UART_SCR: 179 dev->scr = ioport__read8(data); 180 break; 181 default: 182 return false; 183 } 184 } 185 return true; 186 } 187 188 static bool serial8250_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) 189 { 190 struct serial8250_device *dev; 191 uint16_t offset; 192 193 dev = find_device(port); 194 if (!dev) 195 return false; 196 197 offset = port - dev->iobase; 198 199 if (dev->lcr & UART_LCR_DLAB) { 200 switch (offset) { 201 case UART_DLL: 202 ioport__write8(data, dev->dll); 203 return true; 204 case UART_DLM: 205 ioport__write8(data, dev->dlm); 206 return true; 207 default: 208 break; 209 } 210 } else { 211 switch (offset) { 212 case UART_RX: 213 ioport__write8(data, dev->rbr); 214 dev->lsr &= ~UART_LSR_DR; 215 dev->iir = UART_IIR_NO_INT; 216 return true; 217 case UART_IER: 218 ioport__write8(data, dev->ier); 219 return true; 220 default: 221 break; 222 } 223 } 224 225 switch (offset) { 226 case UART_IIR: { 227 uint8_t iir = dev->iir; 228 229 if (dev->fcr & UART_FCR_ENABLE_FIFO) 230 iir |= 0xc0; 231 232 ioport__write8(data, iir); 233 break; 234 } 235 case UART_LCR: 236 ioport__write8(data, dev->lcr); 237 break; 238 case UART_MCR: 239 ioport__write8(data, dev->mcr); 240 break; 241 case UART_LSR: 242 ioport__write8(data, dev->lsr); 243 dev->lsr &= ~(UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_BI); 244 break; 245 case UART_MSR: 246 ioport__write8(data, dev->msr); 247 break; 248 case UART_SCR: 249 ioport__write8(data, dev->scr); 250 break; 251 default: 252 return false; 253 } 254 return true; 255 } 256 257 static struct ioport_operations serial8250_ops = { 258 .io_in = serial8250_in, 259 .io_out = serial8250_out, 260 }; 261 262 static void serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev) 263 { 264 ioport__register(dev->iobase, &serial8250_ops, 8); 265 kvm__irq_line(kvm, dev->irq, 0); 266 } 267 268 void serial8250__init(struct kvm *kvm) 269 { 270 unsigned int i; 271 272 for (i = 0; i < ARRAY_SIZE(devices); i++) { 273 struct serial8250_device *dev = &devices[i]; 274 275 serial8250__device_init(kvm, dev); 276 } 277 } 278