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
101struct 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} typedef 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
123
124 int thr_ipending;
125 qemu_irq irq;
126 CharDriverState *chr;
127 int last_break_enable;
128 int it_shift;
129 int baudbase;
130 int tsr_retry;
131
132 uint64_t last_xmit_ts;
133 SerialFIFO recv_fifo;
134 SerialFIFO xmit_fifo;
135
136 struct QEMUTimer *fifo_timeout_timer;
137 int timeout_ipending;
138 struct QEMUTimer *transmit_timer;
139
140
141 uint64_t char_transmit_time;
142 int poll_msl;
143
144 struct QEMUTimer *modem_status_poll;
145};
146
147static void serial_receive1(void *opaque, const uint8_t *buf, int size);
148
149static void fifo_clear(SerialState *s, int fifo)
150{
151 SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
152 memset(f->data, 0, UART_FIFO_LENGTH);
153 f->count = 0;
154 f->head = 0;
155 f->tail = 0;
156}
157
158static int fifo_put(SerialState *s, int fifo, uint8_t chr)
159{
160 SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
161
162 f->data[f->head++] = chr;
163
164 if (f->head == UART_FIFO_LENGTH)
165 f->head = 0;
166 f->count++;
167
168 return 1;
169}
170
171static uint8_t fifo_get(SerialState *s, int fifo)
172{
173 SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
174 uint8_t c;
175
176 if(f->count == 0)
177 return 0;
178
179 c = f->data[f->tail++];
180 if (f->tail == UART_FIFO_LENGTH)
181 f->tail = 0;
182 f->count--;
183
184 return c;
185}
186
187static void serial_update_irq(SerialState *s)
188{
189 uint8_t tmp_iir = UART_IIR_NO_INT;
190
191 if ((s->ier & UART_IER_RLSI) && (s->lsr & UART_LSR_INT_ANY)) {
192 tmp_iir = UART_IIR_RLSI;
193 } else if ((s->ier & UART_IER_RDI) && s->timeout_ipending) {
194
195
196
197 tmp_iir = UART_IIR_CTI;
198 } else if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR)) {
199 if (!(s->fcr & UART_FCR_FE)) {
200 tmp_iir = UART_IIR_RDI;
201 } else if (s->recv_fifo.count >= s->recv_fifo.itl) {
202 tmp_iir = UART_IIR_RDI;
203 }
204 } else if ((s->ier & UART_IER_THRI) && s->thr_ipending) {
205 tmp_iir = UART_IIR_THRI;
206 } else if ((s->ier & UART_IER_MSI) && (s->msr & UART_MSR_ANY_DELTA)) {
207 tmp_iir = UART_IIR_MSI;
208 }
209
210 s->iir = tmp_iir | (s->iir & 0xF0);
211
212 if (tmp_iir != UART_IIR_NO_INT) {
213 qemu_irq_raise(s->irq);
214 } else {
215 qemu_irq_lower(s->irq);
216 }
217}
218
219static void serial_update_parameters(SerialState *s)
220{
221 int speed, parity, data_bits, stop_bits, frame_size;
222 QEMUSerialSetParams ssp;
223
224 if (s->divider == 0)
225 return;
226
227 frame_size = 1;
228 if (s->lcr & 0x08) {
229 if (s->lcr & 0x10)
230 parity = 'E';
231 else
232 parity = 'O';
233 } else {
234 parity = 'N';
235 frame_size = 0;
236 }
237 if (s->lcr & 0x04)
238 stop_bits = 2;
239 else
240 stop_bits = 1;
241
242 data_bits = (s->lcr & 0x03) + 5;
243 frame_size += data_bits + stop_bits;
244 speed = s->baudbase / s->divider;
245 ssp.speed = speed;
246 ssp.parity = parity;
247 ssp.data_bits = data_bits;
248 ssp.stop_bits = stop_bits;
249 s->char_transmit_time = (ticks_per_sec / speed) * frame_size;
250 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
251#if 0
252 printf("speed=%d parity=%c data=%d stop=%d\n",
253 speed, parity, data_bits, stop_bits);
254#endif
255}
256
257static void serial_update_msl(SerialState *s)
258{
259 uint8_t omsr;
260 int flags;
261
262 qemu_del_timer(s->modem_status_poll);
263
264 if (qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) {
265 s->poll_msl = -1;
266 return;
267 }
268
269 omsr = s->msr;
270
271 s->msr = (flags & CHR_TIOCM_CTS) ? s->msr | UART_MSR_CTS : s->msr & ~UART_MSR_CTS;
272 s->msr = (flags & CHR_TIOCM_DSR) ? s->msr | UART_MSR_DSR : s->msr & ~UART_MSR_DSR;
273 s->msr = (flags & CHR_TIOCM_CAR) ? s->msr | UART_MSR_DCD : s->msr & ~UART_MSR_DCD;
274 s->msr = (flags & CHR_TIOCM_RI) ? s->msr | UART_MSR_RI : s->msr & ~UART_MSR_RI;
275
276 if (s->msr != omsr) {
277
278 s->msr = s->msr | ((s->msr >> 4) ^ (omsr >> 4));
279
280 if ((s->msr & UART_MSR_TERI) && !(omsr & UART_MSR_RI))
281 s->msr &= ~UART_MSR_TERI;
282 serial_update_irq(s);
283 }
284
285
286
287
288 if (s->poll_msl)
289 qemu_mod_timer(s->modem_status_poll, qemu_get_clock(vm_clock) + ticks_per_sec / 100);
290}
291
292static void serial_xmit(void *opaque)
293{
294 SerialState *s = opaque;
295 uint64_t new_xmit_ts = qemu_get_clock(vm_clock);
296
297 if (s->tsr_retry <= 0) {
298 if (s->fcr & UART_FCR_FE) {
299 s->tsr = fifo_get(s,XMIT_FIFO);
300 if (!s->xmit_fifo.count)
301 s->lsr |= UART_LSR_THRE;
302 } else {
303 s->tsr = s->thr;
304 s->lsr |= UART_LSR_THRE;
305 }
306 }
307
308 if (s->mcr & UART_MCR_LOOP) {
309
310 serial_receive1(s, &s->tsr, 1);
311 } else if (qemu_chr_write(s->chr, &s->tsr, 1) != 1) {
312 if ((s->tsr_retry > 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) {
313 s->tsr_retry++;
314 qemu_mod_timer(s->transmit_timer, new_xmit_ts + s->char_transmit_time);
315 return;
316 } else if (s->poll_msl < 0) {
317
318
319
320 s->tsr_retry = -1;
321 }
322 }
323 else {
324 s->tsr_retry = 0;
325 }
326
327 s->last_xmit_ts = qemu_get_clock(vm_clock);
328 if (!(s->lsr & UART_LSR_THRE))
329 qemu_mod_timer(s->transmit_timer, s->last_xmit_ts + s->char_transmit_time);
330
331 if (s->lsr & UART_LSR_THRE) {
332 s->lsr |= UART_LSR_TEMT;
333 s->thr_ipending = 1;
334 serial_update_irq(s);
335 }
336}
337
338
339static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
340{
341 SerialState *s = opaque;
342
343 addr &= 7;
344#ifdef DEBUG_SERIAL
345 printf("serial: write addr=0x%02x val=0x%02x\n", addr, val);
346#endif
347 switch(addr) {
348 default:
349 case 0:
350 if (s->lcr & UART_LCR_DLAB) {
351 s->divider = (s->divider & 0xff00) | val;
352 serial_update_parameters(s);
353 } else {
354 s->thr = (uint8_t) val;
355 if(s->fcr & UART_FCR_FE) {
356 fifo_put(s, XMIT_FIFO, s->thr);
357 s->thr_ipending = 0;
358 s->lsr &= ~UART_LSR_TEMT;
359 s->lsr &= ~UART_LSR_THRE;
360 serial_update_irq(s);
361 } else {
362 s->thr_ipending = 0;
363 s->lsr &= ~UART_LSR_THRE;
364 serial_update_irq(s);
365 }
366 serial_xmit(s);
367 }
368 break;
369 case 1:
370 if (s->lcr & UART_LCR_DLAB) {
371 s->divider = (s->divider & 0x00ff) | (val << 8);
372 serial_update_parameters(s);
373 } else {
374 s->ier = val & 0x0f;
375
376
377 if (s->poll_msl >= 0) {
378 if (s->ier & UART_IER_MSI) {
379 s->poll_msl = 1;
380 serial_update_msl(s);
381 } else {
382 qemu_del_timer(s->modem_status_poll);
383 s->poll_msl = 0;
384 }
385 }
386 if (s->lsr & UART_LSR_THRE) {
387 s->thr_ipending = 1;
388 serial_update_irq(s);
389 }
390 }
391 break;
392 case 2:
393 val = val & 0xFF;
394
395 if (s->fcr == val)
396 break;
397
398
399 if ((val ^ s->fcr) & UART_FCR_FE)
400 val |= UART_FCR_XFR | UART_FCR_RFR;
401
402
403
404 if (val & UART_FCR_RFR) {
405 qemu_del_timer(s->fifo_timeout_timer);
406 s->timeout_ipending=0;
407 fifo_clear(s,RECV_FIFO);
408 }
409
410 if (val & UART_FCR_XFR) {
411 fifo_clear(s,XMIT_FIFO);
412 }
413
414 if (val & UART_FCR_FE) {
415 s->iir |= UART_IIR_FE;
416
417 switch (val & 0xC0) {
418 case UART_FCR_ITL_1:
419 s->recv_fifo.itl = 1;
420 break;
421 case UART_FCR_ITL_2:
422 s->recv_fifo.itl = 4;
423 break;
424 case UART_FCR_ITL_3:
425 s->recv_fifo.itl = 8;
426 break;
427 case UART_FCR_ITL_4:
428 s->recv_fifo.itl = 14;
429 break;
430 }
431 } else
432 s->iir &= ~UART_IIR_FE;
433
434
435 s->fcr = val & 0xC9;
436 serial_update_irq(s);
437 break;
438 case 3:
439 {
440 int break_enable;
441 s->lcr = val;
442 serial_update_parameters(s);
443 break_enable = (val >> 6) & 1;
444 if (break_enable != s->last_break_enable) {
445 s->last_break_enable = break_enable;
446 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
447 &break_enable);
448 }
449 }
450 break;
451 case 4:
452 {
453 int flags;
454 int old_mcr = s->mcr;
455 s->mcr = val & 0x1f;
456 if (val & UART_MCR_LOOP)
457 break;
458
459 if (s->poll_msl >= 0 && old_mcr != s->mcr) {
460
461 qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
462
463 flags &= ~(CHR_TIOCM_RTS | CHR_TIOCM_DTR);
464
465 if (val & UART_MCR_RTS)
466 flags |= CHR_TIOCM_RTS;
467 if (val & UART_MCR_DTR)
468 flags |= CHR_TIOCM_DTR;
469
470 qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
471
472
473 qemu_mod_timer(s->modem_status_poll, qemu_get_clock(vm_clock) + s->char_transmit_time);
474 }
475 }
476 break;
477 case 5:
478 break;
479 case 6:
480 break;
481 case 7:
482 s->scr = val;
483 break;
484 }
485}
486
487static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
488{
489 SerialState *s = opaque;
490 uint32_t ret;
491
492 addr &= 7;
493 switch(addr) {
494 default:
495 case 0:
496 if (s->lcr & UART_LCR_DLAB) {
497 ret = s->divider & 0xff;
498 } else {
499 if(s->fcr & UART_FCR_FE) {
500 ret = fifo_get(s,RECV_FIFO);
501 if (s->recv_fifo.count == 0)
502 s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
503 else
504 qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock (vm_clock) + s->char_transmit_time * 4);
505 s->timeout_ipending = 0;
506 } else {
507 ret = s->rbr;
508 s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
509 }
510 serial_update_irq(s);
511 if (!(s->mcr & UART_MCR_LOOP)) {
512
513 qemu_chr_accept_input(s->chr);
514 }
515 }
516 break;
517 case 1:
518 if (s->lcr & UART_LCR_DLAB) {
519 ret = (s->divider >> 8) & 0xff;
520 } else {
521 ret = s->ier;
522 }
523 break;
524 case 2:
525 ret = s->iir;
526 s->thr_ipending = 0;
527 serial_update_irq(s);
528 break;
529 case 3:
530 ret = s->lcr;
531 break;
532 case 4:
533 ret = s->mcr;
534 break;
535 case 5:
536 ret = s->lsr;
537
538 if (s->lsr & UART_LSR_BI) {
539 s->lsr &= ~UART_LSR_BI;
540 serial_update_irq(s);
541 }
542 break;
543 case 6:
544 if (s->mcr & UART_MCR_LOOP) {
545
546
547 ret = (s->mcr & 0x0c) << 4;
548 ret |= (s->mcr & 0x02) << 3;
549 ret |= (s->mcr & 0x01) << 5;
550 } else {
551 if (s->poll_msl >= 0)
552 serial_update_msl(s);
553 ret = s->msr;
554
555 if (s->msr & UART_MSR_ANY_DELTA) {
556 s->msr &= 0xF0;
557 serial_update_irq(s);
558 }
559 }
560 break;
561 case 7:
562 ret = s->scr;
563 break;
564 }
565#ifdef DEBUG_SERIAL
566 printf("serial: read addr=0x%02x val=0x%02x\n", addr, ret);
567#endif
568 return ret;
569}
570
571static int serial_can_receive(SerialState *s)
572{
573 if(s->fcr & UART_FCR_FE) {
574 if(s->recv_fifo.count < UART_FIFO_LENGTH)
575
576
577
578 return (s->recv_fifo.count <= s->recv_fifo.itl) ? s->recv_fifo.itl - s->recv_fifo.count : 1;
579 else
580 return 0;
581 } else {
582 return !(s->lsr & UART_LSR_DR);
583 }
584}
585
586static void serial_receive_break(SerialState *s)
587{
588 s->rbr = 0;
589
590 fifo_put(s, RECV_FIFO, '\0');
591 s->lsr |= UART_LSR_BI | UART_LSR_DR;
592 serial_update_irq(s);
593}
594
595
596static void fifo_timeout_int (void *opaque) {
597 SerialState *s = opaque;
598 if (s->recv_fifo.count) {
599 s->timeout_ipending = 1;
600 serial_update_irq(s);
601 }
602}
603
604static int serial_can_receive1(void *opaque)
605{
606 SerialState *s = opaque;
607 return serial_can_receive(s);
608}
609
610static void serial_receive1(void *opaque, const uint8_t *buf, int size)
611{
612 SerialState *s = opaque;
613 if(s->fcr & UART_FCR_FE) {
614 int i;
615 for (i = 0; i < size; i++) {
616 fifo_put(s, RECV_FIFO, buf[i]);
617 }
618 s->lsr |= UART_LSR_DR;
619
620 qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock (vm_clock) + s->char_transmit_time * 4);
621 } else {
622 s->rbr = buf[0];
623 s->lsr |= UART_LSR_DR;
624 }
625 serial_update_irq(s);
626}
627
628static void serial_event(void *opaque, int event)
629{
630 SerialState *s = opaque;
631#ifdef DEBUG_SERIAL
632 printf("serial: event %x\n", event);
633#endif
634 if (event == CHR_EVENT_BREAK)
635 serial_receive_break(s);
636}
637
638static void serial_save(QEMUFile *f, void *opaque)
639{
640 SerialState *s = opaque;
641
642 qemu_put_be16s(f,&s->divider);
643 qemu_put_8s(f,&s->rbr);
644 qemu_put_8s(f,&s->ier);
645 qemu_put_8s(f,&s->iir);
646 qemu_put_8s(f,&s->lcr);
647 qemu_put_8s(f,&s->mcr);
648 qemu_put_8s(f,&s->lsr);
649 qemu_put_8s(f,&s->msr);
650 qemu_put_8s(f,&s->scr);
651 qemu_put_8s(f,&s->fcr);
652}
653
654static int serial_load(QEMUFile *f, void *opaque, int version_id)
655{
656 SerialState *s = opaque;
657 uint8_t fcr = 0;
658
659 if(version_id > 3)
660 return -EINVAL;
661
662 if (version_id >= 2)
663 qemu_get_be16s(f, &s->divider);
664 else
665 s->divider = qemu_get_byte(f);
666 qemu_get_8s(f,&s->rbr);
667 qemu_get_8s(f,&s->ier);
668 qemu_get_8s(f,&s->iir);
669 qemu_get_8s(f,&s->lcr);
670 qemu_get_8s(f,&s->mcr);
671 qemu_get_8s(f,&s->lsr);
672 qemu_get_8s(f,&s->msr);
673 qemu_get_8s(f,&s->scr);
674
675 if (version_id >= 3)
676 qemu_get_8s(f,&fcr);
677
678
679 serial_ioport_write(s, 0x02, fcr);
680 return 0;
681}
682
683static void serial_reset(void *opaque)
684{
685 SerialState *s = opaque;
686
687 s->rbr = 0;
688 s->ier = 0;
689 s->iir = UART_IIR_NO_INT;
690 s->lcr = 0;
691 s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
692 s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
693
694 s->divider = 0x0C;
695 s->mcr = UART_MCR_OUT2;
696 s->scr = 0;
697 s->tsr_retry = 0;
698 s->char_transmit_time = (ticks_per_sec / 9600) * 9;
699 s->poll_msl = 0;
700
701 fifo_clear(s,RECV_FIFO);
702 fifo_clear(s,XMIT_FIFO);
703
704 s->last_xmit_ts = qemu_get_clock(vm_clock);
705
706 s->thr_ipending = 0;
707 s->last_break_enable = 0;
708 qemu_irq_lower(s->irq);
709}
710
711static void serial_init_core(SerialState *s, qemu_irq irq, int baudbase,
712 CharDriverState *chr)
713{
714 s->irq = irq;
715 s->baudbase = baudbase;
716 s->chr = chr ?: qemu_chr_open("null", "null", NULL);
717
718 s->modem_status_poll = qemu_new_timer(vm_clock, (QEMUTimerCB *) serial_update_msl, s);
719
720 s->fifo_timeout_timer = qemu_new_timer(vm_clock, (QEMUTimerCB *) fifo_timeout_int, s);
721 s->transmit_timer = qemu_new_timer(vm_clock, (QEMUTimerCB *) serial_xmit, s);
722
723 qemu_register_reset(serial_reset, s);
724 serial_reset(s);
725
726 qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
727 serial_event, s);
728}
729
730
731SerialState *serial_init(int base, qemu_irq irq, int baudbase,
732 CharDriverState *chr)
733{
734 SerialState *s;
735
736 s = qemu_mallocz(sizeof(SerialState));
737
738 serial_init_core(s, irq, baudbase, chr);
739
740 register_savevm("serial", base, 3, serial_save, serial_load, s);
741
742 register_ioport_write(base, 8, 1, serial_ioport_write, s);
743 register_ioport_read(base, 8, 1, serial_ioport_read, s);
744 return s;
745}
746
747
748uint32_t serial_mm_readb (void *opaque, target_phys_addr_t addr)
749{
750 SerialState *s = opaque;
751
752 return serial_ioport_read(s, addr >> s->it_shift) & 0xFF;
753}
754
755void serial_mm_writeb (void *opaque,
756 target_phys_addr_t addr, uint32_t value)
757{
758 SerialState *s = opaque;
759
760 serial_ioport_write(s, addr >> s->it_shift, value & 0xFF);
761}
762
763uint32_t serial_mm_readw (void *opaque, target_phys_addr_t addr)
764{
765 SerialState *s = opaque;
766 uint32_t val;
767
768 val = serial_ioport_read(s, addr >> s->it_shift) & 0xFFFF;
769#ifdef TARGET_WORDS_BIGENDIAN
770 val = bswap16(val);
771#endif
772 return val;
773}
774
775void serial_mm_writew (void *opaque,
776 target_phys_addr_t addr, uint32_t value)
777{
778 SerialState *s = opaque;
779#ifdef TARGET_WORDS_BIGENDIAN
780 value = bswap16(value);
781#endif
782 serial_ioport_write(s, addr >> s->it_shift, value & 0xFFFF);
783}
784
785uint32_t serial_mm_readl (void *opaque, target_phys_addr_t addr)
786{
787 SerialState *s = opaque;
788 uint32_t val;
789
790 val = serial_ioport_read(s, addr >> s->it_shift);
791#ifdef TARGET_WORDS_BIGENDIAN
792 val = bswap32(val);
793#endif
794 return val;
795}
796
797void serial_mm_writel (void *opaque,
798 target_phys_addr_t addr, uint32_t value)
799{
800 SerialState *s = opaque;
801#ifdef TARGET_WORDS_BIGENDIAN
802 value = bswap32(value);
803#endif
804 serial_ioport_write(s, addr >> s->it_shift, value);
805}
806
807static CPUReadMemoryFunc *serial_mm_read[] = {
808 &serial_mm_readb,
809 &serial_mm_readw,
810 &serial_mm_readl,
811};
812
813static CPUWriteMemoryFunc *serial_mm_write[] = {
814 &serial_mm_writeb,
815 &serial_mm_writew,
816 &serial_mm_writel,
817};
818
819SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
820 qemu_irq irq, int baudbase,
821 CharDriverState *chr, int ioregister)
822{
823 SerialState *s;
824 int s_io_memory;
825
826 s = qemu_mallocz(sizeof(SerialState));
827
828 s->it_shift = it_shift;
829
830 serial_init_core(s, irq, baudbase, chr);
831 register_savevm("serial", base, 3, serial_save, serial_load, s);
832
833 if (ioregister) {
834 s_io_memory = cpu_register_io_memory(serial_mm_read,
835 serial_mm_write, s);
836 cpu_register_physical_memory(base, 8 << it_shift, s_io_memory);
837 }
838 serial_update_msl(s);
839 return s;
840}
841