aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2014-10-02 16:30:13 +1000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-10-08 14:07:46 +1100
commitc7e777f83513b74ebc53f9c37aa817caa7ec089d (patch)
tree87ad1da879b8f13bbde931eaac1521428be9053b
parent666ee3d06824400eff61c30d7722ea60d673fe8c (diff)
downloadskiboot-c7e777f83513b74ebc53f9c37aa817caa7ec089d.zip
skiboot-c7e777f83513b74ebc53f9c37aa817caa7ec089d.tar.gz
skiboot-c7e777f83513b74ebc53f9c37aa817caa7ec089d.tar.bz2
PHB3: Support MM64 error injection
The patch enables injecting PCI errors to 64-bits MMIO range. BZ: 115222 Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--hw/phb3.c88
1 files changed, 82 insertions, 6 deletions
diff --git a/hw/phb3.c b/hw/phb3.c
index b8019ac..9b6b4f8 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -2663,6 +2663,80 @@ static int64_t phb3_err_inject_mem32(struct phb3 *p, uint32_t pe_no,
return phb3_err_inject_finalize(p, a, m, ctrl, is_write);
}
+static int64_t phb3_err_inject_mem64(struct phb3 *p, uint32_t pe_no,
+ uint64_t addr, uint64_t mask,
+ bool is_write)
+{
+ uint64_t base, len, segstart, segsize;
+ uint64_t cache, a, m;
+ uint64_t ctrl = PHB_PAPR_ERR_INJ_CTL_OUTB;
+ uint32_t index;
+
+ a = base = len = 0x0ull;
+ for (index = 0; index < ARRAY_SIZE(p->m64b_cache); index++) {
+ cache = p->m64b_cache[index];
+ if (!(cache & IODA2_M64BT_ENABLE))
+ continue;
+
+ if (cache & IODA2_M64BT_SINGLE_PE) {
+ if (GETFIELD(IODA2_M64BT_PE_HI, cache) != (pe_no >> 5) ||
+ GETFIELD(IODA2_M64BT_PE_LOW, cache) != (pe_no & 0x1f))
+ continue;
+
+ segstart = GETFIELD(IODA2_M64BT_SINGLE_BASE, cache);
+ segstart <<= 25; /* 32MB aligned */
+ segsize = GETFIELD(IODA2_M64BT_SINGLE_MASK, cache);
+ segsize = (0x2000000ull - segsize) << 25;
+ } else {
+ segstart = GETFIELD(IODA2_M64BT_BASE, cache);
+ segstart <<= 20; /* 1MB aligned */
+ segsize = GETFIELD(IODA2_M64BT_MASK, cache);
+ segsize = (0x40000000ull - segsize) << 20;
+
+ segsize /= PHB3_MAX_PE_NUM;
+ segstart = segstart + segsize * pe_no;
+ }
+
+ /* We expect contiguous segments. Otherwise, to
+ * pick the bigger one, which has more possibility
+ * to be accessed
+ */
+ if (!len) {
+ base = segstart;
+ len = segsize;
+ } else if ((base + len) == segstart) {
+ len += segsize;
+ } else if (segsize > len) {
+ base = segstart;
+ len = segsize;
+ }
+
+ /* Specified address is valid one */
+ if (addr >= segstart && addr < (segstart + segsize)) {
+ a = addr;
+ break;
+ }
+ }
+
+ /* No MM64 segments assigned to the PE */
+ if (!len)
+ return OPAL_PARAMETER;
+
+ /* Address specified or calculated */
+ if (!a) {
+ 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);
+}
+
static int64_t phb3_err_inject_cfg(struct phb3 *p, uint32_t pe_no,
uint64_t addr, uint64_t mask,
bool is_write)
@@ -2717,10 +2791,6 @@ static int64_t phb3_err_inject(struct phb *phb, uint32_t pe_no,
uint64_t addr, uint64_t mask, bool is_write);
bool is_write;
- /* To support 64-bits error injection later */
- if (type == OPAL_ERR_INJECT_TYPE_IOA_BUS_ERR64)
- return OPAL_UNSUPPORTED;
-
/* How could we get here without valid RTT? */
if (!p->tbl_rtt)
return OPAL_HARDWARE;
@@ -2736,12 +2806,18 @@ static int64_t phb3_err_inject(struct phb *phb, uint32_t pe_no,
case OPAL_ERR_INJECT_FUNC_IOA_LD_MEM_ADDR:
case OPAL_ERR_INJECT_FUNC_IOA_LD_MEM_DATA:
is_write = false;
- handler = phb3_err_inject_mem32;
+ if (type == OPAL_ERR_INJECT_TYPE_IOA_BUS_ERR64)
+ handler = phb3_err_inject_mem64;
+ else
+ handler = phb3_err_inject_mem32;
break;
case OPAL_ERR_INJECT_FUNC_IOA_ST_MEM_ADDR:
case OPAL_ERR_INJECT_FUNC_IOA_ST_MEM_DATA:
is_write = true;
- handler = phb3_err_inject_mem32;
+ if (type == OPAL_ERR_INJECT_TYPE_IOA_BUS_ERR64)
+ handler = phb3_err_inject_mem64;
+ else
+ handler = phb3_err_inject_mem32;
break;
case OPAL_ERR_INJECT_FUNC_IOA_LD_CFG_ADDR:
case OPAL_ERR_INJECT_FUNC_IOA_LD_CFG_DATA: