diff mbox series

[37/61] hw/phb5: Add support for 'Address-Based Interrupt Trigger' mode

Message ID 20210719132012.150948-38-hegdevasant@linux.vnet.ibm.com
State Superseded
Headers show
Series P10 Enablement | expand

Commit Message

Vasant Hegde July 19, 2021, 1:19 p.m. UTC
From: Cédric Le Goater <clg@kaod.org>

The PHB5 introduces a new Address-Based Interrupt mode which extends
the notification offloading to the ESB pages. When ABT is activated,
the PHB maps the interrupt source number into the interrupt command
address. The PHB triggers the interrupt using directly the IC ESB page
of the interrupt number and does not use the notify page of the IC
anymore.

The PHB interrrupt configuration under ABT is a little different. The
'Interrupt Notify Base Address' register points to the base address of
the IC ESB pages and not to the notify page of the IC anymore as on
P9. The 'Interrupt Notify Base Index' register is unused.

This should improve overall performance. The P10 IC can handle higher
interrupt rates compared to P9 and the PHB latency should be improved
under ABT. Debug is easier as the interrupt number is now exposed on
the PowerBUS.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
[FB: port to phb4.c]
Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
---
 hw/phb4.c           | 63 ++++++++++++++++++++++++++++++++++++++++-----
 hw/xive2.c          |  6 -----
 include/phb4-regs.h |  2 ++
 3 files changed, 59 insertions(+), 12 deletions(-)
diff mbox series

Patch

diff --git a/hw/phb4.c b/hw/phb4.c
index 6747fcb8f..29da3e08c 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -159,6 +159,18 @@  static inline bool phb_pq_disable(struct phb4 *p __unused)
 	return false;
 }
 
