diff options
author | aa72041 <none@none> | 2007-03-01 08:15:27 -0800 |
---|---|---|
committer | aa72041 <none@none> | 2007-03-01 08:15:27 -0800 |
commit | 34d3f749ac43373799b9d54ef5a45245b0ee2883 (patch) | |
tree | 05bf2ea3e13bb313d8807e043412bc38e3f9fcdc | |
parent | ef6c36dbbd258b0657b4755d78d229d176457bc3 (diff) | |
download | illumos-gate-34d3f749ac43373799b9d54ef5a45245b0ee2883.tar.gz |
6521915 EFCode interpreter can not access extended config space on PCIe devices
-rw-r--r-- | usr/src/uts/common/sys/pci.h | 2 | ||||
-rw-r--r-- | usr/src/uts/sun4/io/efcode/fcpci.c | 29 |
2 files changed, 19 insertions, 12 deletions
diff --git a/usr/src/uts/common/sys/pci.h b/usr/src/uts/common/sys/pci.h index 9f65ba6026..647a2060e3 100644 --- a/usr/src/uts/common/sys/pci.h +++ b/usr/src/uts/common/sys/pci.h @@ -970,11 +970,13 @@ typedef struct pci_phys_spec pci_regspec_t; #define PCI_REG_PF_M 0x40000000 /* prefetch bit mask */ #define PCI_REG_REL_M 0x80000000 /* relocation bit mask */ #define PCI_REG_BDFR_M 0xffffff /* bus, dev, func, reg mask */ +#define PCI_REG_EXTREG_M 0xF0000000 /* extended config bits mask */ #define PCI_REG_FUNC_SHIFT 8 /* Offset of function bits */ #define PCI_REG_DEV_SHIFT 11 /* Offset of device bits */ #define PCI_REG_BUS_SHIFT 16 /* Offset of bus bits */ #define PCI_REG_ADDR_SHIFT 24 /* Offset of address bits */ +#define PCI_REG_EXTREG_SHIFT 28 /* Offset of ext. config bits */ #define PCI_REG_REG_G(x) ((x) & PCI_REG_REG_M) #define PCI_REG_FUNC_G(x) (((x) & PCI_REG_FUNC_M) >> PCI_REG_FUNC_SHIFT) diff --git a/usr/src/uts/sun4/io/efcode/fcpci.c b/usr/src/uts/sun4/io/efcode/fcpci.c index 1f3e8fbee8..5e2ec1e1e0 100644 --- a/usr/src/uts/sun4/io/efcode/fcpci.c +++ b/usr/src/uts/sun4/io/efcode/fcpci.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -45,7 +45,9 @@ #include <sys/promimpl.h> #include <sys/ddi_implfuncs.h> -#define PCI_NPT_bits (PCI_RELOCAT_B | PCI_PREFETCH_B | PCI_ALIAS_B) +#define PCI_NPT_bits (PCI_RELOCAT_B | PCI_PREFETCH_B | PCI_ALIAS_B) +#define PCI_BDF_bits (PCI_REG_BDFR_M & ~PCI_REG_REG_M) + #define PCICFG_CONF_INDIRECT_MAP 1 static int pfc_map_in(dev_info_t *, fco_handle_t, fc_ci_t *); @@ -856,10 +858,9 @@ pfc_config_fetch(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp) /* * Verify that the address is a configuration space address - * ss must be zero, n,p,t must be zero. + * ss must be zero. */ - if (((p.pci_phys_hi & PCI_ADDR_MASK) != PCI_ADDR_CONFIG) || - ((p.pci_phys_hi & PCI_NPT_bits) != 0)) { + if ((p.pci_phys_hi & PCI_ADDR_MASK) != PCI_ADDR_CONFIG) { cmn_err(CE_CONT, "pfc_config_fetch: " "invalid config addr: %x\n", p.pci_phys_hi); return (fc_priv_error(cp, "non-config addr")); @@ -869,8 +870,11 @@ pfc_config_fetch(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp) * Extract the register number from the config address and * remove the register number from the physical address. */ - reg = p.pci_phys_hi & PCI_REG_REG_M; - p.pci_phys_hi &= ~PCI_REG_REG_M; + + reg = (p.pci_phys_hi & PCI_REG_REG_M) | + (((p.pci_phys_hi & PCI_REG_EXTREG_M) >> PCI_REG_EXTREG_SHIFT) << 8); + + p.pci_phys_hi &= PCI_BDF_bits; /* * Determine the access width .. we can switch on the 9th @@ -986,10 +990,9 @@ pfc_config_store(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp) /* * Verify that the address is a configuration space address - * ss must be zero, n,p,t must be zero. + * ss must be zero. */ - if (((p.pci_phys_hi & PCI_ADDR_MASK) != PCI_ADDR_CONFIG) || - ((p.pci_phys_hi & PCI_NPT_bits) != 0)) { + if ((p.pci_phys_hi & PCI_ADDR_MASK) != PCI_ADDR_CONFIG) { cmn_err(CE_CONT, "pfc_config_store: " "invalid config addr: %x\n", p.pci_phys_hi); return (fc_priv_error(cp, "non-config addr")); @@ -999,8 +1002,10 @@ pfc_config_store(dev_info_t *ap, fco_handle_t rp, fc_ci_t *cp) * Extract the register number from the config address and * remove the register number from the physical address. */ - reg = p.pci_phys_hi & PCI_REG_REG_M; - p.pci_phys_hi &= ~PCI_REG_REG_M; + reg = (p.pci_phys_hi & PCI_REG_REG_M) | + (((p.pci_phys_hi & PCI_REG_EXTREG_M) >> PCI_REG_EXTREG_SHIFT) << 8); + + p.pci_phys_hi &= PCI_BDF_bits; /* * Determine the access width .. we can switch on the 8th |