qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH v2 11/15] ppc/pnv: POWER9 XSCOM quad support


From: David Gibson
Subject: Re: [Qemu-devel] [PATCH v2 11/15] ppc/pnv: POWER9 XSCOM quad support
Date: Fri, 8 Mar 2019 11:32:56 +1100
User-agent: Mutt/1.11.3 (2019-02-01)

On Thu, Mar 07, 2019 at 11:35:44PM +0100, Cédric Le Goater wrote:
> The POWER9 processor does not support per-core frequency control. The
> cores are arranged in groups of four, along with their respective L2
> and L3 caches, into a structure known as a Quad. The frequency must be
> managed at the Quad level.
> 
> Provide a basic Quad model to fake the settings done by the firmware
> on the Non-Cacheable Unit (NCU). Each core pair (EX) needs a special
> BAR setting for the TIMA area of XIVE because it resides on the same
> address on all chips.
> 
> Signed-off-by: Cédric Le Goater <address@hidden>

Applied, thanks.

> ---
>  include/hw/ppc/pnv.h       |  4 ++
>  include/hw/ppc/pnv_core.h  | 10 +++++
>  include/hw/ppc/pnv_xscom.h | 12 ++++--
>  hw/ppc/pnv.c               | 38 ++++++++++++++++-
>  hw/ppc/pnv_core.c          | 87 ++++++++++++++++++++++++++++++++++++++
>  5 files changed, 146 insertions(+), 5 deletions(-)
> 
> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
> index 39888f9d52c1..e5b00d373ed2 100644
> --- a/include/hw/ppc/pnv.h
> +++ b/include/hw/ppc/pnv.h
> @@ -26,6 +26,7 @@
>  #include "hw/ppc/pnv_psi.h"
>  #include "hw/ppc/pnv_occ.h"
>  #include "hw/ppc/pnv_xive.h"
> +#include "hw/ppc/pnv_core.h"
>  
>  #define TYPE_PNV_CHIP "pnv-chip"
>  #define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP)
> @@ -89,6 +90,9 @@ typedef struct Pnv9Chip {
>      Pnv9Psi      psi;
>      PnvLpcController lpc;
>      PnvOCC       occ;
> +
> +    uint32_t     nr_quads;
> +    PnvQuad      *quads;
>  } Pnv9Chip;
>  
>  typedef struct PnvChipClass {
> diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
> index cbe9ad36f32c..50cdb2b35838 100644
> --- a/include/hw/ppc/pnv_core.h
> +++ b/include/hw/ppc/pnv_core.h
> @@ -58,4 +58,14 @@ static inline PnvCPUState *pnv_cpu_state(PowerPCCPU *cpu)
>      return (PnvCPUState *)cpu->machine_data;
>  }
>  
> +#define TYPE_PNV_QUAD "powernv-cpu-quad"
> +#define PNV_QUAD(obj) \
> +    OBJECT_CHECK(PnvQuad, (obj), TYPE_PNV_QUAD)
> +
> +typedef struct PnvQuad {
> +    DeviceState parent_obj;
> +
> +    uint32_t id;
> +    MemoryRegion xscom_regs;
> +} PnvQuad;
>  #endif /* _PPC_PNV_CORE_H */
> diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
> index 3292459fbb78..68dfae0dfe41 100644
> --- a/include/hw/ppc/pnv_xscom.h
> +++ b/include/hw/ppc/pnv_xscom.h
> @@ -60,10 +60,6 @@ typedef struct PnvXScomInterfaceClass {
>      (PNV_XSCOM_EX_CORE_BASE | ((uint64_t)(core) << 24))
>  #define PNV_XSCOM_EX_SIZE         0x100000
>  
> -#define PNV_XSCOM_P9_EC_BASE(core) \
> -    ((uint64_t)(((core) & 0x1F) + 0x20) << 24)
> -#define PNV_XSCOM_P9_EC_SIZE      0x100000
> -
>  #define PNV_XSCOM_LPC_BASE        0xb0020
>  #define PNV_XSCOM_LPC_SIZE        0x4
>  
> @@ -73,6 +69,14 @@ typedef struct PnvXScomInterfaceClass {
>  #define PNV_XSCOM_OCC_BASE        0x0066000
>  #define PNV_XSCOM_OCC_SIZE        0x6000
>  
> +#define PNV9_XSCOM_EC_BASE(core) \
> +    ((uint64_t)(((core) & 0x1F) + 0x20) << 24)
> +#define PNV9_XSCOM_EC_SIZE        0x100000
> +
> +#define PNV9_XSCOM_EQ_BASE(core) \
> +    ((uint64_t)(((core) & 0x1C) + 0x40) << 22)
> +#define PNV9_XSCOM_EQ_SIZE        0x100000
> +
>  #define PNV9_XSCOM_OCC_BASE       PNV_XSCOM_OCC_BASE
>  #define PNV9_XSCOM_OCC_SIZE       0x8000
>  
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 1559a733235b..e68d419203e8 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -963,6 +963,36 @@ static void pnv_chip_power9_instance_init(Object *obj)
>                                     OBJECT(&chip9->psi), &error_abort);
>  }
>  
> +static void pnv_chip_quad_realize(Pnv9Chip *chip9, Error **errp)
> +{
> +    PnvChip *chip = PNV_CHIP(chip9);
> +    const char *typename = pnv_chip_core_typename(chip);
> +    size_t typesize = object_type_get_instance_size(typename);
> +    int i;
> +
> +    chip9->nr_quads = DIV_ROUND_UP(chip->nr_cores, 4);
> +    chip9->quads = g_new0(PnvQuad, chip9->nr_quads);
> +
> +    for (i = 0; i < chip9->nr_quads; i++) {
> +        char eq_name[32];
> +        PnvQuad *eq = &chip9->quads[i];
> +        PnvCore *pnv_core = PNV_CORE(chip->cores + (i * 4) * typesize);
> +        int core_id = CPU_CORE(pnv_core)->core_id;
> +
> +        object_initialize(eq, sizeof(*eq), TYPE_PNV_QUAD);
> +        snprintf(eq_name, sizeof(eq_name), "eq[%d]", core_id);
> +
> +        object_property_add_child(OBJECT(chip), eq_name, OBJECT(eq),
> +                                  &error_fatal);
> +        object_property_set_int(OBJECT(eq), core_id, "id", &error_fatal);
> +        object_property_set_bool(OBJECT(eq), true, "realized", &error_fatal);
> +        object_unref(OBJECT(eq));
> +
> +        pnv_xscom_add_subregion(chip, PNV9_XSCOM_EQ_BASE(eq->id),
> +                                &eq->xscom_regs);
> +    }
> +}
> +
>  static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
>  {
>      PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
> @@ -977,6 +1007,12 @@ static void pnv_chip_power9_realize(DeviceState *dev, 
> Error **errp)
>          return;
>      }
>  
> +    pnv_chip_quad_realize(chip9, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +
>      /* XIVE interrupt controller (POWER9) */
>      object_property_set_int(OBJECT(&chip9->xive), PNV9_XIVE_IC_BASE(chip),
>                              "ic-bar", &error_fatal);
> @@ -1135,7 +1171,7 @@ static void pnv_chip_core_realize(PnvChip *chip, Error 
> **errp)
>          if (!pnv_chip_is_power9(chip)) {
>              xscom_core_base = PNV_XSCOM_EX_BASE(core_hwid);
>          } else {
> -            xscom_core_base = PNV_XSCOM_P9_EC_BASE(core_hwid);
> +            xscom_core_base = PNV9_XSCOM_EC_BASE(core_hwid);
>          }
>  
>          pnv_xscom_add_subregion(chip, xscom_core_base,
> diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
> index 171474e0805c..5feeed6bc463 100644
> --- a/hw/ppc/pnv_core.c
> +++ b/hw/ppc/pnv_core.c
> @@ -327,3 +327,90 @@ static const TypeInfo pnv_core_infos[] = {
>  };
>  
>  DEFINE_TYPES(pnv_core_infos)
> +
> +/*
> + * POWER9 Quads
> + */
> +
> +#define P9X_EX_NCU_SPEC_BAR                     0x11010
> +
> +static uint64_t pnv_quad_xscom_read(void *opaque, hwaddr addr,
> +                                    unsigned int width)
> +{
> +    uint32_t offset = addr >> 3;
> +    uint64_t val = -1;
> +
> +    switch (offset) {
> +    case P9X_EX_NCU_SPEC_BAR:
> +    case P9X_EX_NCU_SPEC_BAR + 0x400: /* Second EX */
> +        val = 0;
> +        break;
> +    default:
> +        qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__,
> +                      offset);
> +    }
> +
> +    return val;
> +}
> +
> +static void pnv_quad_xscom_write(void *opaque, hwaddr addr, uint64_t val,
> +                                 unsigned int width)
> +{
> +    uint32_t offset = addr >> 3;
> +
> +    switch (offset) {
> +    case P9X_EX_NCU_SPEC_BAR:
> +    case P9X_EX_NCU_SPEC_BAR + 0x400: /* Second EX */
> +        break;
> +    default:
> +        qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__,
> +                  offset);
> +    }
> +}
> +
> +static const MemoryRegionOps pnv_quad_xscom_ops = {
> +    .read = pnv_quad_xscom_read,
> +    .write = pnv_quad_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,
> +};
> +
> +static void pnv_quad_realize(DeviceState *dev, Error **errp)
> +{
> +    PnvQuad *eq = PNV_QUAD(dev);
> +    char name[32];
> +
> +    snprintf(name, sizeof(name), "xscom-quad.%d", eq->id);
> +    pnv_xscom_region_init(&eq->xscom_regs, OBJECT(dev), &pnv_quad_xscom_ops,
> +                          eq, name, PNV9_XSCOM_EQ_SIZE);
> +}
> +
> +static Property pnv_quad_properties[] = {
> +    DEFINE_PROP_UINT32("id", PnvQuad, id, 0),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void pnv_quad_class_init(ObjectClass *oc, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(oc);
> +
> +    dc->realize = pnv_quad_realize;
> +    dc->props = pnv_quad_properties;
> +}
> +
> +static const TypeInfo pnv_quad_info = {
> +    .name          = TYPE_PNV_QUAD,
> +    .parent        = TYPE_DEVICE,
> +    .instance_size = sizeof(PnvQuad),
> +    .class_init    = pnv_quad_class_init,
> +};
> +
> +static void pnv_core_register_types(void)
> +{
> +    type_register_static(&pnv_quad_info);
> +}
> +
> +type_init(pnv_core_register_types)

-- 
David Gibson                    | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
                                | _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


reply via email to

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