+/*
+ * Use the ESB page of the XIVE IC for event notification. Latency
+ * improvement.
+ */
+static inline bool phb_abt_mode(struct phb4 *p __unused)
+{
+	if (is_phb5())
+		return 1;
+
+	return false;
+}
+
 static inline bool phb_can_store_eoi(struct phb4 *p)
 {
 	if (is_phb5())
@@ -5000,12 +5012,49 @@  static const struct phb_ops phb4_ops = {
 
 static void phb4_init_ioda3(struct phb4 *p)
 {
-	/* Init_18 - Interrupt Notify Base Address */
-	out_be64(p->regs + PHB_INT_NOTIFY_ADDR, p->irq_port);
+	if (is_phb5()) {
+		/*
+		 * When ABT is on, the MSIs on the PHB use the PQ state bits
+		 * of the IC and MSI triggers from the PHB are forwarded
+		 * directly to the IC ESB page. However, the LSIs are still
+		 * controlled locally on the PHB and LSI triggers use a
+		 * special offset for trigger injection.
+		 */
+		if (phb_abt_mode(p)) {
+			uint64_t mmio_base = xive2_get_esb_base(p->base_msi);
+
+			PHBDBG(p, "Using ABT mode. ESB: 0x%016llx\n", mmio_base);
+
+			/* Init_18 - Interrupt Notify Base Address */
+			out_be64(p->regs + PHB_INT_NOTIFY_ADDR,
+				 PHB_INT_NOTIFY_ADDR_64K | mmio_base);
+
+			/* Interrupt Notify Base Index is unused */
+		} else {
+			p->irq_port = xive2_get_notify_port(p->chip_id,
+						XIVE_HW_SRC_PHBn(p->index));
+
+			PHBDBG(p, "Using IC notif page at 0x%016llx\n",
+						p->irq_port);
 
-	/* Init_19 - Interrupt Notify Base Index */
-	out_be64(p->regs + PHB_INT_NOTIFY_INDEX,
-		 xive2_get_notify_base(p->base_msi));
+			/* Init_18 - Interrupt Notify Base Address */
+			out_be64(p->regs + PHB_INT_NOTIFY_ADDR, p->irq_port);
+
+			/* Init_19 - Interrupt Notify Base Index */
+			out_be64(p->regs + PHB_INT_NOTIFY_INDEX,
+				 xive2_get_notify_base(p->base_msi));
+		}
+
+	} else { /* p9 */
+		p->irq_port = xive_get_notify_port(p->chip_id,
+						   XIVE_HW_SRC_PHBn(p->index));
+		/* Init_18 - Interrupt Notify Base Address */
+		out_be64(p->regs + PHB_INT_NOTIFY_ADDR, p->irq_port);
+
+		/* Init_19 - Interrupt Notify Base Index */
+		out_be64(p->regs + PHB_INT_NOTIFY_INDEX,
+			 xive_get_notify_base(p->base_msi));
+	}
 
 	/* Init_19x - Not in spec: Initialize source ID */
 	PHBDBG(p, "Reset state SRC_ID: %016llx\n",
@@ -5385,6 +5434,8 @@  static void phb4_init_hw(struct phb4 *p)
 	val |= SETFIELD(PHB_CTRLR_TVT_ADDR_SEL, 0ull, TVT_2_PER_PE);
 	if (phb_pq_disable(p))
 		val |= PHB_CTRLR_IRQ_PQ_DISABLE;
+	if (phb_abt_mode(p))
+		val |= PHB_CTRLR_IRQ_ABT_MODE;
 	if (phb_can_store_eoi(p)) {
 		val |= PHB_CTRLR_IRQ_STORE_EOI;
 		PHBDBG(p, "store EOI is enabled\n");
@@ -5959,7 +6010,7 @@  static void phb4_create(struct dt_node *np)
 		 * ESB pages of the XIVE IC for the MSI sources instead of the
 		 * ESB pages of the PHB.
 		 */
-		if (phb_pq_disable(p)) {
+		if (phb_pq_disable(p) || phb_abt_mode(p)) {
 			xive2_register_esb_source(p->base_msi, p->num_irqs - 8);
 		} else {
 			xive2_register_hw_source(p->base_msi,
diff --git a/hw/xive2.c b/hw/xive2.c
index 9f9ccb325..b80c61b71 100644
--- a/hw/xive2.c
+++ b/hw/xive2.c
@@ -2146,12 +2146,6 @@  uint64_t xive2_get_notify_port(uint32_t chip_id, uint32_t ent)
 	 *
 	 * P10 might now be randomizing the cache line bits in HW to
 	 * balance snoop bus usage
-	 *
-	 * TODO (phb5) : implement "address based triggers" (DD2.0?)
-	 *
-	 * The PHBs would no longer target the notify port page but
-	 * the "base ESB MMIO address" of the ESB/EAS range they are
-	 * allocated. Needs a XIVE API change for the PHBs.
 	 */
 	switch(ent) {
 	case XIVE_HW_SRC_PHBn(0):
diff --git a/include/phb4-regs.h b/include/phb4-regs.h
index 139522814..99633e103 100644
--- a/include/phb4-regs.h
+++ b/include/phb4-regs.h
@@ -97,11 +97,13 @@ 
 #define   PHB_PAPR_ERR_INJ_MASK_MMIO		PPC_BITMASK(16,63)
 #define PHB_ETU_ERR_SUMMARY		0x2c8
 #define PHB_INT_NOTIFY_ADDR		0x300
+#define   PHB_INT_NOTIFY_ADDR_64K	PPC_BIT(1)	/* PHB5 */
 #define PHB_INT_NOTIFY_INDEX		0x308
 
 #define PHB_VERSION			0x800
 #define PHB_CTRLR			0x810
 #define   PHB_CTRLR_IRQ_PQ_DISABLE	PPC_BIT(9)	/* PHB5 */
+#define   PHB_CTRLR_IRQ_ABT_MODE	PPC_BIT(10)	/* PHB5 */
 #define   PHB_CTRLR_IRQ_PGSZ_64K	PPC_BIT(11)
 #define   PHB_CTRLR_IRQ_STORE_EOI	PPC_BIT(12)
 #define   PHB_CTRLR_MMIO_RD_STRICT	PPC_BIT(13)