pci.c (252315) | pci.c (253120) |
---|---|
1/*- 2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 3 * Copyright (c) 2000, Michael Smith <msmith@freebsd.org> 4 * Copyright (c) 2000, BSDi 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 13 unchanged lines hidden (view full) --- 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 3 * Copyright (c) 2000, Michael Smith <msmith@freebsd.org> 4 * Copyright (c) 2000, BSDi 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 13 unchanged lines hidden (view full) --- 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/dev/pci/pci.c 252315 2013-06-27 20:21:54Z jhb $"); | 30__FBSDID("$FreeBSD: head/sys/dev/pci/pci.c 253120 2013-07-09 23:12:26Z marius $"); |
31 32#include "opt_bus.h" 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/malloc.h> 37#include <sys/module.h> 38#include <sys/linker.h> --- 34 unchanged lines hidden (view full) --- 73#if (BUS_SPACE_MAXADDR > 0xFFFFFFFF) 74#define PCI_DMA_BOUNDARY 0x100000000 75#endif 76 77#define PCIR_IS_BIOS(cfg, reg) \ 78 (((cfg)->hdrtype == PCIM_HDRTYPE_NORMAL && reg == PCIR_BIOS) || \ 79 ((cfg)->hdrtype == PCIM_HDRTYPE_BRIDGE && reg == PCIR_BIOS_1)) 80 | 31 32#include "opt_bus.h" 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/malloc.h> 37#include <sys/module.h> 38#include <sys/linker.h> --- 34 unchanged lines hidden (view full) --- 73#if (BUS_SPACE_MAXADDR > 0xFFFFFFFF) 74#define PCI_DMA_BOUNDARY 0x100000000 75#endif 76 77#define PCIR_IS_BIOS(cfg, reg) \ 78 (((cfg)->hdrtype == PCIM_HDRTYPE_NORMAL && reg == PCIR_BIOS) || \ 79 ((cfg)->hdrtype == PCIM_HDRTYPE_BRIDGE && reg == PCIR_BIOS_1)) 80 |
81static int pci_has_quirk(uint32_t devid, int quirk); |
|
81static pci_addr_t pci_mapbase(uint64_t mapreg); 82static const char *pci_maptype(uint64_t mapreg); 83static int pci_mapsize(uint64_t testval); 84static int pci_maprange(uint64_t mapreg); 85static pci_addr_t pci_rombase(uint64_t mapreg); 86static int pci_romsize(uint64_t testval); 87static void pci_fixancient(pcicfgregs *cfg); 88static int pci_printf(pcicfgregs *cfg, const char *fmt, ...); --- 25 unchanged lines hidden (view full) --- 114static void pci_disable_msi(device_t dev); 115static void pci_enable_msi(device_t dev, uint64_t address, 116 uint16_t data); 117static void pci_enable_msix(device_t dev, u_int index, 118 uint64_t address, uint32_t data); 119static void pci_mask_msix(device_t dev, u_int index); 120static void pci_unmask_msix(device_t dev, u_int index); 121static int pci_msi_blacklisted(void); | 82static pci_addr_t pci_mapbase(uint64_t mapreg); 83static const char *pci_maptype(uint64_t mapreg); 84static int pci_mapsize(uint64_t testval); 85static int pci_maprange(uint64_t mapreg); 86static pci_addr_t pci_rombase(uint64_t mapreg); 87static int pci_romsize(uint64_t testval); 88static void pci_fixancient(pcicfgregs *cfg); 89static int pci_printf(pcicfgregs *cfg, const char *fmt, ...); --- 25 unchanged lines hidden (view full) --- 115static void pci_disable_msi(device_t dev); 116static void pci_enable_msi(device_t dev, uint64_t address, 117 uint16_t data); 118static void pci_enable_msix(device_t dev, u_int index, 119 uint64_t address, uint32_t data); 120static void pci_mask_msix(device_t dev, u_int index); 121static void pci_unmask_msix(device_t dev, u_int index); 122static int pci_msi_blacklisted(void); |
123static int pci_msix_blacklisted(void); |
|
122static void pci_resume_msi(device_t dev); 123static void pci_resume_msix(device_t dev); 124static int pci_remap_intr_method(device_t bus, device_t dev, 125 u_int irq); 126 127static device_method_t pci_methods[] = { 128 /* Device interface */ 129 DEVMETHOD(device_probe, pci_probe), --- 50 unchanged lines hidden (view full) --- 180 DEVMETHOD(pci_msix_count, pci_msix_count_method), 181 182 DEVMETHOD_END 183}; 184 185DEFINE_CLASS_0(pci, pci_driver, pci_methods, sizeof(struct pci_softc)); 186 187static devclass_t pci_devclass; | 124static void pci_resume_msi(device_t dev); 125static void pci_resume_msix(device_t dev); 126static int pci_remap_intr_method(device_t bus, device_t dev, 127 u_int irq); 128 129static device_method_t pci_methods[] = { 130 /* Device interface */ 131 DEVMETHOD(device_probe, pci_probe), --- 50 unchanged lines hidden (view full) --- 182 DEVMETHOD(pci_msix_count, pci_msix_count_method), 183 184 DEVMETHOD_END 185}; 186 187DEFINE_CLASS_0(pci, pci_driver, pci_methods, sizeof(struct pci_softc)); 188 189static devclass_t pci_devclass; |
188DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, 0); | 190DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, NULL); |
189MODULE_VERSION(pci, 1); 190 191static char *pci_vendordata; 192static size_t pci_vendordata_size; 193 194struct pci_quirk { 195 uint32_t devid; /* Vendor/device of the card */ 196 int type; 197#define PCI_QUIRK_MAP_REG 1 /* PCI map register in weird place */ | 191MODULE_VERSION(pci, 1); 192 193static char *pci_vendordata; 194static size_t pci_vendordata_size; 195 196struct pci_quirk { 197 uint32_t devid; /* Vendor/device of the card */ 198 int type; 199#define PCI_QUIRK_MAP_REG 1 /* PCI map register in weird place */ |
198#define PCI_QUIRK_DISABLE_MSI 2 /* MSI/MSI-X doesn't work */ | 200#define PCI_QUIRK_DISABLE_MSI 2 /* Neither MSI nor MSI-X work */ |
199#define PCI_QUIRK_ENABLE_MSI_VM 3 /* Older chipset in VM where MSI works */ 200#define PCI_QUIRK_UNMAP_REG 4 /* Ignore PCI map register */ | 201#define PCI_QUIRK_ENABLE_MSI_VM 3 /* Older chipset in VM where MSI works */ 202#define PCI_QUIRK_UNMAP_REG 4 /* Ignore PCI map register */ |
203#define PCI_QUIRK_DISABLE_MSIX 5 /* MSI-X doesn't work */ |
|
201 int arg1; 202 int arg2; 203}; 204 205static const struct pci_quirk pci_quirks[] = { | 204 int arg1; 205 int arg2; 206}; 207 208static const struct pci_quirk pci_quirks[] = { |
206 /* The Intel 82371AB and 82443MX has a map register at offset 0x90. */ | 209 /* The Intel 82371AB and 82443MX have a map register at offset 0x90. */ |
207 { 0x71138086, PCI_QUIRK_MAP_REG, 0x90, 0 }, 208 { 0x719b8086, PCI_QUIRK_MAP_REG, 0x90, 0 }, 209 /* As does the Serverworks OSB4 (the SMBus mapping register) */ 210 { 0x02001166, PCI_QUIRK_MAP_REG, 0x90, 0 }, 211 212 /* 213 * MSI doesn't work with the ServerWorks CNB20-HE Host Bridge 214 * or the CMIC-SL (AKA ServerWorks GC_LE). --- 18 unchanged lines hidden (view full) --- 233 * bridge. 234 */ 235 { 0x74501022, PCI_QUIRK_DISABLE_MSI, 0, 0 }, 236 237 /* 238 * MSI-X allocation doesn't work properly for devices passed through 239 * by VMware up to at least ESXi 5.1. 240 */ | 210 { 0x71138086, PCI_QUIRK_MAP_REG, 0x90, 0 }, 211 { 0x719b8086, PCI_QUIRK_MAP_REG, 0x90, 0 }, 212 /* As does the Serverworks OSB4 (the SMBus mapping register) */ 213 { 0x02001166, PCI_QUIRK_MAP_REG, 0x90, 0 }, 214 215 /* 216 * MSI doesn't work with the ServerWorks CNB20-HE Host Bridge 217 * or the CMIC-SL (AKA ServerWorks GC_LE). --- 18 unchanged lines hidden (view full) --- 236 * bridge. 237 */ 238 { 0x74501022, PCI_QUIRK_DISABLE_MSI, 0, 0 }, 239 240 /* 241 * MSI-X allocation doesn't work properly for devices passed through 242 * by VMware up to at least ESXi 5.1. 243 */ |
241 { 0x079015ad, PCI_QUIRK_DISABLE_MSI, 0, 0 }, /* PCI/PCI-X */ 242 { 0x07a015ad, PCI_QUIRK_DISABLE_MSI, 0, 0 }, /* PCIe */ | 244 { 0x079015ad, PCI_QUIRK_DISABLE_MSIX, 0, 0 }, /* PCI/PCI-X */ 245 { 0x07a015ad, PCI_QUIRK_DISABLE_MSIX, 0, 0 }, /* PCIe */ |
243 244 /* 245 * Some virtualization environments emulate an older chipset 246 * but support MSI just fine. QEMU uses the Intel 82440. 247 */ 248 { 0x12378086, PCI_QUIRK_ENABLE_MSI_VM, 0, 0 }, 249 250 /* --- 65 unchanged lines hidden (view full) --- 316static int pci_do_msix = 1; 317TUNABLE_INT("hw.pci.enable_msix", &pci_do_msix); 318SYSCTL_INT(_hw_pci, OID_AUTO, enable_msix, CTLFLAG_RW, &pci_do_msix, 1, 319 "Enable support for MSI-X interrupts"); 320 321static int pci_honor_msi_blacklist = 1; 322TUNABLE_INT("hw.pci.honor_msi_blacklist", &pci_honor_msi_blacklist); 323SYSCTL_INT(_hw_pci, OID_AUTO, honor_msi_blacklist, CTLFLAG_RD, | 246 247 /* 248 * Some virtualization environments emulate an older chipset 249 * but support MSI just fine. QEMU uses the Intel 82440. 250 */ 251 { 0x12378086, PCI_QUIRK_ENABLE_MSI_VM, 0, 0 }, 252 253 /* --- 65 unchanged lines hidden (view full) --- 319static int pci_do_msix = 1; 320TUNABLE_INT("hw.pci.enable_msix", &pci_do_msix); 321SYSCTL_INT(_hw_pci, OID_AUTO, enable_msix, CTLFLAG_RW, &pci_do_msix, 1, 322 "Enable support for MSI-X interrupts"); 323 324static int pci_honor_msi_blacklist = 1; 325TUNABLE_INT("hw.pci.honor_msi_blacklist", &pci_honor_msi_blacklist); 326SYSCTL_INT(_hw_pci, OID_AUTO, honor_msi_blacklist, CTLFLAG_RD, |
324 &pci_honor_msi_blacklist, 1, "Honor chipset blacklist for MSI"); | 327 &pci_honor_msi_blacklist, 1, "Honor chipset blacklist for MSI/MSI-X"); |
325 326#if defined(__i386__) || defined(__amd64__) 327static int pci_usb_takeover = 1; 328#else 329static int pci_usb_takeover = 0; 330#endif 331TUNABLE_INT("hw.pci.usb_early_takeover", &pci_usb_takeover); 332SYSCTL_INT(_hw_pci, OID_AUTO, usb_early_takeover, CTLFLAG_RDTUN, 333 &pci_usb_takeover, 1, "Enable early takeover of USB controllers.\n\ 334Disable this if you depend on BIOS emulation of USB devices, that is\n\ 335you use USB devices (like keyboard or mouse) but do not load USB drivers"); 336 | 328 329#if defined(__i386__) || defined(__amd64__) 330static int pci_usb_takeover = 1; 331#else 332static int pci_usb_takeover = 0; 333#endif 334TUNABLE_INT("hw.pci.usb_early_takeover", &pci_usb_takeover); 335SYSCTL_INT(_hw_pci, OID_AUTO, usb_early_takeover, CTLFLAG_RDTUN, 336 &pci_usb_takeover, 1, "Enable early takeover of USB controllers.\n\ 337Disable this if you depend on BIOS emulation of USB devices, that is\n\ 338you use USB devices (like keyboard or mouse) but do not load USB drivers"); 339 |
340static int 341pci_has_quirk(uint32_t devid, int quirk) 342{ 343 const struct pci_quirk *q; 344 345 for (q = &pci_quirks[0]; q->devid; q++) { 346 if (q->devid == devid && q->type == quirk) 347 return (1); 348 } 349 return (0); 350} 351 |
|
337/* Find a device_t by bus/slot/function in domain 0 */ 338 339device_t 340pci_find_bsf(uint8_t bus, uint8_t slot, uint8_t func) 341{ 342 343 return (pci_find_dbsf(0, bus, slot, func)); 344} --- 1076 unchanged lines hidden (view full) --- 1421 rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, 0); 1422 if (rle != NULL && rle->res != NULL) 1423 return (ENXIO); 1424 1425 /* Already have allocated messages? */ 1426 if (cfg->msi.msi_alloc != 0 || cfg->msix.msix_alloc != 0) 1427 return (ENXIO); 1428 | 352/* Find a device_t by bus/slot/function in domain 0 */ 353 354device_t 355pci_find_bsf(uint8_t bus, uint8_t slot, uint8_t func) 356{ 357 358 return (pci_find_dbsf(0, bus, slot, func)); 359} --- 1076 unchanged lines hidden (view full) --- 1436 rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, 0); 1437 if (rle != NULL && rle->res != NULL) 1438 return (ENXIO); 1439 1440 /* Already have allocated messages? */ 1441 if (cfg->msi.msi_alloc != 0 || cfg->msix.msix_alloc != 0) 1442 return (ENXIO); 1443 |
1429 /* If MSI is blacklisted for this system, fail. */ 1430 if (pci_msi_blacklisted()) | 1444 /* If MSI-X is blacklisted for this system, fail. */ 1445 if (pci_msix_blacklisted()) |
1431 return (ENXIO); 1432 1433 /* MSI-X capability present? */ 1434 if (cfg->msix.msix_location == 0 || !pci_do_msix) 1435 return (ENODEV); 1436 1437 /* Make sure the appropriate BARs are mapped. */ 1438 rle = resource_list_find(&dinfo->resources, SYS_RES_MEMORY, --- 539 unchanged lines hidden (view full) --- 1978 1979/* 1980 * Returns true if the specified device is blacklisted because MSI 1981 * doesn't work. 1982 */ 1983int 1984pci_msi_device_blacklisted(device_t dev) 1985{ | 1446 return (ENXIO); 1447 1448 /* MSI-X capability present? */ 1449 if (cfg->msix.msix_location == 0 || !pci_do_msix) 1450 return (ENODEV); 1451 1452 /* Make sure the appropriate BARs are mapped. */ 1453 rle = resource_list_find(&dinfo->resources, SYS_RES_MEMORY, --- 539 unchanged lines hidden (view full) --- 1993 1994/* 1995 * Returns true if the specified device is blacklisted because MSI 1996 * doesn't work. 1997 */ 1998int 1999pci_msi_device_blacklisted(device_t dev) 2000{ |
1986 const struct pci_quirk *q; | |
1987 1988 if (!pci_honor_msi_blacklist) 1989 return (0); 1990 | 2001 2002 if (!pci_honor_msi_blacklist) 2003 return (0); 2004 |
1991 for (q = &pci_quirks[0]; q->devid; q++) { 1992 if (q->devid == pci_get_devid(dev) && 1993 q->type == PCI_QUIRK_DISABLE_MSI) 1994 return (1); 1995 } 1996 return (0); | 2005 return (pci_has_quirk(pci_get_devid(dev), PCI_QUIRK_DISABLE_MSI)); |
1997} 1998 1999/* | 2006} 2007 2008/* |
2000 * Returns true if a specified chipset supports MSI when it is 2001 * emulated hardware in a virtual machine. 2002 */ 2003static int 2004pci_msi_vm_chipset(device_t dev) 2005{ 2006 const struct pci_quirk *q; 2007 2008 for (q = &pci_quirks[0]; q->devid; q++) { 2009 if (q->devid == pci_get_devid(dev) && 2010 q->type == PCI_QUIRK_ENABLE_MSI_VM) 2011 return (1); 2012 } 2013 return (0); 2014} 2015 2016/* 2017 * Determine if MSI is blacklisted globally on this sytem. Currently, | 2009 * Determine if MSI is blacklisted globally on this system. Currently, |
2018 * we just check for blacklisted chipsets as represented by the 2019 * host-PCI bridge at device 0:0:0. In the future, it may become 2020 * necessary to check other system attributes, such as the kenv values 2021 * that give the motherboard manufacturer and model number. 2022 */ 2023static int 2024pci_msi_blacklisted(void) 2025{ 2026 device_t dev; 2027 2028 if (!pci_honor_msi_blacklist) 2029 return (0); 2030 2031 /* Blacklist all non-PCI-express and non-PCI-X chipsets. */ 2032 if (!(pcie_chipset || pcix_chipset)) { 2033 if (vm_guest != VM_GUEST_NO) { | 2010 * we just check for blacklisted chipsets as represented by the 2011 * host-PCI bridge at device 0:0:0. In the future, it may become 2012 * necessary to check other system attributes, such as the kenv values 2013 * that give the motherboard manufacturer and model number. 2014 */ 2015static int 2016pci_msi_blacklisted(void) 2017{ 2018 device_t dev; 2019 2020 if (!pci_honor_msi_blacklist) 2021 return (0); 2022 2023 /* Blacklist all non-PCI-express and non-PCI-X chipsets. */ 2024 if (!(pcie_chipset || pcix_chipset)) { 2025 if (vm_guest != VM_GUEST_NO) { |
2026 /* 2027 * Whitelist older chipsets in virtual 2028 * machines known to support MSI. 2029 */ |
|
2034 dev = pci_find_bsf(0, 0, 0); 2035 if (dev != NULL) | 2030 dev = pci_find_bsf(0, 0, 0); 2031 if (dev != NULL) |
2036 return (pci_msi_vm_chipset(dev) == 0); | 2032 return (!pci_has_quirk(pci_get_devid(dev), 2033 PCI_QUIRK_ENABLE_MSI_VM)); |
2037 } 2038 return (1); 2039 } 2040 2041 dev = pci_find_bsf(0, 0, 0); 2042 if (dev != NULL) 2043 return (pci_msi_device_blacklisted(dev)); 2044 return (0); 2045} 2046 2047/* | 2034 } 2035 return (1); 2036 } 2037 2038 dev = pci_find_bsf(0, 0, 0); 2039 if (dev != NULL) 2040 return (pci_msi_device_blacklisted(dev)); 2041 return (0); 2042} 2043 2044/* |
2045 * Returns true if the specified device is blacklisted because MSI-X 2046 * doesn't work. Note that this assumes that if MSI doesn't work, 2047 * MSI-X doesn't either. 2048 */ 2049int 2050pci_msix_device_blacklisted(device_t dev) 2051{ 2052 2053 if (!pci_honor_msi_blacklist) 2054 return (0); 2055 2056 if (pci_has_quirk(pci_get_devid(dev), PCI_QUIRK_DISABLE_MSIX)) 2057 return (1); 2058 2059 return (pci_msi_device_blacklisted(dev)); 2060} 2061 2062/* 2063 * Determine if MSI-X is blacklisted globally on this system. If MSI 2064 * is blacklisted, assume that MSI-X is as well. Check for additional 2065 * chipsets where MSI works but MSI-X does not. 2066 */ 2067static int 2068pci_msix_blacklisted(void) 2069{ 2070 device_t dev; 2071 2072 if (!pci_honor_msi_blacklist) 2073 return (0); 2074 2075 dev = pci_find_bsf(0, 0, 0); 2076 if (dev != NULL && pci_has_quirk(pci_get_devid(dev), 2077 PCI_QUIRK_DISABLE_MSIX)) 2078 return (1); 2079 2080 return (pci_msi_blacklisted()); 2081} 2082 2083/* |
|
2048 * Attempt to allocate *count MSI messages. The actual number allocated is 2049 * returned in *count. After this function returns, each message will be 2050 * available to the driver as SYS_RES_IRQ resources starting at a rid 1. 2051 */ 2052int 2053pci_alloc_msi_method(device_t dev, device_t child, int *count) 2054{ 2055 struct pci_devinfo *dinfo = device_get_ivars(child); --- 2706 unchanged lines hidden --- | 2084 * Attempt to allocate *count MSI messages. The actual number allocated is 2085 * returned in *count. After this function returns, each message will be 2086 * available to the driver as SYS_RES_IRQ resources starting at a rid 1. 2087 */ 2088int 2089pci_alloc_msi_method(device_t dev, device_t child, int *count) 2090{ 2091 struct pci_devinfo *dinfo = device_get_ivars(child); --- 2706 unchanged lines hidden --- |