From patchwork Wed Mar 8 10:52:46 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: 736533 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vdVqj5DxPz9sCX for ; Wed, 8 Mar 2017 21:58:09 +1100 (AEDT) Received: from localhost ([::1]:55536 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1clZIF-0002ok-5K for incoming@patchwork.ozlabs.org; Wed, 08 Mar 2017 05:58:07 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37006) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1clZDZ-0007eR-UY for qemu-devel@nongnu.org; Wed, 08 Mar 2017 05:53:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1clZDV-00037V-GZ for qemu-devel@nongnu.org; Wed, 08 Mar 2017 05:53:18 -0500 Received: from mo177.mail-out.ovh.net ([178.32.228.177]:49274) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1clZDV-00036t-6Z for qemu-devel@nongnu.org; Wed, 08 Mar 2017 05:53:13 -0500 Received: from player714.ha.ovh.net (b7.ovh.net [213.186.33.57]) by mo177.mail-out.ovh.net (Postfix) with ESMTP id C43B732945 for ; Wed, 8 Mar 2017 11:53:09 +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 player714.ha.ovh.net (Postfix) with ESMTPSA id 9E9AF3C006B; Wed, 8 Mar 2017 11:53:05 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: David Gibson Date: Wed, 8 Mar 2017 11:52:46 +0100 Message-Id: <1488970371-8865-4-git-send-email-clg@kaod.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488970371-8865-1-git-send-email-clg@kaod.org> References: <1488970371-8865-1-git-send-email-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 16326956027808943078 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelhedrgeeggddujecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 178.32.228.177 Subject: [Qemu-devel] [PATCH for-2.10 3/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+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" 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. 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 --- hw/ppc/pnv.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/pnv.h | 4 +++ include/hw/ppc/xics.h | 1 + 3 files changed, 94 insertions(+) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 09f0d22defb8..461d3535e99c 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -32,6 +32,8 @@ #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/pnv_xscom.h" @@ -416,6 +418,23 @@ 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(ICPState, pnv->nr_servers); + for (i = 0; i < pnv->nr_servers; i++) { + ICPState *icp = &pnv->icps[i]; + object_initialize(icp, sizeof(*icp), TYPE_ICP); + qdev_set_parent_bus(DEVICE(icp), sysbus_get_default()); + object_property_add_child(OBJECT(pnv), "icp[*]", 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)) { @@ -742,6 +761,48 @@ 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 void pnv_ics_eoi(XICSFabric *xi, int irq) +{ + PnvMachineState *pnv = POWERNV_MACHINE(xi); + ICSState *ics; + + QLIST_FOREACH(ics, &pnv->ics, list) { + if (ics_valid_irq(ics, irq)) { + ics_eoi(ics, irq); + } + } +} + +static ICPState *pnv_icp_get(XICSFabric *xi, int server) +{ + PnvMachineState *pnv = POWERNV_MACHINE(xi); + + return (server < pnv->nr_servers) ? &pnv->icps[server] : NULL; +} + static void pnv_set_num_chips(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { @@ -783,9 +844,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(&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; @@ -796,6 +875,11 @@ 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_eoi = pnv_ics_eoi; + xic->ics_resend = pnv_ics_resend; + ispc->print_info = pnv_pic_print_info; powernv_machine_class_props_init(oc); } @@ -806,6 +890,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..6a0b004cea93 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; + ICPState *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 00b003b2392d..c2032cac55f6 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -115,6 +115,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)