Commit 81174dae3f9189519cd60c7b79e91c291b021bbe

Authored by aliguori
1 parent 06057e6f

Upgrade emulated UART to 16550A (Stefano Stabellini)

This patch upgrades the emulated UART to 16550A, the code comes from
xen-unstable. The main improvement was introduced with the following patch and
subsequent email thread:

http://lists.xensource.com/archives/html/xen-devel/2007-12/msg00129.html

The changes compared to previous version are:

- change clock_gettime to qemu_get_clock

- no token bucket anymore;

- fixed a small bug handling IRQs; this was the problem that prevented
kgdb to work over the serial (thanks to Jason Wessel for the help
spotting and reproducing this bug).

- many many style fixes;

- savevm version number increased;

- not including termios.h and sys/ioctl.h anymore, declaring static
constants in qemu-char.h instead;

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4993 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 3 changed files with 433 additions and 94 deletions
hw/serial.c
1 1 /*
2   - * QEMU 16450 UART emulation
  2 + * QEMU 16550A UART emulation
3 3 *
4 4 * Copyright (c) 2003-2004 Fabrice Bellard
  5 + * Copyright (c) 2008 Citrix Systems, Inc.
5 6 *
6 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 8 * of this software and associated documentation files (the "Software"), to deal
... ... @@ -43,6 +44,10 @@
43 44 #define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
44 45 #define UART_IIR_RDI 0x04 /* Receiver data interrupt */
45 46 #define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
  47 +#define UART_IIR_CTI 0x0C /* Character Timeout Indication */
  48 +
  49 +#define UART_IIR_FENF 0x80 /* Fifo enabled, but not functionning */
  50 +#define UART_IIR_FE 0xC0 /* Fifo enabled */
46 51  
47 52 /*
48 53 * These are the definitions for the Modem Control Register
... ... @@ -73,17 +78,39 @@
73 78 #define UART_LSR_PE 0x04 /* Parity error indicator */
74 79 #define UART_LSR_OE 0x02 /* Overrun error indicator */
75 80 #define UART_LSR_DR 0x01 /* Receiver data ready */
  81 +#define UART_LSR_INT_ANY 0x1E /* Any of the lsr-interrupt-triggering status bits */
76 82  
77   -/*
78   - * Delay TX IRQ after sending as much characters as the given interval would
79   - * contain on real hardware. This avoids overloading the guest if it processes
80   - * its output buffer in a loop inside the TX IRQ handler.
81   - */
82   -#define THROTTLE_TX_INTERVAL 10 /* ms */
  83 +/* Interrupt trigger levels. The byte-counts are for 16550A - in newer UARTs the byte-count for each ITL is higher. */
  84 +
  85 +#define UART_FCR_ITL_1 0x00 /* 1 byte ITL */
  86 +#define UART_FCR_ITL_2 0x40 /* 4 bytes ITL */
  87 +#define UART_FCR_ITL_3 0x80 /* 8 bytes ITL */
  88 +#define UART_FCR_ITL_4 0xC0 /* 14 bytes ITL */
  89 +
  90 +#define UART_FCR_DMS 0x08 /* DMA Mode Select */
  91 +#define UART_FCR_XFR 0x04 /* XMIT Fifo Reset */
  92 +#define UART_FCR_RFR 0x02 /* RCVR Fifo Reset */
  93 +#define UART_FCR_FE 0x01 /* FIFO Enable */
  94 +
  95 +#define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */
  96 +
  97 +#define XMIT_FIFO 0
  98 +#define RECV_FIFO 1
  99 +#define MAX_XMIT_RETRY 4
  100 +
  101 +struct SerialFIFO {
  102 + uint8_t data[UART_FIFO_LENGTH];
  103 + uint8_t count;
  104 + uint8_t itl; /* Interrupt Trigger Level */
  105 + uint8_t tail;
  106 + uint8_t head;
  107 +} typedef SerialFIFO;
