aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/phb3.c43
-rw-r--r--include/phb3-regs.h6
2 files changed, 30 insertions, 19 deletions
diff --git a/hw/phb3.c b/hw/phb3.c
index 2623d5a..b8019ac 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -2613,44 +2613,53 @@ static int64_t phb3_err_inject_mem32(struct phb3 *p, uint32_t pe_no,
uint64_t addr, uint64_t mask,
bool is_write)
{
- uint64_t a, m, prefer, base;
+ uint64_t base, len, segstart, segsize;
+ uint64_t a, m;
uint64_t ctrl = PHB_PAPR_ERR_INJ_CTL_OUTB;
- int index;
+ uint32_t index;
+
+ segsize = (M32_PCI_SIZE / PHB3_MAX_PE_NUM);
+ a = base = len = 0x0ull;
- a = 0x0ull;
- prefer = 0x0ull;
for (index = 0; index < PHB3_MAX_PE_NUM; index++) {
if (GETFIELD(IODA2_M32DT_PE, p->m32d_cache[index]) != pe_no)
continue;
- base = p->mm1_base + (M32_PCI_SIZE / PHB3_MAX_PE_NUM) * index;
-
- /* Update preferred address */
- if (!prefer) {
- prefer = GETFIELD(PHB_PAPR_ERR_INJ_MASK_MMIO, base);
- prefer = SETFIELD(PHB_PAPR_ERR_INJ_MASK_MMIO, 0x0ull, prefer);
+ /* Obviously, we can't support discontiguous segments.
+ * We have to pick the first batch of contiguous segments
+ * for that case
+ */
+ segstart = p->mm1_base + segsize * index;
+ if (!len) {
+ base = segstart;
+ len = segsize;
+ } else if ((base + len) == segstart) {
+ len += segsize;
}
- /* The input address matches ? */
- if (addr >= base &&
- addr < base + M32_PCI_SIZE / PHB3_MAX_PE_NUM) {
+ /* Check the specified address is valid one */
+ if (addr >= segstart && addr < (segstart + segsize)) {
a = addr;
break;
}
}
- /* Invalid PE number */
- if (!prefer)
+ /* No MM32 segments assigned to the PE */
+ if (!len)
return OPAL_PARAMETER;
/* Specified address is out of range */
if (!a) {
- a = prefer;
- m = PHB_PAPR_ERR_INJ_MASK_MMIO_MASK;
+ a = base;
+ len = len & ~(len - 1);
+ m = ~(len - 1);
} else {
m = mask;
}
+ a = SETFIELD(PHB_PAPR_ERR_INJ_ADDR_MMIO, 0x0ull, a);
+ m = SETFIELD(PHB_PAPR_ERR_INJ_MASK_MMIO, 0x0ull, m);
+
return phb3_err_inject_finalize(p, a, m, ctrl, is_write);
}
diff --git a/include/phb3-regs.h b/include/phb3-regs.h
index 2611b5f..686a113 100644
--- a/include/phb3-regs.h
+++ b/include/phb3-regs.h
@@ -144,11 +144,13 @@
#define PHB_PAPR_ERR_INJ_CTL_WR PPC_BIT(5)
#define PHB_PAPR_ERR_INJ_CTL_FREEZE PPC_BIT(6)
#define PHB_PAPR_ERR_INJ_ADDR 0x2b8
+#define PHB_PAPR_ERR_INJ_ADDR_MMIO_MASK PPC_BITMASK(16,63)
+#define PHB_PAPR_ERR_INJ_ADDR_MMIO_LSH PPC_BITLSHIFT(63)
#define PHB_PAPR_ERR_INJ_MASK 0x2c0
#define PHB_PAPR_ERR_INJ_MASK_CFG_MASK PPC_BITMASK(4,11)
#define PHB_PAPR_ERR_INJ_MASK_CFG_LSH PPC_BITLSHIFT(11)
-#define PHB_PAPR_ERR_INJ_MASK_MMIO_MASK PPC_BITMASK(14,40) /* 8M aligned */
-#define PHB_PAPR_ERR_INJ_MASK_MMIO_LSH PPC_BITLSHIFT(40)
+#define PHB_PAPR_ERR_INJ_MASK_MMIO_MASK PPC_BITMASK(16,63)
+#define PHB_PAPR_ERR_INJ_MASK_MMIO_LSH PPC_BITLSHIFT(63)
#define PHB_ETU_ERR_SUMMARY 0x2c8
/* UTL registers */