[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 3/3] qdev'ify dp8393x
From: |
Laurent Vivier |
Subject: |
[Qemu-devel] [PATCH 3/3] qdev'ify dp8393x |
Date: |
Mon, 29 Dec 2014 01:39:10 +0100 |
Signed-off-by: Laurent Vivier <address@hidden>
---
hw/mips/mips_jazz.c | 2 +-
hw/net/dp8393x.c | 182 +++++++++++++++++++++++++++++++----------------
include/hw/net/dp8393x.h | 1 -
3 files changed, 121 insertions(+), 64 deletions(-)
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index 4d556ab..8eca5a2 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -268,7 +268,7 @@ static void mips_jazz_init(MemoryRegion *address_space,
if (!nd->model)
nd->model = g_strdup("dp83932");
if (strcmp(nd->model, "dp83932") == 0) {
- dp83932_init(nd, 0x80001000, 0, 2, 0, get_system_memory(),
+ dp83932_init(nd, 0x80001000, 0, 2, 0,
rc4030[4], rc4030_opaque, rc4030_dma_memory_rw);
break;
} else if (is_help_option(nd->model)) {
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index bd97851..b81e68c 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -17,9 +17,10 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include "hw/hw.h"
-#include "qemu/timer.h"
+#include "hw/sysbus.h"
#include "net/net.h"
+#include "hw/devices.h"
+#include "qemu/timer.h"
#include "hw/net/dp8393x.h"
//#define DEBUG_SONIC
@@ -147,10 +148,15 @@ do { printf("sonic ERROR: %s: " fmt, __func__ , ##
__VA_ARGS__); } while (0)
#define SONIC_ISR_PINT 0x0800
#define SONIC_ISR_LCD 0x1000
+#define TYPE_DP8393X "dp8393x"
+#define DP8393X(obj) OBJECT_CHECK(dp8393xState, (obj), TYPE_DP8393X)
+
typedef struct dp8393xState {
+ SysBusDevice parent_obj;
+
/* Hardware */
- int it_shift;
- int regs_offset;
+ int32_t it_shift;
+ int32_t regs_offset;
qemu_irq irq;
#ifdef DEBUG_SONIC
int irq_level;
@@ -172,10 +178,13 @@ typedef struct dp8393xState {
int loopback_packet;
/* Memory access */
- void (*memory_rw)(void *opaque, hwaddr addr, uint8_t *buf, int len, int
is_write);
- void* mem_opaque;
+ void *memory_rw;
+ void *mem_opaque;
} dp8393xState;
+#define MEMORY_RW(func) void (*func)(void *opaque, hwaddr addr, \
+ uint8_t *buf, int len, int is_write) = s->memory_rw
+
static void dp8393x_update_irq(dp8393xState *s)
{
int level = (s->regs[SONIC_IMR] & s->regs[SONIC_ISR]) ? 1 : 0;
@@ -199,13 +208,14 @@ static void do_load_cam(dp8393xState *s)
uint16_t data[8];
int width, size;
uint16_t index = 0;
+ MEMORY_RW(memory_rw);
width = (s->regs[SONIC_DCR] & SONIC_DCR_DW) ? 2 : 1;
size = sizeof(uint16_t) * 4 * width;
while (s->regs[SONIC_CDC] & 0x1f) {
/* Fill current entry */
- s->memory_rw(s->mem_opaque,
+ memory_rw(s->mem_opaque,
(s->regs[SONIC_URRA] << 16) | s->regs[SONIC_CDP],
(uint8_t *)data, size, 0);
s->cam[index][0] = data[1 * width] & 0xff;
@@ -224,7 +234,7 @@ static void do_load_cam(dp8393xState *s)
}
/* Read CAM enable */
- s->memory_rw(s->mem_opaque,
+ memory_rw(s->mem_opaque,
(s->regs[SONIC_URRA] << 16) | s->regs[SONIC_CDP],
(uint8_t *)data, size, 0);
s->regs[SONIC_CE] = data[0 * width];
@@ -240,11 +250,14 @@ static void do_read_rra(dp8393xState *s)
{
uint16_t data[8];
int width, size;
+ MEMORY_RW(memory_rw);
/* Read memory */
width = (s->regs[SONIC_DCR] & SONIC_DCR_DW) ? 2 : 1;
size = sizeof(uint16_t) * 4 * width;
- s->memory_rw(s->mem_opaque,
+ DPRINTF("READ from %08x\n",
+ (s->regs[SONIC_URRA] << 16) | s->regs[SONIC_RRP]);
+ memory_rw(s->mem_opaque,
(s->regs[SONIC_URRA] << 16) | s->regs[SONIC_RRP],
(uint8_t *)data, size, 0);
@@ -348,6 +361,7 @@ static void do_transmit_packets(dp8393xState *s)
int width, size;
int tx_len, len;
uint16_t i;
+ MEMORY_RW(memory_rw);
width = (s->regs[SONIC_DCR] & SONIC_DCR_DW) ? 2 : 1;
@@ -357,7 +371,7 @@ static void do_transmit_packets(dp8393xState *s)
(s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_CTDA]);
size = sizeof(uint16_t) * 6 * width;
s->regs[SONIC_TTDA] = s->regs[SONIC_CTDA];
- s->memory_rw(s->mem_opaque,
+ memory_rw(s->mem_opaque,
((s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA]) +
sizeof(uint16_t) * width,
(uint8_t *)data, size, 0);
tx_len = 0;
@@ -383,7 +397,7 @@ static void do_transmit_packets(dp8393xState *s)
if (tx_len + len > sizeof(s->tx_buffer)) {
len = sizeof(s->tx_buffer) - tx_len;
}
- s->memory_rw(s->mem_opaque,
+ memory_rw(s->mem_opaque,
(s->regs[SONIC_TSA1] << 16) | s->regs[SONIC_TSA0],
&s->tx_buffer[tx_len], len, 0);
tx_len += len;
@@ -392,7 +406,7 @@ static void do_transmit_packets(dp8393xState *s)
if (i != s->regs[SONIC_TFC]) {
/* Read next fragment details */
size = sizeof(uint16_t) * 3 * width;
- s->memory_rw(s->mem_opaque,
+ memory_rw(s->mem_opaque,
((s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA]) +
sizeof(uint16_t) * (4 + 3 * i) * width,
(uint8_t *)data, size, 0);
s->regs[SONIC_TSA0] = data[0 * width];
@@ -426,14 +440,14 @@ static void do_transmit_packets(dp8393xState *s)
/* Write status */
data[0 * width] = s->regs[SONIC_TCR] & 0x0fff; /* status */
size = sizeof(uint16_t) * width;
- s->memory_rw(s->mem_opaque,
+ memory_rw(s->mem_opaque,
(s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA],
(uint8_t *)data, size, 1);
if (!(s->regs[SONIC_CR] & SONIC_CR_HTX)) {
/* Read footer of packet */
size = sizeof(uint16_t) * width;
- s->memory_rw(s->mem_opaque,
+ memory_rw(s->mem_opaque,
((s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_TTDA]) +
sizeof(uint16_t) * (4 + 3 * s->regs[SONIC_TFC]) * width,
(uint8_t *)data, size, 0);
s->regs[SONIC_CTDA] = data[0 * width] & ~0x1;
@@ -680,7 +694,7 @@ static const MemoryRegionOps dp8393x_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static int nic_can_receive(NetClientState *nc)
+static int dp8393x_can_receive(NetClientState *nc)
{
dp8393xState *s = qemu_get_nic_opaque(nc);
@@ -729,7 +743,8 @@ static int receive_filter(dp8393xState *s, const uint8_t *
buf, int size)
return -1;
}
-static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t
size)
+static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf,
+ size_t size)
{
dp8393xState *s = qemu_get_nic_opaque(nc);
uint16_t data[10];
@@ -737,6 +752,7 @@ static ssize_t nic_receive(NetClientState *nc, const
uint8_t * buf, size_t size)
uint32_t available, address;
int width, rx_len = size;
uint32_t checksum;
+ MEMORY_RW(memory_rw);
width = (s->regs[SONIC_DCR] & SONIC_DCR_DW) ? 2 : 1;
@@ -755,8 +771,9 @@ static ssize_t nic_receive(NetClientState *nc, const
uint8_t * buf, size_t size)
if (s->regs[SONIC_LLFA] & 0x1) {
/* Are we still in resource exhaustion? */
size = sizeof(uint16_t) * 1 * width;
- address = ((s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]) +
sizeof(uint16_t) * 5 * width;
- s->memory_rw(s->mem_opaque, address, (uint8_t*)data, size, 0);
+ address = ((s->regs[SONIC_URDA] << 16) |
+ s->regs[SONIC_CRDA]) + sizeof(uint16_t) * 5 * width;
+ memory_rw(s->mem_opaque, address, (uint8_t *)data, size, 0);
if (data[0 * width] & 0x1) {
/* Still EOL ; stop reception */
return -1;
@@ -779,9 +796,9 @@ static ssize_t nic_receive(NetClientState *nc, const
uint8_t * buf, size_t size)
/* Put packet into RBA */
DPRINTF("Receive packet at %08x\n", (s->regs[SONIC_CRBA1] << 16) |
s->regs[SONIC_CRBA0]);
address = (s->regs[SONIC_CRBA1] << 16) | s->regs[SONIC_CRBA0];
- s->memory_rw(s->mem_opaque, address, (uint8_t*)buf, rx_len, 1);
+ memory_rw(s->mem_opaque, address, (uint8_t *)buf, rx_len, 1);
address += rx_len;
- s->memory_rw(s->mem_opaque, address, (uint8_t*)&checksum, 4, 1);
+ memory_rw(s->mem_opaque, address, (uint8_t *)&checksum, 4, 1);
rx_len += 4;
s->regs[SONIC_CRBA1] = address >> 16;
s->regs[SONIC_CRBA0] = address & 0xffff;
@@ -809,11 +826,12 @@ static ssize_t nic_receive(NetClientState *nc, const
uint8_t * buf, size_t size)
data[3 * width] = s->regs[SONIC_TRBA1]; /* pkt_ptr1 */
data[4 * width] = s->regs[SONIC_RSC]; /* seq_no */
size = sizeof(uint16_t) * 5 * width;
- s->memory_rw(s->mem_opaque, (s->regs[SONIC_URDA] << 16) |
s->regs[SONIC_CRDA], (uint8_t *)data, size, 1);
+ memory_rw(s->mem_opaque, (s->regs[SONIC_URDA] << 16) |
+ s->regs[SONIC_CRDA], (uint8_t *)data, size, 1);
/* Move to next descriptor */
size = sizeof(uint16_t) * width;
- s->memory_rw(s->mem_opaque,
+ memory_rw(s->mem_opaque,
((s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]) + sizeof(uint16_t)
* 5 * width,
(uint8_t *)data, size, 0);
s->regs[SONIC_LLFA] = data[0 * width];
@@ -822,7 +840,7 @@ static ssize_t nic_receive(NetClientState *nc, const
uint8_t * buf, size_t size)
s->regs[SONIC_ISR] |= SONIC_ISR_RDE;
} else {
data[0 * width] = 0; /* in_use */
- s->memory_rw(s->mem_opaque,
+ memory_rw(s->mem_opaque,
((s->regs[SONIC_URDA] << 16) | s->regs[SONIC_CRDA]) +
sizeof(uint16_t) * 6 * width,
(uint8_t *)data, size, 1);
s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA];
@@ -841,9 +859,9 @@ static ssize_t nic_receive(NetClientState *nc, const
uint8_t * buf, size_t size)
return size;
}
-static void nic_reset(void *opaque)
+static void dp8393x_reset(DeviceState *d)
{
- dp8393xState *s = opaque;
+ dp8393xState *s = DP8393X(d);
timer_del(s->watchdog);
s->regs[SONIC_CR] = SONIC_CR_RST | SONIC_CR_STP | SONIC_CR_RXDIS;
@@ -865,7 +883,7 @@ static void nic_reset(void *opaque)
dp8393x_update_irq(s);
}
-static void nic_cleanup(NetClientState *nc)
+static void dp8393x_cleanup(NetClientState *nc)
{
dp8393xState *s = qemu_get_nic_opaque(nc);
@@ -878,54 +896,94 @@ static void nic_cleanup(NetClientState *nc)
static NetClientInfo net_dp83932_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
- .can_receive = nic_can_receive,
- .receive = nic_receive,
- .cleanup = nic_cleanup,
+ .can_receive = dp8393x_can_receive,
+ .receive = dp8393x_receive,
+ .cleanup = dp8393x_cleanup,
};
-void dp83932_init(NICInfo *nd, hwaddr base, hwaddr prombase,
- int it_shift, int regs_offset,
- MemoryRegion *address_space,
- qemu_irq irq, void* mem_opaque,
- void (*memory_rw)(void *opaque, hwaddr addr, uint8_t *buf,
int len, int is_write))
+static int dp8393x_init1(SysBusDevice *sbd)
{
- dp8393xState *s;
+ DeviceState *dev = DEVICE(sbd);
+ dp8393xState *s = DP8393X(dev);
int i;
uint8_t *prom;
- qemu_check_nic_model(nd, "dp83932");
+ memory_region_init_io(&s->mmio, NULL, &dp8393x_ops, s,
+ "dp8393x", 0x40 << s->it_shift);
+ sysbus_init_mmio(sbd, &s->mmio);
+ sysbus_init_irq(sbd, &s->irq);
- s = g_malloc0(sizeof(dp8393xState));
+ s->nic = qemu_new_nic(&net_dp83932_info, &s->conf,
+ object_get_typename(OBJECT(dev)), dev->id, s);
+ qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
- s->address_space = address_space;
- s->mem_opaque = mem_opaque;
- s->memory_rw = memory_rw;
- s->it_shift = it_shift;
- s->regs_offset = regs_offset;
- s->irq = irq;
s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
- s->conf.macaddr = nd->macaddr;
- s->conf.peers.ncs[0] = nd->netdev;
+ memory_region_init_rom_device(&s->prom, NULL, NULL, NULL,
+ "dp8393x-prom", SONIC_PROM_SIZE, NULL);
+ prom = memory_region_get_ram_ptr(&s->prom);
+ for (i = 0; i < 6; i++) {
+ prom[i] = s->conf.macaddr.a[i];
+ }
+ sysbus_init_mmio(sbd, &s->prom);
- s->nic = qemu_new_nic(&net_dp83932_info, &s->conf, nd->model, nd->name, s);
+ return 0;
+}
- qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
- qemu_register_reset(nic_reset, s);
- nic_reset(s);
+static Property dp8393x_properties[] = {
+ DEFINE_NIC_PROPERTIES(dp8393xState, conf),
+ DEFINE_PROP_PTR("memory_rw", dp8393xState, memory_rw),
+ DEFINE_PROP_PTR("mem_opaque", dp8393xState, mem_opaque),
+ DEFINE_PROP_INT32("it_shift", dp8393xState, it_shift, 0),
+ DEFINE_PROP_INT32("regs_offset", dp8393xState, regs_offset, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
- memory_region_init_io(&s->mmio, NULL, &dp8393x_ops, s,
- "dp8393x", 0x40 << it_shift);
- memory_region_add_subregion(address_space, base, &s->mmio);
-
- if (prombase) {
- memory_region_init_rom_device(&s->prom, NULL, NULL, NULL,
- "dp8393x-prom", SONIC_PROM_SIZE, NULL);
- prom = memory_region_get_ram_ptr(&s->prom);
- for (i = 0; i < 6; i++) {
- prom[i] = s->conf.macaddr.a[i];
- }
- memory_region_add_subregion(address_space, prombase, &s->prom);
- }
+static void dp8393x_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+ k->init = dp8393x_init1;
+ dc->reset = dp8393x_reset;
+ dc->props = dp8393x_properties;
}
+
+static const TypeInfo dp8393x_info = {
+ .name = TYPE_DP8393X,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(dp8393xState),
+ .class_init = dp8393x_class_init,
+};
+
+static void dp8393x_register_types(void)
+{
+ type_register_static(&dp8393x_info);
+}
+
+void dp83932_init(NICInfo *nd, hwaddr base, hwaddr prombase,
+ int it_shift, int regs_offset,
+ qemu_irq irq, void *mem_opaque,
+ void (*memory_rw)(void *opaque, hwaddr addr, uint8_t *buf,
+ int len, int is_write))
+{
+ DeviceState *dev;
+ SysBusDevice *s;
+
+ qemu_check_nic_model(nd, "dp83932");
+
+ dev = qdev_create(NULL, TYPE_DP8393X);
+ qdev_set_nic_properties(dev, nd);
+ qdev_prop_set_int32(dev, "it_shift", it_shift);
+ qdev_prop_set_int32(dev, "regs_offset", regs_offset);
+ qdev_prop_set_ptr(dev, "mem_opaque", mem_opaque);
+ qdev_prop_set_ptr(dev, "memory_rw", memory_rw);
+ qdev_init_nofail(dev);
+ s = SYS_BUS_DEVICE(dev);
+ sysbus_mmio_map(s, 0, base);
+ sysbus_mmio_map(s, 1, prombase);
+ sysbus_connect_irq(s, 0, irq);
+}
+
+type_init(dp8393x_register_types)
diff --git a/include/hw/net/dp8393x.h b/include/hw/net/dp8393x.h
index 47eb187..178ff5c 100644
--- a/include/hw/net/dp8393x.h
+++ b/include/hw/net/dp8393x.h
@@ -1,6 +1,5 @@
void dp83932_init(NICInfo *nd, hwaddr base, hwaddr rombase,
int it_shift, int regs_offset,
- MemoryRegion *address_space,
qemu_irq irq, void *mem_opaque,
void (*memory_rw)(void *opaque, hwaddr addr, uint8_t *buf,
int len, int is_write));
--
1.9.1