[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 09/14] hw/lan9118.c: Basic byte/word/long access sup
From: |
Evgeny Voevodin |
Subject: |
[Qemu-devel] [PATCH 09/14] hw/lan9118.c: Basic byte/word/long access support. |
Date: |
Wed, 07 Dec 2011 13:47:00 +0400 |
We included this chip into s5pc210 platform because SMDK board holds
lan9215 chip. Difference is that 9215 access is 16-bit wide and some
registers differ. By addition basic 16-bit access to 9118 emulation we
achieved ethernet controller support by Linux lernel on SMDK boards.
Signed-off-by: Evgeny Voevodin <address@hidden>
---
hw/lan9118.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 90 insertions(+), 6 deletions(-)
diff --git a/hw/lan9118.c b/hw/lan9118.c
index ee8b2ea..7aebabd 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -212,6 +212,14 @@ typedef struct {
int rxp_offset;
int rxp_size;
int rxp_pad;
+
+ uint32_t write_word_prev_offset;
+ uint32_t write_word_n;
+ uint16_t write_word_l;
+ uint16_t write_word_h;
+ uint32_t read_word_prev_offset;
+ uint32_t read_word_n;
+ uint32_t read_long;
} lan9118_state;
static void lan9118_update(lan9118_state *s)
@@ -345,6 +353,9 @@ static void lan9118_reset(DeviceState *d)
s->mac_mii_data = 0;
s->mac_flow = 0;
+ s->read_word_n = 0;
+ s->write_word_n = 0;
+
phy_reset(s);
s->eeprom_writable = 0;
@@ -896,11 +907,11 @@ static void lan9118_tick(void *opaque)
}
static void lan9118_writel(void *opaque, target_phys_addr_t offset,
- uint64_t val, unsigned size)
+ uint32_t val)
{
lan9118_state *s = (lan9118_state *)opaque;
offset &= 0xff;
-
+
//DPRINTF("Write reg 0x%02x = 0x%08x\n", (int)offset, val);
if (offset >= 0x20 && offset < 0x40) {
/* TX FIFO */
@@ -1029,8 +1040,43 @@ static void lan9118_writel(void *opaque,
target_phys_addr_t offset,
lan9118_update(s);
}
-static uint64_t lan9118_readl(void *opaque, target_phys_addr_t offset,
- unsigned size)
+static void lan9118_writeb(void *opaque, target_phys_addr_t offset,
+ uint32_t val)
+{
+ hw_error("lan9118_writeb: Bad reg 0x%x = %x\n", (int)offset, val);
+}
+
+static void lan9118_writew(void *opaque, target_phys_addr_t offset,
+ uint32_t val)
+{
+ lan9118_state *s = (lan9118_state *)opaque;
+ offset &= 0xff;
+
+ /* TODO: Implement fair word operation, because this implementation
+ * assumes that any register is accessed as two 16-bit operations. */
+
+ if (s->write_word_prev_offset != (offset & ~0x3)) {
+ /* New offset, reset word counter */
+ s->write_word_n = 0;
+ s->write_word_prev_offset = offset & ~0x3;
+ }
+
+ if (offset & 0x2) {
+ s->write_word_h = val;
+ } else {
+ s->write_word_l = val;
+ }
+
+ //DPRINTF("Writew reg 0x%02x = 0x%08x\n", (int)offset, val);
+ s->write_word_n++;
+ if (s->write_word_n == 2) {
+ s->write_word_n = 0;
+ lan9118_writel(s, offset & ~3, s->write_word_l +
+ (s->write_word_h << 16));
+ }
+}
+
+static uint32_t lan9118_readl(void *opaque, target_phys_addr_t offset)
{
lan9118_state *s = (lan9118_state *)opaque;
@@ -1103,9 +1149,47 @@ static uint64_t lan9118_readl(void *opaque,
target_phys_addr_t offset,
return 0;
}
+static uint32_t lan9118_readb(void *opaque, target_phys_addr_t offset)
+{
+ hw_error("lan9118_readb: Bad reg 0x%x\n", (int)offset);
+}
+
+static uint32_t lan9118_readw(void *opaque, target_phys_addr_t offset)
+{
+ lan9118_state *s = (lan9118_state *)opaque;
+ uint32_t val;
+
+ /* TODO: Implement fair word operation, because this implementation
+ * assumes that any register is accessed as two 16-bit operations. */
+
+ if (s->read_word_prev_offset != (offset & ~0x3)) {
+ /* New offset, reset word counter */
+ s->read_word_n = 0;
+ s->read_word_prev_offset = offset & ~0x3;
+ }
+
+ s->read_word_n++;
+ if (s->read_word_n == 1) {
+ s->read_long = lan9118_readl(s, offset & ~3);
+ } else {
+ s->read_word_n = 0;
+ }
+
+ if (offset & 2) {
+ val = s->read_long >> 16;
+ } else {
+ val = s->read_long & 0xFFFF;
+ }
+
+ //DPRINTF("Readw reg 0x%02x, val 0x%x\n", (int)offset, val);
+ return val;
+}
+
static const MemoryRegionOps lan9118_mem_ops = {
- .read = lan9118_readl,
- .write = lan9118_writel,
+ .old_mmio = {
+ .read = { lan9118_readb, lan9118_readw, lan9118_readl, },
+ .write = { lan9118_writeb, lan9118_writew, lan9118_writel, },
+ },
.endianness = DEVICE_NATIVE_ENDIAN,
};
--
1.7.4.1
- [Qemu-devel] [PATCH 00/14] ARM: Samsung S5PC210-based boards support., Evgeny Voevodin, 2011/12/07
- [Qemu-devel] [PATCH 02/14] hw/sysbus.h: Increase maximum number of device IRQs., Evgeny Voevodin, 2011/12/07
- [Qemu-devel] [PATCH 05/14] hw/arm_boot.c: Add new secondary CPU bootloader., Evgeny Voevodin, 2011/12/07
- [Qemu-devel] [PATCH 04/14] ARM: s5pc210: PWM support., Evgeny Voevodin, 2011/12/07
- [Qemu-devel] [PATCH 01/14] ARM: s5pc210: Basic support of s5pc210 boards, Evgeny Voevodin, 2011/12/07
- [Qemu-devel] [PATCH 03/14] ARM: s5pc210: IRQ subsystem support., Evgeny Voevodin, 2011/12/07
- [Qemu-devel] [PATCH 09/14] hw/lan9118.c: Basic byte/word/long access support.,
Evgeny Voevodin <=
- [Qemu-devel] [PATCH 08/14] ARM: s5pc210: Boot secondary CPU., Evgeny Voevodin, 2011/12/07
- [Qemu-devel] [PATCH 12/14] SD card: add query function to check wether SD card currently ready to recieve data Before executing data transfer to card, we must check that previously issued command wasn't a simple query command (for ex. CMD13), which doesn't require data transfer. Currently, we only can aquire information about whether SD card is in sending data state or not. This patch allows us to query wether previous command was data write command and it was successfully accepted by card (meaning that SD card in recieving data state)., Evgeny Voevodin, 2011/12/07
- [Qemu-devel] [PATCH 06/14] hw/arm_gic.c: lower IRQ only on changing of enable bit., Evgeny Voevodin, 2011/12/07
- [Qemu-devel] [PATCH 14/14] s5pc210: Switch to sysbus_init_mmio., Evgeny Voevodin, 2011/12/07
- [Qemu-devel] [PATCH 07/14] ARM: s5pc210: MCT support., Evgeny Voevodin, 2011/12/07
- [Qemu-devel] [PATCH 10/14] hw/s5pc210.c: Add lan9118 support to SMDK board., Evgeny Voevodin, 2011/12/07