From patchwork Thu Nov 23 13:29:31 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: 840758 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjKxH6Pv6z9s76 for ; Fri, 24 Nov 2017 00:32:03 +1100 (AEDT) Received: from localhost ([::1]:44350 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrbm-0000im-04 for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:32:02 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37693) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHraw-0000ff-CG for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHraq-00005m-Ib for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:10 -0500 Received: from 4.mo3.mail-out.ovh.net ([178.33.46.10]:47193) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHraq-0008US-Am for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:04 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 26FC7175A58 for ; Thu, 23 Nov 2017 14:31:03 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id E31512E00A4; Thu, 23 Nov 2017 14:30:57 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:31 +0100 Message-Id: <20171123132955.1261-2-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14814309500415609683 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 178.33.46.10 Subject: [Qemu-devel] [PATCH 01/25] ppc/xics: introduce an icp_create() helper 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The sPAPR and the PowerNV core objects create the interrupt presenter object of the CPUs in a very similar way. Let's provide a common routine in which we use the presenter 'type' as a child identifier. Signed-off-by: Cédric Le Goater Reviewed-by: David Gibson Reviewed-by: Greg Kurz --- hw/intc/xics.c | 22 ++++++++++++++++++++++ hw/ppc/pnv_core.c | 10 +--------- hw/ppc/spapr_cpu_core.c | 13 ++----------- include/hw/ppc/xics.h | 3 +++ 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index a1cc0e420c98..e4ccdff8f577 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -384,6 +384,28 @@ static const TypeInfo icp_info = { .class_size = sizeof(ICPStateClass), }; +Object *icp_create(CPUState *cs, const char *type, XICSFabric *xi, Error **errp) +{ + Object *child = OBJECT(cs); + Error *local_err = NULL; + Object *obj; + + obj = object_new(type); + object_property_add_child(child, type, obj, &error_abort); + object_unref(obj); + object_property_add_const_link(obj, ICP_PROP_XICS, OBJECT(xi), + &error_abort); + object_property_add_const_link(obj, ICP_PROP_CPU, child, &error_abort); + object_property_set_bool(obj, true, "realized", &local_err); + if (local_err) { + object_unparent(obj); + error_propagate(errp, local_err); + obj = NULL; + } + + return obj; +} + /* * ICS: Source layer */ diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 82ff440b3334..a066736846f8 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -126,7 +126,6 @@ static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp) Error *local_err = NULL; CPUState *cs = CPU(child); PowerPCCPU *cpu = POWERPC_CPU(cs); - Object *obj; object_property_set_bool(child, true, "realized", &local_err); if (local_err) { @@ -134,13 +133,7 @@ static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp) return; } - obj = object_new(TYPE_PNV_ICP); - object_property_add_child(child, "icp", obj, NULL); - object_unref(obj); - object_property_add_const_link(obj, ICP_PROP_XICS, OBJECT(xi), - &error_abort); - object_property_add_const_link(obj, ICP_PROP_CPU, child, &error_abort); - object_property_set_bool(obj, true, "realized", &local_err); + icp_create(cs, TYPE_PNV_ICP, xi, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -148,7 +141,6 @@ static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp) powernv_cpu_init(cpu, &local_err); if (local_err) { - object_unparent(obj); error_propagate(errp, local_err); return; } diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 4ba8563d49e4..f8a520a2fa2d 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -111,7 +111,6 @@ static void spapr_cpu_core_realize_child(Object *child, Error *local_err = NULL; CPUState *cs = CPU(child); PowerPCCPU *cpu = POWERPC_CPU(cs); - Object *obj; object_property_set_bool(child, true, "realized", &local_err); if (local_err) { @@ -123,21 +122,13 @@ static void spapr_cpu_core_realize_child(Object *child, goto error; } - obj = object_new(spapr->icp_type); - object_property_add_child(child, "icp", obj, &error_abort); - object_unref(obj); - object_property_add_const_link(obj, ICP_PROP_XICS, OBJECT(spapr), - &error_abort); - object_property_add_const_link(obj, ICP_PROP_CPU, child, &error_abort); - object_property_set_bool(obj, true, "realized", &local_err); + icp_create(cs, spapr->icp_type, XICS_FABRIC(spapr), &local_err); if (local_err) { - goto free_icp; + goto error; } return; -free_icp: - object_unparent(obj); error: error_propagate(errp, local_err); } diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index 2df99be111ce..126b47dec38b 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -212,4 +212,7 @@ typedef struct sPAPRMachineState sPAPRMachineState; int xics_kvm_init(sPAPRMachineState *spapr, Error **errp); void xics_spapr_init(sPAPRMachineState *spapr); +Object *icp_create(CPUState *cs, const char *type, XICSFabric *xi, + Error **errp); + #endif /* XICS_H */ From patchwork Thu Nov 23 13:29:32 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: 840763 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjL0k2QQqz9s72 for ; Fri, 24 Nov 2017 00:35:02 +1100 (AEDT) Received: from localhost ([::1]:44367 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHree-0003O1-9x for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:35:00 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37761) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHray-0000hM-UY for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrav-0000Hr-QL for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:12 -0500 Received: from 7.mo3.mail-out.ovh.net ([46.105.57.200]:42541) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrav-0000Gk-Kc for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:09 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 45C17171C45 for ; Thu, 23 Nov 2017 14:31:08 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 163672E0081; Thu, 23 Nov 2017 14:31:03 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:32 +0100 Message-Id: <20171123132955.1261-3-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14815716876075633491 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 46.105.57.200 Subject: [Qemu-devel] [PATCH 02/25] ppc/xics: assign of the CPU 'intc' pointer under the core 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The 'intc' pointer of the CPU references the interrupt presenter in the XICS interrupt mode. When the XIVE interrupt mode is available and activated, the machine will need to reassign this pointer to reflect the change. Moving this assignment under the realize routine of the CPU will ease the process when the interrupt mode is toggled. Signed-off-by: Cédric Le Goater Reviewed-by: David Gibson Reviewed-by: Greg Kurz --- hw/intc/xics.c | 1 - hw/ppc/pnv_core.c | 2 +- hw/ppc/spapr_cpu_core.c | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index e4ccdff8f577..0f2e7273bc8f 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -334,7 +334,6 @@ static void icp_realize(DeviceState *dev, Error **errp) } cpu = POWERPC_CPU(obj); - cpu->intc = OBJECT(icp); icp->cs = CPU(obj); env = &cpu->env; diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index a066736846f8..90acaac45889 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -133,7 +133,7 @@ static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp) return; } - icp_create(cs, TYPE_PNV_ICP, xi, &local_err); + cpu->intc = icp_create(cs, TYPE_PNV_ICP, xi, &local_err); if (local_err) { error_propagate(errp, local_err); return; diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index f8a520a2fa2d..f7cc74512481 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -122,7 +122,7 @@ static void spapr_cpu_core_realize_child(Object *child, goto error; } - icp_create(cs, spapr->icp_type, XICS_FABRIC(spapr), &local_err); + cpu->intc = icp_create(cs, spapr->icp_type, XICS_FABRIC(spapr), &local_err); if (local_err) { goto error; } From patchwork Thu Nov 23 13:29:33 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: 840767 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjL433Dt6z9s72 for ; Fri, 24 Nov 2017 00:37:55 +1100 (AEDT) Received: from localhost ([::1]:44387 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrhR-0006DM-DF for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:37:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37836) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrb3-0000ly-Vr for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrb0-0000PD-QO for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:18 -0500 Received: from 18.mo3.mail-out.ovh.net ([87.98.172.162]:34584) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrb0-0000NH-KM for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:14 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 6B74B175AA8 for ; Thu, 23 Nov 2017 14:31:13 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 3E7CE2E0098; Thu, 23 Nov 2017 14:31:08 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:33 +0100 Message-Id: <20171123132955.1261-4-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14817124252450917203 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.172.162 Subject: [Qemu-devel] [PATCH 03/25] spapr: introduce a spapr_icp_create() helper 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" On sPAPR, the creation of the interrupt presenter depends on some of the machine attributes. When the XIVE interrupt mode is available, this will get more complex. So provide a machine-level helper to isolate the process and hide the details to the sPAPR core realize function. Signed-off-by: Cédric Le Goater Reviewed-by: Greg Kurz --- hw/ppc/spapr.c | 14 ++++++++++++++ hw/ppc/spapr_cpu_core.c | 2 +- include/hw/ppc/spapr.h | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 174e7ff0678d..925cbd3c1bf4 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3556,6 +3556,20 @@ static ICPState *spapr_icp_get(XICSFabric *xi, int vcpu_id) return cpu ? ICP(cpu->intc) : NULL; } +Object *spapr_icp_create(sPAPRMachineState *spapr, CPUState *cs, Error **errp) +{ + Error *local_err = NULL; + Object *obj; + + obj = icp_create(cs, spapr->icp_type, XICS_FABRIC(spapr), &local_err); + if (local_err) { + error_propagate(errp, local_err); + return NULL; + } + + return obj; +} + static void spapr_pic_print_info(InterruptStatsProvider *obj, Monitor *mon) { diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index f7cc74512481..61a9850e688b 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -122,7 +122,7 @@ static void spapr_cpu_core_realize_child(Object *child, goto error; } - cpu->intc = icp_create(cs, spapr->icp_type, XICS_FABRIC(spapr), &local_err); + cpu->intc = spapr_icp_create(spapr, cs, &local_err); if (local_err) { goto error; } diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 9d21ca9bde3a..9da38de34277 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -707,4 +707,6 @@ void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg); int spapr_vcpu_id(PowerPCCPU *cpu); PowerPCCPU *spapr_find_cpu(int vcpu_id); +Object *spapr_icp_create(sPAPRMachineState *spapr, CPUState *cs, Error **errp); + #endif /* HW_SPAPR_H */ From patchwork Thu Nov 23 13:29:34 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: 840770 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjL7s1fr6z9s72 for ; Fri, 24 Nov 2017 00:41:13 +1100 (AEDT) Received: from localhost ([::1]:44410 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrkd-0000e9-83 for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:41:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37905) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrb8-0000qh-Mi for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrb6-0000Xg-Ip for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:22 -0500 Received: from 10.mo3.mail-out.ovh.net ([87.98.165.232]:50037) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrb6-0000WM-9h for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:20 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id C15DD171A49 for ; Thu, 23 Nov 2017 14:31:18 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 673092E009B; Thu, 23 Nov 2017 14:31:13 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:34 +0100 Message-Id: <20171123132955.1261-5-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14818531626810968915 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.165.232 Subject: [Qemu-devel] [PATCH 04/25] spapr: move the IRQ allocation routines 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Also change the prototype to use a sPAPRMachineState and prefix them with spapr_irq_. It will let us synchronise the IRQ allocation with the XIVE interrupt mode when available. Signed-off-by: Cédric Le Goater Reviewed-by: David Gibson Reviewed-by: Greg Kurz --- hw/intc/trace-events | 4 -- hw/intc/xics_spapr.c | 114 ------------------------------------------------- hw/ppc/spapr.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++ hw/ppc/spapr_events.c | 4 +- hw/ppc/spapr_pci.c | 8 ++-- hw/ppc/spapr_vio.c | 2 +- hw/ppc/trace-events | 4 ++ include/hw/ppc/spapr.h | 6 +++ include/hw/ppc/xics.h | 4 -- 9 files changed, 131 insertions(+), 129 deletions(-) diff --git a/hw/intc/trace-events b/hw/intc/trace-events index b298fac7c6a8..7077aaaee6d0 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -64,10 +64,6 @@ xics_ics_simple_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq 0x%x] xics_ics_simple_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_xive: irq 0x%x [src %d] server 0x%x prio 0x%x" xics_ics_simple_reject(int nr, int srcno) "reject irq 0x%x [src %d]" xics_ics_simple_eoi(int nr) "ics_eoi: irq 0x%x" -xics_alloc(int irq) "irq %d" -xics_alloc_block(int first, int num, bool lsi, int align) "first irq %d, %d irqs, lsi=%d, alignnum %d" -xics_ics_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs" -xics_ics_free_warn(int src, int irq) "Source#%d, irq %d is already free" # hw/intc/s390_flic_kvm.c flic_create_device(int err) "flic: create device failed %d" diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index e8c0a1b3e903..5a0967caf430 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -245,120 +245,6 @@ void xics_spapr_init(sPAPRMachineState *spapr) spapr_register_hypercall(H_IPOLL, h_ipoll); } -#define ICS_IRQ_FREE(ics, srcno) \ - (!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK))) - -static int ics_find_free_block(ICSState *ics, int num, int alignnum) -{ - int first, i; - - for (first = 0; first < ics->nr_irqs; first += alignnum) { - if (num > (ics->nr_irqs - first)) { - return -1; - } - for (i = first; i < first + num; ++i) { - if (!ICS_IRQ_FREE(ics, i)) { - break; - } - } - if (i == (first + num)) { - return first; - } - } - - return -1; -} - -int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp) -{ - int irq; - - if (!ics) { - return -1; - } - if (irq_hint) { - if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) { - error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint); - return -1; - } - irq = irq_hint; - } else { - irq = ics_find_free_block(ics, 1, 1); - if (irq < 0) { - error_setg(errp, "can't allocate IRQ: no IRQ left"); - return -1; - } - irq += ics->offset; - } - - ics_set_irq_type(ics, irq - ics->offset, lsi); - trace_xics_alloc(irq); - - return irq; -} - -/* - * Allocate block of consecutive IRQs, and return the number of the first IRQ in - * the block. If align==true, aligns the first IRQ number to num. - */ -int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi, - bool align, Error **errp) -{ - int i, first = -1; - - if (!ics) { - return -1; - } - - /* - * MSIMesage::data is used for storing VIRQ so - * it has to be aligned to num to support multiple - * MSI vectors. MSI-X is not affected by this. - * The hint is used for the first IRQ, the rest should - * be allocated continuously. - */ - if (align) { - assert((num == 1) || (num == 2) || (num == 4) || - (num == 8) || (num == 16) || (num == 32)); - first = ics_find_free_block(ics, num, num); - } else { - first = ics_find_free_block(ics, num, 1); - } - if (first < 0) { - error_setg(errp, "can't find a free %d-IRQ block", num); - return -1; - } - - for (i = first; i < first + num; ++i) { - ics_set_irq_type(ics, i, lsi); - } - first += ics->offset; - - trace_xics_alloc_block(first, num, lsi, align); - - return first; -} - -static void ics_free(ICSState *ics, int srcno, int num) -{ - int i; - - for (i = srcno; i < srcno + num; ++i) { - if (ICS_IRQ_FREE(ics, i)) { - trace_xics_ics_free_warn(0, i + ics->offset); - } - memset(&ics->irqs[i], 0, sizeof(ICSIRQState)); - } -} - -void spapr_ics_free(ICSState *ics, int irq, int num) -{ - if (ics_valid_irq(ics, irq)) { - trace_xics_ics_free(0, irq, num); - ics_free(ics, irq - ics->offset, num); - } -} - void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle) { uint32_t interrupt_server_ranges_prop[] = { diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 925cbd3c1bf4..7ae84d40bdb4 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3570,6 +3570,120 @@ Object *spapr_icp_create(sPAPRMachineState *spapr, CPUState *cs, Error **errp) return obj; } +#define ICS_IRQ_FREE(ics, srcno) \ + (!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK))) + +static int ics_find_free_block(ICSState *ics, int num, int alignnum) +{ + int first, i; + + for (first = 0; first < ics->nr_irqs; first += alignnum) { + if (num > (ics->nr_irqs - first)) { + return -1; + } + for (i = first; i < first + num; ++i) { + if (!ICS_IRQ_FREE(ics, i)) { + break; + } + } + if (i == (first + num)) { + return first; + } + } + + return -1; +} + +int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi, + Error **errp) +{ + ICSState *ics = spapr->ics; + int irq; + + if (!ics) { + return -1; + } + if (irq_hint) { + if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) { + error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint); + return -1; + } + irq = irq_hint; + } else { + irq = ics_find_free_block(ics, 1, 1); + if (irq < 0) { + error_setg(errp, "can't allocate IRQ: no IRQ left"); + return -1; + } + irq += ics->offset; + } + + ics_set_irq_type(ics, irq - ics->offset, lsi); + trace_spapr_irq_alloc(irq); + + return irq; +} + +/* + * Allocate block of consecutive IRQs, and return the number of the first IRQ in + * the block. If align==true, aligns the first IRQ number to num. + */ +int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi, + bool align, Error **errp) +{ + ICSState *ics = spapr->ics; + int i, first = -1; + + if (!ics) { + return -1; + } + + /* + * MSIMesage::data is used for storing VIRQ so + * it has to be aligned to num to support multiple + * MSI vectors. MSI-X is not affected by this. + * The hint is used for the first IRQ, the rest should + * be allocated continuously. + */ + if (align) { + assert((num == 1) || (num == 2) || (num == 4) || + (num == 8) || (num == 16) || (num == 32)); + first = ics_find_free_block(ics, num, num); + } else { + first = ics_find_free_block(ics, num, 1); + } + if (first < 0) { + error_setg(errp, "can't find a free %d-IRQ block", num); + return -1; + } + + for (i = first; i < first + num; ++i) { + ics_set_irq_type(ics, i, lsi); + } + first += ics->offset; + + trace_spapr_irq_alloc_block(first, num, lsi, align); + + return first; +} + +void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num) +{ + ICSState *ics = spapr->ics; + int srcno = irq - ics->offset; + int i; + + if (ics_valid_irq(ics, irq)) { + trace_spapr_irq_free(0, irq, num); + for (i = srcno; i < srcno + num; ++i) { + if (ICS_IRQ_FREE(ics, i)) { + trace_spapr_irq_free_warn(0, i + ics->offset); + } + memset(&ics->irqs[i], 0, sizeof(ICSIRQState)); + } + } +} + static void spapr_pic_print_info(InterruptStatsProvider *obj, Monitor *mon) { diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index e377fc7ddea2..cead596f3e7a 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -718,7 +718,7 @@ void spapr_events_init(sPAPRMachineState *spapr) spapr->event_sources = spapr_event_sources_new(); spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_EPOW, - spapr_ics_alloc(spapr->ics, 0, false, + spapr_irq_alloc(spapr, 0, false, &error_fatal)); /* NOTE: if machine supports modern/dedicated hotplug event source, @@ -731,7 +731,7 @@ void spapr_events_init(sPAPRMachineState *spapr) */ if (spapr->use_hotplug_event_source) { spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_HOT_PLUG, - spapr_ics_alloc(spapr->ics, 0, false, + spapr_irq_alloc(spapr, 0, false, &error_fatal)); } diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 5a3122a9f9f9..e0ef77a480e5 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -314,7 +314,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, return; } - spapr_ics_free(spapr->ics, msi->first_irq, msi->num); + spapr_irq_free(spapr, msi->first_irq, msi->num); if (msi_present(pdev)) { spapr_msi_setmsg(pdev, 0, false, 0, 0); } @@ -352,7 +352,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, } /* Allocate MSIs */ - irq = spapr_ics_alloc_block(spapr->ics, req_num, false, + irq = spapr_irq_alloc_block(spapr, req_num, false, ret_intr_type == RTAS_TYPE_MSI, &err); if (err) { error_reportf_err(err, "Can't allocate MSIs for device %x: ", @@ -363,7 +363,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, /* Release previous MSIs */ if (msi) { - spapr_ics_free(spapr->ics, msi->first_irq, msi->num); + spapr_irq_free(spapr, msi->first_irq, msi->num); g_hash_table_remove(phb->msi, &config_addr); } @@ -1675,7 +1675,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) uint32_t irq; Error *local_err = NULL; - irq = spapr_ics_alloc_block(spapr->ics, 1, true, false, &local_err); + irq = spapr_irq_alloc_block(spapr, 1, true, false, &local_err); if (local_err) { error_propagate(errp, local_err); error_prepend(errp, "can't allocate LSIs: "); diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index ea3bc8bd9e21..bb7ed2c537b0 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -454,7 +454,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp) dev->qdev.id = id; } - dev->irq = spapr_ics_alloc(spapr->ics, dev->irq, false, &local_err); + dev->irq = spapr_irq_alloc(spapr, dev->irq, false, &local_err); if (local_err) { error_propagate(errp, local_err); return; diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events index 4a6a6490fa78..b7c3e64b5ee7 100644 --- a/hw/ppc/trace-events +++ b/hw/ppc/trace-events @@ -12,6 +12,10 @@ spapr_pci_msi_retry(unsigned config_addr, unsigned req_num, unsigned max_irqs) " # hw/ppc/spapr.c spapr_cas_failed(unsigned long n) "DT diff buffer is too small: %ld bytes" spapr_cas_continue(unsigned long n) "Copy changes to the guest: %ld bytes" +spapr_irq_alloc(int irq) "irq %d" +spapr_irq_alloc_block(int first, int num, bool lsi, int align) "first irq %d, %d irqs, lsi=%d, alignnum %d" +spapr_irq_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs" +spapr_irq_free_warn(int src, int irq) "Source#%d, irq %d is already free" # hw/ppc/spapr_hcall.c spapr_cas_pvr_try(uint32_t pvr) "0x%x" diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 9da38de34277..7a133f80411a 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -709,4 +709,10 @@ PowerPCCPU *spapr_find_cpu(int vcpu_id); Object *spapr_icp_create(sPAPRMachineState *spapr, CPUState *cs, Error **errp); +int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi, + Error **errp); +int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi, + bool align, Error **errp); +void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num); + #endif /* HW_SPAPR_H */ diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index 126b47dec38b..cea462bc7f3e 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -181,10 +181,6 @@ typedef struct XICSFabricClass { #define XICS_IRQS_SPAPR 1024 -int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp); -int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi, bool align, - Error **errp); -void spapr_ics_free(ICSState *ics, int irq, int num); void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle); qemu_irq xics_get_qirq(XICSFabric *xi, int irq); From patchwork Thu Nov 23 13:29:35 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: 840773 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjLBh56gwz9s72 for ; Fri, 24 Nov 2017 00:43:40 +1100 (AEDT) Received: from localhost ([::1]:44423 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrn0-00042r-QV for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:43:38 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38066) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrbE-0000w0-ET for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrbB-0000f7-9Y for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:28 -0500 Received: from 18.mo3.mail-out.ovh.net ([87.98.172.162]:38006) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrbB-0000dd-3v for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:25 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id EF36D171BED for ; Thu, 23 Nov 2017 14:31:23 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id BE8102E0096; Thu, 23 Nov 2017 14:31:18 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:35 +0100 Message-Id: <20171123132955.1261-6-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14819939002675006291 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.172.162 Subject: [Qemu-devel] [PATCH 05/25] spapr: introduce a spapr_irq_set() helper 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" It will make synchronisation easier with the XIVE interrupt mode when available. The 'irq' parameter refers to the global IRQ number space. Signed-off-by: Cédric Le Goater Reviewed-by: David Gibson --- hw/ppc/spapr.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 7ae84d40bdb4..79f38a9ff4e1 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3594,6 +3594,11 @@ static int ics_find_free_block(ICSState *ics, int num, int alignnum) return -1; } +static void spapr_irq_set(sPAPRMachineState *spapr, int irq, bool lsi) +{ + ics_set_irq_type(spapr->ics, irq - spapr->ics->offset, lsi); +} + int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi, Error **errp) { @@ -3618,7 +3623,7 @@ int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi, irq += ics->offset; } - ics_set_irq_type(ics, irq - ics->offset, lsi); + spapr_irq_set(spapr, irq, lsi); trace_spapr_irq_alloc(irq); return irq; @@ -3657,10 +3662,10 @@ int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi, return -1; } + first += ics->offset; for (i = first; i < first + num; ++i) { - ics_set_irq_type(ics, i, lsi); + spapr_irq_set(spapr, i, lsi); } - first += ics->offset; trace_spapr_irq_alloc_block(first, num, lsi, align); From patchwork Thu Nov 23 13:29:36 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: 840762 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjL0R5jQ2z9s72 for ; Fri, 24 Nov 2017 00:34:47 +1100 (AEDT) Received: from localhost ([::1]:44364 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHreP-0003B2-Pe for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:34:45 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38312) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrbQ-000148-CH for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrbG-0000sD-Ls for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:40 -0500 Received: from 11.mo3.mail-out.ovh.net ([87.98.184.158]:50733) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrbG-0000oO-DK for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:30 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 249B4175AB0 for ; Thu, 23 Nov 2017 14:31:29 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id E8CD42E0096; Thu, 23 Nov 2017 14:31:23 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:36 +0100 Message-Id: <20171123132955.1261-7-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14821627850708978515 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.184.158 Subject: [Qemu-devel] [PATCH 06/25] spapr: introduce a spapr_irq_get_qirq() helper 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" xics_get_qirq() is only used by the sPAPR machine. Let's move it there and change its name to reflect its scope. It will be useful for XIVE support which will use its own set of qirqs. Signed-off-by: Cédric Le Goater Reviewed-by: David Gibson --- hw/intc/xics.c | 12 ------------ hw/ppc/spapr.c | 11 +++++++++++ hw/ppc/spapr_events.c | 12 +++++------- hw/ppc/spapr_pci.c | 2 +- include/hw/pci-host/spapr.h | 2 +- include/hw/ppc/spapr.h | 1 + include/hw/ppc/spapr_vio.h | 2 +- include/hw/ppc/xics.h | 1 - 8 files changed, 20 insertions(+), 23 deletions(-) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 0f2e7273bc8f..a78b4dbd033d 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -714,18 +714,6 @@ static const TypeInfo xics_fabric_info = { /* * Exported functions */ -qemu_irq xics_get_qirq(XICSFabric *xi, int irq) -{ - XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(xi); - ICSState *ics = xic->ics_get(xi, irq); - - if (ics) { - return ics->qirqs[irq - ics->offset]; - } - - return NULL; -} - ICPState *xics_icp_get(XICSFabric *xi, int server) { XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(xi); diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 79f38a9ff4e1..5d3325ca3c88 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3689,6 +3689,17 @@ void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num) } } +qemu_irq spapr_irq_get_qirq(sPAPRMachineState *spapr, int irq) +{ + ICSState *ics = spapr->ics; + + if (ics_valid_irq(ics, irq)) { + return ics->qirqs[irq - ics->offset]; + } + + return NULL; +} + static void spapr_pic_print_info(InterruptStatsProvider *obj, Monitor *mon) { diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index cead596f3e7a..0427590e9cac 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -472,9 +472,8 @@ static void spapr_powerdown_req(Notifier *n, void *opaque) rtas_event_log_queue(spapr, entry); - qemu_irq_pulse(xics_get_qirq(XICS_FABRIC(spapr), - rtas_event_log_to_irq(spapr, - RTAS_LOG_TYPE_EPOW))); + qemu_irq_pulse(spapr_irq_get_qirq(spapr, + rtas_event_log_to_irq(spapr, RTAS_LOG_TYPE_EPOW))); } static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action, @@ -556,9 +555,8 @@ static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action, rtas_event_log_queue(spapr, entry); - qemu_irq_pulse(xics_get_qirq(XICS_FABRIC(spapr), - rtas_event_log_to_irq(spapr, - RTAS_LOG_TYPE_HOTPLUG))); + qemu_irq_pulse(spapr_irq_get_qirq(spapr, + rtas_event_log_to_irq(spapr, RTAS_LOG_TYPE_HOTPLUG))); } void spapr_hotplug_req_add_by_index(sPAPRDRConnector *drc) @@ -678,7 +676,7 @@ static void check_exception(PowerPCCPU *cpu, sPAPRMachineState *spapr, spapr_event_sources_get_source(spapr->event_sources, i); g_assert(source->enabled); - qemu_irq_pulse(xics_get_qirq(XICS_FABRIC(spapr), source->irq)); + qemu_irq_pulse(spapr_irq_get_qirq(spapr, source->irq)); } } diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index e0ef77a480e5..a02faa12333e 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -723,7 +723,7 @@ static void spapr_msi_write(void *opaque, hwaddr addr, trace_spapr_pci_msi_write(addr, data, irq); - qemu_irq_pulse(xics_get_qirq(XICS_FABRIC(spapr), irq)); + qemu_irq_pulse(spapr_irq_get_qirq(spapr, irq)); } static const MemoryRegionOps spapr_msi_ops = { diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 38470b2f0e5c..3059fdd614e6 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -108,7 +108,7 @@ static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin) { sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); - return xics_get_qirq(XICS_FABRIC(spapr), phb->lsi_table[pin].irq); + return spapr_irq_get_qirq(spapr, phb->lsi_table[pin].irq); } PCIHostState *spapr_create_phb(sPAPRMachineState *spapr, int index); diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 7a133f80411a..9a3885593c86 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -714,5 +714,6 @@ int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi, int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi, bool align, Error **errp); void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num); +qemu_irq spapr_irq_get_qirq(sPAPRMachineState *spapr, int irq); #endif /* HW_SPAPR_H */ diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h index 2e9685a5d900..404f1de2c046 100644 --- a/include/hw/ppc/spapr_vio.h +++ b/include/hw/ppc/spapr_vio.h @@ -87,7 +87,7 @@ static inline qemu_irq spapr_vio_qirq(VIOsPAPRDevice *dev) { sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); - return xics_get_qirq(XICS_FABRIC(spapr), dev->irq); + return spapr_irq_get_qirq(spapr, dev->irq); } static inline bool spapr_vio_dma_valid(VIOsPAPRDevice *dev, uint64_t taddr, diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index cea462bc7f3e..2f1f35294e6d 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -183,7 +183,6 @@ typedef struct XICSFabricClass { void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle); -qemu_irq xics_get_qirq(XICSFabric *xi, int irq); ICPState *xics_icp_get(XICSFabric *xi, int server); /* Internal XICS interfaces */ From patchwork Thu Nov 23 13:29:37 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: 840776 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjLF71nlFz9s72 for ; Fri, 24 Nov 2017 00:45:47 +1100 (AEDT) Received: from localhost ([::1]:44437 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrp3-0005hb-AG for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:45:45 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38280) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrbO-00012e-SX for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrbL-00015p-O6 for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:38 -0500 Received: from 17.mo3.mail-out.ovh.net ([87.98.178.58]:50149) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrbL-000146-Ho for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:35 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 5376A175AB6 for ; Thu, 23 Nov 2017 14:31:34 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 1D84C2E0084; Thu, 23 Nov 2017 14:31:29 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:37 +0100 Message-Id: <20171123132955.1261-8-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14823035225677204307 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.178.58 Subject: [Qemu-devel] [PATCH 07/25] migration: add VMSTATE_STRUCT_VARRAY_UINT32_ALLOC 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Cédric Le Goater --- include/migration/vmstate.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 88b55df5ae0c..c0bf06e7bf89 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -560,6 +560,16 @@ extern const VMStateInfo vmstate_info_qtailq; .offset = vmstate_offset_pointer(_state, _field, _type), \ } +#define VMSTATE_STRUCT_VARRAY_UINT32_ALLOC(_field, _state, _field_num, _version, _vmsd, _type) {\ + .name = (stringify(_field)), \ + .version_id = (_version), \ + .vmsd = &(_vmsd), \ + .num_offset = vmstate_offset_value(_state, _field_num, uint32_t), \ + .size = sizeof(_type), \ + .flags = VMS_STRUCT|VMS_VARRAY_UINT32|VMS_ALLOC|VMS_POINTER, \ + .offset = vmstate_offset_pointer(_state, _field, _type), \ +} + #define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \ .name = (stringify(_field)), \ .version_id = (_version), \ From patchwork Thu Nov 23 13:29:38 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: 840760 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjKyl2y7bz9s72 for ; Fri, 24 Nov 2017 00:33:19 +1100 (AEDT) Received: from localhost ([::1]:44359 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrcz-0001zK-Ec for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:33:17 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38534) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrbY-0001Qw-6T for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrbR-0001Ha-Ku for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:48 -0500 Received: from 19.mo3.mail-out.ovh.net ([178.32.98.231]:55585) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrbQ-0001D0-Q4 for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:41 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 74C32175A1C for ; Thu, 23 Nov 2017 14:31:39 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 4638B2E00A4; Thu, 23 Nov 2017 14:31:34 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:38 +0100 Message-Id: <20171123132955.1261-9-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14824442602041019219 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 178.32.98.231 Subject: [Qemu-devel] [PATCH 08/25] spapr: introduce a skeleton for the XIVE interrupt controller 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The XIVE interrupt controller uses a set of tables to redirect exception from event sources to CPU threads. The Interrupt Virtualization Entry (IVE) table, also known as Event Assignment Structure (EAS), is one them. The XIVE model is designed to make use of the full range of the IRQ number space and does not use an offset like the XICS mode does. Hence, the IVE table is directly indexed by the IRQ number. The IVE stores Event Queue data associated with a source. The lookups are performed when the source is configured or when an event is triggered. Signed-off-by: Cédric Le Goater --- default-configs/ppc64-softmmu.mak | 1 + hw/intc/Makefile.objs | 1 + hw/intc/spapr_xive.c | 165 ++++++++++++++++++++++++++++++++++++++ hw/intc/xive-internal.h | 50 ++++++++++++ include/hw/ppc/spapr_xive.h | 44 ++++++++++ 5 files changed, 261 insertions(+) create mode 100644 hw/intc/spapr_xive.c create mode 100644 hw/intc/xive-internal.h create mode 100644 include/hw/ppc/spapr_xive.h diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak index d1b3a6dd50f8..4a7f6a0696de 100644 --- a/default-configs/ppc64-softmmu.mak +++ b/default-configs/ppc64-softmmu.mak @@ -56,6 +56,7 @@ CONFIG_SM501=y CONFIG_XICS=$(CONFIG_PSERIES) CONFIG_XICS_SPAPR=$(CONFIG_PSERIES) CONFIG_XICS_KVM=$(call land,$(CONFIG_PSERIES),$(CONFIG_KVM)) +CONFIG_XIVE_SPAPR=$(CONFIG_PSERIES) # For PReP CONFIG_SERIAL_ISA=y CONFIG_MC146818RTC=y diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index ae358569a155..49e13e7aeeee 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -35,6 +35,7 @@ obj-$(CONFIG_SH4) += sh_intc.o obj-$(CONFIG_XICS) += xics.o obj-$(CONFIG_XICS_SPAPR) += xics_spapr.o obj-$(CONFIG_XICS_KVM) += xics_kvm.o +obj-$(CONFIG_XIVE_SPAPR) += spapr_xive.o obj-$(CONFIG_POWERNV) += xics_pnv.o obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o obj-$(CONFIG_S390_FLIC) += s390_flic.o diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c new file mode 100644 index 000000000000..b2fc3007c85f --- /dev/null +++ b/hw/intc/spapr_xive.c @@ -0,0 +1,165 @@ +/* + * QEMU PowerPC sPAPR XIVE model + * + * Copyright (c) 2017, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qapi/error.h" +#include "target/ppc/cpu.h" +#include "sysemu/cpus.h" +#include "sysemu/dma.h" +#include "monitor/monitor.h" +#include "hw/ppc/spapr_xive.h" + +#include "xive-internal.h" + +/* + * Main XIVE object + */ + +void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon) +{ + int i; + + for (i = 0; i < xive->nr_irqs; i++) { + XiveIVE *ive = &xive->ivt[i]; + + if (!(ive->w & IVE_VALID)) { + continue; + } + + monitor_printf(mon, " %4x %s %08x %08x\n", i, + ive->w & IVE_MASKED ? "M" : " ", + (int) GETFIELD(IVE_EQ_INDEX, ive->w), + (int) GETFIELD(IVE_EQ_DATA, ive->w)); + } +} + +void spapr_xive_reset(void *dev) +{ + sPAPRXive *xive = SPAPR_XIVE(dev); + int i; + + /* Mask all valid IVEs in the IRQ number space. */ + for (i = 0; i < xive->nr_irqs; i++) { + XiveIVE *ive = &xive->ivt[i]; + if (ive->w & IVE_VALID) { + ive->w |= IVE_MASKED; + } + } +} + +static void spapr_xive_realize(DeviceState *dev, Error **errp) +{ + sPAPRXive *xive = SPAPR_XIVE(dev); + + if (!xive->nr_irqs) { + error_setg(errp, "Number of interrupt needs to be greater 0"); + return; + } + + /* Allocate the IVT (Interrupt Virtualization Table) */ + xive->ivt = g_malloc0(xive->nr_irqs * sizeof(XiveIVE)); + + qemu_register_reset(spapr_xive_reset, dev); +} + +static const VMStateDescription vmstate_spapr_xive_ive = { + .name = TYPE_SPAPR_XIVE "/ive", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField []) { + VMSTATE_UINT64(w, XiveIVE), + VMSTATE_END_OF_LIST() + }, +}; + +static bool vmstate_spapr_xive_needed(void *opaque) +{ + /* TODO check machine XIVE support */ + return true; +} + +static const VMStateDescription vmstate_spapr_xive = { + .name = TYPE_SPAPR_XIVE, + .version_id = 1, + .minimum_version_id = 1, + .needed = vmstate_spapr_xive_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT32_EQUAL(nr_irqs, sPAPRXive, NULL), + VMSTATE_STRUCT_VARRAY_UINT32_ALLOC(ivt, sPAPRXive, nr_irqs, 1, + vmstate_spapr_xive_ive, XiveIVE), + VMSTATE_END_OF_LIST() + }, +}; + +static Property spapr_xive_properties[] = { + DEFINE_PROP_UINT32("nr-irqs", sPAPRXive, nr_irqs, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void spapr_xive_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = spapr_xive_realize; + dc->props = spapr_xive_properties; + dc->desc = "sPAPR XIVE interrupt controller"; + dc->vmsd = &vmstate_spapr_xive; +} + +static const TypeInfo spapr_xive_info = { + .name = TYPE_SPAPR_XIVE, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(sPAPRXive), + .class_init = spapr_xive_class_init, +}; + +static void spapr_xive_register_types(void) +{ + type_register_static(&spapr_xive_info); +} + +type_init(spapr_xive_register_types) + +XiveIVE *spapr_xive_get_ive(sPAPRXive *xive, uint32_t lisn) +{ + return lisn < xive->nr_irqs ? &xive->ivt[lisn] : NULL; +} + +bool spapr_xive_irq_set(sPAPRXive *xive, uint32_t lisn) +{ + XiveIVE *ive = spapr_xive_get_ive(xive, lisn); + + if (!ive) { + return false; + } + + ive->w |= IVE_VALID; + return true; +} + +bool spapr_xive_irq_unset(sPAPRXive *xive, uint32_t lisn) +{ + XiveIVE *ive = spapr_xive_get_ive(xive, lisn); + + if (!ive) { + return false; + } + + ive->w &= ~IVE_VALID; + return true; +} diff --git a/hw/intc/xive-internal.h b/hw/intc/xive-internal.h new file mode 100644 index 000000000000..bea88d82992c --- /dev/null +++ b/hw/intc/xive-internal.h @@ -0,0 +1,50 @@ +/* + * QEMU PowerPC XIVE model + * + * Copyright 2016,2017 IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _INTC_XIVE_INTERNAL_H +#define _INTC_XIVE_INTERNAL_H + +/* Utilities to manipulate these (originaly from OPAL) */ +#define MASK_TO_LSH(m) (__builtin_ffsl(m) - 1) +#define GETFIELD(m, v) (((v) & (m)) >> MASK_TO_LSH(m)) +#define SETFIELD(m, v, val) \ + (((v) & ~(m)) | ((((typeof(v))(val)) << MASK_TO_LSH(m)) & (m))) + +#define PPC_BIT(bit) (0x8000000000000000UL >> (bit)) +#define PPC_BIT32(bit) (0x80000000UL >> (bit)) +#define PPC_BIT8(bit) (0x80UL >> (bit)) +#define PPC_BITMASK(bs, be) ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs)) +#define PPC_BITMASK32(bs, be) ((PPC_BIT32(bs) - PPC_BIT32(be)) | \ + PPC_BIT32(bs)) + +/* IVE/EAS + * + * One per interrupt source. Targets that interrupt to a given EQ + * and provides the corresponding logical interrupt number (EQ data) + * + * We also map this structure to the escalation descriptor inside + * an EQ, though in that case the valid and masked bits are not used. + */ +typedef struct XiveIVE { + /* Use a single 64-bit definition to make it easier to + * perform atomic updates + */ + uint64_t w; +#define IVE_VALID PPC_BIT(0) +#define IVE_EQ_BLOCK PPC_BITMASK(4, 7) /* Destination EQ block# */ +#define IVE_EQ_INDEX PPC_BITMASK(8, 31) /* Destination EQ index */ +#define IVE_MASKED PPC_BIT(32) /* Masked */ +#define IVE_EQ_DATA PPC_BITMASK(33, 63) /* Data written to the EQ */ +} XiveIVE; + +void spapr_xive_reset(void *dev); +XiveIVE *spapr_xive_get_ive(sPAPRXive *xive, uint32_t lisn); + +#endif /* _INTC_XIVE_INTERNAL_H */ diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h new file mode 100644 index 000000000000..795b3f4ded7c --- /dev/null +++ b/include/hw/ppc/spapr_xive.h @@ -0,0 +1,44 @@ +/* + * QEMU PowerPC sPAPR XIVE model + * + * Copyright (c) 2017, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef PPC_SPAPR_XIVE_H +#define PPC_SPAPR_XIVE_H + +#include + +typedef struct sPAPRXive sPAPRXive; +typedef struct XiveIVE XiveIVE; + +#define TYPE_SPAPR_XIVE "spapr-xive" +#define SPAPR_XIVE(obj) OBJECT_CHECK(sPAPRXive, (obj), TYPE_SPAPR_XIVE) + +struct sPAPRXive { + SysBusDevice parent; + + /* Properties */ + uint32_t nr_irqs; + + /* XIVE internal tables */ + XiveIVE *ivt; +}; + +bool spapr_xive_irq_set(sPAPRXive *xive, uint32_t lisn); +bool spapr_xive_irq_unset(sPAPRXive *xive, uint32_t lisn); +void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon); + +#endif /* PPC_SPAPR_XIVE_H */ From patchwork Thu Nov 23 13:29:39 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: 840768 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjL481jDPz9s72 for ; Fri, 24 Nov 2017 00:38:00 +1100 (AEDT) Received: from localhost ([::1]:44388 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrhW-0006Ie-6V for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:37:58 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38556) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrbZ-0001Rg-4K for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrbW-0001X3-K2 for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:49 -0500 Received: from 19.mo3.mail-out.ovh.net ([178.32.98.231]:45324) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrbW-0001Tz-C2 for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:46 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 6C40C175AA8 for ; Thu, 23 Nov 2017 14:31:45 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 709212E00AA; Thu, 23 Nov 2017 14:31:39 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:39 +0100 Message-Id: <20171123132955.1261-10-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14825849976367254355 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 178.32.98.231 Subject: [Qemu-devel] [PATCH 09/25] spapr: introduce handlers for XIVE interrupt sources 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" These are very similar to the XICS handlers in a simpler form. They make use of a status array for the LSI interrupts. The spapr_xive_irq() routine in charge of triggering the CPU interrupt line will be filled later on. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 55 +++++++++++++++++++++++++++++++++++++++++++-- include/hw/ppc/spapr_xive.h | 14 +++++++++++- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index b2fc3007c85f..66c533fb1d78 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -26,6 +26,47 @@ #include "xive-internal.h" +static void spapr_xive_irq(sPAPRXive *xive, int lisn) +{ + +} + +/* + * XIVE Interrupt Source + */ +static void spapr_xive_source_set_irq_msi(sPAPRXive *xive, int lisn, int val) +{ + if (val) { + spapr_xive_irq(xive, lisn); + } +} + +static void spapr_xive_source_set_irq_lsi(sPAPRXive *xive, int lisn, int val) +{ + if (val) { + xive->status[lisn] |= XIVE_STATUS_ASSERTED; + } else { + xive->status[lisn] &= ~XIVE_STATUS_ASSERTED; + } + + if (xive->status[lisn] & XIVE_STATUS_ASSERTED && + !(xive->status[lisn] & XIVE_STATUS_SENT)) { + xive->status[lisn] |= XIVE_STATUS_SENT; + spapr_xive_irq(xive, lisn); + } +} + +static void spapr_xive_source_set_irq(void *opaque, int lisn, int val) +{ + sPAPRXive *xive = SPAPR_XIVE(opaque); + + if (spapr_xive_irq_is_lsi(xive, lisn)) { + spapr_xive_source_set_irq_lsi(xive, lisn, val); + } else { + spapr_xive_source_set_irq_msi(xive, lisn, val); + } +} + /* * Main XIVE object */ @@ -41,7 +82,8 @@ void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon) continue; } - monitor_printf(mon, " %4x %s %08x %08x\n", i, + monitor_printf(mon, " %4x %s %s %08x %08x\n", i, + spapr_xive_irq_is_lsi(xive, i) ? "LSI" : "MSI", ive->w & IVE_MASKED ? "M" : " ", (int) GETFIELD(IVE_EQ_INDEX, ive->w), (int) GETFIELD(IVE_EQ_DATA, ive->w)); @@ -53,6 +95,8 @@ void spapr_xive_reset(void *dev) sPAPRXive *xive = SPAPR_XIVE(dev); int i; + /* Do not clear IRQs status */ + /* Mask all valid IVEs in the IRQ number space. */ for (i = 0; i < xive->nr_irqs; i++) { XiveIVE *ive = &xive->ivt[i]; @@ -71,6 +115,11 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp) return; } + /* QEMU IRQs */ + xive->qirqs = qemu_allocate_irqs(spapr_xive_source_set_irq, xive, + xive->nr_irqs); + xive->status = g_malloc0(xive->nr_irqs); + /* Allocate the IVT (Interrupt Virtualization Table) */ xive->ivt = g_malloc0(xive->nr_irqs * sizeof(XiveIVE)); @@ -102,6 +151,7 @@ static const VMStateDescription vmstate_spapr_xive = { VMSTATE_UINT32_EQUAL(nr_irqs, sPAPRXive, NULL), VMSTATE_STRUCT_VARRAY_UINT32_ALLOC(ivt, sPAPRXive, nr_irqs, 1, vmstate_spapr_xive_ive, XiveIVE), + VMSTATE_VBUFFER_UINT32(status, sPAPRXive, 1, NULL, nr_irqs), VMSTATE_END_OF_LIST() }, }; @@ -140,7 +190,7 @@ XiveIVE *spapr_xive_get_ive(sPAPRXive *xive, uint32_t lisn) return lisn < xive->nr_irqs ? &xive->ivt[lisn] : NULL; } -bool spapr_xive_irq_set(sPAPRXive *xive, uint32_t lisn) +bool spapr_xive_irq_set(sPAPRXive *xive, uint32_t lisn, bool lsi) { XiveIVE *ive = spapr_xive_get_ive(xive, lisn); @@ -149,6 +199,7 @@ bool spapr_xive_irq_set(sPAPRXive *xive, uint32_t lisn) } ive->w |= IVE_VALID; + xive->status[lisn] |= lsi ? XIVE_STATUS_LSI : 0; return true; } diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 795b3f4ded7c..6a799cdaba66 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -33,11 +33,23 @@ struct sPAPRXive { /* Properties */ uint32_t nr_irqs; + /* IRQ */ + qemu_irq *qirqs; +#define XIVE_STATUS_LSI 0x1 +#define XIVE_STATUS_ASSERTED 0x2 +#define XIVE_STATUS_SENT 0x4 + uint8_t *status; + /* XIVE internal tables */ XiveIVE *ivt; }; -bool spapr_xive_irq_set(sPAPRXive *xive, uint32_t lisn); +static inline bool spapr_xive_irq_is_lsi(sPAPRXive *xive, int lisn) +{ + return xive->status[lisn] & XIVE_STATUS_LSI; +} + +bool spapr_xive_irq_set(sPAPRXive *xive, uint32_t lisn, bool lsi); bool spapr_xive_irq_unset(sPAPRXive *xive, uint32_t lisn); void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon); From patchwork Thu Nov 23 13:29:40 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: 840759 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjKyc2dr1z9s72 for ; Fri, 24 Nov 2017 00:33:12 +1100 (AEDT) Received: from localhost ([::1]:44358 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrcp-0001sL-5t for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:33:07 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38636) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrbd-0001UL-0s for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrbb-0001kv-3o for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:53 -0500 Received: from 13.mo3.mail-out.ovh.net ([188.165.33.202]:58382) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrba-0001iG-Qx for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:51 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id C589B171B42 for ; Thu, 23 Nov 2017 14:31:49 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 9A1B52E00A3; Thu, 23 Nov 2017 14:31:44 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:40 +0100 Message-Id: <20171123132955.1261-11-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14827257350085053267 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.33.202 Subject: [Qemu-devel] [PATCH 10/25] spapr: add MMIO handlers for the XIVE interrupt sources 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Each interrupt source is associated with a two bit state machine called an Event State Buffer (ESB). The bits are named "P" (pending) and "Q" (queued) and can be controlled by MMIO. It is used to trigger events. See code for more details on the states and transitions. The MMIO space for the ESB translation is 512GB large on baremetal (powernv) systems and the BAR depends on the chip id. In our model for the sPAPR machine, we choose to only map a sub memory region for the provisionned IRQ numbers and to use the mapping address of chip 0 on a real system. The OS will get the address of the MMIO page of the ESB entry associated with an IRQ using the H_INT_GET_SOURCE_INFO hcall. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 268 +++++++++++++++++++++++++++++++++++++++++++- include/hw/ppc/spapr_xive.h | 8 ++ 2 files changed, 275 insertions(+), 1 deletion(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 66c533fb1d78..f45f50fd017e 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -32,6 +32,216 @@ static void spapr_xive_irq(sPAPRXive *xive, int lisn) } /* + * "magic" Event State Buffer (ESB) MMIO offsets. + * + * Each interrupt source has a 2-bit state machine called ESB + * which can be controlled by MMIO. It's made of 2 bits, P and + * Q. P indicates that an interrupt is pending (has been sent + * to a queue and is waiting for an EOI). Q indicates that the + * interrupt has been triggered while pending. + * + * This acts as a coalescing mechanism in order to guarantee + * that a given interrupt only occurs at most once in a queue. + * + * When doing an EOI, the Q bit will indicate if the interrupt + * needs to be re-triggered. + * + * The following offsets into the ESB MMIO allow to read or + * manipulate the PQ bits. They must be used with an 8-bytes + * load instruction. They all return the previous state of the + * interrupt (atomically). + * + * Additionally, some ESB pages support doing an EOI via a + * store at 0 and some ESBs support doing a trigger via a + * separate trigger page. + */ +#define XIVE_ESB_GET 0x800 +#define XIVE_ESB_SET_PQ_00 0xc00 +#define XIVE_ESB_SET_PQ_01 0xd00 +#define XIVE_ESB_SET_PQ_10 0xe00 +#define XIVE_ESB_SET_PQ_11 0xf00 + +#define XIVE_ESB_VAL_P 0x2 +#define XIVE_ESB_VAL_Q 0x1 + +#define XIVE_ESB_RESET 0x0 +#define XIVE_ESB_PENDING XIVE_ESB_VAL_P +#define XIVE_ESB_QUEUED (XIVE_ESB_VAL_P | XIVE_ESB_VAL_Q) +#define XIVE_ESB_OFF XIVE_ESB_VAL_Q + +static uint8_t spapr_xive_pq_get(sPAPRXive *xive, uint32_t lisn) +{ + uint32_t byte = lisn / 4; + uint32_t bit = (lisn % 4) * 2; + + assert(byte < xive->sbe_size); + + return (xive->sbe[byte] >> bit) & 0x3; +} + +static uint8_t spapr_xive_pq_set(sPAPRXive *xive, uint32_t lisn, uint8_t pq) +{ + uint32_t byte = lisn / 4; + uint32_t bit = (lisn % 4) * 2; + uint8_t old, new; + + assert(byte < xive->sbe_size); + + old = xive->sbe[byte]; + + new = xive->sbe[byte] & ~(0x3 << bit); + new |= (pq & 0x3) << bit; + + xive->sbe[byte] = new; + + return (old >> bit) & 0x3; +} + +static bool spapr_xive_pq_eoi(sPAPRXive *xive, uint32_t lisn) +{ + uint8_t old_pq = spapr_xive_pq_get(xive, lisn); + + switch (old_pq) { + case XIVE_ESB_RESET: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_RESET); + return false; + case XIVE_ESB_PENDING: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_RESET); + return false; + case XIVE_ESB_QUEUED: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_PENDING); + return true; + case XIVE_ESB_OFF: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_OFF); + return false; + default: + g_assert_not_reached(); + } +} + +static bool spapr_xive_pq_trigger(sPAPRXive *xive, uint32_t lisn) +{ + uint8_t old_pq = spapr_xive_pq_get(xive, lisn); + + switch (old_pq) { + case XIVE_ESB_RESET: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_PENDING); + return true; + case XIVE_ESB_PENDING: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_QUEUED); + return true; + case XIVE_ESB_QUEUED: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_QUEUED); + return true; + case XIVE_ESB_OFF: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_OFF); + return false; + default: + g_assert_not_reached(); + } +} + +/* + * XIVE Interrupt Source MMIOs + */ +static void spapr_xive_source_eoi(sPAPRXive *xive, uint32_t lisn) +{ + if (spapr_xive_irq_is_lsi(xive, lisn)) { + xive->status[lisn] &= ~XIVE_STATUS_SENT; + } +} + +/* TODO: handle second page + * + * Some HW use a separate page for trigger. We only support the case + * in which the trigger can be done in the same page as the EOI. + */ +static uint64_t spapr_xive_esb_read(void *opaque, hwaddr addr, unsigned size) +{ + sPAPRXive *xive = SPAPR_XIVE(opaque); + uint32_t offset = addr & 0xF00; + uint32_t lisn = addr >> xive->esb_shift; + XiveIVE *ive; + uint64_t ret = -1; + + ive = spapr_xive_get_ive(xive, lisn); + if (!ive || !(ive->w & IVE_VALID)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid LISN %d\n", lisn); + goto out; + } + + switch (offset) { + case 0: + spapr_xive_source_eoi(xive, lisn); + + /* return TRUE or FALSE depending on PQ value */ + ret = spapr_xive_pq_eoi(xive, lisn); + break; + + case XIVE_ESB_GET: + ret = spapr_xive_pq_get(xive, lisn); + break; + + case XIVE_ESB_SET_PQ_00: + case XIVE_ESB_SET_PQ_01: + case XIVE_ESB_SET_PQ_10: + case XIVE_ESB_SET_PQ_11: + ret = spapr_xive_pq_set(xive, lisn, (offset >> 8) & 0x3); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid ESB addr %d\n", offset); + } + +out: + return ret; +} + +static void spapr_xive_esb_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size) +{ + sPAPRXive *xive = SPAPR_XIVE(opaque); + uint32_t offset = addr & 0xF00; + uint32_t lisn = addr >> xive->esb_shift; + XiveIVE *ive; + bool notify = false; + + ive = spapr_xive_get_ive(xive, lisn); + if (!ive || !(ive->w & IVE_VALID)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid LISN %d\n", lisn); + return; + } + + switch (offset) { + case 0: + /* TODO: should we trigger even if the IVE is masked ? */ + notify = spapr_xive_pq_trigger(xive, lisn); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid ESB write addr %d\n", + offset); + return; + } + + if (notify && !(ive->w & IVE_MASKED)) { + qemu_irq_pulse(xive->qirqs[lisn]); + } +} + +static const MemoryRegionOps spapr_xive_esb_ops = { + .read = spapr_xive_esb_read, + .write = spapr_xive_esb_write, + .endianness = DEVICE_BIG_ENDIAN, + .valid = { + .min_access_size = 8, + .max_access_size = 8, + }, + .impl = { + .min_access_size = 8, + .max_access_size = 8, + }, +}; + +/* * XIVE Interrupt Source */ static void spapr_xive_source_set_irq_msi(sPAPRXive *xive, int lisn, int val) @@ -70,6 +280,33 @@ static void spapr_xive_source_set_irq(void *opaque, int lisn, int val) /* * Main XIVE object */ +#define P9_MMIO_BASE 0x006000000000000ull + +/* VC BAR contains set translations for the ESBs and the EQs. */ +#define VC_BAR_DEFAULT 0x10000000000ull +#define VC_BAR_SIZE 0x08000000000ull +#define ESB_SHIFT 16 /* One 64k page. OPAL has two */ + +static uint64_t spapr_xive_esb_default_read(void *p, hwaddr offset, + unsigned size) +{ + qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n", + __func__, offset, size); + return 0; +} + +static void spapr_xive_esb_default_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n", + __func__, offset, value, size); +} + +static const MemoryRegionOps spapr_xive_esb_default_ops = { + .read = spapr_xive_esb_default_read, + .write = spapr_xive_esb_default_write, + .endianness = DEVICE_BIG_ENDIAN, +}; void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon) { @@ -77,14 +314,19 @@ void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon) for (i = 0; i < xive->nr_irqs; i++) { XiveIVE *ive = &xive->ivt[i]; + uint8_t pq; if (!(ive->w & IVE_VALID)) { continue; } - monitor_printf(mon, " %4x %s %s %08x %08x\n", i, + pq = spapr_xive_pq_get(xive, i); + + monitor_printf(mon, " %4x %s %s %c%c %08x %08x\n", i, spapr_xive_irq_is_lsi(xive, i) ? "LSI" : "MSI", ive->w & IVE_MASKED ? "M" : " ", + pq & XIVE_ESB_VAL_P ? 'P' : '-', + pq & XIVE_ESB_VAL_Q ? 'Q' : '-', (int) GETFIELD(IVE_EQ_INDEX, ive->w), (int) GETFIELD(IVE_EQ_DATA, ive->w)); } @@ -104,6 +346,9 @@ void spapr_xive_reset(void *dev) ive->w |= IVE_MASKED; } } + + /* SBEs are initialized to 0b01 which corresponds to "ints off" */ + memset(xive->sbe, 0x55, xive->sbe_size); } static void spapr_xive_realize(DeviceState *dev, Error **errp) @@ -123,6 +368,26 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp) /* Allocate the IVT (Interrupt Virtualization Table) */ xive->ivt = g_malloc0(xive->nr_irqs * sizeof(XiveIVE)); + /* Allocate SBEs (State Bit Entry). 2 bits, so 4 entries per byte */ + xive->sbe_size = DIV_ROUND_UP(xive->nr_irqs, 4); + xive->sbe = g_malloc0(xive->sbe_size); + + /* VC BAR. That's the full window but we will only map the + * subregions in use. */ + xive->esb_base = (P9_MMIO_BASE | VC_BAR_DEFAULT); + xive->esb_shift = ESB_SHIFT; + + /* Install default memory region handlers to log bogus access */ + memory_region_init_io(&xive->esb_mr, NULL, &spapr_xive_esb_default_ops, + NULL, "xive.esb.full", VC_BAR_SIZE); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &xive->esb_mr); + + /* Install the ESB memory region in the overall one */ + memory_region_init_io(&xive->esb_iomem, OBJECT(xive), &spapr_xive_esb_ops, + xive, "xive.esb", + (1ull << xive->esb_shift) * xive->nr_irqs); + memory_region_add_subregion(&xive->esb_mr, 0, &xive->esb_iomem); + qemu_register_reset(spapr_xive_reset, dev); } @@ -152,6 +417,7 @@ static const VMStateDescription vmstate_spapr_xive = { VMSTATE_STRUCT_VARRAY_UINT32_ALLOC(ivt, sPAPRXive, nr_irqs, 1, vmstate_spapr_xive_ive, XiveIVE), VMSTATE_VBUFFER_UINT32(status, sPAPRXive, 1, NULL, nr_irqs), + VMSTATE_VBUFFER_UINT32(sbe, sPAPRXive, 1, NULL, sbe_size), VMSTATE_END_OF_LIST() }, }; diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 6a799cdaba66..84c910e62e56 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -42,6 +42,14 @@ struct sPAPRXive { /* XIVE internal tables */ XiveIVE *ivt; + uint8_t *sbe; + uint32_t sbe_size; + + /* ESB memory region */ + uint32_t esb_shift; + hwaddr esb_base; + MemoryRegion esb_mr; + MemoryRegion esb_iomem; }; static inline bool spapr_xive_irq_is_lsi(sPAPRXive *xive, int lisn) From patchwork Thu Nov 23 13:29:41 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: 840771 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjL7s4FZ3z9s76 for ; Fri, 24 Nov 2017 00:41:13 +1100 (AEDT) Received: from localhost ([::1]:44411 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrkd-0000fH-HX for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:41:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38832) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrbm-0001dU-4T for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:08 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrbg-0001wN-5b for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:02 -0500 Received: from 15.mo3.mail-out.ovh.net ([87.98.150.177]:59483) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrbf-0001uT-W4 for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:56 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id F27F2175ADC for ; Thu, 23 Nov 2017 14:31:54 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id C343B2E0081; Thu, 23 Nov 2017 14:31:49 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:41 +0100 Message-Id: <20171123132955.1261-12-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14828664725220199251 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.150.177 Subject: [Qemu-devel] [PATCH 11/25] spapr: describe the XIVE interrupt source flags 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The XIVE interrupt sources can have different characteristics depending on their nature and the HW level in use. The sPAPR specs provide a set of flags to describe them : - XIVE_SRC_H_INT_ESB the Event State Buffers are controlled with a specific hcall H_INT_ESB and not with MMIO - XIVE_SRC_LSI LSI or MSI source (ICSIRQState level) - XIVE_SRC_TRIGGER the full function page supports trigger - XIVE_SRC_STORE_EOI EOI can be done with a store. Our QEMU emulation of XIVE for the sPAPR machine gathers all sources under a same model and provides a common source with the XIVE_SRC_TRIGGER type. So, the above list is mostly informative apart from the XIVE_SRC_LSI flag which will be deduced from the XIVE_STATUS_LSI flag. The OS retrieves this information on the source with the H_INT_GET_SOURCE_INFO hcall. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 4 ++++ include/hw/ppc/spapr_xive.h | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index f45f50fd017e..b1e3f8710cff 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -368,6 +368,10 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp) /* Allocate the IVT (Interrupt Virtualization Table) */ xive->ivt = g_malloc0(xive->nr_irqs * sizeof(XiveIVE)); + /* All sources are emulated under the XIVE object and share the + * same characteristic */ + xive->flags = XIVE_SRC_TRIGGER; + /* Allocate SBEs (State Bit Entry). 2 bits, so 4 entries per byte */ xive->sbe_size = DIV_ROUND_UP(xive->nr_irqs, 4); xive->sbe = g_malloc0(xive->sbe_size); diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 84c910e62e56..7a308fb4db2b 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -40,6 +40,13 @@ struct sPAPRXive { #define XIVE_STATUS_SENT 0x4 uint8_t *status; + /* Interrupt source flags */ +#define XIVE_SRC_H_INT_ESB (1ull << (63 - 60)) +#define XIVE_SRC_LSI (1ull << (63 - 61)) +#define XIVE_SRC_TRIGGER (1ull << (63 - 62)) +#define XIVE_SRC_STORE_EOI (1ull << (63 - 63)) + uint32_t flags; + /* XIVE internal tables */ XiveIVE *ivt; uint8_t *sbe; From patchwork Thu Nov 23 13:29:42 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: 840774 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjLBj66XSz9s72 for ; Fri, 24 Nov 2017 00:43:41 +1100 (AEDT) Received: from localhost ([::1]:44424 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrn1-00043C-Tk for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:43:39 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38913) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrbp-0001g5-6T for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrbl-00028P-Vu for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:05 -0500 Received: from 11.mo3.mail-out.ovh.net ([87.98.184.158]:56342) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrbl-00025U-LE for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:01 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 2B35E175AC7 for ; Thu, 23 Nov 2017 14:32:00 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id EDA792E0081; Thu, 23 Nov 2017 14:31:54 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:42 +0100 Message-Id: <20171123132955.1261-13-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14830353575675595603 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.184.158 Subject: [Qemu-devel] [PATCH 12/25] spapr: introduce a XIVE interrupt presenter model 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The XIVE interrupt presenter exposes a set of rings, also called Thread Interrupt Management Areas (TIMA), to handle priority management and interrupt acknowledgment among other things. There is one ring per level of privilege, four in all. The one we are interested in for the sPAPR machine is the OS ring. The TIMA is mapped at the same address for each CPU. 'current_cpu' is used to retrieve the targeted interrupt presenter object holding the cache data of the registers the model use. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 271 ++++++++++++++++++++++++++++++++++++++++++++ hw/intc/xive-internal.h | 89 +++++++++++++++ include/hw/ppc/spapr_xive.h | 11 ++ 3 files changed, 371 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index b1e3f8710cff..554b25e0884c 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -23,9 +23,166 @@ #include "sysemu/dma.h" #include "monitor/monitor.h" #include "hw/ppc/spapr_xive.h" +#include "hw/ppc/xics.h" #include "xive-internal.h" +struct sPAPRXiveICP { + DeviceState parent_obj; + + CPUState *cs; + uint8_t tima[TM_RING_COUNT * 0x10]; + uint8_t *tima_os; + qemu_irq output; +}; + +static uint64_t spapr_xive_icp_accept(sPAPRXiveICP *icp) +{ + return 0; +} + +static void spapr_xive_icp_set_cppr(sPAPRXiveICP *icp, uint8_t cppr) +{ + if (cppr > XIVE_PRIORITY_MAX) { + cppr = 0xff; + } + + icp->tima_os[TM_CPPR] = cppr; +} + +/* + * Thread Interrupt Management Area MMIO + */ +static uint64_t spapr_xive_tm_read_special(sPAPRXiveICP *icp, hwaddr offset, + unsigned size) +{ + uint64_t ret = -1; + + if (offset == TM_SPC_ACK_OS_REG && size == 2) { + ret = spapr_xive_icp_accept(icp); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid TIMA read @%" + HWADDR_PRIx" size %d\n", offset, size); + } + + return ret; +} + +static uint64_t spapr_xive_tm_read(void *opaque, hwaddr offset, unsigned size) +{ + PowerPCCPU *cpu = POWERPC_CPU(current_cpu); + sPAPRXiveICP *icp = SPAPR_XIVE_ICP(cpu->intc); + uint64_t ret = -1; + int i; + + if (offset >= TM_SPC_ACK_EBB) { + return spapr_xive_tm_read_special(icp, offset, size); + } + + if ((offset & 0xf0) == TM_QW1_OS) { + switch (size) { + case 1: + case 2: + case 4: + case 8: + if (QEMU_IS_ALIGNED(offset, size)) { + ret = 0; + for (i = 0; i < size; i++) { + ret |= icp->tima[offset + i] << (8 * i); + } + } else { + qemu_log_mask(LOG_GUEST_ERROR, + "XIVE: invalid TIMA read alignment @%" + HWADDR_PRIx" size %d\n", offset, size); + } + break; + default: + g_assert_not_reached(); + } + } else { + qemu_log_mask(LOG_UNIMP, "XIVE: does handle non-OS TIMA ring @%" + HWADDR_PRIx"\n", offset); + } + + return ret; +} + +static bool spapr_xive_tm_is_readonly(uint8_t offset) +{ + /* Let's be optimistic and prepare ground for HV mode support */ + switch (offset) { + case TM_QW1_OS + TM_CPPR: + return false; + default: + return true; + } +} + +static void spapr_xive_tm_write_special(sPAPRXiveICP *icp, hwaddr offset, + uint64_t value, unsigned size) +{ + /* TODO: support TM_SPC_SET_OS_PENDING */ + + /* TODO: support TM_SPC_ACK_OS_EL */ +} + +static void spapr_xive_tm_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + PowerPCCPU *cpu = POWERPC_CPU(current_cpu); + sPAPRXiveICP *icp = SPAPR_XIVE_ICP(cpu->intc); + int i; + + if (offset >= TM_SPC_ACK_EBB) { + spapr_xive_tm_write_special(icp, offset, value, size); + return; + } + + if ((offset & 0xf0) == TM_QW1_OS) { + switch (size) { + case 1: + if (offset == TM_QW1_OS + TM_CPPR) { + spapr_xive_icp_set_cppr(icp, value & 0xff); + } + break; + case 4: + case 8: + if (QEMU_IS_ALIGNED(offset, size)) { + for (i = 0; i < size; i++) { + if (!spapr_xive_tm_is_readonly(offset + i)) { + icp->tima[offset + i] = (value >> (8 * i)) & 0xff; + } + } + } else { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid TIMA write @%" + HWADDR_PRIx" size %d\n", offset, size); + } + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid TIMA write @%" + HWADDR_PRIx" size %d\n", offset, size); + } + } else { + qemu_log_mask(LOG_UNIMP, "XIVE: does handle non-OS TIMA ring @%" + HWADDR_PRIx"\n", offset); + } +} + + +static const MemoryRegionOps spapr_xive_tm_ops = { + .read = spapr_xive_tm_read, + .write = spapr_xive_tm_write, + .endianness = DEVICE_BIG_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 8, + }, + .impl = { + .min_access_size = 1, + .max_access_size = 8, + }, +}; + static void spapr_xive_irq(sPAPRXive *xive, int lisn) { @@ -287,6 +444,11 @@ static void spapr_xive_source_set_irq(void *opaque, int lisn, int val) #define VC_BAR_SIZE 0x08000000000ull #define ESB_SHIFT 16 /* One 64k page. OPAL has two */ +/* Thread Interrupt Management Area MMIO */ +#define TM_BAR_DEFAULT 0x30203180000ull +#define TM_SHIFT 16 +#define TM_BAR_SIZE (TM_RING_COUNT * (1 << TM_SHIFT)) + static uint64_t spapr_xive_esb_default_read(void *p, hwaddr offset, unsigned size) { @@ -392,6 +554,14 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp) (1ull << xive->esb_shift) * xive->nr_irqs); memory_region_add_subregion(&xive->esb_mr, 0, &xive->esb_iomem); + /* TM BAR. Same address for each chip */ + xive->tm_base = (P9_MMIO_BASE | TM_BAR_DEFAULT); + xive->tm_shift = TM_SHIFT; + + memory_region_init_io(&xive->tm_iomem, OBJECT(xive), &spapr_xive_tm_ops, + xive, "xive.tm", TM_BAR_SIZE); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &xive->tm_iomem); + qemu_register_reset(spapr_xive_reset, dev); } @@ -448,9 +618,110 @@ static const TypeInfo spapr_xive_info = { .class_init = spapr_xive_class_init, }; +void spapr_xive_icp_pic_print_info(sPAPRXiveICP *xicp, Monitor *mon) +{ + int cpu_index = xicp->cs ? xicp->cs->cpu_index : -1; + + monitor_printf(mon, "CPU %d CPPR=%02x IPB=%02x PIPR=%02x NSR=%02x\n", + cpu_index, xicp->tima_os[TM_CPPR], xicp->tima_os[TM_IPB], + xicp->tima_os[TM_PIPR], xicp->tima_os[TM_NSR]); +} + +static void spapr_xive_icp_reset(void *dev) +{ + sPAPRXiveICP *xicp = SPAPR_XIVE_ICP(dev); + + memset(xicp->tima, 0, sizeof(xicp->tima)); +} + +static void spapr_xive_icp_realize(DeviceState *dev, Error **errp) +{ + sPAPRXiveICP *xicp = SPAPR_XIVE_ICP(dev); + PowerPCCPU *cpu; + CPUPPCState *env; + Object *obj; + Error *err = NULL; + + obj = object_property_get_link(OBJECT(dev), ICP_PROP_CPU, &err); + if (!obj) { + error_propagate(errp, err); + error_prepend(errp, "required link '" ICP_PROP_CPU "' not found: "); + return; + } + + cpu = POWERPC_CPU(obj); + xicp->cs = CPU(obj); + + env = &cpu->env; + switch (PPC_INPUT(env)) { + case PPC_FLAGS_INPUT_POWER7: + xicp->output = env->irq_inputs[POWER7_INPUT_INT]; + break; + + case PPC_FLAGS_INPUT_970: + xicp->output = env->irq_inputs[PPC970_INPUT_INT]; + break; + + default: + error_setg(errp, "XIVE interrupt controller does not support " + "this CPU bus model"); + return; + } + + qemu_register_reset(spapr_xive_icp_reset, dev); +} + +static void spapr_xive_icp_unrealize(DeviceState *dev, Error **errp) +{ + qemu_unregister_reset(spapr_xive_icp_reset, dev); +} + +static void spapr_xive_icp_init(Object *obj) +{ + sPAPRXiveICP *xicp = SPAPR_XIVE_ICP(obj); + + xicp->tima_os = &xicp->tima[TM_QW1_OS]; +} + +static bool vmstate_spapr_xive_icp_needed(void *opaque) +{ + /* TODO check machine XIVE support */ + return true; +} + +static const VMStateDescription vmstate_spapr_xive_icp = { + .name = TYPE_SPAPR_XIVE_ICP, + .version_id = 1, + .minimum_version_id = 1, + .needed = vmstate_spapr_xive_icp_needed, + .fields = (VMStateField[]) { + VMSTATE_BUFFER(tima, sPAPRXiveICP), + VMSTATE_END_OF_LIST() + }, +}; + +static void spapr_xive_icp_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = spapr_xive_icp_realize; + dc->unrealize = spapr_xive_icp_unrealize; + dc->desc = "sPAPR XIVE Interrupt Presenter"; + dc->vmsd = &vmstate_spapr_xive_icp; +} + +static const TypeInfo xive_icp_info = { + .name = TYPE_SPAPR_XIVE_ICP, + .parent = TYPE_DEVICE, + .instance_size = sizeof(sPAPRXiveICP), + .instance_init = spapr_xive_icp_init, + .class_init = spapr_xive_icp_class_init, +}; + static void spapr_xive_register_types(void) { type_register_static(&spapr_xive_info); + type_register_static(&xive_icp_info); } type_init(spapr_xive_register_types) diff --git a/hw/intc/xive-internal.h b/hw/intc/xive-internal.h index bea88d82992c..7d329f203a9b 100644 --- a/hw/intc/xive-internal.h +++ b/hw/intc/xive-internal.h @@ -24,6 +24,93 @@ #define PPC_BITMASK32(bs, be) ((PPC_BIT32(bs) - PPC_BIT32(be)) | \ PPC_BIT32(bs)) +/* + * Thread Management (aka "TM") registers + */ + +/* Number of Thread Management Interrupt Areas */ +#define TM_RING_COUNT 4 + +/* TM register offsets */ +#define TM_QW0_USER 0x000 /* All rings */ +#define TM_QW1_OS 0x010 /* Ring 0..2 */ +#define TM_QW2_HV_POOL 0x020 /* Ring 0..1 */ +#define TM_QW3_HV_PHYS 0x030 /* Ring 0..1 */ + +/* Byte offsets inside a QW QW0 QW1 QW2 QW3 */ +#define TM_NSR 0x0 /* + + - + */ +#define TM_CPPR 0x1 /* - + - + */ +#define TM_IPB 0x2 /* - + + + */ +#define TM_LSMFB 0x3 /* - + + + */ +#define TM_ACK_CNT 0x4 /* - + - - */ +#define TM_INC 0x5 /* - + - + */ +#define TM_AGE 0x6 /* - + - + */ +#define TM_PIPR 0x7 /* - + - + */ + +#define TM_WORD0 0x0 +#define TM_WORD1 0x4 + +/* + * QW word 2 contains the valid bit at the top and other fields + * depending on the QW. + */ +#define TM_WORD2 0x8 +#define TM_QW0W2_VU PPC_BIT32(0) +#define TM_QW0W2_LOGIC_SERV PPC_BITMASK32(1, 31) /* XX 2,31 ? */ +#define TM_QW1W2_VO PPC_BIT32(0) +#define TM_QW1W2_OS_CAM PPC_BITMASK32(8, 31) +#define TM_QW2W2_VP PPC_BIT32(0) +#define TM_QW2W2_POOL_CAM PPC_BITMASK32(8, 31) +#define TM_QW3W2_VT PPC_BIT32(0) +#define TM_QW3W2_LP PPC_BIT32(6) +#define TM_QW3W2_LE PPC_BIT32(7) +#define TM_QW3W2_T PPC_BIT32(31) + +/* + * In addition to normal loads to "peek" and writes (only when invalid) + * using 4 and 8 bytes accesses, the above registers support these + * "special" byte operations: + * + * - Byte load from QW0[NSR] - User level NSR (EBB) + * - Byte store to QW0[NSR] - User level NSR (EBB) + * - Byte load/store to QW1[CPPR] and QW3[CPPR] - CPPR access + * - Byte load from QW3[TM_WORD2] - Read VT||00000||LP||LE on thrd 0 + * otherwise VT||0000000 + * - Byte store to QW3[TM_WORD2] - Set VT bit (and LP/LE if present) + * + * Then we have all these "special" CI ops at these offset that trigger + * all sorts of side effects: + */ +#define TM_SPC_ACK_EBB 0x800 /* Load8 ack EBB to reg*/ +#define TM_SPC_ACK_OS_REG 0x810 /* Load16 ack OS irq to reg */ +#define TM_SPC_PUSH_USR_CTX 0x808 /* Store32 Push/Validate user context */ +#define TM_SPC_PULL_USR_CTX 0x808 /* Load32 Pull/Invalidate user + * context */ +#define TM_SPC_SET_OS_PENDING 0x812 /* Store8 Set OS irq pending bit */ +#define TM_SPC_PULL_OS_CTX 0x818 /* Load32/Load64 Pull/Invalidate OS + * context to reg */ +#define TM_SPC_PULL_POOL_CTX 0x828 /* Load32/Load64 Pull/Invalidate Pool + * context to reg*/ +#define TM_SPC_ACK_HV_REG 0x830 /* Load16 ack HV irq to reg */ +#define TM_SPC_PULL_USR_CTX_OL 0xc08 /* Store8 Pull/Inval usr ctx to odd + * line */ +#define TM_SPC_ACK_OS_EL 0xc10 /* Store8 ack OS irq to even line */ +#define TM_SPC_ACK_HV_POOL_EL 0xc20 /* Store8 ack HV evt pool to even + * line */ +#define TM_SPC_ACK_HV_EL 0xc30 /* Store8 ack HV irq to even line */ +/* XXX more... */ + +/* NSR fields for the various QW ack types */ +#define TM_QW0_NSR_EB PPC_BIT8(0) +#define TM_QW1_NSR_EO PPC_BIT8(0) +#define TM_QW3_NSR_HE PPC_BITMASK8(0, 1) +#define TM_QW3_NSR_HE_NONE 0 +#define TM_QW3_NSR_HE_POOL 1 +#define TM_QW3_NSR_HE_PHYS 2 +#define TM_QW3_NSR_HE_LSI 3 +#define TM_QW3_NSR_I PPC_BIT8(2) +#define TM_QW3_NSR_GRP_LVL PPC_BIT8(3, 7) + /* IVE/EAS * * One per interrupt source. Targets that interrupt to a given EQ @@ -44,6 +131,8 @@ typedef struct XiveIVE { #define IVE_EQ_DATA PPC_BITMASK(33, 63) /* Data written to the EQ */ } XiveIVE; +#define XIVE_PRIORITY_MAX 7 + void spapr_xive_reset(void *dev); XiveIVE *spapr_xive_get_ive(sPAPRXive *xive, uint32_t lisn); diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 7a308fb4db2b..6e8a189e723f 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -23,10 +23,15 @@ typedef struct sPAPRXive sPAPRXive; typedef struct XiveIVE XiveIVE; +typedef struct sPAPRXiveICP sPAPRXiveICP; #define TYPE_SPAPR_XIVE "spapr-xive" #define SPAPR_XIVE(obj) OBJECT_CHECK(sPAPRXive, (obj), TYPE_SPAPR_XIVE) +#define TYPE_SPAPR_XIVE_ICP "spapr-xive-icp" +#define SPAPR_XIVE_ICP(obj) \ + OBJECT_CHECK(sPAPRXiveICP, (obj), TYPE_SPAPR_XIVE_ICP) + struct sPAPRXive { SysBusDevice parent; @@ -57,6 +62,11 @@ struct sPAPRXive { hwaddr esb_base; MemoryRegion esb_mr; MemoryRegion esb_iomem; + + /* TIMA memory region */ + uint32_t tm_shift; + hwaddr tm_base; + MemoryRegion tm_iomem; }; static inline bool spapr_xive_irq_is_lsi(sPAPRXive *xive, int lisn) @@ -67,5 +77,6 @@ static inline bool spapr_xive_irq_is_lsi(sPAPRXive *xive, int lisn) bool spapr_xive_irq_set(sPAPRXive *xive, uint32_t lisn, bool lsi); bool spapr_xive_irq_unset(sPAPRXive *xive, uint32_t lisn); void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon); +void spapr_xive_icp_pic_print_info(sPAPRXiveICP *xicp, Monitor *mon); #endif /* PPC_SPAPR_XIVE_H */ From patchwork Thu Nov 23 13:29:43 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: 840766 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjL3t48Tjz9s72 for ; Fri, 24 Nov 2017 00:37:46 +1100 (AEDT) Received: from localhost ([::1]:44385 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrhI-0005rF-BT for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:37:44 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39088) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrbw-0001mF-TJ for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrbq-0002IW-Ri for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:12 -0500 Received: from 6.mo3.mail-out.ovh.net ([188.165.43.173]:58376) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrbq-0002Gf-J0 for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:06 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 584BE175AEB for ; Thu, 23 Nov 2017 14:32:05 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 2762A2E008A; Thu, 23 Nov 2017 14:32:00 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:43 +0100 Message-Id: <20171123132955.1261-14-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14831760949959953235 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.43.173 Subject: [Qemu-devel] [PATCH 13/25] spapr: introduce the XIVE Event Queues 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The Event Queue Descriptor (EQD) table, also known as Event Notification Descriptor (END), is one of the internal tables the XIVE interrupt controller uses to redirect exception from event sources to CPU threads. The EQD specifies on which Event Queue the event data should be posted when an exception occurs (later on pulled by the OS) and which server (VPD in XIVE terminology) to notify. The Event Queue is a much more complex structure but we start with a simple model for the sPAPR machine. There is one XiveEQ per priority and the model chooses to store them under the Xive Interrupt presenter model. It will be retrieved, just like for XICS, through the 'intc' object pointer of the CPU. The EQ indexing follows a simple pattern: (server << 3) | (priority & 0x7) Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ hw/intc/xive-internal.h | 50 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 554b25e0884c..983317a6b3f6 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -23,6 +23,7 @@ #include "sysemu/dma.h" #include "monitor/monitor.h" #include "hw/ppc/spapr_xive.h" +#include "hw/ppc/spapr.h" #include "hw/ppc/xics.h" #include "xive-internal.h" @@ -34,6 +35,8 @@ struct sPAPRXiveICP { uint8_t tima[TM_RING_COUNT * 0x10]; uint8_t *tima_os; qemu_irq output; + + XiveEQ eqt[XIVE_PRIORITY_MAX + 1]; }; static uint64_t spapr_xive_icp_accept(sPAPRXiveICP *icp) @@ -183,6 +186,13 @@ static const MemoryRegionOps spapr_xive_tm_ops = { }, }; +static sPAPRXiveICP *spapr_xive_icp_get(sPAPRXive *xive, int server) +{ + PowerPCCPU *cpu = spapr_find_cpu(server); + + return cpu ? SPAPR_XIVE_ICP(cpu->intc) : NULL; +} + static void spapr_xive_irq(sPAPRXive *xive, int lisn) { @@ -632,6 +642,8 @@ static void spapr_xive_icp_reset(void *dev) sPAPRXiveICP *xicp = SPAPR_XIVE_ICP(dev); memset(xicp->tima, 0, sizeof(xicp->tima)); + + memset(xicp->eqt, 0, sizeof(xicp->eqt)); } static void spapr_xive_icp_realize(DeviceState *dev, Error **errp) @@ -683,6 +695,23 @@ static void spapr_xive_icp_init(Object *obj) xicp->tima_os = &xicp->tima[TM_QW1_OS]; } +static const VMStateDescription vmstate_spapr_xive_icp_eq = { + .name = TYPE_SPAPR_XIVE_ICP "/eq", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField []) { + VMSTATE_UINT32(w0, XiveEQ), + VMSTATE_UINT32(w1, XiveEQ), + VMSTATE_UINT32(w2, XiveEQ), + VMSTATE_UINT32(w3, XiveEQ), + VMSTATE_UINT32(w4, XiveEQ), + VMSTATE_UINT32(w5, XiveEQ), + VMSTATE_UINT32(w6, XiveEQ), + VMSTATE_UINT32(w7, XiveEQ), + VMSTATE_END_OF_LIST() + }, +}; + static bool vmstate_spapr_xive_icp_needed(void *opaque) { /* TODO check machine XIVE support */ @@ -696,6 +725,8 @@ static const VMStateDescription vmstate_spapr_xive_icp = { .needed = vmstate_spapr_xive_icp_needed, .fields = (VMStateField[]) { VMSTATE_BUFFER(tima, sPAPRXiveICP), + VMSTATE_STRUCT_ARRAY(eqt, sPAPRXiveICP, (XIVE_PRIORITY_MAX + 1), 1, + vmstate_spapr_xive_icp_eq, XiveEQ), VMSTATE_END_OF_LIST() }, }; @@ -755,3 +786,28 @@ bool spapr_xive_irq_unset(sPAPRXive *xive, uint32_t lisn) ive->w &= ~IVE_VALID; return true; } + +/* + * Use a simple indexing for the EQs. + */ +XiveEQ *spapr_xive_get_eq(sPAPRXive *xive, uint32_t eq_idx) +{ + int priority = eq_idx & 0x7; + sPAPRXiveICP *xicp = spapr_xive_icp_get(xive, eq_idx >> 3); + + return xicp ? &xicp->eqt[priority] : NULL; +} + +bool spapr_xive_eq_for_server(sPAPRXive *xive, uint32_t server, + uint8_t priority, uint32_t *out_eq_idx) +{ + if (priority > XIVE_PRIORITY_MAX) { + return false; + } + + if (out_eq_idx) { + *out_eq_idx = (server << 3) | (priority & 0x7); + } + + return true; +} diff --git a/hw/intc/xive-internal.h b/hw/intc/xive-internal.h index 7d329f203a9b..c3949671aa03 100644 --- a/hw/intc/xive-internal.h +++ b/hw/intc/xive-internal.h @@ -131,9 +131,59 @@ typedef struct XiveIVE { #define IVE_EQ_DATA PPC_BITMASK(33, 63) /* Data written to the EQ */ } XiveIVE; +/* EQ */ +typedef struct XiveEQ { + uint32_t w0; +#define EQ_W0_VALID PPC_BIT32(0) +#define EQ_W0_ENQUEUE PPC_BIT32(1) +#define EQ_W0_UCOND_NOTIFY PPC_BIT32(2) +#define EQ_W0_BACKLOG PPC_BIT32(3) +#define EQ_W0_PRECL_ESC_CTL PPC_BIT32(4) +#define EQ_W0_ESCALATE_CTL PPC_BIT32(5) +#define EQ_W0_END_OF_INTR PPC_BIT32(6) +#define EQ_W0_QSIZE PPC_BITMASK32(12, 15) +#define EQ_W0_SW0 PPC_BIT32(16) +#define EQ_W0_FIRMWARE EQ_W0_SW0 /* Owned by FW */ +#define EQ_QSIZE_4K 0 +#define EQ_QSIZE_64K 4 +#define EQ_W0_HWDEP PPC_BITMASK32(24, 31) + uint32_t w1; +#define EQ_W1_ESn PPC_BITMASK32(0, 1) +#define EQ_W1_ESn_P PPC_BIT32(0) +#define EQ_W1_ESn_Q PPC_BIT32(1) +#define EQ_W1_ESe PPC_BITMASK32(2, 3) +#define EQ_W1_ESe_P PPC_BIT32(2) +#define EQ_W1_ESe_Q PPC_BIT32(3) +#define EQ_W1_GENERATION PPC_BIT32(9) +#define EQ_W1_PAGE_OFF PPC_BITMASK32(10, 31) + uint32_t w2; +#define EQ_W2_MIGRATION_REG PPC_BITMASK32(0, 3) +#define EQ_W2_OP_DESC_HI PPC_BITMASK32(4, 31) + uint32_t w3; +#define EQ_W3_OP_DESC_LO PPC_BITMASK32(0, 31) + uint32_t w4; +#define EQ_W4_ESC_EQ_BLOCK PPC_BITMASK32(4, 7) +#define EQ_W4_ESC_EQ_INDEX PPC_BITMASK32(8, 31) + uint32_t w5; +#define EQ_W5_ESC_EQ_DATA PPC_BITMASK32(1, 31) + uint32_t w6; +#define EQ_W6_FORMAT_BIT PPC_BIT32(8) +#define EQ_W6_NVT_BLOCK PPC_BITMASK32(9, 12) +#define EQ_W6_NVT_INDEX PPC_BITMASK32(13, 31) + uint32_t w7; +#define EQ_W7_F0_IGNORE PPC_BIT32(0) +#define EQ_W7_F0_BLK_GROUPING PPC_BIT32(1) +#define EQ_W7_F0_PRIORITY PPC_BITMASK32(8, 15) +#define EQ_W7_F1_WAKEZ PPC_BIT32(0) +#define EQ_W7_F1_LOG_SERVER_ID PPC_BITMASK32(1, 31) +} XiveEQ; + #define XIVE_PRIORITY_MAX 7 void spapr_xive_reset(void *dev); XiveIVE *spapr_xive_get_ive(sPAPRXive *xive, uint32_t lisn); +XiveEQ *spapr_xive_get_eq(sPAPRXive *xive, uint32_t idx); +bool spapr_xive_eq_for_server(sPAPRXive *xive, uint32_t server, uint8_t prio, + uint32_t *out_eq_idx); #endif /* _INTC_XIVE_INTERNAL_H */ From patchwork Thu Nov 23 13:29:44 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: 840783 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjLJk64Ndz9s72 for ; Fri, 24 Nov 2017 00:48:54 +1100 (AEDT) Received: from localhost ([::1]:44462 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrs4-00088J-Tq for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:48:52 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39150) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrbz-0001oE-1H for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrbv-0002Rf-Sl for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:15 -0500 Received: from 7.mo3.mail-out.ovh.net ([46.105.57.200]:40843) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrbv-0002Qg-NE for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:11 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 7C2B3175ADD for ; Thu, 23 Nov 2017 14:32:10 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 51A452E0084; Thu, 23 Nov 2017 14:32:05 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:44 +0100 Message-Id: <20171123132955.1261-15-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14833168323722054483 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 46.105.57.200 Subject: [Qemu-devel] [PATCH 14/25] spapr: push the XIVE EQ data in OS event queue 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" If a triggered event is let through, the Event Queue data defined in the associated IVE is pushed in the in-memory event queue. The latter is a circular buffer provided by the OS using the H_INT_SET_QUEUE_CONFIG hcall, one per server and priority couple. It is composed of Event Queue entries which are 4 bytes long, the first bit being a 'generation' bit and the 31 following bits the EQ Data field. The EQ Data field provides a way to set an invariant logical event source number for an IRQ. It is set with the H_INT_SET_SOURCE_CONFIG hcall. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 983317a6b3f6..df14c5a88275 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -193,9 +193,76 @@ static sPAPRXiveICP *spapr_xive_icp_get(sPAPRXive *xive, int server) return cpu ? SPAPR_XIVE_ICP(cpu->intc) : NULL; } +static void spapr_xive_eq_push(XiveEQ *eq, uint32_t data) +{ + uint64_t qaddr_base = (((uint64_t)(eq->w2 & 0x0fffffff)) << 32) | eq->w3; + uint32_t qsize = GETFIELD(EQ_W0_QSIZE, eq->w0); + uint32_t qindex = GETFIELD(EQ_W1_PAGE_OFF, eq->w1); + uint32_t qgen = GETFIELD(EQ_W1_GENERATION, eq->w1); + + uint64_t qaddr = qaddr_base + (qindex << 2); + uint32_t qdata = cpu_to_be32((qgen << 31) | (data & 0x7fffffff)); + uint32_t qentries = 1 << (qsize + 10); + + if (dma_memory_write(&address_space_memory, qaddr, &qdata, sizeof(qdata))) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to write EQ data @0x%" + HWADDR_PRIx "\n", __func__, qaddr); + return; + } + + qindex = (qindex + 1) % qentries; + if (qindex == 0) { + qgen ^= 1; + eq->w1 = SETFIELD(EQ_W1_GENERATION, eq->w1, qgen); + } + eq->w1 = SETFIELD(EQ_W1_PAGE_OFF, eq->w1, qindex); +} + static void spapr_xive_irq(sPAPRXive *xive, int lisn) { + XiveIVE *ive; + XiveEQ *eq; + uint32_t eq_idx; + uint8_t priority; + + ive = spapr_xive_get_ive(xive, lisn); + if (!ive || !(ive->w & IVE_VALID)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid LISN %d\n", lisn); + return; + } + if (ive->w & IVE_MASKED) { + return; + } + + /* Find our XiveEQ */ + eq_idx = GETFIELD(IVE_EQ_INDEX, ive->w); + eq = spapr_xive_get_eq(xive, eq_idx); + if (!eq) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No EQ for LISN %d\n", lisn); + return; + } + + if (eq->w0 & EQ_W0_ENQUEUE) { + spapr_xive_eq_push(eq, GETFIELD(IVE_EQ_DATA, ive->w)); + } else { + qemu_log_mask(LOG_UNIMP, "XIVE: !ENQUEUE not implemented\n"); + } + + if (!(eq->w0 & EQ_W0_UCOND_NOTIFY)) { + qemu_log_mask(LOG_UNIMP, "XIVE: !UCOND_NOTIFY not implemented\n"); + } + + if (GETFIELD(EQ_W6_FORMAT_BIT, eq->w6) == 0) { + priority = GETFIELD(EQ_W7_F0_PRIORITY, eq->w7); + + /* The EQ is masked. Can this happen ? */ + if (priority == 0xff) { + g_assert_not_reached(); + } + } else { + qemu_log_mask(LOG_UNIMP, "XIVE: w7 format1 not implemented\n"); + } } /* From patchwork Thu Nov 23 13:29:45 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: 840789 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjLML1g6zz9s72 for ; Fri, 24 Nov 2017 00:51:10 +1100 (AEDT) Received: from localhost ([::1]:44477 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHruG-0001Wg-8p for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:51:08 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39281) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrc4-0001tl-4a for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrc0-0002Xg-VK for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:20 -0500 Received: from 5.mo3.mail-out.ovh.net ([87.98.178.36]:32969) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrc0-0002Vs-MB for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:16 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id A98FA175AF9 for ; Thu, 23 Nov 2017 14:32:15 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 7A74E2E0084; Thu, 23 Nov 2017 14:32:10 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:45 +0100 Message-Id: <20171123132955.1261-16-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14834575698886953811 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.178.36 Subject: [Qemu-devel] [PATCH 15/25] spapr: notify the CPU when the XIVE interrupt priority is more privileged 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The Pending Interrupt Priority Register (PIPR) contains the priority of the most favored pending notification. It is calculated from the Interrupt Pending Buffer (IPB) which indicates a pending interrupt at the priority corresponding to the bit number. If the PIPR is more favored (1) than the Current Processor Priority Register (CPPR), the CPU interrupt line is raised and the EO bit of the Notification Source Register is updated to notify the presence of an exception for the O/S. The check needs to be done whenever the PIPR or the CPPR is changed. Then, the O/S Exception is raised and the O/S acknowledges the interrupt with a special read in the TIMA. If the EO bit of the Notification Source Register (NSR) is set (and it should), the Current Processor Priority Register (CPPR) takes the value of the Pending Interrupt Priority Register (PIPR). The bit number in the Interrupt Pending Buffer (IPB) corresponding to the priority of the pending interrupt is reseted and so is the EO bit of the NSR. (1) numerically less than Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index df14c5a88275..fead9c7031f3 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -39,9 +39,63 @@ struct sPAPRXiveICP { XiveEQ eqt[XIVE_PRIORITY_MAX + 1]; }; +/* Convert a priority number to an Interrupt Pending Buffer (IPB) + * register, which indicates a pending interrupt at the priority + * corresponding to the bit number + */ +static uint8_t priority_to_ipb(uint8_t priority) +{ + return priority > XIVE_PRIORITY_MAX ? + 0 : 1 << (XIVE_PRIORITY_MAX - priority); +} + +/* Convert an Interrupt Pending Buffer (IPB) register to a Pending + * Interrupt Priority Register (PIPR), which contains the priority of + * the most favored pending notification. + * + * TODO: + * + * PIPR is clamped to CPPR. So the value in the PIPR is: + * + * v = leftmost_bit_of(ipb) (or 0xff); + * pipr = v < cppr ? v : cppr; + * + * Ben says: "which means it's never actually 0xff ... surprise !". + * But, the CPPR can be set to 0xFF ... I am confused ... + */ +static uint8_t ipb_to_pipr(uint8_t ibp) +{ + return ibp ? clz32((uint32_t)ibp << 24) : 0xff; +} + static uint64_t spapr_xive_icp_accept(sPAPRXiveICP *icp) { - return 0; + uint8_t nsr = icp->tima_os[TM_NSR]; + + qemu_irq_lower(icp->output); + + if (icp->tima_os[TM_NSR] & TM_QW1_NSR_EO) { + uint8_t cppr = icp->tima_os[TM_PIPR]; + + icp->tima_os[TM_CPPR] = cppr; + + /* Reset the pending buffer bit */ + icp->tima_os[TM_IPB] &= ~priority_to_ipb(cppr); + icp->tima_os[TM_PIPR] = ipb_to_pipr(icp->tima_os[TM_IPB]); + + /* Drop Exception bit for OS */ + icp->tima_os[TM_NSR] &= ~TM_QW1_NSR_EO; + } + + return (nsr << 8) | icp->tima_os[TM_CPPR]; +} + +static void spapr_xive_icp_notify(sPAPRXiveICP *icp) +{ + if (icp->tima_os[TM_PIPR] < icp->tima_os[TM_CPPR]) { + icp->tima_os[TM_NSR] |= TM_QW1_NSR_EO; + qemu_irq_raise(icp->output); + } } static void spapr_xive_icp_set_cppr(sPAPRXiveICP *icp, uint8_t cppr) @@ -51,6 +105,9 @@ static void spapr_xive_icp_set_cppr(sPAPRXiveICP *icp, uint8_t cppr) } icp->tima_os[TM_CPPR] = cppr; + + /* CPPR has changed, inform the ICP which might raise an exception */ + spapr_xive_icp_notify(icp); } /* @@ -224,6 +281,8 @@ static void spapr_xive_irq(sPAPRXive *xive, int lisn) XiveEQ *eq; uint32_t eq_idx; uint8_t priority; + uint32_t server; + sPAPRXiveICP *icp; ive = spapr_xive_get_ive(xive, lisn); if (!ive || !(ive->w & IVE_VALID)) { @@ -253,6 +312,13 @@ static void spapr_xive_irq(sPAPRXive *xive, int lisn) qemu_log_mask(LOG_UNIMP, "XIVE: !UCOND_NOTIFY not implemented\n"); } + server = GETFIELD(EQ_W6_NVT_INDEX, eq->w6); + icp = spapr_xive_icp_get(xive, server); + if (!icp) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No ICP for server %d\n", server); + return; + } + if (GETFIELD(EQ_W6_FORMAT_BIT, eq->w6) == 0) { priority = GETFIELD(EQ_W7_F0_PRIORITY, eq->w7); @@ -260,9 +326,18 @@ static void spapr_xive_irq(sPAPRXive *xive, int lisn) if (priority == 0xff) { g_assert_not_reached(); } + + /* Update the IPB (Interrupt Pending Buffer) with the priority + * of the new notification and inform the ICP, which will + * decide to raise the exception, or not, depending the CPPR. + */ + icp->tima_os[TM_IPB] |= priority_to_ipb(priority); + icp->tima_os[TM_PIPR] = ipb_to_pipr(icp->tima_os[TM_IPB]); } else { qemu_log_mask(LOG_UNIMP, "XIVE: w7 format1 not implemented\n"); } + + spapr_xive_icp_notify(icp); } /* From patchwork Thu Nov 23 13:29: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: 840778 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjLFm0Xf9z9s76 for ; Fri, 24 Nov 2017 00:46:20 +1100 (AEDT) Received: from localhost ([::1]:44446 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrpa-0006DK-4m for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:46:18 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39381) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrc9-0001yr-SW for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrc6-0002gc-1g for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:25 -0500 Received: from 2.mo3.mail-out.ovh.net ([46.105.75.36]:40325) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrc5-0002fi-R6 for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:21 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id CDA5F175B04 for ; Thu, 23 Nov 2017 14:32:20 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id A24762E00A2; Thu, 23 Nov 2017 14:32:15 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:46 +0100 Message-Id: <20171123132955.1261-17-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14835983075899968339 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 46.105.75.36 Subject: [Qemu-devel] [PATCH 16/25] spapr: add support for the SET_OS_PENDING command (XIVE) 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Adjusting the Interrupt Pending Buffer for the O/S would allow a CPU to process event queues of other priorities during one physical interrupt cycle. This is not currently used by the XIVE support for sPAPR in Linux but it is by the hypervisor. From Ben : It's a way to avoid the SW replay on EOI. IE, assume you have 2 interrupts in the queue. You take the exception, ack the first one, process it etc... Then you EOI, the HW won't send a second notification. You need to look at the queue and continue consuming until it's empty. Today Linux checks the queue on EOI and use a SW mechanism to synthesize a new pseudo-external interrupt. This MMIO command would allow the OS to instead set back the corresponding priority bit to 1 in the IPB and cause the HW to re-emit the interrupt instead of SW. Linux doesn't use this today because DD1 didn't support it for the HV level, but other OSes might and we also might use it when we do groups, thus allowing redistribution. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index fead9c7031f3..b732aaf4f8ba 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -181,7 +181,14 @@ static bool spapr_xive_tm_is_readonly(uint8_t offset) static void spapr_xive_tm_write_special(sPAPRXiveICP *icp, hwaddr offset, uint64_t value, unsigned size) { - /* TODO: support TM_SPC_SET_OS_PENDING */ + if (offset == TM_SPC_SET_OS_PENDING && size == 1) { + icp->tima_os[TM_IPB] |= priority_to_ipb(value & 0xff); + icp->tima_os[TM_PIPR] = ipb_to_pipr(icp->tima_os[TM_IPB]); + spapr_xive_icp_notify(icp); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid TIMA write @%" + HWADDR_PRIx" size %d\n", offset, size); + } /* TODO: support TM_SPC_ACK_OS_EL */ } From patchwork Thu Nov 23 13:29:47 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: 840781 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjLJW3JTDz9s72 for ; Fri, 24 Nov 2017 00:48:43 +1100 (AEDT) Received: from localhost ([::1]:44460 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrrt-0007xl-CK for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:48:41 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39529) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrcE-00021W-Ai for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrcB-0002nP-56 for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:30 -0500 Received: from 14.mo3.mail-out.ovh.net ([188.165.43.98]:55544) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrcA-0002mb-W0 for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:27 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 03DC5175AF9 for ; Thu, 23 Nov 2017 14:32:26 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id CA9E22E00AC; Thu, 23 Nov 2017 14:32:20 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:47 +0100 Message-Id: <20171123132955.1261-18-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14837390451636407123 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.43.98 Subject: [Qemu-devel] [PATCH 17/25] spapr: add a sPAPRXive object to 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The XIVE object is designed to be always available, so it is created unconditionally on newer machines. Depending on the configuration and the guest capabilities, the CAS negotiation process will decide which interrupt model to use, legacy or XIVE. The XIVE model makes use of the full range of the IRQ number space because the IRQ numbers for the CPU IPIs are allocated in the range below XICS_IRQ_BASE, which is unused by XICS. Signed-off-by: Cédric Le Goater --- hw/ppc/spapr.c | 34 ++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr.h | 2 ++ 2 files changed, 36 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 5d3325ca3c88..0e0107c8272c 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -56,6 +56,7 @@ #include "hw/ppc/spapr_vio.h" #include "hw/pci-host/spapr.h" #include "hw/ppc/xics.h" +#include "hw/ppc/spapr_xive.h" #include "hw/pci/msi.h" #include "hw/pci/pci.h" @@ -204,6 +205,29 @@ static void xics_system_init(MachineState *machine, int nr_irqs, Error **errp) } } +static sPAPRXive *spapr_xive_create(sPAPRMachineState *spapr, int nr_irqs, + Error **errp) +{ + Error *local_err = NULL; + Object *obj; + + obj = object_new(TYPE_SPAPR_XIVE); + object_property_add_child(OBJECT(spapr), "xive", obj, &error_abort); + object_property_set_int(obj, nr_irqs, "nr-irqs", &local_err); + if (local_err) { + goto error; + } + object_property_set_bool(obj, true, "realized", &local_err); + if (local_err) { + goto error; + } + + return SPAPR_XIVE(obj); +error: + error_propagate(errp, local_err); + return NULL; +} + static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu, int smt_threads) { @@ -2360,6 +2384,16 @@ static void ppc_spapr_init(MachineState *machine) /* Set up Interrupt Controller before we create the VCPUs */ xics_system_init(machine, XICS_IRQS_SPAPR, &error_fatal); + /* We don't have KVM support yet, so check for irqchip=on */ + if (kvm_enabled() && machine_kernel_irqchip_required(machine)) { + error_report("kernel_irqchip requested. no XIVE support"); + } else { + /* XIVE uses the full range of IRQ numbers. The CPU IPIs will + * use the range below XICS_IRQ_BASE, which is unused by XICS. */ + spapr->xive = spapr_xive_create(spapr, XICS_IRQ_BASE + XICS_IRQS_SPAPR, + &error_fatal); + } + /* Set up containers for ibm,client-architecture-support negotiated options */ spapr->ov5 = spapr_ovec_new(); diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 9a3885593c86..90e2b0f6c678 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -14,6 +14,7 @@ struct sPAPRNVRAM; typedef struct sPAPREventLogEntry sPAPREventLogEntry; typedef struct sPAPREventSource sPAPREventSource; typedef struct sPAPRPendingHPT sPAPRPendingHPT; +typedef struct sPAPRXive sPAPRXive; #define HPTE64_V_HPTE_DIRTY 0x0000000000000040ULL #define SPAPR_ENTRY_POINT 0x100 @@ -127,6 +128,7 @@ struct sPAPRMachineState { MemoryHotplugState hotplug_memory; const char *icp_type; + sPAPRXive *xive; }; #define H_SUCCESS 0 From patchwork Thu Nov 23 13:29:48 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: 840769 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjL7C1KL5z9s76 for ; Fri, 24 Nov 2017 00:40:39 +1100 (AEDT) Received: from localhost ([::1]:44398 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrk5-00008v-61 for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:40:37 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39702) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrcJ-00026u-Sl for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrcG-0002wh-Mp for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:35 -0500 Received: from 20.mo3.mail-out.ovh.net ([178.33.47.94]:34402) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrcG-0002ux-FH for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:32 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 2DEFF16E538 for ; Thu, 23 Nov 2017 14:32:31 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id F33952E00A2; Thu, 23 Nov 2017 14:32:25 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:48 +0100 Message-Id: <20171123132955.1261-19-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14839079300336028499 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 178.33.47.94 Subject: [Qemu-devel] [PATCH 18/25] spapr: allocate IRQ numbers for the XIVE interrupt mode 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The IRQ numbers for the IPIs are allocated at the bottom of the IRQ number space to preserve compatibility with XICS which only uses IRQ numbers above 4096. Also make sure that the allocated IRQ numbers are kept in sync between XICS and XIVE. Signed-off-by: Cédric Le Goater --- hw/ppc/spapr.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 0e0107c8272c..ca4e72187f60 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2392,6 +2392,11 @@ static void ppc_spapr_init(MachineState *machine) * use the range below XICS_IRQ_BASE, which is unused by XICS. */ spapr->xive = spapr_xive_create(spapr, XICS_IRQ_BASE + XICS_IRQS_SPAPR, &error_fatal); + + /* Allocate the first IRQ numbers for the XIVE IPIs */ + for (i = 0; i < xics_max_server_number(); ++i) { + spapr_xive_irq_set(spapr->xive, i, false); + } } /* Set up containers for ibm,client-architecture-support negotiated options @@ -3631,6 +3636,7 @@ static int ics_find_free_block(ICSState *ics, int num, int alignnum) static void spapr_irq_set(sPAPRMachineState *spapr, int irq, bool lsi) { ics_set_irq_type(spapr->ics, irq - spapr->ics->offset, lsi); + spapr_xive_irq_set(spapr->xive, irq, lsi); } int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi, @@ -3721,6 +3727,7 @@ void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num) memset(&ics->irqs[i], 0, sizeof(ICSIRQState)); } } + spapr_xive_irq_unset(spapr->xive, irq); } qemu_irq spapr_irq_get_qirq(sPAPRMachineState *spapr, int irq) From patchwork Thu Nov 23 13:29:49 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: 840764 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjL2q5k00z9s72 for ; Fri, 24 Nov 2017 00:36:50 +1100 (AEDT) Received: from localhost ([::1]:44381 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrgN-0004n4-UF for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:36:48 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39913) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrcT-0002Ee-He for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrcM-00036R-KK for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:45 -0500 Received: from 17.mo3.mail-out.ovh.net ([87.98.178.58]:37151) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrcM-00033f-08 for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:38 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 5EC6C175B01 for ; Thu, 23 Nov 2017 14:32:36 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 2815C2E00A2; Thu, 23 Nov 2017 14:32:31 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:49 +0100 Message-Id: <20171123132955.1261-20-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14840486672748612435 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.178.58 Subject: [Qemu-devel] [PATCH 19/25] spapr: add hcalls support for the XIVE interrupt mode 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" A set of Hypervisor's call are used to configure the interrupt sources and the event/notification queues of the guest: - H_INT_GET_SOURCE_INFO used to obtain the address of the MMIO page of the Event State Buffer (PQ bits) entry associated with the source. - H_INT_SET_SOURCE_CONFIG assigns a source to a "target". - H_INT_GET_SOURCE_CONFIG determines to which "target" and "priority" is assigned to a source - H_INT_GET_QUEUE_INFO returns the address of the notification management page associated with the specified "target" and "priority". - H_INT_SET_QUEUE_CONFIG sets or resets the event queue for a given "target" and "priority". It is also used to set the notification config associated with the queue, only unconditional notification for the moment. Reset is performed with a queue size of 0 and queueing is disabled in that case. - H_INT_GET_QUEUE_CONFIG returns the queue settings for a given "target" and "priority". - H_INT_RESET resets all of the partition's interrupt exploitation structures to their initial state, losing all configuration set via the hcalls H_INT_SET_SOURCE_CONFIG and H_INT_SET_QUEUE_CONFIG. - H_INT_SYNC issue a synchronisation on a source to make sure sure all notifications have reached their queue. Calls that still need to be addressed : H_INT_SET_OS_REPORTING_LINE H_INT_GET_OS_REPORTING_LINE See the code for more documentation on each hcall. Signed-off-by: Cédric Le Goater --- hw/intc/Makefile.objs | 2 +- hw/intc/spapr_xive_hcall.c | 885 ++++++++++++++++++++++++++++++++++++++++++++ hw/ppc/spapr.c | 2 + include/hw/ppc/spapr.h | 15 +- include/hw/ppc/spapr_xive.h | 4 + 5 files changed, 906 insertions(+), 2 deletions(-) create mode 100644 hw/intc/spapr_xive_hcall.c diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index 49e13e7aeeee..122e2ec77e8d 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -35,7 +35,7 @@ obj-$(CONFIG_SH4) += sh_intc.o obj-$(CONFIG_XICS) += xics.o obj-$(CONFIG_XICS_SPAPR) += xics_spapr.o obj-$(CONFIG_XICS_KVM) += xics_kvm.o -obj-$(CONFIG_XIVE_SPAPR) += spapr_xive.o +obj-$(CONFIG_XIVE_SPAPR) += spapr_xive.o spapr_xive_hcall.o obj-$(CONFIG_POWERNV) += xics_pnv.o obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o obj-$(CONFIG_S390_FLIC) += s390_flic.o diff --git a/hw/intc/spapr_xive_hcall.c b/hw/intc/spapr_xive_hcall.c new file mode 100644 index 000000000000..676fe0e2d5c7 --- /dev/null +++ b/hw/intc/spapr_xive_hcall.c @@ -0,0 +1,885 @@ +/* + * QEMU PowerPC sPAPR XIVE model + * + * Copyright (c) 2017, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qapi/error.h" +#include "cpu.h" +#include "hw/ppc/spapr.h" +#include "hw/ppc/spapr_xive.h" +#include "hw/ppc/fdt.h" +#include "monitor/monitor.h" + +#include "xive-internal.h" + +/* Priority ranges reserved by the hypervisor. The Linux driver is + * expected to choose priority 6. + */ +static const uint32_t reserved_priorities[] = { + 7, /* start */ + 0xf8, /* count */ +}; + +static bool priority_is_valid(uint32_t priority) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(reserved_priorities) / 2; i++) { + uint32_t base = reserved_priorities[2 * i]; + uint32_t count = reserved_priorities[2 * i + 1]; + + if (priority >= base && priority < base + count) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: priority %d is reserved\n", + __func__, priority); + return false; + } + } + + return true; +} + +/* + * The H_INT_GET_SOURCE_INFO hcall() is used to obtain the logical + * real address of the MMIO page through which the Event State Buffer + * entry associated with the value of the "lisn" parameter is managed. + * + * Parameters: + * Input + * - "flags" + * Bits 0-63 reserved + * - "lisn" is per "interrupts", "interrupt-map", or + * "ibm,xive-lisn-ranges" properties, or as returned by the + * ibm,query-interrupt-source-number RTAS call, or as returned + * by the H_ALLOCATE_VAS_WINDOW hcall + * + * Output + * - R4: "flags" + * Bits 0-59: Reserved + * Bit 60: H_INT_ESB must be used for Event State Buffer + * management + * Bit 61: 1 == LSI 0 == MSI + * Bit 62: the full function page supports trigger + * Bit 63: Store EOI Supported + * - R5: Logical Real address of full function Event State Buffer + * management page, -1 if ESB hcall flag is set to 1. + * - R6: Logical Real Address of trigger only Event State Buffer + * management page or -1. + * - R7: Power of 2 page size for the ESB management pages returned in + * R5 and R6. + */ +static target_ulong h_int_get_source_info(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + sPAPRXive *xive = spapr->xive; + XiveIVE *ive; + target_ulong flags = args[0]; + target_ulong lisn = args[1]; + uint64_t mmio_base; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags) { + return H_PARAMETER; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + ive = spapr_xive_get_ive(spapr->xive, lisn); + if (!ive || !(ive->w & IVE_VALID)) { + return H_P2; + } + + mmio_base = (uint64_t)xive->esb_base + (1ull << xive->esb_shift) * lisn; + + args[0] = 0; + if (spapr_xive_irq_is_lsi(xive, lisn)) { + args[0] |= XIVE_SRC_LSI; + } + if (xive->flags & XIVE_SRC_TRIGGER) { + args[0] |= XIVE_SRC_TRIGGER; + } + + if (xive->flags & XIVE_SRC_H_INT_ESB) { + args[1] = -1; /* never used in QEMU */ + args[2] = -1; + } else { + args[1] = mmio_base; + if (xive->flags & XIVE_SRC_TRIGGER) { + args[2] = -1; /* No specific trigger page */ + } else { + args[2] = -1; /* TODO: support for specific trigger page */ + } + } + + args[3] = xive->esb_shift; + + return H_SUCCESS; +} + +/* + * The H_INT_SET_SOURCE_CONFIG hcall() is used to assign a Logical + * Interrupt Source to a target. The Logical Interrupt Source is + * designated with the "lisn" parameter and the target is designated + * with the "target" and "priority" parameters. Upon return from the + * hcall(), no additional interrupts will be directed to the old EQ. + * + * TODO: The old EQ should be investigated for interrupts that + * occurred prior to or during the hcall(). + * + * Parameters: + * Input: + * - "flags" + * Bits 0-61: Reserved + * Bit 62: set the "eisn" in the EA + * Bit 63: masks the interrupt source in the hardware interrupt + * control structure. An interrupt masked by this mechanism will + * be dropped, but it's source state bits will still be + * set. There is no race-free way of unmasking and restoring the + * source. Thus this should only be used in interrupts that are + * also masked at the source, and only in cases where the + * interrupt is not meant to be used for a large amount of time + * because no valid target exists for it for example + * - "lisn" is per "interrupts", "interrupt-map", or + * "ibm,xive-lisn-ranges" properties, or as returned by the + * ibm,query-interrupt-source-number RTAS call, or as returned by + * the H_ALLOCATE_VAS_WINDOW hcall + * - "target" is per "ibm,ppc-interrupt-server#s" or + * "ibm,ppc-interrupt-gserver#s" + * - "priority" is a valid priority not in + * "ibm,plat-res-int-priorities" + * - "eisn" is the guest EISN associated with the "lisn" + * + * Output: + * - None + */ + +#define XIVE_SRC_SET_EISN (1ull << (63 - 62)) +#define XIVE_SRC_MASK (1ull << (63 - 63)) + +static target_ulong h_int_set_source_config(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + XiveIVE *ive; + uint64_t new_ive; + target_ulong flags = args[0]; + target_ulong lisn = args[1]; + target_ulong target = args[2]; + target_ulong priority = args[3]; + target_ulong eisn = args[4]; + uint32_t eq_idx; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags & ~(XIVE_SRC_SET_EISN | XIVE_SRC_MASK)) { + return H_PARAMETER; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + ive = spapr_xive_get_ive(spapr->xive, lisn); + if (!ive || !(ive->w & IVE_VALID)) { + return H_P2; + } + + /* priority 0xff is used to reset the IVE */ + if (priority == 0xff) { + new_ive = IVE_VALID | IVE_MASKED; + goto out; + } + + new_ive = ive->w; + + if (flags & XIVE_SRC_MASK) { + new_ive = ive->w | IVE_MASKED; + } else { + new_ive = ive->w & ~IVE_MASKED; + } + + if (!priority_is_valid(priority)) { + return H_P4; + } + + /* TODO: If the partition thread count is greater than the + * hardware thread count, validate the "target" has a + * corresponding hardware thread else return H_NOT_AVAILABLE. + */ + + /* Validate that "target" is part of the list of threads allocated + * to the partition. For that, find the EQ corresponding to the + * target. + */ + if (!spapr_xive_eq_for_server(spapr->xive, target, priority, &eq_idx)) { + return H_P3; + } + + new_ive = SETFIELD(IVE_EQ_BLOCK, new_ive, 0ul); + new_ive = SETFIELD(IVE_EQ_INDEX, new_ive, eq_idx); + + if (flags & XIVE_SRC_SET_EISN) { + new_ive = SETFIELD(IVE_EQ_DATA, new_ive, eisn); + } + +out: + /* TODO: handle syncs ? */ + + /* And update */ + ive->w = new_ive; + + return H_SUCCESS; +} + +/* + * The H_INT_GET_SOURCE_CONFIG hcall() is used to determine to which + * target/priority pair is assigned to the specified Logical Interrupt + * Source. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-63 Reserved + * - "lisn" is per "interrupts", "interrupt-map", or + * "ibm,xive-lisn-ranges" properties, or as returned by the + * ibm,query-interrupt-source-number RTAS call, or as + * returned by the H_ALLOCATE_VAS_WINDOW hcall + * + * Output: + * - R4: Target to which the specified Logical Interrupt Source is + * assigned + * - R5: Priority to which the specified Logical Interrupt Source is + * assigned + * - R6: EISN for the specified Logical Interrupt Source (this will be + * equivalent to the LISN if not changed by H_INT_SET_SOURCE_CONFIG) + */ +static target_ulong h_int_get_source_config(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + target_ulong flags = args[0]; + target_ulong lisn = args[1]; + XiveIVE *ive; + XiveEQ *eq; + uint32_t eq_idx; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags) { + return H_PARAMETER; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + ive = spapr_xive_get_ive(spapr->xive, lisn); + if (!ive || !(ive->w & IVE_VALID)) { + return H_P2; + } + + eq_idx = GETFIELD(IVE_EQ_INDEX, ive->w); + eq = spapr_xive_get_eq(spapr->xive, eq_idx); + if (!eq) { + return H_HARDWARE; + } + + args[0] = GETFIELD(EQ_W6_NVT_INDEX, eq->w6); + + if (ive->w & IVE_MASKED) { + args[1] = 0xff; + } else { + args[1] = GETFIELD(EQ_W7_F0_PRIORITY, eq->w7); + } + + args[2] = GETFIELD(IVE_EQ_DATA, ive->w); + + return H_SUCCESS; +} + +/* + * The H_INT_GET_QUEUE_INFO hcall() is used to get the logical real + * address of the notification management page associated with the + * specified target and priority. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-63 Reserved + * - "target" is per "ibm,ppc-interrupt-server#s" or + * "ibm,ppc-interrupt-gserver#s" + * - "priority" is a valid priority not in + * "ibm,plat-res-int-priorities" + * + * Output: + * - R4: Logical real address of notification page + * - R5: Power of 2 page size of the notification page + */ +static target_ulong h_int_get_queue_info(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + target_ulong flags = args[0]; + target_ulong target = args[1]; + target_ulong priority = args[2]; + uint32_t eq_idx; + XiveEQ *eq; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags) { + return H_PARAMETER; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + if (!priority_is_valid(priority)) { + return H_P3; + } + + /* Validate that "target" is part of the list of threads allocated + * to the partition. For that, find the EQ corresponding to the + * target. + */ + if (!spapr_xive_eq_for_server(spapr->xive, target, priority, &eq_idx)) { + return H_P2; + } + + /* TODO: If the partition thread count is greater than the + * hardware thread count, validate the "target" has a + * corresponding hardware thread else return H_NOT_AVAILABLE. + */ + + eq = spapr_xive_get_eq(spapr->xive, eq_idx); + if (!eq) { + return H_HARDWARE; + } + + args[0] = -1; /* TODO: return ESn page */ + if (eq->w0 & EQ_W0_ENQUEUE) { + args[1] = GETFIELD(EQ_W0_QSIZE, eq->w0) + 12; + } else { + args[1] = 0; + } + + return H_SUCCESS; +} + +/* + * The H_INT_SET_QUEUE_CONFIG hcall() is used to set or reset a EQ for + * a given "target" and "priority". It is also used to set the + * notification config associated with the EQ. An EQ size of 0 is + * used to reset the EQ config for a given target and priority. If + * resetting the EQ config, the END associated with the given "target" + * and "priority" will be changed to disable queueing. + * + * Upon return from the hcall(), no additional interrupts will be + * directed to the old EQ (if one was set). The old EQ (if one was + * set) should be investigated for interrupts that occurred prior to + * or during the hcall(). + * + * Parameters: + * Input: + * - "flags" + * Bits 0-62: Reserved + * Bit 63: Unconditional Notify (n) per the XIVE spec + * - "target" is per "ibm,ppc-interrupt-server#s" or + * "ibm,ppc-interrupt-gserver#s" + * - "priority" is a valid priority not in + * "ibm,plat-res-int-priorities" + * - "eventQueue": The logical real address of the start of the EQ + * - "eventQueueSize": The power of 2 EQ size per "ibm,xive-eq-sizes" + * + * Output: + * - None + */ + +#define XIVE_EQ_ALWAYS_NOTIFY (1ull << (63 - 63)) + +static target_ulong h_int_set_queue_config(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + target_ulong flags = args[0]; + target_ulong target = args[1]; + target_ulong priority = args[2]; + target_ulong qpage = args[3]; + target_ulong qsize = args[4]; + uint32_t eq_idx; + XiveEQ *old_eq; + XiveEQ eq; + uint32_t qdata; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags & ~XIVE_EQ_ALWAYS_NOTIFY) { + return H_PARAMETER; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + if (!priority_is_valid(priority)) { + return H_P3; + } + + /* Validate that "target" is part of the list of threads allocated + * to the partition. For that, find the EQ corresponding to the + * target. + */ + if (!spapr_xive_eq_for_server(spapr->xive, target, priority, &eq_idx)) { + return H_P2; + } + + /* TODO: If the partition thread count is greater than the + * hardware thread count, validate the "target" has a + * corresponding hardware thread else return H_NOT_AVAILABLE. + */ + + old_eq = spapr_xive_get_eq(spapr->xive, eq_idx); + if (!old_eq) { + return H_HARDWARE; + } + + eq = *old_eq; + + switch (qsize) { + case 12: + case 16: + case 21: + case 24: + eq.w3 = ((uint64_t)qpage) & 0xffffffff; + eq.w2 = (((uint64_t)qpage)) >> 32 & 0x0fffffff; + eq.w0 |= EQ_W0_ENQUEUE; + eq.w0 = SETFIELD(EQ_W0_QSIZE, eq.w0, qsize - 12); + break; + case 0: + /* reset queue and disable queueing */ + eq.w2 = eq.w3 = 0; + eq.w0 &= ~EQ_W0_ENQUEUE; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid EQ size %"PRIx64"\n", + __func__, qsize); + return H_P5; + } + + if (qsize) { + /* + * Let's validate the EQ address with a read of the first EQ + * entry. We could also check that the full queue has been + * zeroed by the OS. + */ + if (address_space_read(&address_space_memory, qpage, + MEMTXATTRS_UNSPECIFIED, + (uint8_t *) &qdata, sizeof(qdata))) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to read EQ data @0x%" + HWADDR_PRIx "\n", __func__, qpage); + return H_P4; + } + } + + /* Ensure the priority and target are correctly set (they will not + * be right after allocation) + */ + eq.w6 = SETFIELD(EQ_W6_NVT_BLOCK, 0ul, 0ul) | + SETFIELD(EQ_W6_NVT_INDEX, 0ul, target); + eq.w7 = SETFIELD(EQ_W7_F0_PRIORITY, 0ul, priority); + + /* TODO: depends on notitification page (ESn) from H_INT_GET_QUEUE_INFO */ + if (flags & XIVE_EQ_ALWAYS_NOTIFY) { + eq.w0 |= EQ_W0_UCOND_NOTIFY; + } + + /* The generation bit for the EQ starts at 1 and The EQ page + * offset counter starts at 0. + */ + eq.w1 = EQ_W1_GENERATION | SETFIELD(EQ_W1_PAGE_OFF, 0ul, 0ul); + eq.w0 |= EQ_W0_VALID; + + /* TODO: issue syncs required to ensure all in-flight interrupts + * are complete on the old EQ */ + + /* Update EQ */ + *old_eq = eq; + + return H_SUCCESS; +} + +/* + * The H_INT_GET_QUEUE_CONFIG hcall() is used to get a EQ for a given + * target and priority. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-62: Reserved + * Bit 63: Debug: Return debug data + * - "target" is per "ibm,ppc-interrupt-server#s" or + * "ibm,ppc-interrupt-gserver#s" + * - "priority" is a valid priority not in + * "ibm,plat-res-int-priorities" + * + * Output: + * - R4: "flags": + * Bits 0-62: Reserved + * Bit 63: The value of Unconditional Notify (n) per the XIVE spec + * - R5: The logical real address of the start of the EQ + * - R6: The power of 2 EQ size per "ibm,xive-eq-sizes" + * - R7: The value of Event Queue Offset Counter per XIVE spec + * if "Debug" = 1, else 0 + * + */ + +#define XIVE_EQ_DEBUG (1ull << (63 - 63)) + +static target_ulong h_int_get_queue_config(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + target_ulong flags = args[0]; + target_ulong target = args[1]; + target_ulong priority = args[2]; + uint32_t eq_idx; + XiveEQ *eq; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags & ~XIVE_EQ_DEBUG) { + return H_PARAMETER; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + if (!priority_is_valid(priority)) { + return H_P3; + } + + /* Validate that "target" is part of the list of threads allocated + * to the partition. For that, find the EQ corresponding to the + * target. + */ + if (!spapr_xive_eq_for_server(spapr->xive, target, priority, &eq_idx)) { + return H_P2; + } + + /* TODO: If the partition thread count is greater than the + * hardware thread count, validate the "target" has a + * corresponding hardware thread else return H_NOT_AVAILABLE. + */ + + eq = spapr_xive_get_eq(spapr->xive, eq_idx); + if (!eq) { + return H_HARDWARE; + } + + args[0] = 0; + if (eq->w0 & EQ_W0_UCOND_NOTIFY) { + args[0] |= XIVE_EQ_ALWAYS_NOTIFY; + } + + if (eq->w0 & EQ_W0_ENQUEUE) { + args[1] = + (((uint64_t)(eq->w2 & 0x0fffffff)) << 32) | eq->w3; + args[2] = GETFIELD(EQ_W0_QSIZE, eq->w0) + 12; + } else { + args[1] = 0; + args[2] = 0; + } + + /* TODO: do we need any locking on the EQ ? */ + if (flags & XIVE_EQ_DEBUG) { + /* Load the event queue generation number into the return flags */ + args[0] |= GETFIELD(EQ_W1_GENERATION, eq->w1); + + /* Load R7 with the event queue offset counter */ + args[3] = GETFIELD(EQ_W1_PAGE_OFF, eq->w1); + } + + return H_SUCCESS; +} + +/* + * The H_INT_SET_OS_REPORTING_LINE hcall() is used to set the + * reporting cache line pair for the calling thread. The reporting + * cache lines will contain the OS interrupt context when the OS + * issues a CI store byte to @TIMA+0xC10 to acknowledge the OS + * interrupt. The reporting cache lines can be reset by inputting -1 + * in "reportingLine". Issuing the CI store byte without reporting + * cache lines registered will result in the data not being accessible + * to the OS. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-63: Reserved + * - "reportingLine": The logical real address of the reporting cache + * line pair + * + * Output: + * - None + */ +static target_ulong h_int_set_os_reporting_line(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + /* TODO: H_INT_SET_OS_REPORTING_LINE */ + return H_FUNCTION; +} + +/* + * The H_INT_GET_OS_REPORTING_LINE hcall() is used to get the logical + * real address of the reporting cache line pair set for the input + * "target". If no reporting cache line pair has been set, -1 is + * returned. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-63: Reserved + * - "target" is per "ibm,ppc-interrupt-server#s" or + * "ibm,ppc-interrupt-gserver#s" + * - "reportingLine": The logical real address of the reporting cache + * line pair + * + * Output: + * - R4: The logical real address of the reporting line if set, else -1 + */ +static target_ulong h_int_get_os_reporting_line(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + /* TODO: H_INT_GET_OS_REPORTING_LINE */ + return H_FUNCTION; +} + +/* + * The H_INT_ESB hcall() is used to issue a load or store to the ESB + * page for the input "lisn". This hcall is only supported for LISNs + * that have the ESB hcall flag set to 1 when returned from hcall() + * H_INT_GET_SOURCE_INFO. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-62: Reserved + * bit 63: Store: Store=1, store operation, else load operation + * - "lisn" is per "interrupts", "interrupt-map", or + * "ibm,xive-lisn-ranges" properties, or as returned by the + * ibm,query-interrupt-source-number RTAS call, or as + * returned by the H_ALLOCATE_VAS_WINDOW hcall + * - "esbOffset" is the offset into the ESB page for the load or store operation + * - "storeData" is the data to write for a store operation + * + * Output: + * - R4: R4: The value of the load if load operation, else -1 + */ + +#define XIVE_ESB_STORE (1ull << (63 - 63)) + +static target_ulong h_int_esb(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + sPAPRXive *xive = spapr->xive; + XiveIVE *ive; + target_ulong flags = args[0]; + target_ulong lisn = args[1]; + target_ulong offset = args[2]; + target_ulong data = args[3]; + uint64_t esb_base; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags & ~XIVE_ESB_STORE) { + return H_PARAMETER; + } + + ive = spapr_xive_get_ive(xive, lisn); + if (!ive || !(ive->w & IVE_VALID)) { + return H_P2; + } + + if (offset > (1ull << xive->esb_shift)) { + return H_P3; + } + + esb_base = (uint64_t)xive->esb_base + (1ull << xive->esb_shift) * lisn; + esb_base += offset; + + if (dma_memory_rw(&address_space_memory, esb_base, &data, 8, + (flags & XIVE_ESB_STORE))) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to rw data @0x%" + HWADDR_PRIx "\n", __func__, esb_base); + return H_HARDWARE; + } + args[0] = (flags & XIVE_ESB_STORE) ? -1 : data; + return H_SUCCESS; +} + +/* + * The H_INT_SYNC hcall() is used to issue hardware syncs that will + * ensure any in flight events for the input lisn are in the event + * queue. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-63: Reserved + * - "lisn" is per "interrupts", "interrupt-map", or + * "ibm,xive-lisn-ranges" properties, or as returned by the + * ibm,query-interrupt-source-number RTAS call, or as + * returned by the H_ALLOCATE_VAS_WINDOW hcall + * + * Output: + * - None + */ +static target_ulong h_int_sync(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + XiveIVE *ive; + target_ulong flags = args[0]; + target_ulong lisn = args[1]; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags) { + return H_PARAMETER; + } + + ive = spapr_xive_get_ive(spapr->xive, lisn); + if (!ive || !(ive->w & IVE_VALID)) { + return H_P2; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + /* This is not real hardware. Nothing to be done */ + return H_SUCCESS; +} + +/* + * The H_INT_RESET hcall() is used to reset all of the partition's + * interrupt exploitation structures to their initial state. This + * means losing all previously set interrupt state set via + * H_INT_SET_SOURCE_CONFIG and H_INT_SET_QUEUE_CONFIG. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-63: Reserved + * + * Output: + * - None + */ +static target_ulong h_int_reset(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + target_ulong flags = args[0]; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags) { + return H_PARAMETER; + } + + spapr_xive_reset(spapr->xive); + return H_SUCCESS; +} + +void spapr_xive_hcall_init(sPAPRMachineState *spapr) +{ + spapr_register_hypercall(H_INT_GET_SOURCE_INFO, h_int_get_source_info); + spapr_register_hypercall(H_INT_SET_SOURCE_CONFIG, h_int_set_source_config); + spapr_register_hypercall(H_INT_GET_SOURCE_CONFIG, h_int_get_source_config); + spapr_register_hypercall(H_INT_GET_QUEUE_INFO, h_int_get_queue_info); + spapr_register_hypercall(H_INT_SET_QUEUE_CONFIG, h_int_set_queue_config); + spapr_register_hypercall(H_INT_GET_QUEUE_CONFIG, h_int_get_queue_config); + spapr_register_hypercall(H_INT_SET_OS_REPORTING_LINE, + h_int_set_os_reporting_line); + spapr_register_hypercall(H_INT_GET_OS_REPORTING_LINE, + h_int_get_os_reporting_line); + spapr_register_hypercall(H_INT_ESB, h_int_esb); + spapr_register_hypercall(H_INT_SYNC, h_int_sync); + spapr_register_hypercall(H_INT_RESET, h_int_reset); +} diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index ca4e72187f60..8b15c0b500d0 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -222,6 +222,8 @@ static sPAPRXive *spapr_xive_create(sPAPRMachineState *spapr, int nr_irqs, goto error; } + spapr_xive_hcall_init(spapr); + return SPAPR_XIVE(obj); error: error_propagate(errp, local_err); diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 90e2b0f6c678..a25e218b34e2 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -387,7 +387,20 @@ struct sPAPRMachineState { #define H_INVALIDATE_PID 0x378 #define H_REGISTER_PROC_TBL 0x37C #define H_SIGNAL_SYS_RESET 0x380 -#define MAX_HCALL_OPCODE H_SIGNAL_SYS_RESET + +#define H_INT_GET_SOURCE_INFO 0x3A8 +#define H_INT_SET_SOURCE_CONFIG 0x3AC +#define H_INT_GET_SOURCE_CONFIG 0x3B0 +#define H_INT_GET_QUEUE_INFO 0x3B4 +#define H_INT_SET_QUEUE_CONFIG 0x3B8 +#define H_INT_GET_QUEUE_CONFIG 0x3BC +#define H_INT_SET_OS_REPORTING_LINE 0x3C0 +#define H_INT_GET_OS_REPORTING_LINE 0x3C4 +#define H_INT_ESB 0x3C8 +#define H_INT_SYNC 0x3CC +#define H_INT_RESET 0x3D0 + +#define MAX_HCALL_OPCODE H_INT_RESET /* The hcalls above are standardized in PAPR and implemented by pHyp * as well. diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 6e8a189e723f..3f822220647f 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -79,4 +79,8 @@ bool spapr_xive_irq_unset(sPAPRXive *xive, uint32_t lisn); void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon); void spapr_xive_icp_pic_print_info(sPAPRXiveICP *xicp, Monitor *mon); +typedef struct sPAPRMachineState sPAPRMachineState; + +void spapr_xive_hcall_init(sPAPRMachineState *spapr); + #endif /* PPC_SPAPR_XIVE_H */ From patchwork Thu Nov 23 13:29:50 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: 840790 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjLPh1gG5z9s76 for ; Fri, 24 Nov 2017 00:53:11 +1100 (AEDT) Received: from localhost ([::1]:44488 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrwC-0003FP-IG for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:53:08 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39926) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrcU-0002FE-4v for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrcQ-0003GG-V4 for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:46 -0500 Received: from 14.mo3.mail-out.ovh.net ([188.165.43.98]:41568) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrcQ-0003D2-MA for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:42 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 7F08E175AB6 for ; Thu, 23 Nov 2017 14:32:41 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 5588C2E00B3; Thu, 23 Nov 2017 14:32:36 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:50 +0100 Message-Id: <20171123132955.1261-21-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14841894048724847443 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.43.98 Subject: [Qemu-devel] [PATCH 20/25] spapr: add device tree support for the XIVE interrupt mode 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The XIVE interface for the guest is described in the device tree under the "interrupt-controller" node. A couple of new properties are specific to XIVE : - "reg" contains the base address and size of the thread interrupt managnement areas (TIMA), also called rings, for the User level and for the Guest OS level. Only the Guest OS level is taken into account today. - "ibm,xive-eq-sizes" the size of the event queues. One cell per size supported, contains log2 of size, in ascending order. - "ibm,xive-lisn-ranges" the interrupt numbers ranges assigned to the guest. These are allocated using a simple bitmap. and also under the root node : - "ibm,plat-res-int-priorities" contains a list of priorities that the hypervisor has reserved for its own use. Simulate ranges as defined by the PowerVM Hypervisor. When the XIVE interrupt mode is activated after the CAS negotiation, the machine will perform a reboot to rebuild the device tree. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive_hcall.c | 50 +++++++++++++++++++++++++++++++++++++++++++++ hw/ppc/spapr.c | 7 ++++++- hw/ppc/spapr_hcall.c | 6 ++++++ include/hw/ppc/spapr_xive.h | 2 ++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/hw/intc/spapr_xive_hcall.c b/hw/intc/spapr_xive_hcall.c index 676fe0e2d5c7..60c6c9f4be8f 100644 --- a/hw/intc/spapr_xive_hcall.c +++ b/hw/intc/spapr_xive_hcall.c @@ -883,3 +883,53 @@ void spapr_xive_hcall_init(sPAPRMachineState *spapr) spapr_register_hypercall(H_INT_SYNC, h_int_sync); spapr_register_hypercall(H_INT_RESET, h_int_reset); } + +void spapr_xive_populate(sPAPRMachineState *spapr, int nr_servers, + void *fdt, uint32_t phandle) +{ + sPAPRXive *xive = spapr->xive; + int node; + uint64_t timas[2 * 2]; + uint32_t lisn_ranges[] = { + cpu_to_be32(0), + cpu_to_be32(nr_servers), + }; + uint32_t eq_sizes[] = { + cpu_to_be32(12), /* 4K */ + cpu_to_be32(16), /* 64K */ + cpu_to_be32(21), /* 2M */ + cpu_to_be32(24), /* 16M */ + }; + uint32_t plat_res_int_priorities[ARRAY_SIZE(reserved_priorities)]; + int i; + + for (i = 0; i < ARRAY_SIZE(plat_res_int_priorities); i++) { + plat_res_int_priorities[i] = cpu_to_be32(reserved_priorities[i]); + } + + /* Thread Interrupt Management Areas : User and OS */ + for (i = 0; i < 2; i++) { + timas[i * 2] = cpu_to_be64(xive->tm_base + i * (1 << xive->tm_shift)); + timas[i * 2 + 1] = cpu_to_be64(1 << xive->tm_shift); + } + + _FDT(node = fdt_add_subnode(fdt, 0, "interrupt-controller")); + + _FDT(fdt_setprop_string(fdt, node, "name", "interrupt-controller")); + _FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe")); + _FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas))); + + _FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe")); + _FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes, + sizeof(eq_sizes))); + _FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges, + sizeof(lisn_ranges))); + + /* For SLOF */ + _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle)); + _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle)); + + /* top properties */ + _FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities", + plat_res_int_priorities, sizeof(plat_res_int_priorities))); +} diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 8b15c0b500d0..3a62369883cc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1127,7 +1127,12 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr, _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2)); /* /interrupt controller */ - spapr_dt_xics(xics_max_server_number(), fdt, PHANDLE_XICP); + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + spapr_dt_xics(xics_max_server_number(), fdt, PHANDLE_XICP); + } else { + /* Populate device tree for XIVE */ + spapr_xive_populate(spapr, xics_max_server_number(), fdt, PHANDLE_XICP); + } ret = spapr_populate_memory(spapr, fdt); if (ret < 0) { diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index be22a6b2895f..e2a1665beee9 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1646,6 +1646,12 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu, (spapr_h_cas_compose_response(spapr, args[1], args[2], ov5_updates) != 0); } + + /* We need to rebuild the device tree for XIVE, generate a reset */ + if (!spapr->cas_reboot) { + spapr->cas_reboot = spapr_ovec_test(ov5_updates, OV5_XIVE_EXPLOIT); + } + spapr_ovec_cleanup(ov5_updates); if (spapr->cas_reboot) { diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 3f822220647f..f6d4bf26e06a 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -82,5 +82,7 @@ void spapr_xive_icp_pic_print_info(sPAPRXiveICP *xicp, Monitor *mon); typedef struct sPAPRMachineState sPAPRMachineState; void spapr_xive_hcall_init(sPAPRMachineState *spapr); +void spapr_xive_populate(sPAPRMachineState *spapr, int nr_servers, void *fdt, + uint32_t phandle); #endif /* PPC_SPAPR_XIVE_H */ From patchwork Thu Nov 23 13:29:51 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: 840775 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjLCK220mz9s72 for ; Fri, 24 Nov 2017 00:44:13 +1100 (AEDT) Received: from localhost ([::1]:44429 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrnX-0004SY-BA for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:44:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40034) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrca-0002Kh-6f for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrcW-0003RQ-8Y for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:52 -0500 Received: from 12.mo3.mail-out.ovh.net ([188.165.41.191]:45348) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrcW-0003QO-2i for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:48 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id AA5FF171BED for ; Thu, 23 Nov 2017 14:32:46 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 7DE152E0096; Thu, 23 Nov 2017 14:32:41 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:51 +0100 Message-Id: <20171123132955.1261-22-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14843301424967027539 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.41.191 Subject: [Qemu-devel] [PATCH 21/25] spapr: introduce a helper to map the XIVE memory regions 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" When the XIVE interrupt mode is activated, the machine needs to expose to the guest the MMIO regions use by the controller : - Event State Buffer (ESB) - Thread Interrupt Management Area (TIMA) Migration will also need to reflect the current interrupt mode in use. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive_hcall.c | 14 ++++++++++++++ hw/ppc/spapr.c | 5 +++++ include/hw/ppc/spapr_xive.h | 1 + 3 files changed, 20 insertions(+) diff --git a/hw/intc/spapr_xive_hcall.c b/hw/intc/spapr_xive_hcall.c index 60c6c9f4be8f..ba217144878e 100644 --- a/hw/intc/spapr_xive_hcall.c +++ b/hw/intc/spapr_xive_hcall.c @@ -933,3 +933,17 @@ void spapr_xive_populate(sPAPRMachineState *spapr, int nr_servers, _FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities", plat_res_int_priorities, sizeof(plat_res_int_priorities))); } + +void spapr_xive_mmio_map(sPAPRMachineState *spapr) +{ + sPAPRXive *xive = spapr->xive; + + /* ESBs */ + sysbus_mmio_map(SYS_BUS_DEVICE(xive), 0, xive->esb_base); + + /* Thread Management Interrupt Areas */ + /* TODO: Only map the OS TIMA for the moment. Mapping the whole + * region needs some rework in the handlers */ + sysbus_mmio_map(SYS_BUS_DEVICE(xive), 1, + xive->tm_base + (1 << xive->tm_shift)); +} diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 3a62369883cc..734706c18cb3 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1132,6 +1132,7 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr, } else { /* Populate device tree for XIVE */ spapr_xive_populate(spapr, xics_max_server_number(), fdt, PHANDLE_XICP); + spapr_xive_mmio_map(spapr); } ret = spapr_populate_memory(spapr, fdt); @@ -1613,6 +1614,10 @@ static int spapr_post_load(void *opaque, int version_id) } } + if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + spapr_xive_mmio_map(spapr); + } + return err; } diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index f6d4bf26e06a..88355f7eb643 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -84,5 +84,6 @@ typedef struct sPAPRMachineState sPAPRMachineState; void spapr_xive_hcall_init(sPAPRMachineState *spapr); void spapr_xive_populate(sPAPRMachineState *spapr, int nr_servers, void *fdt, uint32_t phandle); +void spapr_xive_mmio_map(sPAPRMachineState *spapr); #endif /* PPC_SPAPR_XIVE_H */ From patchwork Thu Nov 23 13:29:52 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: 840788 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjLM72XV3z9s76 for ; Fri, 24 Nov 2017 00:50:59 +1100 (AEDT) Received: from localhost ([::1]:44473 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHru5-0001L5-EQ for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:50:57 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40118) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrce-0002PH-7T for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrcb-0003Wk-2Y for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:56 -0500 Received: from 11.mo3.mail-out.ovh.net ([87.98.184.158]:33621) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrca-0003Vf-TX for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:53 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id D4CA7175B10 for ; Thu, 23 Nov 2017 14:32:51 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id A69F52E008E; Thu, 23 Nov 2017 14:32:46 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:52 +0100 Message-Id: <20171123132955.1261-23-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14844708799453498195 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.184.158 Subject: [Qemu-devel] [PATCH 22/25] spapr: add XIVE support to spapr_irq_get_qirq() 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The XIVE object has its own set of qirqs which is to be used when the XIVE interrupt mode is activated. Signed-off-by: Cédric Le Goater --- hw/ppc/spapr.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 734706c18cb3..a91ec1c0751a 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3746,8 +3746,12 @@ qemu_irq spapr_irq_get_qirq(sPAPRMachineState *spapr, int irq) { ICSState *ics = spapr->ics; - if (ics_valid_irq(ics, irq)) { - return ics->qirqs[irq - ics->offset]; + if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return spapr->xive->qirqs[irq]; + } else { + if (ics_valid_irq(ics, irq)) { + return ics->qirqs[irq - ics->offset]; + } } return NULL; From patchwork Thu Nov 23 13:29:53 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: 840777 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjLFl4hXpz9s72 for ; Fri, 24 Nov 2017 00:46:19 +1100 (AEDT) Received: from localhost ([::1]:44445 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrpZ-0006Bz-Ms for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:46:17 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40228) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrcj-0002TV-Of for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:33:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrcg-0003cD-IZ for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:33:01 -0500 Received: from 14.mo3.mail-out.ovh.net ([188.165.43.98]:41950) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrcg-0003bT-CF for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:32:58 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 06667175B19 for ; Thu, 23 Nov 2017 14:32:57 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id CEC572E0096; Thu, 23 Nov 2017 14:32:51 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:53 +0100 Message-Id: <20171123132955.1261-24-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14846116172624530259 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.43.98 Subject: [Qemu-devel] [PATCH 23/25] spapr: toggle the ICP depending on the selected interrupt mode 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Each interrupt mode has its own specific interrupt presenter object, that we store under the CPU object, one for XICS and one for XIVE. The active presenter, corresponding to the current interrupt mode, is simply selected with a lookup on the children of the CPU. Migration and CPU hotplug also need to reflect the current interrupt mode in use. Signed-off-by: Cédric Le Goater --- hw/ppc/spapr.c | 21 ++++++++++++++++++++- hw/ppc/spapr_cpu_core.c | 31 +++++++++++++++++++++++++++++++ include/hw/ppc/spapr_cpu_core.h | 1 + 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index a91ec1c0751a..b7389dbdf5ca 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1128,8 +1128,10 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr, /* /interrupt controller */ if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + spapr_cpu_core_set_icp(spapr->icp_type); spapr_dt_xics(xics_max_server_number(), fdt, PHANDLE_XICP); } else { + spapr_cpu_core_set_icp(TYPE_SPAPR_XIVE_ICP); /* Populate device tree for XIVE */ spapr_xive_populate(spapr, xics_max_server_number(), fdt, PHANDLE_XICP); spapr_xive_mmio_map(spapr); @@ -1615,6 +1617,7 @@ static int spapr_post_load(void *opaque, int version_id) } if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + spapr_cpu_core_set_icp(TYPE_SPAPR_XIVE_ICP); spapr_xive_mmio_map(spapr); } @@ -3610,7 +3613,7 @@ static ICPState *spapr_icp_get(XICSFabric *xi, int vcpu_id) Object *spapr_icp_create(sPAPRMachineState *spapr, CPUState *cs, Error **errp) { Error *local_err = NULL; - Object *obj; + Object *obj, *obj_xive; obj = icp_create(cs, spapr->icp_type, XICS_FABRIC(spapr), &local_err); if (local_err) { @@ -3618,6 +3621,22 @@ Object *spapr_icp_create(sPAPRMachineState *spapr, CPUState *cs, Error **errp) return NULL; } + /* Add a XIVE interrupt presenter. The machine will switch the CPU + * ICP depending on the interrupt model negotiated at CAS time. + */ + obj_xive = icp_create(cs, TYPE_SPAPR_XIVE_ICP, XICS_FABRIC(spapr), + &local_err); + if (local_err) { + object_unparent(obj); + error_propagate(errp, local_err); + return NULL; + } + + /* when hotplugged, the CPU should have the correct ICP */ + if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return obj_xive; + } + return obj; } diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 61a9850e688b..b0e39270f262 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -257,3 +257,34 @@ static const TypeInfo spapr_cpu_core_type_infos[] = { }; DEFINE_TYPES(spapr_cpu_core_type_infos) + +typedef struct ForeachFindICPArgs { + const char *icp_type; + Object *icp; +} ForeachFindICPArgs; + +static int spapr_cpu_core_find_icp(Object *child, void *opaque) +{ + ForeachFindICPArgs *args = opaque; + + if (object_dynamic_cast(child, args->icp_type)) { + args->icp = child; + } + + return args->icp != NULL; +} + +void spapr_cpu_core_set_icp(const char *icp_type) +{ + CPUState *cs; + + CPU_FOREACH(cs) { + ForeachFindICPArgs args = { icp_type, NULL }; + PowerPCCPU *cpu = POWERPC_CPU(cs); + + object_child_foreach(OBJECT(cs), spapr_cpu_core_find_icp, &args); + g_assert(args.icp); + + cpu->intc = args.icp; + } +} diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h index f2d48d6a6786..a657dfb8863c 100644 --- a/include/hw/ppc/spapr_cpu_core.h +++ b/include/hw/ppc/spapr_cpu_core.h @@ -38,4 +38,5 @@ typedef struct sPAPRCPUCoreClass { } sPAPRCPUCoreClass; const char *spapr_get_cpu_core_type(const char *cpu_type); +void spapr_cpu_core_set_icp(const char *icp_type); #endif From patchwork Thu Nov 23 13:29:54 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: 840791 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjLRg5G21z9s5L for ; Fri, 24 Nov 2017 00:54:55 +1100 (AEDT) Received: from localhost ([::1]:44500 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrxt-0004UZ-PL for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:54:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40361) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrcr-0002Ys-6h for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:33:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrcl-0003is-FL for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:33:09 -0500 Received: from 6.mo3.mail-out.ovh.net ([188.165.43.173]:45105) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrcl-0003hX-9L for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:33:03 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 3198E175B24 for ; Thu, 23 Nov 2017 14:33:02 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 02BC02E008A; Thu, 23 Nov 2017 14:32:56 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:54 +0100 Message-Id: <20171123132955.1261-25-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14847805023152540499 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.43.173 Subject: [Qemu-devel] [PATCH 24/25] spapr: add support to dump XIVE information 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Modify the InterruptStatsProvider output to reflect the interrupt mode currently in use by the machine. Signed-off-by: Cédric Le Goater --- hw/ppc/spapr.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index b7389dbdf5ca..9fe3a9966b12 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3785,10 +3785,18 @@ static void spapr_pic_print_info(InterruptStatsProvider *obj, CPU_FOREACH(cs) { PowerPCCPU *cpu = POWERPC_CPU(cs); - icp_pic_print_info(ICP(cpu->intc), mon); + if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + spapr_xive_icp_pic_print_info(SPAPR_XIVE_ICP(cpu->intc), mon); + } else { + icp_pic_print_info(ICP(cpu->intc), mon); + } } - ics_pic_print_info(spapr->ics, mon); + if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + spapr_xive_pic_print_info(spapr->xive, mon); + } else { + ics_pic_print_info(spapr->ics, mon); + } } int spapr_vcpu_id(PowerPCCPU *cpu) From patchwork Thu Nov 23 13:29:55 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: 840782 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3yjLJW3PlWz9sNd for ; Fri, 24 Nov 2017 00:48:43 +1100 (AEDT) Received: from localhost ([::1]:44461 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrrt-0007zh-Em for incoming@patchwork.ozlabs.org; Thu, 23 Nov 2017 08:48:41 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40580) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrd0-0002gs-GF for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:33:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrcq-0003wD-Ps for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:33:18 -0500 Received: from 19.mo3.mail-out.ovh.net ([178.32.98.231]:39273) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrcq-0003ti-Hc for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:33:08 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id 59DE9175B34 for ; Thu, 23 Nov 2017 14:33:07 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 2ACBE2E0093; Thu, 23 Nov 2017 14:33:02 +0100 (CET) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:55 +0100 Message-Id: <20171123132955.1261-26-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14849212396795235155 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 178.32.98.231 Subject: [Qemu-devel] [PATCH 25/25] spapr: advertise XIVE exploitation mode in CAS 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: =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" We introduce a 'xive_exploitation' boolean at the machine level to enable the XIVE interrupt mode for newer machines and to disable it on older ones. The XIVE interrupt mode can still be forced on the command line with a machine option. That might be a bit dangerous. To be discussed. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 10 ++++++---- hw/ppc/spapr.c | 52 +++++++++++++++++++++++++++++++++++++++++++++----- include/hw/ppc/spapr.h | 1 + 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index b732aaf4f8ba..f7fab70cb8bb 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -736,8 +736,9 @@ static const VMStateDescription vmstate_spapr_xive_ive = { static bool vmstate_spapr_xive_needed(void *opaque) { - /* TODO check machine XIVE support */ - return true; + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); + + return spapr->xive_exploitation; } static const VMStateDescription vmstate_spapr_xive = { @@ -863,8 +864,9 @@ static const VMStateDescription vmstate_spapr_xive_icp_eq = { static bool vmstate_spapr_xive_icp_needed(void *opaque) { - /* TODO check machine XIVE support */ - return true; + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); + + return spapr->xive_exploitation; } static const VMStateDescription vmstate_spapr_xive_icp = { diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 9fe3a9966b12..d3a4b1f8f6f9 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -961,10 +961,11 @@ static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt) spapr_dt_rtas_tokens(fdt, rtas); } -/* Prepare ibm,arch-vec-5-platform-support, which indicates the MMU features - * that the guest may request and thus the valid values for bytes 24..26 of - * option vector 5: */ -static void spapr_dt_ov5_platform_support(void *fdt, int chosen) +/* Prepare ibm,arch-vec-5-platform-support, which indicates the MMU + * and the XIVE features that the guest may request and thus the valid + * values for bytes 23..26 of option vector 5: */ +static void spapr_dt_ov5_platform_support(sPAPRMachineState *spapr, void *fdt, + int chosen) { PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu); @@ -987,7 +988,16 @@ static void spapr_dt_ov5_platform_support(void *fdt, int chosen) } else { val[3] = 0x00; /* Hash */ } + /* TODO: introduce a kvmppc_has_cap_xive() ? Works with + * irqchip=off for now + */ + if (spapr->xive_exploitation) { + val[1] = 0x80; /* OV5_XIVE_BOTH */ + } } else { + if (spapr->xive_exploitation) { + val[1] = 0x80; /* OV5_XIVE_BOTH */ + } /* V3 MMU supports both hash and radix in tcg (with dynamic switching) */ val[3] = 0xC0; } @@ -1048,7 +1058,7 @@ static void spapr_dt_chosen(sPAPRMachineState *spapr, void *fdt) _FDT(fdt_setprop_string(fdt, chosen, "linux,stdout-path", stdout_path)); } - spapr_dt_ov5_platform_support(fdt, chosen); + spapr_dt_ov5_platform_support(spapr, fdt, chosen); g_free(stdout_path); g_free(bootlist); @@ -2441,6 +2451,11 @@ static void ppc_spapr_init(MachineState *machine) spapr_ovec_set(spapr->ov5, OV5_HPT_RESIZE); } + /* advertise XIVE if not disabled by the user */ + if (spapr->xive_exploitation) { + spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT); + } + /* init CPUs */ spapr_set_vsmt_mode(spapr, &error_fatal); @@ -2840,6 +2855,21 @@ static void spapr_set_vsmt(Object *obj, Visitor *v, const char *name, visit_type_uint32(v, name, (uint32_t *)opaque, errp); } +static bool spapr_get_xive_exploitation(Object *obj, Error **errp) +{ + sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + + return spapr->xive_exploitation; +} + +static void spapr_set_xive_exploitation(Object *obj, bool value, + Error **errp) +{ + sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + + spapr->xive_exploitation = value; +} + static void spapr_machine_initfn(Object *obj) { sPAPRMachineState *spapr = SPAPR_MACHINE(obj); @@ -2875,6 +2905,15 @@ static void spapr_machine_initfn(Object *obj) object_property_set_description(obj, "vsmt", "Virtual SMT: KVM behaves as if this were" " the host's SMT mode", &error_abort); + + spapr->xive_exploitation = true; + object_property_add_bool(obj, "xive-exploitation", + spapr_get_xive_exploitation, + spapr_set_xive_exploitation, + NULL); + object_property_set_description(obj, "xive-exploitation", + "XIVE exploitation mode POWER9", + NULL); } static void spapr_machine_finalizefn(Object *obj) @@ -3956,7 +3995,10 @@ DEFINE_SPAPR_MACHINE(2_12, "2.12", true); static void spapr_machine_2_11_instance_options(MachineState *machine) { + sPAPRMachineState *spapr = SPAPR_MACHINE(machine); + spapr_machine_2_12_instance_options(machine); + spapr->xive_exploitation = false; } static void spapr_machine_2_11_class_options(MachineClass *mc) diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index a25e218b34e2..c4f051f974fe 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -129,6 +129,7 @@ struct sPAPRMachineState { const char *icp_type; sPAPRXive *xive; + bool xive_exploitation; }; #define H_SUCCESS 0