npe_misc.c revision 49fbdd30212f016ddd49c4b5c997b0b827ff0962
70025d765b044c6d8594bb965a2247a61e991a99johnny * CDDL HEADER START
70025d765b044c6d8594bb965a2247a61e991a99johnny * The contents of this file are subject to the terms of the
7a23d1009aa28ea040052630547929b9c5eb6ab4anish * Common Development and Distribution License (the "License").
7a23d1009aa28ea040052630547929b9c5eb6ab4anish * You may not use this file except in compliance with the License.
70025d765b044c6d8594bb965a2247a61e991a99johnny * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
70025d765b044c6d8594bb965a2247a61e991a99johnny * See the License for the specific language governing permissions
70025d765b044c6d8594bb965a2247a61e991a99johnny * and limitations under the License.
70025d765b044c6d8594bb965a2247a61e991a99johnny * When distributing Covered Code, include this CDDL HEADER in each
70025d765b044c6d8594bb965a2247a61e991a99johnny * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
70025d765b044c6d8594bb965a2247a61e991a99johnny * If applicable, add the following below this CDDL HEADER, with the
70025d765b044c6d8594bb965a2247a61e991a99johnny * fields enclosed by brackets "[]" replaced with your own identifying
70025d765b044c6d8594bb965a2247a61e991a99johnny * information: Portions Copyright [yyyy] [name of copyright owner]
70025d765b044c6d8594bb965a2247a61e991a99johnny * CDDL HEADER END
eae2e508a8e70b1ec407b10bd068c080651bbe5ckrishnae * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
70025d765b044c6d8594bb965a2247a61e991a99johnny * Use is subject to license terms.
70025d765b044c6d8594bb965a2247a61e991a99johnny * Library file that has miscellaneous support for npe(7d)
70025d765b044c6d8594bb965a2247a61e991a99johnny * Prototype declaration
7a23d1009aa28ea040052630547929b9c5eb6ab4anishint npe_disable_empty_bridges_workaround(dev_info_t *child);
eae2e508a8e70b1ec407b10bd068c080651bbe5ckrishnaevoid npe_nvidia_error_mask(ddi_acc_handle_t cfg_hdl);
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaurboolean_t check_and_set_mmcfg(dev_info_t *dip);
70025d765b044c6d8594bb965a2247a61e991a99johnny * Default ecfga base address
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur/* AMD's northbridges vendor-id and device-ids */
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur#define AMD_NTBRDIGE_VID 0x1022 /* AMD vendor-id */
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur#define AMD_HT_NTBRIDGE_DID 0x1100 /* HT Configuration */
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur#define AMD_AM_NTBRIDGE_DID 0x1101 /* Address Map */
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur#define AMD_DC_NTBRIDGE_DID 0x1102 /* DRAM Controller */
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur#define AMD_MC_NTBRIDGE_DID 0x1103 /* Misc Controller */
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * Check if the given device is an AMD northbridge
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur#define AMD_MMIO_CFG_BADDR_ADDR_MASK 0xFFFFFFF00000ULL
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur#define AMD_MMIO_CFG_BADDR_ENA_MASK 0x000000000001ULL
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur#define AMD_MMIO_CFG_BADDR_ENA_ON 0x000000000001ULL
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur#define AMD_MMIO_CFG_BADDR_ENA_OFF 0x000000000000ULL
70025d765b044c6d8594bb965a2247a61e991a99johnny * Query the MCFG table using ACPI. If MCFG is found, setup the
70025d765b044c6d8594bb965a2247a61e991a99johnny * 'ecfga-base-address' (Enhanced Configuration Access base address)
70025d765b044c6d8594bb965a2247a61e991a99johnny * property accordingly. Otherwise, set the value of the property
70025d765b044c6d8594bb965a2247a61e991a99johnny * to the default value.
70025d765b044c6d8594bb965a2247a61e991a99johnny /* Query the MCFG table using ACPI */
db2bae3047e71d795bde12e3baa621f4b6cc8930Dana Myers if (AcpiGetTable(ACPI_SIG_MCFG, 1, (ACPI_TABLE_HEADER **)&mcfgp) ==
70025d765b044c6d8594bb965a2247a61e991a99johnny cfg_baap = (CFG_BASE_ADDR_ALLOC *)mcfgp->CfgBaseAddrAllocList;
70025d765b044c6d8594bb965a2247a61e991a99johnny * Setup the 'ecfga-base-address' property to
70025d765b044c6d8594bb965a2247a61e991a99johnny * the base_addr found in the MCFG and return.
70025d765b044c6d8594bb965a2247a61e991a99johnny * If MCFG is not found or ecfga_base is not found in MCFG table,
70025d765b044c6d8594bb965a2247a61e991a99johnny * set the 'ecfga-base-address' property to the default value.
70025d765b044c6d8594bb965a2247a61e991a99johnny * Enable reporting of AER capability next pointer.
70025d765b044c6d8594bb965a2247a61e991a99johnny * This needs to be done only for CK8-04 devices
70025d765b044c6d8594bb965a2247a61e991a99johnny * by setting NV_XVR_VEND_CYA1 (offset 0xf40) bit 13
70025d765b044c6d8594bb965a2247a61e991a99johnny * NOTE: BIOS is disabling this, it needs to be enabled temporarily
2f15eac90d333799a61f99c8b0f11a8524a716b9anish if ((pci_config_get16(cfg_hdl, PCI_CONF_VENID) == NVIDIA_VENDOR_ID) &&
2f15eac90d333799a61f99c8b0f11a8524a716b9anish cya1 = pci_config_get16(cfg_hdl, NVIDIA_CK804_VEND_CYA1_OFF);
7a23d1009aa28ea040052630547929b9c5eb6ab4anish * If the bridge is empty, disable it
7a23d1009aa28ea040052630547929b9c5eb6ab4anishnpe_disable_empty_bridges_workaround(dev_info_t *child)
7a23d1009aa28ea040052630547929b9c5eb6ab4anish * Do not bind drivers to empty bridges.
7a23d1009aa28ea040052630547929b9c5eb6ab4anish * Fail above, if the bridge is found to be hotplug capable
7a23d1009aa28ea040052630547929b9c5eb6ab4anish if (ddi_driver_major(child) == ddi_name_to_major("pcie_pci") &&
7a23d1009aa28ea040052630547929b9c5eb6ab4anish ddi_prop_get_int(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
7a23d1009aa28ea040052630547929b9c5eb6ab4anish "pci-hotplug-type", INBAND_HPC_NONE) == INBAND_HPC_NONE)
7a23d1009aa28ea040052630547929b9c5eb6ab4anish return (1);
7a23d1009aa28ea040052630547929b9c5eb6ab4anish return (0);
eae2e508a8e70b1ec407b10bd068c080651bbe5ckrishnae uint16_t vendor_id = pci_config_get16(cfg_hdl, PCI_CONF_VENID);
eae2e508a8e70b1ec407b10bd068c080651bbe5ckrishnae uint16_t dev_id = pci_config_get16(cfg_hdl, PCI_CONF_DEVID);
eae2e508a8e70b1ec407b10bd068c080651bbe5ckrishnae if ((vendor_id == NVIDIA_VENDOR_ID) && NVIDIA_PCIE_RC_DEV_ID(dev_id)) {
eae2e508a8e70b1ec407b10bd068c080651bbe5ckrishnae /* Disable ECRC for all devices */
eae2e508a8e70b1ec407b10bd068c080651bbe5ckrishnae regs = pcie_get_aer_uce_mask() | npe_aer_uce_mask |
eae2e508a8e70b1ec407b10bd068c080651bbe5ckrishnae * Turn full scan on since the Error Source ID register may not
eae2e508a8e70b1ec407b10bd068c080651bbe5ckrishnae * have the correct ID.
5c0a55ff7158dbb6220c31dda253139cf9cf5fdeet uint16_t vendor_id = pci_config_get16(cfg_hdl, PCI_CONF_VENID);
5c0a55ff7158dbb6220c31dda253139cf9cf5fdeet * Due to an errata in Intel's ESB2 southbridge, all ECRCs
5c0a55ff7158dbb6220c31dda253139cf9cf5fdeet * generation/checking need to be disabled. There is a
5c0a55ff7158dbb6220c31dda253139cf9cf5fdeet * workaround by setting a proprietary bit in the ESB2, but it
5c0a55ff7158dbb6220c31dda253139cf9cf5fdeet * is not well documented or understood. If that bit is set in
5c0a55ff7158dbb6220c31dda253139cf9cf5fdeet * the future, then ECRC generation/checking should be enabled
5c0a55ff7158dbb6220c31dda253139cf9cf5fdeet * Disable ECRC generation/checking by masking ECRC in the AER
5c0a55ff7158dbb6220c31dda253139cf9cf5fdeet * UE Mask. The pcie misc module would then automatically
5c0a55ff7158dbb6220c31dda253139cf9cf5fdeet * disable ECRC generation/checking in the AER Control register.
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * Check's if this child is a PCI device.
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * Child is a PCI device if:
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * parent has a dev_type of "pci"
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * child does not have a dev_type of "pciex"
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * If the parent is not of dev_type "pci", then assume it is "pciex" and all
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * children should support using PCIe style MMCFG access.
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * If parent's dev_type is "pci" and child is "pciex", then also enable using
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * PCIe style MMCFG access. This covers the case where NPE is "pci" and a PCIe
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * RP is beneath.
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_get_parent(dip),
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur DDI_PROP_DONTPASS, "device_type", &dev_type) ==
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur parent_is_pci = (strcmp(dev_type, "pci") == 0);
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur "device_type", &dev_type) == DDI_PROP_SUCCESS) {
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur child_is_pciex = (strcmp(dev_type, "pciex") == 0);
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * Checks to see if MMCFG is supported and enables it if necessary.
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * Returns: TRUE is MMCFG is support, FLASE is not.
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * In general if a device sits below a parent who's "dev_type" is "pciex" the
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * support MMCFG. Otherwise, default back to legacy IOCFG access.
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * Enable Legacy PCI config space access for AMD K8 north bridges.
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * Host bridge: AMD HyperTransport Technology Configuration
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * Host bridge: AMD Address Map
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * Host bridge: AMD DRAM Controller
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * Host bridge: AMD Miscellaneous Control
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * These devices do not support MMCFG access.
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur * Enable MMCFG via msr for AMD K10 north bridges
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur vendor_id = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur device_id = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur if (IS_K10_AMD_NTBRIDGE(vendor_id, device_id)) {
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur data = ddi_prop_get_int64(DDI_DEV_T_ANY, dip, 0,
49fbdd30212f016ddd49c4b5c997b0b827ff0962Erwin T Tsaur "ecfga-base-address", 0);