Patchwork [RFC,v1,3/4] xilinx_axienet: Create Proxy object for stream

login
register
mail settings
Submitter Peter Crosthwaite
Date Feb. 12, 2013, 1:17 a.m.
Message ID <58b0886852b27b243099cc07ef9ef4da56c01f1e.1360631576.git.peter.crosthwaite@xilinx.com>
Download mbox | patch
Permalink /patch/219719/
State New
Headers show

Comments

Peter Crosthwaite - Feb. 12, 2013, 1:17 a.m.
Create a separate child object to proxy the stream slave connection. This is
setup for future work where a second stream slave connection is needed. The
new child object is created at qdev init time and is linked back to the parent
(the ethernet device itself) automatically.

Stream slave masters differentiate which slave connection they are connected to
by linking to the proxy object rather than the parent.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---

 hw/petalogix_ml605_mmu.c |    8 ++++++-
 hw/xilinx_axienet.c      |   47 ++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 50 insertions(+), 5 deletions(-)
Peter Crosthwaite - Feb. 21, 2013, 4:17 a.m.
Ping!

Edgar merged patches 1&2 (trivials) before he went on vacation, but
left this out because he wanted to give everyone a chance to review in
the context of the active QOM discussions. I probably should have ccd
Paolo as this little sub system started way back with his refactoring
of axienet to get rid of the DEFINE_PROP_PTRs we had there.

Regards,
Peter

