From 4ae7e3fc941add72b2ff11ce95a579a09b79b4e6 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Thu, 2 Apr 2009 20:44:01 +0400 Subject: [PATCH 3/3] Support 7785's serial. To: address@hidden X-KMail-Transport: CodeSourcery X-KMail-Identity: 901867920 --- hw/sh.h | 1 + hw/sh_serial.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/hw/sh.h b/hw/sh.h index 5e3c22b..da051f1 100644 --- a/hw/sh.h +++ b/hw/sh.h @@ -37,6 +37,7 @@ void tmu012_init(target_phys_addr_t base, int feat, uint32_t freq, /* sh_serial.c */ #define SH_SERIAL_FEAT_SCIF (1 << 0) +#define SH_SERIAL_FEAT_7785 (1 << 1) void sh_serial_init (target_phys_addr_t base, int feat, uint32_t freq, CharDriverState *chr, qemu_irq eri_source, diff --git a/hw/sh_serial.c b/hw/sh_serial.c index e004e28..4f606ff 100644 --- a/hw/sh_serial.c +++ b/hw/sh_serial.c @@ -154,10 +154,28 @@ static void sh_serial_ioport_write(void *opaque, uint32_t offs, uint32_t val) } return; - case 0x20: /* SPTR */ - s->sptr = val & 0xf3; + case 0x20: + if (s->feat & SH_SERIAL_FEAT_7785) + { + /* Recieve fifo data count register, not writable. */ + } + else + { + /* SPTR */ + s->sptr = val & 0xf3; + } return; - case 0x24: /* LSR */ + case 0x24: + if (s->feat & SH_SERIAL_FEAT_7785) + { + s->sptr = val & 0xf3; + } + else + { + /* LSR */ + } + return; + case 0x28: return; } } @@ -233,12 +251,47 @@ static uint32_t sh_serial_ioport_read(void *opaque, uint32_t offs) break; #endif case 0x1c: - ret = s->rx_cnt; + if (s->feat & SH_SERIAL_FEAT_7785) + { + /* Trasmit fifo data count. Because we immediate send + everything, we also claim the fifo is always empty. */ + ret = 0; + } + else + { + /* On 7751, this is unified receive/trasmit fifo data + count register. The received data count is in low + 8 bits. In QEMU, transmit fifo is always empty, so + return just receive count. */ + ret = s->rx_cnt; + } break; case 0x20: - ret = s->sptr; + if (s->feat & SH_SERIAL_FEAT_7785) + { + /* On 7785, there's separate trasmit fifo data register. */ + ret = s->rx_cnt; + } + else + { + ret = s->sptr; + } break; case 0x24: + /* On 7785, this is serial port register. On 7751, this is line + status register. */ + if (s->feat & SH_SERIAL_FEAT_7785) + { + ret = s->sptr; + } + else + { + ret = 0; + } + break; + case 0x28: + /* On 7785, this is line status register. */ + assert(s->feat & SH_SERIAL_FEAT_7785); ret = 0; break; } @@ -359,6 +412,7 @@ void sh_serial_init (target_phys_addr_t base, int feat, { sh_serial_state *s; int s_io_memory; + int is_7785 = (feat & SH_SERIAL_FEAT_7785); s = qemu_mallocz(sizeof(sh_serial_state)); @@ -378,14 +432,17 @@ void sh_serial_init (target_phys_addr_t base, int feat, s->dr = 0xff; } - s->rx_capacity = 16; + s->rx_capacity = is_7785 ? 64 : 16; s->rx_fifo = (uint8_t *)malloc(s->rx_capacity); sh_serial_clear_fifo(s); s_io_memory = cpu_register_io_memory(0, sh_serial_readfn, sh_serial_writefn, s); - cpu_register_physical_memory(P4ADDR(base), 0x28, s_io_memory); - cpu_register_physical_memory(A7ADDR(base), 0x28, s_io_memory); + cpu_register_physical_memory(P4ADDR(base), + is_7785 ? 0x2E : 0x28, s_io_memory); + cpu_register_physical_memory(A7ADDR(base), + is_7785 ? 0x2E : 0x28, s_io_memory); + s->chr = chr; -- 1.6.2.1