From patchwork Mon Sep 11 17:12:15 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: 812451 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 3xrZJw57pBz9s83 for ; Tue, 12 Sep 2017 03:13:52 +1000 (AEST) Received: from localhost ([::1]:59253 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSHO-0000D6-Kq for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:13:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34584) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSGc-00006f-1S for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSGX-0003jA-Rr for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:02 -0400 Received: from 2.mo2.mail-out.ovh.net ([188.165.53.149]:59556) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSGX-0003ib-IB for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:12:57 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id EDECEA4C3C for ; Mon, 11 Sep 2017 19:12:55 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id BD0BE3C006C; Mon, 11 Sep 2017 19:12:48 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:15 +0200 Message-Id: <20170911171235.29331-2-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14129762359865412435 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.53.149 Subject: [Qemu-devel] [RFC PATCH v2 01/21] ppc/xive: introduce a skeleton for the sPAPR 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" Start with a couple of attributes for the XIVE sPAPR controller model. The number of provisionned IRQ is necessary to size the different internal XIVE tables, the number of CPUs is also. Signed-off-by: Cédric Le Goater --- default-configs/ppc64-softmmu.mak | 1 + hw/intc/Makefile.objs | 1 + hw/intc/spapr_xive.c | 76 +++++++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr_xive.h | 37 +++++++++++++++++++ 4 files changed, 115 insertions(+) create mode 100644 hw/intc/spapr_xive.c create mode 100644 include/hw/ppc/spapr_xive.h diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak index 46c95993217d..8294df31c0f5 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=$(and $(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 78426a7dafcd..2dae80bdf611 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..c83796519586 --- /dev/null +++ b/hw/intc/spapr_xive.c @@ -0,0 +1,76 @@ +/* + * 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/xics.h" +#include "hw/ppc/spapr_xive.h" + + +/* + * Main XIVE object + */ + +static void spapr_xive_realize(DeviceState *dev, Error **errp) +{ + sPAPRXive *xive = SPAPR_XIVE(dev); + + if (!xive->nr_targets) { + error_setg(errp, "Number of interrupt targets needs to be greater 0"); + return; + } + + /* We need to be able to allocate at least the IPIs */ + if (!xive->nr_irqs || xive->nr_irqs < xive->nr_targets) { + error_setg(errp, "Number of interrupts too small"); + return; + } +} + +static Property spapr_xive_properties[] = { + DEFINE_PROP_UINT32("nr-irqs", sPAPRXive, nr_irqs, 0), + DEFINE_PROP_UINT32("nr-targets", sPAPRXive, nr_targets, 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"; +} + +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) diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h new file mode 100644 index 000000000000..5b99f7fc2b81 --- /dev/null +++ b/include/hw/ppc/spapr_xive.h @@ -0,0 +1,37 @@ +/* + * 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; + +#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_targets; + uint32_t nr_irqs; +}; + +#endif /* PPC_SPAPR_XIVE_H */ From patchwork Mon Sep 11 17:12:16 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: 812456 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 3xrZMk0JBdz9s83 for ; Tue, 12 Sep 2017 03:16:18 +1000 (AEST) Received: from localhost ([::1]:59273 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSJj-0002bM-UA for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:16:15 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34656) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSGj-0000Dn-5Z for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSGe-0003mD-LI for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:09 -0400 Received: from 5.mo2.mail-out.ovh.net ([87.98.181.248]:52012) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSGe-0003ll-F4 for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:04 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 2C8CDAACCD for ; Mon, 11 Sep 2017 19:13:03 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id EC69F3C0072; Mon, 11 Sep 2017 19:12:55 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:16 +0200 Message-Id: <20170911171235.29331-3-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14132014156361665363 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.181.248 Subject: [Qemu-devel] [RFC PATCH v2 02/21] 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" This is needed to migrate the state of the internal tables of the XIVE object. 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 85e43da56868..4dfb1bf84b5e 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 Mon Sep 11 17:12:17 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: 812452 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 3xrZKT3YLWz9sBd for ; Tue, 12 Sep 2017 03:14:21 +1000 (AEST) Received: from localhost ([::1]:59259 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSHr-0000id-GE for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:14:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34675) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSGn-0000J2-H1 for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSGl-0003oH-KC for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:13 -0400 Received: from 4.mo2.mail-out.ovh.net ([87.98.172.75]:33139) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSGl-0003o6-AW for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:11 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 56E7BAA3B5 for ; Mon, 11 Sep 2017 19:13:10 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id 27CBF3C0072; Mon, 11 Sep 2017 19:13:03 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:17 +0200 Message-Id: <20170911171235.29331-4-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14133984482916272979 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.172.75 Subject: [Qemu-devel] [RFC PATCH v2 03/21] ppc/xive: define the XIVE internal tables 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 of the POWER9 uses a set of tables to redirect exception from event sources to CPU threads. Among which we choose to model : - the State Bit Entries (SBE), also known as Event State Buffer (ESB). This is a two bit state machine for each event source which is used to trigger events. The bits are named "P" (pending) and "Q" (queued) and can be controlled by MMIO. - the Interrupt Virtualization Entry (IVE) table, also known as Event Assignment Structure (EAS). This table is indexed by the IRQ number and is looked up to find the Event Queue associated with a triggered event. - the Event Queue Descriptor (EQD) table, also known as Event Notification Descriptor (END). The EQD contains fields that specify the Event Queue on which event data is posted (and later pulled by the OS) and also a target (or VPD) to notify. An additional table was not modeled but we might need to support the H_INT_SET_OS_REPORTING_LINE hcall: - the Virtual Processor Descriptor (VPD) table, also known as Notification Virtual Target (NVT). The XIVE object is expanded with the tables described above. The size of each table depends on the number of provisioned IRQ and the maximum number of CPUs in the system. The indexing is very basic and might need to be improved for the EQs. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 108 ++++++++++++++++++++++++++++++++++++++++++++ hw/intc/xive-internal.h | 105 ++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr_xive.h | 9 ++++ 3 files changed, 222 insertions(+) create mode 100644 hw/intc/xive-internal.h diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index c83796519586..6d98528fae68 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -25,11 +25,34 @@ #include "hw/ppc/xics.h" #include "hw/ppc/spapr_xive.h" +#include "xive-internal.h" /* * Main XIVE object */ +void spapr_xive_reset(void *dev) +{ + sPAPRXive *xive = SPAPR_XIVE(dev); + int i; + + /* SBEs are initialized to 0b01 which corresponds to "ints off" */ + memset(xive->sbe, 0x55, xive->sbe_size); + + /* Validate all available IVEs in the IRQ number space. It would + * be more correct to validate only the allocated IRQs but this + * would require some callback routine from the spapr machine into + * XIVE. To be done later. + */ + for (i = 0; i < xive->nr_irqs; i++) { + XiveIVE *ive = &xive->ivt[i]; + ive->w = IVE_VALID | IVE_MASKED; + } + + /* clear all EQs */ + memset(xive->eqt, 0, xive->nr_eqs * sizeof(XiveEQ)); +} + static void spapr_xive_realize(DeviceState *dev, Error **errp) { sPAPRXive *xive = SPAPR_XIVE(dev); @@ -44,8 +67,64 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp) error_setg(errp, "Number of interrupts too small"); return; } + + /* 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); + + /* Allocate the IVT (Interrupt Virtualization Table) */ + xive->ivt = g_malloc0(xive->nr_irqs * sizeof(XiveIVE)); + + /* Allocate the EQDT (Event Queue Descriptor Table), 8 priorities + * for each thread in the system */ + xive->nr_eqs = xive->nr_targets * XIVE_EQ_PRIORITY_COUNT; + xive->eqt = g_malloc0(xive->nr_eqs * sizeof(XiveEQ)); + + qemu_register_reset(spapr_xive_reset, dev); } +static const VMStateDescription vmstate_spapr_xive_ive = { + .name = "xive/ive", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField []) { + VMSTATE_UINT64(w, XiveIVE), + VMSTATE_END_OF_LIST() + }, +}; + +static const VMStateDescription vmstate_spapr_xive_eq = { + .name = "xive/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 const VMStateDescription vmstate_xive = { + .name = "xive", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_VARRAY_UINT32_ALLOC(sbe, sPAPRXive, sbe_size, 0, + vmstate_info_uint8, uint8_t), + VMSTATE_STRUCT_VARRAY_UINT32_ALLOC(ivt, sPAPRXive, nr_irqs, 0, + vmstate_spapr_xive_ive, XiveIVE), + VMSTATE_STRUCT_VARRAY_UINT32_ALLOC(eqt, sPAPRXive, nr_eqs, 0, + vmstate_spapr_xive_eq, XiveEQ), + VMSTATE_END_OF_LIST() + }, +}; + static Property spapr_xive_properties[] = { DEFINE_PROP_UINT32("nr-irqs", sPAPRXive, nr_irqs, 0), DEFINE_PROP_UINT32("nr-targets", sPAPRXive, nr_targets, 0), @@ -59,6 +138,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data) dc->realize = spapr_xive_realize; dc->props = spapr_xive_properties; dc->desc = "sPAPR XIVE interrupt controller"; + dc->vmsd = &vmstate_xive; } static const TypeInfo spapr_xive_info = { @@ -74,3 +154,31 @@ static void spapr_xive_register_types(void) } type_init(spapr_xive_register_types) + +XiveIVE *spapr_xive_get_ive(sPAPRXive *xive, uint32_t idx) +{ + return idx < xive->nr_irqs ? &xive->ivt[idx] : NULL; +} + +XiveEQ *spapr_xive_get_eq(sPAPRXive *xive, uint32_t idx) +{ + return idx < xive->nr_eqs ? &xive->eqt[idx] : NULL; +} + +/* TODO: improve EQ indexing. This is very simple and relies on the + * fact that target (CPU) numbers start at 0 and are contiguous. It + * should be OK for sPAPR. + */ +bool spapr_xive_eq_for_target(sPAPRXive *xive, uint32_t target, + uint8_t priority, uint32_t *out_eq_idx) +{ + if (priority > XIVE_PRIORITY_MAX || target >= xive->nr_targets) { + return false; + } + + if (out_eq_idx) { + *out_eq_idx = target + priority; + } + + return true; +} diff --git a/hw/intc/xive-internal.h b/hw/intc/xive-internal.h new file mode 100644 index 000000000000..95184bad5c1d --- /dev/null +++ b/hw/intc/xive-internal.h @@ -0,0 +1,105 @@ +/* + * 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; + +/* 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_EQ_PRIORITY_COUNT 8 +#define XIVE_PRIORITY_MAX (XIVE_EQ_PRIORITY_COUNT - 1) + +void spapr_xive_reset(void *dev); +XiveIVE *spapr_xive_get_ive(sPAPRXive *xive, uint32_t isn); +XiveEQ *spapr_xive_get_eq(sPAPRXive *xive, uint32_t idx); + +bool spapr_xive_eq_for_target(sPAPRXive *xive, uint32_t target, uint8_t prio, + uint32_t *out_eq_idx); + + +#endif /* _INTC_XIVE_INTERNAL_H */ diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 5b99f7fc2b81..b17dd4f17b0b 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -22,6 +22,8 @@ #include typedef struct sPAPRXive sPAPRXive; +typedef struct XiveIVE XiveIVE; +typedef struct XiveEQ XiveEQ; #define TYPE_SPAPR_XIVE "spapr-xive" #define SPAPR_XIVE(obj) OBJECT_CHECK(sPAPRXive, (obj), TYPE_SPAPR_XIVE) @@ -32,6 +34,13 @@ struct sPAPRXive { /* Properties */ uint32_t nr_targets; uint32_t nr_irqs; + + /* XIVE internal tables */ + uint8_t *sbe; + uint32_t sbe_size; + XiveIVE *ivt; + XiveEQ *eqt; + uint32_t nr_eqs; }; #endif /* PPC_SPAPR_XIVE_H */ From patchwork Mon Sep 11 17:12:18 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: 812454 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 3xrZKq6KZmz9s83 for ; Tue, 12 Sep 2017 03:14:39 +1000 (AEST) Received: from localhost ([::1]:59261 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSI9-00011h-Qr for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:14:37 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34740) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSGx-0000UK-61 for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSGs-0003qB-M7 for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:23 -0400 Received: from 6.mo2.mail-out.ovh.net ([87.98.165.38]:40367) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSGs-0003pu-FY for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:18 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 879B7AACCD for ; Mon, 11 Sep 2017 19:13:17 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id 585BE3C007E; Mon, 11 Sep 2017 19:13:10 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:18 +0200 Message-Id: <20170911171235.29331-5-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14135954807111322451 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.165.38 Subject: [Qemu-devel] [RFC PATCH v2 04/21] ppc/xive: provide a link to the sPAPR ICS object under 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" The sPAPR machine first starts with a XICS interrupt model and depending on the guest capabilities, the XIVE exploitation mode is negotiated during CAS. A reset should then be performed to rebuild the device tree but the same IRQ numbers which were allocated by the devices prior to reset, when the XICS model was operating, are still in use. For this purpose, we need a common IRQ number allocator for both the interrupt models: XICS legacy or XIVE exploitation. This is what the ICSIRQState array of the XICS interrupt source is used for. It also contains the LSI/MSI flag of an interrupt which will we need later on. So, let's provide a link to the sPAPR ICS object under XIVE to make use of it. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 12 ++++++++++++ include/hw/ppc/spapr_xive.h | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 6d98528fae68..1681affb0848 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -56,6 +56,8 @@ void spapr_xive_reset(void *dev) static void spapr_xive_realize(DeviceState *dev, Error **errp) { sPAPRXive *xive = SPAPR_XIVE(dev); + Object *obj; + Error *err = NULL; if (!xive->nr_targets) { error_setg(errp, "Number of interrupt targets needs to be greater 0"); @@ -68,6 +70,16 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp) return; } + /* Retrieve SPAPR ICS source to share the IRQ number allocator */ + obj = object_property_get_link(OBJECT(dev), "ics", &err); + if (!obj) { + error_setg(errp, "%s: required link 'ics' not found: %s", + __func__, error_get_pretty(err)); + return; + } + + xive->ics = ICS_BASE(obj); + /* 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 b17dd4f17b0b..29112589b37f 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -24,6 +24,7 @@ typedef struct sPAPRXive sPAPRXive; typedef struct XiveIVE XiveIVE; typedef struct XiveEQ XiveEQ; +typedef struct ICSState ICSState; #define TYPE_SPAPR_XIVE "spapr-xive" #define SPAPR_XIVE(obj) OBJECT_CHECK(sPAPRXive, (obj), TYPE_SPAPR_XIVE) @@ -35,6 +36,9 @@ struct sPAPRXive { uint32_t nr_targets; uint32_t nr_irqs; + /* IRQ */ + ICSState *ics; /* XICS source inherited from the SPAPR machine */ + /* XIVE internal tables */ uint8_t *sbe; uint32_t sbe_size; From patchwork Mon Sep 11 17:12:19 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: 812459 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 3xrZNn6d4Dz9s83 for ; Tue, 12 Sep 2017 03:17:13 +1000 (AEST) Received: from localhost ([::1]:59277 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSKd-0003LD-Hj for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:17:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34823) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSH4-0000eE-Pa for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSGz-0003tt-TT for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:30 -0400 Received: from 1.mo2.mail-out.ovh.net ([46.105.63.121]:53584) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSGz-0003t0-MJ for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:25 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id B9789AB108 for ; Mon, 11 Sep 2017 19:13:24 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id 86D183C006E; Mon, 11 Sep 2017 19:13:17 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:19 +0200 Message-Id: <20170911171235.29331-6-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14137925131950852947 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 46.105.63.121 Subject: [Qemu-devel] [RFC PATCH v2 05/21] ppc/xive: allocate IRQ numbers for the IPIs 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 number of IPIs is deduced from the max number of CPUs the guest supports and the IRQ numbers for the IPIs are allocated from the top of the IRQ number space to reduce conflict with other IRQ numbers allocated by the devices. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 1681affb0848..52c32f588d6d 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -58,6 +58,7 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp) sPAPRXive *xive = SPAPR_XIVE(dev); Object *obj; Error *err = NULL; + int i; if (!xive->nr_targets) { error_setg(errp, "Number of interrupt targets needs to be greater 0"); @@ -80,6 +81,11 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp) xive->ics = ICS_BASE(obj); + /* Allocate the last IRQ numbers for the IPIs */ + for (i = xive->nr_irqs - xive->nr_targets; i < xive->nr_irqs; i++) { + ics_set_irq_type(xive->ics, i, false); + } + /* 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); From patchwork Mon Sep 11 17:12:20 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: 812460 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 3xrZP26brDz9s83 for ; Tue, 12 Sep 2017 03:17:26 +1000 (AEST) Received: from localhost ([::1]:59280 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSKq-0003Xj-UA for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:17:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34922) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSHD-0000mk-Ah for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSH7-0003z8-M0 for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:39 -0400 Received: from 3.mo2.mail-out.ovh.net ([46.105.58.226]:40795) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSH7-0003yW-DC for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:33 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 2337AAB138 for ; Mon, 11 Sep 2017 19:13:32 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id B54D03C006E; Mon, 11 Sep 2017 19:13:24 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:20 +0200 Message-Id: <20170911171235.29331-7-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14140176933383408467 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 46.105.58.226 Subject: [Qemu-devel] [RFC PATCH v2 06/21] ppc/xive: introduce handlers for 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 the ICSIRQState array of the XICS interrupt source to differentiate the MSI from the LSI interrupts. The spapr_xive_irq() routine in charge of triggering the CPU interrupt line will be filled later on. The next patch will introduce the MMIO handlers to interact with XIVE interrupt sources. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr_xive.h | 1 + 2 files changed, 47 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 52c32f588d6d..1ed7b6a286e9 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -27,6 +27,50 @@ #include "xive-internal.h" +static void spapr_xive_irq(sPAPRXive *xive, int srcno) +{ + +} + +/* + * XIVE Interrupt Source + */ +static void spapr_xive_source_set_irq_msi(sPAPRXive *xive, int srcno, int val) +{ + if (val) { + spapr_xive_irq(xive, srcno); + } +} + +static void spapr_xive_source_set_irq_lsi(sPAPRXive *xive, int srcno, int val) +{ + ICSIRQState *irq = &xive->ics->irqs[srcno]; + + if (val) { + irq->status |= XICS_STATUS_ASSERTED; + } else { + irq->status &= ~XICS_STATUS_ASSERTED; + } + + if (irq->status & XICS_STATUS_ASSERTED + && !(irq->status & XICS_STATUS_SENT)) { + irq->status |= XICS_STATUS_SENT; + spapr_xive_irq(xive, srcno); + } +} + +static void spapr_xive_source_set_irq(void *opaque, int srcno, int val) +{ + sPAPRXive *xive = SPAPR_XIVE(opaque); + ICSIRQState *irq = &xive->ics->irqs[srcno]; + + if (irq->flags & XICS_FLAGS_IRQ_LSI) { + spapr_xive_source_set_irq_lsi(xive, srcno, val); + } else { + spapr_xive_source_set_irq_msi(xive, srcno, val); + } +} + /* * Main XIVE object */ @@ -80,6 +124,8 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp) } xive->ics = ICS_BASE(obj); + xive->qirqs = qemu_allocate_irqs(spapr_xive_source_set_irq, xive, + xive->nr_irqs); /* Allocate the last IRQ numbers for the IPIs */ for (i = xive->nr_irqs - xive->nr_targets; i < xive->nr_irqs; i++) { diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 29112589b37f..eab92c4c1bb8 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -38,6 +38,7 @@ struct sPAPRXive { /* IRQ */ ICSState *ics; /* XICS source inherited from the SPAPR machine */ + qemu_irq *qirqs; /* XIVE internal tables */ uint8_t *sbe; From patchwork Mon Sep 11 17:12:21 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: 812466 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 3xrZSM5fldz9s81 for ; Tue, 12 Sep 2017 03:20:19 +1000 (AEST) Received: from localhost ([::1]:59297 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSNd-0005wo-Nb for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:20:17 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35016) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSHJ-0000sW-7U for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSHE-00042k-IC for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:45 -0400 Received: from 7.mo2.mail-out.ovh.net ([188.165.48.182]:49537) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSHE-00041p-9D for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:40 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 54295AB0A1 for ; Mon, 11 Sep 2017 19:13:39 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id 240B93C006C; Mon, 11 Sep 2017 19:13:32 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:21 +0200 Message-Id: <20170911171235.29331-8-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14142147256532831059 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.48.182 Subject: [Qemu-devel] [RFC PATCH v2 07/21] ppc/xive: 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) which is controlled by MMIO 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. For KVM support, we should think of a way to map this QEMU memory region in the host to trigger events directly. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 255 ++++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr_xive.h | 6 ++ 2 files changed, 261 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 1ed7b6a286e9..8a85d64efc4c 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -33,6 +33,218 @@ static void spapr_xive_irq(sPAPRXive *xive, int srcno) } /* + * "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 idx) +{ + uint32_t byte = idx / 4; + uint32_t bit = (idx % 4) * 2; + + assert(byte < xive->sbe_size); + + return (xive->sbe[byte] >> bit) & 0x3; +} + +static uint8_t spapr_xive_pq_set(sPAPRXive *xive, uint32_t idx, uint8_t pq) +{ + uint32_t byte = idx / 4; + uint32_t bit = (idx % 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 srcno) +{ + uint8_t old_pq = spapr_xive_pq_get(xive, srcno); + + switch (old_pq) { + case XIVE_ESB_RESET: + spapr_xive_pq_set(xive, srcno, XIVE_ESB_RESET); + return false; + case XIVE_ESB_PENDING: + spapr_xive_pq_set(xive, srcno, XIVE_ESB_RESET); + return false; + case XIVE_ESB_QUEUED: + spapr_xive_pq_set(xive, srcno, XIVE_ESB_PENDING); + return true; + case XIVE_ESB_OFF: + spapr_xive_pq_set(xive, srcno, XIVE_ESB_OFF); + return false; + default: + g_assert_not_reached(); + } +} + +static bool spapr_xive_pq_trigger(sPAPRXive *xive, uint32_t srcno) +{ + uint8_t old_pq = spapr_xive_pq_get(xive, srcno); + + switch (old_pq) { + case XIVE_ESB_RESET: + spapr_xive_pq_set(xive, srcno, XIVE_ESB_PENDING); + return true; + case XIVE_ESB_PENDING: + spapr_xive_pq_set(xive, srcno, XIVE_ESB_QUEUED); + return true; + case XIVE_ESB_QUEUED: + spapr_xive_pq_set(xive, srcno, XIVE_ESB_QUEUED); + return true; + case XIVE_ESB_OFF: + spapr_xive_pq_set(xive, srcno, XIVE_ESB_OFF); + return false; + default: + g_assert_not_reached(); + } +} + +/* + * XIVE Interrupt Source MMIOs + */ +static void spapr_xive_source_eoi(sPAPRXive *xive, uint32_t srcno) +{ + ICSIRQState *irq = &xive->ics->irqs[srcno]; + + if (irq->flags & XICS_FLAGS_IRQ_LSI) { + irq->status &= ~XICS_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 srcno = addr >> xive->esb_shift; + XiveIVE *ive; + uint64_t ret = -1; + + ive = spapr_xive_get_ive(xive, srcno); + if (!ive || !(ive->w & IVE_VALID)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid LISN %d\n", srcno); + goto out; + } + + switch (offset) { + case 0: + spapr_xive_source_eoi(xive, srcno); + + /* return TRUE or FALSE depending on PQ value */ + ret = spapr_xive_pq_eoi(xive, srcno); + break; + + case XIVE_ESB_GET: + ret = spapr_xive_pq_get(xive, srcno); + 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, srcno, (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 srcno = addr >> xive->esb_shift; + XiveIVE *ive; + bool notify = false; + + ive = spapr_xive_get_ive(xive, srcno); + if (!ive || !(ive->w & IVE_VALID)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid LISN %d\n", srcno); + return; + } + + switch (offset) { + case 0: + /* TODO: should we trigger even if the IVE is masked ? */ + notify = spapr_xive_pq_trigger(xive, srcno); + 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[srcno]); + } +} + +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 srcno, int val) @@ -74,6 +286,33 @@ static void spapr_xive_source_set_irq(void *opaque, int srcno, 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_reset(void *dev) { @@ -144,6 +383,22 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp) xive->nr_eqs = xive->nr_targets * XIVE_EQ_PRIORITY_COUNT; xive->eqt = g_malloc0(xive->nr_eqs * sizeof(XiveEQ)); + /* 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); } diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index eab92c4c1bb8..0f516534d76a 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -46,6 +46,12 @@ struct sPAPRXive { XiveIVE *ivt; XiveEQ *eqt; uint32_t nr_eqs; + + /* ESB memory region */ + uint32_t esb_shift; + hwaddr esb_base; + MemoryRegion esb_mr; + MemoryRegion esb_iomem; }; #endif /* PPC_SPAPR_XIVE_H */ From patchwork Mon Sep 11 17:12:22 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: 812464 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 3xrZRM39Kpz9s81 for ; Tue, 12 Sep 2017 03:19:27 +1000 (AEST) Received: from localhost ([::1]:59294 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSMn-0005HA-Dk for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:19:25 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35112) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSHQ-0000zG-Is for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSHL-00048K-Kr for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:52 -0400 Received: from 2.mo2.mail-out.ovh.net ([188.165.53.149]:38889) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSHL-00047l-Ez for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:47 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 835E3AB087 for ; Mon, 11 Sep 2017 19:13:46 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id 53DFF3C006C; Mon, 11 Sep 2017 19:13:39 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:22 +0200 Message-Id: <20170911171235.29331-9-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14144117580534418259 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.53.149 Subject: [Qemu-devel] [RFC PATCH v2 08/21] ppc/xive: 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 PAPR 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 XICS_FLAGS_IRQ_LSI flag of the ICSIRQState array when needed. 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 8a85d64efc4c..a1ce993d2afa 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -371,6 +371,10 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp) ics_set_irq_type(xive->ics, i, false); } + /* 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 0f516534d76a..b46e59319236 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -40,6 +40,13 @@ struct sPAPRXive { ICSState *ics; /* XICS source inherited from the SPAPR machine */ qemu_irq *qirqs; + /* 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 */ uint8_t *sbe; uint32_t sbe_size; From patchwork Mon Sep 11 17:12:23 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: 812469 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 3xrZWl0NZ7z9s81 for ; Tue, 12 Sep 2017 03:23:14 +1000 (AEST) Received: from localhost ([::1]:59316 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSQT-0000B0-3H for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:23:13 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35196) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSHX-00016I-Gz for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSHT-0004EK-0B for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:59 -0400 Received: from 3.mo2.mail-out.ovh.net ([46.105.58.226]:46402) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSHS-0004DT-Pf for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:54 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id B5090AB1DC for ; Mon, 11 Sep 2017 19:13:53 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id 835F63C006E; Mon, 11 Sep 2017 19:13:46 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:23 +0200 Message-Id: <20170911171235.29331-10-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14146087907405499219 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 46.105.58.226 Subject: [Qemu-devel] [RFC PATCH v2 09/21] ppc/xive: extend the interrupt presenter model for 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" The XIVE interrupt presenter exposes a set of Thread Interrupt Management Areas, also called rings, one per different level of privilege (four in all). This area is used to handle priority management and interrupt acknowledgment among other things. We extend the ICPState object with a cache of the register data for XIVE. The integration with the sPAPR machine is much easier and we need a common framework to switch from one controller model to another: XICS <-> XIVE. The next patch will introduce the MMIO handlers to interact with the TIMA, OS only, which is required for the sPAPR support. Signed-off-by: Cédric Le Goater --- hw/intc/xics.c | 4 ++++ include/hw/ppc/xics.h | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index a84ba51ad8ff..927d4fec966a 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -274,6 +274,7 @@ static const VMStateDescription vmstate_icp_server = { VMSTATE_UINT32(xirr, ICPState), VMSTATE_UINT8(pending_priority, ICPState), VMSTATE_UINT8(mfrr, ICPState), + VMSTATE_UINT8_ARRAY(tima, ICPState, 0x40), VMSTATE_END_OF_LIST() }, }; @@ -293,6 +294,7 @@ static void icp_reset(void *dev) if (icpc->reset) { icpc->reset(icp); } + memset(icp->tima, 0, sizeof(icp->tima)); } static void icp_realize(DeviceState *dev, Error **errp) @@ -343,6 +345,8 @@ static void icp_realize(DeviceState *dev, Error **errp) icpc->realize(icp, errp); } + icp->tima_os = &icp->tima[0x10]; + qemu_register_reset(icp_reset, dev); vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server, icp); } diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index 28d248abad61..c835997303c4 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -83,6 +83,12 @@ struct ICPState { qemu_irq output; XICSFabric *xics; + + /* XIVE section */ +#define XIVE_TM_RING_COUNT 4 + + uint8_t tima[XIVE_TM_RING_COUNT * 0x10]; + uint8_t *tima_os; }; #define ICP_PROP_XICS "xics" From patchwork Mon Sep 11 17:12:24 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: 812467 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 3xrZSs09qsz9s83 for ; Tue, 12 Sep 2017 03:20:45 +1000 (AEST) Received: from localhost ([::1]:59300 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSO3-0006GG-1Z for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:20:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35260) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSHe-0001DJ-Hg for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSHa-0004Lt-4x for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:06 -0400 Received: from 8.mo2.mail-out.ovh.net ([188.165.52.147]:44991) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSHZ-0004Kf-Rt for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:02 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id DFC8FAB108 for ; Mon, 11 Sep 2017 19:14:00 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id B21D43C006C; Mon, 11 Sep 2017 19:13:53 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:24 +0200 Message-Id: <20170911171235.29331-11-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14148058232926866259 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.52.147 Subject: [Qemu-devel] [RFC PATCH v2 10/21] ppc/xive: add MMIO handlers for the XIVE TIMA 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 Thread Interrupt Management Area for the OS is mostly used to acknowledge interrupts and set the CPPR of the CPU. 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. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 161 ++++++++++++++++++++++++++++++++++++++++++++ hw/intc/xive-internal.h | 84 +++++++++++++++++++++++ include/hw/ppc/spapr_xive.h | 5 ++ 3 files changed, 250 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index a1ce993d2afa..557a7e2535b5 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -27,6 +27,154 @@ #include "xive-internal.h" + +static uint64_t spapr_xive_icp_accept(ICPState *icp) +{ + return 0; +} + +static void spapr_xive_icp_set_cppr(ICPState *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(ICPState *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); + ICPState *icp = 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 & 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 index) +{ + /* Let's be optimistic and prepare ground for HV mode support */ + switch (index) { + case TM_QW1_OS + TM_CPPR: + return false; + default: + return true; + } +} + +static void spapr_xive_tm_write_special(ICPState *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); + ICPState *icp = ICP(cpu->intc); + int i; + + if (offset >= TM_SPC_ACK_EBB) { + spapr_xive_tm_write_special(icp, offset, value, size); + return; + } + + if (offset & 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 srcno) { @@ -293,6 +441,11 @@ static void spapr_xive_source_set_irq(void *opaque, int srcno, 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 (XIVE_TM_RING_COUNT * (1 << TM_SHIFT)) + static uint64_t spapr_xive_esb_default_read(void *p, hwaddr offset, unsigned size) { @@ -403,6 +556,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); } diff --git a/hw/intc/xive-internal.h b/hw/intc/xive-internal.h index 95184bad5c1d..c6678ec7d161 100644 --- a/hw/intc/xive-internal.h +++ b/hw/intc/xive-internal.h @@ -24,6 +24,90 @@ #define PPC_BITMASK32(bs, be) ((PPC_BIT32(bs) - PPC_BIT32(be)) | \ PPC_BIT32(bs)) +/* + * Thread Management (aka "TM") registers + */ + +/* 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 diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index b46e59319236..3af01a0a4b22 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -59,6 +59,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; }; #endif /* PPC_SPAPR_XIVE_H */ From patchwork Mon Sep 11 17:12:25 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: 812472 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 3xrZZv0HT1z9s83 for ; Tue, 12 Sep 2017 03:25:59 +1000 (AEST) Received: from localhost ([::1]:59335 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drST7-0002gO-3J for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:25:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35308) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSHl-0001JE-CQ for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSHh-0004Qk-8d for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:13 -0400 Received: from 8.mo2.mail-out.ovh.net ([188.165.52.147]:43955) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSHh-0004QQ-2A for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:09 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 1C75BAB215 for ; Mon, 11 Sep 2017 19:14:08 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id E113D3C0072; Mon, 11 Sep 2017 19:14:00 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:25 +0200 Message-Id: <20170911171235.29331-12-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14150310029844908883 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.52.147 Subject: [Qemu-devel] [RFC PATCH v2 11/21] ppc/xive: push the 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 target 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. Notification of the CPU will be done in the following patch. 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 557a7e2535b5..4bc61cfda67a 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -175,9 +175,76 @@ static const MemoryRegionOps spapr_xive_tm_ops = { }, }; +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 srcno) { + XiveIVE *ive; + XiveEQ *eq; + uint32_t eq_idx; + uint32_t priority; + + ive = spapr_xive_get_ive(xive, srcno); + if (!ive || !(ive->w & IVE_VALID)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid LISN %d\n", srcno); + 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", srcno); + 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) { + return; + } + } else { + qemu_log_mask(LOG_UNIMP, "XIVE: w7 format1 not implemented\n"); + } } /* From patchwork Mon Sep 11 17:12:26 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: 812468 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 3xrZW96Vb0z9s81 for ; Tue, 12 Sep 2017 03:22:45 +1000 (AEST) Received: from localhost ([::1]:59313 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSPz-000867-TE for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:22:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35382) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSHs-0001QQ-Uc for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSHo-0004U8-Dx for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:20 -0400 Received: from 3.mo2.mail-out.ovh.net ([46.105.58.226]:59734) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSHo-0004Ti-88 for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:16 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 507E3AB262 for ; Mon, 11 Sep 2017 19:14:15 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id 1C2663C0072; Mon, 11 Sep 2017 19:14:08 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:26 +0200 Message-Id: <20170911171235.29331-13-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14152280358323194707 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 46.105.58.226 Subject: [Qemu-devel] [RFC PATCH v2 12/21] ppc/xive: notify the CPU when 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 can be 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. (1) numerically less than Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 4bc61cfda67a..e5d4b723b7e0 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -28,11 +28,39 @@ #include "xive-internal.h" +/* 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 << (7 - 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 can never be OxFF. Needs a fix. + */ +static uint8_t ipb_to_pipr(uint8_t ibp) +{ + return ibp ? clz32((uint32_t)ibp << 24) : 0xff; +} + static uint64_t spapr_xive_icp_accept(ICPState *icp) { return 0; } +static void spapr_xive_icp_notify(ICPState *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(icp)->output); + } +} + static void spapr_xive_icp_set_cppr(ICPState *icp, uint8_t cppr) { if (cppr > XIVE_PRIORITY_MAX) { @@ -40,6 +68,10 @@ static void spapr_xive_icp_set_cppr(ICPState *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); } /* @@ -206,6 +238,8 @@ static void spapr_xive_irq(sPAPRXive *xive, int srcno) XiveEQ *eq; uint32_t eq_idx; uint32_t priority; + uint32_t target; + ICPState *icp; ive = spapr_xive_get_ive(xive, srcno); if (!ive || !(ive->w & IVE_VALID)) { @@ -235,6 +269,13 @@ static void spapr_xive_irq(sPAPRXive *xive, int srcno) qemu_log_mask(LOG_UNIMP, "XIVE: !UCOND_NOTIFY not implemented\n"); } + target = GETFIELD(EQ_W6_NVT_INDEX, eq->w6); + icp = xics_icp_get(xive->ics->xics, target); + if (!icp) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No ICP for target %d\n", target); + return; + } + if (GETFIELD(EQ_W6_FORMAT_BIT, eq->w6) == 0) { priority = GETFIELD(EQ_W7_F0_PRIORITY, eq->w7); @@ -242,9 +283,18 @@ static void spapr_xive_irq(sPAPRXive *xive, int srcno) if (priority == 0xff) { return; } + + /* 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 Mon Sep 11 17:12:27 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: 812477 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 3xrZfC4vM8z9s81 for ; Tue, 12 Sep 2017 03:28:51 +1000 (AEST) Received: from localhost ([::1]:59353 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSVt-00061G-M9 for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:28:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35469) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSI0-0001X4-Br for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSHv-0004ZV-RH for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:28 -0400 Received: from 2.mo2.mail-out.ovh.net ([188.165.53.149]:39178) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSHv-0004Xq-LX for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:23 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 79984AB24B for ; Mon, 11 Sep 2017 19:14:22 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id 4B7CF3C0073; Mon, 11 Sep 2017 19:14:15 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:27 +0200 Message-Id: <20170911171235.29331-14-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14154250680636050259 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.53.149 Subject: [Qemu-devel] [RFC PATCH v2 13/21] ppc/xive: handle interrupt acknowledgment by the O/S 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 an O/S Exception is raised, 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), which contains the priority of the most favored pending notification. The bit number corresponding to the priority of the pending interrupt is reseted in the Interrupt Pending Buffer (IPB) and so is the EO bit of the NSR. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index e5d4b723b7e0..ad3ff91b13ea 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -50,7 +50,24 @@ static uint8_t ipb_to_pipr(uint8_t ibp) static uint64_t spapr_xive_icp_accept(ICPState *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(ICPState *icp) From patchwork Mon Sep 11 17:12:28 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: 812471 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 3xrZYY6DJkz9s81 for ; Tue, 12 Sep 2017 03:24:49 +1000 (AEST) Received: from localhost ([::1]:59327 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSRz-0001bj-Qe for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:24:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35545) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSI7-0001eK-AN for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSI2-0004eM-R1 for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:35 -0400 Received: from 3.mo2.mail-out.ovh.net ([46.105.58.226]:57314) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSI2-0004di-KB for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:30 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id A79E4AB236 for ; Mon, 11 Sep 2017 19:14:29 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id 7A2F93C006C; Mon, 11 Sep 2017 19:14:22 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:28 +0200 Message-Id: <20170911171235.29331-15-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14156221004876188499 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 46.105.58.226 Subject: [Qemu-devel] [RFC PATCH v2 14/21] ppc/xive: add support for the SET_OS_PENDING command 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. 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 ad3ff91b13ea..ad3f03e37401 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -162,7 +162,14 @@ static bool spapr_xive_tm_is_readonly(uint8_t index) static void spapr_xive_tm_write_special(ICPState *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 Mon Sep 11 17:12:29 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: 812479 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 3xrZjP19w1z9s83 for ; Tue, 12 Sep 2017 03:31:37 +1000 (AEST) Received: from localhost ([::1]:59371 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSYZ-0000Av-6Q for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:31:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35618) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSIF-0001lv-2B for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSIA-0004h8-6a for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:43 -0400 Received: from 6.mo2.mail-out.ovh.net ([87.98.165.38]:50765) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSIA-0004gm-0r for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:38 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id D808DAB1FE for ; Mon, 11 Sep 2017 19:14:36 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id A8EDD3C006C; Mon, 11 Sep 2017 19:14:29 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:29 +0200 Message-Id: <20170911171235.29331-16-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14158191328759548755 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.165.38 Subject: [Qemu-devel] [RFC PATCH v2 15/21] spapr: modify spapr_populate_pci_dt() to use a 'nr_irqs' argument 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" This adds some flexibility in the definition of the number of available IRQS used in a sPAPR machine. Signed-off-by: Cédric Le Goater --- hw/ppc/spapr.c | 2 +- hw/ppc/spapr_pci.c | 4 ++-- include/hw/pci-host/spapr.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 3e3ff1fbc988..5d69df928434 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1093,7 +1093,7 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr, } QLIST_FOREACH(phb, &spapr->phbs, list) { - ret = spapr_populate_pci_dt(phb, PHANDLE_XICP, fdt); + ret = spapr_populate_pci_dt(phb, PHANDLE_XICP, fdt, XICS_IRQS_SPAPR); if (ret < 0) { error_report("couldn't setup PCI devices in fdt"); exit(1); diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index d84abf1070a0..05b0a067458e 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -2073,7 +2073,7 @@ static void spapr_phb_pci_enumerate(sPAPRPHBState *phb) int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t xics_phandle, - void *fdt) + void *fdt, int nr_irqs) { int bus_off, i, j, ret; char nodename[FDT_NAME_MAX]; @@ -2142,7 +2142,7 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, _FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof_ranges)); _FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg))); _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pci-config-space-type", 0x1)); - _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", XICS_IRQS_SPAPR)); + _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", nr_irqs)); /* Dynamic DMA window */ if (phb->ddw_enabled) { diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 38470b2f0e5c..40146f72c103 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -115,7 +115,7 @@ PCIHostState *spapr_create_phb(sPAPRMachineState *spapr, int index); int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t xics_phandle, - void *fdt); + void *fdt, int nr_irqs); void spapr_pci_rtas_init(void); From patchwork Mon Sep 11 17:12:30 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: 812485 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 3xrZnC53xDz9s81 for ; Tue, 12 Sep 2017 03:34:55 +1000 (AEST) Received: from localhost ([::1]:59388 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSbl-0003CO-NC for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:34:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35692) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSIL-0001sc-Ti for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSIH-0004l7-B8 for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:49 -0400 Received: from 8.mo2.mail-out.ovh.net ([188.165.52.147]:45433) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSIH-0004km-1D for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:45 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 1529EAB24B for ; Mon, 11 Sep 2017 19:14:44 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id D8A623C006C; Mon, 11 Sep 2017 19:14:36 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:30 +0200 Message-Id: <20170911171235.29331-17-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14160443129388567379 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.52.147 Subject: [Qemu-devel] [RFC PATCH v2 16/21] spapr: add a XIVE object to the sPAPR 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" If the machine supports XIVE (POWER9 CPU), create a XIVE object. The CAS negotiation process will decide which model (legacy or XIVE) will be used for the interrupt controller depending on the guest capabilities. Also extend the number of provisionned IRQs with the number of CPUs, this is required for XIVE which allocates one IRQ number for each IPI. Signed-off-by: Cédric Le Goater --- hw/ppc/spapr.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++-- include/hw/ppc/spapr.h | 2 ++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 5d69df928434..b6577dbecdea 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -44,6 +44,7 @@ #include "mmu-hash64.h" #include "mmu-book3s-v3.h" #include "qom/cpu.h" +#include "target/ppc/cpu-models.h" #include "hw/boards.h" #include "hw/ppc/ppc.h" @@ -54,6 +55,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" @@ -202,6 +204,35 @@ static void xics_system_init(MachineState *machine, int nr_irqs, Error **errp) } } +static sPAPRXive *spapr_spapr_xive_create(sPAPRMachineState *spapr, int nr_irqs, + int nr_servers, 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_add_const_link(obj, "ics", OBJECT(spapr->ics), + &error_abort); + object_property_set_int(obj, nr_irqs, "nr-irqs", &local_err); + if (local_err) { + goto error; + } + object_property_set_int(obj, nr_servers, "nr-targets", &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) { @@ -1093,7 +1124,8 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr, } QLIST_FOREACH(phb, &spapr->phbs, list) { - ret = spapr_populate_pci_dt(phb, PHANDLE_XICP, fdt, XICS_IRQS_SPAPR); + ret = spapr_populate_pci_dt(phb, PHANDLE_XICP, fdt, + XICS_IRQS_SPAPR + xics_max_server_number()); if (ret < 0) { error_report("couldn't setup PCI devices in fdt"); exit(1); @@ -2140,6 +2172,16 @@ static void spapr_init_cpus(sPAPRMachineState *spapr) g_free(type); } +/* + * Only POWER9 Processor chips support the XIVE interrupt controller + */ +static bool ppc_support_xive(MachineState *machine) +{ + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(first_cpu); + + return pcc->pvr_match(pcc, CPU_POWERPC_POWER9_BASE); +} + /* pSeries LPAR / sPAPR hardware init */ static void ppc_spapr_init(MachineState *machine) { @@ -2237,7 +2279,8 @@ static void ppc_spapr_init(MachineState *machine) load_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FW_OVERHEAD; /* Set up Interrupt Controller before we create the VCPUs */ - xics_system_init(machine, XICS_IRQS_SPAPR, &error_fatal); + xics_system_init(machine, XICS_IRQS_SPAPR + xics_max_server_number(), + &error_fatal); /* Set up containers for ibm,client-set-architecture negotiated options */ spapr->ov5 = spapr_ovec_new(); @@ -2274,6 +2317,22 @@ static void ppc_spapr_init(MachineState *machine) spapr_init_cpus(spapr); + /* Set up XIVE. CAS will choose whether the guest runs in XICS + * (legacy mode) or XIVE Exploitation mode + * + * We don't have KVM support yet, so check for irqchip=on + */ + if (ppc_support_xive(machine)) { + if (kvm_enabled() && machine_kernel_irqchip_required(machine)) { + error_report("kernel_irqchip requested. no XIVE support"); + } else { + spapr->xive = spapr_spapr_xive_create(spapr, + XICS_IRQS_SPAPR + xics_max_server_number(), + xics_max_server_number(), + &error_fatal); + } + } + if (kvm_enabled()) { /* Enable H_LOGICAL_CI_* so SLOF can talk to in-kernel devices */ kvmppc_enable_logical_ci_hcalls(); diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 2a303a705c17..6cd5ab73c5dc 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 Mon Sep 11 17:12: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: 812474 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 3xrZb53Sj1z9s81 for ; Tue, 12 Sep 2017 03:26:09 +1000 (AEST) Received: from localhost ([::1]:59338 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSTH-0002pF-El for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:26:07 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35753) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSIS-0001y2-U6 for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:15:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSIO-0004pY-Lh for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:56 -0400 Received: from 1.mo2.mail-out.ovh.net ([46.105.63.121]:50444) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSIO-0004om-8d for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:14:52 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 4BEFCAB215 for ; Mon, 11 Sep 2017 19:14:51 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id 13D143C0073; Mon, 11 Sep 2017 19:14:44 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:31 +0200 Message-Id: <20170911171235.29331-18-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14162413455515945811 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 46.105.63.121 Subject: [Qemu-devel] [RFC PATCH v2 17/21] ppc/xive: add hcalls support 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 | 876 ++++++++++++++++++++++++++++++++++++++++++++ hw/ppc/spapr.c | 2 + include/hw/ppc/spapr.h | 15 +- include/hw/ppc/spapr_xive.h | 4 + 5 files changed, 897 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 2dae80bdf611..00a9aea2dd29 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..4c77b65683de --- /dev/null +++ b/hw/intc/spapr_xive_hcall.c @@ -0,0 +1,876 @@ +/* + * 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" + +/* + * TODO: check the valid priorities from the ranges listed in the + * "ibm,plat-res-int-priorities" property. Be simple for the moment. + */ +static bool priority_is_valid(int priority) +{ + return priority >= 0 && priority < 8; +} + +/* + * 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; + ICSIRQState *irq; + uint32_t srcno = lisn - spapr->ics->offset; + + 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, srcno); + if (!ive || !(ive->w & IVE_VALID)) { + return H_P2; + } + + mmio_base = (uint64_t)xive->esb_base + (1ull << xive->esb_shift) * srcno; + irq = &spapr->ics->irqs[srcno]; + + args[0] = 0; + if (irq->flags & XICS_FLAGS_IRQ_LSI) { + 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; + uint32_t srcno = lisn - spapr->ics->offset; + + 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, srcno); + 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_target(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; + uint32_t srcno = lisn - spapr->ics->offset; + + 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, srcno); + 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_target(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_target(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_target(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; + uint32_t srcno = lisn - spapr->ics->offset; + + 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, srcno); + if (!ive || !(ive->w & IVE_VALID)) { + return H_P2; + } + + if (offset > (1ull << xive->esb_shift)) { + return H_P3; + } + + srcno = lisn - spapr->ics->offset; + esb_base = (uint64_t)xive->esb_base + (1ull << xive->esb_shift) * srcno; + 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]; + uint32_t srcno = lisn - spapr->ics->offset; + + 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, srcno); + 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 b6577dbecdea..c2011cb2dc72 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -227,6 +227,8 @@ static sPAPRXive *spapr_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 6cd5ab73c5dc..b7683fae6415 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 3af01a0a4b22..ae5ff89533c0 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -66,4 +66,8 @@ struct sPAPRXive { MemoryRegion tm_iomem; }; +typedef struct sPAPRMachineState sPAPRMachineState; + +void spapr_xive_hcall_init(sPAPRMachineState *spapr); + #endif /* PPC_SPAPR_XIVE_H */ From patchwork Mon Sep 11 17:12: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: 812475 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 3xrZcf0rJFz9s83 for ; Tue, 12 Sep 2017 03:27:30 +1000 (AEST) Received: from localhost ([::1]:59347 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSUa-0004E4-6c for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:27:28 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35823) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSIb-00025d-0m for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:15:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSIW-0004s9-3E for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:15:05 -0400 Received: from 3.mo2.mail-out.ovh.net ([46.105.58.226]:53420) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSIV-0004rm-St for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:15:00 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 80B67AB2DB for ; Mon, 11 Sep 2017 19:14:58 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id 4B5A53C0072; Mon, 11 Sep 2017 19:14:51 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:32 +0200 Message-Id: <20170911171235.29331-19-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14164383780940712787 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 46.105.58.226 Subject: [Qemu-devel] [RFC PATCH v2 18/21] ppc/xive: add device tree support 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" Like for XICS, 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. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive_hcall.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr_xive.h | 1 + 2 files changed, 55 insertions(+) diff --git a/hw/intc/spapr_xive_hcall.c b/hw/intc/spapr_xive_hcall.c index 4c77b65683de..7b19ea6373dd 100644 --- a/hw/intc/spapr_xive_hcall.c +++ b/hw/intc/spapr_xive_hcall.c @@ -874,3 +874,57 @@ 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(sPAPRXive *xive, void *fdt, uint32_t phandle) +{ + int node; + uint64_t timas[2 * 2]; + uint32_t lisn_ranges[] = { + cpu_to_be32(xive->nr_irqs - xive->nr_targets + xive->ics->offset), + cpu_to_be32(xive->nr_targets), + }; + uint32_t eq_sizes[] = { + cpu_to_be32(12), /* 4K */ + cpu_to_be32(16), /* 64K */ + cpu_to_be32(21), /* 2M */ + cpu_to_be32(24), /* 16M */ + }; + + /* Use some ranges to exercise the Linux driver, which should + * result in Linux choosing priority 6. This is not strictly + * necessary + */ + uint32_t reserved_priorities[] = { + cpu_to_be32(1), /* start */ + cpu_to_be32(2), /* count */ + cpu_to_be32(7), /* start */ + cpu_to_be32(0xf8), /* count */ + }; + int 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", + reserved_priorities, sizeof(reserved_priorities))); +} diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index ae5ff89533c0..0a156f2d8591 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -69,5 +69,6 @@ struct sPAPRXive { typedef struct sPAPRMachineState sPAPRMachineState; void spapr_xive_hcall_init(sPAPRMachineState *spapr); +void spapr_xive_populate(sPAPRXive *xive, void *fdt, uint32_t phandle); #endif /* PPC_SPAPR_XIVE_H */ From patchwork Mon Sep 11 17:12: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: 812478 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 3xrZgd6yp3z9s81 for ; Tue, 12 Sep 2017 03:30:05 +1000 (AEST) Received: from localhost ([::1]:59360 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSX6-0007Jw-1H for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:30:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35857) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSIg-0002D7-3N for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:15:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSIc-0004v3-TQ for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:15:10 -0400 Received: from 4.mo2.mail-out.ovh.net ([87.98.172.75]:37131) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSIc-0004uh-N3 for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:15:06 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id AAC4CAB2B3 for ; Mon, 11 Sep 2017 19:15:05 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id 7B33A3C006C; Mon, 11 Sep 2017 19:14:58 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:33 +0200 Message-Id: <20170911171235.29331-20-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14166354105444305747 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.172.75 Subject: [Qemu-devel] [RFC PATCH v2 19/21] ppc/xive: 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" It will be used when the guest chooses the XIVE exploitation mode in CAS. Signed-off-by: Cédric Le Goater --- hw/intc/spapr_xive.c | 12 ++++++++++++ include/hw/ppc/spapr_xive.h | 1 + 2 files changed, 13 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index ad3f03e37401..adcbbc6ec245 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -807,3 +807,15 @@ bool spapr_xive_eq_for_target(sPAPRXive *xive, uint32_t target, return true; } + +void spapr_xive_mmio_map(sPAPRXive *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/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 0a156f2d8591..13cf10f365d8 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -70,5 +70,6 @@ typedef struct sPAPRMachineState sPAPRMachineState; void spapr_xive_hcall_init(sPAPRMachineState *spapr); void spapr_xive_populate(sPAPRXive *xive, void *fdt, uint32_t phandle); +void spapr_xive_mmio_map(sPAPRXive *xive); #endif /* PPC_SPAPR_XIVE_H */ From patchwork Mon Sep 11 17:12: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: 812465 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 3xrZRS49ckz9s81 for ; Tue, 12 Sep 2017 03:19:32 +1000 (AEST) Received: from localhost ([::1]:59295 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSMs-0005Lp-DL for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:19:30 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35916) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSIl-0002LR-8G for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:15:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSIk-00051m-0g for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:15:15 -0400 Received: from 4.mo2.mail-out.ovh.net ([87.98.172.75]:33886) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSIj-00051I-Qj for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:15:13 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id D81CAAB1FE for ; Mon, 11 Sep 2017 19:15:12 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id AA8863C0073; Mon, 11 Sep 2017 19:15:05 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:34 +0200 Message-Id: <20170911171235.29331-21-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14168324429764070227 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudeiucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.172.75 Subject: [Qemu-devel] [RFC PATCH v2 20/21] ppc/xics: introduce a qirq_get() helper in the XICSFabric 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 be used to choose the appropriate set of qirqs when XIVE is activated. Signed-off-by: Cédric Le Goater --- hw/intc/xics.c | 7 +------ hw/ppc/spapr.c | 12 ++++++++++++ include/hw/ppc/xics.h | 1 + 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 927d4fec966a..7691492aa17b 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -685,13 +685,8 @@ static const TypeInfo xics_fabric_info = { 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; + return xic->qirq_get(xi, irq); } ICPState *xics_icp_get(XICSFabric *xi, int server) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index c2011cb2dc72..d8b25be70cd8 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3455,6 +3455,17 @@ static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index, *mmio64 = SPAPR_PCI_BASE + (index + 1) * SPAPR_PCI_MEM64_WIN_SIZE; } +static qemu_irq spapr_qirq_get(XICSFabric *dev, int irq) +{ + sPAPRMachineState *spapr = SPAPR_MACHINE(dev); + + if (!ics_valid_irq(spapr->ics, irq)) { + return NULL; + } + + return spapr->ics->qirqs[irq - spapr->ics->offset]; +} + static ICSState *spapr_ics_get(XICSFabric *dev, int irq) { sPAPRMachineState *spapr = SPAPR_MACHINE(dev); @@ -3539,6 +3550,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) vhc->unmap_hptes = spapr_unmap_hptes; vhc->store_hpte = spapr_store_hpte; vhc->get_patbe = spapr_get_patbe; + xic->qirq_get = spapr_qirq_get; xic->ics_get = spapr_ics_get; xic->ics_resend = spapr_ics_resend; xic->icp_get = spapr_icp_get; diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index c835997303c4..46d2fc1ef2c1 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -178,6 +178,7 @@ struct XICSFabric { typedef struct XICSFabricClass { InterfaceClass parent; + qemu_irq (*qirq_get)(XICSFabric *xi, int irq); ICSState *(*ics_get)(XICSFabric *xi, int irq); void (*ics_resend)(XICSFabric *xi); ICPState *(*icp_get)(XICSFabric *xi, int server); From patchwork Mon Sep 11 17:12: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: 812489 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 3xrZsM5PQlz9s81 for ; Tue, 12 Sep 2017 03:38:31 +1000 (AEST) Received: from localhost ([::1]:59410 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSfF-0006BQ-Qp for incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:38:29 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35984) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSIw-0002Uw-A2 for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:15:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSIr-00054a-BI for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:15:26 -0400 Received: from 7.mo2.mail-out.ovh.net ([188.165.48.182]:34120) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSIr-00054K-1Y for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:15:21 -0400 Received: from player770.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo2.mail-out.ovh.net (Postfix) with ESMTP id 14321AB263 for ; Mon, 11 Sep 2017 19:15:20 +0200 (CEST) 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 player770.ha.ovh.net (Postfix) with ESMTPSA id D9A563C0073; Mon, 11 Sep 2017 19:15:12 +0200 (CEST) From: =?utf-8?q?C=C3=A9dric_Le_Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Alexey Kardashevskiy , Alexander Graf Date: Mon, 11 Sep 2017 19:12:35 +0200 Message-Id: <20170911171235.29331-22-clg@kaod.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170911171235.29331-1-clg@kaod.org> References: <20170911171235.29331-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14170576229094099795 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudeiucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 188.165.48.182 Subject: [Qemu-devel] [RFC PATCH v2 21/21] spapr: activate XIVE exploitation 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 couple of adjustments need to be done to activate XIVE exploitation mode. First, the hypervisor should advertise support for both models XIVE legacy and XIVE exploitation in "ibm,arch-vec-5-platform-support". The sPAPR machine starts with the XICS interrupt model (the default behavior could be changed later on for POWER9) and, depending on the guest capabilities, the XIVE exploitation mode is negotiated during CAS. A reset is then performed to rebuild the device tree with new XIVE properties under the "interrupt-controller" node. Finally, the MMIO regions for the ESB and TIMA should be mapped at reset time and post_load when XIVE exploitation mode is on. Signed-off-by: Cédric Le Goater --- hw/ppc/spapr.c | 33 ++++++++++++++++++++++++++++++--- hw/ppc/spapr_hcall.c | 6 ++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index d8b25be70cd8..aaf1be7a50fe 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -942,7 +942,8 @@ static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt) /* 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) +static void spapr_dt_ov5_platform_support(sPAPRMachineState *spapr, + void *fdt, int chosen) { PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu); @@ -961,6 +962,13 @@ 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) { + val[1] = 0x80; /* OV5_XIVE_BOTH */ + } } else { if (first_ppc_cpu->env.mmu_model & POWERPC_MMU_V3) { /* V3 MMU supports both hash and radix (with dynamic switching) */ @@ -969,6 +977,9 @@ static void spapr_dt_ov5_platform_support(void *fdt, int chosen) /* Otherwise we can only do hash */ val[3] = 0x00; } + if (spapr->xive) { + val[1] = 0x80; /* OV5_XIVE_BOTH */ + } } _FDT(fdt_setprop(fdt, chosen, "ibm,arch-vec-5-platform-support", val, sizeof(val))); @@ -1027,7 +1038,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); @@ -1106,7 +1117,13 @@ 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->xive, fdt, PHANDLE_XICP); + spapr_xive_mmio_map(spapr->xive); + } ret = spapr_populate_memory(spapr, fdt); if (ret < 0) { @@ -1552,6 +1569,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->xive); + } + return err; } @@ -2332,6 +2353,7 @@ static void ppc_spapr_init(MachineState *machine) XICS_IRQS_SPAPR + xics_max_server_number(), xics_max_server_number(), &error_fatal); + spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT); } } @@ -3463,6 +3485,11 @@ static qemu_irq spapr_qirq_get(XICSFabric *dev, int irq) return NULL; } + /* use XIVE qirqs when XIVE exploitation mode is on */ + if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return spapr->xive->qirqs[irq - spapr->ics->offset]; + } + return spapr->ics->qirqs[irq - spapr->ics->offset]; } diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 92f1e21358b8..ba00b8d3fdd6 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1613,6 +1613,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) {