On Tue, Feb 12, 2013 at 11:17 AM, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> Create a separate child object to proxy the stream slave connection. This is
> setup for future work where a second stream slave connection is needed. The
> new child object is created at qdev init time and is linked back to the parent
> (the ethernet device itself) automatically.
>
> Stream slave masters differentiate which slave connection they are connected to
> by linking to the proxy object rather than the parent.
>
> Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
> ---
>
>  hw/petalogix_ml605_mmu.c |    8 ++++++-
>  hw/xilinx_axienet.c      |   47 ++++++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 50 insertions(+), 5 deletions(-)
>
> diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
> index 82d7183..3636993 100644
> --- a/hw/petalogix_ml605_mmu.c
> +++ b/hw/petalogix_ml605_mmu.c
> @@ -79,6 +79,7 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
>      const char *cpu_model = args->cpu_model;
>      MemoryRegion *address_space_mem = get_system_memory();
>      DeviceState *dev, *dma, *eth0;
> +    Object *peer;
>      MicroBlazeCPU *cpu;
>      SysBusDevice *busdev;
>      CPUMBState *env;
> @@ -136,11 +137,16 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
>      /* FIXME: attach to the sysbus instead */
>      object_property_add_child(container_get(qdev_get_machine(), "/unattached"),
>                                    "xilinx-dma", OBJECT(dma), NULL);
> +    object_property_add_child(container_get(qdev_get_machine(), "/unattached"),
> +                                  "xilinx-eth0", OBJECT(eth0), NULL);
>
>      xilinx_axiethernet_init(eth0, &nd_table[0], STREAM_SLAVE(dma),
>                                     0x82780000, irq[3], 0x1000, 0x1000);
>
> -    xilinx_axidma_init(dma, STREAM_SLAVE(eth0), 0x84600000, irq[1], irq[0],
> +    peer = object_property_get_link(OBJECT(eth0), "data-stream", NULL);
> +    assert(peer);
> +
> +    xilinx_axidma_init(dma, STREAM_SLAVE(peer), 0x84600000, irq[1], irq[0],
>                         100 * 1000000);
>
>      {
> diff --git a/hw/xilinx_axienet.c b/hw/xilinx_axienet.c
> index 34e344c..7adb24d 100644
> --- a/hw/xilinx_axienet.c
> +++ b/hw/xilinx_axienet.c
> @@ -364,6 +364,18 @@ struct XilinxAXIEnet {
>      uint8_t *rxmem;
>  };
>
> +#define TYPE_XILINX_AXI_ENET_DATA_STREAM "xilinx-axienet-data-stream"
> +
> +#define XILINX_AXI_ENET_DATA_STREAM(obj) \
> +     OBJECT_CHECK(XilinxAXIEnetStreamSlave, (obj),\
> +     TYPE_XILINX_AXI_ENET_DATA_STREAM)
> +
> +typedef struct XilinxAXIEnetStreamSlave {
> +    Object parent;
> +
> +    struct XilinxAXIEnet *enet;
> +} XilinxAXIEnetStreamSlave;
> +
>  static void axienet_rx_reset(struct XilinxAXIEnet *s)
>  {
>      s->rcw[1] = RCW1_JUM | RCW1_FCS | RCW1_RX | RCW1_VLAN;
> @@ -791,9 +803,11 @@ static void eth_cleanup(NetClientState *nc)
>  }
>
>  static void
> -axienet_stream_push(StreamSlave *obj, uint8_t *buf, size_t size, uint32_t *hdr)
> +axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size,
> +                         uint32_t *hdr)
>  {
> -    struct XilinxAXIEnet *s = FROM_SYSBUS(typeof(*s), SYS_BUS_DEVICE(obj));
> +    XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(obj);
> +    struct XilinxAXIEnet *s = ds->enet;
>
>      /* TX enable ?  */
>      if (!(s->tc & TC_TX)) {
> @@ -844,6 +858,17 @@ static NetClientInfo net_xilinx_enet_info = {
>  static int xilinx_enet_init(SysBusDevice *dev)
>  {
>      struct XilinxAXIEnet *s = FROM_SYSBUS(typeof(*s), dev);
> +    XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(
> +                        object_new(TYPE_XILINX_AXI_ENET_DATA_STREAM));
> +    Error *errp = NULL;
> +
> +    object_property_add_child(OBJECT(s), "data-stream", (Object *)ds, &errp);
> +    assert_no_error(errp);
> +    object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet",
> +                             (Object **) &ds->enet, &errp);
> +    assert_no_error(errp);
> +    object_property_set_link(OBJECT(ds), OBJECT(s), "enet", &errp);
> +    assert_no_error(errp);
>
>      sysbus_init_irq(dev, &s->irq);
>
> @@ -886,11 +911,16 @@ static void xilinx_enet_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
>      SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
> -    StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
>
>      k->init = xilinx_enet_init;
>      dc->props = xilinx_enet_properties;
> -    ssc->push = axienet_stream_push;
> +}
> +
> +static void xilinx_enet_stream_class_init(ObjectClass *klass, void *data)
> +{
> +    StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
> +
> +    ssc->push = data;
>  }
>
>  static const TypeInfo xilinx_enet_info = {
> @@ -899,6 +929,14 @@ static const TypeInfo xilinx_enet_info = {
>      .instance_size = sizeof(struct XilinxAXIEnet),
>      .class_init    = xilinx_enet_class_init,
>      .instance_init = xilinx_enet_initfn,
> +};
> +
> +static const TypeInfo xilinx_enet_data_stream_info = {
> +    .name          = TYPE_XILINX_AXI_ENET_DATA_STREAM,
> +    .parent        = TYPE_OBJECT,
> +    .instance_size = sizeof(struct XilinxAXIEnetStreamSlave),
> +    .class_init    = xilinx_enet_stream_class_init,
> +    .class_data    = axienet_data_stream_push,
>      .interfaces = (InterfaceInfo[]) {
>              { TYPE_STREAM_SLAVE },
>              { }
> @@ -908,6 +946,7 @@ static const TypeInfo xilinx_enet_info = {
>  static void xilinx_enet_register_types(void)
>  {
>      type_register_static(&xilinx_enet_info);
> +    type_register_static(&xilinx_enet_data_stream_info);
>  }
>
>  type_init(xilinx_enet_register_types)
> --
> 1.7.0.4
>
Andreas Färber - Feb. 21, 2013, 4:49 a.m.
Am 21.02.2013 05:17, schrieb Peter Crosthwaite:
> Ping!
> 
> Edgar merged patches 1&2 (trivials) before he went on vacation, but
> left this out because he wanted to give everyone a chance to review in
> the context of the active QOM discussions. I probably should have ccd
> Paolo as this little sub system started way back with his refactoring
> of axienet to get rid of the DEFINE_PROP_PTRs we had there.

I'm sorry, I don't fully understand the current code or the changes
you're applying... Some minor comments below.

> On Tue, Feb 12, 2013 at 11:17 AM, Peter Crosthwaite
> <peter.crosthwaite@xilinx.com> wrote:
>> Create a separate child object to proxy the stream slave connection. This is
>> setup for future work where a second stream slave connection is needed. The
>> new child object is created at qdev init time and is linked back to the parent
>> (the ethernet device itself) automatically.
>>
>> Stream slave masters differentiate which slave connection they are connected to
>> by linking to the proxy object rather than the parent.
>>
>> Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
>> ---
>>
>>  hw/petalogix_ml605_mmu.c |    8 ++++++-
>>  hw/xilinx_axienet.c      |   47 ++++++++++++++++++++++++++++++++++++++++++---
>>  2 files changed, 50 insertions(+), 5 deletions(-)
>>
>> diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
>> index 82d7183..3636993 100644
>> --- a/hw/petalogix_ml605_mmu.c
>> +++ b/hw/petalogix_ml605_mmu.c
>> @@ -79,6 +79,7 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
>>      const char *cpu_model = args->cpu_model;
>>      MemoryRegion *address_space_mem = get_system_memory();
>>      DeviceState *dev, *dma, *eth0;
>> +    Object *peer;
>>      MicroBlazeCPU *cpu;
>>      SysBusDevice *busdev;
>>      CPUMBState *env;
>> @@ -136,11 +137,16 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
>>      /* FIXME: attach to the sysbus instead */
>>      object_property_add_child(container_get(qdev_get_machine(), "/unattached"),
>>                                    "xilinx-dma", OBJECT(dma), NULL);
>> +    object_property_add_child(container_get(qdev_get_machine(), "/unattached"),
>> +                                  "xilinx-eth0", OBJECT(eth0), NULL);

Why are you adding properties to /machine/unassigned? It's your machine
so you can add things to /machine as you like, modulo Anthony's ABI
stability rules (no type changes for existing properties).

Copied indentation looks a bit weird btw.

>>
>>      xilinx_axiethernet_init(eth0, &nd_table[0], STREAM_SLAVE(dma),
>>                                     0x82780000, irq[3], 0x1000, 0x1000);
>>
>> -    xilinx_axidma_init(dma, STREAM_SLAVE(eth0), 0x84600000, irq[1], irq[0],
>> +    peer = object_property_get_link(OBJECT(eth0), "data-stream", NULL);
>> +    assert(peer);
>> +
>> +    xilinx_axidma_init(dma, STREAM_SLAVE(peer), 0x84600000, irq[1], irq[0],
>>                         100 * 1000000);
>>
>>      {
>> diff --git a/hw/xilinx_axienet.c b/hw/xilinx_axienet.c
>> index 34e344c..7adb24d 100644
>> --- a/hw/xilinx_axienet.c
>> +++ b/hw/xilinx_axienet.c
>> @@ -364,6 +364,18 @@ struct XilinxAXIEnet {
>>      uint8_t *rxmem;
>>  };
>>
>> +#define TYPE_XILINX_AXI_ENET_DATA_STREAM "xilinx-axienet-data-stream"
>> +
>> +#define XILINX_AXI_ENET_DATA_STREAM(obj) \
>> +     OBJECT_CHECK(XilinxAXIEnetStreamSlave, (obj),\
>> +     TYPE_XILINX_AXI_ENET_DATA_STREAM)
>> +
>> +typedef struct XilinxAXIEnetStreamSlave {
>> +    Object parent;
>> +
>> +    struct XilinxAXIEnet *enet;
>> +} XilinxAXIEnetStreamSlave;
>> +
>>  static void axienet_rx_reset(struct XilinxAXIEnet *s)
>>  {
>>      s->rcw[1] = RCW1_JUM | RCW1_FCS | RCW1_RX | RCW1_VLAN;
>> @@ -791,9 +803,11 @@ static void eth_cleanup(NetClientState *nc)
>>  }
>>
>>  static void
>> -axienet_stream_push(StreamSlave *obj, uint8_t *buf, size_t size, uint32_t *hdr)
>> +axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size,
>> +                         uint32_t *hdr)
>>  {
>> -    struct XilinxAXIEnet *s = FROM_SYSBUS(typeof(*s), SYS_BUS_DEVICE(obj));
>> +    XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(obj);
>> +    struct XilinxAXIEnet *s = ds->enet;
>>
>>      /* TX enable ?  */
>>      if (!(s->tc & TC_TX)) {
>> @@ -844,6 +858,17 @@ static NetClientInfo net_xilinx_enet_info = {
>>  static int xilinx_enet_init(SysBusDevice *dev)
>>  {
>>      struct XilinxAXIEnet *s = FROM_SYSBUS(typeof(*s), dev);
>> +    XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(
>> +                        object_new(TYPE_XILINX_AXI_ENET_DATA_STREAM));
>> +    Error *errp = NULL;

This SysBus initfn function will at some point need to be turned into a
realize function, which gets an Error **errp argument. If you want to do
local error checking, better to name this err, error or local_err to
leave errp for Error** argument.
Keep in mind that there is no guarantee that errp will be non-NULL, thus
the possible need for a local Error* despite Error** argument.

>> +
>> +    object_property_add_child(OBJECT(s), "data-stream", (Object *)ds, &errp);
>> +    assert_no_error(errp);
>> +    object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet",
>> +                             (Object **) &ds->enet, &errp);
>> +    assert_no_error(errp);
>> +    object_property_set_link(OBJECT(ds), OBJECT(s), "enet", &errp);
>> +    assert_no_error(errp);

This should not assert but be turned into a realize function and set
errp argument via error_propagate() and return.

>>
>>      sysbus_init_irq(dev, &s->irq);

Outside the scope of this patch, but this looks like a candidate for
instance_init, to allow connecting IRQs before realization.

>>
>> @@ -886,11 +911,16 @@ static void xilinx_enet_class_init(ObjectClass *klass, void *data)
>>  {
>>      DeviceClass *dc = DEVICE_CLASS(klass);
>>      SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
>> -    StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
>>
>>      k->init = xilinx_enet_init;
>>      dc->props = xilinx_enet_properties;
>> -    ssc->push = axienet_stream_push;
>> +}
>> +
>> +static void xilinx_enet_stream_class_init(ObjectClass *klass, void *data)
>> +{
>> +    StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
>> +
>> +    ssc->push = data;
>>  }
>>
>>  static const TypeInfo xilinx_enet_info = {
>> @@ -899,6 +929,14 @@ static const TypeInfo xilinx_enet_info = {
>>      .instance_size = sizeof(struct XilinxAXIEnet),
>>      .class_init    = xilinx_enet_class_init,
>>      .instance_init = xilinx_enet_initfn,
>> +};
>> +
>> +static const TypeInfo xilinx_enet_data_stream_info = {
>> +    .name          = TYPE_XILINX_AXI_ENET_DATA_STREAM,
>> +    .parent        = TYPE_OBJECT,
>> +    .instance_size = sizeof(struct XilinxAXIEnetStreamSlave),
>> +    .class_init    = xilinx_enet_stream_class_init,
>> +    .class_data    = axienet_data_stream_push,

Why pass a single function as .class_data rather than setting it in
xilinx_enet_stream_class_init() directly without void* in between?

>>      .interfaces = (InterfaceInfo[]) {
>>              { TYPE_STREAM_SLAVE },
>>              { }
>> @@ -908,6 +946,7 @@ static const TypeInfo xilinx_enet_info = {
>>  static void xilinx_enet_register_types(void)
>>  {
>>      type_register_static(&xilinx_enet_info);
>> +    type_register_static(&xilinx_enet_data_stream_info);
>>  }
>>
>>  type_init(xilinx_enet_register_types)
>> --
>> 1.7.0.4

Cheers,
Andreas

Patch

diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
index 82d7183..3636993 100644
--- a/hw/petalogix_ml605_mmu.c
+++ b/hw/petalogix_ml605_mmu.c
@@ -79,6 +79,7 @@  petalogix_ml605_init(QEMUMachineInitArgs *args)
     const char *cpu_model = args->cpu_model;
     MemoryRegion *address_space_mem = get_system_memory();
     DeviceState *dev, *dma, *eth0;
+    Object *peer;
     MicroBlazeCPU *cpu;
     SysBusDevice *busdev;
     CPUMBState *env;
@@ -136,11 +137,16 @@  petalogix_ml605_init(QEMUMachineInitArgs *args)
     /* FIXME: attach to the sysbus instead */
     object_property_add_child(container_get(qdev_get_machine(), "/unattached"),
                                   "xilinx-dma", OBJECT(dma), NULL);
+    object_property_add_child(container_get(qdev_get_machine(), "/unattached"),
+                                  "xilinx-eth0", OBJECT(eth0), NULL);
 
     xilinx_axiethernet_init(eth0, &nd_table[0], STREAM_SLAVE(dma),
                                    0x82780000, irq[3], 0x1000, 0x1000);
 
-    xilinx_axidma_init(dma, STREAM_SLAVE(eth0), 0x84600000, irq[1], irq[0],
+    peer = object_property_get_link(OBJECT(eth0), "data-stream", NULL);
+    assert(peer);
+
+    xilinx_axidma_init(dma, STREAM_SLAVE(peer), 0x84600000, irq[1], irq[0],
                        100 * 1000000);
 
     {
diff --git a/hw/xilinx_axienet.c b/hw/xilinx_axienet.c
index 34e344c..7adb24d 100644
--- a/hw/xilinx_axienet.c
+++ b/hw/xilinx_axienet.c
@@ -364,6 +364,18 @@  struct XilinxAXIEnet {
     uint8_t *rxmem;
 };
 
+#define TYPE_XILINX_AXI_ENET_DATA_STREAM "xilinx-axienet-data-stream"
+
+#define XILINX_AXI_ENET_DATA_STREAM(obj) \
+     OBJECT_CHECK(XilinxAXIEnetStreamSlave, (obj),\
+     TYPE_XILINX_AXI_ENET_DATA_STREAM)
+
+typedef struct XilinxAXIEnetStreamSlave {
+    Object parent;
+
+    struct XilinxAXIEnet *enet;
+} XilinxAXIEnetStreamSlave;
+
 static void axienet_rx_reset(struct XilinxAXIEnet *s)
 {
     s->rcw[1] = RCW1_JUM | RCW1_FCS | RCW1_RX | RCW1_VLAN;
@@ -791,9 +803,11 @@  static void eth_cleanup(NetClientState *nc)
 }
 
 static void
-axienet_stream_push(StreamSlave *obj, uint8_t *buf, size_t size, uint32_t *hdr)
+axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size,
+                         uint32_t *hdr)
 {
-    struct XilinxAXIEnet *s = FROM_SYSBUS(typeof(*s), SYS_BUS_DEVICE(obj));
+    XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(obj);
+    struct XilinxAXIEnet *s = ds->enet;
 
     /* TX enable ?  */
     if (!(s->tc & TC_TX)) {
@@ -844,6 +858,17 @@  static NetClientInfo net_xilinx_enet_info = {
 static int xilinx_enet_init(SysBusDevice *dev)
 {
     struct XilinxAXIEnet *s = FROM_SYSBUS(typeof(*s), dev);
+    XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(
+                        object_new(TYPE_XILINX_AXI_ENET_DATA_STREAM));
+    Error *errp = NULL;
+
+    object_property_add_child(OBJECT(s), "data-stream", (Object *)ds, &errp);
+    assert_no_error(errp);
+    object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet",
+                             (Object **) &ds->enet, &errp);
+    assert_no_error(errp);
+    object_property_set_link(OBJECT(ds), OBJECT(s), "enet", &errp);
+    assert_no_error(errp);
 
     sysbus_init_irq(dev, &s->irq);
 
@@ -886,11 +911,16 @@  static void xilinx_enet_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-    StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
 
     k->init = xilinx_enet_init;
     dc->props = xilinx_enet_properties;
-    ssc->push = axienet_stream_push;
+}
+
+static void xilinx_enet_stream_class_init(ObjectClass *klass, void *data)
+{
+    StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
+
+    ssc->push = data;
 }
 
 static const TypeInfo xilinx_enet_info = {
@@ -899,6 +929,14 @@  static const TypeInfo xilinx_enet_info = {
     .instance_size = sizeof(struct XilinxAXIEnet),
     .class_init    = xilinx_enet_class_init,
     .instance_init = xilinx_enet_initfn,
+};
+
+static const TypeInfo xilinx_enet_data_stream_info = {
+    .name          = TYPE_XILINX_AXI_ENET_DATA_STREAM,
+    .parent        = TYPE_OBJECT,
+    .instance_size = sizeof(struct XilinxAXIEnetStreamSlave),
+    .class_init    = xilinx_enet_stream_class_init,
+    .class_data    = axienet_data_stream_push,
     .interfaces = (InterfaceInfo[]) {
             { TYPE_STREAM_SLAVE },
             { }
@@ -908,6 +946,7 @@  static const TypeInfo xilinx_enet_info = {
 static void xilinx_enet_register_types(void)
 {
     type_register_static(&xilinx_enet_info);
+    type_register_static(&xilinx_enet_data_stream_info);
 }
 
 type_init(xilinx_enet_register_types)