diff options
author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2015-06-29 10:44:22 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-07-03 07:23:57 +1000 |
commit | 83637485080bc38a0792b1d9b7b3c8a191c070e4 (patch) | |
tree | 21f6722431a69ec016a17a33b07609a7331d0b34 /hw | |
parent | b2636472eef708006a017fa3858ac754968e6cc9 (diff) | |
download | talos-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.c | 33 |
1 files changed, 22 insertions, 11 deletions
@@ -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; } } |