From patchwork Thu Mar 16 14:35:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 9628449 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B2C7F60244 for ; Thu, 16 Mar 2017 14:42:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A6E7028648 for ; Thu, 16 Mar 2017 14:42:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9B2E828643; Thu, 16 Mar 2017 14:42:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EFCC828643 for ; Thu, 16 Mar 2017 14:42:56 +0000 (UTC) Received: from localhost ([::1]:43939 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coWcC-00075z-1j for patchwork-qemu-devel@patchwork.kernel.org; Thu, 16 Mar 2017 10:42:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33340) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1coWXR-00036i-AZ for qemu-devel@nongnu.org; Thu, 16 Mar 2017 10:38:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1coWXM-0006tM-Q1 for qemu-devel@nongnu.org; Thu, 16 Mar 2017 10:38:01 -0400 Received: from 12.mo1.mail-out.ovh.net ([87.98.162.229]:47717) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1coWXM-0006t8-GT for qemu-devel@nongnu.org; Thu, 16 Mar 2017 10:37:56 -0400 Received: from player756.ha.ovh.net (b7.ovh.net [213.186.33.57]) by mo1.mail-out.ovh.net (Postfix) with ESMTP id CFDCC62597 for ; Thu, 16 Mar 2017 15:37:54 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-10647-27.w90-89.abo.wanadoo.fr [90.89.233.27]) (Authenticated sender: clg@kaod.org) by player756.ha.ovh.net (Postfix) with ESMTPSA id 33C654200AD; Thu, 16 Mar 2017 15:37:50 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Thu, 16 Mar 2017 15:35:09 +0100 Message-Id: <1489674912-21942-6-git-send-email-clg@kaod.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1489674912-21942-1-git-send-email-clg@kaod.org> References: <1489674912-21942-1-git-send-email-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11763965178485115878 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelhedriedtgdegfecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.162.229 Subject: [Qemu-devel] [PATCH v2 5/8] ppc/pnv: create the ICP and ICS objects under the machine 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: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Like this is done for the sPAPR machine, we use a simple array under the PowerNV machine to store the Interrupt Control Presenters (ICP) objects, one for each vCPU. This array is indexed by 'cpu_index' of the CPUState but the users will provide a core PIR number. The mapping is done in the icp_get() handler of the machine and is transparent to XICS. We use a list to hold the different Interrupt Control Sources (ICS) objects, as PowerNV needs to handle multiple sources: for PCI-E and for the Processor Service Interface (PSI). Finally, to interface with the XICS layer which manipulates the ICP and ICS objects, we extend the PowerNV machine with an XICSFabric interface and its associated handlers. Signed-off-by: Cédric Le Goater --- Changes since v1: - handled pir-to-cpu_index mapping under icp_get - removed ics_eio handler - changed ICP name indexing - removed sysbus parenting of the ICP object hw/ppc/pnv.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/pnv.h | 4 ++ include/hw/ppc/xics.h | 1 + 3 files changed, 107 insertions(+) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 3fa722af82e6..6ff01c3b84d5 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -33,7 +33,10 @@ #include "exec/address-spaces.h" #include "qemu/cutils.h" #include "qapi/visitor.h" +#include "monitor/monitor.h" +#include "hw/intc/intc.h" +#include "hw/ppc/xics.h" #include "hw/ppc/pnv_xscom.h" #include "hw/isa/isa.h" @@ -417,6 +420,26 @@ static void ppc_powernv_init(MachineState *machine) machine->cpu_model = "POWER8"; } + /* Create the Interrupt Control Presenters before the vCPUs */ + pnv->nr_servers = pnv->num_chips * smp_cores * smp_threads; + pnv->icps = g_new0(PnvICPState, pnv->nr_servers); + for (i = 0; i < pnv->nr_servers; i++) { + PnvICPState *icp = &pnv->icps[i]; + char name[32]; + + /* TODO: fix ICP object name to be in sync with the core name */ + snprintf(name, sizeof(name), "icp[%d]", i); + object_initialize(icp, sizeof(*icp), TYPE_PNV_ICP); + object_property_add_child(OBJECT(pnv), name, OBJECT(icp), + &error_fatal); + object_property_add_const_link(OBJECT(icp), "xics", OBJECT(pnv), + &error_fatal); + object_property_set_bool(OBJECT(icp), true, "realized", &error_fatal); + } + + /* and the list of Interrupt Control Sources */ + QLIST_INIT(&pnv->ics); + /* Create the processor chips */ chip_typename = g_strdup_printf(TYPE_PNV_CHIP "-%s", machine->cpu_model); if (!object_class_by_name(chip_typename)) { @@ -743,6 +766,58 @@ static void pnv_get_num_chips(Object *obj, Visitor *v, const char *name, visit_type_uint32(v, name, &POWERNV_MACHINE(obj)->num_chips, errp); } +static ICSState *pnv_ics_get(XICSFabric *xi, int irq) +{ + PnvMachineState *pnv = POWERNV_MACHINE(xi); + ICSState *ics; + + QLIST_FOREACH(ics, &pnv->ics, list) { + if (ics_valid_irq(ics, irq)) { + return ics; + } + } + return NULL; +} + +static void pnv_ics_resend(XICSFabric *xi) +{ + PnvMachineState *pnv = POWERNV_MACHINE(xi); + ICSState *ics; + + QLIST_FOREACH(ics, &pnv->ics, list) { + ics_resend(ics); + } +} + +static PowerPCCPU *ppc_get_vcpu_by_pir(int pir) +{ + CPUState *cs; + + CPU_FOREACH(cs) { + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + + if (env->spr_cb[SPR_PIR].default_value == pir) { + return cpu; + } + } + + return NULL; +} + +static ICPState *pnv_icp_get(XICSFabric *xi, int pir) +{ + PnvMachineState *pnv = POWERNV_MACHINE(xi); + PowerPCCPU *cpu = ppc_get_vcpu_by_pir(pir); + + if (!cpu) { + return NULL; + } + + assert(cpu->parent_obj.cpu_index < pnv->nr_servers); + return ICP(&pnv->icps[cpu->parent_obj.cpu_index]); +} + static void pnv_set_num_chips(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { @@ -784,9 +859,27 @@ static void powernv_machine_class_props_init(ObjectClass *oc) NULL); } +static void pnv_pic_print_info(InterruptStatsProvider *obj, + Monitor *mon) +{ + PnvMachineState *pnv = POWERNV_MACHINE(obj); + ICSState *ics; + int i; + + for (i = 0; i < pnv->nr_servers; i++) { + icp_pic_print_info(ICP(&pnv->icps[i]), mon); + } + + QLIST_FOREACH(ics, &pnv->ics, list) { + ics_pic_print_info(ics, mon); + } +} + static void powernv_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + XICSFabricClass *xic = XICS_FABRIC_CLASS(oc); + InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc); mc->desc = "IBM PowerNV (Non-Virtualized)"; mc->init = ppc_powernv_init; @@ -797,6 +890,10 @@ static void powernv_machine_class_init(ObjectClass *oc, void *data) mc->no_parallel = 1; mc->default_boot_order = NULL; mc->default_ram_size = 1 * G_BYTE; + xic->icp_get = pnv_icp_get; + xic->ics_get = pnv_ics_get; + xic->ics_resend = pnv_ics_resend; + ispc->print_info = pnv_pic_print_info; powernv_machine_class_props_init(oc); } @@ -807,6 +904,11 @@ static const TypeInfo powernv_machine_info = { .instance_size = sizeof(PnvMachineState), .instance_init = powernv_machine_initfn, .class_init = powernv_machine_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_XICS_FABRIC }, + { TYPE_INTERRUPT_STATS_PROVIDER }, + { }, + }, }; static void powernv_machine_register_types(void) diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index df98a72006e4..d6ef04771aff 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -22,6 +22,7 @@ #include "hw/boards.h" #include "hw/sysbus.h" #include "hw/ppc/pnv_lpc.h" +#include "hw/ppc/xics.h" #define TYPE_PNV_CHIP "powernv-chip" #define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP) @@ -114,6 +115,9 @@ typedef struct PnvMachineState { PnvChip **chips; ISABus *isa_bus; + PnvICPState *icps; + uint32_t nr_servers; + QLIST_HEAD(, ICSState) ics; } PnvMachineState; #define PNV_FDT_ADDR 0x01000000 diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index cfcf7ecece69..4b100869003c 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -128,6 +128,7 @@ struct ICSState { qemu_irq *qirqs; ICSIRQState *irqs; XICSFabric *xics; + QLIST_ENTRY(ICSState) list; }; static inline bool ics_valid_irq(ICSState *ics, uint32_t nr)