Revision b2a5160c
b/hw/serial.c | ||
---|---|---|
93 | 93 |
int it_shift; |
94 | 94 |
}; |
95 | 95 |
|
96 |
static void serial_receive_byte(SerialState *s, int ch); |
|
97 |
|
|
96 | 98 |
static void serial_update_irq(SerialState *s) |
97 | 99 |
{ |
98 | 100 |
if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) { |
... | ... | |
161 | 163 |
s->lsr &= ~UART_LSR_THRE; |
162 | 164 |
serial_update_irq(s); |
163 | 165 |
ch = val; |
164 |
qemu_chr_write(s->chr, &ch, 1); |
|
166 |
if (!(s->mcr & UART_MCR_LOOP)) { |
|
167 |
/* when not in loopback mode, send the char */ |
|
168 |
qemu_chr_write(s->chr, &ch, 1); |
|
169 |
} |
|
165 | 170 |
s->thr_ipending = 1; |
166 | 171 |
s->lsr |= UART_LSR_THRE; |
167 | 172 |
s->lsr |= UART_LSR_TEMT; |
168 | 173 |
serial_update_irq(s); |
174 |
if (s->mcr & UART_MCR_LOOP) { |
|
175 |
/* in loopback mode, say that we just received a char */ |
|
176 |
serial_receive_byte(s, ch); |
|
177 |
} |
|
169 | 178 |
} |
170 | 179 |
break; |
171 | 180 |
case 1: |
... | ... | |
223 | 232 |
ret = s->rbr; |
224 | 233 |
s->lsr &= ~(UART_LSR_DR | UART_LSR_BI); |
225 | 234 |
serial_update_irq(s); |
226 |
qemu_chr_accept_input(s->chr); |
|
235 |
if (!(s->mcr & UART_MCR_LOOP)) { |
|
236 |
/* in loopback mode, don't receive any data */ |
|
237 |
qemu_chr_accept_input(s->chr); |
|
238 |
} |
|
227 | 239 |
} |
228 | 240 |
break; |
229 | 241 |
case 1: |
... | ... | |
346 | 358 |
return 0; |
347 | 359 |
} |
348 | 360 |
|
361 |
static void serial_reset(void *opaque) |
|
362 |
{ |
|
363 |
SerialState *s = opaque; |
|
364 |
|
|
365 |
s->divider = 0; |
|
366 |
s->rbr = 0; |
|
367 |
s->ier = 0; |
|
368 |
s->iir = UART_IIR_NO_INT; |
|
369 |
s->lcr = 0; |
|
370 |
s->mcr = 0; |
|
371 |
s->lsr = UART_LSR_TEMT | UART_LSR_THRE; |
|
372 |
s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS; |
|
373 |
s->scr = 0; |
|
374 |
|
|
375 |
s->thr_ipending = 0; |
|
376 |
s->last_break_enable = 0; |
|
377 |
qemu_irq_lower(s->irq); |
|
378 |
} |
|
379 |
|
|
349 | 380 |
/* If fd is zero, it means that the serial device uses the console */ |
350 | 381 |
SerialState *serial_init(int base, qemu_irq irq, CharDriverState *chr) |
351 | 382 |
{ |
... | ... | |
355 | 386 |
if (!s) |
356 | 387 |
return NULL; |
357 | 388 |
s->irq = irq; |
358 |
s->lsr = UART_LSR_TEMT | UART_LSR_THRE; |
|
359 |
s->iir = UART_IIR_NO_INT;
|
|
360 |
s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
|
|
389 |
|
|
390 |
qemu_register_reset(serial_reset, s);
|
|
391 |
serial_reset(s);
|
|
361 | 392 |
|
362 | 393 |
register_savevm("serial", base, 2, serial_save, serial_load, s); |
363 | 394 |
|
... | ... | |
452 | 483 |
if (!s) |
453 | 484 |
return NULL; |
454 | 485 |
s->irq = irq; |
455 |
s->lsr = UART_LSR_TEMT | UART_LSR_THRE; |
|
456 |
s->iir = UART_IIR_NO_INT; |
|
457 |
s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS; |
|
458 | 486 |
s->base = base; |
459 | 487 |
s->it_shift = it_shift; |
460 | 488 |
|
489 |
qemu_register_reset(serial_reset, s); |
|
490 |
serial_reset(s); |
|
491 |
|
|
461 | 492 |
register_savevm("serial", base, 2, serial_save, serial_load, s); |
462 | 493 |
|
463 | 494 |
if (ioregister) { |
Also available in: Unified diff