1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "hw.h"
26#include "qemu-char.h"
27#include "isa.h"
28#include "pc.h"
29#include "qemu-timer.h"
30
31
32
33#define UART_LCR_DLAB 0x80
34
35#define UART_IER_MSI 0x08
36#define UART_IER_RLSI 0x04
37#define UART_IER_THRI 0x02
38#define UART_IER_RDI 0x01
39
40#define UART_IIR_NO_INT 0x01
41#define UART_IIR_ID 0x06
42
43#define UART_IIR_MSI 0x00
44#define UART_IIR_THRI 0x02
45#define UART_IIR_RDI 0x04
46#define UART_IIR_RLSI 0x06
47#define UART_IIR_CTI 0x0C
48
49#define UART_IIR_FENF 0x80
50#define UART_IIR_FE 0xC0
51
52
53
54
55#define UART_MCR_LOOP 0x10
56#define UART_MCR_OUT2 0x08
57#define UART_MCR_OUT1 0x04
58#define UART_MCR_RTS 0x02
59#define UART_MCR_DTR 0x01
60
61
62
63
64#define UART_MSR_DCD 0x80
65#define UART_MSR_RI 0x40
66#define UART_MSR_DSR 0x20
67#define UART_MSR_CTS 0x10
68#define UART_MSR_DDCD 0x08
69#define UART_MSR_TERI 0x04
70#define UART_MSR_DDSR 0x02
71#define UART_MSR_DCTS 0x01
72#define UART_MSR_ANY_DELTA 0x0F
73
74#define UART_LSR_TEMT 0x40
75#define UART_LSR_THRE 0x20
76#define UART_LSR_BI 0x10
77#define UART_LSR_FE 0x08
78#define UART_LSR_PE 0x04
79#define UART_LSR_OE 0x02
80#define UART_LSR_DR 0x01
81#define UART_LSR_INT_ANY 0x1E
82
83
84
85#define UART_FCR_ITL_1 0x00
86#define UART_FCR_ITL_2 0x40
87#define UART_FCR_ITL_3 0x80
88#define UART_FCR_ITL_4 0xC0
89
90#define UART_FCR_DMS 0x08
91#define UART_FCR_XFR 0x04
92#define UART_FCR_RFR 0x02
93#define UART_FCR_FE 0x01
94
95#define UART_FIFO_LENGTH 16
96
97#define XMIT_FIFO 0
98#define RECV_FIFO 1
99#define MAX_XMIT_RETRY 4
100
101typedef struct SerialFIFO {
102 uint8_t data[UART_FIFO_LENGTH];
103 uint8_t count;
104 uint8_t itl;
105 uint8_t tail;
106 uint8_t head;
107} SerialFIFO;
108
109struct SerialState {
110 uint16_t divider;
111 uint8_t rbr;
112 uint8_t thr;
113 uint8_t tsr;
114 uint8_t ier;
115 uint8_t iir;
116 uint8_t lcr;
117 uint8_t mcr;
118 uint8_t lsr;
119 uint8_t msr;
120 uint8_t scr;
121 uint8_t fcr;
122 uint8_t fcr_vmstate;
123
124
125
126 int thr_ipending;
127 qemu_irq irq;
128 CharDriverState *chr;
129 int last_break_enable;
130 int it_shift;
131 int baudbase;
132 int tsr_retry;
133
134 uint64_t last_xmit_ts;
135 SerialFIFO recv_fifo;
136 SerialFIFO xmit_fifo;
137
138 struct QEMUTimer *fifo_timeout_timer;
139 int timeout_ipending;
140 struct QEMUTimer *transmit_timer;
141
142
143 uint64_t char_transmit_time;
144 int poll_msl;
145
146 struct QEMUTimer *modem_status_poll;
147};
148
149typedef struct ISASerialState {
150 ISADevice dev;
151 uint32_t index;
152 uint32_t iobase;
153 uint32_t isairq;
154 SerialState state;
155} ISASerialState;
156
157static void serial_receive1(void *opaque, const uint8_t *buf, int size);
158
159static void fifo_clear(SerialState *s, int fifo)
160{
161 SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
162 memset(f->data, 0, UART_FIFO_LENGTH);
163 f->count = 0;
164 f->head = 0;
165 f->tail = 0;
166}
167
168static int fifo_put(SerialState *s, int fifo, uint8_t chr)
169{
170 SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
171
172 f->data[f->head++] = chr;
173
174 if (f->head == UART_FIFO_LENGTH)
175 f->head = 0;
176 f->count++;
177
178 return 1;
179}
180
181static uint8_t fifo_get(SerialState *s, int fifo)
182{
183 SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
184 uint8_t c;
185
186 if(f->count == 0)
187 return 0;
188
189 c = f->data[f->tail++];
190 if (f->tail == UART_FIFO_LENGTH)
191 f->tail = 0;
192 f->count--;
193
194 return c;
195}
196
197static void serial_update_irq(SerialState *s)
198{
199 uint8_t tmp_iir = UART_IIR_NO_INT;
200
201 if ((s->ier & UART_IER_RLSI) && (s->lsr & UART_LSR_INT_ANY)) {
202 tmp_iir = UART_IIR_RLSI;
203 } else if ((s->ier & UART_IER_RDI) && s->timeout_ipending) {
204
205
206
207 tmp_iir = UART_IIR_CTI;
208 } else if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR) &&
209 (!(s->fcr & UART_FCR_FE) ||
210 s->recv_fifo.count >= s->recv_fifo.itl)) {
211 tmp_iir = UART_IIR_RDI;
212 } else if ((s->ier & UART_IER_THRI) && s->thr_ipending) {
213 tmp_iir = UART_IIR_THRI;
214 } else if ((s->ier & UART_IER_MSI) && (s->msr & UART_MSR_ANY_DELTA)) {
215 tmp_iir = UART_IIR_MSI;
216 }
217
218 s->iir = tmp_iir | (s->iir & 0xF0);
219
220 if (tmp_iir != UART_IIR_NO_INT) {
221 qemu_irq_raise(s->irq);
222 } else {
223 qemu_irq_lower(s->irq);
224 }
225}
226
227static void serial_update_parameters(SerialState *s)
228{
229 int speed, parity, data_bits, stop_bits, frame_size;
230 QEMUSerialSetParams ssp;
231
232 if (s->divider == 0)
233 return;
234
235
236 frame_size = 1;
237 if (s->lcr & 0x08) {
238
239 frame_size++;
240 if (s->lcr & 0x10)
241 parity = 'E';
242 else
243 parity = 'O';
244 } else {
245 parity = 'N';
246 }
247 if (s->lcr & 0x04)
248 stop_bits = 2;
249 else
250 stop_bits = 1;
251
252 data_bits = (s->lcr & 0x03) + 5;
253 frame_size += data_bits + stop_bits;
254 speed = s->baudbase / s->divider;
255 ssp.speed = speed;
256 ssp.parity = parity;
257 ssp.data_bits = data_bits;
258 ssp.stop_bits = stop_bits;
259 s->char_transmit_time = (get_ticks_per_sec() / speed) * frame_size;
260 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
261#if 0
262 printf("speed=%d parity=%c data=%d stop=%d\n",
263 speed, parity, data_bits, stop_bits);
264#endif
265}
266
267static void serial_update_msl(SerialState *s)
268{
269 uint8_t omsr;
270 int flags;
271
272 qemu_del_timer(s->modem_status_poll);
273
274 if (qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) {
275 s->poll_msl = -1;
276 return;
277 }
278
279 omsr = s->msr;
280
281 s->msr = (flags & CHR_TIOCM_CTS) ? s->msr | UART_MSR_CTS : s->msr & ~UART_MSR_CTS;
282 s->msr = (flags & CHR_TIOCM_DSR) ? s->msr | UART_MSR_DSR : s->msr & ~UART_MSR_DSR;
283 s->msr = (flags & CHR_TIOCM_CAR) ? s->msr | UART_MSR_DCD : s->msr & ~UART_MSR_DCD;
284 s->msr = (flags & CHR_TIOCM_RI) ? s->msr | UART_MSR_RI : s->msr & ~UART_MSR_RI;
285
286 if (s->msr != omsr) {
287
288 s->msr = s->msr | ((s->msr >> 4) ^ (omsr >> 4));
289
290 if ((s->msr & UART_MSR_TERI) && !(omsr & UART_MSR_RI))
291 s->msr &= ~UART_MSR_TERI;
292 serial_update_irq(s);
293 }
294
295
296
297
298 if (s->poll_msl)
299 qemu_mod_timer(s->modem_status_poll, qemu_get_clock(vm_clock) + get_ticks_per_sec() / 100);
300}
301
302static void serial_xmit(void *opaque)
303{
304 SerialState *s = opaque;
305 uint64_t new_xmit_ts = qemu_get_clock(vm_clock);
306
307 if (s->tsr_retry <= 0) {
308 if (s->fcr & UART_FCR_FE) {
309 s->tsr = fifo_get(s,XMIT_FIFO);
310 if (!s->xmit_fifo.count)
311 s->lsr |= UART_LSR_THRE;
312 } else {
313 s->tsr = s->thr;
314 s->lsr |= UART_LSR_THRE;
315 }
316 }
317
318 if (s->mcr & UART_MCR_LOOP) {
319
320 serial_receive1(s, &s->tsr, 1);
321 } else if (qemu_chr_write(s->chr, &s->tsr, 1) != 1) {
322 if ((s->tsr_retry > 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) {
323 s->tsr_retry++;
324 qemu_mod_timer(s->transmit_timer, new_xmit_ts + s->char_transmit_time);
325 return;
326 } else if (s->poll_msl < 0) {
327
328
329
330 s->tsr_retry = -1;
331 }
332 }
333 else {
334 s->tsr_retry = 0;
335 }
336
337 s->last_xmit_ts = qemu_get_clock(vm_clock);
338 if (!(s->lsr & UART_LSR_THRE))
339 qemu_mod_timer(s->transmit_timer, s->last_xmit_ts + s->char_transmit_time);
340
341 if (s->lsr & UART_LSR_THRE) {
342 s->lsr |= UART_LSR_TEMT;
343 s->thr_ipending = 1;
344 serial_update_irq(s);
345 }
346}
347
348
349static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
350{
351 SerialState *s = opaque;
352
353 addr &= 7;
354#ifdef DEBUG_SERIAL
355 printf("serial: write addr=0x%02x val=0x%02x\n", addr, val);
356#endif
357 switch(addr) {
358 default:
359 case 0:
360 if (s->lcr & UART_LCR_DLAB) {
361 s->divider = (s->divider & 0xff00) | val;
362 serial_update_parameters(s);
363 } else {
364 s->thr = (uint8_t) val;
365 if(s->fcr & UART_FCR_FE) {
366 fifo_put(s, XMIT_FIFO, s->thr);
367 s->thr_ipending = 0;
368 s->lsr &= ~UART_LSR_TEMT;
369 s->lsr &= ~UART_LSR_THRE;
370 serial_update_irq(s);
371 } else {
372 s->thr_ipending = 0;
373 s->lsr &= ~UART_LSR_THRE;
374 serial_update_irq(s);
375 }
376 serial_xmit(s);
377 }
378 break;
379 case 1:
380 if (s->lcr & UART_LCR_DLAB) {
381 s->divider = (s->divider & 0x00ff) | (val << 8);
382 serial_update_parameters(s);
383 } else {
384 s->ier = val & 0x0f;
385
386
387 if (s->poll_msl >= 0) {
388 if (s->ier & UART_IER_MSI) {
389 s->poll_msl = 1;
390 serial_update_msl(s);
391 } else {
392 qemu_del_timer(s->modem_status_poll);
393 s->poll_msl = 0;
394 }
395 }
396 if (s->lsr & UART_LSR_THRE) {
397 s->thr_ipending = 1;
398 serial_update_irq(s);
399 }
400 }
401 break;
402 case 2:
403 val = val & 0xFF;
404
405 if (s->fcr == val)
406 break;
407
408
409 if ((val ^ s->fcr) & UART_FCR_FE)
410 val |= UART_FCR_XFR | UART_FCR_RFR;
411
412
413
414 if (val & UART_FCR_RFR) {
415 qemu_del_timer(s->fifo_timeout_timer);
416 s->timeout_ipending=0;
417 fifo_clear(s,RECV_FIFO);
418 }
419
420 if (val & UART_FCR_XFR) {
421 fifo_clear(s,XMIT_FIFO);
422 }
423
424 if (val & UART_FCR_FE) {
425 s->iir |= UART_IIR_FE;
426
427 switch (val & 0xC0) {
428 case UART_FCR_ITL_1:
429 s->recv_fifo.itl = 1;
430 break;
431 case UART_FCR_ITL_2:
432 s->recv_fifo.itl = 4;
433 break;
434 case UART_FCR_ITL_3:
435 s->recv_fifo.itl = 8;
436 break;
437 case UART_FCR_ITL_4:
438 s->recv_fifo.itl = 14;
439 break;
440 }
441 } else
442 s->iir &= ~UART_IIR_FE;
443
444
445 s->fcr = val & 0xC9;
446 serial_update_irq(s);
447 break;
448 case 3:
449 {
450 int break_enable;
451 s->lcr = val;
452 serial_update_parameters(s);
453 break_enable = (val >> 6) & 1;
454 if (break_enable != s->last_break_enable) {
455 s->last_break_enable = break_enable;
456 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
457 &break_enable);
458 }
459 }
460 break;
461 case 4:
462 {
463 int flags;
464 int old_mcr = s->mcr;
465 s->mcr = val & 0x1f;
466 if (val & UART_MCR_LOOP)
467 break;
468
469 if (s->poll_msl >= 0 && old_mcr != s->mcr) {
470
471 qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
472
473 flags &= ~(CHR_TIOCM_RTS | CHR_TIOCM_DTR);
474
475 if (val & UART_MCR_RTS)
476 flags |= CHR_TIOCM_RTS;
477 if (val & UART_MCR_DTR)
478 flags |= CHR_TIOCM_DTR;
479
480 qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
481
482
483 qemu_mod_timer(s->modem_status_poll, qemu_get_clock(vm_clock) + s->char_transmit_time);
484 }
485 }
486 break;
487 case 5:
488 break;
489 case 6:
490 break;
491 case 7:
492 s->scr = val;
493 break;
494 }
495}
496
497static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
498{
499 SerialState *s = opaque;
500 uint32_t ret;
501
502 addr &= 7;
503 switch(addr) {
504 default:
505 case 0:
506 if (s->lcr & UART_LCR_DLAB) {
507 ret = s->divider & 0xff;
508 } else {
509 if(s->fcr & UART_FCR_FE) {
510 ret = fifo_get(s,RECV_FIFO);
511 if (s->recv_fifo.count == 0)
512 s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
513 else
514 qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock (vm_clock) + s->char_transmit_time * 4);
515 s->timeout_ipending = 0;
516 } else {
517 ret = s->rbr;
518 s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
519 }
520 serial_update_irq(s);
521 if (!(s->mcr & UART_MCR_LOOP)) {
522
523 qemu_chr_accept_input(s->chr);
524 }
525 }
526 break;
527 case 1:
528 if (s->lcr & UART_LCR_DLAB) {
529 ret = (s->divider >> 8) & 0xff;
530 } else {
531 ret = s->ier;
532 }
533 break;
534 case 2:
535 ret = s->iir;
536 s->thr_ipending = 0;
537 serial_update_irq(s);
538 break;
539 case 3:
540 ret = s->lcr;
541 break;
542 case 4:
543 ret = s->mcr;
544 break;
545 case 5:
546 ret = s->lsr;
547
548 if (s->lsr & UART_LSR_BI) {
549 s->lsr &= ~UART_LSR_BI;
550 serial_update_irq(s);
551 }
552 break;
553 case 6:
554 if (s->mcr & UART_MCR_LOOP) {
555
556
557 ret = (s->mcr & 0x0c) << 4;
558 ret |= (s->mcr & 0x02) << 3;
559 ret |= (s->mcr & 0x01) << 5;
560 } else {
561 if (s->poll_msl >= 0)
562 serial_update_msl(s);
563 ret = s->msr;
564
565 if (s->msr & UART_MSR_ANY_DELTA) {
566 s->msr &= 0xF0;
567 serial_update_irq(s);
568 }
569 }
570 break;
571 case 7:
572 ret = s->scr;
573 break;
574 }
575#ifdef DEBUG_SERIAL
576 printf("serial: read addr=0x%02x val=0x%02x\n", addr, ret);
577#endif
578 return ret;
579}
580
581static int serial_can_receive(SerialState *s)
582{
583 if(s->fcr & UART_FCR_FE) {
584 if(s->recv_fifo.count < UART_FIFO_LENGTH)
585
586
587
588 return (s->recv_fifo.count <= s->recv_fifo.itl) ? s->recv_fifo.itl - s->recv_fifo.count : 1;
589 else
590 return 0;
591 } else {
592 return !(s->lsr & UART_LSR_DR);
593 }
594}
595
596static void serial_receive_break(SerialState *s)
597{
598 s->rbr = 0;
599
600 fifo_put(s, RECV_FIFO, '\0');
601 s->lsr |= UART_LSR_BI | UART_LSR_DR;
602 serial_update_irq(s);
603}
604
605
606static void fifo_timeout_int (void *opaque) {
607 SerialState *s = opaque;
608 if (s->recv_fifo.count) {
609 s->timeout_ipending = 1;
610 serial_update_irq(s);
611 }
612}
613
614static int serial_can_receive1(void *opaque)
615{
616 SerialState *s = opaque;
617 return serial_can_receive(s);
618}
619
620static void serial_receive1(void *opaque, const uint8_t *buf, int size)
621{
622 SerialState *s = opaque;
623 if(s->fcr & UART_FCR_FE) {
624 int i;
625 for (i = 0; i < size; i++) {
626 fifo_put(s, RECV_FIFO, buf[i]);
627 }
628 s->lsr |= UART_LSR_DR;
629
630 qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock (vm_clock) + s->char_transmit_time * 4);
631 } else {
632 s->rbr = buf[0];
633 s->lsr |= UART_LSR_DR;
634 }
635 serial_update_irq(s);
636}
637
638static void serial_event(void *opaque, int event)
639{
640 SerialState *s = opaque;
641#ifdef DEBUG_SERIAL
642 printf("serial: event %x\n", event);
643#endif
644 if (event == CHR_EVENT_BREAK)
645 serial_receive_break(s);
646}
647
648static void serial_pre_save(void *opaque)
649{
650 SerialState *s = opaque;
651 s->fcr_vmstate = s->fcr;
652}
653
654static int serial_post_load(void *opaque, int version_id)
655{
656 SerialState *s = opaque;
657
658 if (version_id < 3) {
659 s->fcr_vmstate = 0;
660 }
661
662 serial_ioport_write(s, 0x02, s->fcr_vmstate);
663 return 0;
664}
665
666static const VMStateDescription vmstate_serial = {
667 .name = "serial",
668 .version_id = 3,
669 .minimum_version_id = 2,
670 .pre_save = serial_pre_save,
671 .post_load = serial_post_load,
672 .fields = (VMStateField []) {
673 VMSTATE_UINT16_V(divider, SerialState, 2),
674 VMSTATE_UINT8(rbr, SerialState),
675 VMSTATE_UINT8(ier, SerialState),
676 VMSTATE_UINT8(iir, SerialState),
677 VMSTATE_UINT8(lcr, SerialState),
678 VMSTATE_UINT8(mcr, SerialState),
679 VMSTATE_UINT8(lsr, SerialState),
680 VMSTATE_UINT8(msr, SerialState),
681 VMSTATE_UINT8(scr, SerialState),
682 VMSTATE_UINT8_V(fcr_vmstate, SerialState, 3),
683 VMSTATE_END_OF_LIST()
684 }
685};
686
687static void serial_reset(void *opaque)
688{
689 SerialState *s = opaque;
690
691 s->rbr = 0;
692 s->ier = 0;
693 s->iir = UART_IIR_NO_INT;
694 s->lcr = 0;
695 s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
696 s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
697
698 s->divider = 0x0C;
699 s->mcr = UART_MCR_OUT2;
700 s->scr = 0;
701 s->tsr_retry = 0;
702 s->char_transmit_time = (get_ticks_per_sec() / 9600) * 10;
703 s->poll_msl = 0;
704
705 fifo_clear(s,RECV_FIFO);
706 fifo_clear(s,XMIT_FIFO);
707
708 s->last_xmit_ts = qemu_get_clock(vm_clock);
709
710 s->thr_ipending = 0;
711 s->last_break_enable = 0;
712 qemu_irq_lower(s->irq);
713}
714
715static void serial_init_core(SerialState *s)
716{
717 if (!s->chr) {
718 fprintf(stderr, "Can't create serial device, empty char device\n");
719 exit(1);
720 }
721
722 s->modem_status_poll = qemu_new_timer(vm_clock, (QEMUTimerCB *) serial_update_msl, s);
723
724 s->fifo_timeout_timer = qemu_new_timer(vm_clock, (QEMUTimerCB *) fifo_timeout_int, s);
725 s->transmit_timer = qemu_new_timer(vm_clock, (QEMUTimerCB *) serial_xmit, s);
726
727 qemu_register_reset(serial_reset, s);
728
729 qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
730 serial_event, s);
731}
732
733
734void serial_set_frequency(SerialState *s, uint32_t frequency)
735{
736 s->baudbase = frequency;
737 serial_update_parameters(s);
738}
739
740static const int isa_serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
741static const int isa_serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
742
743static int serial_isa_initfn(ISADevice *dev)
744{
745 static int index;
746 ISASerialState *isa = DO_UPCAST(ISASerialState, dev, dev);
747 SerialState *s = &isa->state;
748
749 if (isa->index == -1)
750 isa->index = index;
751 if (isa->index >= MAX_SERIAL_PORTS)
752 return -1;
753 if (isa->iobase == -1)
754 isa->iobase = isa_serial_io[isa->index];
755 if (isa->isairq == -1)
756 isa->isairq = isa_serial_irq[isa->index];
757 index++;
758
759 s->baudbase = 115200;
760 isa_init_irq(dev, &s->irq, isa->isairq);
761 serial_init_core(s);
762 vmstate_register(isa->iobase, &vmstate_serial, s);
763
764 register_ioport_write(isa->iobase, 8, 1, serial_ioport_write, s);
765 register_ioport_read(isa->iobase, 8, 1, serial_ioport_read, s);
766 return 0;
767}
768
769SerialState *serial_isa_init(int index, CharDriverState *chr)
770{
771 ISADevice *dev;
772
773 dev = isa_create("isa-serial");
774 qdev_prop_set_uint32(&dev->qdev, "index", index);
775 qdev_prop_set_chr(&dev->qdev, "chardev", chr);
776 if (qdev_init(&dev->qdev) < 0)
777 return NULL;
778 return &DO_UPCAST(ISASerialState, dev, dev)->state;
779}
780
781SerialState *serial_init(int base, qemu_irq irq, int baudbase,
782 CharDriverState *chr)
783{
784 SerialState *s;
785
786 s = qemu_mallocz(sizeof(SerialState));
787
788 s->irq = irq;
789 s->baudbase = baudbase;
790 s->chr = chr;
791 serial_init_core(s);
792
793 vmstate_register(base, &vmstate_serial, s);
794
795 register_ioport_write(base, 8, 1, serial_ioport_write, s);
796 register_ioport_read(base, 8, 1, serial_ioport_read, s);
797 return s;
798}
799
800
801static uint32_t serial_mm_readb(void *opaque, target_phys_addr_t addr)
802{
803 SerialState *s = opaque;
804
805 return serial_ioport_read(s, addr >> s->it_shift) & 0xFF;
806}
807
808static void serial_mm_writeb(void *opaque, target_phys_addr_t addr,
809 uint32_t value)
810{
811 SerialState *s = opaque;
812
813 serial_ioport_write(s, addr >> s->it_shift, value & 0xFF);
814}
815
816static uint32_t serial_mm_readw(void *opaque, target_phys_addr_t addr)
817{
818 SerialState *s = opaque;
819 uint32_t val;
820
821 val = serial_ioport_read(s, addr >> s->it_shift) & 0xFFFF;
822#ifdef TARGET_WORDS_BIGENDIAN
823 val = bswap16(val);
824#endif
825 return val;
826}
827
828static void serial_mm_writew(void *opaque, target_phys_addr_t addr,
829 uint32_t value)
830{
831 SerialState *s = opaque;
832#ifdef TARGET_WORDS_BIGENDIAN
833 value = bswap16(value);
834#endif
835 serial_ioport_write(s, addr >> s->it_shift, value & 0xFFFF);
836}
837
838static uint32_t serial_mm_readl(void *opaque, target_phys_addr_t addr)
839{
840 SerialState *s = opaque;
841 uint32_t val;
842
843 val = serial_ioport_read(s, addr >> s->it_shift);
844#ifdef TARGET_WORDS_BIGENDIAN
845 val = bswap32(val);
846#endif
847 return val;
848}
849
850static void serial_mm_writel(void *opaque, target_phys_addr_t addr,
851 uint32_t value)
852{
853 SerialState *s = opaque;
854#ifdef TARGET_WORDS_BIGENDIAN
855 value = bswap32(value);
856#endif
857 serial_ioport_write(s, addr >> s->it_shift, value);
858}
859
860static CPUReadMemoryFunc * const serial_mm_read[] = {
861 &serial_mm_readb,
862 &serial_mm_readw,
863 &serial_mm_readl,
864};
865
866static CPUWriteMemoryFunc * const serial_mm_write[] = {
867 &serial_mm_writeb,
868 &serial_mm_writew,
869 &serial_mm_writel,
870};
871
872SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
873 qemu_irq irq, int baudbase,
874 CharDriverState *chr, int ioregister)
875{
876 SerialState *s;
877 int s_io_memory;
878
879 s = qemu_mallocz(sizeof(SerialState));
880
881 s->it_shift = it_shift;
882 s->irq = irq;
883 s->baudbase = baudbase;
884 s->chr = chr;
885
886 serial_init_core(s);
887 vmstate_register(base, &vmstate_serial, s);
888
889 if (ioregister) {
890 s_io_memory = cpu_register_io_memory(serial_mm_read,
891 serial_mm_write, s);
892 cpu_register_physical_memory(base, 8 << it_shift, s_io_memory);
893 }
894 serial_update_msl(s);
895 return s;
896}
897
898static ISADeviceInfo serial_isa_info = {
899 .qdev.name = "isa-serial",
900 .qdev.size = sizeof(ISASerialState),
901 .init = serial_isa_initfn,
902 .qdev.props = (Property[]) {
903 DEFINE_PROP_UINT32("index", ISASerialState, index, -1),
904 DEFINE_PROP_HEX32("iobase", ISASerialState, iobase, -1),
905 DEFINE_PROP_UINT32("irq", ISASerialState, isairq, -1),
906 DEFINE_PROP_CHR("chardev", ISASerialState, state.chr),
907 DEFINE_PROP_END_OF_LIST(),
908 },
909};
910
911static void serial_register_devices(void)
912{
913 isa_qdev_register(&serial_isa_info);
914}
915
916device_init(serial_register_devices)
917