aboutsummaryrefslogtreecommitdiff
path: root/core/pci.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2015-09-10 14:35:52 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-10-07 18:42:02 +1100
commit72f0f43d60718ff4de7430b425b430343223cbac (patch)
tree755a8abf2f14677ffe7e3e68eece92fba46f0b39 /core/pci.c
parent516424269edde1a53d40a34ecc540503b6e0b38b (diff)
downloadskiboot-72f0f43d60718ff4de7430b425b430343223cbac.zip
skiboot-72f0f43d60718ff4de7430b425b430343223cbac.tar.gz
skiboot-72f0f43d60718ff4de7430b425b430343223cbac.tar.bz2
pci: Use a fixed numbering of PHBs on OPAL and improve log consistency
On P8, we calculate the OPAL ID of the PHB as a function of the physical chip number and PHB index on that chip. P7 continues using "allocated" numbers for now. We also consistently print the PHB ID as a 4-digit hex number which facilitates decoding it, and print the chip:index location in the probe code to make it easier to correlate log entries. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> [stewart@linux.vnet.ibm.com: use next_chip rather than get_chip] Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/pci.c')
-rw-r--r--core/pci.c81
1 files changed, 49 insertions, 32 deletions
diff --git a/core/pci.c b/core/pci.c
index 6cfb3cb..c133dfe 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -22,27 +22,26 @@
#include <device.h>
#include <fsp.h>
-/* The eeh event code will need updating if this is ever increased to
- * support more than 64 phbs */
-static struct phb *phbs[64];
+#define MAX_PHB_ID 256
+static struct phb *phbs[MAX_PHB_ID];
#define PCITRACE(_p, _bdfn, fmt, a...) \
- prlog(PR_TRACE, "PHB%d:%02x:%02x.%x " fmt, \
+ prlog(PR_TRACE, "PHB#%04x:%02x:%02x.%x " fmt, \
(_p)->opal_id, \
((_bdfn) >> 8) & 0xff, \
((_bdfn) >> 3) & 0x1f, (_bdfn) & 0x7, ## a)
#define PCIDBG(_p, _bdfn, fmt, a...) \
- prlog(PR_DEBUG, "PHB%d:%02x:%02x.%x " fmt, \
+ prlog(PR_DEBUG, "PHB#%04x:%02x:%02x.%x " fmt, \
(_p)->opal_id, \
((_bdfn) >> 8) & 0xff, \
((_bdfn) >> 3) & 0x1f, (_bdfn) & 0x7, ## a)
#define PCINOTICE(_p, _bdfn, fmt, a...) \
- prlog(PR_NOTICE, "PHB%d:%02x:%02x.%x " fmt, \
+ prlog(PR_NOTICE, "PHB#%04x:%02x:%02x.%x " fmt, \
(_p)->opal_id, \
((_bdfn) >> 8) & 0xff, \
((_bdfn) >> 3) & 0x1f, (_bdfn) & 0x7, ## a)
#define PCIERR(_p, _bdfn, fmt, a...) \
- prlog(PR_ERR, "PHB%d:%02x:%02x.%x " fmt, \
+ prlog(PR_ERR, "PHB#%04x:%02x:%02x.%x " fmt, \
(_p)->opal_id, \
((_bdfn) >> 8) & 0xff, \
((_bdfn) >> 3) & 0x1f, (_bdfn) & 0x7, ## a)
@@ -536,7 +535,7 @@ static uint8_t pci_scan(struct phb *phb, uint8_t bus, uint8_t max_bus,
* bridge (when we need to give aligned powers of two's
* on P7IOC). If is is set to false, we just adjust the
* subordinate bus number based on what we probed.
- *
+ *
*/
max_bus = save_max;
next_bus = phb->ops->choose_bus(phb, pd, next_bus,
@@ -787,28 +786,38 @@ static void pci_scan_phb(void *data)
pci_walk_dev(phb, pci_configure_mps, NULL);
}
-int64_t pci_register_phb(struct phb *phb)
+int64_t pci_register_phb(struct phb *phb, int opal_id)
{
- int64_t rc = OPAL_SUCCESS;
- unsigned int i;
-
- /* This is called at init time in non-concurrent way, so no lock needed */
- for (i = 0; i < ARRAY_SIZE(phbs); i++)
- if (!phbs[i])
- break;
- if (i >= ARRAY_SIZE(phbs)) {
- prerror("PHB: Failed to find a free ID slot\n");
- rc = OPAL_RESOURCE;
+ /* The user didn't specify an opal_id, allocate one */
+ if (opal_id < 0) {
+ /* This is called at init time in non-concurrent way, so no lock needed */
+ for (opal_id = 0; opal_id < ARRAY_SIZE(phbs); opal_id++)
+ if (!phbs[opal_id])
+ break;
+ if (opal_id >= ARRAY_SIZE(phbs)) {
+ prerror("PHB: Failed to find a free ID slot\n");
+ return OPAL_RESOURCE;
+ }
} else {
- phbs[i] = phb;
- phb->opal_id = i;
- dt_add_property_cells(phb->dt_node, "ibm,opal-phbid",
- 0, phb->opal_id);
- PCIDBG(phb, 0, "PCI: Registered PHB\n");
+ if (opal_id >= ARRAY_SIZE(phbs)) {
+ prerror("PHB: ID %d out of range !\n", opal_id);
+ return OPAL_PARAMETER;
+ }
+ /* The user did specify an opal_id, check it's free */
+ if (phbs[opal_id]) {
+ prerror("PHB: Duplicate registration of ID %d\n", opal_id);
+ return OPAL_PARAMETER;
+ }
}
+
+ phbs[opal_id] = phb;
+ phb->opal_id = opal_id;
+ dt_add_property_cells(phb->dt_node, "ibm,opal-phbid", 0, phb->opal_id);
+ PCIDBG(phb, 0, "PCI: Registered PHB\n");
+
list_head_init(&phb->devices);
- return rc;
+ return OPAL_SUCCESS;
}
int64_t pci_unregister_phb(struct phb *phb)
@@ -1188,10 +1197,15 @@ static void pci_add_loc_code(struct dt_node *np, struct pci_device *pd)
uint8_t class, sub;
uint8_t pos, len;
- /* Look for a parent with a slot-location-code */
- while (p && !blcode) {
- blcode = dt_prop_get_def(p, "ibm,slot-location-code", NULL);
- p = p->parent;
+ /* If there is a label assigned to the function, use it on openpower machines */
+ if (pd->slot_info && strlen(pd->slot_info->label) && !fsp_present()) {
+ blcode = pd->slot_info->label;
+ } else {
+ /* Look for a parent with a slot-location-code */
+ while (p && !blcode) {
+ blcode = dt_prop_get_def(p, "ibm,slot-location-code", NULL);
+ p = p->parent;
+ }
}
if (!blcode)
return;
@@ -1349,8 +1363,8 @@ static void pci_add_one_node(struct phb *phb, struct pci_device *pd,
* - ...
*/
- /* Add slot properties if needed */
- if (pd->slot_info)
+ /* Add slot properties if needed and iff this is a bridge */
+ if (pd->slot_info && pd->is_bridge)
pci_add_slot_properties(phb, pd->slot_info, np);
/* Make up location code */
@@ -1448,9 +1462,11 @@ void pci_reset(void)
static void pci_do_jobs(void (*fn)(void *))
{
- void *jobs[ARRAY_SIZE(phbs)];
+ struct cpu_job **jobs;
int i;
+ jobs = zalloc(sizeof(struct cpu_job *) * ARRAY_SIZE(phbs));
+ assert(jobs);
for (i = 0; i < ARRAY_SIZE(phbs); i++) {
if (!phbs[i]) {
jobs[i] = NULL;
@@ -1473,6 +1489,7 @@ static void pci_do_jobs(void (*fn)(void *))
cpu_wait_job(jobs[i], true);
}
+ free(jobs);
}
void pci_init_slots(void)