diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/lib/fm/topo/modules/common/pcibus/did.c | 203 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/modules/common/pcibus/did.h | 4 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c | 17 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.c | 29 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/modules/i86pc/hostbridge/Makefile | 6 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/modules/i86pc/pcibus/Makefile | 7 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.c | 83 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.h | 296 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/modules/sun4/hostbridge/Makefile.hb | 6 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/modules/sun4/ioboard/Makefile.iob | 6 | ||||
-rw-r--r-- | usr/src/lib/fm/topo/modules/sun4/pcibus/Makefile.pci | 6 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/pci_bios.c | 7 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/startup.c | 11 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pci/pci_boot.c | 34 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pciex/pcie_nvidia.c | 12 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pciex/pcie_nvidia.h | 5 |
16 files changed, 554 insertions, 178 deletions
diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/did.c b/usr/src/lib/fm/topo/modules/common/pcibus/did.c index 9920ddd914..4ecb3f5aee 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus/did.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/did.c @@ -20,8 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -81,37 +80,6 @@ slotnm_destroy(slotnm_t *p) } static int -slotnm_cp(did_t *from, did_t *to, int *nslots) -{ - slotnm_t *nxt, *new; - slotnm_t *last = NULL; - - *nslots = 0; - for (nxt = from->dp_slotnames; nxt != NULL; nxt = nxt->snm_next) { - new = slotnm_create(to->dp_mod, nxt->snm_dev, nxt->snm_name); - if (new == NULL) { - if (to->dp_slotnames != NULL) - slotnm_destroy(to->dp_slotnames); - to->dp_slotnames = NULL; - *nslots = 0; - return (-1); - } - if (last == NULL) { - to->dp_slotnames = last = new; - } else { - last->snm_next = new; - last = new; - } - (*nslots)++; - } - if (*nslots > 0) - topo_mod_dprintf(to->dp_mod, - "%p inherits %d slot label(s) from %p.\n", - to, *nslots, from); - return (0); -} - -static int di_devtype_get(topo_mod_t *mp, di_node_t src, char **devtype) { int sz; @@ -134,18 +102,41 @@ di_devtype_get(topo_mod_t *mp, di_node_t src, char **devtype) return (-1); } +typedef struct smbios_slot_cb { + int cb_slotnum; + const char *cb_label; +} smbios_slot_cb_t; + +static int +di_smbios_find_slot(smbios_hdl_t *shp, const smbios_struct_t *strp, void *data) +{ + smbios_slot_cb_t *cbp = data; + smbios_slot_t slot; + + if (strp->smbstr_type != SMB_TYPE_SLOT || + smbios_info_slot(shp, strp->smbstr_id, &slot) != 0) + return (0); + + if (slot.smbl_id == cbp->cb_slotnum) { + cbp->cb_label = slot.smbl_name; + return (1); + } + + return (0); +} + static int di_physlotinfo_get(topo_mod_t *mp, di_node_t src, int *slotnum, char **slotname) { char *slotbuf; int sz; uchar_t *buf; + smbios_hdl_t *shp; + boolean_t got_slotprop = B_FALSE; *slotnum = -1; - (void) di_uintprop_get(mp, src, DI_PHYSPROP, (uint_t *)slotnum); - if (*slotnum == -1) - return (0); + (void) di_uintprop_get(mp, src, DI_PHYSPROP, (uint_t *)slotnum); /* * For PCI-Express, there is only one downstream device, so check for @@ -154,9 +145,48 @@ di_physlotinfo_get(topo_mod_t *mp, di_node_t src, int *slotnum, char **slotname) */ if (di_bytes_get(mp, src, DI_SLOTPROP, &sz, &buf) == 0 && sz > 4) { + /* + * If there is a DI_SLOTPROP of the form SlotX (ie set up from + * the IRQ routing table) then trust that in preference to + * DI_PHYSPROP (which is set up from the PCIe slotcap reg). + */ + got_slotprop = B_TRUE; + (void) sscanf((char *)&buf[4], "Slot%d", slotnum); + } + + if (*slotnum == -1) + return (0); + + /* + * Order of preference + * 1) take slotnum and look up in SMBIOS table + * 2) use slot-names + * 3) fabricate name based on slotnum + */ + if ((shp = topo_mod_smbios(mp)) != NULL) { + /* + * The PCI spec describes slot number 0 as reserved for + * internal PCI devices. Not all platforms respect + * this, so we have to treat slot 0 as a valid device. + * But other platforms use 0 to identify an internal + * device. We deal with this by letting SMBIOS be the + * final decision maker. If SMBIOS is supported, but + * the given slot number is not represented in the + * SMBIOS tables, then ignore the slot entirely. + */ + smbios_slot_cb_t cbdata; + + cbdata.cb_slotnum = *slotnum; + cbdata.cb_label = NULL; + if (smbios_iter(shp, di_smbios_find_slot, &cbdata) <= 0) + return (0); + slotbuf = (char *)cbdata.cb_label; + topo_mod_dprintf(mp, "%s: node=%p: using smbios name\n", + __func__, src); + } else if (got_slotprop == B_TRUE) { slotbuf = (char *)&buf[4]; - topo_mod_dprintf(mp, "di_physlotinfo_get: node=%p: " - "found %s property\n", src, DI_SLOTPROP); + topo_mod_dprintf(mp, "%s: node=%p: found %s property\n", + __func__, src, DI_SLOTPROP); } else { /* * Make generic description string "SLOT <num>", allow up to @@ -164,14 +194,14 @@ di_physlotinfo_get(topo_mod_t *mp, di_node_t src, int *slotnum, char **slotname) */ slotbuf = alloca(16); (void) snprintf(slotbuf, 16, "SLOT %d", *slotnum); - topo_mod_dprintf(mp, "di_physlotinfo_get: node=%p: " - "using generic slot name\n", src); + topo_mod_dprintf(mp, "%s: node=%p: using generic slot name\n", + __func__, src); } if ((*slotname = topo_mod_strdup(mp, slotbuf)) == NULL) return (-1); - topo_mod_dprintf(mp, "di_physlotinfo_get: node=%p: slotname=%s\n", - src, *slotname); + topo_mod_dprintf(mp, "%s: node=%p: slotname=%s\n", + __func__, src, *slotname); return (0); } @@ -290,26 +320,29 @@ did_create(topo_mod_t *mp, di_node_t src, * There *may* be a device type we can capture. */ (void) di_devtype_get(mp, src, &np->dp_devtype); - /* - * There *may* be a physical slot number property we can capture. - */ - if (di_physlotinfo_get(mp, - src, &np->dp_physlot, &np->dp_physlot_name) < 0) { - if (np->dp_devtype != NULL) - topo_mod_strfree(mp, np->dp_devtype); - topo_mod_free(mp, np, sizeof (did_t)); - return (NULL); - } - /* - * There *may* be PCI slot info we can capture - */ - if (di_slotinfo_get(mp, src, &np->dp_nslots, &np->dp_slotnames) < 0) { - if (np->dp_devtype != NULL) - topo_mod_strfree(mp, np->dp_devtype); - if (np->dp_physlot_name != NULL) - topo_mod_strfree(mp, np->dp_physlot_name); - topo_mod_free(mp, np, sizeof (did_t)); - return (NULL); + + if (irc >= 0) { + /* + * This is a pciex node. + */ + if (di_physlotinfo_get(mp, src, &np->dp_physlot, + &np->dp_physlot_name) < 0) { + if (np->dp_devtype != NULL) + topo_mod_strfree(mp, np->dp_devtype); + topo_mod_free(mp, np, sizeof (did_t)); + return (NULL); + } + } else { + /* + * This is a pci node. + */ + if (di_slotinfo_get(mp, src, &np->dp_nslots, + &np->dp_slotnames) < 0) { + if (np->dp_devtype != NULL) + topo_mod_strfree(mp, np->dp_devtype); + topo_mod_free(mp, np, sizeof (did_t)); + return (NULL); + } } did_hash_insert(mp, src, np); did_hold(np); @@ -451,13 +484,6 @@ did_rc(did_t *did) return (did->dp_rc); } -static int -did_numlabels(did_t *dp) -{ - assert(dp != NULL); - return (dp->dp_nslots); -} - int did_excap(did_t *dp) { @@ -484,8 +510,16 @@ did_physlot_name(did_t *dp, int dev) slotnm_t *slot; assert(dp != NULL); + + /* + * For pciex, name will be in dp_physlot_name + */ if (dp->dp_physlot_name != NULL) return (dp->dp_physlot_name); + + /* + * For pci, name will be in dp_slotnames + */ for (slot = dp->dp_slotnames; slot != NULL; slot = slot->snm_next) if (slot->snm_dev == dev) break; @@ -567,37 +601,6 @@ pciex_cap_get(topo_mod_t *mp, di_node_t dn) return (dp->dp_excap); } -int -did_inherit(did_t *pdp, did_t *dp) -{ - /* - * If the child already has a label, we're done. - */ - assert(dp != NULL); - if (did_numlabels(dp) > 0) - return (0); - - assert(pdp != NULL); - - /* - * If the child and parent are the same, we're done. - */ - if (dp == pdp) - return (0); - - if (pdp->dp_physlot_name != NULL) { - topo_mod_dprintf(dp->dp_mod, - "%p inherits physlot label from %p.\n", dp, pdp); - dp->dp_physlot_name = - topo_mod_strdup(dp->dp_mod, pdp->dp_physlot_name); - if (dp->dp_physlot_name == NULL) - return (-1); - } - if (slotnm_cp(pdp, dp, &dp->dp_nslots) < 0) - return (-1); - return (0); -} - void did_setspecific(topo_mod_t *mp, void *data) { diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/did.h b/usr/src/lib/fm/topo/modules/common/pcibus/did.h index b5f6f68075..61e08150d8 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus/did.h +++ b/usr/src/lib/fm/topo/modules/common/pcibus/did.h @@ -20,8 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _DID_H @@ -60,7 +59,6 @@ extern int did_physlot(did_t *); extern int did_physlot_exists(did_t *); extern char *did_slot_label_get(did_t *); extern void did_slot_label_set(did_t *, char *); -extern int did_inherit(did_t *, did_t *); extern int did_excap(did_t *); extern void did_excap_set(did_t *, int); diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c index c3e406b486..b97ac2656c 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <sys/fm/protocol.h> @@ -597,15 +596,19 @@ pciexbus_enum(topo_mod_t *mp, tnode_t *ptn, char *pnm, topo_instance_t min, topo_instance_t max) { di_node_t pdn; - int rc; + int rc, hb; + tnode_t *hbtn; int retval; /* - * PCI-Express; root complex shares the hostbridge's instance - * number. Parent node's private data is a simple di_node_t + * PCI-Express; parent node's private data is a simple di_node_t * and we have to construct our own did hash and did_t. */ rc = topo_node_instance(ptn); + if ((hbtn = topo_node_parent(ptn)) != NULL) + hb = topo_node_instance(hbtn); + else + hb = rc; if ((pdn = topo_node_getspecific(ptn)) == DI_NODE_NIL) { topo_mod_dprintf(mp, @@ -615,10 +618,10 @@ pciexbus_enum(topo_mod_t *mp, tnode_t *ptn, char *pnm, topo_instance_t min, } if (did_hash_init(mp) != 0) return (-1); - if ((did_create(mp, pdn, 0, 0, rc, TRUST_BDF)) == NULL) + if ((did_create(mp, pdn, 0, hb, rc, TRUST_BDF)) == NULL) return (-1); /* errno already set */ - retval = pci_children_instantiate(mp, ptn, pdn, 0, 0, rc, + retval = pci_children_instantiate(mp, ptn, pdn, 0, hb, rc, (min == max) ? min : TRUST_BDF, 0); did_hash_fini(mp); diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.c b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.c index 5fd6f339c8..a7e59ec300 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.c @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <alloca.h> @@ -61,7 +60,7 @@ pci_label_physlot_lookup(topo_mod_t *mod, char *platform, did_t *dp) for (p = 0; p < Physlot_Names->psn_nplats; p++) { topo_mod_dprintf(mod, "%s: comparing against platform=%s\n", __func__, Physlot_Names->psn_names[p].pnm_platform); - if (strcmp(Physlot_Names->psn_names[p].pnm_platform, + if (strcasecmp(Physlot_Names->psn_names[p].pnm_platform, platform) != 0) continue; topo_mod_dprintf(mod, "%s: found lookup table for this " @@ -104,7 +103,7 @@ pci_label_slotname_lookup(topo_mod_t *mod, char *platform, for (s = 0; s < Slot_Rewrites->srw_nplats; s++) { topo_mod_dprintf(mod, "%s: comparing against platform=%s\n", __func__, Slot_Rewrites->srw_platrewrites[s].prw_platform); - if (strcmp(Slot_Rewrites->srw_platrewrites[s].prw_platform, + if (strcasecmp(Slot_Rewrites->srw_platrewrites[s].prw_platform, platform) != 0) continue; topo_mod_dprintf(mod, "%s: found lookup table for this " @@ -117,7 +116,8 @@ pci_label_slotname_lookup(topo_mod_t *mod, char *platform, if (strcmp(rw.srw_obp, label) == 0) { topo_mod_dprintf(mod, "%s: matched entry=%d, " "old_label=%s, new_label=%s\n", - __func__, i, rw.srw_obp, rw.srw_new); + __func__, i, rw.srw_obp, + rw.srw_new ? rw.srw_new : NULL); /* * If a test function is specified then call * it to do an additional check. @@ -139,8 +139,8 @@ pci_label_slotname_lookup(topo_mod_t *mod, char *platform, } break; } - assert(rlabel != NULL); - topo_mod_dprintf(mod, "%s: returning label=%s\n", __func__, rlabel); + topo_mod_dprintf(mod, "%s: returning label=%s\n", __func__, + rlabel ? rlabel : "NULL"); return (rlabel); } @@ -169,7 +169,7 @@ pci_label_missing_lookup(topo_mod_t *mod, char *platform, did_t *dp) for (p = 0; p < Missing_Names->mn_nplats; p++) { topo_mod_dprintf(mod, "%s: comparing against platform=%s\n", __func__, Missing_Names->mn_names[p].pdl_platform); - if (strcmp(Missing_Names->mn_names[p].pdl_platform, + if (strcasecmp(Missing_Names->mn_names[p].pdl_platform, platform) != 0) continue; topo_mod_dprintf(mod, "%s: found lookup table for this " @@ -178,8 +178,9 @@ pci_label_missing_lookup(topo_mod_t *mod, char *platform, did_t *dp) devlab_t m; m = Missing_Names->mn_names[p].pdl_names[i]; if (m.dl_board == board && m.dl_bridge == bridge && - m.dl_rc == rc && m.dl_bus == bus && - m.dl_dev == dev) { + m.dl_rc == rc && + (m.dl_bus == -1 || m.dl_bus == bus) && + (m.dl_dev == -1 || m.dl_dev == dev)) { topo_mod_dprintf(mod, "%s: matched entry=%d, " "label=%s\n", __func__, i, m.dl_label); /* @@ -195,11 +196,12 @@ pci_label_missing_lookup(topo_mod_t *mod, char *platform, did_t *dp) topo_mod_dprintf(mod, "%s: test function return=%d\n", __func__, ret); + if (ret) + break; } else { rlabel = m.dl_label; + break; } - - break; } } break; @@ -387,7 +389,8 @@ pci_slot_label_lookup(topo_mod_t *mod, tnode_t *node, did_t *dp, did_t *pdp) if ((l = (char *)did_physlot_name(pdp, d)) != NULL) { l = (char *) pci_label_slotname_lookup(mod, pp, l, dp); - } else { + } + if (l == NULL) { l = (char *) pci_label_missing_lookup(mod, pp, dp); } diff --git a/usr/src/lib/fm/topo/modules/i86pc/hostbridge/Makefile b/usr/src/lib/fm/topo/modules/i86pc/hostbridge/Makefile index bc863f51df..2642fa859a 100644 --- a/usr/src/lib/fm/topo/modules/i86pc/hostbridge/Makefile +++ b/usr/src/lib/fm/topo/modules/i86pc/hostbridge/Makefile @@ -19,10 +19,8 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # -# ident "%Z%%M% %I% %E% SMI" MODULE = hostbridge ARCH = i86pc @@ -35,7 +33,7 @@ MODULESRCS = $(HBSRCS) $(UTILSRCS) include ../../Makefile.plugin -LDLIBS += -ldevinfo +LDLIBS += -ldevinfo -lsmbios CPPFLAGS += -I$(UTILDIR) -I$(HBDIR) diff --git a/usr/src/lib/fm/topo/modules/i86pc/pcibus/Makefile b/usr/src/lib/fm/topo/modules/i86pc/pcibus/Makefile index 977e9df692..ec904260f1 100644 --- a/usr/src/lib/fm/topo/modules/i86pc/pcibus/Makefile +++ b/usr/src/lib/fm/topo/modules/i86pc/pcibus/Makefile @@ -20,10 +20,7 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" +# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # MODULE = pcibus @@ -38,6 +35,6 @@ MODULESRCS = $(UTILSRCS) $(PCISRCS) pci_i86pc.c include ../../Makefile.plugin -LDLIBS += -ldevinfo +LDLIBS += -ldevinfo -lsmbios CPPFLAGS += -I$(UTILDIR) -I$(HBDIR) diff --git a/usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.c b/usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.c index 770678a98a..7fef097c1c 100644 --- a/usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.c +++ b/usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.c @@ -20,12 +20,9 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <fm/topo_mod.h> #include "pcibus.h" @@ -33,9 +30,13 @@ #include <string.h> #include <strings.h> -slotnm_rewrite_t *Slot_Rewrites = NULL; -physlot_names_t *Physlot_Names = NULL; -missing_names_t *Missing_Names = NULL; +/* + * Including the following file gives us definitions of the three + * global arrays used to adjust labels, Slot_Rewrites, Physlot_Names, + * and Missing_Names. With those defined we can use the common labeling + * routines for pci. + */ +#include "pci_i86pc.h" int platform_pci_label(topo_mod_t *mod, tnode_t *node, nvlist_t *in, @@ -50,3 +51,71 @@ platform_pci_fru(topo_mod_t *mod, tnode_t *node, nvlist_t *in, { return (pci_fru_cmn(mod, node, in, out)); } + +/* + * return true if pciexbus node whose parent is a pciexrc node + */ +/*ARGSUSED*/ +int +parent_is_rc(topo_mod_t *mod, did_t *dp) +{ + return (strcmp(topo_node_name(did_gettnode(dp)), PCIEX_ROOT) == 0); +} + +/* + * Look for down-stream switch "2" on riser card. First find this node's parent. + * If it is a pciexfn node and it has dev=2 and node 6 levels further up + * from it has a physlot then return true. + */ +int +ba_is_2(topo_mod_t *mod, did_t *dp) +{ + tnode_t *ptp; + did_t *pdp; + int i, d; + + ptp = did_gettnode(dp); + if (strcmp(topo_node_name(ptp), PCIEX_FUNCTION) != 0) + return (0); + pdp = did_find(mod, topo_node_getspecific(ptp)); + if (!pdp) + return (0); + did_BDF(pdp, NULL, &d, NULL); + if (d != 2) + return (0); + + for (i = 0; i < 6; i++) + if ((ptp = topo_node_parent(ptp)) == NULL) + return (0); + pdp = did_find(mod, topo_node_getspecific(ptp)); + return (pdp && did_physlot_exists(pdp)); +} + +/* + * Look for down-stream switch "4" on riser card. First find this node's parent. + * If it is a pciexfn node and it has dev=4 and node 6 levels further up + * from it has a physlot then return true. + */ +int +ba_is_4(topo_mod_t *mod, did_t *dp) +{ + tnode_t *ptp; + did_t *pdp; + int i, d; + + ptp = did_gettnode(dp); + if (strcmp(topo_node_name(ptp), PCIEX_FUNCTION) != 0) + return (0); + pdp = did_find(mod, topo_node_getspecific(ptp)); + if (!pdp) + return (0); + did_BDF(pdp, NULL, &d, NULL); + if (d != 4) + return (0); + + for (i = 0; i < 6; i++) + if ((ptp = topo_node_parent(ptp)) == NULL) + return (0); + pdp = did_find(mod, topo_node_getspecific(ptp)); + return (pdp && did_physlot_exists(pdp)); +} diff --git a/usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.h b/usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.h new file mode 100644 index 0000000000..d6a4515b39 --- /dev/null +++ b/usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.h @@ -0,0 +1,296 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + */ + +#ifndef _PCI_I86PC_H +#define _PCI_I86PC_H + +#include <pcibus_labels.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Data for label lookup based on existing slot label. + * + * Platforms may need entries here if the slot labels + * provided by firmware are incorrect. + * + * Note that re-writing to NULL provides a way of getting rid of totally + * spurious labels. + */ + +slot_rwd_t x4600_rewrites[] = { + /* from hw, should be, test func */ + { "PCIX SLOT0", NULL, NULL }, + { "PCIX SLOT1", NULL, NULL }, + { "PCIX SLOT2", NULL, NULL }, + { "PCIExp SLOT2", NULL, NULL }, + { "PCIExp SLOT3", NULL, NULL }, + { "PCIExp SLOT4", NULL, NULL }, + { "PCIExp SLOT5", NULL, NULL }, + { "PCIExp SLOT6", NULL, NULL }, + { "PCIExp SLOT7", NULL, NULL }, + { "PCIExp SLOT8", NULL, NULL } +}; + +slot_rwd_t netra_x4200_rewrites[] = { + /* from hw, should be, test func */ + { "PCIExp SLOT1", NULL, NULL }, + { "PCIX SLOT2", NULL, NULL }, +}; + +slot_rwd_t x4250_rewrites[] = { + /* from hw, should be, test func */ + { "SLOT0", NULL, NULL }, + { "SLOT1", NULL, NULL }, + { "SLOT2", NULL, NULL } +}; + +plat_rwd_t plat_rewrites[] = { + { "Sun-Fire-X4600", + sizeof (x4600_rewrites) / sizeof (slot_rwd_t), + x4600_rewrites }, + { "Sun-Fire-X4600-M2", + sizeof (x4600_rewrites) / sizeof (slot_rwd_t), + x4600_rewrites }, + { "Sun-Fire-X4250", + sizeof (x4250_rewrites) / sizeof (slot_rwd_t), + x4250_rewrites }, + { "Netra-X4200-M2", + sizeof (netra_x4200_rewrites) / sizeof (slot_rwd_t), + netra_x4200_rewrites } +}; + +slotnm_rewrite_t SlotRWs = { + sizeof (plat_rewrites) / sizeof (plat_rwd_t), + plat_rewrites +}; + +/* + * Data for label lookup based on device info. + * + * Platforms need entries here if there is no physical slot number + * or slot-names. + */ + +extern int parent_is_rc(topo_mod_t *, did_t *); +extern int ba_is_2(topo_mod_t *, did_t *); +extern int ba_is_4(topo_mod_t *, did_t *); + +devlab_t x4600_missing[] = { + /* board, bridge, root-complex, bus, dev, label, test func */ + { 0, 2, 2, -1, -1, "PCIExp SLOT4", parent_is_rc }, + { 0, 3, 3, -1, -1, "PCIExp SLOT2", parent_is_rc }, + { 0, 4, 4, -1, -1, "PCIExp SLOT3", parent_is_rc }, + { 0, 8, 8, -1, -1, "PCIExp SLOT7", parent_is_rc }, + { 0, 9, 9, -1, -1, "PCIExp SLOT5", parent_is_rc }, + { 0, 10, 10, -1, -1, "PCIExp SLOT6", parent_is_rc } +}; + +devlab_t x4600m2_missing[] = { + /* board, bridge, root-complex, bus, dev, label, test func */ + { 0, 1, 1, -1, -1, "PCIExp SLOT4", parent_is_rc }, + { 0, 2, 2, -1, -1, "PCIExp SLOT2", parent_is_rc }, + { 0, 3, 3, -1, -1, "PCIExp SLOT3", parent_is_rc }, + { 0, 6, 6, -1, -1, "PCIExp SLOT7", parent_is_rc }, + { 0, 7, 7, -1, -1, "PCIExp SLOT5", parent_is_rc }, + { 0, 8, 8, -1, -1, "PCIExp SLOT6", parent_is_rc } +}; + +devlab_t x4250_missing[] = { + /* board, bridge, root-complex, bus, dev, label, test func */ + { 0, 0, 0, -1, -1, "PCIExp SLOT3", ba_is_2 }, + { 0, 0, 0, -1, -1, "PCIExp SLOT0", ba_is_4 }, + { 0, 2, 2, -1, -1, "PCIExp SLOT4", ba_is_2 }, + { 0, 2, 2, -1, -1, "PCIExp SLOT1", ba_is_4 }, + { 0, 4, 4, -1, -1, "PCIExp SLOT5", ba_is_2 }, + { 0, 4, 4, -1, -1, "PCIExp SLOT2", ba_is_4 } +}; + +devlab_t netra_x4200_missing[] = { + /* board, bridge, root-complex, bus, dev, label, test func */ + { 0, 4, 4, -1, -1, "PCIExp SLOT0", NULL }, + { 0, 0, 3 - TO_PCI, -1, -1, "PCIX SLOT", NULL }, + { 0, 0, 7 - TO_PCI, -1, -1, "PCIX SLOT", NULL } +}; + +pdevlabs_t plats_missing[] = { + { "Sun-Fire-X4600", + sizeof (x4600_missing) / sizeof (devlab_t), + x4600_missing }, + { "Sun-Fire-X4600-M2", + sizeof (x4600m2_missing) / sizeof (devlab_t), + x4600m2_missing }, + { "Sun-Fire-X4250", + sizeof (x4250_missing) / sizeof (devlab_t), + x4250_missing }, + { "Netra-X4200-M2", + sizeof (netra_x4200_missing) / sizeof (devlab_t), + netra_x4200_missing } +}; + +physnm_t x2100m2_pnms[] = { + /* Slot #, Label */ + { 37, "PCIe 0" }, + { 32, "PCIe 1" } +}; + +physnm_t x2200m2_pnms[] = { + /* Slot #, Label */ + { 37, "PCIe 0" }, + { 32, "PCIe 1" } +}; + +physnm_t x2250_pnms[] = { + /* Slot #, Label */ + { 6, "PCIe 0" } +}; + +physnm_t x2270_pnms[] = { + /* Slot #, Label */ + { 55, "PCIe 0" } +}; + +physnm_t x4170_pnms[] = { + /* Slot #, Label */ + { 1, "PCIe 0" }, + { 2, "PCIe 1" }, + { 3, "PCIe 2" } +}; + +physnm_t x4270_pnms[] = { + /* Slot #, Label */ + { 1, "PCIe 0" }, + { 2, "PCIe 1" }, + { 3, "PCIe 2" }, + { 4, "PCIe 3" }, + { 5, "PCIe 4" }, + { 6, "PCIe 5" } +}; + +physnm_t x4275_pnms[] = { + /* Slot #, Label */ + { 1, "PCIe 0" }, + { 2, "PCIe 1" }, + { 3, "PCIe 2" }, + { 4, "PCIe 3" }, + { 5, "PCIe 4" }, + { 6, "PCIe 5" } +}; + +physnm_t netra4270_pnms[] = { + /* Slot #, Label */ + { 1, "PCIe 0" }, + { 2, "PCIe 1" }, + { 3, "PCIe 2" }, + { 5, "PCIe 4" }, + { 6, "PCIe 5" } +}; + +physnm_t x4150_pnms[] = { + /* Slot #, Label */ + { 40, "PCIe 0" }, + { 48, "PCIe 1" }, + { 50, "PCIe 2" } +}; + +physnm_t x4450_pnms[] = { + /* Slot #, Label */ + { 52, "PCIe 0" }, + { 54, "PCIe 1" }, + { 40, "PCIe 2" }, + { 49, "PCIe 3" }, + { 51, "PCIe 4" }, + { 41, "PCIe 5" } +}; + +pphysnm_t plat_pnames[] = { + { "X2100-M2", + sizeof (x2100m2_pnms) / sizeof (physnm_t), + x2100m2_pnms }, + { "Sun-Fire-X2100-M2", + sizeof (x2100m2_pnms) / sizeof (physnm_t), + x2100m2_pnms }, + { "X2200-M2", + sizeof (x2200m2_pnms) / sizeof (physnm_t), + x2200m2_pnms }, + { "Sun-Fire-X2200-M2", + sizeof (x2200m2_pnms) / sizeof (physnm_t), + x2200m2_pnms }, + { "Sun-Fire-X2250", + sizeof (x2250_pnms) / sizeof (physnm_t), + x2250_pnms }, + { "Sun-Fire-X2270", + sizeof (x2270_pnms) / sizeof (physnm_t), + x2270_pnms }, + { "Sun-Fire-X4170", + sizeof (x4170_pnms) / sizeof (physnm_t), + x4170_pnms }, + { "Sun-Fire-X4270", + sizeof (x4270_pnms) / sizeof (physnm_t), + x4270_pnms }, + { "Sun-Fire-X4275", + sizeof (x4275_pnms) / sizeof (physnm_t), + x4275_pnms }, + { "Sun-Fire-X4170-Server", + sizeof (x4170_pnms) / sizeof (physnm_t), + x4170_pnms }, + { "Sun-Fire-X4270-Server", + sizeof (x4270_pnms) / sizeof (physnm_t), + x4270_pnms }, + { "Sun-Fire-X4275-Server", + sizeof (x4275_pnms) / sizeof (physnm_t), + x4275_pnms }, + { "Sun-Netra-X4270", + sizeof (netra4270_pnms) / sizeof (physnm_t), + netra4270_pnms }, + { "Sun-Fire-X4150", + sizeof (x4150_pnms) / sizeof (physnm_t), + x4150_pnms }, + { "Sun-Fire-X4450", + sizeof (x4450_pnms) / sizeof (physnm_t), + x4450_pnms } +}; + +missing_names_t Missing = { + sizeof (plats_missing) / sizeof (pdevlabs_t), + plats_missing +}; + +physlot_names_t PhyslotNMs = { + sizeof (plat_pnames) / sizeof (pphysnm_t), + plat_pnames +}; + +slotnm_rewrite_t *Slot_Rewrites = &SlotRWs; +physlot_names_t *Physlot_Names = &PhyslotNMs; +missing_names_t *Missing_Names = &Missing; + +#ifdef __cplusplus +} +#endif + +#endif /* _PCI_I86PC_H */ diff --git a/usr/src/lib/fm/topo/modules/sun4/hostbridge/Makefile.hb b/usr/src/lib/fm/topo/modules/sun4/hostbridge/Makefile.hb index d38f073aa8..7d610c9b9c 100644 --- a/usr/src/lib/fm/topo/modules/sun4/hostbridge/Makefile.hb +++ b/usr/src/lib/fm/topo/modules/sun4/hostbridge/Makefile.hb @@ -20,10 +20,8 @@ # # -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # -# ident "%Z%%M% %I% %E% SMI" MODULE = hostbridge CLASS = arch @@ -35,7 +33,7 @@ MODULESRCS = $(HBSRCS) $($(ARCH)_SRCS) include ../../Makefile.plugin -LDLIBS += -ldevinfo +LDLIBS += -ldevinfo -lsmbios CPPFLAGS += -I$(SUN4DIR) -I$(UTILDIR) -I$(HBDIR) %.o: $(SUN4DIR)/%.c diff --git a/usr/src/lib/fm/topo/modules/sun4/ioboard/Makefile.iob b/usr/src/lib/fm/topo/modules/sun4/ioboard/Makefile.iob index 68a6bfeef5..95828ddc1a 100644 --- a/usr/src/lib/fm/topo/modules/sun4/ioboard/Makefile.iob +++ b/usr/src/lib/fm/topo/modules/sun4/ioboard/Makefile.iob @@ -20,10 +20,8 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # -# ident "%Z%%M% %I% %E% SMI" MODULE = ioboard SUN4DIR = ../../sun4/$(MODULE) @@ -35,7 +33,7 @@ MODULESRCS = $(UTILSRCS) $(IOBSRCS) iob_platform.c include ../../Makefile.plugin -LDLIBS += -ldevinfo +LDLIBS += -ldevinfo -lsmbios CPPFLAGS += -I$(UTILDIR) -I$(HBDIR) -I$(SUN4DIR) %.o: $(UTILDIR)/%.c diff --git a/usr/src/lib/fm/topo/modules/sun4/pcibus/Makefile.pci b/usr/src/lib/fm/topo/modules/sun4/pcibus/Makefile.pci index 507ff65970..916478491f 100644 --- a/usr/src/lib/fm/topo/modules/sun4/pcibus/Makefile.pci +++ b/usr/src/lib/fm/topo/modules/sun4/pcibus/Makefile.pci @@ -20,10 +20,8 @@ # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. # -# ident "%Z%%M% %I% %E% SMI" MODULE = pcibus CLASS = arch @@ -37,7 +35,7 @@ MODULESRCS = $(PCISRCS) $(UTILSRCS) pci_$(ARCH).c include ../../Makefile.plugin -LDLIBS += -ldevinfo +LDLIBS += -ldevinfo -lsmbios CPPFLAGS += -I$(SUN4DIR) -I$(UTILDIR) -I$(HBDIR) %.o: $(SUN4DIR)/%.c diff --git a/usr/src/uts/i86pc/os/pci_bios.c b/usr/src/uts/i86pc/os/pci_bios.c index c0553b3ca7..9ee865c7d2 100644 --- a/usr/src/uts/i86pc/os/pci_bios.c +++ b/usr/src/uts/i86pc/os/pci_bios.c @@ -19,12 +19,9 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/stat.h> #include <sys/sunndi.h> @@ -39,7 +36,7 @@ /* * pci irq routing information table */ -static int pci_irq_nroutes; +int pci_irq_nroutes; static pci_irq_route_t *pci_irq_routes; diff --git a/usr/src/uts/i86pc/os/startup.c b/usr/src/uts/i86pc/os/startup.c index c0e9c2404b..ad719dfcdd 100644 --- a/usr/src/uts/i86pc/os/startup.c +++ b/usr/src/uts/i86pc/os/startup.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 2010, Intel Corporation. @@ -688,7 +687,6 @@ startup(void) { #if !defined(__xpv) extern void startup_pci_bios(void); - extern int post_fastreboot; #endif extern cpuset_t cpu_ready_set; @@ -717,8 +715,11 @@ startup(void) startup_kmem(); startup_vm(); #if !defined(__xpv) - if (!post_fastreboot) - startup_pci_bios(); + /* + * Note we need to do this even on fast reboot in order to access + * the irq routing table (used for pci labels). + */ + startup_pci_bios(); #endif #if defined(__xpv) startup_xen_mca(); diff --git a/usr/src/uts/intel/io/pci/pci_boot.c b/usr/src/uts/intel/io/pci/pci_boot.c index d0e5f821b1..850a5124d6 100644 --- a/usr/src/uts/intel/io/pci/pci_boot.c +++ b/usr/src/uts/intel/io/pci/pci_boot.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <sys/types.h> @@ -1876,6 +1875,7 @@ process_devfunc(uchar_t bus, uchar_t dev, uchar_t func, uchar_t header, int pciex = 0; ushort_t is_pci_bridge = 0; struct pci_devfunc *devlist = NULL, *entry = NULL; + boolean_t slot_valid; gfx_entry_t *gfxp; pcie_req_id_t bdf; @@ -1935,8 +1935,8 @@ process_devfunc(uchar_t bus, uchar_t dev, uchar_t func, uchar_t header, ndi_devi_alloc_sleep(pci_bus_res[bus].dip, nodename, DEVI_SID_NODEID, &dip); - if (check_if_device_is_pciex(dip, bus, dev, func, &slot_num, - &is_pci_bridge) == B_TRUE) + if (check_if_device_is_pciex(dip, bus, dev, func, &slot_valid, + &slot_num, &is_pci_bridge) == B_TRUE) pciex = 1; bdf = PCI_GETBDF(bus, dev, func); @@ -2028,7 +2028,7 @@ process_devfunc(uchar_t bus, uchar_t dev, uchar_t func, uchar_t header, if (status & PCI_STAT_UDF) (void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip, "udf-supported"); - if (pciex && slot_num) { + if (pciex && slot_valid) { (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "physical-slot#", slot_num); if (!is_pci_bridge) @@ -3041,12 +3041,28 @@ add_bus_slot_names_prop(int bus) { char slotprop[256]; int len; + extern int pci_irq_nroutes; + char *slotcap_name; + /* + * If no irq routing table, then go with the slot-names as set up + * in pciex_slot_names_prop() from slot capability register (if any). + */ + if (pci_irq_nroutes == 0) + return; + + /* + * Otherise delete the slot-names we already have and use the irq + * routing table values as returned by pci_slot_names_prop() instead, + * but keep any property of value "pcie0" as that can't be represented + * in the irq routing table. + */ if (pci_bus_res[bus].dip != NULL) { - /* simply return if the property is already defined */ - if (ddi_prop_exists(DDI_DEV_T_ANY, pci_bus_res[bus].dip, - DDI_PROP_DONTPASS, "slot-names")) - return; + if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pci_bus_res[bus].dip, + DDI_PROP_DONTPASS, "slot-names", &slotcap_name) != + DDI_SUCCESS || strcmp(slotcap_name, "pcie0") != 0) + (void) ndi_prop_remove(DDI_DEV_T_NONE, + pci_bus_res[bus].dip, "slot-names"); } len = pci_slot_names_prop(bus, slotprop, sizeof (slotprop)); diff --git a/usr/src/uts/intel/io/pciex/pcie_nvidia.c b/usr/src/uts/intel/io/pciex/pcie_nvidia.c index 7bc62d4478..b792e6a564 100644 --- a/usr/src/uts/intel/io/pciex/pcie_nvidia.c +++ b/usr/src/uts/intel/io/pciex/pcie_nvidia.c @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -47,7 +46,8 @@ extern uint64_t mcfg_mem_base; boolean_t check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev, - uchar_t func, ushort_t *slot_number, ushort_t *is_pci_bridge) + uchar_t func, boolean_t *slot_valid, ushort_t *slot_number, + ushort_t *is_pci_bridge) { boolean_t found_pciex = B_FALSE; ushort_t cap; @@ -56,7 +56,7 @@ check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev, ushort_t status; uint32_t slot_cap; - *slot_number = 0; + *slot_valid = B_FALSE; status = (*pci_getw_func)(bus, dev, func, PCI_CONF_STAT); if (!(status & PCI_STAT_CAP)) @@ -93,6 +93,7 @@ check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev, /* offset 14h is Slot Cap Register */ slot_cap = (*pci_getl_func)(bus, dev, func, capsp + PCIE_SLOTCAP); + *slot_valid = B_TRUE; *slot_number = PCIE_SLOTCAP_PHY_SLOT_NUM(slot_cap); @@ -133,6 +134,7 @@ look_for_any_pciex_device(uchar_t bus) uchar_t dev, func; uchar_t nfunc, header; ushort_t venid, slot_num, is_pci_bridge = 0; + boolean_t slot_valid; for (dev = 0; dev < 32; dev++) { nfunc = 1; @@ -164,7 +166,7 @@ look_for_any_pciex_device(uchar_t bus) nfunc = 8; if (check_if_device_is_pciex(NULL, bus, dev, func, - &slot_num, &is_pci_bridge) == B_TRUE) + &slot_valid, &slot_num, &is_pci_bridge) == B_TRUE) return (B_TRUE); } /* end of func */ } /* end of dev */ diff --git a/usr/src/uts/intel/io/pciex/pcie_nvidia.h b/usr/src/uts/intel/io/pciex/pcie_nvidia.h index 2b01966385..e0624ab2cb 100644 --- a/usr/src/uts/intel/io/pciex/pcie_nvidia.h +++ b/usr/src/uts/intel/io/pciex/pcie_nvidia.h @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _PCIEX_PCI_NVIDIA_H @@ -36,7 +35,7 @@ extern "C" { */ boolean_t look_for_any_pciex_device(uchar_t); boolean_t check_if_device_is_pciex(dev_info_t *, uchar_t, uchar_t, - uchar_t, ushort_t *, ushort_t *); + uchar_t, boolean_t *, ushort_t *, ushort_t *); boolean_t create_pcie_root_bus(uchar_t, dev_info_t *); void add_nvidia_isa_bridge_props(dev_info_t *, uchar_t, uchar_t, uchar_t); |