From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36627) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bxsvS-0006UZ-TC for qemu-devel@nongnu.org; Sat, 22 Oct 2016 05:49:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bxsvP-0002gG-PW for qemu-devel@nongnu.org; Sat, 22 Oct 2016 05:49:14 -0400 Received: from 10.mo69.mail-out.ovh.net ([46.105.73.241]:49392) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1bxsvP-0002fJ-Ha for qemu-devel@nongnu.org; Sat, 22 Oct 2016 05:49:11 -0400 Received: from player798.ha.ovh.net (b7.ovh.net [213.186.33.57]) by mo69.mail-out.ovh.net (Postfix) with ESMTP id 31DAE6A8C for ; Sat, 22 Oct 2016 11:49:10 +0200 (CEST) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Sat, 22 Oct 2016 11:46:45 +0200 Message-Id: <1477129610-31353-13-git-send-email-clg@kaod.org> In-Reply-To: <1477129610-31353-1-git-send-email-clg@kaod.org> References: <1477129610-31353-1-git-send-email-clg@kaod.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH v5 12/17] ppc/pnv: add a XICS native to each PowerNV chip List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-ppc@nongnu.org Cc: David Gibson , Benjamin Herrenschmidt , qemu-devel@nongnu.org, Alexander Graf , Cedric Le Goater It also links the XICS object to each core as it is needed to do the CPU setup and the ICP MMIO windows are memory mapped for each thread. Signed-off-by: C=C3=A9dric Le Goater --- Changes since v4: - changed the calculation of the number of ICPs to use smp_threads - added the mapping of the ICP subregions per thread hw/ppc/pnv.c | 27 +++++++++++++++++++++++++++ hw/ppc/pnv_core.c | 24 ++++++++++++++++++++---- include/hw/ppc/pnv.h | 2 ++ 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index c6dc7ca895b6..16d7baf0da71 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -33,6 +33,7 @@ #include "qemu/cutils.h" #include "qapi/visitor.h" =20 +#include "hw/ppc/xics.h" #include "hw/ppc/pnv_xscom.h" =20 #include "hw/isa/isa.h" @@ -231,6 +232,9 @@ static void powernv_populate_chip(PnvChip *chip, void= *fdt) PnvCore *pnv_core =3D PNV_CORE(chip->cores + i * typesize); =20 powernv_create_core_node(chip, pnv_core, fdt); + + /* Interrupt presentation controllers (ICP). One per thread. */ + xics_native_populate_icp(chip, fdt, 0, pnv_core->pir, smp_thread= s); } =20 if (chip->ram_size) { @@ -637,6 +641,9 @@ static void pnv_chip_init(Object *obj) =20 object_initialize(&chip->lpc, sizeof(chip->lpc), TYPE_PNV_LPC); object_property_add_child(obj, "lpc", OBJECT(&chip->lpc), NULL); + + object_initialize(&chip->xics, sizeof(chip->xics), TYPE_XICS_NATIVE)= ; + object_property_add_child(obj, "xics", OBJECT(&chip->xics), NULL); } =20 static void pnv_chip_realize(DeviceState *dev, Error **errp) @@ -668,12 +675,23 @@ static void pnv_chip_realize(DeviceState *dev, Erro= r **errp) return; } =20 + /* + * Interrupt Controller. To be created before the cores because + * each thread will fetch its ICP in the XICS + */ + object_property_set_int(OBJECT(&chip->xics), chip->nr_cores * smp_th= reads, + "nr_servers", &error_fatal); + object_property_set_bool(OBJECT(&chip->xics), true, "realized", + &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(&chip->xics), 0, PNV_XICS_BASE); + chip->cores =3D g_malloc0(typesize * chip->nr_cores); =20 for (i =3D 0, core_hwid =3D 0; (core_hwid < sizeof(chip->cores_mask)= * 8) && (i < chip->nr_cores); core_hwid++) { char core_name[32]; void *pnv_core =3D chip->cores + i * typesize; + int j; =20 if (!(chip->cores_mask & (1ull << core_hwid))) { continue; @@ -690,6 +708,8 @@ static void pnv_chip_realize(DeviceState *dev, Error = **errp) object_property_set_int(OBJECT(pnv_core), pcc->core_pir(chip, core_hwid), "pir", &error_fatal); + object_property_add_const_link(OBJECT(pnv_core), "xics", + OBJECT(&chip->xics), &error_fatal= ); object_property_set_bool(OBJECT(pnv_core), true, "realized", &error_fatal); object_unref(OBJECT(pnv_core)); @@ -697,6 +717,13 @@ static void pnv_chip_realize(DeviceState *dev, Error= **errp) /* Each core has an XSCOM MMIO region */ pnv_xscom_add_subregion(chip, PNV_XSCOM_EX_CORE_BASE(core_hwid), &PNV_CORE(pnv_core)->xscom_regs); + + /* Each thread as region for its ICP */ + for (j =3D 0; j < smp_threads; j++) { + memory_region_add_subregion(&chip->xics.icp_mmio, + pcc->core_pir(chip, core_hwid) <= < 12, + &chip->xics.icp_mmios[i]); + } i++; } g_free(typename); diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 2acda9637db5..e15c76163759 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -24,6 +24,7 @@ #include "hw/ppc/ppc.h" #include "hw/ppc/pnv.h" #include "hw/ppc/pnv_core.h" +#include "hw/ppc/xics.h" =20 static void powernv_cpu_reset(void *opaque) { @@ -42,7 +43,7 @@ static void powernv_cpu_reset(void *opaque) env->msr |=3D MSR_HVB; /* Hypervisor mode */ } =20 -static void powernv_cpu_init(PowerPCCPU *cpu, Error **errp) +static void powernv_cpu_init(PowerPCCPU *cpu, XICSState *xics, Error **e= rrp) { CPUPPCState *env =3D &cpu->env; int core_pir; @@ -62,6 +63,11 @@ static void powernv_cpu_init(PowerPCCPU *cpu, Error **= errp) cpu_ppc_tb_init(env, PNV_TIMEBASE_FREQ); =20 qemu_register_reset(powernv_cpu_reset, cpu); + + /* + * xics_cpu_setup() assigns the CPU to the ICP in XICS + */ + xics_cpu_setup(xics, cpu); } =20 /* @@ -109,7 +115,7 @@ static const MemoryRegionOps pnv_core_xscom_ops =3D { .endianness =3D DEVICE_BIG_ENDIAN, }; =20 -static void pnv_core_realize_child(Object *child, Error **errp) +static void pnv_core_realize_child(Object *child, XICSState *xics, Error= **errp) { Error *local_err =3D NULL; CPUState *cs =3D CPU(child); @@ -121,7 +127,7 @@ static void pnv_core_realize_child(Object *child, Err= or **errp) return; } =20 - powernv_cpu_init(cpu, &local_err); + powernv_cpu_init(cpu, xics, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -139,6 +145,7 @@ static void pnv_core_realize(DeviceState *dev, Error = **errp) void *obj; int i, j; char name[32]; + XICSState *xics; =20 pc->threads =3D g_malloc0(size * cc->nr_threads); for (i =3D 0; i < cc->nr_threads; i++) { @@ -156,10 +163,19 @@ static void pnv_core_realize(DeviceState *dev, Erro= r **errp) object_unref(obj); } =20 + /* get XICS object from chip */ + obj =3D object_property_get_link(OBJECT(dev), "xics", &local_err); + if (!obj) { + error_setg(errp, "%s: required link 'xics' not found: %s", + __func__, error_get_pretty(local_err)); + return; + } + xics =3D XICS_COMMON(obj); + for (j =3D 0; j < cc->nr_threads; j++) { obj =3D pc->threads + j * size; =20 - pnv_core_realize_child(obj, &local_err); + pnv_core_realize_child(obj, xics, &local_err); if (local_err) { goto err; } diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index c08ed1c72b17..e11618b05f1d 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -23,6 +23,7 @@ #include "hw/sysbus.h" #include "hw/ppc/pnv_xscom.h" #include "hw/ppc/pnv_lpc.h" +#include "hw/ppc/xics.h" =20 #define TYPE_PNV_CHIP "powernv-chip" #define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP) @@ -57,6 +58,7 @@ typedef struct PnvChip { AddressSpace xscom_as; =20 PnvLpcController lpc; + XICSNative xics; } PnvChip; =20 typedef struct PnvChipClass { --=20 2.7.4