qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH] hw: misc: Add Aspeed XDMA device


From: Cédric Le Goater
Subject: Re: [Qemu-devel] [PATCH] hw: misc: Add Aspeed XDMA device
Date: Tue, 11 Jun 2019 08:53:29 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.0

On 06/06/2019 23:42, Eddie James wrote:
> 
> On 6/6/19 1:16 AM, Cédric Le Goater wrote:
>> Hello Eddie,
>>
>> On 04/06/2019 00:09, Eddie James wrote:
>>> The XDMA engine embedded in the Aspeed SOCs performs PCI DMA operations
>>> between the SOC (acting as a BMC) and a host processor in a server.
>>>
>>> The XDMA engine exists on the AST2400, AST2500, and AST2600 SOCs, so
>>> enable it for all of those.
>>>
>>> Signed-off-by: Eddie James <address@hidden>
>> This looks correct to me. It's sufficient to exercise the BMC driver.
>>
>> However, we will need to rebase on an Aspeed patchset I sent earlier :
>>
>>     http://patchwork.ozlabs.org/cover/1105343/
>>
>> I can do that and include the patch in my tree for the moment.
> 
> 
> I built and tested the model on your tree, so let me know if you want me to 
> send that patch instead?

yes. I will take it into my tree and reshuffle the code if needed.

The Aspeed patchset above needs more reviews and it is blocking 
other changes.

Thanks,