83 108  
84 109 struct SerialState {
85 110 uint16_t divider;
86 111 uint8_t rbr; /* receive register */
  112 + uint8_t thr; /* transmit holding register */
  113 + uint8_t tsr; /* transmit shift register */
87 114 uint8_t ier;
88 115 uint8_t iir; /* read only */
89 116 uint8_t lcr;
... ... @@ -91,6 +118,7 @@ struct SerialState {
91 118 uint8_t lsr; /* read only */
92 119 uint8_t msr; /* read only */
93 120 uint8_t scr;
  121 + uint8_t fcr;
94 122 /* NOTE: this hidden state is necessary for tx irq generation as
95 123 it can be reset while reading iir */
96 124 int thr_ipending;
... ... @@ -100,55 +128,106 @@ struct SerialState {
100 128 target_phys_addr_t base;
101 129 int it_shift;
102 130 int baudbase;
103   - QEMUTimer *tx_timer;
104   - int tx_burst;
  131 + int tsr_retry;
  132 +
  133 + uint64_t last_xmit_ts; /* Time when the last byte was successfully sent out of the tsr */
  134 + SerialFIFO recv_fifo;
  135 + SerialFIFO xmit_fifo;
  136 +
  137 + struct QEMUTimer *fifo_timeout_timer;
  138 + int timeout_ipending; /* timeout interrupt pending state */
  139 + struct QEMUTimer *transmit_timer;
  140 +
  141 +
  142 + uint64_t char_transmit_time; /* time to transmit a char in ticks*/
  143 + int poll_msl;
  144 +
  145 + struct QEMUTimer *modem_status_poll;
105 146 };
106 147  
107   -static void serial_receive_byte(SerialState *s, int ch);
  148 +static void serial_receive1(void *opaque, const uint8_t *buf, int size);
108 149  
109   -static void serial_update_irq(SerialState *s)
  150 +static void fifo_clear(SerialState *s, int fifo)
110 151 {
111   - if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) {
112   - s->iir = UART_IIR_RDI;
113   - } else if (s->thr_ipending && (s->ier & UART_IER_THRI)) {
114   - s->iir = UART_IIR_THRI;
115   - } else {
116   - s->iir = UART_IIR_NO_INT;
117   - }
118   - if (s->iir != UART_IIR_NO_INT) {
119   - qemu_irq_raise(s->irq);
120   - } else {
121   - qemu_irq_lower(s->irq);
122   - }
  152 + SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
  153 + memset(f->data, 0, UART_FIFO_LENGTH);
  154 + f->count = 0;
  155 + f->head = 0;
  156 + f->tail = 0;
123 157 }
124 158  
125   -static void serial_tx_done(void *opaque)
  159 +static int fifo_put(SerialState *s, int fifo, uint8_t chr)
126 160 {
127   - SerialState *s = opaque;
  161 + SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
128 162  
129   - if (s->tx_burst < 0) {
130   - uint16_t divider;
  163 + f->data[f->head++] = chr;
131 164  
132   - if (s->divider)
133   - divider = s->divider;
134   - else
135   - divider = 1;
  165 + if (f->head == UART_FIFO_LENGTH)
  166 + f->head = 0;
  167 + f->count++;
  168 +
  169 + return 1;
  170 +}
  171 +
  172 +static uint8_t fifo_get(SerialState *s, int fifo)
  173 +{
  174 + SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
  175 + uint8_t c;
  176 +
  177 + if(f->count == 0)
  178 + return 0;
  179 +
  180 + c = f->data[f->tail++];
  181 + if (f->tail == UART_FIFO_LENGTH)
  182 + f->tail = 0;
  183 + f->count--;
  184 +
  185 + return c;
  186 +}
136 187  
137   - /* We assume 10 bits/char, OK for this purpose. */
138   - s->tx_burst = THROTTLE_TX_INTERVAL * 1000 /
139   - (1000000 * 10 / (s->baudbase / divider));
  188 +static void serial_update_irq(SerialState *s)
  189 +{
  190 + uint8_t tmp_iir = UART_IIR_NO_INT;
  191 +
  192 + if (!s->ier) {
  193 + qemu_irq_lower(s->irq);
  194 + return;
  195 + }
  196 +
  197 + if ((s->ier & UART_IER_RLSI) && (s->lsr & UART_LSR_INT_ANY)) {
  198 + tmp_iir = UART_IIR_RLSI;
  199 + } else if (s->timeout_ipending) {
  200 + tmp_iir = UART_IIR_CTI;
  201 + } else if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR)) {
  202 + if (!(s->fcr & UART_FCR_FE)) {
  203 + tmp_iir = UART_IIR_RDI;
  204 + } else if (s->recv_fifo.count >= s->recv_fifo.itl) {
  205 + tmp_iir = UART_IIR_RDI;
  206 + }
  207 + } else if ((s->ier & UART_IER_THRI) && s->thr_ipending) {
  208 + tmp_iir = UART_IIR_THRI;
  209 + } else if ((s->ier & UART_IER_MSI) && (s->msr & UART_MSR_ANY_DELTA)) {
  210 + tmp_iir = UART_IIR_MSI;
  211 + }
  212 +
  213 + s->iir = tmp_iir | (s->iir & 0xF0);
  214 +
  215 + if (tmp_iir != UART_IIR_NO_INT) {
  216 + qemu_irq_raise(s->irq);
  217 + } else {
  218 + qemu_irq_lower(s->irq);
140 219 }
141   - s->thr_ipending = 1;
142   - s->lsr |= UART_LSR_THRE;
143   - s->lsr |= UART_LSR_TEMT;
144   - serial_update_irq(s);
145 220 }
146 221  
147 222 static void serial_update_parameters(SerialState *s)
148 223 {
149   - int speed, parity, data_bits, stop_bits;
  224 + int speed, parity, data_bits, stop_bits, frame_size;
150 225 QEMUSerialSetParams ssp;
151 226  
  227 + if (s->divider == 0)
  228 + return;
  229 +
  230 + frame_size = 1;
152 231 if (s->lcr & 0x08) {
153 232 if (s->lcr & 0x10)
154 233 parity = 'E';
... ... @@ -156,19 +235,21 @@ static void serial_update_parameters(SerialState *s)
156 235 parity = 'O';
157 236 } else {
158 237 parity = 'N';
  238 + frame_size = 0;
159 239 }
160 240 if (s->lcr & 0x04)
161 241 stop_bits = 2;
162 242 else
163 243 stop_bits = 1;
  244 +
164 245 data_bits = (s->lcr & 0x03) + 5;
165   - if (s->divider == 0)
166   - return;
  246 + frame_size += data_bits + stop_bits;
167 247 speed = s->baudbase / s->divider;
168 248 ssp.speed = speed;
169 249 ssp.parity = parity;
170 250 ssp.data_bits = data_bits;
171 251 ssp.stop_bits = stop_bits;
  252 + s->char_transmit_time = (ticks_per_sec / speed) * frame_size;
172 253 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
173 254 #if 0
174 255 printf("speed=%d parity=%c data=%d stop=%d\n",
... ... @@ -176,10 +257,91 @@ static void serial_update_parameters(SerialState *s)
176 257 #endif
177 258 }
178 259  
  260 +static void serial_update_msl(SerialState *s)
  261 +{
  262 + uint8_t omsr;
  263 + int flags;
  264 +
  265 + qemu_del_timer(s->modem_status_poll);
  266 +
  267 + if (qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) {
  268 + s->poll_msl = -1;
  269 + return;
  270 + }
  271 +
  272 + omsr = s->msr;
  273 +
  274 + s->msr = (flags & CHR_TIOCM_CTS) ? s->msr | UART_MSR_CTS : s->msr & ~UART_MSR_CTS;
  275 + s->msr = (flags & CHR_TIOCM_DSR) ? s->msr | UART_MSR_DSR : s->msr & ~UART_MSR_DSR;
  276 + s->msr = (flags & CHR_TIOCM_CAR) ? s->msr | UART_MSR_DCD : s->msr & ~UART_MSR_DCD;
  277 + s->msr = (flags & CHR_TIOCM_RI) ? s->msr | UART_MSR_RI : s->msr & ~UART_MSR_RI;
  278 +
  279 + if (s->msr != omsr) {
  280 + /* Set delta bits */
  281 + s->msr = s->msr | ((s->msr >> 4) ^ (omsr >> 4));
  282 + /* UART_MSR_TERI only if change was from 1 -> 0 */
  283 + if ((s->msr & UART_MSR_TERI) && !(omsr & UART_MSR_RI))
  284 + s->msr &= ~UART_MSR_TERI;
  285 + serial_update_irq(s);
  286 + }
  287 +
  288 + /* The real 16550A apparently has a 250ns response latency to line status changes.
  289 + We'll be lazy and poll only every 10ms, and only poll it at all if MSI interrupts are turned on */
  290 +
  291 + if (s->poll_msl)
  292 + qemu_mod_timer(s->modem_status_poll, qemu_get_clock(vm_clock) + ticks_per_sec / 100);
  293 +}
  294 +
  295 +static void serial_xmit(void *opaque)
  296 +{
  297 + SerialState *s = opaque;
  298 + uint64_t new_xmit_ts = qemu_get_clock(vm_clock);
  299 +
  300 + if (s->tsr_retry <= 0) {
  301 + if (s->fcr & UART_FCR_FE) {
  302 + s->tsr = fifo_get(s,XMIT_FIFO);
  303 + if (!s->xmit_fifo.count)
  304 + s->lsr |= UART_LSR_THRE;
  305 + } else {
  306 + s->tsr = s->thr;
  307 + s->lsr |= UART_LSR_THRE;
  308 + }
  309 + }
  310 +
  311 + if (s->mcr & UART_MCR_LOOP) {
  312 + /* in loopback mode, say that we just received a char */
  313 + serial_receive1(s, &s->tsr, 1);
  314 + } else if (qemu_chr_write(s->chr, &s->tsr, 1) != 1) {
  315 + if ((s->tsr_retry > 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) {
  316 + s->tsr_retry++;
  317 + qemu_mod_timer(s->transmit_timer, new_xmit_ts + s->char_transmit_time);
  318 + return;
  319 + } else if (s->poll_msl < 0) {
  320 + /* If we exceed MAX_XMIT_RETRY and the backend is not a real serial port, then
  321 + drop any further failed writes instantly, until we get one that goes through.
  322 + This is to prevent guests that log to unconnected pipes or pty's from stalling. */
  323 + s->tsr_retry = -1;
  324 + }
  325 + }
  326 + else {
  327 + s->tsr_retry = 0;
  328 + }
  329 +
  330 + s->last_xmit_ts = qemu_get_clock(vm_clock);
  331 + if (!(s->lsr & UART_LSR_THRE))
  332 + qemu_mod_timer(s->transmit_timer, s->last_xmit_ts + s->char_transmit_time);
  333 +
  334 + if (s->lsr & UART_LSR_THRE) {
  335 + s->lsr |= UART_LSR_TEMT;
  336 + s->thr_ipending = 1;
  337 + serial_update_irq(s);
  338 + }
  339 +}
  340 +
  341 +
179 342 static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
180 343 {
181 344 SerialState *s = opaque;
182   - unsigned char ch;
183 345  
184 346 addr &= 7;
185 347 #ifdef DEBUG_SERIAL
... ... @@ -192,25 +354,19 @@ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
192 354 s->divider = (s->divider & 0xff00) | val;
193 355 serial_update_parameters(s);
194 356 } else {
  357 + s->thr = (uint8_t) val;
  358 + if(s->fcr & UART_FCR_FE) {
  359 + fifo_put(s, XMIT_FIFO, s->thr);
195 360 s->thr_ipending = 0;
  361 + s->lsr &= ~UART_LSR_TEMT;
196 362 s->lsr &= ~UART_LSR_THRE;
197 363 serial_update_irq(s);
198   - ch = val;
199   - if (!(s->mcr & UART_MCR_LOOP)) {
200   - /* when not in loopback mode, send the char */
201   - qemu_chr_write(s->chr, &ch, 1);
202 364 } else {
203   - /* in loopback mode, say that we just received a char */
204   - serial_receive_byte(s, ch);
205   - }
206   - if (s->tx_burst > 0) {
207   - s->tx_burst--;
208   - serial_tx_done(s);
209   - } else if (s->tx_burst == 0) {
210   - s->tx_burst--;
211   - qemu_mod_timer(s->tx_timer, qemu_get_clock(vm_clock) +
212   - ticks_per_sec * THROTTLE_TX_INTERVAL / 1000);
  365 + s->thr_ipending = 0;
  366 + s->lsr &= ~UART_LSR_THRE;
  367 + serial_update_irq(s);
213 368 }
  369 + serial_xmit(s);
214 370 }
215 371 break;
216 372 case 1:
... ... @@ -219,13 +375,68 @@ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
219 375 serial_update_parameters(s);
220 376 } else {
221 377 s->ier = val & 0x0f;
  378 + /* If the backend device is a real serial port, turn polling of the modem
  379 + status lines on physical port on or off depending on UART_IER_MSI state */
  380 + if (s->poll_msl >= 0) {
  381 + if (s->ier & UART_IER_MSI) {
  382 + s->poll_msl = 1;
  383 + serial_update_msl(s);
  384 + } else {
  385 + qemu_del_timer(s->modem_status_poll);
  386 + s->poll_msl = 0;
  387 + }
  388 + }
222 389 if (s->lsr & UART_LSR_THRE) {
223 390 s->thr_ipending = 1;
  391 + serial_update_irq(s);
224 392 }
225   - serial_update_irq(s);
226 393 }
227 394 break;
228 395 case 2:
  396 + val = val & 0xFF;
  397 +
  398 + if (s->fcr == val)
  399 + break;
  400 +
  401 + /* Did the enable/disable flag change? If so, make sure FIFOs get flushed */
  402 + if ((val ^ s->fcr) & UART_FCR_FE)
  403 + val |= UART_FCR_XFR | UART_FCR_RFR;
  404 +
  405 + /* FIFO clear */
  406 +
  407 + if (val & UART_FCR_RFR) {
  408 + qemu_del_timer(s->fifo_timeout_timer);
  409 + s->timeout_ipending=0;
  410 + fifo_clear(s,RECV_FIFO);
  411 + }
  412 +
  413 + if (val & UART_FCR_XFR) {
  414 + fifo_clear(s,XMIT_FIFO);
  415 + }
  416 +
  417 + if (val & UART_FCR_FE) {
  418 + s->iir |= UART_IIR_FE;
  419 + /* Set RECV_FIFO trigger Level */
  420 + switch (val & 0xC0) {
  421 + case UART_FCR_ITL_1:
  422 + s->recv_fifo.itl = 1;
  423 + break;
  424 + case UART_FCR_ITL_2:
  425 + s->recv_fifo.itl = 4;
  426 + break;
  427 + case UART_FCR_ITL_3:
  428 + s->recv_fifo.itl = 8;
  429 + break;
  430 + case UART_FCR_ITL_4:
  431 + s->recv_fifo.itl = 14;
  432 + break;
  433 + }
  434 + } else
  435 + s->iir &= ~UART_IIR_FE;
  436 +
  437 + /* Set fcr - or at least the bits in it that are supposed to "stick" */
  438 + s->fcr = val & 0xC9;
  439 + serial_update_irq(s);
229 440 break;
230 441 case 3:
231 442 {
... ... @@ -241,7 +452,30 @@ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
241 452 }
242 453 break;
243 454 case 4:
244   - s->mcr = val & 0x1f;
  455 + {
  456 + int flags;
  457 + int old_mcr = s->mcr;
  458 + s->mcr = val & 0x1f;
  459 + if (val & UART_MCR_LOOP)
  460 + break;
  461 +
  462 + if (s->poll_msl >= 0 && old_mcr != s->mcr) {
  463 +
  464 + qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
  465 +
  466 + flags &= ~(CHR_TIOCM_RTS | CHR_TIOCM_DTR);
  467 +
  468 + if (val & UART_MCR_RTS)
  469 + flags |= CHR_TIOCM_RTS;
  470 + if (val & UART_MCR_DTR)
  471 + flags |= CHR_TIOCM_DTR;
  472 +
  473 + qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
  474 + /* Update the modem status after a one-character-send wait-time, since there may be a response
  475 + from the device/computer at the other end of the serial line */
  476 + qemu_mod_timer(s->modem_status_poll, qemu_get_clock(vm_clock) + s->char_transmit_time);
  477 + }
  478 + }
245 479 break;
246 480 case 5:
247 481 break;
... ... @@ -265,8 +499,17 @@ static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
265 499 if (s->lcr & UART_LCR_DLAB) {
266 500 ret = s->divider & 0xff;
267 501 } else {
268   - ret = s->rbr;
269   - s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
  502 + if(s->fcr & UART_FCR_FE) {
  503 + ret = fifo_get(s,RECV_FIFO);
  504 + if (s->recv_fifo.count == 0)
  505 + s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
  506 + else
  507 + qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock (vm_clock) + s->char_transmit_time * 4);
  508 + s->timeout_ipending = 0;
  509 + } else {
  510 + ret = s->rbr;
  511 + s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
  512 + }
270 513 serial_update_irq(s);
271 514 if (!(s->mcr & UART_MCR_LOOP)) {
272 515 /* in loopback mode, don't receive any data */
... ... @@ -283,8 +526,6 @@ static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
283 526 break;
284 527 case 2:
285 528 ret = s->iir;
286   - /* reset THR pending bit */
287   - if ((ret & 0x7) == UART_IIR_THRI)
288 529 s->thr_ipending = 0;
289 530 serial_update_irq(s);
290 531 break;
... ... @@ -296,6 +537,11 @@ static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
296 537 break;
297 538 case 5:
298 539 ret = s->lsr;
  540 + /* Clear break interrupt */
  541 + if (s->lsr & UART_LSR_BI) {
  542 + s->lsr &= ~UART_LSR_BI;
  543 + serial_update_irq(s);
  544 + }
299 545 break;
300 546 case 6:
301 547 if (s->mcr & UART_MCR_LOOP) {
... ... @@ -305,7 +551,14 @@ static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
305 551 ret |= (s->mcr & 0x02) << 3;
306 552 ret |= (s->mcr & 0x01) << 5;
307 553 } else {
  554 + if (s->poll_msl >= 0)
  555 + serial_update_msl(s);
308 556 ret = s->msr;
  557 + /* Clear delta bits & msr int after read, if they were set */
  558 + if (s->msr & UART_MSR_ANY_DELTA) {
  559 + s->msr &= 0xF0;
  560 + serial_update_irq(s);
  561 + }
309 562 }
310 563 break;
311 564 case 7:
... ... @@ -320,14 +573,17 @@ static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
320 573  
321 574 static int serial_can_receive(SerialState *s)
322 575 {
  576 + if(s->fcr & UART_FCR_FE) {
  577 + if(s->recv_fifo.count < UART_FIFO_LENGTH)
  578 + /* Advertise (fifo.itl - fifo.count) bytes when count < ITL, and 1 if above. If UART_FIFO_LENGTH - fifo.count is
  579 + advertised the effect will be to almost always fill the fifo completely before the guest has a chance to respond,
  580 + effectively overriding the ITL that the guest has set. */
  581 + return (s->recv_fifo.count <= s->recv_fifo.itl) ? s->recv_fifo.itl - s->recv_fifo.count : 1;
  582 + else
  583 + return 0;
  584 + } else {
323 585 return !(s->lsr & UART_LSR_DR);
324   -}
325   -
326   -static void serial_receive_byte(SerialState *s, int ch)
327   -{
328   - s->rbr = ch;
329   - s->lsr |= UART_LSR_DR;
330   - serial_update_irq(s);
  586 + }
331 587 }
332 588  
333 589 static void serial_receive_break(SerialState *s)
... ... @@ -337,6 +593,15 @@ static void serial_receive_break(SerialState *s)
337 593 serial_update_irq(s);
338 594 }
339 595  
  596 +/* There's data in recv_fifo and s->rbr has not been read for 4 char transmit times */
  597 +static void fifo_timeout_int (void *opaque) {
  598 + SerialState *s = opaque;
  599 + if (s->recv_fifo.count) {
  600 + s->timeout_ipending = 1;
  601 + serial_update_irq(s);
  602 + }
  603 +}
  604 +
340 605 static int serial_can_receive1(void *opaque)
341 606 {
342 607 SerialState *s = opaque;
... ... @@ -346,12 +611,27 @@ static int serial_can_receive1(void *opaque)
346 611 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
347 612 {
348 613 SerialState *s = opaque;
349   - serial_receive_byte(s, buf[0]);
  614 + if(s->fcr & UART_FCR_FE) {
  615 + int i;
  616 + for (i = 0; i < size; i++) {
  617 + fifo_put(s, RECV_FIFO, buf[i]);
  618 + }
  619 + s->lsr |= UART_LSR_DR;
  620 + /* call the timeout receive callback in 4 char transmit time */
  621 + qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock (vm_clock) + s->char_transmit_time * 4);
  622 + } else {
  623 + s->rbr = buf[0];
  624 + s->lsr |= UART_LSR_DR;
  625 + }
  626 + serial_update_irq(s);
350 627 }
351 628  
352 629 static void serial_event(void *opaque, int event)
353 630 {
354 631 SerialState *s = opaque;
  632 +#ifdef DEBUG_SERIAL
  633 + printf("serial: event %x\n", event);
  634 +#endif
355 635 if (event == CHR_EVENT_BREAK)
356 636 serial_receive_break(s);
357 637 }
... ... @@ -369,13 +649,15 @@ static void serial_save(QEMUFile *f, void *opaque)
369 649 qemu_put_8s(f,&s->lsr);
370 650 qemu_put_8s(f,&s->msr);
371 651 qemu_put_8s(f,&s->scr);
  652 + qemu_put_8s(f,&s->fcr);
372 653 }
373 654  
374 655 static int serial_load(QEMUFile *f, void *opaque, int version_id)
375 656 {
376 657 SerialState *s = opaque;
  658 + uint8_t fcr = 0;
377 659  
378   - if(version_id > 2)
  660 + if(version_id > 3)
379 661 return -EINVAL;
380 662  
381 663 if (version_id >= 2)
... ... @@ -391,6 +673,11 @@ static int serial_load(QEMUFile *f, void *opaque, int version_id)
391 673 qemu_get_8s(f,&s->msr);
392 674 qemu_get_8s(f,&s->scr);
393 675  
  676 + if (version_id >= 3)
  677 + qemu_get_8s(f,&fcr);
  678 +
  679 + /* Initialize fcr via setter to perform essential side-effects */
  680 + serial_ioport_write(s, 0x02, fcr);
394 681 return 0;
395 682 }
396 683  
... ... @@ -398,21 +685,47 @@ static void serial_reset(void *opaque)
398 685 {
399 686 SerialState *s = opaque;
400 687  
401   - s->divider = 0;
402 688 s->rbr = 0;
403 689 s->ier = 0;
404 690 s->iir = UART_IIR_NO_INT;
405 691 s->lcr = 0;
406   - s->mcr = 0;
407 692 s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
408 693 s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
  694 + /* Default to 9600 baud, no parity, one stop bit */
  695 + s->divider = 0x0C;
  696 + s->mcr = UART_MCR_OUT2;
409 697 s->scr = 0;
  698 + s->tsr_retry = 0;
  699 + s->char_transmit_time = (ticks_per_sec / 9600) * 9;
  700 + s->poll_msl = 0;
  701 +
  702 + fifo_clear(s,RECV_FIFO);
  703 + fifo_clear(s,XMIT_FIFO);
  704 +
  705 + s->last_xmit_ts = qemu_get_clock(vm_clock);
410 706  
411 707 s->thr_ipending = 0;
412 708 s->last_break_enable = 0;
413 709 qemu_irq_lower(s->irq);
414 710 }
415 711  
  712 +static void serial_init_core(SerialState *s, qemu_irq irq, int baudbase,
  713 + CharDriverState *chr)
  714 +{
  715 + s->irq = irq;
  716 + s->baudbase = baudbase;
  717 + s->chr = chr;
  718 +
  719 + s->modem_status_poll = qemu_new_timer(vm_clock, (QEMUTimerCB *) serial_update_msl, s);
  720 +
  721 + s->fifo_timeout_timer = qemu_new_timer(vm_clock, (QEMUTimerCB *) fifo_timeout_int, s);
  722 + s->transmit_timer = qemu_new_timer(vm_clock, (QEMUTimerCB *) serial_xmit, s);
  723 +
  724 + qemu_register_reset(serial_reset, s);
  725 + serial_reset(s);
  726 +
  727 +}
  728 +
416 729 /* If fd is zero, it means that the serial device uses the console */
417 730 SerialState *serial_init(int base, qemu_irq irq, int baudbase,
418 731 CharDriverState *chr)
... ... @@ -422,21 +735,13 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
422 735 s = qemu_mallocz(sizeof(SerialState));
423 736 if (!s)
424 737 return NULL;
425   - s->irq = irq;
426   - s->baudbase = baudbase;
427   -
428   - s->tx_timer = qemu_new_timer(vm_clock, serial_tx_done, s);
429   - if (!s->tx_timer)
430   - return NULL;
431 738  
432   - qemu_register_reset(serial_reset, s);
433   - serial_reset(s);
  739 + serial_init_core(s, irq, baudbase, chr);
434 740  
435   - register_savevm("serial", base, 2, serial_save, serial_load, s);
  741 + register_savevm("serial", base, 3, serial_save, serial_load, s);
436 742  
437 743 register_ioport_write(base, 8, 1, serial_ioport_write, s);
438 744 register_ioport_read(base, 8, 1, serial_ioport_read, s);
439   - s->chr = chr;
440 745 qemu_chr_add_handlers(chr, serial_can_receive1, serial_receive1,
441 746 serial_event, s);
442 747 return s;
... ... @@ -524,27 +829,20 @@ SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
524 829 s = qemu_mallocz(sizeof(SerialState));
525 830 if (!s)
526 831 return NULL;
527   - s->irq = irq;
  832 +
528 833 s->base = base;
529 834 s->it_shift = it_shift;
530   - s->baudbase= baudbase;
531 835  
532   - s->tx_timer = qemu_new_timer(vm_clock, serial_tx_done, s);
533   - if (!s->tx_timer)
534   - return NULL;
535   -
536   - qemu_register_reset(serial_reset, s);
537   - serial_reset(s);
538   -
539   - register_savevm("serial", base, 2, serial_save, serial_load, s);
  836 + serial_init_core(s, irq, baudbase, chr);
  837 + register_savevm("serial", base, 3, serial_save, serial_load, s);
540 838  
541 839 if (ioregister) {
542 840 s_io_memory = cpu_register_io_memory(0, serial_mm_read,
543 841 serial_mm_write, s);
544 842 cpu_register_physical_memory(base, 8 << it_shift, s_io_memory);
545 843 }
546   - s->chr = chr;
547 844 qemu_chr_add_handlers(chr, serial_can_receive1, serial_receive1,
548 845 serial_event, s);
  846 + serial_update_msl(s);
549 847 return s;
550 848 }
... ...
qemu-char.h
... ... @@ -28,6 +28,16 @@ typedef struct {
28 28 #define CHR_IOCTL_PP_EPP_WRITE_ADDR 10
29 29 #define CHR_IOCTL_PP_EPP_WRITE 11
30 30  
  31 +#define CHR_IOCTL_SERIAL_SET_TIOCM 12
  32 +#define CHR_IOCTL_SERIAL_GET_TIOCM 13
  33 +
  34 +#define CHR_TIOCM_CTS 0x020
  35 +#define CHR_TIOCM_CAR 0x040
  36 +#define CHR_TIOCM_DSR 0x100
  37 +#define CHR_TIOCM_RI 0x080
  38 +#define CHR_TIOCM_DTR 0x002
  39 +#define CHR_TIOCM_RTS 0x004
  40 +
31 41 typedef void IOEventHandler(void *opaque, int event);
32 42  
33 43 struct CharDriverState {
... ...
... ... @@ -2721,6 +2721,37 @@ static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
2721 2721 tcsendbreak(s->fd_in, 1);
2722 2722 }
2723 2723 break;
  2724 + case CHR_IOCTL_SERIAL_GET_TIOCM:
  2725 + {
  2726 + int sarg = 0;
  2727 + int *targ = (int *)arg;
  2728 + ioctl(s->fd_in, TIOCMGET, &sarg);
  2729 + *targ = 0;
  2730 + if (sarg | TIOCM_CTS)
  2731 + *targ |= CHR_TIOCM_CTS;
  2732 + if (sarg | TIOCM_CAR)
  2733 + *targ |= CHR_TIOCM_CAR;
  2734 + if (sarg | TIOCM_DSR)
  2735 + *targ |= CHR_TIOCM_DSR;
  2736 + if (sarg | TIOCM_RI)
  2737 + *targ |= CHR_TIOCM_RI;
  2738 + if (sarg | TIOCM_DTR)
  2739 + *targ |= CHR_TIOCM_DTR;
  2740 + if (sarg | TIOCM_RTS)
  2741 + *targ |= CHR_TIOCM_RTS;
  2742 + }
  2743 + break;
  2744 + case CHR_IOCTL_SERIAL_SET_TIOCM:
  2745 + {
  2746 + int sarg = *(int *)arg;
  2747 + int targ = 0;
  2748 + if (sarg | CHR_TIOCM_DTR)
  2749 + targ |= TIOCM_DTR;
  2750 + if (sarg | CHR_TIOCM_RTS)
  2751 + targ |= TIOCM_RTS;
  2752 + ioctl(s->fd_in, TIOCMSET, &targ);
  2753 + }
  2754 + break;
2724 2755 default:
2725 2756 return -ENOTSUP;
2726 2757 }
... ...