qemu-ppc
[Top][All Lists]
Advanced

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

Re: [Qemu-ppc] [PATCH v4 06/20] ppc/pnv: add XSCOM infrastructure


From: Cédric Le Goater
Subject: Re: [Qemu-ppc] [PATCH v4 06/20] ppc/pnv: add XSCOM infrastructure
Date: Thu, 13 Oct 2016 08:26:14 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0

On 10/13/2016 02:41 AM, David Gibson wrote:
> On Mon, Oct 03, 2016 at 09:24:42AM +0200, Cédric Le Goater wrote:
>> On a real POWER8 system, the Pervasive Interconnect Bus (PIB) serves
>> as a backbone to connect different units of the system. The host
>> firmware connects to the PIB through a bridge unit, the
>> Alter-Display-Unit (ADU), which gives him access to all the chiplets
>> on the PCB network (Pervasive Connect Bus), the PIB acting as the root
>> of this network.
>>
>> XSCOM (serial communication) is the interface to the sideband bus
>> provided by the POWER8 pervasive unit to read and write to chiplets
>> resources. This is needed by the host firmware, OPAL and to a lesser
>> extent, Linux. This is among others how the PCI Host bridges get
>> configured at boot or how the LPC bus is accessed.
>>
>> To represent the ADU of a real system, we introduce a specific
>> AddressSpace to dispatch XSCOM accesses to the targeted chiplets. The
>> translation of an XSCOM address into a PCB register address is
>> slightly different between the P9 and the P8. This is handled before
>> the dispatch using a 8byte alignment for all.
>>
>> To customize the device tree, a QOM InterfaceClass, PnvXScomInterface,
>> is provided with a populate() handler. The chip populates the device
>> tree by simply looping on its children. Therefore, each model needing
>> custom nodes should not forget to declare itself as a child at
>> instantiation time.
>>
>> Based on previous work done by :
>>       Benjamin Herrenschmidt <address@hidden>
>>
>> Signed-off-by: Cédric Le Goater <address@hidden>
>> ---
>>
>>  Changes since v3:
>>
>>  - reworked the model to dispatch addresses to the memory regions
>>    using pcb_addr << 3, which is a no-op for the P9. The benefit is
>>    that all the address translation work can be done before dispatch
>>    and the conversion handlers in the chip and in the xscom interface
>>    are gone.
>>    
>>  - removed the proxy PnnXscom object and extended the PnvChip object
>>    with an address space for XSCOM and its associated memory region.
>>    
>>  - changed the read/write handlers in the address space to use
>>    address_space_stq() and address_space_ldq()
>>    
>>  - introduced 'fake' default read/write handlers to handle 'core'
>>    registers. We can add a real device model when more work needs to
>>    be done under these.
>>    
>>  - fixed an issue with the monitor doing read/write in the XSCOM
>>    address space. When under the monitor, we don't have a cpu to
>>    update the HMER SPR. That might need more work in the long term.
>>    
>>  - introduced a xscom base field to hold the xscom base address as
>>    it is different on P9
>>
>>  - renamed the devnode() handler to populate()
>>
>>  Changes since v2:
>>
>>  - QOMified the model.
>>  
>>  - all mappings in main memory space are now gathered in
>>    pnv_chip_realize() as done on other architectures.
>>    
>>  - removed XScomBus. The parenthood is established through the QOM
>>    model
>>    
>>  - replaced the XScomDevice with an InterfaceClass : PnvXScomInterface. 
>>  - introduced an XSCOM address space to dispatch accesses to the
>>    chiplets
>>
>>  hw/ppc/Makefile.objs       |   2 +-
>>  hw/ppc/pnv.c               |  25 +++++
>>  hw/ppc/pnv_xscom.c         | 262 
>> +++++++++++++++++++++++++++++++++++++++++++++
>>  include/hw/ppc/pnv.h       |  15 +++
>>  include/hw/ppc/pnv_xscom.h |  47 ++++++++
>>  5 files changed, 350 insertions(+), 1 deletion(-)
>>  create mode 100644 hw/ppc/pnv_xscom.c
>>  create mode 100644 include/hw/ppc/pnv_xscom.h
>>
>> diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
>> index f8c7d1db9ade..08c213c40684 100644
>> --- a/hw/ppc/Makefile.objs
>> +++ b/hw/ppc/Makefile.objs
>> @@ -6,7 +6,7 @@ obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o 
>> spapr_rtas.o
>>  obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o
>>  obj-$(CONFIG_PSERIES) += spapr_cpu_core.o
>>  # IBM PowerNV
>> -obj-$(CONFIG_POWERNV) += pnv.o pnv_core.o
>> +obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o
>>  ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
>>  obj-y += spapr_pci_vfio.o
>>  endif
>> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
>> index 2376bb222918..5e19b6880387 100644
>> --- a/hw/ppc/pnv.c
>> +++ b/hw/ppc/pnv.c
>> @@ -32,6 +32,8 @@
>>  #include "exec/address-spaces.h"
>>  #include "qemu/cutils.h"
>>  
>> +#include "hw/ppc/pnv_xscom.h"
>> +
>>  #include <libfdt.h>
>>  
>>  #define FDT_MAX_SIZE            0x00100000
>> @@ -218,6 +220,8 @@ static void powernv_populate_chip(PnvChip *chip, void 
>> *fdt)
>>      size_t typesize = object_type_get_instance_size(typename);
>>      int i;
>>  
>> +    pnv_xscom_populate(chip, fdt, 0);
>> +
>>      for (i = 0; i < chip->nr_cores; i++) {
>>          PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
>>  
>> @@ -450,6 +454,7 @@ static void pnv_chip_power8e_class_init(ObjectClass 
>> *klass, void *data)
>>      k->chip_cfam_id = 0x221ef04980000000ull;  /* P8 Murano DD2.1 */
>>      k->cores_mask = POWER8E_CORE_MASK;
>>      k->core_pir = pnv_chip_core_pir_p8;
>> +    k->xscom_base = 0x003fc0000000000ull;
>>      dc->desc = "PowerNV Chip POWER8E";
>>  }
>>  
>> @@ -470,6 +475,7 @@ static void pnv_chip_power8_class_init(ObjectClass 
>> *klass, void *data)
>>      k->chip_cfam_id = 0x220ea04980000000ull; /* P8 Venice DD2.0 */
>>      k->cores_mask = POWER8_CORE_MASK;
>>      k->core_pir = pnv_chip_core_pir_p8;
>> +    k->xscom_base = 0x003fc0000000000ull;
>>      dc->desc = "PowerNV Chip POWER8";
>>  }
>>  
>> @@ -490,6 +496,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass 
>> *klass, void *data)
>>      k->chip_cfam_id = 0x120d304980000000ull;  /* P8 Naples DD1.0 */
>>      k->cores_mask = POWER8_CORE_MASK;
>>      k->core_pir = pnv_chip_core_pir_p8;
>> +    k->xscom_base = 0x003fc0000000000ull;
>>      dc->desc = "PowerNV Chip POWER8NVL";
>>  }
>>  
>> @@ -510,6 +517,7 @@ static void pnv_chip_power9_class_init(ObjectClass 
>> *klass, void *data)
>>      k->chip_cfam_id = 0x100d104980000000ull; /* P9 Nimbus DD1.0 */
>>      k->cores_mask = POWER9_CORE_MASK;
>>      k->core_pir = pnv_chip_core_pir_p9;
>> +    k->xscom_base = 0x00603fc00000000ull;
>>      dc->desc = "PowerNV Chip POWER9";
>>  }
>>  
>> @@ -549,6 +557,14 @@ static void pnv_chip_core_sanitize(PnvChip *chip, Error 
>> **errp)
>>      }
>>  }
>>  
>> +static void pnv_chip_init(Object *obj)
>> +{
>> +    PnvChip *chip = PNV_CHIP(obj);
>> +    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
>> +
>> +    chip->xscom_base = pcc->xscom_base;
> 
> Is there any reason you really need the per-isntance xscom_base as
> well as the per-class xscom_base?

The per-instance xscom_base is not strictly necessary. It is a chip 
constant relative to the chip id. So I need the chip to calculate it.

> If you do have a per-instance value, it seems like you should fold in
> the calculation from PNV_XSCOM_BASE() here.

But I can make it a little cleaner. We need the value in pnv_chip_realize()
and pnv_xscom_populate() to populate the device tree. something like 
that would do :

 ( PNV_CHIP_GET_CLASS(chip)->xscom_base + ((uint64_t)(chip)->chip_id) * 
PNV_XSCOM_SIZE)

I want to add a mmio_base because the ICP BAR and the PSIHB BAR depend 
on it. PHB will also and the Centaur if we model this chip one day.

>> +}
>> +
>>  static void pnv_chip_realize(DeviceState *dev, Error **errp)
>>  {
>>      PnvChip *chip = PNV_CHIP(dev);
>> @@ -563,6 +579,14 @@ static void pnv_chip_realize(DeviceState *dev, Error 
>> **errp)
>>          return;
>>      }
>>  
>> +    /* XSCOM bridge */
>> +    pnv_xscom_realize(chip, &error);
>> +    if (error) {
>> +        error_propagate(errp, error);
>> +        return;
>> +    }
>> +    sysbus_mmio_map(SYS_BUS_DEVICE(chip), 0, PNV_XSCOM_BASE(chip));
>> +
>>      /* Early checks on the core settings */
>>      pnv_chip_core_sanitize(chip, &error);
>>      if (error) {
>> @@ -620,6 +644,7 @@ static const TypeInfo pnv_chip_info = {
>>      .name          = TYPE_PNV_CHIP,
>>      .parent        = TYPE_SYS_BUS_DEVICE,
>>      .class_init    = pnv_chip_class_init,
>> +    .instance_init = pnv_chip_init,
>>      .class_size    = sizeof(PnvChipClass),
>>      .abstract      = true,
>>  };
>> diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
>> new file mode 100644
>> index 000000000000..ce1182d9a13e
>> --- /dev/null
>> +++ b/hw/ppc/pnv_xscom.c
>> @@ -0,0 +1,262 @@
>> +/*
>> + * QEMU PowerPC PowerNV XSCOM bus
>> + *
>> + * Copyright (c) 2016, IBM Corporation.
>> + *
>> + * This library is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU Lesser General Public
>> + * License as published by the Free Software Foundation; either
>> + * version 2 of the License, or (at your option) any later version.
>> + *
>> + * This library is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> + * Lesser General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU Lesser General Public
>> + * License along with this library; if not, see 
>> <http://www.gnu.org/licenses/>.
>> + */
>> +#include "qemu/osdep.h"
>> +#include "qapi/error.h"
>> +#include "hw/hw.h"
>> +#include "qemu/log.h"
>> +#include "sysemu/kvm.h"
>> +#include "target-ppc/cpu.h"
>> +#include "hw/sysbus.h"
>> +
>> +#include "hw/ppc/fdt.h"
>> +#include "hw/ppc/pnv_xscom.h"
>> +#include "hw/ppc/pnv.h"
>> +
>> +#include <libfdt.h>
>> +
>> +static void xscom_complete(uint64_t hmer_bits)
> 
> I think this should take a cpu parameter instead of assuming
> current_cpu.  Of course, the callers will probably just use
> current_cpu, but in the callers it's a bit more obvious that
> current_cpu is actually the right thing.

Yes. the 'if (cs)' statement below is good argument for what you
say.

Thanks,

C.


>> +{
>> +    CPUState *cs = current_cpu;
>> +
>> +    /*
>> +     * TODO: When the read/write comes from the monitor, we do not
>> +     * have a cpu.
>> +     */
>> +    if (cs) {
>> +        PowerPCCPU *cpu = POWERPC_CPU(cs);
>> +        CPUPPCState *env = &cpu->env;
>> +
>> +        /*
>> +         * TODO: Need a CPU helper to set HMER, also handle generation
>> +         * of HMIs
>> +         */
>> +        cpu_synchronize_state(cs);
>> +        env->spr[SPR_HMER] |= hmer_bits;
>> +    }
>> +}
>> +
>> +static uint32_t pnv_xscom_pcba(PnvChip *chip, uint64_t addr)
>> +{
>> +    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
>> +
>> +    addr &= (PNV_XSCOM_SIZE - 1);
>> +    if (pcc->chip_type == PNV_CHIP_POWER9) {
>> +        return addr >> 3;
>> +    } else {
>> +        return ((addr >> 4) & ~0xfull) | ((addr >> 3) & 0xf);
>> +    }
>> +}
>> +
>> +static uint64_t xscom_read_default(PnvChip *chip, uint32_t pcba)
>> +{
>> +    switch (pcba) {
>> +    case 0xf000f:
>> +        return PNV_CHIP_GET_CLASS(chip)->chip_cfam_id;
>> +    case 0x1010c00:     /* PIBAM FIR */
>> +    case 0x1010c03:     /* PIBAM FIR MASK */
>> +    case 0x2020007:     /* ADU stuff */
>> +    case 0x2020009:     /* ADU stuff */
>> +    case 0x202000f:     /* ADU stuff */
>> +        return 0;
>> +    case 0x2013f00:     /* PBA stuff */
>> +    case 0x2013f01:     /* PBA stuff */
>> +    case 0x2013f02:     /* PBA stuff */
>> +    case 0x2013f03:     /* PBA stuff */
>> +    case 0x2013f04:     /* PBA stuff */
>> +    case 0x2013f05:     /* PBA stuff */
>> +    case 0x2013f06:     /* PBA stuff */
>> +    case 0x2013f07:     /* PBA stuff */
>> +        return 0;
>> +    case 0x2013028:     /* CAPP stuff */
>> +    case 0x201302a:     /* CAPP stuff */
>> +    case 0x2013801:     /* CAPP stuff */
>> +    case 0x2013802:     /* CAPP stuff */
>> +        return 0;
>> +    default:
>> +        return -1;
>> +    }
>> +}
>> +
>> +static bool xscom_write_default(PnvChip *chip, uint32_t pcba, uint64_t val)
>> +{
>> +    /* We ignore writes to these */
>> +    switch (pcba) {
>> +    case 0xf000f:       /* chip id is RO */
>> +    case 0x1010c00:     /* PIBAM FIR */
>> +    case 0x1010c01:     /* PIBAM FIR */
>> +    case 0x1010c02:     /* PIBAM FIR */
>> +    case 0x1010c03:     /* PIBAM FIR MASK */
>> +    case 0x1010c04:     /* PIBAM FIR MASK */
>> +    case 0x1010c05:     /* PIBAM FIR MASK */
>> +    case 0x2020007:     /* ADU stuff */
>> +    case 0x2020009:     /* ADU stuff */
>> +    case 0x202000f:     /* ADU stuff */
>> +        return true;
>> +    default:
>> +        return false;
>> +    }
>> +}
>> +
>> +static uint64_t xscom_read(void *opaque, hwaddr addr, unsigned width)
>> +{
>> +    PnvChip *chip = opaque;
>> +    uint32_t pcba = pnv_xscom_pcba(chip, addr);
>> +    uint64_t val = 0;
>> +    MemTxResult result;
>> +
>> +    /* Handle some SCOMs here before dispatch */
>> +    val = xscom_read_default(chip, pcba);
>> +    if (val != -1) {
>> +        goto complete;
>> +    }
>> +
>> +    val = address_space_ldq(&chip->xscom_as, pcba << 3, 
>> MEMTXATTRS_UNSPECIFIED,
>> +                            &result);
>> +    if (result != MEMTX_OK) {
>> +        qemu_log_mask(LOG_GUEST_ERROR, "XSCOM read failed at @0x%"
>> +                      HWADDR_PRIx " pcba=0x%08x\n", addr, pcba);
>> +        xscom_complete(HMER_XSCOM_FAIL | HMER_XSCOM_DONE);
>> +        return 0;
>> +    }
>> +
>> +complete:
>> +    xscom_complete(HMER_XSCOM_DONE);
>> +    return val;
>> +}
>> +
>> +static void xscom_write(void *opaque, hwaddr addr, uint64_t val,
>> +                        unsigned width)
>> +{
>> +    PnvChip *chip = opaque;
>> +    uint32_t pcba = pnv_xscom_pcba(chip, addr);
>> +    MemTxResult result;
>> +
>> +    /* Handle some SCOMs here before dispatch */
>> +    if (xscom_write_default(chip, pcba, val)) {
>> +        goto complete;
>> +    }
>> +
>> +    address_space_stq(&chip->xscom_as, pcba << 3, val, 
>> MEMTXATTRS_UNSPECIFIED,
>> +                      &result);
>> +    if (result != MEMTX_OK) {
>> +        qemu_log_mask(LOG_GUEST_ERROR, "XSCOM write failed at @0x%"
>> +                      HWADDR_PRIx " pcba=0x%08x data=0x%" PRIx64 "\n",
>> +                      addr, pcba, val);
>> +        xscom_complete(HMER_XSCOM_FAIL | HMER_XSCOM_DONE);
>> +        return;
>> +    }
>> +
>> +complete:
>> +    xscom_complete(HMER_XSCOM_DONE);
>> +}
>> +
>> +const MemoryRegionOps pnv_xscom_ops = {
>> +    .read = xscom_read,
>> +    .write = xscom_write,
>> +    .valid.min_access_size = 8,
>> +    .valid.max_access_size = 8,
>> +    .impl.min_access_size = 8,
>> +    .impl.max_access_size = 8,
>> +    .endianness = DEVICE_BIG_ENDIAN,
>> +};
>> +
>> +void pnv_xscom_realize(PnvChip *chip, Error **errp)
>> +{
>> +    SysBusDevice *sbd = SYS_BUS_DEVICE(chip);
>> +    char *name;
>> +
>> +    name = g_strdup_printf("xscom-%x", chip->chip_id);
>> +    memory_region_init_io(&chip->xscom_mmio, OBJECT(chip), &pnv_xscom_ops,
>> +                          chip, name, PNV_XSCOM_SIZE);
>> +    sysbus_init_mmio(sbd, &chip->xscom_mmio);
>> +
>> +    memory_region_init(&chip->xscom, OBJECT(chip), name, PNV_XSCOM_SIZE);
>> +    address_space_init(&chip->xscom_as, &chip->xscom, name);
>> +    g_free(name);
>> +}
>> +
>> +static const TypeInfo pnv_xscom_interface_info = {
>> +    .name = TYPE_PNV_XSCOM_INTERFACE,
>> +    .parent = TYPE_INTERFACE,
>> +    .class_size = sizeof(PnvXScomInterfaceClass),
>> +};
>> +
>> +static void pnv_xscom_register_types(void)
>> +{
>> +    type_register_static(&pnv_xscom_interface_info);
>> +}
>> +
>> +type_init(pnv_xscom_register_types)
>> +
>> +typedef struct ForeachPopulateArgs {
>> +    void *fdt;
>> +    int xscom_offset;
>> +} ForeachPopulateArgs;
>> +
>> +static int xscom_populate_child(Object *child, void *opaque)
>> +{
>> +    if (object_dynamic_cast(child, TYPE_PNV_XSCOM_INTERFACE)) {
>> +        ForeachPopulateArgs *args = opaque;
>> +        PnvXScomInterface *xd = PNV_XSCOM_INTERFACE(child);
>> +        PnvXScomInterfaceClass *xc = PNV_XSCOM_INTERFACE_GET_CLASS(xd);
>> +
>> +        if (xc->populate) {
>> +            _FDT((xc->populate(xd, args->fdt, args->xscom_offset)));
>> +        }
>> +    }
>> +    return 0;
>> +}
>> +
>> +static const char compat_p8[] = "ibm,power8-xscom\0ibm,xscom";
>> +static const char compat_p9[] = "ibm,power9-xscom\0ibm,xscom";
>> +
>> +int pnv_xscom_populate(PnvChip *chip, void *fdt, int root_offset)
>> +{
>> +    uint64_t reg[] = { cpu_to_be64(PNV_XSCOM_BASE(chip)),
>> +                       cpu_to_be64(PNV_XSCOM_SIZE) };
>> +    int xscom_offset;
>> +    ForeachPopulateArgs args;
>> +    char *name;
>> +    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
>> +
>> +    name = g_strdup_printf("address@hidden" PRIx64, be64_to_cpu(reg[0]));
>> +    xscom_offset = fdt_add_subnode(fdt, root_offset, name);
>> +    _FDT(xscom_offset);
>> +    g_free(name);
>> +    _FDT((fdt_setprop_cell(fdt, xscom_offset, "ibm,chip-id", 
>> chip->chip_id)));
>> +    _FDT((fdt_setprop_cell(fdt, xscom_offset, "#address-cells", 1)));
>> +    _FDT((fdt_setprop_cell(fdt, xscom_offset, "#size-cells", 1)));
>> +    _FDT((fdt_setprop(fdt, xscom_offset, "reg", reg, sizeof(reg))));
>> +
>> +    if (pcc->chip_type == PNV_CHIP_POWER9) {
>> +        _FDT((fdt_setprop(fdt, xscom_offset, "compatible", compat_p9,
>> +                          sizeof(compat_p9))));
>> +    } else {
>> +        _FDT((fdt_setprop(fdt, xscom_offset, "compatible", compat_p8,
>> +                          sizeof(compat_p8))));
>> +    }
>> +
>> +    _FDT((fdt_setprop(fdt, xscom_offset, "scom-controller", NULL, 0)));
>> +
>> +    args.fdt = fdt;
>> +    args.xscom_offset = xscom_offset;
>> +
>> +    object_child_foreach(OBJECT(chip), xscom_populate_child, &args);
>> +    return 0;
>> +}
>> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
>> index ed4a360cde3b..f89eddb6e5e0 100644
>> --- a/include/hw/ppc/pnv.h
>> +++ b/include/hw/ppc/pnv.h
>> @@ -21,6 +21,7 @@
>>  
>>  #include "hw/boards.h"
>>  #include "hw/sysbus.h"
>> +#include "hw/ppc/pnv_xscom.h"
>>  
>>  #define TYPE_PNV_CHIP "powernv-chip"
>>  #define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP)
>> @@ -43,6 +44,11 @@ typedef struct PnvChip {
>>      /*< public >*/
>>      uint32_t     chip_id;
>>  
>> +    hwaddr       xscom_base;
>> +    MemoryRegion xscom_mmio;
>> +    MemoryRegion xscom;
>> +    AddressSpace xscom_as;
>> +
>>      uint32_t  nr_cores;
>>      uint64_t  cores_mask;
>>      void      *cores;
>> @@ -58,6 +64,8 @@ typedef struct PnvChipClass {
>>      uint64_t     chip_cfam_id;
>>      uint64_t     cores_mask;
>>  
>> +    hwaddr       xscom_base;
>> +
>>      uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id);
>>  } PnvChipClass;
>>  
>> @@ -105,4 +113,11 @@ typedef struct PnvMachineState {
>>  
>>  #define PNV_TIMEBASE_FREQ           512000000ULL
>>  
>> +/*
>> + * POWER8 MMIO base addresses
>> + */
>> +#define PNV_XSCOM_SIZE        0x800000000ull
>> +#define PNV_XSCOM_BASE(chip)                                            \
>> +    (chip->xscom_base + ((uint64_t)(chip)->chip_id) * PNV_XSCOM_SIZE)
>> +
>>  #endif /* _PPC_PNV_H */
>> diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
>> new file mode 100644
>> index 000000000000..f50eb0bc4099
>> --- /dev/null
>> +++ b/include/hw/ppc/pnv_xscom.h
>> @@ -0,0 +1,47 @@
>> +/*
>> + * QEMU PowerPC PowerNV XSCOM bus definitions
>> + *
>> + * Copyright (c) 2016, IBM Corporation.
>> + *
>> + * This library is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU Lesser General Public
>> + * License as published by the Free Software Foundation; either
>> + * version 2 of the License, or (at your option) any later version.
>> + *
>> + * This library is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> + * Lesser General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU Lesser General Public
>> + * License along with this library; if not, see 
>> <http://www.gnu.org/licenses/>.
>> + */
>> +#ifndef _PPC_PNV_XSCOM_H
>> +#define _PPC_PNV_XSCOM_H
>> +
>> +#include "qom/object.h"
>> +
>> +typedef struct PnvChip PnvChip;
>> +
>> +typedef struct PnvXScomInterface {
>> +    Object parent;
>> +} PnvXScomInterface;
>> +
>> +#define TYPE_PNV_XSCOM_INTERFACE "pnv-xscom-interface"
>> +#define PNV_XSCOM_INTERFACE(obj) \
>> +     OBJECT_CHECK(PnvXScomInterface, (obj), TYPE_PNV_XSCOM_INTERFACE)
>> +#define PNV_XSCOM_INTERFACE_CLASS(klass)                \
>> +    OBJECT_CLASS_CHECK(PnvXScomInterfaceClass, (klass), \
>> +                       TYPE_PNV_XSCOM_INTERFACE)
>> +#define PNV_XSCOM_INTERFACE_GET_CLASS(obj) \
>> +     OBJECT_GET_CLASS(PnvXScomInterfaceClass, (obj), 
>> TYPE_PNV_XSCOM_INTERFACE)
>> +
>> +typedef struct PnvXScomInterfaceClass {
>> +    InterfaceClass parent;
>> +    int (*populate)(PnvXScomInterface *dev, void *fdt, int offset);
>> +} PnvXScomInterfaceClass;
>> +
>> +extern void pnv_xscom_realize(PnvChip *chip, Error **errp);
>> +extern int pnv_xscom_populate(PnvChip *chip, void *fdt, int offset);
>> +
>> +#endif /* _PPC_PNV_XSCOM_H */
> 




reply via email to

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