Message ID | 20230726132512.149618-23-sergey.kambalin@auriga.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Raspberry Pi 4B machine | expand |
On Wed, 26 Jul 2023 at 14:53, Sergey Kambalin <serg.oker@gmail.com> wrote: > > Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com> > --- > hw/net/bcm2838_genet.c | 100 +++++++++++++++++++++++++++++++++ > hw/net/meson.build | 2 + > hw/net/trace-events | 17 ++++++ > include/hw/net/bcm2838_genet.h | 40 +++++++++++++ > 4 files changed, 159 insertions(+) > create mode 100644 hw/net/bcm2838_genet.c > create mode 100644 include/hw/net/bcm2838_genet.h > > diff --git a/hw/net/bcm2838_genet.c b/hw/net/bcm2838_genet.c > new file mode 100644 > index 0000000000..c3e7d90451 > --- /dev/null > +++ b/hw/net/bcm2838_genet.c > @@ -0,0 +1,100 @@ > +/* > + * BCM2838 Gigabit Ethernet emulation > + * > + * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com> > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#include "qemu/osdep.h" > +#include "qemu/module.h" > +#include "qemu/log.h" > +#include "qemu/error-report.h" > +#include "net/eth.h" > +#include "qapi/error.h" > +#include "hw/irq.h" > +#include "net/checksum.h" > +#include "sysemu/dma.h" > +#include "hw/net/bcm2838_genet.h" > +#include "trace.h" > + > + > +static uint64_t bcm2838_genet_read(void *opaque, hwaddr offset, unsigned size) > +{ > + uint64_t value = ~0; > + > + qemu_log_mask( > + LOG_GUEST_ERROR, > + "%s: out-of-range access, %u bytes @ offset 0x%04" PRIx64 "\n", > + __func__, size, offset); > + > + trace_bcm2838_genet_read(size, offset, value); > + return value; > +} > + > +static void bcm2838_genet_write(void *opaque, hwaddr offset, uint64_t value, > + unsigned size) { > + qemu_log_mask( > + LOG_GUEST_ERROR, > + "%s: out-of-range access, %u bytes @ offset 0x%04" PRIx64 "\n", > + __func__, size, offset); tracepoint on the read but not on the write ? > +} > + > +static const MemoryRegionOps bcm2838_genet_ops = { > + .read = bcm2838_genet_read, > + .write = bcm2838_genet_write, > + .endianness = DEVICE_NATIVE_ENDIAN, > + .impl = {.max_access_size = sizeof(uint32_t)}, > + .valid = {.min_access_size = sizeof(uint32_t)}, Just say 4, please. Do you definitely need to support all of 1, 2 and 4 byte accesses? (The implementation gets more painful then.) > +}; > + > + > +static void bcm2838_genet_realize(DeviceState *dev, Error **errp) > +{ > + BCM2838GenetState *s = BCM2838_GENET(dev); > + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); > + > + /* Controller registers */ > + memory_region_init_io(&s->regs_mr, OBJECT(s), &bcm2838_genet_ops, s, > + "bcm2838_genet_regs", sizeof(s->regs)); > + sysbus_init_mmio(sbd, &s->regs_mr); > +} > + > +static void bcm2838_genet_phy_reset(BCM2838GenetState *s) > +{ > + /* Temporary unimplemented */ "Temporarily" (though you don't really need to say that in a stub-device commit). > + trace_bcm2838_genet_phy_reset("done"); > +} > + > +static void bcm2838_genet_reset(DeviceState *d) > +{ > + BCM2838GenetState *s = BCM2838_GENET(d); > + > + memset(&s->regs, 0x00, sizeof(s->regs)); > + > + trace_bcm2838_genet_reset("done"); > + > + bcm2838_genet_phy_reset(s); > +} > + > +static void bcm2838_genet_class_init(ObjectClass *class, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(class); > + > + dc->realize = bcm2838_genet_realize; > + dc->reset = bcm2838_genet_reset; > +} > + > +static const TypeInfo bcm2838_genet_info = { > + .name = TYPE_BCM2838_GENET, > + .parent = TYPE_SYS_BUS_DEVICE, > + .instance_size = sizeof(BCM2838GenetState), > + .class_init = bcm2838_genet_class_init, > +}; > + > +static void bcm2838_genet_register(void) > +{ > + type_register_static(&bcm2838_genet_info); > +} > + > +type_init(bcm2838_genet_register) > diff --git a/hw/net/meson.build b/hw/net/meson.build > index 2632634df3..9bb01f45e2 100644 > --- a/hw/net/meson.build > +++ b/hw/net/meson.build > @@ -72,4 +72,6 @@ system_ss.add(when: 'CONFIG_ROCKER', if_true: files( > system_ss.add(when: 'CONFIG_ALL', if_true: files('rocker/qmp-norocker.c')) > system_ss.add(files('rocker/rocker-hmp-cmds.c')) > > +system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2838_genet.c')) > + > subdir('can') > diff --git a/hw/net/trace-events b/hw/net/trace-events > index 6b5ba669a2..f9e4f76776 100644 > --- a/hw/net/trace-events > +++ b/hw/net/trace-events > @@ -480,3 +480,20 @@ dp8393x_receive_oversize(int size) "oversize packet, pkt_size is %d" > dp8393x_receive_not_netcard(void) "packet not for netcard" > dp8393x_receive_packet(int crba) "Receive packet at 0x%"PRIx32 > dp8393x_receive_write_status(int crba) "Write status at 0x%"PRIx32 > + > +# bcm2838_genet.c > +bcm2838_genet_read(unsigned int size, uint64_t offset, uint64_t value) "%u bytes @ 0x%04" PRIx64 ": 0x%016" PRIx64 > +bcm2838_genet_write(unsigned int size, uint64_t offset, uint64_t value) "%u bytes @ 0x%04" PRIx64 ": 0x%016" PRIx64 > +bcm2838_genet_can_receive(const char *state) "receive is %s" > +bcm2838_genet_receive(ssize_t bytes_received) "%ld bytes received" %ld in a printf format string for some type other than "long" isn't portable -- long is 4 bytes on 32-bit hosts and 8 bytes on 64-bit hosts, so depending on what you passed it tends not to compile. Always use the right format string for the type you're printing. For a ssize_t type that is "%zd". > +bcm2838_genet_phy_update_link(const char *link_state) "link is %s" > +bcm2838_genet_phy_reset(const char *status) "PHY reset %s" > +bcm2838_genet_reset(const char *status) "MAC reset %s" > +bcm2838_genet_mac_address(const char *info) "%s" > +bcm2838_genet_tx_dma(const char *dma_state) "TX DMA %s" > +bcm2838_genet_tx_dma_ring(uint32_t ring_en) "TX DMA enabled rings: 0x%05x" > +bcm2838_genet_tx_dma_ring_buf(uint32_t ring_buf_en) "TX DMA enabled ring buffers: 0x%05x" > +bcm2838_genet_tx_dma_ring_active(unsigned int ring, const char *ring_state) "ring %u is %s" > +bcm2838_genet_tx_request(unsigned int ring_idx, uint32_t prod_idx, uint32_t cons_idx) "ring %u, PROD_INDEX %u, CONS_INDEX %u" > +bcm2838_genet_tx(unsigned int ring_idx, uint64_t desc_idx, uint32_t desc_status, uint64_t data_addr) "ring %u, descriptor %" PRIu64 ": 0x%08x, data @ 0x%08" PRIx64 > +bcm2838_genet_rx_dma_ring_active(unsigned int ring, const char *ring_state) "ring %u is %s" > diff --git a/include/hw/net/bcm2838_genet.h b/include/hw/net/bcm2838_genet.h > new file mode 100644 > index 0000000000..f62b24fa2f > --- /dev/null > +++ b/include/hw/net/bcm2838_genet.h > @@ -0,0 +1,40 @@ > +/* > + * BCM2838 Gigabit Ethernet emulation > + * > + * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com> > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#ifndef BCM2838_GENET_H > +#define BCM2838_GENET_H > + > +#include "net/net.h" > +#include "hw/sysbus.h" > + > +#define TYPE_BCM2838_GENET "bcm2838-genet" > +OBJECT_DECLARE_SIMPLE_TYPE(BCM2838GenetState, BCM2838_GENET) > + > +#define BCM2838_GENET_REV_MAJOR 6 > +#define BCM2838_GENET_REV_MINOR 0 > + > +typedef struct { > + uint8_t stub_area[0x10000]; /* temporary stub */ > +} __attribute__((__packed__)) BCM2838GenetRegs; Why is this attribute(packed) ? You almost certainly do not want this, especially given it's a byte buffer anyway. > + > +struct BCM2838GenetState { > + /*< private >*/ > + SysBusDevice parent_obj; > + > + /*< public >*/ > + > + MemoryRegion regs_mr; > + AddressSpace dma_as; > + > + BCM2838GenetRegs regs; > + > + qemu_irq irq_default; > + qemu_irq irq_prio; > +}; > + > +#endif /* BCM2838_GENET_H */ thanks -- PMM
diff --git a/hw/net/bcm2838_genet.c b/hw/net/bcm2838_genet.c new file mode 100644 index 0000000000..c3e7d90451 --- /dev/null +++ b/hw/net/bcm2838_genet.c @@ -0,0 +1,100 @@ +/* + * BCM2838 Gigabit Ethernet emulation + * + * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/module.h" +#include "qemu/log.h" +#include "qemu/error-report.h" +#include "net/eth.h" +#include "qapi/error.h" +#include "hw/irq.h" +#include "net/checksum.h" +#include "sysemu/dma.h" +#include "hw/net/bcm2838_genet.h" +#include "trace.h" + + +static uint64_t bcm2838_genet_read(void *opaque, hwaddr offset, unsigned size) +{ + uint64_t value = ~0; + + qemu_log_mask( + LOG_GUEST_ERROR, + "%s: out-of-range access, %u bytes @ offset 0x%04" PRIx64 "\n", + __func__, size, offset); + + trace_bcm2838_genet_read(size, offset, value); + return value; +} + +static void bcm2838_genet_write(void *opaque, hwaddr offset, uint64_t value, + unsigned size) { + qemu_log_mask( + LOG_GUEST_ERROR, + "%s: out-of-range access, %u bytes @ offset 0x%04" PRIx64 "\n", + __func__, size, offset); +} + +static const MemoryRegionOps bcm2838_genet_ops = { + .read = bcm2838_genet_read, + .write = bcm2838_genet_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = {.max_access_size = sizeof(uint32_t)}, + .valid = {.min_access_size = sizeof(uint32_t)}, +}; + + +static void bcm2838_genet_realize(DeviceState *dev, Error **errp) +{ + BCM2838GenetState *s = BCM2838_GENET(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + + /* Controller registers */ + memory_region_init_io(&s->regs_mr, OBJECT(s), &bcm2838_genet_ops, s, + "bcm2838_genet_regs", sizeof(s->regs)); + sysbus_init_mmio(sbd, &s->regs_mr); +} + +static void bcm2838_genet_phy_reset(BCM2838GenetState *s) +{ + /* Temporary unimplemented */ + trace_bcm2838_genet_phy_reset("done"); +} + +static void bcm2838_genet_reset(DeviceState *d) +{ + BCM2838GenetState *s = BCM2838_GENET(d); + + memset(&s->regs, 0x00, sizeof(s->regs)); + + trace_bcm2838_genet_reset("done"); + + bcm2838_genet_phy_reset(s); +} + +static void bcm2838_genet_class_init(ObjectClass *class, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(class); + + dc->realize = bcm2838_genet_realize; + dc->reset = bcm2838_genet_reset; +} + +static const TypeInfo bcm2838_genet_info = { + .name = TYPE_BCM2838_GENET, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(BCM2838GenetState), + .class_init = bcm2838_genet_class_init, +}; + +static void bcm2838_genet_register(void) +{ + type_register_static(&bcm2838_genet_info); +} + +type_init(bcm2838_genet_register) diff --git a/hw/net/meson.build b/hw/net/meson.build index 2632634df3..9bb01f45e2 100644 --- a/hw/net/meson.build +++ b/hw/net/meson.build @@ -72,4 +72,6 @@ system_ss.add(when: 'CONFIG_ROCKER', if_true: files( system_ss.add(when: 'CONFIG_ALL', if_true: files('rocker/qmp-norocker.c')) system_ss.add(files('rocker/rocker-hmp-cmds.c')) +system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2838_genet.c')) + subdir('can') diff --git a/hw/net/trace-events b/hw/net/trace-events index 6b5ba669a2..f9e4f76776 100644 --- a/hw/net/trace-events +++ b/hw/net/trace-events @@ -480,3 +480,20 @@ dp8393x_receive_oversize(int size) "oversize packet, pkt_size is %d" dp8393x_receive_not_netcard(void) "packet not for netcard" dp8393x_receive_packet(int crba) "Receive packet at 0x%"PRIx32 dp8393x_receive_write_status(int crba) "Write status at 0x%"PRIx32 + +# bcm2838_genet.c +bcm2838_genet_read(unsigned int size, uint64_t offset, uint64_t value) "%u bytes @ 0x%04" PRIx64 ": 0x%016" PRIx64 +bcm2838_genet_write(unsigned int size, uint64_t offset, uint64_t value) "%u bytes @ 0x%04" PRIx64 ": 0x%016" PRIx64 +bcm2838_genet_can_receive(const char *state) "receive is %s" +bcm2838_genet_receive(ssize_t bytes_received) "%ld bytes received" +bcm2838_genet_phy_update_link(const char *link_state) "link is %s" +bcm2838_genet_phy_reset(const char *status) "PHY reset %s" +bcm2838_genet_reset(const char *status) "MAC reset %s" +bcm2838_genet_mac_address(const char *info) "%s" +bcm2838_genet_tx_dma(const char *dma_state) "TX DMA %s" +bcm2838_genet_tx_dma_ring(uint32_t ring_en) "TX DMA enabled rings: 0x%05x" +bcm2838_genet_tx_dma_ring_buf(uint32_t ring_buf_en) "TX DMA enabled ring buffers: 0x%05x" +bcm2838_genet_tx_dma_ring_active(unsigned int ring, const char *ring_state) "ring %u is %s" +bcm2838_genet_tx_request(unsigned int ring_idx, uint32_t prod_idx, uint32_t cons_idx) "ring %u, PROD_INDEX %u, CONS_INDEX %u" +bcm2838_genet_tx(unsigned int ring_idx, uint64_t desc_idx, uint32_t desc_status, uint64_t data_addr) "ring %u, descriptor %" PRIu64 ": 0x%08x, data @ 0x%08" PRIx64 +bcm2838_genet_rx_dma_ring_active(unsigned int ring, const char *ring_state) "ring %u is %s" diff --git a/include/hw/net/bcm2838_genet.h b/include/hw/net/bcm2838_genet.h new file mode 100644 index 0000000000..f62b24fa2f --- /dev/null +++ b/include/hw/net/bcm2838_genet.h @@ -0,0 +1,40 @@ +/* + * BCM2838 Gigabit Ethernet emulation + * + * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef BCM2838_GENET_H +#define BCM2838_GENET_H + +#include "net/net.h" +#include "hw/sysbus.h" + +#define TYPE_BCM2838_GENET "bcm2838-genet" +OBJECT_DECLARE_SIMPLE_TYPE(BCM2838GenetState, BCM2838_GENET) + +#define BCM2838_GENET_REV_MAJOR 6 +#define BCM2838_GENET_REV_MINOR 0 + +typedef struct { + uint8_t stub_area[0x10000]; /* temporary stub */ +} __attribute__((__packed__)) BCM2838GenetRegs; + +struct BCM2838GenetState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + + MemoryRegion regs_mr; + AddressSpace dma_as; + + BCM2838GenetRegs regs; + + qemu_irq irq_default; + qemu_irq irq_prio; +}; + +#endif /* BCM2838_GENET_H */
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com> --- hw/net/bcm2838_genet.c | 100 +++++++++++++++++++++++++++++++++ hw/net/meson.build | 2 + hw/net/trace-events | 17 ++++++ include/hw/net/bcm2838_genet.h | 40 +++++++++++++ 4 files changed, 159 insertions(+) create mode 100644 hw/net/bcm2838_genet.c create mode 100644 include/hw/net/bcm2838_genet.h