From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([209.51.188.92]:42251) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h240N-0006FL-ND for qemu-devel@nongnu.org; Thu, 07 Mar 2019 20:08:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h240K-0000zz-Cv for qemu-devel@nongnu.org; Thu, 07 Mar 2019 20:08:55 -0500 Date: Fri, 8 Mar 2019 11:32:56 +1100 From: David Gibson Message-ID: <20190308003256.GO7722@umbus.fritz.box> References: <20190307223548.20516-1-clg@kaod.org> <20190307223548.20516-12-clg@kaod.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="Bf1m62tZozKFsi1s" Content-Disposition: inline In-Reply-To: <20190307223548.20516-12-clg@kaod.org> Subject: Re: [Qemu-devel] [PATCH v2 11/15] ppc/pnv: POWER9 XSCOM quad support List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: =?iso-8859-1?Q?C=E9dric?= Le Goater Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org --Bf1m62tZozKFsi1s Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Thu, Mar 07, 2019 at 11:35:44PM +0100, C=E9dric 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. >=20 > 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. >=20 > Signed-off-by: C=E9dric Le Goater 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(-) >=20 > 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" > =20 > #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; > =20 > 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 *c= pu) > return (PnvCPUState *)cpu->machine_data; > } > =20 > +#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 > =20 > -#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 > =20 > @@ -73,6 +69,14 @@ typedef struct PnvXScomInterfaceClass { > #define PNV_XSCOM_OCC_BASE 0x0066000 > #define PNV_XSCOM_OCC_SIZE 0x6000 > =20 > +#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 > =20 > 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 *ob= j) > OBJECT(&chip9->psi), &error_abort); > } > =20 > +static void pnv_chip_quad_realize(Pnv9Chip *chip9, Error **errp) > +{ > + PnvChip *chip =3D PNV_CHIP(chip9); > + const char *typename =3D pnv_chip_core_typename(chip); > + size_t typesize =3D object_type_get_instance_size(typename); > + int i; > + > + chip9->nr_quads =3D DIV_ROUND_UP(chip->nr_cores, 4); > + chip9->quads =3D g_new0(PnvQuad, chip9->nr_quads); > + > + for (i =3D 0; i < chip9->nr_quads; i++) { > + char eq_name[32]; > + PnvQuad *eq =3D &chip9->quads[i]; > + PnvCore *pnv_core =3D PNV_CORE(chip->cores + (i * 4) * typesize); > + int core_id =3D 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_fa= tal); > + 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 =3D PNV_CHIP_GET_CLASS(dev); > @@ -977,6 +1007,12 @@ static void pnv_chip_power9_realize(DeviceState *de= v, Error **errp) > return; > } > =20 > + 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, Er= ror **errp) > if (!pnv_chip_is_power9(chip)) { > xscom_core_base =3D PNV_XSCOM_EX_BASE(core_hwid); > } else { > - xscom_core_base =3D PNV_XSCOM_P9_EC_BASE(core_hwid); > + xscom_core_base =3D PNV9_XSCOM_EC_BASE(core_hwid); > } > =20 > 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[] =3D { > }; > =20 > 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 =3D addr >> 3; > + uint64_t val =3D -1; > + > + switch (offset) { > + case P9X_EX_NCU_SPEC_BAR: > + case P9X_EX_NCU_SPEC_BAR + 0x400: /* Second EX */ > + val =3D 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 =3D 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 =3D { > + .read =3D pnv_quad_xscom_read, > + .write =3D pnv_quad_xscom_write, > + .valid.min_access_size =3D 8, > + .valid.max_access_size =3D 8, > + .impl.min_access_size =3D 8, > + .impl.max_access_size =3D 8, > + .endianness =3D DEVICE_BIG_ENDIAN, > +}; > + > +static void pnv_quad_realize(DeviceState *dev, Error **errp) > +{ > + PnvQuad *eq =3D 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[] =3D { > + DEFINE_PROP_UINT32("id", PnvQuad, id, 0), > + DEFINE_PROP_END_OF_LIST(), > +}; > + > +static void pnv_quad_class_init(ObjectClass *oc, void *data) > +{ > + DeviceClass *dc =3D DEVICE_CLASS(oc); > + > + dc->realize =3D pnv_quad_realize; > + dc->props =3D pnv_quad_properties; > +} > + > +static const TypeInfo pnv_quad_info =3D { > + .name =3D TYPE_PNV_QUAD, > + .parent =3D TYPE_DEVICE, > + .instance_size =3D sizeof(PnvQuad), > + .class_init =3D pnv_quad_class_init, > +}; > + > +static void pnv_core_register_types(void) > +{ > + type_register_static(&pnv_quad_info); > +} > + > +type_init(pnv_core_register_types) --=20 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 --Bf1m62tZozKFsi1s Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEdfRlhq5hpmzETofcbDjKyiDZs5IFAlyBuDgACgkQbDjKyiDZ s5JQ/BAA0PCnFq84tsX+jwIoeBJ/Gpguil131Tmlm3Prw93oxGt/Av09xup8fU5h 0svaAy+m9Pec5Nqkz6/z9XZkseOjmyVAA68O6Yh2O+a/pbuv+FJhQ45vwyvbzWFH Q7/5wVR3hyXeO8jRKCDRfjN9bdelIayWRg+s645M8JDuJBOkgjEo7vkpUoS+fSZn mt45RS6etDZ0+rzM9eCJTjJhRasFw8L18bSMod0tEsztCUb64gOaLzxCJ7VCgpgx LN8c+FRxDX7XFVBKf0aWPwIx0aH4gRjWEI00/r1ww9BReoSzHvyON75rvUgTispQ vLZ+6dxqhudDpetBfzz+6QqZBUYIXJdQKGPnDbkHcXJZxsEGhFEA3M01am5HMnQg zgp7rEpf0zeBjCiYrBV5e6xX0vF7jmoiC9uMCOc8m/MLiBQNN91c1KQigJwMiIJG lLsmDuNukgdCFjhMwoFgofEj3oT2GctxdfZs+Wf/CbiXDNPGxa1Zjee1ZiiUXYxg QKl1/1CLP86UdRKkte5oP9YBERHGJS42hqmI8i0t8Ej+DjO599tGSPUvWNOmhn4o xsuhw2Pr7n/n+1uuB18VZH+yq1r468gezxIDDycPMOuQFknhmJ7BX0Xpjb2wnq3J AatyQpoQw2wEG5ysLCBAPmcXJ6IrsghF0SXDgU3r4sUdyCzYwVk= =RIe9 -----END PGP SIGNATURE----- --Bf1m62tZozKFsi1s--