From: "Cédric Le Goater" <clg@kaod.org>
To: qemu-ppc@nongnu.org
Cc: qemu-devel@nongnu.org,
"David Gibson" <david@gibson.dropbear.id.au>,
"Greg Kurz" <groug@kaod.org>, "Cédric Le Goater" <clg@kaod.org>
Subject: [Qemu-devel] [PATCH v4 09/28] ppc/xive: add support for the EQ Event State buffers
Date: Thu, 7 Jun 2018 17:49:44 +0200 [thread overview]
Message-ID: <20180607155003.1580-10-clg@kaod.org> (raw)
In-Reply-To: <20180607155003.1580-1-clg@kaod.org>
The Event Queue Descriptor also contains two Event State Buffers
providing further coalescing of interrupts, one for the notification
event (ESn) and one for the escalation events (ESe). A MMIO page is
assigned for each to control the EOI through loads only. Stores are
not allowed.
The EQ ESB are modeled through an object resembling the 'XiveSource'
It is stateless as the EQ state bits are backed into the XiveEQ
structure under the XiveRouter and the MMIO accesses follow the same
rules as the standard source ESBs.
EQ ESBs are not supported by the Linux drivers neither on OPAL nor on
sPAPR. Nnevetherless, it provides a mean to study the question in the
future and validates a bit more the XIVE model.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
include/hw/ppc/xive.h | 20 +++++++
hw/intc/xive.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 177 insertions(+), 2 deletions(-)
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index fc2ed7319f0f..e5f6800b50d3 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -209,6 +209,26 @@ int xive_router_set_eq(XiveRouter *xrtr, uint8_t eq_blk, uint32_t eq_idx,
XiveEQ *eq);
/*
+ * XIVE EQ ESBs
+ */
+
+#define TYPE_XIVE_EQ_SOURCE "xive-eq-source"
+#define XIVE_EQ_SOURCE(obj) \
+ OBJECT_CHECK(XiveEQSource, (obj), TYPE_XIVE_EQ_SOURCE)
+
+typedef struct XiveEQSource {
+ SysBusDevice parent;
+
+ uint32_t nr_eqs;
+
+ /* ESB memory region */
+ uint32_t esb_shift;
+ MemoryRegion esb_mmio;
+
+ XiveRouter *xrtr;
+} XiveEQSource;
+
+/*
* For legacy compatibility, the exceptions define up to 256 different
* priorities. P9 implements only 9 levels : 8 active levels [0 - 7]
* and the least favored level 0xFF.
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index ae5c7f545d30..64d8d15385bc 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -584,8 +584,18 @@ static void xive_router_eq_notify(XiveRouter *xrtr, uint8_t eq_blk,
* futher even coalescing in the Router
*/
if (!(eq.w0 & EQ_W0_UCOND_NOTIFY)) {
- qemu_log_mask(LOG_UNIMP, "XIVE: !UCOND_NOTIFY not implemented\n");
- return;
+ uint8_t pq = GETFIELD(EQ_W1_ESn, eq.w1);
+ bool notify = xive_esb_trigger(&pq);
+
+ if (pq != GETFIELD(EQ_W1_ESn, eq.w1)) {
+ eq.w1 = SETFIELD(EQ_W1_ESn, eq.w1, pq);
+ xive_router_set_eq(xrtr, eq_blk, eq_idx, &eq);
+ }
+
+ /* ESn[Q]=1 : end of notification */
+ if (!notify) {
+ return;
+ }
}
/*
@@ -687,6 +697,150 @@ void xive_router_print_ive(XiveRouter *xrtr, uint32_t lisn, XiveIVE *ive,
}
/*
+ * EQ ESB MMIO loads
+ */
+static uint64_t xive_eq_source_read(void *opaque, hwaddr addr, unsigned size)
+{
+ XiveEQSource *xsrc = XIVE_EQ_SOURCE(opaque);
+ XiveRouter *xrtr = xsrc->xrtr;
+ uint32_t offset = addr & 0xFFF;
+ uint8_t eq_blk;
+ uint32_t eq_idx;
+ XiveEQ eq;
+ uint32_t eq_esmask;
+ uint8_t pq;
+ uint64_t ret = -1;
+
+ eq_blk = xrtr->chip_id;
+ eq_idx = addr >> (xsrc->esb_shift + 1);
+ if (xive_router_get_eq(xrtr, eq_blk, eq_idx, &eq)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No EQ %x/%x\n", eq_blk, eq_idx);
+ return -1;
+ }
+
+ if (!(eq.w0 & EQ_W0_VALID)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "XIVE: EQ %x/%x is invalid\n",
+ eq_blk, eq_idx);
+ return -1;
+ }
+
+ eq_esmask = addr_is_even(addr, xsrc->esb_shift) ? EQ_W1_ESn : EQ_W1_ESe;
+ pq = GETFIELD(eq_esmask, eq.w1);
+
+ switch (offset) {
+ case XIVE_ESB_LOAD_EOI ... XIVE_ESB_LOAD_EOI + 0x7FF:
+ ret = xive_esb_eoi(&pq);
+
+ /* Forward the source event notification for routing ?? */
+ break;
+
+ case XIVE_ESB_GET ... XIVE_ESB_GET + 0x3FF:
+ ret = pq;
+ break;
+
+ case XIVE_ESB_SET_PQ_00 ... XIVE_ESB_SET_PQ_00 + 0x0FF:
+ case XIVE_ESB_SET_PQ_01 ... XIVE_ESB_SET_PQ_01 + 0x0FF:
+ case XIVE_ESB_SET_PQ_10 ... XIVE_ESB_SET_PQ_10 + 0x0FF:
+ case XIVE_ESB_SET_PQ_11 ... XIVE_ESB_SET_PQ_11 + 0x0FF:
+ ret = xive_esb_set(&pq, (offset >> 8) & 0x3);
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid EQ ESB load addr %d\n",
+ offset);
+ return -1;
+ }
+
+ if (pq != GETFIELD(eq_esmask, eq.w1)) {
+ eq.w1 = SETFIELD(eq_esmask, eq.w1, pq);
+ xive_router_set_eq(xrtr, eq_blk, eq_idx, &eq);
+ }
+
+ return ret;
+}
+
+/*
+ * EQ ESB MMIO stores are invalid
+ */
+static void xive_eq_source_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
+{
+ qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid ESB write addr 0x%"
+ HWADDR_PRIx"\n", addr);
+}
+
+static const MemoryRegionOps xive_eq_source_ops = {
+ .read = xive_eq_source_read,
+ .write = xive_eq_source_write,
+ .endianness = DEVICE_BIG_ENDIAN,
+ .valid = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+ .impl = {
+ .min_access_size = 8,
+ .max_access_size = 8,
+ },
+};
+
+static void xive_eq_source_realize(DeviceState *dev, Error **errp)
+{
+ XiveEQSource *xsrc = XIVE_EQ_SOURCE(dev);
+ Object *obj;
+ Error *local_err = NULL;
+
+ obj = object_property_get_link(OBJECT(dev), "xive", &local_err);
+ if (!obj) {
+ error_propagate(errp, local_err);
+ error_prepend(errp, "required link 'xive' not found: ");
+ return;
+ }
+
+ xsrc->xrtr = XIVE_ROUTER(obj);
+
+ if (!xsrc->nr_eqs) {
+ error_setg(errp, "Number of interrupt needs to be greater than 0");
+ return;
+ }
+
+ if (xsrc->esb_shift != XIVE_ESB_4K &&
+ xsrc->esb_shift != XIVE_ESB_64K) {
+ error_setg(errp, "Invalid ESB shift setting");
+ return;
+ }
+
+ /*
+ * Each EQ is assigned an even/odd pair of MMIO pages, the even page
+ * manages the ESn field while the odd page manages the ESe field.
+ */
+ memory_region_init_io(&xsrc->esb_mmio, OBJECT(xsrc),
+ &xive_eq_source_ops, xsrc, "xive.eq",
+ (1ull << (xsrc->esb_shift + 1)) * xsrc->nr_eqs);
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &xsrc->esb_mmio);
+}
+
+static Property xive_eq_source_properties[] = {
+ DEFINE_PROP_UINT32("nr-eqs", XiveEQSource, nr_eqs, 0),
+ DEFINE_PROP_UINT32("shift", XiveEQSource, esb_shift, XIVE_ESB_64K),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void xive_eq_source_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->desc = "XIVE EQ Source";
+ dc->props = xive_eq_source_properties;
+ dc->realize = xive_eq_source_realize;
+}
+
+static const TypeInfo xive_eq_source_info = {
+ .name = TYPE_XIVE_EQ_SOURCE,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(XiveEQSource),
+ .class_init = xive_eq_source_class_init,
+};
+
+/*
* XIVE Fabric
*/
static const TypeInfo xive_fabric_info = {
@@ -700,6 +854,7 @@ static void xive_register_types(void)
type_register_static(&xive_source_info);
type_register_static(&xive_fabric_info);
type_register_static(&xive_router_info);
+ type_register_static(&xive_eq_source_info);
}
type_init(xive_register_types)
--
2.13.6
next prev parent reply other threads:[~2018-06-07 15:51 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-07 15:49 [Qemu-devel] [PATCH v4 00/28] ppc: support for the XIVE interrupt controller (POWER9) Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 01/28] sparp_pci: simplify how the PCI LSIs are allocated Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 02/28] spapr: introduce a generic IRQ frontend to the machine Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 03/28] spapr: introduce a new IRQ backend using fixed IRQ number ranges Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 04/28] ppc/xive: introduce a XIVE interrupt source model Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 05/28] ppc/xive: add support for the LSI interrupt sources Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 06/28] ppc/xive: introduce the XiveFabric interface Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 07/28] ppc/xive: introduce the XiveRouter model Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 08/28] ppc/xive: introduce the XIVE Event Queues Cédric Le Goater
2018-06-07 15:49 ` Cédric Le Goater [this message]
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 10/28] ppc/xive: introduce the XIVE interrupt thread context Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 11/28] ppc/xive: introduce a simplified XIVE presenter Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 12/28] ppc/xive: notify the CPU when the interrupt priority is more privileged Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 13/28] spapr/xive: introduce a XIVE interrupt controller Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 14/28] spapr/xive: use the VCPU id as a VP identifier in the OS CAM Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 15/28] spapr: initialize VSMT before initializing the IRQ backend Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 16/28] spapr: introdude a new machine IRQ backend for XIVE Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 17/28] spapr: add hcalls support for the XIVE exploitation interrupt mode Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 18/28] spapr: add device tree support for the XIVE exploitation mode Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 19/28] spapr: allocate the interrupt thread context under the CPU core Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 20/28] spapr: introduce a 'pseries-3.0-xive' QEMU machine Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 21/28] spapr: add classes for the XIVE models Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 22/28] target/ppc/kvm: add Linux KVM definitions for XIVE Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 23/28] spapr/xive: add common realize routine for KVM Cédric Le Goater
2018-06-07 15:49 ` [Qemu-devel] [PATCH v4 24/28] spapr/xive: add KVM support Cédric Le Goater
2018-06-07 15:50 ` [Qemu-devel] [PATCH v4 25/28] spapr: fix XICS migration Cédric Le Goater
2018-06-07 15:50 ` [Qemu-devel] [PATCH v4 26/28] pnv: add a physical mapping array describing MMIO ranges in each chip Cédric Le Goater
2018-06-07 15:50 ` [Qemu-devel] [PATCH v4 27/28] ppc: externalize ppc_get_vcpu_by_pir() Cédric Le Goater
2018-06-07 15:50 ` [Qemu-devel] [PATCH v4 28/28] ppc/pnv: add XIVE support Cédric Le Goater
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180607155003.1580-10-clg@kaod.org \
--to=clg@kaod.org \
--cc=david@gibson.dropbear.id.au \
--cc=groug@kaod.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).