C. 

 
> 
> 
>>
>>
>> For my understanding, how can we interact with the model and pretend
>> there is a host side ?
> 
> 
> I have an application that can test the driver here: 
> https://github.com/eddiejames/xdma-test
> 
> But as you say there is no host side; the operations don't copy any memory 
> anywhere. Joel suggested adding some way to copy and check some dummy memory 
> contents, but I haven't looked into that yet.
> 
> 
> Thanks,
> 
> Eddie
> 
> 
>>
>> Thanks,
>>
>> C.
>>
>>> ---
>>>   hw/arm/aspeed_soc.c           |  14 ++++
>>>   hw/misc/Makefile.objs         |   2 +-
>>>   hw/misc/aspeed_xdma.c         | 156 
>>> ++++++++++++++++++++++++++++++++++++++++++
>>>   include/hw/arm/aspeed_soc.h   |   2 +
>>>   include/hw/misc/aspeed_xdma.h |  31 +++++++++
>>>   5 files changed, 204 insertions(+), 1 deletion(-)
>>>   create mode 100644 hw/misc/aspeed_xdma.c
>>>   create mode 100644 include/hw/misc/aspeed_xdma.h
>>>
>>> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
>>> index faff42b..b25bb18 100644
>>> --- a/hw/arm/aspeed_soc.c
>>> +++ b/hw/arm/aspeed_soc.c
>>> @@ -31,6 +31,7 @@
>>>   #define ASPEED_SOC_VIC_BASE         0x1E6C0000
>>>   #define ASPEED_SOC_SDMC_BASE        0x1E6E0000
>>>   #define ASPEED_SOC_SCU_BASE         0x1E6E2000
>>> +#define ASPEED_SOC_XDMA_BASE        0x1E6E7000
>>>   #define ASPEED_SOC_SRAM_BASE        0x1E720000
>>>   #define ASPEED_SOC_TIMER_BASE       0x1E782000
>>>   #define ASPEED_SOC_WDT_BASE         0x1E785000
>>> @@ -159,6 +160,9 @@ static void aspeed_soc_init(Object *obj)
>>>         sysbus_init_child_obj(obj, "ftgmac100", OBJECT(&s->ftgmac100),
>>>                             sizeof(s->ftgmac100), TYPE_FTGMAC100);
>>> +
>>> +    sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma),
>>> +                          TYPE_ASPEED_XDMA);
>>>   }
>>>     static void aspeed_soc_realize(DeviceState *dev, Error **errp)
>>> @@ -298,6 +302,16 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
>>> **errp)
>>>       sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100), 0, 
>>> ASPEED_SOC_ETH1_BASE);
>>>       sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100), 0,
>>>                          qdev_get_gpio_in(DEVICE(&s->vic), 2));
>>> +
>>> +    /* XDMA */
>>> +    object_property_set_bool(OBJECT(&s->xdma), true, "realized", &err);
>>> +    if (err) {
>>> +        error_propagate(errp, err);
>>> +        return;
>>> +    }
>>> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->xdma), 0, ASPEED_SOC_XDMA_BASE);
>>> +    sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0,
>>> +                       qdev_get_gpio_in(DEVICE(&s->vic), 6));
>>>   }
>>>     static void aspeed_soc_class_init(ObjectClass *oc, void *data)
>>> diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
>>> index 77b9df9..a4483af 100644
>>> --- a/hw/misc/Makefile.objs
>>> +++ b/hw/misc/Makefile.objs
>>> @@ -74,7 +74,7 @@ obj-$(CONFIG_ARMSSE_MHU) += armsse-mhu.o
>>>     obj-$(CONFIG_PVPANIC) += pvpanic.o
>>>   obj-$(CONFIG_AUX) += auxbus.o
>>> -obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
>>> +obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o aspeed_xdma.o
>>>   obj-$(CONFIG_MSF2) += msf2-sysreg.o
>>>   obj-$(CONFIG_NRF51_SOC) += nrf51_rng.o
>>>   diff --git a/hw/misc/aspeed_xdma.c b/hw/misc/aspeed_xdma.c
>>> new file mode 100644
>>> index 0000000..fe3a32e
>>> --- /dev/null
>>> +++ b/hw/misc/aspeed_xdma.c
>>> @@ -0,0 +1,156 @@
>>> +/*
>>> + * ASPEED XDMA Controller
>>> + * Eddie James <address@hidden>
>>> + *
>>> + * Copyright (C) 2019 IBM Corp
>>> + * SPDX-License-Identifer: GPL-2.0-or-later
>>> + */
>>> +
>>> +#include "qemu/osdep.h"
>>> +#include "qemu/log.h"
>>> +#include "qemu/error-report.h"
>>> +#include "hw/misc/aspeed_xdma.h"
>>> +#include "qapi/error.h"
>>> +
>>> +#define XDMA_BMC_CMDQ_ADDR         0x10
>>> +#define XDMA_BMC_CMDQ_ENDP         0x14
>>> +#define XDMA_BMC_CMDQ_WRP          0x18
>>> +#define  XDMA_BMC_CMDQ_W_MASK      0x0003FFFF
>>> +#define XDMA_BMC_CMDQ_RDP          0x1C
>>> +#define  XDMA_BMC_CMDQ_RDP_MAGIC   0xEE882266
>>> +#define XDMA_IRQ_ENG_CTRL          0x20
>>> +#define  XDMA_IRQ_ENG_CTRL_US_COMP BIT(4)
>>> +#define  XDMA_IRQ_ENG_CTRL_DS_COMP BIT(5)
>>> +#define  XDMA_IRQ_ENG_CTRL_W_MASK  0xBFEFF07F
>>> +#define XDMA_IRQ_ENG_STAT          0x24
>>> +#define  XDMA_IRQ_ENG_STAT_US_COMP BIT(4)
>>> +#define  XDMA_IRQ_ENG_STAT_DS_COMP BIT(5)
>>> +#define  XDMA_IRQ_ENG_STAT_RESET   0xF8000000
>>> +
>>> +#define TO_REG(addr) ((addr) / sizeof(uint32_t))
>>> +
>>> +static uint64_t aspeed_xdma_read(void *opaque, hwaddr addr, unsigned int 
>>> size)
>>> +{
>>> +    uint32_t val = 0;
>>> +    AspeedXDMAState *xdma = opaque;
>>> +
>>> +    if (addr < ASPEED_XDMA_REG_SIZE) {
>>> +        val = xdma->regs[TO_REG(addr)];
>>> +    }
>>> +
>>> +    return (uint64_t)val;
>>> +}
>>> +
>>> +static void aspeed_xdma_write(void *opaque, hwaddr addr, uint64_t val,
>>> +                              unsigned int size)
>>> +{
>>> +    unsigned int idx;
>>> +    uint32_t val32 = (uint32_t)val;
>>> +    AspeedXDMAState *xdma = opaque;
>>> +
>>> +    if (addr >= ASPEED_XDMA_REG_SIZE) {
>>> +        return;
>>> +    }
>>> +
>>> +    switch (addr) {
>>> +    case XDMA_BMC_CMDQ_ENDP:
>>> +        xdma->regs[TO_REG(addr)] = val32 & XDMA_BMC_CMDQ_W_MASK;
>>> +        break;
>>> +    case XDMA_BMC_CMDQ_WRP:
>>> +        idx = TO_REG(addr);
>>> +        xdma->regs[idx] = val32 & XDMA_BMC_CMDQ_W_MASK;
>>> +        xdma->regs[TO_REG(XDMA_BMC_CMDQ_RDP)] = xdma->regs[idx];
>>> +
>>> +        if (xdma->bmc_cmdq_readp_set) {
>>> +            xdma->bmc_cmdq_readp_set = 0;
>>> +        } else {
>>> +            xdma->regs[TO_REG(XDMA_IRQ_ENG_STAT)] |=
>>> +                XDMA_IRQ_ENG_STAT_US_COMP | XDMA_IRQ_ENG_STAT_DS_COMP;
>>> +
>>> +            if (xdma->regs[TO_REG(XDMA_IRQ_ENG_CTRL)] &
>>> +                (XDMA_IRQ_ENG_CTRL_US_COMP | XDMA_IRQ_ENG_CTRL_DS_COMP))
>>> +                qemu_irq_raise(xdma->irq);
>>> +        }
>>> +        break;
>>> +    case XDMA_BMC_CMDQ_RDP:
>>> +        if (val32 == XDMA_BMC_CMDQ_RDP_MAGIC) {
>>> +            xdma->bmc_cmdq_readp_set = 1;
>>> +        }
>>> +        break;
>>> +    case XDMA_IRQ_ENG_CTRL:
>>> +        xdma->regs[TO_REG(addr)] = val32 & XDMA_IRQ_ENG_CTRL_W_MASK;
>>> +        break;
>>> +    case XDMA_IRQ_ENG_STAT:
>>> +        idx = TO_REG(addr);
>>> +        if (val32 & (XDMA_IRQ_ENG_STAT_US_COMP | 
>>> XDMA_IRQ_ENG_STAT_DS_COMP)) {
>>> +            xdma->regs[TO_REG(addr)] &=
>>> +                ~(XDMA_IRQ_ENG_STAT_US_COMP | XDMA_IRQ_ENG_STAT_DS_COMP);
>>> +            qemu_irq_lower(xdma->irq);
>>> +        }
>>> +        break;
>>> +    default:
>>> +        xdma->regs[TO_REG(addr)] = val32;
>>> +        break;
>>> +    }
>>> +}
>>> +
>>> +static const MemoryRegionOps aspeed_xdma_ops = {
>>> +    .read = aspeed_xdma_read,
>>> +    .write = aspeed_xdma_write,
>>> +    .endianness = DEVICE_NATIVE_ENDIAN,
>>> +    .valid.min_access_size = 4,
>>> +    .valid.max_access_size = 4,
>>> +};
>>> +
>>> +static void aspeed_xdma_realize(DeviceState *dev, Error **errp)
>>> +{
>>> +    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
>>> +    AspeedXDMAState *xdma = ASPEED_XDMA(dev);
>>> +
>>> +    sysbus_init_irq(sbd, &xdma->irq);
>>> +    memory_region_init_io(&xdma->iomem, OBJECT(xdma), &aspeed_xdma_ops, 
>>> xdma,
>>> +                          TYPE_ASPEED_XDMA, ASPEED_XDMA_MEM_SIZE);
>>> +    sysbus_init_mmio(sbd, &xdma->iomem);
>>> +}
>>> +
>>> +static void aspeed_xdma_reset(DeviceState *dev)
>>> +{
>>> +    AspeedXDMAState *xdma = ASPEED_XDMA(dev);
>>> +
>>> +    xdma->bmc_cmdq_readp_set = 0;
>>> +    memset(xdma->regs, 0, ASPEED_XDMA_REG_SIZE);
>>> +    xdma->regs[TO_REG(XDMA_IRQ_ENG_STAT)] = XDMA_IRQ_ENG_STAT_RESET;
>>> +
>>> +    qemu_irq_lower(xdma->irq);
>>> +}
>>> +
>>> +static const VMStateDescription aspeed_xdma_vmstate = {
>>> +    .name = TYPE_ASPEED_XDMA,
>>> +    .version_id = 1,
>>> +    .fields = (VMStateField[]) {
>>> +        VMSTATE_UINT32_ARRAY(regs, AspeedXDMAState, ASPEED_XDMA_NUM_REGS),
>>> +        VMSTATE_END_OF_LIST(),
>>> +    },
>>> +};
>>> +
>>> +static void aspeed_xdma_class_init(ObjectClass *classp, void *data)
>>> +{
>>> +    DeviceClass *dc = DEVICE_CLASS(classp);
>>> +
>>> +    dc->realize = aspeed_xdma_realize;
>>> +    dc->reset = aspeed_xdma_reset;
>>> +    dc->vmsd = &aspeed_xdma_vmstate;
>>> +}
>>> +
>>> +static const TypeInfo aspeed_xdma_info = {
>>> +    .name          = TYPE_ASPEED_XDMA,
>>> +    .parent        = TYPE_SYS_BUS_DEVICE,
>>> +    .instance_size = sizeof(AspeedXDMAState),
>>> +    .class_init    = aspeed_xdma_class_init,
>>> +};
>>> +
>>> +static void aspeed_xdma_register_type(void)
>>> +{
>>> +    type_register_static(&aspeed_xdma_info);
>>> +}
>>> +type_init(aspeed_xdma_register_type);
>>> diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
>>> index 836b2ba..0329247 100644
>>> --- a/include/hw/arm/aspeed_soc.h
>>> +++ b/include/hw/arm/aspeed_soc.h
>>> @@ -20,6 +20,7 @@
>>>   #include "hw/ssi/aspeed_smc.h"
>>>   #include "hw/watchdog/wdt_aspeed.h"
>>>   #include "hw/net/ftgmac100.h"
>>> +#include "hw/misc/aspeed_xdma.h"
>>>     #define ASPEED_SPIS_NUM  2
>>>   #define ASPEED_WDTS_NUM  3
>>> @@ -40,6 +41,7 @@ typedef struct AspeedSoCState {
>>>       AspeedSDMCState sdmc;
>>>       AspeedWDTState wdt[ASPEED_WDTS_NUM];
>>>       FTGMAC100State ftgmac100;
>>> +    AspeedXDMAState xdma;
>>>   } AspeedSoCState;
>>>     #define TYPE_ASPEED_SOC "aspeed-soc"
>>> diff --git a/include/hw/misc/aspeed_xdma.h b/include/hw/misc/aspeed_xdma.h
>>> new file mode 100644
>>> index 0000000..d19e9a7
>>> --- /dev/null
>>> +++ b/include/hw/misc/aspeed_xdma.h
>>> @@ -0,0 +1,31 @@
>>> +/*
>>> + * ASPEED XDMA Controller
>>> + * Eddie James <address@hidden>
>>> + *
>>> + * Copyright (C) 2019 IBM Corp.
>>> + * SPDX-License-Identifer: GPL-2.0-or-later
>>> + */
>>> +
>>> +#ifndef ASPEED_XDMA_H
>>> +#define ASPEED_XDMA_H
>>> +
>>> +#include "hw/sysbus.h"
>>> +
>>> +#define TYPE_ASPEED_XDMA "aspeed.xdma"
>>> +#define ASPEED_XDMA(obj) OBJECT_CHECK(AspeedXDMAState, (obj), 
>>> TYPE_ASPEED_XDMA)
>>> +
>>> +#define ASPEED_XDMA_MEM_SIZE 0x1000
>>> +#define ASPEED_XDMA_NUM_REGS (ASPEED_XDMA_REG_SIZE / sizeof(uint32_t))
>>> +#define ASPEED_XDMA_REG_SIZE 0x7C
>>> +
>>> +typedef struct AspeedXDMAState {
>>> +    SysBusDevice parent;
>>> +
>>> +    MemoryRegion iomem;
>>> +    qemu_irq irq;
>>> +
>>> +    char bmc_cmdq_readp_set;
>>> +    uint32_t regs[ASPEED_XDMA_NUM_REGS];
>>> +} AspeedXDMAState;
>>> +
>>> +#endif /* ASPEED_XDMA_H */
>>>
> 




reply via email to

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