kvm tools: Add ivshmem device
[linux-2.6/next.git] / tools / kvm / hw / serial.c
blobb3b233ff186a9f32949e6b9bae6ab4b77683e29d
1 #include "kvm/8250-serial.h"
3 #include "kvm/read-write.h"
4 #include "kvm/ioport.h"
5 #include "kvm/mutex.h"
6 #include "kvm/util.h"
7 #include "kvm/term.h"
8 #include "kvm/kvm.h"
10 #include <linux/types.h>
11 #include <linux/serial_reg.h>
13 #include <pthread.h>
15 struct serial8250_device {
16 pthread_mutex_t mutex;
18 u16 iobase;
19 u8 irq;
21 u8 rbr; /* receive buffer */
22 u8 dll;
23 u8 dlm;
24 u8 iir;
25 u8 ier;
26 u8 fcr;
27 u8 lcr;
28 u8 mcr;
29 u8 lsr;
30 u8 msr;
31 u8 scr;
34 #define SERIAL_REGS_SETTING \
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,
40 static struct serial8250_device devices[] = {
41 /* ttyS0 */
42 [0] = {
43 .mutex = PTHREAD_MUTEX_INITIALIZER,
45 .iobase = 0x3f8,
46 .irq = 4,
48 SERIAL_REGS_SETTING
50 /* ttyS1 */
51 [1] = {
52 .mutex = PTHREAD_MUTEX_INITIALIZER,
54 .iobase = 0x2f8,
55 .irq = 3,
57 SERIAL_REGS_SETTING
59 /* ttyS2 */
60 [2] = {
61 .mutex = PTHREAD_MUTEX_INITIALIZER,
63 .iobase = 0x3e8,
64 .irq = 4,
66 SERIAL_REGS_SETTING
68 /* ttyS3 */
69 [3] = {
70 .mutex = PTHREAD_MUTEX_INITIALIZER,
72 .iobase = 0x2e8,
73 .irq = 3,
75 SERIAL_REGS_SETTING
79 #define SYSRQ_PENDING_NONE 0
80 #define SYSRQ_PENDING_BREAK 1
81 #define SYSRQ_PENDING_CMD 2
83 static int sysrq_pending;
85 static void serial8250__sysrq(struct kvm *kvm, struct serial8250_device *dev)
87 switch (sysrq_pending) {
88 case SYSRQ_PENDING_BREAK:
89 dev->lsr |= UART_LSR_DR | UART_LSR_BI;
91 sysrq_pending = SYSRQ_PENDING_CMD;
92 break;
93 case SYSRQ_PENDING_CMD:
94 dev->rbr = 'p';
95 dev->lsr |= UART_LSR_DR;
97 sysrq_pending = SYSRQ_PENDING_NONE;
98 break;
102 static void serial8250__receive(struct kvm *kvm, struct serial8250_device *dev)
104 int c;
106 if (dev->lsr & UART_LSR_DR)
107 return;
109 if (sysrq_pending) {
110 serial8250__sysrq(kvm, dev);
111 return;
114 if (!term_readable(CONSOLE_8250))
115 return;
117 c = term_getc(CONSOLE_8250);
119 if (c < 0)
120 return;
122 dev->rbr = c;
123 dev->lsr |= UART_LSR_DR;
127 * Interrupts are injected for ttyS0 only.
129 void serial8250__inject_interrupt(struct kvm *kvm)
131 struct serial8250_device *dev = &devices[0];
133 mutex_lock(&dev->mutex);
135 serial8250__receive(kvm, dev);
137 if (dev->ier & UART_IER_RDI && dev->lsr & UART_LSR_DR)
138 dev->iir = UART_IIR_RDI;
139 else if (dev->ier & UART_IER_THRI)
140 dev->iir = UART_IIR_THRI;
141 else
142 dev->iir = UART_IIR_NO_INT;
144 if (dev->iir != UART_IIR_NO_INT) {
145 kvm__irq_line(kvm, dev->irq, 0);
146 kvm__irq_line(kvm, dev->irq, 1);
149 mutex_unlock(&dev->mutex);
152 void serial8250__inject_sysrq(struct kvm *kvm)
154 sysrq_pending = SYSRQ_PENDING_BREAK;
157 static struct serial8250_device *find_device(u16 port)
159 unsigned int i;
161 for (i = 0; i < ARRAY_SIZE(devices); i++) {
162 struct serial8250_device *dev = &devices[i];
164 if (dev->iobase == (port & ~0x7))
165 return dev;
167 return NULL;
170 static bool serial8250_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
172 struct serial8250_device *dev;
173 u16 offset;
174 bool ret = true;
176 dev = find_device(port);
177 if (!dev)
178 return false;
180 mutex_lock(&dev->mutex);
182 offset = port - dev->iobase;
184 if (dev->lcr & UART_LCR_DLAB) {
185 switch (offset) {
186 case UART_DLL:
187 dev->dll = ioport__read8(data);
188 break;
189 case UART_DLM:
190 dev->dlm = ioport__read8(data);
191 break;
192 case UART_FCR:
193 dev->fcr = ioport__read8(data);
194 break;
195 case UART_LCR:
196 dev->lcr = ioport__read8(data);
197 break;
198 case UART_MCR:
199 dev->mcr = ioport__read8(data);
200 break;
201 case UART_LSR:
202 /* Factory test */
203 break;
204 case UART_MSR:
205 /* Not used */
206 break;
207 case UART_SCR:
208 dev->scr = ioport__read8(data);
209 break;
210 default:
211 ret = false;
212 goto out_unlock;
214 } else {
215 switch (offset) {
216 case UART_TX: {
217 char *addr = data;
219 if (!(dev->mcr & UART_MCR_LOOP))
220 term_putc(CONSOLE_8250, addr, size);
222 dev->iir = UART_IIR_NO_INT;
223 break;
225 case UART_FCR:
226 dev->fcr = ioport__read8(data);
227 break;
228 case UART_IER:
229 dev->ier = ioport__read8(data) & 0x3f;
230 break;
231 case UART_LCR:
232 dev->lcr = ioport__read8(data);
233 break;
234 case UART_MCR:
235 dev->mcr = ioport__read8(data);
236 break;
237 case UART_LSR:
238 /* Factory test */
239 break;
240 case UART_MSR:
241 /* Not used */
242 break;
243 case UART_SCR:
244 dev->scr = ioport__read8(data);
245 break;
246 default:
247 ret = false;
248 goto out_unlock;
252 out_unlock:
253 mutex_unlock(&dev->mutex);
255 return ret;
258 static bool serial8250_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
260 struct serial8250_device *dev;
261 u16 offset;
262 bool ret = true;
264 dev = find_device(port);
265 if (!dev)
266 return false;
268 mutex_lock(&dev->mutex);
270 offset = port - dev->iobase;
272 if (dev->lcr & UART_LCR_DLAB) {
273 switch (offset) {
274 case UART_DLL:
275 ioport__write8(data, dev->dll);
276 goto out_unlock;
278 case UART_DLM:
279 ioport__write8(data, dev->dlm);
280 goto out_unlock;
282 default:
283 break;
285 } else {
286 switch (offset) {
287 case UART_RX:
288 ioport__write8(data, dev->rbr);
289 dev->lsr &= ~UART_LSR_DR;
290 dev->iir = UART_IIR_NO_INT;
291 goto out_unlock;
293 case UART_IER:
294 ioport__write8(data, dev->ier);
295 goto out_unlock;
297 default:
298 break;
302 switch (offset) {
303 case UART_IIR: {
304 u8 iir = dev->iir;
306 if (dev->fcr & UART_FCR_ENABLE_FIFO)
307 iir |= 0xc0;
309 ioport__write8(data, iir);
310 break;
312 case UART_LCR:
313 ioport__write8(data, dev->lcr);
314 break;
315 case UART_MCR:
316 ioport__write8(data, dev->mcr);
317 break;
318 case UART_LSR:
319 ioport__write8(data, dev->lsr);
320 dev->lsr &= ~(UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_BI);
321 break;
322 case UART_MSR:
323 ioport__write8(data, dev->msr);
324 break;
325 case UART_SCR:
326 ioport__write8(data, dev->scr);
327 break;
328 default:
329 ret = false;
330 goto out_unlock;
332 out_unlock:
333 mutex_unlock(&dev->mutex);
335 return ret;
338 static struct ioport_operations serial8250_ops = {
339 .io_in = serial8250_in,
340 .io_out = serial8250_out,
343 static void serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev)
345 ioport__register(dev->iobase, &serial8250_ops, 8, NULL);
346 kvm__irq_line(kvm, dev->irq, 0);
349 void serial8250__init(struct kvm *kvm)
351 unsigned int i;
353 for (i = 0; i < ARRAY_SIZE(devices); i++) {
354 struct serial8250_device *dev = &devices[i];
356 serial8250__device_init(kvm, dev);