summaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2015-06-29 10:44:22 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-07-03 07:23:57 +1000
commit83637485080bc38a0792b1d9b7b3c8a191c070e4 (patch)
tree21f6722431a69ec016a17a33b07609a7331d0b34 /hw
parentb2636472eef708006a017fa3858ac754968e6cc9 (diff)
downloadtalos-skiboot-83637485080bc38a0792b1d9b7b3c8a191c070e4.tar.gz
talos-skiboot-83637485080bc38a0792b1d9b7b3c8a191c070e4.zip
hw/phb3: Fix M64 error injection for VFs
The last M64 (64-bits MMIO) BAR is always enabled and it is equal to the PHB's M64 window. Also, the BAR is split to 256 segments and each PE will have one segment in it. However, the VF PE takes another BAR other than the last one to accomodate its M64 resources. So current code will always give wrong M64 base address and size when injecting M64 error for specified VF PE. In order to fix the issue, we have to recognize the type of the target PE: (A) bus dependent or (B) PCI device (VF) dependent. For (A), we figure out the M64 base address and length from the last M64 BAR. For (B), we scan from BAR#0 to BAR#14 and first hit wins. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/phb3.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/hw/phb3.c b/hw/phb3.c
index 009790e3..df9d57c1 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -2818,10 +2818,27 @@ static int64_t phb3_err_inject_mem64(struct phb3 *p, uint32_t pe_no,
uint64_t base, len, segstart, segsize;
uint64_t cache, a, m;
uint64_t ctrl = PHB_PAPR_ERR_INJ_CTL_OUTB;
- uint32_t index;
+ uint32_t index, s_index, e_index;
+
+ /* By default, the PE is PCI device dependent one */
+ s_index = 0;
+ e_index = ARRAY_SIZE(p->m64b_cache) - 2;
+ for (index = 0; index < RTT_TABLE_ENTRIES; index++) {
+ if (p->rte_cache[index] != pe_no)
+ continue;
+
+ if (index + 8 >= RTT_TABLE_ENTRIES)
+ break;
+
+ /* PCI bus dependent PE */
+ if (p->rte_cache[index + 8] == pe_no) {
+ s_index = e_index = ARRAY_SIZE(p->m64b_cache) - 1;
+ break;
+ }
+ }
a = base = len = 0x0ull;
- for (index = 0; index < ARRAY_SIZE(p->m64b_cache); index++) {
+ for (index = s_index; !len && index <= e_index; index++) {
cache = p->m64b_cache[index];
if (!(cache & IODA2_M64BT_ENABLE))
continue;
@@ -2845,24 +2862,18 @@ static int64_t phb3_err_inject_mem64(struct phb3 *p, uint32_t pe_no,
segstart = segstart + segsize * pe_no;
}
- /* We expect contiguous segments. Otherwise, to
- * pick the bigger one, which has more possibility
- * to be accessed
+ /* First window always wins based on the ascending
+ * searching priority the 16 BARs have. We're using
+ * the feature to assign resource for SRIOV VFs.
*/
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;
}
}
OpenPOWER on IntegriCloud