diff options
Diffstat (limited to 'hw/net')
-rw-r--r-- | hw/net/xilinx_ethlite.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 14bf2b2..15d9b95 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -34,6 +34,7 @@ #include "hw/sysbus.h" #include "hw/irq.h" #include "hw/qdev-properties.h" +#include "hw/qdev-properties-system.h" #include "hw/misc/unimp.h" #include "net/net.h" #include "trace.h" @@ -85,6 +86,7 @@ struct XlnxXpsEthLite { SysBusDevice parent_obj; + EndianMode model_endianness; MemoryRegion container; qemu_irq irq; NICState *nic; @@ -183,10 +185,10 @@ static void port_tx_write(void *opaque, hwaddr addr, uint64_t value, } } -static const MemoryRegionOps eth_porttx_ops = { +static const MemoryRegionOps eth_porttx_ops[2] = { + [0 ... 1] = { .read = port_tx_read, .write = port_tx_write, - .endianness = DEVICE_NATIVE_ENDIAN, .impl = { .min_access_size = 4, .max_access_size = 4, @@ -195,6 +197,9 @@ static const MemoryRegionOps eth_porttx_ops = { .min_access_size = 4, .max_access_size = 4, }, + }, + [0].endianness = DEVICE_LITTLE_ENDIAN, + [1].endianness = DEVICE_BIG_ENDIAN, }; static uint64_t port_rx_read(void *opaque, hwaddr addr, unsigned int size) @@ -232,10 +237,10 @@ static void port_rx_write(void *opaque, hwaddr addr, uint64_t value, } } -static const MemoryRegionOps eth_portrx_ops = { +static const MemoryRegionOps eth_portrx_ops[2] = { + [0 ... 1] = { .read = port_rx_read, .write = port_rx_write, - .endianness = DEVICE_NATIVE_ENDIAN, .impl = { .min_access_size = 4, .max_access_size = 4, @@ -244,6 +249,9 @@ static const MemoryRegionOps eth_portrx_ops = { .min_access_size = 4, .max_access_size = 4, }, + }, + [0].endianness = DEVICE_LITTLE_ENDIAN, + [1].endianness = DEVICE_BIG_ENDIAN, }; static bool eth_can_rx(NetClientState *nc) @@ -300,6 +308,14 @@ static NetClientInfo net_xilinx_ethlite_info = { static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) { XlnxXpsEthLite *s = XILINX_ETHLITE(dev); + unsigned ops_index; + + if (s->model_endianness == ENDIAN_MODE_UNSPECIFIED) { + error_setg(errp, TYPE_XILINX_ETHLITE " property 'endianness'" + " must be set to 'big' or 'little'"); + return; + } + ops_index = s->model_endianness == ENDIAN_MODE_BIG ? 1 : 0; memory_region_init(&s->container, OBJECT(dev), "xlnx.xps-ethernetlite", 0x2000); @@ -328,7 +344,7 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) BUFSZ_MAX, &error_abort); memory_region_add_subregion(&s->container, 0x0800 * i, &s->port[i].txbuf); memory_region_init_io(&s->port[i].txio, OBJECT(dev), - ð_porttx_ops, s, + ð_porttx_ops[ops_index], s, i ? "ethlite.tx[1]io" : "ethlite.tx[0]io", 4 * TX_MAX); memory_region_add_subregion(&s->container, i ? A_TX_BASE1 : A_TX_BASE0, @@ -340,7 +356,7 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&s->container, 0x1000 + 0x0800 * i, &s->port[i].rxbuf); memory_region_init_io(&s->port[i].rxio, OBJECT(dev), - ð_portrx_ops, s, + ð_portrx_ops[ops_index], s, i ? "ethlite.rx[1]io" : "ethlite.rx[0]io", 4 * RX_MAX); memory_region_add_subregion(&s->container, i ? A_RX_BASE1 : A_RX_BASE0, @@ -363,6 +379,7 @@ static void xilinx_ethlite_init(Object *obj) } static const Property xilinx_ethlite_properties[] = { + DEFINE_PROP_ENDIAN_NODEFAULT("endianness", XlnxXpsEthLite, model_endianness), DEFINE_PROP_UINT32("tx-ping-pong", XlnxXpsEthLite, c_tx_pingpong, 1), DEFINE_PROP_UINT32("rx-ping-pong", XlnxXpsEthLite, c_rx_pingpong, 1), DEFINE_NIC_PROPERTIES(XlnxXpsEthLite, conf), |