diff mbox series

[22/44] Add GENET stub

Message ID 20230726132512.149618-23-sergey.kambalin@auriga.com (mailing list archive)
State New, archived
Headers show
Series Raspberry Pi 4B machine | expand

Commit Message

Sergey Kambalin July 26, 2023, 1:24 p.m. UTC
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

Comments

Peter Maydell Aug. 4, 2023, 2:47 p.m. UTC | #1
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 mbox series

Patch

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 */