From 4db2ac5c9f9b50dad488ba9d8c75d435ad30247f Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Thu, 2 Apr 2009 20:44:01 +0400 Subject: [PATCH 3/6] Support 7785's serial. Signed-off-by: Vladimir Prus --- hw/sh.h | 1 + hw/sh_serial.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 51 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 fc7de72..2881b5c 100644 --- a/hw/sh_serial.c +++ b/hw/sh_serial.c @@ -158,10 +158,22 @@ 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: + if (s->feat & SH_SERIAL_FEAT_7785) { + s->sptr = val & 0xf3; + } else { + /* LSR */ + } return; - case 0x24: /* LSR */ + case 0x28: return; } } @@ -240,12 +252,38 @@ 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; } @@ -367,6 +405,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)); @@ -386,14 +425,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