From nobody Mon Feb 9 17:59:45 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; dkim=fail spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 149299989247764.49856839145207; Sun, 23 Apr 2017 19:11:32 -0700 (PDT) Received: from localhost ([::1]:41349 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d2TTP-00022o-0n for importer@patchew.org; Sun, 23 Apr 2017 22:11:31 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56360) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d2TIC-0001X1-1x for qemu-devel@nongnu.org; Sun, 23 Apr 2017 21:59:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d2TIA-0003Qj-KD for qemu-devel@nongnu.org; Sun, 23 Apr 2017 21:59:56 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:37621) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d2TIA-0003OZ-5d; Sun, 23 Apr 2017 21:59:54 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 3wB8fd2P9Pz9s8Y; Mon, 24 Apr 2017 11:59:36 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1492999177; bh=mUj6KknYXJQQUmJdOkRjtXXxX3Vaq7I1XTQI4R5dSw0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=i0Gz6WdBvCpO8MUiUofAJl05mXVnqLqaIX/PV39UfkPdaQ6JxVhr+dTNIdWtQdPw9 c0EZtVg6elJWGpMh67k31VAWVgPxyPge5Pjj7JNiAknwsfRKhKY1Ijpybg8Y2atuu7 U1yFLS8aPJs5w2OdtAxQjPuSi5urTJQQYtesK5mo= From: David Gibson To: peter.maydell@linaro.org Date: Mon, 24 Apr 2017 11:59:06 +1000 Message-Id: <20170424015927.8933-27-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170424015927.8933-1-david@gibson.dropbear.id.au> References: <20170424015927.8933-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PULL 26/47] ppc/pnv: add memory regions for the ICP registers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mdroth@linux.vnet.ibm.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: C=C3=A9dric Le Goater This provides to a PowerNV chip (POWER8) access to the Interrupt Management area, which contains the registers of the Interrupt Control Presenters of each thread. These are used to accept, return, forward interrupts in the system. This area is modeled with a per-chip container memory region holding all the ICP registers. Each thread of a chip is then associated with its ICP registers using a memory subregion indexed by its PIR number in the overall region. The device tree is populated accordingly. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/pnv.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++= ++++ include/hw/ppc/pnv.h | 19 ++++++++++++ 2 files changed, 100 insertions(+) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 2add2ad..1fa90d6 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -218,6 +218,43 @@ static void powernv_create_core_node(PnvChip *chip, Pn= vCore *pc, void *fdt) servers_prop, sizeof(servers_prop)))); } =20 +static void powernv_populate_icp(PnvChip *chip, void *fdt, uint32_t pir, + uint32_t nr_threads) +{ + uint64_t addr =3D PNV_ICP_BASE(chip) | (pir << 12); + char *name; + const char compat[] =3D "IBM,power8-icp\0IBM,ppc-xicp"; + uint32_t irange[2], i, rsize; + uint64_t *reg; + int offset; + + irange[0] =3D cpu_to_be32(pir); + irange[1] =3D cpu_to_be32(nr_threads); + + rsize =3D sizeof(uint64_t) * 2 * nr_threads; + reg =3D g_malloc(rsize); + for (i =3D 0; i < nr_threads; i++) { + reg[i * 2] =3D cpu_to_be64(addr | ((pir + i) * 0x1000)); + reg[i * 2 + 1] =3D cpu_to_be64(0x1000); + } + + name =3D g_strdup_printf("interrupt-controller@%"PRIX64, addr); + offset =3D fdt_add_subnode(fdt, 0, name); + _FDT(offset); + g_free(name); + + _FDT((fdt_setprop(fdt, offset, "compatible", compat, sizeof(compat)))); + _FDT((fdt_setprop(fdt, offset, "reg", reg, rsize))); + _FDT((fdt_setprop_string(fdt, offset, "device_type", + "PowerPC-External-Interrupt-Presentation"))); + _FDT((fdt_setprop(fdt, offset, "interrupt-controller", NULL, 0))); + _FDT((fdt_setprop(fdt, offset, "ibm,interrupt-server-ranges", + irange, sizeof(irange)))); + _FDT((fdt_setprop_cell(fdt, offset, "#interrupt-cells", 1))); + _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 0))); + g_free(reg); +} + static void powernv_populate_chip(PnvChip *chip, void *fdt) { PnvChipClass *pcc =3D PNV_CHIP_GET_CLASS(chip); @@ -231,6 +268,10 @@ 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 Control Presenters (ICP). One per core. */ + powernv_populate_icp(chip, fdt, pnv_core->pir, + CPU_CORE(pnv_core)->nr_threads); } =20 if (chip->ram_size) { @@ -643,6 +684,38 @@ static void pnv_chip_init(Object *obj) object_property_add_child(obj, "lpc", OBJECT(&chip->lpc), NULL); } =20 +static void pnv_chip_icp_realize(PnvChip *chip, Error **errp) +{ + PnvChipClass *pcc =3D PNV_CHIP_GET_CLASS(chip); + char *typename =3D pnv_core_typename(pcc->cpu_model); + size_t typesize =3D object_type_get_instance_size(typename); + int i, j; + char *name; + XICSFabric *xi =3D XICS_FABRIC(qdev_get_machine()); + + name =3D g_strdup_printf("icp-%x", chip->chip_id); + memory_region_init(&chip->icp_mmio, OBJECT(chip), name, PNV_ICP_SIZE); + sysbus_init_mmio(SYS_BUS_DEVICE(chip), &chip->icp_mmio); + g_free(name); + + sysbus_mmio_map(SYS_BUS_DEVICE(chip), 1, PNV_ICP_BASE(chip)); + + /* Map the ICP registers for each thread */ + for (i =3D 0; i < chip->nr_cores; i++) { + PnvCore *pnv_core =3D PNV_CORE(chip->cores + i * typesize); + int core_hwid =3D CPU_CORE(pnv_core)->core_id; + + for (j =3D 0; j < CPU_CORE(pnv_core)->nr_threads; j++) { + uint32_t pir =3D pcc->core_pir(chip, core_hwid) + j; + PnvICPState *icp =3D PNV_ICP(xics_icp_get(xi, pir)); + + memory_region_add_subregion(&chip->icp_mmio, pir << 12, &icp->= mmio); + } + } + + g_free(typename); +} + static void pnv_chip_realize(DeviceState *dev, Error **errp) { PnvChip *chip =3D PNV_CHIP(dev); @@ -713,6 +786,14 @@ static void pnv_chip_realize(DeviceState *dev, Error *= *errp) object_property_set_bool(OBJECT(&chip->lpc), true, "realized", &error_fatal); pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip->lpc.xscom_reg= s); + + /* Interrupt Management Area. This is the memory region holding + * all the Interrupt Control Presenter (ICP) registers */ + pnv_chip_icp_realize(chip, &error); + if (error) { + error_propagate(errp, error); + return; + } } =20 static Property pnv_chip_properties[] =3D { diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index 5693ba1..96231c1 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -54,6 +54,7 @@ typedef struct PnvChip { MemoryRegion xscom_mmio; MemoryRegion xscom; AddressSpace xscom_as; + MemoryRegion icp_mmio; =20 PnvLpcController lpc; } PnvChip; @@ -136,4 +137,22 @@ typedef struct PnvMachineState { #define PNV_XSCOM_BASE(chip) \ (chip->xscom_base + ((uint64_t)(chip)->chip_id) * PNV_XSCOM_SIZE) =20 +/* + * XSCOM 0x20109CA defines the ICP BAR: + * + * 0:29 : bits 14 to 43 of address to define 1 MB region. + * 30 : 1 to enable ICP to receive loads/stores against its BAR region + * 31:63 : Constant 0 + * + * Usually defined as : + * + * 0xffffe00200000000 -> 0x0003ffff80000000 + * 0xffffe00600000000 -> 0x0003ffff80100000 + * 0xffffe02200000000 -> 0x0003ffff80800000 + * 0xffffe02600000000 -> 0x0003ffff80900000 + */ +#define PNV_ICP_SIZE 0x0000000000100000ull +#define PNV_ICP_BASE(chip) \ + (0x0003ffff80000000ull + (uint64_t) PNV_CHIP_INDEX(chip) * PNV_ICP_SIZ= E) + #endif /* _PPC_PNV_H */ --=20 2.9.3