diff options
Diffstat (limited to 'usr/src')
20 files changed, 373 insertions, 1595 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 7c13a73942..40c83a808e 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus/did.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/did.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * did.c * The acronym did means "Dev-Info-Data". Many properties and @@ -114,27 +112,37 @@ slotnm_cp(did_t *from, did_t *to, int *nslots) } static int -di_physlotinfo_get(topo_mod_t *mp, di_node_t src, uint_t excap, - int *slotnum, char **slotnm) +di_devtype_get(topo_mod_t *mp, di_node_t src, char **devtype) { - char *slotbuf; int sz; uchar_t *buf; - *slotnum = -1; - (void) di_uintprop_get(mp, src, DI_PHYSPROP, (uint_t *)slotnum); /* - * If no physical slot number property was found, then the - * capabilities register may indicate the pci-express device - * implements a slot, and we should record which slot. + * For PCI the device type defined the type of device directly below. + * For PCIe RP and Switches, the device-type should be "pciex". For + * PCIe-PCI and PCI-PCI bridges it should be "pci". NICs = "network", + * Graphics = "display", etc.. */ - if (*slotnum == -1 && (excap & PCIE_PCIECAP_SLOT_IMPL) != 0) { - uint_t slotcap; - int e; - e = di_uintprop_get(mp, src, "pcie-slotcap-reg", &slotcap); - if (e == 0) - *slotnum = slotcap >> PCIE_SLOTCAP_PHY_SLOT_NUM_SHIFT; + if (di_bytes_get(mp, src, DI_DEVTYPPROP, &sz, &buf) == 0) { + *devtype = topo_mod_strdup(mp, (char *)buf); + } else { + *devtype = NULL; } + + if (*devtype != NULL) + return (0); + return (-1); +} + +static int +di_physlotinfo_get(topo_mod_t *mp, di_node_t src, int *slotnum, char **slotnm) +{ + char *slotbuf; + int sz; + uchar_t *buf; + + *slotnum = -1; + (void) di_uintprop_get(mp, src, DI_PHYSPROP, (uint_t *)slotnum); if (*slotnum == -1) return (0); @@ -263,16 +271,16 @@ did_create(topo_mod_t *mp, di_node_t src, np->dp_class = -1; } /* - * There *may* be a PCI-express capabilities register we can capture. - * If there wasn't one, the capabilities will be the out-of-bounds - * value of zero. + * There *may* be a device type we can capture. */ - (void) di_uintprop_get(mp, src, "pcie-capid-reg", &np->dp_excap); + (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_excap, &np->dp_physlot, &np->dp_physlot_label) < 0) { + src, &np->dp_physlot, &np->dp_physlot_label) < 0) { + if (np->dp_devtype != NULL) + topo_mod_strfree(mp, np->dp_devtype); topo_mod_free(mp, np, sizeof (did_t)); return (NULL); } @@ -280,6 +288,8 @@ did_create(topo_mod_t *mp, di_node_t src, * 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_label != NULL) topo_mod_strfree(mp, np->dp_physlot_label); topo_mod_free(mp, np, sizeof (did_t)); @@ -345,6 +355,8 @@ did_destroy(did_t *dp) * code will need to change */ + if (dp->dp_devtype != NULL) + topo_mod_strfree(dp->dp_mod, dp->dp_devtype); if (dp->dp_physlot_label != NULL) topo_mod_strfree(dp->dp_mod, dp->dp_physlot_label); slotnm_destroy(dp->dp_slotnames); @@ -435,6 +447,12 @@ did_excap(did_t *dp) return ((int)dp->dp_excap); } +void +did_excap_set(did_t *dp, int type) +{ + dp->dp_excap = type; +} + int did_bdf(did_t *dp) { @@ -495,6 +513,17 @@ pci_classcode_get(topo_mod_t *mp, di_node_t dn, uint_t *class, uint_t *sub) return (0); } +char * +pci_devtype_get(topo_mod_t *mp, di_node_t dn) +{ + did_t *dp; + + if ((dp = did_find(mp, dn)) == NULL) + return (NULL); + did_rele(dp); + return (dp->dp_devtype); +} + int pciex_cap_get(topo_mod_t *mp, di_node_t dn) { 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 8d1a941562..66bccde65f 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus/did.h +++ b/usr/src/lib/fm/topo/modules/common/pcibus/did.h @@ -20,15 +20,13 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _DID_H #define _DID_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/pci.h> #include <fm/topo_mod.h> #include <libdevinfo.h> @@ -61,6 +59,7 @@ extern int did_rc(did_t *); extern int did_physslot(did_t *); extern int did_inherit(did_t *, did_t *); extern int did_excap(did_t *); +extern void did_excap_set(did_t *, int); extern int did_bdf(did_t *); extern did_t *did_link_get(did_t *); extern did_t *did_chain_get(did_t *); diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h b/usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h index e6a4218794..53642e0df5 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h +++ b/usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h @@ -20,15 +20,13 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _DID_IMPL_H #define _DID_IMPL_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/pci.h> #include <fm/libtopo.h> #include <libdevinfo.h> @@ -70,11 +68,12 @@ struct did { topo_mod_t *dp_mod; /* module that allocated the did private data */ di_node_t dp_src; /* di_node_t from which the info was derived */ int dp_refcnt; /* multiple nodes allowed to point at a did_t */ - uint_t dp_excap; /* PCI-Express capabilities */ + uint_t dp_excap; /* PCI-Express port/device type */ int dp_physlot; /* PCI-Express physical slot # */ char *dp_physlot_label; /* PCI-Express slot implemented */ int dp_class; /* PCI class */ int dp_subclass; /* PCI subclass */ + char *dp_devtype; /* PCI 1275 spec device-type */ int dp_board; /* Board number */ int dp_bridge; /* Bridge number */ int dp_rc; /* Root Complex number */ diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/did_props.c b/usr/src/lib/fm/topo/modules/common/pcibus/did_props.c index 07406fdb4e..3724e78c5a 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus/did_props.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/did_props.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <assert.h> #include <alloca.h> #include <string.h> @@ -446,7 +444,7 @@ FRU_fmri_set(topo_mod_t *mp, tnode_t *tn) return (0); } -static tnode_t * +tnode_t * find_predecessor(tnode_t *tn, char *mod_name) { tnode_t *pnode = topo_node_parent(tn); @@ -620,13 +618,10 @@ static int EXCAP_set(tnode_t *tn, did_t *pd, const char *dpnm, const char *tpgrp, const char *tpnm) { - int excap; + int excap = did_excap(pd); int err; int e = 0; - if ((excap = did_excap(pd)) <= 0) - return (0); - switch (excap & PCIE_PCIECAP_DEV_TYPE_MASK) { case PCIE_PCIECAP_DEV_TYPE_ROOT: e = topo_prop_set_string(tn, TOPO_PGROUP_PCI, diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/did_props.h b/usr/src/lib/fm/topo/modules/common/pcibus/did_props.h index af2e2a5316..20ae8a5b3e 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus/did_props.h +++ b/usr/src/lib/fm/topo/modules/common/pcibus/did_props.h @@ -27,8 +27,6 @@ #ifndef _DID_PROPS_H #define _DID_PROPS_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/pci.h> #include <fm/topo_mod.h> #include <libdevinfo.h> @@ -72,7 +70,9 @@ typedef struct txprop { #define DI_AADDRPROP "assigned-addresses" extern int did_props_set(tnode_t *, did_t *, txprop_t[], int); +extern tnode_t *find_predecessor(tnode_t *, char *); +extern char *pci_devtype_get(topo_mod_t *, di_node_t); extern int pciex_cap_get(topo_mod_t *, di_node_t); extern int pci_BDF_get(topo_mod_t *, di_node_t, int *, int *, int *); extern int pci_classcode_get(topo_mod_t *, di_node_t, uint_t *, uint_t *); 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 e22f562f6d..5c1f8c8554 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/fm/protocol.h> #include <assert.h> #include <stdio.h> @@ -161,10 +159,70 @@ pciexfn_declare(topo_mod_t *mod, tnode_t *parent, di_node_t dn, topo_instance_t i) { did_t *pd; - tnode_t *ntn; + tnode_t *ntn, *ptn; + di_node_t pdn; + uint_t class, subclass; + char *devtyp, *pdevtyp; + int pcie_devtyp, pexcap; + boolean_t dev_is_pcie, pdev_is_pcie; + + /* We need the parent's dev info node for some of the info */ + ptn = find_predecessor(parent, PCIEX_FUNCTION); + /* If this is the first child under root, get root's ptn */ + if (ptn == NULL) + ptn = find_predecessor(parent, PCIEX_ROOT); + if (ptn == NULL) + return (NULL); + pdn = topo_node_getspecific(ptn); + + /* Get the required info to populate the excap */ + (void) pci_classcode_get(mod, dn, &class, &subclass); + devtyp = pci_devtype_get(mod, dn); + pdevtyp = pci_devtype_get(mod, pdn); + pexcap = pciex_cap_get(mod, pdn); + + dev_is_pcie = devtyp && (strcmp(devtyp, "pciex") == 0); + pdev_is_pcie = pdevtyp && (strcmp(pdevtyp, "pciex") == 0); + + /* + * Populate the excap with correct PCIe device type. + * + * Device Parent Device Parent Device + * excap device-type device-type excap Class Code + * ------------------------------------------------------------------- + * PCI(default) pci N/A N/A != bridge + * PCIe pciex N/A N/A != bridge + * Root Port Defined in hostbridge + * Switch Up pciex pciex != up = bridge + * Switch Down pciex pciex = up = bridge + * PCIe-PCI pciex pci N/A = bridge + * PCI-PCIe pci pciex N/A = bridge + */ + pcie_devtyp = PCIE_PCIECAP_DEV_TYPE_PCI_DEV; + if (class == PCI_CLASS_BRIDGE && subclass == PCI_BRIDGE_PCI) { + if (pdev_is_pcie) { + if (dev_is_pcie) { + if (pexcap != PCIE_PCIECAP_DEV_TYPE_UP) + pcie_devtyp = PCIE_PCIECAP_DEV_TYPE_UP; + else + pcie_devtyp = + PCIE_PCIECAP_DEV_TYPE_DOWN; + } else { + pcie_devtyp = PCIE_PCIECAP_DEV_TYPE_PCIE2PCI; + } + } else { + if (dev_is_pcie) + pcie_devtyp = PCIE_PCIECAP_DEV_TYPE_PCI2PCIE; + } + } else { + if (pdev_is_pcie) + pcie_devtyp = PCIE_PCIECAP_DEV_TYPE_PCIE_DEV; + } if ((pd = did_find(mod, dn)) == NULL) return (NULL); + did_excap_set(pd, pcie_devtyp); + if ((ntn = pci_tnode_create(mod, parent, PCIEX_FUNCTION, i, dn)) == NULL) return (NULL); @@ -252,6 +310,8 @@ pcifn_declare(topo_mod_t *mod, tnode_t *parent, di_node_t dn, if ((pd = did_find(mod, dn)) == NULL) return (NULL); + did_excap_set(pd, PCIE_PCIECAP_DEV_TYPE_PCI_DEV); + if ((ntn = pci_tnode_create(mod, parent, PCI_FUNCTION, i, dn)) == NULL) return (NULL); if (did_props_set(ntn, pd, Fn_common_props, Fn_propcnt) < 0) { @@ -348,12 +408,12 @@ static int pci_bridge_declare(topo_mod_t *mod, tnode_t *fn, di_node_t din, int board, int bridge, int rc, int depth) { - int err, excap, extyp; + int err; + char *devtyp; - excap = pciex_cap_get(mod, din); - extyp = excap & PCIE_PCIECAP_DEV_TYPE_MASK; - if (excap <= 0 || - extyp != PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) + devtyp = pci_devtype_get(mod, din); + /* Check if the children are PCI or PCIe */ + if (strcmp(devtyp, "pciex") == 0) err = pci_children_instantiate(mod, fn, din, board, bridge, rc, TRUST_BDF, depth + 1); else diff --git a/usr/src/uts/common/io/pcie_fault.c b/usr/src/uts/common/io/pcie_fault.c index aadb8d11ad..94b7307919 100644 --- a/usr/src/uts/common/io/pcie_fault.c +++ b/usr/src/uts/common/io/pcie_fault.c @@ -1762,7 +1762,8 @@ pf_adjust_for_no_aer(pf_data_t *pfd_p) aer_ue &= ~PCIE_AER_UCE_CA; /* Check if the device sent a UR */ - if (!(status & PCIE_DEVSTS_UR_DETECTED)) + if (!(PCIE_ERR_REG(pfd_p)->pcie_err_status & + PCIE_DEVSTS_UR_DETECTED)) aer_ue &= ~PCIE_AER_UCE_UR; /* @@ -1782,7 +1783,7 @@ pf_adjust_for_no_aer(pf_data_t *pfd_p) * occur, SERR should be set since they are not masked. So if * SERR is not set, none of them occurred. */ - if (!(PCI_ERR_REG(pfd_p)->pci_err_status & PCI_STAT_S_SYSERR)) + if (!(status & PCI_STAT_S_SYSERR)) aer_ue &= ~PCIE_AER_UCE_TO; } diff --git a/usr/src/uts/common/os/pcifm.c b/usr/src/uts/common/os/pcifm.c index 6dd300d401..ca81c7fc9e 100644 --- a/usr/src/uts/common/os/pcifm.c +++ b/usr/src/uts/common/os/pcifm.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/sunndi.h> #include <sys/sysmacros.h> @@ -35,7 +33,7 @@ #include <sys/fm/io/pci.h> #include <sys/fm/io/ddi.h> #include <sys/pci.h> -#include <sys/pcie.h> +#include <sys/pci_cap.h> #include <sys/pci_impl.h> #include <sys/epm.h> #include <sys/pcifm.h> @@ -43,18 +41,6 @@ #define PCIX_ECC_VER_CHECK(x) (((x) == PCI_PCIX_VER_1) ||\ ((x) == PCI_PCIX_VER_2)) -/* - * Expected PCI Express error mask values - * - * !!NOTE!! All PCI Express functionality including PCIe initialization, PCIe - * error handling has been moved to the common pcie misc module. All functions - * and variables dealting with PCIe in this file have been deprecated and will - * be eventually removed. All Legacy PCI and PCI-X related code should remain - * as is. - */ -uint32_t pcie_aer_uce_log_bits = PCIE_AER_UCE_LOG_BITS; -uint32_t pcie_aer_suce_log_bits = PCIE_AER_SUCE_LOG_BITS; - errorq_t *pci_target_queue = NULL; pci_fm_err_t pci_err_tbl[] = { @@ -79,51 +65,6 @@ pci_fm_err_t pci_bdg_err_tbl[] = { NULL, NULL, NULL, NULL, }; -static pci_fm_err_t pciex_ce_err_tbl[] = { - PCIEX_RE, PCIE_AER_CE_RECEIVER_ERR, NULL, DDI_FM_OK, - PCIEX_RNR, PCIE_AER_CE_REPLAY_ROLLOVER, NULL, DDI_FM_OK, - PCIEX_RTO, PCIE_AER_CE_REPLAY_TO, NULL, DDI_FM_OK, - PCIEX_BDP, PCIE_AER_CE_BAD_DLLP, NULL, DDI_FM_OK, - PCIEX_BTP, PCIE_AER_CE_BAD_TLP, NULL, DDI_FM_OK, - PCIEX_ANFE, PCIE_AER_CE_AD_NFE, NULL, DDI_FM_OK, - NULL, NULL, NULL, NULL, -}; - -static pci_fm_err_t pciex_ue_err_tbl[] = { - PCIEX_TE, PCIE_AER_UCE_TRAINING, NULL, DDI_FM_FATAL, - PCIEX_DLP, PCIE_AER_UCE_DLP, NULL, DDI_FM_FATAL, - PCIEX_SD, PCIE_AER_UCE_SD, NULL, DDI_FM_FATAL, - PCIEX_ROF, PCIE_AER_UCE_RO, NULL, DDI_FM_FATAL, - PCIEX_FCP, PCIE_AER_UCE_FCP, NULL, DDI_FM_FATAL, - PCIEX_MFP, PCIE_AER_UCE_MTLP, NULL, DDI_FM_FATAL, - PCIEX_CTO, PCIE_AER_UCE_TO, NULL, DDI_FM_UNKNOWN, - PCIEX_UC, PCIE_AER_UCE_UC, NULL, DDI_FM_OK, - PCIEX_ECRC, PCIE_AER_UCE_ECRC, NULL, DDI_FM_UNKNOWN, - PCIEX_CA, PCIE_AER_UCE_CA, NULL, DDI_FM_UNKNOWN, - PCIEX_UR, PCIE_AER_UCE_UR, NULL, DDI_FM_UNKNOWN, - PCIEX_POIS, PCIE_AER_UCE_PTLP, NULL, DDI_FM_UNKNOWN, - NULL, NULL, NULL, NULL, -}; - -static pci_fm_err_t pcie_sue_err_tbl[] = { - PCIEX_S_TA_SC, PCIE_AER_SUCE_TA_ON_SC, NULL, DDI_FM_UNKNOWN, - PCIEX_S_MA_SC, PCIE_AER_SUCE_MA_ON_SC, NULL, DDI_FM_UNKNOWN, - PCIEX_S_RTA, PCIE_AER_SUCE_RCVD_TA, NULL, DDI_FM_UNKNOWN, -#if defined(__sparc) - PCIEX_S_RMA, PCIE_AER_SUCE_RCVD_MA, NULL, DDI_FM_UNKNOWN, -#endif - PCIEX_S_USC, PCIE_AER_SUCE_USC_ERR, NULL, DDI_FM_UNKNOWN, - PCIEX_S_USCMD, PCIE_AER_SUCE_USC_MSG_DATA_ERR, NULL, DDI_FM_FATAL, - PCIEX_S_UDE, PCIE_AER_SUCE_UC_DATA_ERR, NULL, DDI_FM_UNKNOWN, - PCIEX_S_UAT, PCIE_AER_SUCE_UC_ATTR_ERR, NULL, DDI_FM_FATAL, - PCIEX_S_UADR, PCIE_AER_SUCE_UC_ADDR_ERR, NULL, DDI_FM_FATAL, - PCIEX_S_TEX, PCIE_AER_SUCE_TIMER_EXPIRED, NULL, DDI_FM_FATAL, - PCIEX_S_PERR, PCIE_AER_SUCE_PERR_ASSERT, NULL, DDI_FM_UNKNOWN, - PCIEX_S_SERR, PCIE_AER_SUCE_SERR_ASSERT, NULL, DDI_FM_FATAL, - PCIEX_INTERR, PCIE_AER_SUCE_INTERNAL_ERR, NULL, DDI_FM_FATAL, - NULL, NULL, NULL, NULL, -}; - static pci_fm_err_t pcix_err_tbl[] = { PCIX_SPL_DIS, PCI_PCIX_SPL_DSCD, NULL, DDI_FM_UNKNOWN, PCIX_UNEX_SPL, PCI_PCIX_UNEX_SPL, NULL, DDI_FM_UNKNOWN, @@ -139,14 +80,6 @@ static pci_fm_err_t pcix_sec_err_tbl[] = { NULL, NULL, NULL, NULL, }; -static pci_fm_err_t pciex_nadv_err_tbl[] = { - PCIEX_UR, PCIE_DEVSTS_UR_DETECTED, NULL, DDI_FM_UNKNOWN, - PCIEX_FAT, PCIE_DEVSTS_FE_DETECTED, NULL, DDI_FM_FATAL, - PCIEX_NONFAT, PCIE_DEVSTS_NFE_DETECTED, NULL, DDI_FM_UNKNOWN, - PCIEX_CORR, PCIE_DEVSTS_CE_DETECTED, NULL, DDI_FM_OK, - NULL, NULL, NULL, NULL, -}; - static int pci_config_check(ddi_acc_handle_t handle, int fme_flag) { @@ -222,27 +155,16 @@ pcix_regs_gather(pci_erpt_t *erpt_p, void *pe_regs, int fme_flag) return; if (PCIX_ECC_VER_CHECK(pcix_bdg_regs->pcix_bdg_ver)) { pcix_ecc_regs_t *pcix_bdg_ecc_regs; - /* - * PCI Express to PCI-X bridges only implement the - * secondary side of the PCI-X ECC registers, bit one is - * read-only so we make sure we do not write to it. - */ - if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) { + + for (i = 0; i < 2; i++) { pcix_bdg_ecc_regs = - pcix_bdg_regs->pcix_bdg_ecc_regs[1]; - pcix_ecc_regs_gather(erpt_p, pcix_bdg_ecc_regs, + pcix_bdg_regs->pcix_bdg_ecc_regs[i]; + pci_config_put32(erpt_p->pe_hdl, + (pcix_bdg_cap_ptr + + PCI_PCIX_BDG_ECC_STATUS), i); + pcix_ecc_regs_gather(erpt_p, + pcix_bdg_ecc_regs, pcix_bdg_cap_ptr, fme_flag); - } else { - for (i = 0; i < 2; i++) { - pcix_bdg_ecc_regs = - pcix_bdg_regs->pcix_bdg_ecc_regs[i]; - pci_config_put32(erpt_p->pe_hdl, - (pcix_bdg_cap_ptr + - PCI_PCIX_BDG_ECC_STATUS), i); - pcix_ecc_regs_gather(erpt_p, - pcix_bdg_ecc_regs, - pcix_bdg_cap_ptr, fme_flag); - } } } } else { @@ -269,139 +191,6 @@ pcix_regs_gather(pci_erpt_t *erpt_p, void *pe_regs, int fme_flag) } } -static void -pcie_regs_gather(pci_erpt_t *erpt_p, int fme_flag) -{ - pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; - uint8_t pcie_cap_ptr; - pcie_adv_error_regs_t *pcie_adv_regs; - uint16_t pcie_ecap_ptr; - - pcie_cap_ptr = pcie_regs->pcie_cap_ptr; - - pcie_regs->pcie_err_status = pci_config_get16(erpt_p->pe_hdl, - pcie_cap_ptr + PCIE_DEVSTS); - if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK) - pcie_regs->pcie_vflags |= PCIE_ERR_STATUS_VALID; - else - return; - - pcie_regs->pcie_err_ctl = pci_config_get16(erpt_p->pe_hdl, - (pcie_cap_ptr + PCIE_DEVCTL)); - pcie_regs->pcie_dev_cap = pci_config_get16(erpt_p->pe_hdl, - (pcie_cap_ptr + PCIE_DEVCAP)); - - if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) && (erpt_p->pe_dflags & - PCIX_DEV)) - pcix_regs_gather(erpt_p, pcie_regs->pcix_bdg_regs, fme_flag); - - if (erpt_p->pe_dflags & PCIEX_RC_DEV) { - pcie_rc_error_regs_t *pcie_rc_regs = pcie_regs->pcie_rc_regs; - - pcie_rc_regs->pcie_rc_status = pci_config_get32(erpt_p->pe_hdl, - (pcie_cap_ptr + PCIE_ROOTSTS)); - pcie_rc_regs->pcie_rc_ctl = pci_config_get16(erpt_p->pe_hdl, - (pcie_cap_ptr + PCIE_ROOTCTL)); - } - - if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV)) - return; - - pcie_adv_regs = pcie_regs->pcie_adv_regs; - - pcie_ecap_ptr = pcie_adv_regs->pcie_adv_cap_ptr; - - pcie_adv_regs->pcie_ue_status = pci_config_get32(erpt_p->pe_hdl, - pcie_ecap_ptr + PCIE_AER_UCE_STS); - if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK) - pcie_adv_regs->pcie_adv_vflags |= PCIE_UE_STATUS_VALID; - - pcie_adv_regs->pcie_ue_mask = pci_config_get32(erpt_p->pe_hdl, - pcie_ecap_ptr + PCIE_AER_UCE_MASK); - pcie_adv_regs->pcie_ue_sev = pci_config_get32(erpt_p->pe_hdl, - pcie_ecap_ptr + PCIE_AER_UCE_SERV); - pcie_adv_regs->pcie_adv_ctl = pci_config_get32(erpt_p->pe_hdl, - pcie_ecap_ptr + PCIE_AER_CTL); - pcie_adv_regs->pcie_ue_hdr0 = pci_config_get32(erpt_p->pe_hdl, - pcie_ecap_ptr + PCIE_AER_HDR_LOG); - if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK) { - int i; - pcie_adv_regs->pcie_adv_vflags |= PCIE_UE_HDR_VALID; - - for (i = 0; i < 3; i++) { - pcie_adv_regs->pcie_ue_hdr[i] = pci_config_get32( - erpt_p->pe_hdl, pcie_ecap_ptr + PCIE_AER_HDR_LOG + - (4 * (i + 1))); - } - } - - pcie_adv_regs->pcie_ce_status = pci_config_get32(erpt_p->pe_hdl, - pcie_ecap_ptr + PCIE_AER_CE_STS); - if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK) - pcie_adv_regs->pcie_adv_vflags |= PCIE_CE_STATUS_VALID; - - pcie_adv_regs->pcie_ce_mask = pci_config_get32(erpt_p->pe_hdl, - pcie_ecap_ptr + PCIE_AER_CE_MASK); - - /* - * If pci express to pci bridge then grab the bridge - * error registers. - */ - if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) { - pcie_adv_bdg_error_regs_t *pcie_bdg_regs = - pcie_adv_regs->pcie_adv_bdg_regs; - - pcie_bdg_regs->pcie_sue_status = - pci_config_get32(erpt_p->pe_hdl, - pcie_ecap_ptr + PCIE_AER_SUCE_STS); - pcie_bdg_regs->pcie_sue_mask = - pci_config_get32(erpt_p->pe_hdl, - pcie_ecap_ptr + PCIE_AER_SUCE_MASK); - if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK) - pcie_adv_regs->pcie_adv_vflags |= PCIE_SUE_STATUS_VALID; - pcie_bdg_regs->pcie_sue_hdr0 = pci_config_get32(erpt_p->pe_hdl, - (pcie_ecap_ptr + PCIE_AER_SHDR_LOG)); - - if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK) { - int i; - - pcie_adv_regs->pcie_adv_vflags |= PCIE_SUE_HDR_VALID; - - for (i = 0; i < 3; i++) { - pcie_bdg_regs->pcie_sue_hdr[i] = - pci_config_get32(erpt_p->pe_hdl, - pcie_ecap_ptr + PCIE_AER_SHDR_LOG + - (4 * (i + 1))); - } - } - } - /* - * If PCI Express root complex then grab the root complex - * error registers. - */ - if (erpt_p->pe_dflags & PCIEX_RC_DEV) { - pcie_adv_rc_error_regs_t *pcie_rc_regs = - pcie_adv_regs->pcie_adv_rc_regs; - - pcie_rc_regs->pcie_rc_err_cmd = pci_config_get32(erpt_p->pe_hdl, - (pcie_ecap_ptr + PCIE_AER_RE_CMD)); - pcie_rc_regs->pcie_rc_err_status = - pci_config_get32(erpt_p->pe_hdl, - (pcie_ecap_ptr + PCIE_AER_RE_STS)); - if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK) - pcie_adv_regs->pcie_adv_vflags |= - PCIE_RC_ERR_STATUS_VALID; - pcie_rc_regs->pcie_rc_ce_src_id = - pci_config_get16(erpt_p->pe_hdl, - (pcie_ecap_ptr + PCIE_AER_CE_SRC_ID)); - pcie_rc_regs->pcie_rc_ue_src_id = - pci_config_get16(erpt_p->pe_hdl, - (pcie_ecap_ptr + PCIE_AER_ERR_SRC_ID)); - if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK) - pcie_adv_regs->pcie_adv_vflags |= PCIE_SRC_ID_VALID; - } -} - /*ARGSUSED*/ static void pci_regs_gather(dev_info_t *dip, pci_erpt_t *erpt_p, int fme_flag) @@ -438,14 +227,8 @@ pci_regs_gather(dev_info_t *dip, pci_erpt_t *erpt_p, int fme_flag) PCI_BDG_CTRL_VALID; } - /* - * If pci express device grab pci express error registers and - * check for advanced error reporting features and grab them if - * available. - */ - if (erpt_p->pe_dflags & PCIEX_DEV) - pcie_regs_gather(erpt_p, fme_flag); - else if (erpt_p->pe_dflags & PCIX_DEV) + /* If pci-x device grab error registers */ + if (erpt_p->pe_dflags & PCIX_DEV) pcix_regs_gather(erpt_p, erpt_p->pe_regs, fme_flag); } @@ -475,17 +258,16 @@ pcix_regs_clear(pci_erpt_t *erpt_p, void *pe_regs) if (PCIX_ECC_VER_CHECK(pcix_bdg_regs->pcix_bdg_ver)) { pcix_ecc_regs_t *pcix_bdg_ecc_regs; - /* - * PCI Express to PCI-X bridges only implement the - * secondary side of the PCI-X ECC registers, bit one is - * read-only so we make sure we do not write to it. - */ - if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) { + for (i = 0; i < 2; i++) { pcix_bdg_ecc_regs = - pcix_bdg_regs->pcix_bdg_ecc_regs[1]; + pcix_bdg_regs->pcix_bdg_ecc_regs[i]; if (pcix_bdg_ecc_regs->pcix_ecc_vflags & PCIX_ERR_ECC_STS_VALID) { + pci_config_put32(erpt_p->pe_hdl, + (pcix_bdg_cap_ptr + + PCI_PCIX_BDG_ECC_STATUS), + i); pci_config_put32(erpt_p->pe_hdl, (pcix_bdg_cap_ptr + @@ -493,29 +275,8 @@ pcix_regs_clear(pci_erpt_t *erpt_p, void *pe_regs) pcix_bdg_ecc_regs-> pcix_ecc_ctlstat); } - pcix_bdg_ecc_regs->pcix_ecc_vflags = 0x0; - } else { - for (i = 0; i < 2; i++) { - pcix_bdg_ecc_regs = - pcix_bdg_regs->pcix_bdg_ecc_regs[i]; - - - if (pcix_bdg_ecc_regs->pcix_ecc_vflags & - PCIX_ERR_ECC_STS_VALID) { - pci_config_put32(erpt_p->pe_hdl, - (pcix_bdg_cap_ptr + - PCI_PCIX_BDG_ECC_STATUS), - i); - - pci_config_put32(erpt_p->pe_hdl, - (pcix_bdg_cap_ptr + - PCI_PCIX_BDG_ECC_STATUS), - pcix_bdg_ecc_regs-> - pcix_ecc_ctlstat); - } - pcix_bdg_ecc_regs->pcix_ecc_vflags = - 0x0; - } + pcix_bdg_ecc_regs->pcix_ecc_vflags = + 0x0; } } } else { @@ -547,79 +308,12 @@ pcix_regs_clear(pci_erpt_t *erpt_p, void *pe_regs) } static void -pcie_regs_clear(pci_erpt_t *erpt_p) -{ - pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; - uint8_t pcie_cap_ptr; - pcie_adv_error_regs_t *pcie_adv_regs; - uint16_t pcie_ecap_ptr; - - pcie_cap_ptr = pcie_regs->pcie_cap_ptr; - - if (pcie_regs->pcie_vflags & PCIE_ERR_STATUS_VALID) - pci_config_put16(erpt_p->pe_hdl, pcie_cap_ptr + PCIE_DEVSTS, - pcie_regs->pcie_err_status); - - pcie_regs->pcie_vflags = 0x0; - - if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) && - (erpt_p->pe_dflags & PCIX_DEV)) - pcix_regs_clear(erpt_p, pcie_regs->pcix_bdg_regs); - - if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV)) - return; - - pcie_adv_regs = pcie_regs->pcie_adv_regs; - - pcie_ecap_ptr = pcie_adv_regs->pcie_adv_cap_ptr; - - if (pcie_adv_regs->pcie_adv_vflags & PCIE_UE_STATUS_VALID) - pci_config_put32(erpt_p->pe_hdl, - pcie_ecap_ptr + PCIE_AER_UCE_STS, - pcie_adv_regs->pcie_ue_status); - - if (pcie_adv_regs->pcie_adv_vflags & PCIE_CE_STATUS_VALID) - pci_config_put32(erpt_p->pe_hdl, - pcie_ecap_ptr + PCIE_AER_CE_STS, - pcie_adv_regs->pcie_ce_status); - - - if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) { - pcie_adv_bdg_error_regs_t *pcie_bdg_regs = - pcie_adv_regs->pcie_adv_bdg_regs; - - - if (pcie_adv_regs->pcie_adv_vflags & PCIE_SUE_STATUS_VALID) - pci_config_put32(erpt_p->pe_hdl, - pcie_ecap_ptr + PCIE_AER_SUCE_STS, - pcie_bdg_regs->pcie_sue_status); - } - /* - * If PCI Express root complex then clear the root complex - * error registers. - */ - if (erpt_p->pe_dflags & PCIEX_RC_DEV) { - pcie_adv_rc_error_regs_t *pcie_rc_regs = - pcie_adv_regs->pcie_adv_rc_regs; - - - if (pcie_adv_regs->pcie_adv_vflags & PCIE_RC_ERR_STATUS_VALID) - pci_config_put32(erpt_p->pe_hdl, - (pcie_ecap_ptr + PCIE_AER_RE_STS), - pcie_rc_regs->pcie_rc_err_status); - } - pcie_adv_regs->pcie_adv_vflags = 0x0; -} - -static void pci_regs_clear(pci_erpt_t *erpt_p) { /* * Finally clear the error bits */ - if (erpt_p->pe_dflags & PCIEX_DEV) - pcie_regs_clear(erpt_p); - else if (erpt_p->pe_dflags & PCIX_DEV) + if (erpt_p->pe_dflags & PCIX_DEV) pcix_regs_clear(erpt_p, erpt_p->pe_regs); if (erpt_p->pe_pci_regs->pci_vflags & PCI_ERR_STATUS_VALID) @@ -651,11 +345,13 @@ pci_regs_clear(pci_erpt_t *erpt_p) static void pcix_ereport_setup(dev_info_t *dip, pci_erpt_t *erpt_p) { - uint8_t pcix_cap_ptr; + uint16_t pcix_cap_ptr = PCI_CAP_NEXT_PTR_NULL; + ddi_acc_handle_t eh; int i; - pcix_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, - "pcix-capid-pointer", PCI_CAP_NEXT_PTR_NULL); + if (pci_config_setup(dip, &eh) != DDI_SUCCESS) { + (void) PCI_CAP_LOCATE(eh, PCI_CAP_ID_PCIX, &pcix_cap_ptr); + } if (pcix_cap_ptr != PCI_CAP_NEXT_PTR_NULL) erpt_p->pe_dflags |= PCIX_DEV; @@ -694,190 +390,6 @@ pcix_ereport_setup(dev_info_t *dip, pci_erpt_t *erpt_p) } } -static void -pcie_ereport_setup(dev_info_t *dip, pci_erpt_t *erpt_p) -{ - pcie_error_regs_t *pcie_regs; - pcie_adv_error_regs_t *pcie_adv_regs; - uint8_t pcix_cap_ptr; - uint8_t pcie_cap_ptr; - uint16_t pcie_ecap_ptr; - uint16_t dev_type = 0; - - /* - * The following sparc specific code should be removed once the pci_cap - * interfaces create the necessary properties for us. - */ -#if defined(__sparc) - ushort_t status; - uint32_t slot_cap; - uint8_t cap_ptr = 0; - uint8_t cap_id = 0; - uint32_t hdr, hdr_next_ptr, hdr_cap_id; - uint16_t offset = P2ALIGN(PCIE_EXT_CAP, 4); - uint16_t aer_ptr = 0; - - cap_ptr = pci_config_get8(erpt_p->pe_hdl, PCI_CONF_CAP_PTR); - if (pci_config_check(erpt_p->pe_hdl, DDI_FM_ERR_UNEXPECTED) == - DDI_FM_OK) { - while ((cap_id = pci_config_get8(erpt_p->pe_hdl, cap_ptr)) != - 0xff) { - if (cap_id == PCI_CAP_ID_PCIX) { - (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, - "pcix-capid-pointer", cap_ptr); - } - if (cap_id == PCI_CAP_ID_PCI_E) { - status = pci_config_get16(erpt_p->pe_hdl, cap_ptr + 2); - if (status & PCIE_PCIECAP_SLOT_IMPL) { - /* offset 14h is Slot Cap Register */ - slot_cap = pci_config_get32(erpt_p->pe_hdl, - cap_ptr + PCIE_SLOTCAP); - (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, - "pcie-slotcap-reg", slot_cap); - } - (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, - "pcie-capid-reg", pci_config_get16(erpt_p->pe_hdl, - cap_ptr + PCIE_PCIECAP)); - (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, - "pcie-capid-pointer", cap_ptr); - - } - if ((cap_ptr = pci_config_get8(erpt_p->pe_hdl, - cap_ptr + 1)) == 0xff || cap_ptr == 0 || - (pci_config_check(erpt_p->pe_hdl, - DDI_FM_ERR_UNEXPECTED) != DDI_FM_OK)) - break; - } - } - -#endif - - pcix_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, - "pcix-capid-pointer", PCI_CAP_NEXT_PTR_NULL); - - if (pcix_cap_ptr != PCI_CAP_NEXT_PTR_NULL) - erpt_p->pe_dflags |= PCIX_DEV; - - pcie_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, - DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL); - - if (pcie_cap_ptr != PCI_CAP_NEXT_PTR_NULL) { - erpt_p->pe_dflags |= PCIEX_DEV; - erpt_p->pe_regs = kmem_zalloc(sizeof (pcie_error_regs_t), - KM_SLEEP); - pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; - pcie_regs->pcie_cap_ptr = pcie_cap_ptr; - } - - if (!(erpt_p->pe_dflags & PCIEX_DEV)) - return; - - /* - * Don't currently need to check for version here because we are - * compliant with PCIE 1.0a which is version 0 and is guaranteed - * software compatibility with future versions. We will need to - * add errors for new detectors/features which are added in newer - * revisions [sec 7.8.2]. - */ - pcie_regs->pcie_cap = pci_config_get16(erpt_p->pe_hdl, - pcie_regs->pcie_cap_ptr + PCIE_PCIECAP); - - dev_type = pcie_regs->pcie_cap & PCIE_PCIECAP_DEV_TYPE_MASK; - - if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) && - (erpt_p->pe_dflags & PCIX_DEV)) { - int i; - - pcie_regs->pcix_bdg_regs = - kmem_zalloc(sizeof (pcix_bdg_error_regs_t), KM_SLEEP); - - pcie_regs->pcix_bdg_regs->pcix_bdg_cap_ptr = pcix_cap_ptr; - pcie_regs->pcix_bdg_regs->pcix_bdg_ver = - pci_config_get16(erpt_p->pe_hdl, - pcix_cap_ptr + PCI_PCIX_SEC_STATUS) & PCI_PCIX_VER_MASK; - - if (PCIX_ECC_VER_CHECK(pcie_regs->pcix_bdg_regs->pcix_bdg_ver)) - for (i = 0; i < 2; i++) - pcie_regs->pcix_bdg_regs->pcix_bdg_ecc_regs[i] = - kmem_zalloc(sizeof (pcix_ecc_regs_t), - KM_SLEEP); - } - - if (dev_type == PCIE_PCIECAP_DEV_TYPE_ROOT) { - erpt_p->pe_dflags |= PCIEX_RC_DEV; - pcie_regs->pcie_rc_regs = kmem_zalloc( - sizeof (pcie_rc_error_regs_t), KM_SLEEP); - } - /* - * The following sparc specific code should be removed once the pci_cap - * interfaces create the necessary properties for us. - */ -#if defined(__sparc) - - hdr = pci_config_get32(erpt_p->pe_hdl, offset); - hdr_next_ptr = (hdr >> PCIE_EXT_CAP_NEXT_PTR_SHIFT) & - PCIE_EXT_CAP_NEXT_PTR_MASK; - hdr_cap_id = (hdr >> PCIE_EXT_CAP_ID_SHIFT) & PCIE_EXT_CAP_ID_MASK; - - while ((hdr_next_ptr != PCIE_EXT_CAP_NEXT_PTR_NULL) && - (hdr_cap_id != PCIE_EXT_CAP_ID_AER)) { - offset = P2ALIGN(hdr_next_ptr, 4); - hdr = pci_config_get32(erpt_p->pe_hdl, offset); - hdr_next_ptr = (hdr >> PCIE_EXT_CAP_NEXT_PTR_SHIFT) & - PCIE_EXT_CAP_NEXT_PTR_MASK; - hdr_cap_id = (hdr >> PCIE_EXT_CAP_ID_SHIFT) & - PCIE_EXT_CAP_ID_MASK; - } - - if (hdr_cap_id == PCIE_EXT_CAP_ID_AER) - aer_ptr = P2ALIGN(offset, 4); - if (aer_ptr != PCI_CAP_NEXT_PTR_NULL) - (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, - "pcie-aer-pointer", aer_ptr); -#endif - - /* - * Find and store if this device is capable of pci express - * advanced errors, if not report an error against the device. - */ - pcie_ecap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, - "pcie-aer-pointer", PCI_CAP_NEXT_PTR_NULL); - if (pcie_ecap_ptr != PCI_CAP_NEXT_PTR_NULL) { - erpt_p->pe_dflags |= PCIEX_ADV_DEV; - pcie_regs->pcie_adv_regs = kmem_zalloc( - sizeof (pcie_adv_error_regs_t), KM_SLEEP); - pcie_regs->pcie_adv_regs->pcie_adv_cap_ptr = pcie_ecap_ptr; - } - - if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV)) { - return; - } - - pcie_adv_regs = pcie_regs->pcie_adv_regs; - - if (pcie_adv_regs == NULL) - return; - /* - * Initialize structures for advanced PCI Express devices. - */ - - /* - * Advanced error registers exist for PCI Express to PCI(X) Bridges and - * may also exist for PCI(X) to PCI Express Bridges, the latter is not - * well explained in the PCI Express to PCI/PCI-X Bridge Specification - * 1.0 and will be left out of the current gathering of these registers. - */ - if (dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) { - erpt_p->pe_dflags |= PCIEX_2PCI_DEV; - pcie_adv_regs->pcie_adv_bdg_regs = kmem_zalloc( - sizeof (pcie_adv_bdg_error_regs_t), KM_SLEEP); - } - - if (erpt_p->pe_dflags & PCIEX_RC_DEV) - pcie_adv_regs->pcie_adv_rc_regs = kmem_zalloc( - sizeof (pcie_adv_rc_error_regs_t), KM_SLEEP); -} - /* * pci_ereport_setup: Detect PCI device type and initialize structures to be * used to generate ereports based on detected generic device errors. @@ -952,16 +464,8 @@ pci_ereport_setup(dev_info_t *dip) goto done; } - /* - * Initialize structures for PCI Express and PCI-X devices. - * Order matters below and pcie_ereport_setup should preceed - * pcix_ereport_setup. - */ - pcie_ereport_setup(dip, erpt_p); - - if (!(erpt_p->pe_dflags & PCIEX_DEV)) { - pcix_ereport_setup(dip, erpt_p); - } + /* Initialize structures for PCI-X devices. */ + pcix_ereport_setup(dip, erpt_p); done: pci_regs_gather(dip, erpt_p, DDI_FM_ERR_UNEXPECTED); @@ -1011,46 +515,6 @@ pcix_ereport_teardown(pci_erpt_t *erpt_p) } } -static void -pcie_ereport_teardown(pci_erpt_t *erpt_p) -{ - pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; - - if (erpt_p->pe_dflags & PCIEX_ADV_DEV) { - pcie_adv_error_regs_t *pcie_adv = pcie_regs->pcie_adv_regs; - - if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) - kmem_free(pcie_adv->pcie_adv_bdg_regs, - sizeof (pcie_adv_bdg_error_regs_t)); - if (erpt_p->pe_dflags & PCIEX_RC_DEV) - kmem_free(pcie_adv->pcie_adv_rc_regs, - sizeof (pcie_adv_rc_error_regs_t)); - kmem_free(pcie_adv, sizeof (pcie_adv_error_regs_t)); - } - - if (erpt_p->pe_dflags & PCIEX_RC_DEV) - kmem_free(pcie_regs->pcie_rc_regs, - sizeof (pcie_rc_error_regs_t)); - - if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) { - if (erpt_p->pe_dflags & PCIX_DEV) { - uint16_t pcix_ver = pcie_regs->pcix_bdg_regs-> - pcix_bdg_ver; - - if (PCIX_ECC_VER_CHECK(pcix_ver)) { - int i; - for (i = 0; i < 2; i++) - kmem_free(pcie_regs->pcix_bdg_regs-> - pcix_bdg_ecc_regs[i], - sizeof (pcix_ecc_regs_t)); - } - kmem_free(pcie_regs->pcix_bdg_regs, - sizeof (pcix_bdg_error_regs_t)); - } - } - kmem_free(erpt_p->pe_regs, sizeof (pcie_error_regs_t)); -} - void pci_ereport_teardown(dev_info_t *dip) { @@ -1068,9 +532,7 @@ pci_ereport_teardown(dev_info_t *dip) if (erpt_p == NULL) return; - if (erpt_p->pe_dflags & PCIEX_DEV) - pcie_ereport_teardown(erpt_p); - else if (erpt_p->pe_dflags & PCIX_DEV) + if (erpt_p->pe_dflags & PCIX_DEV) pcix_ereport_teardown(erpt_p); pci_config_teardown((ddi_acc_handle_t *)&erpt_p->pe_hdl); if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) @@ -1084,289 +546,6 @@ pci_ereport_teardown(dev_info_t *dip) * The following sparc specific code should be removed once the pci_cap * interfaces create the necessary properties for us. */ -#if defined(__sparc) - (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcix-capid-pointer"); - (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-slotcap-reg"); - (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-capid-reg"); - (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-capid-pointer"); - (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-aer-pointer"); -#endif -} - -static void -pcie_ereport_post(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p, - char *buf, int errtype) -{ - pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; - pcie_adv_error_regs_t *pcie_adv_regs = pcie_regs->pcie_adv_regs; - pcie_adv_rc_error_regs_t *pcie_adv_rc_regs; - - switch (errtype) { - case PCIEX_TYPE_CE: - ddi_fm_ereport_post(dip, buf, derr->fme_ena, - DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, - PCIEX_DEVSTS_REG, DATA_TYPE_UINT16, - pcie_regs->pcie_err_status, - PCIEX_CE_STATUS_REG, DATA_TYPE_UINT32, - pcie_adv_regs->pcie_ce_status, NULL); - break; - case PCIEX_TYPE_UE: - ddi_fm_ereport_post(dip, buf, derr->fme_ena, - DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, - PCIEX_DEVSTS_REG, DATA_TYPE_UINT16, - pcie_regs->pcie_err_status, - PCIEX_UE_STATUS_REG, DATA_TYPE_UINT32, - pcie_adv_regs->pcie_ue_status, PCIEX_UE_SEV_REG, - DATA_TYPE_UINT32, pcie_adv_regs->pcie_ue_sev, - PCIEX_ADV_CTL, DATA_TYPE_UINT32, - pcie_adv_regs->pcie_adv_ctl, - PCIEX_SRC_ID, DATA_TYPE_UINT16, - pcie_adv_regs->pcie_adv_bdf, - PCIEX_SRC_VALID, DATA_TYPE_BOOLEAN_VALUE, - (pcie_adv_regs->pcie_adv_bdf != NULL) ? - 1 : NULL, -#ifdef DEBUG - PCIEX_UE_HDR0, DATA_TYPE_UINT32, - pcie_adv_regs->pcie_ue_hdr0, - PCIEX_UE_HDR1, DATA_TYPE_UINT32, - pcie_adv_regs->pcie_ue_hdr[0], - PCIEX_UE_HDR2, DATA_TYPE_UINT32, - pcie_adv_regs->pcie_ue_hdr[1], - PCIEX_UE_HDR3, DATA_TYPE_UINT32, - pcie_adv_regs->pcie_ue_hdr[2], -#endif - NULL); - break; - case PCIEX_TYPE_GEN: - ddi_fm_ereport_post(dip, buf, derr->fme_ena, - DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, - 0, PCIEX_DEVSTS_REG, DATA_TYPE_UINT16, - pcie_regs->pcie_err_status, NULL); - break; - case PCIEX_TYPE_RC_UE_MSG: - case PCIEX_TYPE_RC_CE_MSG: - pcie_adv_rc_regs = pcie_adv_regs->pcie_adv_rc_regs; - - ddi_fm_ereport_post(dip, buf, derr->fme_ena, - DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, - PCIEX_ROOT_ERRSTS_REG, DATA_TYPE_UINT32, - pcie_adv_rc_regs->pcie_rc_err_status, - PCIEX_SRC_ID, DATA_TYPE_UINT16, - (errtype == PCIEX_TYPE_RC_UE_MSG) ? - pcie_adv_rc_regs->pcie_rc_ue_src_id : - pcie_adv_rc_regs->pcie_rc_ce_src_id, - PCIEX_SRC_VALID, DATA_TYPE_BOOLEAN_VALUE, - (errtype == PCIEX_TYPE_RC_UE_MSG) ? - (pcie_adv_regs->pcie_adv_vflags & PCIE_SRC_ID_VALID && - pcie_adv_rc_regs->pcie_rc_ue_src_id != 0) : - (pcie_adv_regs->pcie_adv_vflags & PCIE_SRC_ID_VALID && - pcie_adv_rc_regs->pcie_rc_ce_src_id != 0), NULL); - break; - case PCIEX_TYPE_RC_MULT_MSG: - pcie_adv_rc_regs = pcie_adv_regs->pcie_adv_rc_regs; - - ddi_fm_ereport_post(dip, buf, derr->fme_ena, - DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, - PCIEX_ROOT_ERRSTS_REG, DATA_TYPE_UINT32, - pcie_adv_rc_regs->pcie_rc_err_status, NULL); - break; - default: - break; - } -} - -/*ARGSUSED*/ -static void -pcie_check_addr(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p) -{ - pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; - pcie_adv_error_regs_t *pcie_adv_regs = pcie_regs->pcie_adv_regs; - pcie_tlp_hdr_t *ue_hdr0; - uint32_t *ue_hdr; - uint64_t addr = NULL; - int upstream = 0; - pci_fme_bus_specific_t *pci_fme_bsp = - (pci_fme_bus_specific_t *)derr->fme_bus_specific; - - if (!(pcie_adv_regs->pcie_adv_vflags & PCIE_UE_HDR_VALID)) - return; - - ue_hdr0 = (pcie_tlp_hdr_t *)&pcie_adv_regs->pcie_ue_hdr0; - ue_hdr = pcie_adv_regs->pcie_ue_hdr; - - if ((pcie_regs->pcie_cap & PCIE_PCIECAP_DEV_TYPE_MASK) == - PCIE_PCIECAP_DEV_TYPE_ROOT || - (pcie_regs->pcie_cap & PCIE_PCIECAP_DEV_TYPE_MASK) == - PCIE_PCIECAP_DEV_TYPE_DOWN) - upstream = 1; - - switch (ue_hdr0->type) { - case PCIE_TLP_TYPE_MEM: - case PCIE_TLP_TYPE_MEMLK: - if ((ue_hdr0->fmt & 0x1) == 0x1) { - pcie_mem64_t *mem64_tlp = (pcie_mem64_t *)ue_hdr; - - addr = (uint64_t)mem64_tlp->addr1 << 32 | - (uint32_t)mem64_tlp->addr0 << 2; - pcie_adv_regs->pcie_adv_bdf = mem64_tlp->rid; - } else { - pcie_memio32_t *memio32_tlp = (pcie_memio32_t *)ue_hdr; - - addr = (uint32_t)memio32_tlp->addr0 << 2; - pcie_adv_regs->pcie_adv_bdf = memio32_tlp->rid; - } - if (upstream) { - pci_fme_bsp->pci_bs_bdf = pcie_adv_regs->pcie_adv_bdf; - pci_fme_bsp->pci_bs_flags |= PCI_BS_BDF_VALID; - } else if ((pcie_regs->pcie_cap & PCIE_PCIECAP_DEV_TYPE_MASK) == - PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) { - pci_fme_bsp->pci_bs_bdf = erpt_p->pe_bdf; - pci_fme_bsp->pci_bs_flags |= PCI_BS_BDF_VALID; - } - pci_fme_bsp->pci_bs_addr = addr; - pci_fme_bsp->pci_bs_flags |= PCI_BS_ADDR_VALID; - pci_fme_bsp->pci_bs_type = upstream ? DMA_HANDLE : ACC_HANDLE; - break; - - case PCIE_TLP_TYPE_IO: - { - pcie_memio32_t *memio32_tlp = (pcie_memio32_t *)ue_hdr; - - addr = (uint32_t)memio32_tlp->addr0 << 2; - pcie_adv_regs->pcie_adv_bdf = memio32_tlp->rid; - if ((pcie_regs->pcie_cap & - PCIE_PCIECAP_DEV_TYPE_MASK) == - PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) { - pci_fme_bsp->pci_bs_bdf = erpt_p->pe_bdf; - pci_fme_bsp->pci_bs_flags |= PCI_BS_BDF_VALID; - } - pci_fme_bsp->pci_bs_addr = addr; - pci_fme_bsp->pci_bs_flags |= PCI_BS_ADDR_VALID; - pci_fme_bsp->pci_bs_type = ACC_HANDLE; - break; - } - case PCIE_TLP_TYPE_CFG0: - case PCIE_TLP_TYPE_CFG1: - { - pcie_cfg_t *cfg_tlp = (pcie_cfg_t *)ue_hdr; - - pcie_adv_regs->pcie_adv_bdf = cfg_tlp->rid; - pci_fme_bsp->pci_bs_bdf = (uint16_t)cfg_tlp->bus << 8 | - (uint16_t)cfg_tlp->dev << 3 | cfg_tlp->func; - pci_fme_bsp->pci_bs_flags |= PCI_BS_BDF_VALID; - pci_fme_bsp->pci_bs_type = ACC_HANDLE; - break; - } - case PCIE_TLP_TYPE_MSG: - { - pcie_msg_t *msg_tlp = (pcie_msg_t *)ue_hdr; - - pcie_adv_regs->pcie_adv_bdf = msg_tlp->rid; - break; - } - case PCIE_TLP_TYPE_CPL: - case PCIE_TLP_TYPE_CPLLK: - { - pcie_cpl_t *cpl_tlp = (pcie_cpl_t *)ue_hdr; - - pcie_adv_regs->pcie_adv_bdf = cpl_tlp->cid; - pci_fme_bsp->pci_bs_flags |= PCI_BS_BDF_VALID; - if (upstream) { - pci_fme_bsp->pci_bs_bdf = cpl_tlp->cid; - pci_fme_bsp->pci_bs_type = ACC_HANDLE; - } else { - pci_fme_bsp->pci_bs_bdf = cpl_tlp->rid; - pci_fme_bsp->pci_bs_type = DMA_HANDLE; - } - break; - } - case PCIE_TLP_TYPE_MSI: - default: - break; - } -} - -/*ARGSUSED*/ -static void -pcie_pci_check_addr(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p, - int type) -{ - pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; - pcie_adv_error_regs_t *pcie_adv_regs = pcie_regs->pcie_adv_regs; - pcie_adv_bdg_error_regs_t *pcie_bdg_regs = - pcie_adv_regs->pcie_adv_bdg_regs; - uint64_t addr = NULL; - pcix_attr_t *pcie_pci_sue_attr; - int cmd; - int dual_addr = 0; - pci_fme_bus_specific_t *pci_fme_bsp = - (pci_fme_bus_specific_t *)derr->fme_bus_specific; - - if (!(pcie_adv_regs->pcie_adv_vflags & PCIE_SUE_HDR_VALID)) - return; - - pcie_pci_sue_attr = (pcix_attr_t *)&pcie_bdg_regs->pcie_sue_hdr0; - cmd = (pcie_bdg_regs->pcie_sue_hdr[0] >> - PCIE_AER_SUCE_HDR_CMD_LWR_SHIFT) & PCIE_AER_SUCE_HDR_CMD_LWR_MASK; - -cmd_switch: - addr = pcie_bdg_regs->pcie_sue_hdr[2]; - addr = (addr << PCIE_AER_SUCE_HDR_ADDR_SHIFT) | - pcie_bdg_regs->pcie_sue_hdr[1]; - switch (cmd) { - case PCI_PCIX_CMD_IORD: - case PCI_PCIX_CMD_IOWR: - pcie_adv_regs->pcie_adv_bdf = pcie_pci_sue_attr->rid; - if (addr) { - pci_fme_bsp->pci_bs_addr = addr; - pci_fme_bsp->pci_bs_flags |= PCI_BS_ADDR_VALID; - pci_fme_bsp->pci_bs_type = ACC_HANDLE; - } - break; - case PCI_PCIX_CMD_MEMRD_DW: - case PCI_PCIX_CMD_MEMWR: - case PCI_PCIX_CMD_MEMRD_BL: - case PCI_PCIX_CMD_MEMWR_BL: - case PCI_PCIX_CMD_MEMRDBL: - case PCI_PCIX_CMD_MEMWRBL: - pcie_adv_regs->pcie_adv_bdf = pcie_pci_sue_attr->rid; - if (addr) { - pci_fme_bsp->pci_bs_addr = addr; - pci_fme_bsp->pci_bs_flags |= PCI_BS_ADDR_VALID; - pci_fme_bsp->pci_bs_type = type; - } - break; - case PCI_PCIX_CMD_CFRD: - case PCI_PCIX_CMD_CFWR: - pcie_adv_regs->pcie_adv_bdf = pcie_pci_sue_attr->rid; - /* - * for type 1 config transaction we can find bdf from address - */ - if ((addr & 3) == 1) { - pci_fme_bsp->pci_bs_bdf = (addr >> 8) & 0xffffffff; - pci_fme_bsp->pci_bs_flags |= PCI_BS_BDF_VALID; - pci_fme_bsp->pci_bs_type = ACC_HANDLE; - } - break; - case PCI_PCIX_CMD_SPL: - pcie_adv_regs->pcie_adv_bdf = pcie_pci_sue_attr->rid; - if (type == ACC_HANDLE) { - pci_fme_bsp->pci_bs_bdf = pcie_adv_regs->pcie_adv_bdf; - pci_fme_bsp->pci_bs_flags |= PCI_BS_BDF_VALID; - pci_fme_bsp->pci_bs_type = type; - } - break; - case PCI_PCIX_CMD_DADR: - cmd = (pcie_bdg_regs->pcie_sue_hdr[0] >> - PCIE_AER_SUCE_HDR_CMD_UP_SHIFT) & - PCIE_AER_SUCE_HDR_CMD_UP_MASK; - if (dual_addr) - break; - ++dual_addr; - goto cmd_switch; - default: - break; - } } /*ARGSUSED*/ @@ -1482,51 +661,6 @@ pci_bdg_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p) pci_fme_bsp->pci_bs_addr); } } -#if !defined(__sparc) - /* - * For x86, many drivers and even user-level code currently get - * away with accessing bad addresses, getting a UR and getting - * -1 returned. Unfortunately, we have no control over this, so - * we will have to treat all URs as nonfatal. Moreover, if the - * leaf driver is non-hardened, then we don't actually see the - * UR directly. All we see is a secondary bus master abort at - * the root complex - so it's this condition that we actually - * need to treat as nonfatal (providing no other unrelated nfe - * conditions have also been seen by the root complex). - */ - if ((erpt_p->pe_dflags & PCIEX_RC_DEV) && - (pci_bdg_regs->pci_bdg_sec_stat & PCI_STAT_R_MAST_AB) && - !(pci_bdg_regs->pci_bdg_sec_stat & PCI_STAT_S_PERROR)) { - pcie_error_regs_t *pcie_regs = - (pcie_error_regs_t *)erpt_p->pe_regs; - if ((pcie_regs->pcie_vflags & PCIE_ERR_STATUS_VALID) && - !(pcie_regs->pcie_err_status & - PCIE_DEVSTS_NFE_DETECTED)) - nonfatal++; - if (erpt_p->pe_dflags & PCIEX_ADV_DEV) { - pcie_adv_error_regs_t *pcie_adv_regs = - pcie_regs->pcie_adv_regs; - pcie_adv_rc_error_regs_t *pcie_rc_regs = - pcie_adv_regs->pcie_adv_rc_regs; - if ((pcie_adv_regs->pcie_adv_vflags & - PCIE_RC_ERR_STATUS_VALID) && - (pcie_rc_regs->pcie_rc_err_status & - PCIE_AER_RE_STS_NFE_MSGS_RCVD)) { - (void) snprintf(buf, FM_MAX_CLASS, - "%s.%s-%s", PCI_ERROR_SUBCLASS, - PCI_SEC_ERROR_SUBCLASS, PCI_MA); - ddi_fm_ereport_post(dip, buf, - derr->fme_ena, DDI_NOSLEEP, - FM_VERSION, DATA_TYPE_UINT8, 0, - PCI_SEC_CONFIG_STATUS, - DATA_TYPE_UINT16, - pci_bdg_regs->pci_bdg_sec_stat, - PCI_BCNTRL, DATA_TYPE_UINT16, - pci_bdg_regs->pci_bdg_ctrl, NULL); - } - } - } -#endif } done: @@ -1834,313 +968,6 @@ pcix_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p) (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); } -static int -pcie_rc_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p, - void *pe_regs) -{ - pcie_adv_error_regs_t *pcie_adv_regs = (pcie_adv_error_regs_t *)pe_regs; - int fatal = 0; - int nonfatal = 0; - int unknown = 0; - char buf[FM_MAX_CLASS]; - - if (pcie_adv_regs->pcie_adv_vflags & PCIE_RC_ERR_STATUS_VALID) { - pcie_adv_rc_error_regs_t *pcie_rc_regs = - pcie_adv_regs->pcie_adv_rc_regs; - int ce, ue, mult_ce, mult_ue, first_ue_fatal, nfe, fe; - - ce = pcie_rc_regs->pcie_rc_err_status & - PCIE_AER_RE_STS_CE_RCVD; - ue = pcie_rc_regs->pcie_rc_err_status & - PCIE_AER_RE_STS_FE_NFE_RCVD; - mult_ce = pcie_rc_regs->pcie_rc_err_status & - PCIE_AER_RE_STS_MUL_CE_RCVD; - mult_ue = pcie_rc_regs->pcie_rc_err_status & - PCIE_AER_RE_STS_MUL_FE_NFE_RCVD; - first_ue_fatal = pcie_rc_regs->pcie_rc_err_status & - PCIE_AER_RE_STS_FIRST_UC_FATAL; - nfe = pcie_rc_regs->pcie_rc_err_status & - PCIE_AER_RE_STS_NFE_MSGS_RCVD; - fe = pcie_rc_regs->pcie_rc_err_status & - PCIE_AER_RE_STS_FE_MSGS_RCVD; - /* - * log fatal/nonfatal/corrected messages - * recieved by root complex - */ - if (ue && fe) - fatal++; - - if (fe && first_ue_fatal) { - (void) snprintf(buf, FM_MAX_CLASS, - "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_FE_MSG); - pcie_ereport_post(dip, derr, erpt_p, buf, - PCIEX_TYPE_RC_UE_MSG); - } - if (nfe && !first_ue_fatal) { - (void) snprintf(buf, FM_MAX_CLASS, - "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_NFE_MSG); - pcie_ereport_post(dip, derr, erpt_p, buf, - PCIEX_TYPE_RC_UE_MSG); - } - if (ce) { - (void) snprintf(buf, FM_MAX_CLASS, - "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_CE_MSG); - pcie_ereport_post(dip, derr, erpt_p, buf, - PCIEX_TYPE_RC_CE_MSG); - } - if (mult_ce) { - (void) snprintf(buf, FM_MAX_CLASS, - "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_MCE_MSG); - pcie_ereport_post(dip, derr, erpt_p, buf, - PCIEX_TYPE_RC_MULT_MSG); - } - if (mult_ue) { - (void) snprintf(buf, FM_MAX_CLASS, - "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_MUE_MSG); - pcie_ereport_post(dip, derr, erpt_p, buf, - PCIEX_TYPE_RC_MULT_MSG); - } - } - return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : - (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); -} - -static int -pcie_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p) -{ - int fatal = 0; - int nonfatal = 0; - int unknown = 0; - int ok = 0; - int type; - char buf[FM_MAX_CLASS]; - int i; - pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs; - pcie_adv_error_regs_t *pcie_adv_regs; - pcie_adv_bdg_error_regs_t *pcie_bdg_regs; - - if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) && - (erpt_p->pe_dflags & PCIX_DEV)) { - int ret = pcix_bdg_error_report(dip, derr, erpt_p, - (void *)pcie_regs->pcix_bdg_regs); - PCI_FM_SEV_INC(ret); - } - - if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV)) { - if (!(pcie_regs->pcie_vflags & PCIE_ERR_STATUS_VALID)) - goto done; -#if !defined(__sparc) - /* - * On x86 ignore UR on non-RBER leaf devices, pciex-pci - * bridges and switches. - */ - if ((pcie_regs->pcie_err_status & PCIE_DEVSTS_UR_DETECTED) && - !(pcie_regs->pcie_err_status & PCIE_DEVSTS_FE_DETECTED) && - ((erpt_p->pe_dflags & (PCIEX_2PCI_DEV|PCIEX_SWITCH_DEV)) || - !(erpt_p->pe_dflags & PCI_BRIDGE_DEV)) && - !(pcie_regs->pcie_dev_cap & PCIE_DEVCAP_ROLE_BASED_ERR_REP)) - goto done; -#endif - for (i = 0; pciex_nadv_err_tbl[i].err_class != NULL; i++) { - if (!(pcie_regs->pcie_err_status & - pciex_nadv_err_tbl[i].reg_bit)) - continue; - - (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", - PCIEX_ERROR_SUBCLASS, - pciex_nadv_err_tbl[i].err_class); - pcie_ereport_post(dip, derr, erpt_p, buf, - PCIEX_TYPE_GEN); - PCI_FM_SEV_INC(pciex_nadv_err_tbl[i].flags); - } - goto done; - } - - pcie_adv_regs = pcie_regs->pcie_adv_regs; - - /* - * Log PCI Express uncorrectable errors - */ - if (pcie_adv_regs->pcie_adv_vflags & PCIE_UE_STATUS_VALID) { - for (i = 0; pciex_ue_err_tbl[i].err_class != NULL; i++) { - if (!(pcie_adv_regs->pcie_ue_status & - pciex_ue_err_tbl[i].reg_bit)) - continue; - - (void) snprintf(buf, FM_MAX_CLASS, - "%s.%s", PCIEX_ERROR_SUBCLASS, - pciex_ue_err_tbl[i].err_class); - - /* - * First check for advisary nonfatal conditions - * - hardware endpoint successfully retrying a cto - * - hardware endpoint receiving poisoned tlp and - * dealing with it itself (but not if root complex) - * If the device has declared these as correctable - * errors then treat them as such. - */ - if ((pciex_ue_err_tbl[i].reg_bit == PCIE_AER_UCE_TO || - (pciex_ue_err_tbl[i].reg_bit == PCIE_AER_UCE_PTLP && - !(erpt_p->pe_dflags & PCIEX_RC_DEV))) && - (pcie_regs->pcie_err_status & - PCIE_DEVSTS_CE_DETECTED) && - !(pcie_regs->pcie_err_status & - PCIE_DEVSTS_NFE_DETECTED)) { - pcie_ereport_post(dip, derr, erpt_p, buf, - PCIEX_TYPE_UE); - continue; - } - -#if !defined(__sparc) - /* - * On x86 for leaf devices and pciex-pci bridges, - * ignore UR on non-RBER devices or on RBER devices when - * advisory nonfatal. - */ - if (pciex_ue_err_tbl[i].reg_bit == PCIE_AER_UCE_UR && - ((erpt_p->pe_dflags & - (PCIEX_2PCI_DEV|PCIEX_SWITCH_DEV)) || - !(erpt_p->pe_dflags & PCI_BRIDGE_DEV))) { - if (!(pcie_regs->pcie_dev_cap & - PCIE_DEVCAP_ROLE_BASED_ERR_REP)) - continue; - if (!(pcie_regs->pcie_err_status & - PCIE_DEVSTS_NFE_DETECTED)) - continue; - } -#endif - pcie_adv_regs->pcie_adv_bdf = 0; - /* - * Now try and look up handle if - * - error bit is among PCIE_AER_UCE_LOG_BITS, and - * - no other PCIE_AER_UCE_LOG_BITS are set, and - * - error bit is not masked, and - * - flag is DDI_FM_UNKNOWN - */ - if ((pcie_adv_regs->pcie_ue_status & - pcie_aer_uce_log_bits) == - pciex_ue_err_tbl[i].reg_bit && - !(pciex_ue_err_tbl[i].reg_bit & - pcie_adv_regs->pcie_ue_mask) && - pciex_ue_err_tbl[i].flags == DDI_FM_UNKNOWN) - pcie_check_addr(dip, derr, erpt_p); - - PCI_FM_SEV_INC(pciex_ue_err_tbl[i].flags); - pcie_ereport_post(dip, derr, erpt_p, buf, - PCIEX_TYPE_UE); - } - } - - /* - * Log PCI Express correctable errors - */ - if (pcie_adv_regs->pcie_adv_vflags & PCIE_CE_STATUS_VALID) { - for (i = 0; pciex_ce_err_tbl[i].err_class != NULL; i++) { - if (!(pcie_adv_regs->pcie_ce_status & - pciex_ce_err_tbl[i].reg_bit)) - continue; - - (void) snprintf(buf, FM_MAX_CLASS, - "%s.%s", PCIEX_ERROR_SUBCLASS, - pciex_ce_err_tbl[i].err_class); - pcie_ereport_post(dip, derr, erpt_p, buf, - PCIEX_TYPE_CE); - } - } - - if (!(erpt_p->pe_dflags & PCI_BRIDGE_DEV)) - goto done; - - if (erpt_p->pe_dflags & PCIEX_RC_DEV) { - int ret = pcie_rc_error_report(dip, derr, erpt_p, - (void *)pcie_adv_regs); - PCI_FM_SEV_INC(ret); - } - - if (!((erpt_p->pe_dflags & PCIEX_2PCI_DEV) && - (pcie_adv_regs->pcie_adv_vflags & PCIE_SUE_STATUS_VALID))) - goto done; - - pcie_bdg_regs = pcie_adv_regs->pcie_adv_bdg_regs; - - for (i = 0; pcie_sue_err_tbl[i].err_class != NULL; i++) { - if ((pcie_bdg_regs->pcie_sue_status & - pcie_sue_err_tbl[i].reg_bit)) { - (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", - PCIEX_ERROR_SUBCLASS, - pcie_sue_err_tbl[i].err_class); - - if ((pcie_bdg_regs->pcie_sue_status & - pcie_aer_suce_log_bits) != - pcie_sue_err_tbl[i].reg_bit || - pcie_sue_err_tbl[i].flags != DDI_FM_UNKNOWN) { - ddi_fm_ereport_post(dip, buf, derr->fme_ena, - DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, - PCIEX_SEC_UE_STATUS, DATA_TYPE_UINT32, - pcie_bdg_regs->pcie_sue_status, -#ifdef DEBUG - PCIEX_SUE_HDR0, DATA_TYPE_UINT32, - pcie_bdg_regs->pcie_sue_hdr0, - PCIEX_SUE_HDR1, DATA_TYPE_UINT32, - pcie_bdg_regs->pcie_sue_hdr[0], - PCIEX_SUE_HDR2, DATA_TYPE_UINT32, - pcie_bdg_regs->pcie_sue_hdr[1], - PCIEX_SUE_HDR3, DATA_TYPE_UINT32, - pcie_bdg_regs->pcie_sue_hdr[2], -#endif - NULL); - } else { - pcie_adv_regs->pcie_adv_bdf = 0; - switch (pcie_sue_err_tbl[i].reg_bit) { - case PCIE_AER_SUCE_RCVD_TA: - case PCIE_AER_SUCE_RCVD_MA: - case PCIE_AER_SUCE_USC_ERR: - type = ACC_HANDLE; - break; - case PCIE_AER_SUCE_TA_ON_SC: - case PCIE_AER_SUCE_MA_ON_SC: - type = DMA_HANDLE; - break; - case PCIE_AER_SUCE_UC_DATA_ERR: - case PCIE_AER_SUCE_PERR_ASSERT: - if (erpt_p->pe_pci_regs->pci_bdg_regs-> - pci_bdg_sec_stat & - PCI_STAT_S_PERROR) - type = ACC_HANDLE; - else - type = DMA_HANDLE; - break; - } - pcie_pci_check_addr(dip, derr, erpt_p, type); - ddi_fm_ereport_post(dip, buf, derr->fme_ena, - DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0, - PCIEX_SEC_UE_STATUS, DATA_TYPE_UINT32, - pcie_bdg_regs->pcie_sue_status, - PCIEX_SRC_ID, DATA_TYPE_UINT16, - pcie_adv_regs->pcie_adv_bdf, - PCIEX_SRC_VALID, DATA_TYPE_BOOLEAN_VALUE, - (pcie_adv_regs->pcie_adv_bdf != NULL) ? - 1 : NULL, -#ifdef DEBUG - PCIEX_SUE_HDR0, DATA_TYPE_UINT32, - pcie_bdg_regs->pcie_sue_hdr0, - PCIEX_SUE_HDR1, DATA_TYPE_UINT32, - pcie_bdg_regs->pcie_sue_hdr[0], - PCIEX_SUE_HDR2, DATA_TYPE_UINT32, - pcie_bdg_regs->pcie_sue_hdr[1], - PCIEX_SUE_HDR3, DATA_TYPE_UINT32, - pcie_bdg_regs->pcie_sue_hdr[2], -#endif - NULL); - } - PCI_FM_SEV_INC(pcie_sue_err_tbl[i].flags); - } - } -done: - return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : - (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); -} - static void pci_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p) { @@ -2173,22 +1000,9 @@ pci_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p) PCI_CONFIG_COMMAND, DATA_TYPE_UINT16, erpt_p->pe_pci_regs->pci_cfg_comm, NULL); - /* - * The meaning of SERR is different for PCIEX (just - * implies a message has been sent) so we don't want to - * treat that one as fatal. - */ - if ((erpt_p->pe_dflags & PCIEX_DEV) && - pci_err_tbl[i].reg_bit == PCI_STAT_S_SYSERR) { - unknown++; - } else { - PCI_FM_SEV_INC(pci_err_tbl[i].flags); - } + PCI_FM_SEV_INC(pci_err_tbl[i].flags); } - if (erpt_p->pe_dflags & PCIEX_DEV) { - int ret = pcie_error_report(dip, derr, erpt_p); - PCI_FM_SEV_INC(ret); - } else if (erpt_p->pe_dflags & PCIX_DEV) { + if (erpt_p->pe_dflags & PCIX_DEV) { if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) { int ret = pcix_bdg_error_report(dip, derr, erpt_p, erpt_p->pe_regs); @@ -2224,9 +1038,7 @@ pci_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p) */ if (ret == DDI_FM_UNKNOWN && (pci_fme_bsp->pci_bs_flags & PCI_BS_BDF_VALID) && - pci_fme_bsp->pci_bs_bdf == erpt_p->pe_bdf && - (erpt_p->pe_dflags & PCIEX_DEV) && - !(erpt_p->pe_dflags & PCIEX_2PCI_DEV)) { + pci_fme_bsp->pci_bs_bdf == erpt_p->pe_bdf) { ret = ndi_fmc_entry_error_all(dip, pci_fme_bsp->pci_bs_type, derr); PCI_FM_SEV_INC(ret); diff --git a/usr/src/uts/common/sys/pcie_impl.h b/usr/src/uts/common/sys/pcie_impl.h index 7b350f2588..f3c99ebf9f 100644 --- a/usr/src/uts/common/sys/pcie_impl.h +++ b/usr/src/uts/common/sys/pcie_impl.h @@ -85,6 +85,8 @@ extern "C" { PCIE_IS_BDG(bus_p)) #define PCIE_IS_PCIE_BDG(bus_p) \ (bus_p->bus_dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) +#define PCIE_IS_PCI2PCIE(bus_p) \ + (bus_p->bus_dev_type == PCIE_PCIECAP_DEV_TYPE_PCI2PCIE) #define PCIE_IS_PCIE_SEC(bus_p) \ (PCIE_IS_PCIE(bus_p) && PCIE_IS_BDG(bus_p) && !PCIE_IS_PCIE_BDG(bus_p)) #define PCIX_ECC_VERSION_CHECK(bus_p) \ diff --git a/usr/src/uts/common/sys/pcifm.h b/usr/src/uts/common/sys/pcifm.h index 5302313741..5df5c679c8 100644 --- a/usr/src/uts/common/sys/pcifm.h +++ b/usr/src/uts/common/sys/pcifm.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_PCIFM_H #define _SYS_PCIFM_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/dditypes.h> /* for ddi_acc_handle_t */ #ifdef __cplusplus @@ -40,11 +38,6 @@ extern "C" { */ #define PCI_BRIDGE_DEV 0x02 #define PCIX_DEV 0x04 -#define PCIEX_DEV 0x08 -#define PCIEX_ADV_DEV 0x10 -#define PCIEX_RC_DEV 0x20 -#define PCIEX_2PCI_DEV 0x40 -#define PCIEX_SWITCH_DEV 0x80 /* * PCI and PCI-X valid flags @@ -58,17 +51,6 @@ extern "C" { #define PCIX_BDG_STATUS_VALID 0x40 #define PCIX_BDG_SEC_STATUS_VALID 0x80 -/* - * PCI Express valid flags - */ -#define PCIE_ERR_STATUS_VALID 0x1 -#define PCIE_CE_STATUS_VALID 0x2 -#define PCIE_UE_STATUS_VALID 0x4 -#define PCIE_RC_ERR_STATUS_VALID 0x8 -#define PCIE_SUE_STATUS_VALID 0x10 -#define PCIE_SUE_HDR_VALID 0x20 -#define PCIE_UE_HDR_VALID 0x40 -#define PCIE_SRC_ID_VALID 0x80 /* * PCI(-X) structures used (by pci_ereport_setup, pci_ereport_post, and @@ -125,59 +107,6 @@ typedef struct pcix_bdg_error_regs { } pcix_bdg_error_regs_t; /* - * PCI Express error register structures used (by pci_ereport_setup, - * pci_ereport_post, and pci_ereport_teardown) to gather and report errors - * detected by PCI Express compliant devices. - */ -typedef struct pcie_adv_bdg_error_regs { - uint32_t pcie_sue_status; /* pcie bridge secondary ue status */ - uint32_t pcie_sue_mask; /* pcie bridge secondary ue mask */ - uint32_t pcie_sue_sev; /* pcie bridge secondary ue severity */ - uint32_t pcie_sue_hdr0; /* pcie bridge secondary ue hdr log */ - uint32_t pcie_sue_hdr[3]; /* pcie bridge secondary ue hdr log */ -} pcie_adv_bdg_error_regs_t; - -typedef struct pcie_adv_rc_error_regs { - uint32_t pcie_rc_err_status; /* pcie root complex error status reg */ - uint32_t pcie_rc_err_cmd; /* pcie root complex error cmd reg */ - uint16_t pcie_rc_ce_src_id; /* pcie root complex ce source id */ - uint16_t pcie_rc_ue_src_id; /* pcie root complex ue source id */ -} pcie_adv_rc_error_regs_t; - -typedef struct pcie_adv_error_regs { - uint16_t pcie_adv_vflags; /* pcie advanced error valid flags */ - uint16_t pcie_adv_cap_ptr; /* pcie advanced capability pointer */ - uint16_t pcie_adv_bdf; /* pcie bdf */ - uint32_t pcie_adv_ctl; /* pcie advanced control reg */ - uint32_t pcie_ce_status; /* pcie ce error status reg */ - uint32_t pcie_ce_mask; /* pcie ce error mask reg */ - uint32_t pcie_ue_status; /* pcie ue error status reg */ - uint32_t pcie_ue_mask; /* pcie ue error mask reg */ - uint32_t pcie_ue_sev; /* pcie ue error severity reg */ - uint32_t pcie_ue_hdr0; /* pcie ue header log */ - uint32_t pcie_ue_hdr[3]; /* pcie ue header log */ - pcie_adv_bdg_error_regs_t *pcie_adv_bdg_regs; /* pcie bridge regs */ - pcie_adv_rc_error_regs_t *pcie_adv_rc_regs; /* pcie rc regs */ -} pcie_adv_error_regs_t; - -typedef struct pcie_rc_error_regs { - uint32_t pcie_rc_status; /* root complex status register */ - uint16_t pcie_rc_ctl; /* root complex control register */ -} pcie_rc_error_regs_t; - -typedef struct pcie_error_regs { - uint16_t pcie_vflags; /* pcie valid flags */ - uint8_t pcie_cap_ptr; /* PCI Express capability pointer */ - uint16_t pcie_cap; /* PCI Express capability register */ - uint16_t pcie_err_status; /* pcie device status register */ - uint16_t pcie_err_ctl; /* pcie error control register */ - uint16_t pcie_dev_cap; /* pcie device capabilities register */ - pcix_bdg_error_regs_t *pcix_bdg_regs; /* pcix bridge regs */ - pcie_rc_error_regs_t *pcie_rc_regs; /* pcie root complex regs */ - pcie_adv_error_regs_t *pcie_adv_regs; /* pcie advanced err regs */ -} pcie_error_regs_t; - -/* * pcie bus specific structure */ @@ -211,13 +140,6 @@ typedef struct pci_target_err { (((x) == DDI_FM_NONFATAL) ? nonfatal++ :\ (((x) == DDI_FM_UNKNOWN) ? unknown++ : ok++)); -#define PCIEX_TYPE_CE 0x0 -#define PCIEX_TYPE_UE 0x1 -#define PCIEX_TYPE_GEN 0x2 -#define PCIEX_TYPE_RC_UE_MSG 0x3 -#define PCIEX_TYPE_RC_CE_MSG 0x4 -#define PCIEX_TYPE_RC_MULT_MSG 0x5 - #ifdef __cplusplus } #endif diff --git a/usr/src/uts/i86pc/io/mp_platform_common.c b/usr/src/uts/i86pc/io/mp_platform_common.c index a796804176..60dd3d683b 100644 --- a/usr/src/uts/i86pc/io/mp_platform_common.c +++ b/usr/src/uts/i86pc/io/mp_platform_common.c @@ -1774,12 +1774,14 @@ apic_introp_xlate(dev_info_t *dip, struct intrspec *ispec, int type) parent_is_pci_or_pciex = 1; } - if (parent_is_pci_or_pciex && ddi_prop_get_int(DDI_DEV_T_ANY, dip, - DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL) != - PCI_CAP_NEXT_PTR_NULL) { - child_is_pciex = 1; + if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, + DDI_PROP_DONTPASS, "compatible", (caddr_t)dev_type, + &dev_len) == DDI_PROP_SUCCESS) { + if (strstr(dev_type, "pciex")) + child_is_pciex = 1; } + if (DDI_INTR_IS_MSI_OR_MSIX(type)) { if ((airqp = apic_find_irq(dip, ispec, type)) != NULL) { airqp->airq_iflag.bustype = diff --git a/usr/src/uts/i86pc/io/pci/pci_common.c b/usr/src/uts/i86pc/io/pci/pci_common.c index 2c12b83938..f1400d195b 100644 --- a/usr/src/uts/i86pc/io/pci/pci_common.c +++ b/usr/src/uts/i86pc/io/pci/pci_common.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * File that has code which is common between pci(7d) and npe(7d) * It shares the following: @@ -67,7 +65,6 @@ static void pci_disable_intr(dev_info_t *, dev_info_t *, extern int (*psm_intr_ops)(dev_info_t *, ddi_intr_handle_impl_t *, psm_intr_op_t, int *); - /* * pci_name_child: * @@ -1581,27 +1578,3 @@ pci_config_rep_wr64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, pci_config_wr64(hdlp, host_addr++, *dev_addr); } } - - -/* - * Enable Legacy PCI config space access for the following four north bridges - * Host bridge: AMD HyperTransport Technology Configuration - * Host bridge: AMD Address Map - * Host bridge: AMD DRAM Controller - * Host bridge: AMD Miscellaneous Control - */ -int -is_amd_northbridge(dev_info_t *dip) -{ - int vendor_id, device_id; - - vendor_id = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, - "vendor-id", -1); - device_id = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, - "device-id", -1); - - if (IS_AMD_NTBRIDGE(vendor_id, device_id)) - return (0); - - return (1); -} diff --git a/usr/src/uts/i86pc/io/pci/pci_common.h b/usr/src/uts/i86pc/io/pci/pci_common.h index 3b66c23ea7..c5c05d4612 100644 --- a/usr/src/uts/i86pc/io/pci/pci_common.h +++ b/usr/src/uts/i86pc/io/pci/pci_common.h @@ -20,15 +20,13 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _PCI_PCI_COMMON_H #define _PCI_PCI_COMMON_H -#pragma ident "%Z%%M% %I% %E% SMI" - #ifdef __cplusplus extern "C" { #endif @@ -47,28 +45,6 @@ typedef struct pci_state { kmutex_t pci_err_mutex; } pci_state_t; -/* AMD's northbridges vendor-id and device-ids */ -#define AMD_NTBRDIGE_VID 0x1022 /* AMD vendor-id */ -#define AMD_HT_NTBRIDGE_DID 0x1100 /* HT Configuration */ -#define AMD_AM_NTBRIDGE_DID 0x1101 /* Address Map */ -#define AMD_DC_NTBRIDGE_DID 0x1102 /* DRAM Controller */ -#define AMD_MC_NTBRIDGE_DID 0x1103 /* Misc Controller */ - -/* - * Check if the given device is an AMD northbridge - */ -#define IS_AMD_NTBRIDGE(vid, did) \ - (((vid) == AMD_NTBRDIGE_VID) && \ - (((did) == AMD_HT_NTBRIDGE_DID) || \ - ((did) == AMD_AM_NTBRIDGE_DID) || \ - ((did) == AMD_DC_NTBRIDGE_DID) || \ - ((did) == AMD_MC_NTBRIDGE_DID))) - -/* - * Check if the give device is a PCI northbridge - */ -int is_amd_northbridge(dev_info_t *dip); - /* * These are the access routines. * The pci_bus_map sets the handle to point to these in pci(7d). diff --git a/usr/src/uts/i86pc/io/pciex/npe.c b/usr/src/uts/i86pc/io/pciex/npe.c index abd3d2d54c..b31a03ae24 100644 --- a/usr/src/uts/i86pc/io/pciex/npe.c +++ b/usr/src/uts/i86pc/io/pciex/npe.c @@ -170,6 +170,7 @@ extern void npe_ck804_fix_aer_ptr(ddi_acc_handle_t cfg_hdl); extern int npe_disable_empty_bridges_workaround(dev_info_t *child); extern void npe_nvidia_error_mask(ddi_acc_handle_t cfg_hdl); extern void npe_intel_error_mask(ddi_acc_handle_t cfg_hdl); +extern boolean_t npe_check_and_set_mmcfg(dev_info_t *dip); /* * Module linkage information for the kernel. @@ -416,25 +417,8 @@ npe_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, break; case PCI_ADDR_CONFIG: - /* - * Check for AMD's northbridges - * AND - * for any PCI device. - * - * This is a workaround fix for - * AMD-8132's inability to handle MMCFG - * accesses on Galaxy's PE servers - * AND - * to disable MMCFG for any PCI device. - * - * If a device is *not* found to have PCIe - * capability, then assume it is a PCI device. - */ - - if (is_amd_northbridge(rdip) == 0 || - (ddi_prop_get_int(DDI_DEV_T_ANY, rdip, - DDI_PROP_DONTPASS, "pcie-capid-pointer", - PCI_CAP_NEXT_PTR_NULL) == PCI_CAP_NEXT_PTR_NULL)) { + /* Check and see if MMCFG is supported */ + if (!npe_check_and_set_mmcfg(rdip)) { if (DDI_FM_ACC_ERR_CAP(ddi_fm_capable(rdip)) && mp->map_handlep->ah_acc.devacc_attr_access != DDI_DEFAULT_ACC) { @@ -444,6 +428,7 @@ npe_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, return (DDI_SUCCESS); } + pci_rp->pci_size_low = PCIE_CONF_HDR_SIZE; /* FALLTHROUGH */ case PCI_ADDR_MEM64: @@ -511,15 +496,8 @@ npe_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, *vaddrp = (caddr_t)offset; - /* - * Check for AMD's northbridges, pci devices and - * devices underneath a pci bridge. This is to setup - * I/O based config space access. - */ - if (is_amd_northbridge(rdip) == 0 || - (ddi_prop_get_int(DDI_DEV_T_ANY, rdip, DDI_PROP_DONTPASS, - "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL) == - PCI_CAP_NEXT_PTR_NULL)) { + /* Check if MMCFG is supported */ + if (!npe_check_and_set_mmcfg(rdip)) { int ret; if ((ret = pci_fm_acc_setup(hp, offset, len)) == diff --git a/usr/src/uts/i86pc/io/pciex/npe_misc.c b/usr/src/uts/i86pc/io/pciex/npe_misc.c index e017bb42d9..85a14b2f53 100644 --- a/usr/src/uts/i86pc/io/pciex/npe_misc.c +++ b/usr/src/uts/i86pc/io/pciex/npe_misc.c @@ -36,6 +36,7 @@ #include <sys/acpica.h> #include <sys/pci_cap.h> #include <sys/pcie_impl.h> +#include <sys/x86_archext.h> #include <io/pciex/pcie_nvidia.h> #include <io/pciex/pcie_nb5000.h> @@ -47,6 +48,8 @@ void npe_ck804_fix_aer_ptr(ddi_acc_handle_t cfg_hdl); int npe_disable_empty_bridges_workaround(dev_info_t *child); void npe_nvidia_error_mask(ddi_acc_handle_t cfg_hdl); void npe_intel_error_mask(ddi_acc_handle_t cfg_hdl); +boolean_t npe_is_child_pci(dev_info_t *dip); +boolean_t check_and_set_mmcfg(dev_info_t *dip); /* * Default ecfga base address @@ -56,6 +59,43 @@ int64_t npe_default_ecfga_base = 0xE0000000; extern uint32_t npe_aer_uce_mask; extern boolean_t pcie_full_scan; +/* AMD's northbridges vendor-id and device-ids */ +#define AMD_NTBRDIGE_VID 0x1022 /* AMD vendor-id */ +#define AMD_HT_NTBRIDGE_DID 0x1100 /* HT Configuration */ +#define AMD_AM_NTBRIDGE_DID 0x1101 /* Address Map */ +#define AMD_DC_NTBRIDGE_DID 0x1102 /* DRAM Controller */ +#define AMD_MC_NTBRIDGE_DID 0x1103 /* Misc Controller */ +#define AMD_K10_NTBRIDGE_DID_0 0x1200 +#define AMD_K10_NTBRIDGE_DID_1 0x1201 +#define AMD_K10_NTBRIDGE_DID_2 0x1202 +#define AMD_K10_NTBRIDGE_DID_3 0x1203 +#define AMD_K10_NTBRIDGE_DID_4 0x1204 + +/* + * Check if the given device is an AMD northbridge + */ +#define IS_BAD_AMD_NTBRIDGE(vid, did) \ + (((vid) == AMD_NTBRDIGE_VID) && \ + (((did) == AMD_HT_NTBRIDGE_DID) || \ + ((did) == AMD_AM_NTBRIDGE_DID) || \ + ((did) == AMD_DC_NTBRIDGE_DID) || \ + ((did) == AMD_MC_NTBRIDGE_DID))) + +#define IS_K10_AMD_NTBRIDGE(vid, did) \ + (((vid) == AMD_NTBRDIGE_VID) && \ + (((did) == AMD_K10_NTBRIDGE_DID_0) || \ + ((did) == AMD_K10_NTBRIDGE_DID_1) || \ + ((did) == AMD_K10_NTBRIDGE_DID_2) || \ + ((did) == AMD_K10_NTBRIDGE_DID_3) || \ + ((did) == AMD_K10_NTBRIDGE_DID_4))) + +#define MSR_AMD_NB_MMIO_CFG_BADDR 0xc0010058 +#define AMD_MMIO_CFG_BADDR_ADDR_MASK 0xFFFFFFF00000ULL +#define AMD_MMIO_CFG_BADDR_ENA_MASK 0x000000000001ULL +#define AMD_MMIO_CFG_BADDR_ENA_ON 0x000000000001ULL +#define AMD_MMIO_CFG_BADDR_ENA_OFF 0x000000000000ULL + + /* * Query the MCFG table using ACPI. If MCFG is found, setup the * 'ecfga-base-address' (Enhanced Configuration Access base address) @@ -185,3 +225,81 @@ npe_intel_error_mask(ddi_acc_handle_t cfg_hdl) { pcie_set_aer_uce_mask(regs); } } + +/* + * Check's if this child is a PCI device. + * Child is a PCI device if: + * parent has a dev_type of "pci" + * -and- + * child does not have a dev_type of "pciex" + * + * If the parent is not of dev_type "pci", then assume it is "pciex" and all + * children should support using PCIe style MMCFG access. + * + * If parent's dev_type is "pci" and child is "pciex", then also enable using + * PCIe style MMCFG access. This covers the case where NPE is "pci" and a PCIe + * RP is beneath. + */ +boolean_t +npe_child_is_pci(dev_info_t *dip) { + char *dev_type; + boolean_t parent_is_pci, child_is_pciex; + + if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_get_parent(dip), + DDI_PROP_DONTPASS, "device_type", &dev_type) == + DDI_PROP_SUCCESS) { + parent_is_pci = (strcmp(dev_type, "pci") == 0); + ddi_prop_free(dev_type); + } else { + parent_is_pci = B_FALSE; + } + + if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, + "device_type", &dev_type) == DDI_PROP_SUCCESS) { + child_is_pciex = (strcmp(dev_type, "pciex") == 0); + ddi_prop_free(dev_type); + } else { + child_is_pciex = B_FALSE; + } + + return (parent_is_pci && !child_is_pciex); +} + +/* + * Checks to see if MMCFG is supported and enables it if necessary. + * Returns: TRUE is MMCFG is support, FLASE is not. + * + * In general if a device sits below a parent who's "dev_type" is "pciex" the + * support MMCFG. Otherwise, default back to legacy IOCFG access. + * + * Enable Legacy PCI config space access for AMD K8 north bridges. + * Host bridge: AMD HyperTransport Technology Configuration + * Host bridge: AMD Address Map + * Host bridge: AMD DRAM Controller + * Host bridge: AMD Miscellaneous Control + * These devices do not support MMCFG access. + * + * Enable MMCFG via msr for AMD K10 north bridges + */ +boolean_t +npe_check_and_set_mmcfg(dev_info_t *dip) +{ + int vendor_id, device_id; + int64_t data; + + vendor_id = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, + "vendor-id", -1); + device_id = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, + "device-id", -1); + + if (IS_K10_AMD_NTBRIDGE(vendor_id, device_id)) { + data = ddi_prop_get_int64(DDI_DEV_T_ANY, dip, 0, + "ecfga-base-address", 0); + data &= AMD_MMIO_CFG_BADDR_ADDR_MASK; + data |= AMD_MMIO_CFG_BADDR_ENA_ON; + wrmsr(MSR_AMD_NB_MMIO_CFG_BADDR, data); + } + + return !(npe_child_is_pci(dip) || + IS_BAD_AMD_NTBRIDGE(vendor_id, device_id)); +} diff --git a/usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c b/usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c index 08ab16924b..7ca5da0bb4 100644 --- a/usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c +++ b/usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c @@ -35,6 +35,7 @@ #include <sys/autoconf.h> #include <sys/hwconf.h> #include <sys/pcie.h> +#include <sys/pci_cap.h> #include <sys/ddi.h> #include <sys/sunndi.h> #include <sys/hotplug/pci/pcicfg.h> @@ -2859,8 +2860,8 @@ static int pcicfg_set_standard_props(dev_info_t *dip, ddi_acc_handle_t config_handle, uint8_t pcie_dev) { - int ret, cap_id_loc; - uint16_t val; + int ret; + uint16_t cap_id_loc, val; uint32_t wordval; uint8_t byteval; @@ -2985,28 +2986,14 @@ pcicfg_set_standard_props(dev_info_t *dip, ddi_acc_handle_t config_handle, return (ret); } } - if ((cap_id_loc = pcicfg_get_cap(config_handle, PCI_CAP_ID_PCIX)) > 0) { - /* create the pcix-capid-pointer property */ - if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, - "pcix-capid-pointer", cap_id_loc)) != DDI_SUCCESS) - return (ret); - } - if (pcie_dev && (cap_id_loc = pcicfg_get_cap(config_handle, - PCI_CAP_ID_PCI_E)) > 0) { - /* create the pcie-capid-pointer property */ - if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, - "pcie-capid-pointer", cap_id_loc)) != DDI_SUCCESS) - return (ret); + (void) PCI_CAP_LOCATE(config_handle, PCI_CAP_ID_PCI_E, &cap_id_loc); + if (pcie_dev && cap_id_loc != PCI_CAP_NEXT_PTR_NULL) { val = pci_config_get16(config_handle, cap_id_loc + PCIE_PCIECAP) & PCIE_PCIECAP_SLOT_IMPL; /* if slot implemented, get physical slot number */ if (val) { wordval = pci_config_get32(config_handle, cap_id_loc + PCIE_SLOTCAP); - /* create the slotcap-reg property */ - if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, - dip, "pcie-slotcap-reg", wordval)) != DDI_SUCCESS) - return (ret); /* create the property only if slotnum set correctly? */ if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, "physical-slot#", PCIE_SLOTCAP_PHY_SLOT_NUM( @@ -4496,61 +4483,24 @@ debug(char *fmt, uintptr_t a1, uintptr_t a2, uintptr_t a3, } #endif -/* - * given a cap_id, return its cap_id location in config space - */ -static int -pcicfg_get_cap(ddi_acc_handle_t config_handle, uint8_t cap_id) -{ - uint8_t curcap; - uint_t cap_id_loc; - uint16_t status; - int location = -1; - - /* - * Need to check the Status register for ECP support first. - * Also please note that for type 1 devices, the - * offset could change. Should support type 1 next. - */ - status = pci_config_get16(config_handle, PCI_CONF_STAT); - if (!(status & PCI_STAT_CAP)) { - return (-1); - } - cap_id_loc = pci_config_get8(config_handle, PCI_CONF_CAP_PTR); - - /* Walk the list of capabilities */ - while (cap_id_loc) { - - curcap = pci_config_get8(config_handle, cap_id_loc); - - if (curcap == cap_id) { - location = cap_id_loc; - break; - } - cap_id_loc = pci_config_get8(config_handle, - cap_id_loc + 1); - } - return (location); -} - /*ARGSUSED*/ static uint8_t pcicfg_get_nslots(dev_info_t *dip, ddi_acc_handle_t handle) { - int cap_id_loc; + uint16_t cap_id_loc, slot_id_loc; uint8_t num_slots = 0; /* just depend on the pcie_cap for now. */ - if ((cap_id_loc = pcicfg_get_cap(handle, PCI_CAP_ID_PCI_E)) - > 0) { + (void) PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_E, &cap_id_loc); + (void) PCI_CAP_LOCATE(handle, PCI_CAP_ID_SLOT_ID, &slot_id_loc); + if (cap_id_loc != PCI_CAP_NEXT_PTR_NULL) { if (pci_config_get8(handle, cap_id_loc + PCI_CAP_ID_REGS_OFF) & PCIE_PCIECAP_SLOT_IMPL) num_slots = 1; } else /* not a PCIe switch/bridge. Must be a PCI-PCI[-X] bridge */ - if ((cap_id_loc = pcicfg_get_cap(handle, PCI_CAP_ID_SLOT_ID)) - > 0) { - uint8_t esr_reg = pci_config_get8(handle, cap_id_loc + 2); + if (slot_id_loc != PCI_CAP_NEXT_PTR_NULL) { + uint8_t esr_reg = pci_config_get8(handle, slot_id_loc + 2); num_slots = PCI_CAPSLOT_NSLOTS(esr_reg); } /* XXX - need to cover PCI-PCIe bridge with n slots */ @@ -4608,10 +4558,11 @@ static int pcicfg_pcie_port_type(dev_info_t *dip, ddi_acc_handle_t handle) { int port_type = -1; - int cap_loc; + uint16_t cap_loc; /* Note: need to look at the port type information here */ - if ((cap_loc = pcicfg_get_cap(handle, PCI_CAP_ID_PCI_E)) > 0) + (void) PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_E, &cap_loc); + if (cap_loc != PCI_CAP_NEXT_PTR_NULL) port_type = pci_config_get16(handle, cap_loc + PCIE_PCIECAP) & PCIE_PCIECAP_DEV_TYPE_MASK; diff --git a/usr/src/uts/intel/io/pci/pci_boot.c b/usr/src/uts/intel/io/pci/pci_boot.c index 761c8f9499..05cf1aecdd 100644 --- a/usr/src/uts/intel/io/pci/pci_boot.c +++ b/usr/src/uts/intel/io/pci/pci_boot.c @@ -98,12 +98,14 @@ static void process_devfunc(uchar_t, uchar_t, uchar_t, uchar_t, static void add_compatible(dev_info_t *, ushort_t, ushort_t, ushort_t, ushort_t, uchar_t, uint_t, int); static int add_reg_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int, int); -static void add_ppb_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int); +static void add_ppb_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int, + ushort_t); static void add_model_prop(dev_info_t *, uint_t); static void add_bus_range_prop(int); static void add_bus_slot_names_prop(int); static void add_ppb_ranges_prop(int); static void add_bus_available_prop(int); +static int get_pci_cap(uchar_t bus, uchar_t dev, uchar_t func, uint8_t cap_id); static void fix_ppb_res(uchar_t, boolean_t); static void alloc_res_array(); static void create_ioapic_node(int bus, int dev, int fn, ushort_t vendorid, @@ -591,6 +593,40 @@ get_parbus_mem_res(uchar_t parbus, uchar_t bus, uint64_t size, uint64_t align) } /* + * given a cap_id, return its cap_id location in config space + */ +static int +get_pci_cap(uchar_t bus, uchar_t dev, uchar_t func, uint8_t cap_id) +{ + uint8_t curcap, cap_id_loc; + uint16_t status; + int location = -1; + + /* + * Need to check the Status register for ECP support first. + * Also please note that for type 1 devices, the + * offset could change. Should support type 1 next. + */ + status = pci_getw(bus, dev, func, PCI_CONF_STAT); + if (!(status & PCI_STAT_CAP)) { + return (-1); + } + cap_id_loc = pci_getb(bus, dev, func, PCI_CONF_CAP_PTR); + + /* Walk the list of capabilities */ + while (cap_id_loc && cap_id_loc != (uint8_t)-1) { + curcap = pci_getb(bus, dev, func, cap_id_loc); + + if (curcap == cap_id) { + location = cap_id_loc; + break; + } + cap_id_loc = pci_getb(bus, dev, func, cap_id_loc + 1); + } + return (location); +} + +/* * Assign valid resources to unconfigured pci(e) bridges. We are trying * to reprogram the bridge when its * i) SECBUS == SUBBUS || @@ -641,9 +677,8 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub) /* * If pcie bridge, check to see if link is enabled */ - cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, - "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL); - if (cap_ptr != PCI_CAP_NEXT_PTR_NULL) { + cap_ptr = get_pci_cap(bus, dev, func, PCI_CAP_ID_PCI_E); + if (cap_ptr != -1) { cmd_reg = pci_getw(bus, dev, func, (uint16_t)cap_ptr + PCIE_LINKCTL); if (cmd_reg & PCIE_LINKCTL_LINK_DISABLE) { @@ -1505,7 +1540,7 @@ process_devfunc(uchar_t bus, uchar_t dev, uchar_t func, uchar_t header, set_devpm_d0(bus, dev, func); if ((basecl == PCI_CLASS_BRIDGE) && (subcl == PCI_BRIDGE_PCI)) - add_ppb_props(dip, bus, dev, func, pciex); + add_ppb_props(dip, bus, dev, func, pciex, is_pci_bridge); else { /* * Record the non-PPB devices on the bus for possible @@ -2175,7 +2210,7 @@ done: static void add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, - int pciex) + int pciex, ushort_t is_pci_bridge) { char *dev_type; int i; @@ -2206,7 +2241,7 @@ add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, pci_bus_res[secbus].dip = dip; pci_bus_res[secbus].par_bus = bus; - dev_type = pciex ? "pciex" : "pci"; + dev_type = (pciex && !is_pci_bridge) ? "pciex" : "pci"; /* setup bus number hierarchy */ pci_bus_res[secbus].sub_bus = subbus; diff --git a/usr/src/uts/intel/io/pciex/pcie_nvidia.c b/usr/src/uts/intel/io/pciex/pcie_nvidia.c index 23f3993b9f..b419d2dd81 100644 --- a/usr/src/uts/intel/io/pciex/pcie_nvidia.c +++ b/usr/src/uts/intel/io/pciex/pcie_nvidia.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Library file that has code for PCIe booting */ @@ -67,10 +65,6 @@ check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev, capsp &= PCI_CAP_PTR_MASK; cap = (*pci_getb_func)(bus, dev, func, capsp); - if (cap == PCI_CAP_ID_PCIX && cdip) - (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip, - "pcix-capid-pointer", capsp); - if (cap == PCI_CAP_ID_PCI_E) { #ifdef DEBUG if (pci_boot_debug) @@ -86,7 +80,7 @@ check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev, * device is a PCIe2PCI bridge */ *is_pci_bridge = - ((status & PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) == + ((status & PCIE_PCIECAP_DEV_TYPE_MASK) == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) ? 1 : 0; /* @@ -100,11 +94,6 @@ check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev, *slot_number = PCIE_SLOTCAP_PHY_SLOT_NUM(slot_cap); - if (cdip) - (void) ndi_prop_update_int( - DDI_DEV_T_NONE, cdip, - "pcie-slotcap-reg", slot_cap); - /* Is PCI Express HotPlug capability set? */ if (cdip && (slot_cap & PCIE_SLOTCAP_HP_CAPABLE)) { @@ -115,21 +104,6 @@ check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev, } } - /* - * Can only do I/O based config space access at - * this early stage. Meaning, one cannot access - * extended config space i.e. > 256 bytes. - * So, AER cap_id property will be created much later. - */ - if (cdip) { - (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip, - "pcie-capid-reg", - (*pci_getw_func)(bus, dev, func, - capsp + PCIE_PCIECAP)); - (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip, - "pcie-capid-pointer", capsp); - } - found_pciex = B_TRUE; } diff --git a/usr/src/uts/intel/io/pciex/pcie_pci.c b/usr/src/uts/intel/io/pciex/pcie_pci.c index 918460302d..0da90e8b76 100644 --- a/usr/src/uts/intel/io/pciex/pcie_pci.c +++ b/usr/src/uts/intel/io/pciex/pcie_pci.c @@ -211,7 +211,6 @@ typedef struct { kmutex_t pepb_peek_poke_mutex; boolean_t pepb_no_aer_msi; ddi_iblock_cookie_t pepb_fm_ibc; - int port_type; } pepb_devstate_t; /* soft state flags */ @@ -245,9 +244,7 @@ static void pepb_uninitchild(dev_info_t *); static int pepb_initchild(dev_info_t *child); static void pepb_save_config_regs(pepb_devstate_t *pepb_p); static void pepb_restore_config_regs(pepb_devstate_t *pepb_p); -static int pepb_pcie_device_type(dev_info_t *dip, int *port_type); -static int pepb_pcie_port_type(dev_info_t *dip, - ddi_acc_handle_t config_handle); +static boolean_t pepb_is_pcie_device_type(dev_info_t *dip); /* interrupt related declarations */ static int pepb_msi_intr_supported(dev_info_t *, int intr_type); @@ -360,7 +357,7 @@ pepb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) /* * Make sure the "device_type" property exists. */ - if (pepb_pcie_device_type(devi, &pepb->port_type) == DDI_SUCCESS) + if (pepb_is_pcie_device_type(devi)) (void) strcpy(device_type, "pciex"); else (void) strcpy(device_type, "pci"); @@ -547,7 +544,7 @@ pepb_ctlops(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop, case DDI_CTLOPS_PEEK: case DDI_CTLOPS_POKE: - if (pepb->port_type != PCIE_PCIECAP_DEV_TYPE_ROOT) + if (!PCIE_IS_RP(PCIE_DIP2BUS(dip))) return (ddi_ctlops(dip, rdip, ctlop, arg, result)); return (pci_peekpoke_check(dip, rdip, ctlop, arg, result, ddi_ctlops, &pepb->pepb_err_mutex, @@ -865,29 +862,15 @@ pepb_restore_config_regs(pepb_devstate_t *pepb_p) } } -static int -pepb_pcie_device_type(dev_info_t *dip, int *port_type) +static boolean_t +pepb_is_pcie_device_type(dev_info_t *dip) { - ddi_acc_handle_t handle; - - if (pci_config_setup(dip, &handle) != DDI_SUCCESS) - return (DDI_FAILURE); - *port_type = pepb_pcie_port_type(dip, handle); - pci_config_teardown(&handle); - - /* No PCIe CAP regs, we are not PCIe device_type */ - if (*port_type < 0) - return (DDI_FAILURE); + pcie_bus_t *bus_p = PCIE_DIP2BUS(dip); - /* check for all PCIe device_types */ - if ((*port_type == PCIE_PCIECAP_DEV_TYPE_UP) || - (*port_type == PCIE_PCIECAP_DEV_TYPE_DOWN) || - (*port_type == PCIE_PCIECAP_DEV_TYPE_ROOT) || - (*port_type == PCIE_PCIECAP_DEV_TYPE_PCI2PCIE)) - return (DDI_SUCCESS); - - return (DDI_FAILURE); + if (PCIE_IS_SW(bus_p) || PCIE_IS_RP(bus_p) || PCIE_IS_PCI2PCIE(bus_p)) + return (B_TRUE); + return (B_FALSE); } /* @@ -1183,20 +1166,6 @@ pepb_msi_intr_supported(dev_info_t *dip, int intr_type) return (DDI_SUCCESS); } -static int -pepb_pcie_port_type(dev_info_t *dip, ddi_acc_handle_t handle) -{ - uint_t cap_loc; - - /* Need to look at the port type information here */ - cap_loc = ddi_prop_get_int(DDI_DEV_T_ANY, dip, - DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL); - - return (cap_loc == PCI_CAP_NEXT_PTR_NULL ? -1 : - pci_config_get16(handle, cap_loc + PCIE_PCIECAP) & - PCIE_PCIECAP_DEV_TYPE_MASK); -} - /*ARGSUSED*/ int pepb_fm_init(dev_info_t *dip, dev_info_t *tdip, int cap, @@ -1214,24 +1183,8 @@ pepb_fm_init(dev_info_t *dip, dev_info_t *tdip, int cap, static int pepb_check_slot_disabled(dev_info_t *dip) { - int rval = 0; - uint8_t pcie_cap_ptr; - ddi_acc_handle_t config_handle; - - if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS) - return (rval); - - pcie_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, - DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL); - - if (pcie_cap_ptr != PCI_CAP_NEXT_PTR_NULL) { - if (pci_config_get16(config_handle, - pcie_cap_ptr + PCIE_LINKCTL) & PCIE_LINKCTL_LINK_DISABLE) - rval = 1; - } - - pci_config_teardown(&config_handle); - return (rval); + return ((PCIE_CAP_GET(16, PCIE_DIP2BUS(dip), PCIE_LINKCTL) & + PCIE_LINKCTL_LINK_DISABLE) ? 1 : 0); } static int @@ -1682,15 +1635,12 @@ static void pepb_intel_sw_workaround(dev_info_t *dip) { uint16_t vid, regw; - int port_type; ddi_acc_handle_t cfg_hdl; if (pepb_intel_workaround_disable) return; - (void) pepb_pcie_device_type(dip, &port_type); - if (!((port_type == PCIE_PCIECAP_DEV_TYPE_UP) || - (port_type == PCIE_PCIECAP_DEV_TYPE_DOWN))) + if (!PCIE_IS_SW(PCIE_DIP2BUS(dip))) return; (void) pci_config_setup(dip, &cfg_hdl); diff --git a/usr/src/uts/sun4/io/px/px_fm.c b/usr/src/uts/sun4/io/px/px_fm.c index 65c1d78d29..3e570f16b6 100644 --- a/usr/src/uts/sun4/io/px/px_fm.c +++ b/usr/src/uts/sun4/io/px/px_fm.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * PX Fault Management Architecture */ @@ -37,6 +35,8 @@ #include <sys/membar.h> #include "px_obj.h" +extern uint_t px_ranges_phi_mask; + #define PX_PCIE_PANIC_BITS \ (PCIE_AER_UCE_DLP | PCIE_AER_UCE_FCP | PCIE_AER_UCE_TO | \ PCIE_AER_UCE_RO | PCIE_AER_UCE_MTLP | PCIE_AER_UCE_ECRC) @@ -205,6 +205,8 @@ px_fm_acc_setup(ddi_map_req_t *mp, dev_info_t *rdip, pci_regspec_t *rp) errp->err_cf = px_err_pio_hdl_check; break; default: + /* Illegal state, remove the handle from cache */ + ndi_fmc_remove(rdip, ACC_HANDLE, (void *)hp); break; } } else if (mp->map_op == DDI_MO_UNMAP) { @@ -268,8 +270,8 @@ px_in_addr_range(dev_info_t *dip, px_ranges_t *ranges_p, uint64_t addr) { uint64_t addr_low, addr_high; - addr_low = ((uint64_t)ranges_p->parent_high << 32) | - (uint64_t)ranges_p->parent_low; + addr_low = (uint64_t)(ranges_p->parent_high & px_ranges_phi_mask) << 32; + addr_low |= (uint64_t)ranges_p->parent_low; addr_high = addr_low + ((uint64_t)ranges_p->size_high << 32) + (uint64_t)ranges_p->size_low; |