diff -ru qemu-snapshot-2004-08-16_23/hw/serial.c qemu-snapshot-2004-08-16_23-testserial/hw/serial.c --- qemu-snapshot-2004-08-16_23/hw/serial.c 2004-07-15 05:28:13.000000000 +1200 +++ qemu-snapshot-2004-08-16_23-testserial/hw/serial.c 2004-08-20 01:47:43.220843707 +1200 @@ -24,6 +24,7 @@ #include "vl.h" //#define DEBUG_SERIAL +//#define DEBUG_SERIAL_VERBOSE #define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ @@ -87,8 +88,32 @@ CharDriverState *chr; }; +#ifdef DEBUG_SERIAL_VERBOSE +static void dump_uart(SerialState *s) +{ + fprintf(stderr, "Current state of UART is:\n\ +divider = 0x%x\n\ +rbr = 0x%x\n\ +ier = 0x%x\n\ +iir = 0x%x\n\ +lcr = 0x%x\n\ +mcr = 0x%x\n\ +lsr = 0x%x\n\ +msr = 0x%x\n\ +scr = 0x%x\n\ +thr_ipending = %d\n\ +irq = %d\n", +s->divider, s->rbr, s->ier, s->iir, s->lcr, s->mcr, s->lsr, s->msr, s->scr, s->thr_ipending, s->irq); +} +#endif + static void serial_update_irq(SerialState *s) { +#ifdef DEBUG_SERIAL_VERBOSE + fprintf(stderr, "serial_update_irq entry\n"); + dump_uart(s); +#endif + if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) { s->iir = UART_IIR_RDI; } else if (s->thr_ipending && (s->ier & UART_IER_THRI)) { @@ -96,10 +121,10 @@ } else { s->iir = UART_IIR_NO_INT; } - if (s->iir != UART_IIR_NO_INT) { - pic_set_irq(s->irq, 1); - } else { + if (s->iir & UART_IIR_NO_INT) { pic_set_irq(s->irq, 0); + } else { + pic_set_irq(s->irq, 1); } } @@ -107,6 +132,10 @@ { SerialState *s = opaque; unsigned char ch; +#ifdef DEBUG_SERIAL_VERBOSE + fprintf(stderr, "serial_ioport_write entry\n"); + dump_uart(s); +#endif addr &= 7; #ifdef DEBUG_SERIAL @@ -118,6 +147,10 @@ if (s->lcr & UART_LCR_DLAB) { s->divider = (s->divider & 0xff00) | val; } else { +#ifdef DEBUG_SERIAL_VERBOSE + fprintf(stderr, "serial_ioport_write data-to-send\n"); + dump_uart(s); +#endif s->thr_ipending = 0; s->lsr &= ~UART_LSR_THRE; serial_update_irq(s); @@ -126,7 +159,12 @@ s->thr_ipending = 1; s->lsr |= UART_LSR_THRE; s->lsr |= UART_LSR_TEMT; + s->ier &= ~UART_IER_THRI; serial_update_irq(s); +#ifdef DEBUG_SERIAL_VERBOSE + fprintf(stderr, "serial_ioport_write data-sent\n"); + dump_uart(s); +#endif } break; case 1: @@ -160,17 +198,29 @@ { SerialState *s = opaque; uint32_t ret; +#ifdef DEBUG_SERIAL_VERBOSE + fprintf(stderr, "serial_ioport_read entry\n"); + dump_uart(s); +#endif addr &= 7; switch(addr) { default: case 0: if (s->lcr & UART_LCR_DLAB) { - ret = s->divider & 0xff; + ret = s->divider & 0xff; } else { +#ifdef DEBUG_SERIAL_VERBOSE + fprintf(stderr, "serial_ioport_read data-to-read\n"); + dump_uart(s); +#endif ret = s->rbr; s->lsr &= ~(UART_LSR_DR | UART_LSR_BI); serial_update_irq(s); +#ifdef DEBUG_SERIAL_VERBOSE + fprintf(stderr, "serial_ioport_read data-read\n"); + dump_uart(s); +#endif } break; case 1: @@ -183,7 +233,8 @@ case 2: ret = s->iir; /* reset THR pending bit */ - if ((ret & 0x7) == UART_IIR_THRI) + if ((ret & 0x7) == UART_IIR_THRI) /* Is it just me, or does this + evaluation make no sense? */ s->thr_ipending = 0; serial_update_irq(s); break; @@ -225,8 +276,12 @@ static void serial_receive_byte(SerialState *s, int ch) { s->rbr = ch; +#ifdef DEBUG_SERIAL_VERBOSE + fprintf(stderr, "serial_receive_byte s->rbr='%c'\n", s->rbr); +#endif s->lsr |= UART_LSR_DR; serial_update_irq(s); + } static void serial_receive_break(SerialState *s) Only in qemu-snapshot-2004-08-16_23-testserial: qemu.1 Only in qemu-snapshot-2004-08-16_23-testserial: qemu-doc.html Only in qemu-snapshot-2004-08-16_23-testserial: qemu-tech.html diff -ru qemu-snapshot-2004-08-16_23/vl.c qemu-snapshot-2004-08-16_23-testserial/vl.c --- qemu-snapshot-2004-08-16_23/vl.c 2004-08-20 01:41:10.804413581 +1200 +++ qemu-snapshot-2004-08-16_23-testserial/vl.c 2004-08-19 22:22:24.476670548 +1200 @@ -1029,6 +1029,9 @@ static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { +/* + fprintf(stderr, "fd_chr_write wrote %c\n", *buf); +*/ FDCharDriver *s = chr->opaque; return write(s->fd_out, buf, len); } @@ -1226,10 +1229,12 @@ /* Shouldn't ever end up in here */ return NULL; } else { - int fdesc; - fdesc = open(filename, O_RDWR); - if (fdesc >= 0) { - return qemu_chr_open_fd(fdesc, fdesc); + int fdesc_r; + int fdesc_w; + fdesc_w = open(filename, O_WRONLY); + fdesc_r = open(filename, O_RDONLY); + if ((fdesc_r >= 0) && (fdesc_w >= 0)) { + return qemu_chr_open_fd(fdesc_r, fdesc_w); } else { return NULL; }