Index: hw/serial.c =================================================================== RCS file: /cvsroot/qemu/qemu/hw/serial.c,v retrieving revision 1.7 diff -u -r1.7 serial.c --- hw/serial.c 24 Aug 2004 21:55:28 -0000 1.7 +++ hw/serial.c 25 Jul 2005 10:06:16 -0000 @@ -23,6 +23,11 @@ */ #include "vl.h" +#define PIPE_SERIAL +#ifdef PIPE_SERIAL +#include +#endif + //#define DEBUG_SERIAL #define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ @@ -84,7 +89,13 @@ it can be reset while reading iir */ int thr_ipending; int irq; +#ifndef PIPE_SERIAL CharDriverState *chr; +#else + QEMUTimer *timer; + HANDLE pipe_handle; + int32_t baudrate; +#endif }; static void serial_update_irq(SerialState *s) @@ -107,6 +118,9 @@ { SerialState *s = opaque; unsigned char ch; +#ifdef PIPE_SERIAL + DWORD written; +#endif addr &= 7; #ifdef DEBUG_SERIAL @@ -117,12 +131,21 @@ case 0: if (s->lcr & UART_LCR_DLAB) { s->divider = (s->divider & 0xff00) | val; +#ifdef PIPE_SERIAL + if (s->divider) { + s->baudrate = 1843200 / (16 * s->divider); + } +#endif } else { s->thr_ipending = 0; s->lsr &= ~UART_LSR_THRE; serial_update_irq(s); ch = val; +#ifndef PIPE_SERIAL qemu_chr_write(s->chr, &ch, 1); +#else + WriteFile(s->pipe_handle, &ch, 1, &written, NULL); +#endif s->thr_ipending = 1; s->lsr |= UART_LSR_THRE; s->lsr |= UART_LSR_TEMT; @@ -143,6 +166,14 @@ case 2: break; case 3: +#ifdef PIPE_SERIAL + if (!(val & UART_LCR_DLAB) && (s->lcr & UART_LCR_DLAB)) { + if (s->baudrate != 0) { + qemu_mod_timer(s->timer, qemu_get_clock(vm_clock) + + (ticks_per_sec / s->baudrate)); + } + } +#endif s->lcr = val; break; case 4: @@ -174,6 +205,11 @@ ret = s->rbr; s->lsr &= ~(UART_LSR_DR | UART_LSR_BI); serial_update_irq(s); +#ifdef PIPE_SERIAL + if (s->baudrate) + qemu_mod_timer(s->timer, qemu_get_clock(vm_clock) /*+ + (ticks_per_sec / s->baudrate)*/); +#endif } break; case 1: @@ -258,6 +294,27 @@ serial_receive_break(s); } +#ifdef PIPE_SERIAL +static void rx_timer(void *opaque) +{ + SerialState *s = opaque; + DWORD temp; + char buffer; + + if (!(s->lsr & UART_LSR_DR)) { + if (PeekNamedPipe(s->pipe_handle, NULL, 0, NULL, &temp, 0) && temp) { + ReadFile(s->pipe_handle, &buffer, 1, &temp, NULL); + serial_receive_byte(s, buffer); + qemu_del_timer(s->timer); + return; + } + } + + qemu_mod_timer(s->timer, qemu_get_clock(vm_clock) + + (ticks_per_sec / s->baudrate)); +} +#endif + /* If fd is zero, it means that the serial device uses the console */ SerialState *serial_init(int base, int irq, CharDriverState *chr) { @@ -272,8 +329,18 @@ register_ioport_write(base, 8, 1, serial_ioport_write, s); register_ioport_read(base, 8, 1, serial_ioport_read, s); +#ifndef PIPE_SERIAL s->chr = chr; qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s); qemu_chr_add_event_handler(chr, serial_event); +#else + s->timer = qemu_new_timer(vm_clock, rx_timer, s); + qemu_mod_timer(s->timer, qemu_get_clock(vm_clock)); + s->pipe_handle = CreateNamedPipe("\\\\.\\pipe\\com_1", PIPE_ACCESS_DUPLEX, + PIPE_TYPE_BYTE, 1, 0x4000, 0x4000, 30000, + NULL); + s->baudrate = 115200; +#endif + return s; }