qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC PATCH v1 3/4] xilinx_axienet: Create Proxy object


From: Andreas Färber
Subject: Re: [Qemu-devel] [RFC PATCH v1 3/4] xilinx_axienet: Create Proxy object for stream
Date: Thu, 21 Feb 2013 05:49:25 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130105 Thunderbird/17.0.2

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
> <address@hidden> 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 <address@hidden>
>> ---
>>
>>  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

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg



reply via email to

[Prev in Thread] Current Thread [Next in Thread]