[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
signature.asc
Description: PGP signature
- Re: [Qemu-devel] [PATCH v2 13/15] ppc/pnv: add more dummy XSCOM addresses, (continued)
- [Qemu-devel] [PATCH v2 02/15] ppc/pnv: add a PSI bridge model for POWER9, Cédric Le Goater, 2019/03/07
- [Qemu-devel] [PATCH v2 04/15] ppc/pnv: add a LPC Controller class model, Cédric Le Goater, 2019/03/07
- [Qemu-devel] [PATCH v2 09/15] ppc/pnv: add a OCC model for POWER9, Cédric Le Goater, 2019/03/07
- [Qemu-devel] [PATCH v2 07/15] ppc/pnv: add SerIRQ routing registers, Cédric Le Goater, 2019/03/07
- [Qemu-devel] [PATCH v2 11/15] ppc/pnv: POWER9 XSCOM quad support, Cédric Le Goater, 2019/03/07
- Re: [Qemu-devel] [PATCH v2 11/15] ppc/pnv: POWER9 XSCOM quad support,
David Gibson <=
- [Qemu-devel] [PATCH v2 01/15] ppc/pnv: add a PSI bridge class model, Cédric Le Goater, 2019/03/07
- [Qemu-devel] [PATCH v2 06/15] ppc/pnv: add a LPC Controller model for POWER9, Cédric Le Goater, 2019/03/07
- [Qemu-devel] [PATCH v2 15/15] target/ppc: add HV support for POWER9, Cédric Le Goater, 2019/03/07
- [Qemu-devel] [PATCH v2 03/15] ppc/pnv: lpc: fix OPB address ranges, Cédric Le Goater, 2019/03/07
- [Qemu-devel] [PATCH v2 10/15] ppc/pnv: extend XSCOM core support for POWER9, Cédric Le Goater, 2019/03/07