aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Lombard <clombard@linux.vnet.ibm.com>2021-10-14 17:57:03 +0200
committerVasant Hegde <hegdevasant@linux.vnet.ibm.com>2021-10-19 12:26:02 +0530
commit2d89dd334756d19a9ffc3e4c784406177f46c053 (patch)
treee31c9da1b6a84def34305db432ddca09448dcbfa
parentd5b79b2e9bb63ec18b5b5e4d027d5d1d1b0a4e28 (diff)
downloadskiboot-2d89dd334756d19a9ffc3e4c784406177f46c053.zip
skiboot-2d89dd334756d19a9ffc3e4c784406177f46c053.tar.gz
skiboot-2d89dd334756d19a9ffc3e4c784406177f46c053.tar.bz2
pau: mmio invalidates
The remaining translation mode: OpenCAPI 5.0 with TLBI/SLBI Snooping, is not used due to performance problems caused by the mismatch between the ERAT and Bloom Filter sizes. When the Address Translation Mode requires TLB and SLB Invalidate operations to be initiated using MMIO registers, a set of registers like the following is used: • XTS MMIO ATSD0 LPARID register • XTS MMIO ATSD0 AVA register • XTS MMIO ATSD0 launch register, write access initiates a shoot down • XTS MMIO ATSD0 status register Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com> Reviewed-by: Frederic Barrat <fbarrat@linux.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
-rw-r--r--hw/npu-opal.c3
-rw-r--r--hw/pau.c36
-rw-r--r--include/pau-regs.h8
-rw-r--r--include/pau.h2
4 files changed, 49 insertions, 0 deletions
diff --git a/hw/npu-opal.c b/hw/npu-opal.c
index cf13690..2e455dc 100644
--- a/hw/npu-opal.c
+++ b/hw/npu-opal.c
@@ -52,6 +52,9 @@ static int64_t opal_npu_map_lpar(uint64_t phb_id, uint64_t bdf, uint64_t lparid,
if (phb->phb_type == phb_type_npu_v2)
return npu2_map_lpar(phb, bdf, lparid, lpcr);
+ if (phb->phb_type == phb_type_pau_opencapi)
+ return pau_opencapi_map_atsd_lpar(phb, bdf, lparid, lpcr);
+
return OPAL_PARAMETER;
}
opal_call(OPAL_NPU_MAP_LPAR, opal_npu_map_lpar, 4);
diff --git a/hw/pau.c b/hw/pau.c
index 83cd6fe..9f6a709 100644
--- a/hw/pau.c
+++ b/hw/pau.c
@@ -268,6 +268,29 @@ static void pau_device_detect_fixup(struct pau_dev *dev)
dt_add_property_strings(dn, "ibm,pau-link-type", "unknown");
}
+int64_t pau_opencapi_map_atsd_lpar(struct phb *phb, uint64_t __unused bdf,
+ uint64_t lparid, uint64_t __unused lpcr)
+{
+ struct pau_dev *dev = pau_phb_to_opencapi_dev(phb);
+ struct pau *pau = dev->pau;
+ uint64_t val;
+
+ if (lparid >= PAU_XTS_ATSD_MAX)
+ return OPAL_PARAMETER;
+
+ lock(&pau->lock);
+
+ /* We need to allocate an ATSD per link */
+ val = SETFIELD(PAU_XTS_ATSD_HYP_LPARID, 0ull, lparid);
+ if (!lparid)
+ val |= PAU_XTS_ATSD_HYP_MSR_HV;
+
+ pau_write(pau, PAU_XTS_ATSD_HYP(lparid), val);
+
+ unlock(&pau->lock);
+ return OPAL_SUCCESS;
+}
+
int64_t pau_opencapi_spa_setup(struct phb *phb, uint32_t __unused bdfn,
uint64_t addr, uint64_t PE_mask)
{
@@ -1442,6 +1465,18 @@ static void pau_opencapi_create_phb(struct pau_dev *dev)
pau_opencapi_create_phb_slot(dev);
}
+static void pau_dt_add_mmio_atsd(struct pau_dev *dev)
+{
+ struct dt_node *dn = dev->phb.dt_node;
+ struct pau *pau = dev->pau;
+ uint64_t mmio_atsd[PAU_XTS_ATSD_MAX];
+
+ for (uint32_t i = 0; i < PAU_XTS_ATSD_MAX; i++)
+ mmio_atsd[i] = pau->regs[0] + PAU_XTS_ATSD_LAUNCH(i);
+
+ dt_add_property(dn, "ibm,mmio-atsd", mmio_atsd, sizeof(mmio_atsd));
+}
+
static void pau_opencapi_dt_add_mmio_window(struct pau_dev *dev)
{
struct dt_node *dn = dev->phb.dt_node;
@@ -1508,6 +1543,7 @@ static void pau_opencapi_dt_add_props(struct pau_dev *dev)
dt_add_property_cells(dn, "ibm,opal-num-pes", PAU_MAX_PE_NUM);
dt_add_property_cells(dn, "ibm,opal-reserved-pe", PAU_RESERVED_PE_NUM);
+ pau_dt_add_mmio_atsd(dev);
pau_opencapi_dt_add_mmio_window(dev);
pau_opencapi_dt_add_hotpluggable(dev);
}
diff --git a/include/pau-regs.h b/include/pau-regs.h
index 57c2d72..da83ad4 100644
--- a/include/pau-regs.h
+++ b/include/pau-regs.h
@@ -37,6 +37,7 @@
#define PAU_BLOCK_XSL PAU_BLOCK(4, 0xE)
#define PAU_BLOCK_PAU_XTS PAU_BLOCK(7, 1)
#define PAU_BLOCK_PAU_MISC PAU_BLOCK(7, 2)
+#define PAU_BLOCK_PAU_XTS_ATSD(n) PAU_BLOCK(8, (n))
/*
* CQ_SM block registers
@@ -176,6 +177,9 @@
#define PAU_XTS_CFG2_XSL2_ENA PPC_BIT(55)
#define PAU_XTS_CFG3 (PAU_BLOCK_PAU_XTS + 0x068)
#define PAU_XTS_CFG3_MMIOSD_OCAPI PPC_BIT(5)
+#define PAU_XTS_ATSD_HYP(n) (PAU_BLOCK_PAU_XTS + 0x100 + (n) * 8)
+#define PAU_XTS_ATSD_HYP_MSR_HV PPC_BIT(51)
+#define PAU_XTS_ATSD_HYP_LPARID PPC_BITMASK(52, 63)
/* MISC block registers */
#define PAU_MISC_OPTICAL_IO_CONFIG (PAU_BLOCK_PAU_MISC + 0x018)
@@ -204,4 +208,8 @@
#define PAU_MISC_INT_2_CONFIG_XFAULT_2_5(n) PPC_BIT(0 + (n))
#define PAU_MISC_INT_2_CONFIG_XFAULT_0_1(n) PPC_BIT(54 + (n))
+/* PAU_XTS_ATSD block registers */
+#define PAU_XTS_ATSD_LAUNCH(n) (PAU_BLOCK_PAU_XTS_ATSD(n) + 0x000)
+#define PAU_XTS_ATSD_MAX 16
+
#endif /* __PAU_REGS_H */
diff --git a/include/pau.h b/include/pau.h
index 894007d..a70058f 100644
--- a/include/pau.h
+++ b/include/pau.h
@@ -200,6 +200,8 @@ static inline uint64_t pau_read(struct pau *pau, uint64_t reg)
}
void pau_opencapi_dump_scoms(struct pau *pau);
+int64_t pau_opencapi_map_atsd_lpar(struct phb *phb, uint64_t __unused bdf,
+ uint64_t lparid, uint64_t __unused lpcr);
int64_t pau_opencapi_spa_setup(struct phb *phb, uint32_t __unused bdfn,
uint64_t addr, uint64_t PE_mask);
int64_t pau_opencapi_spa_clear_cache(struct phb *phb,