summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraa72041 <none@none>2007-03-01 08:15:27 -0800
committeraa72041 <none@none>2007-03-01 08:15:27 -0800
commit34d3f749ac43373799b9d54ef5a45245b0ee2883 (patch)
tree05bf2ea3e13bb313d8807e043412bc38e3f9fcdc
parentef6c36dbbd258b0657b4755d78d229d176457bc3 (diff)
downloadillumos-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.h2
-rw-r--r--usr/src/uts/sun4/io/efcode/fcpci.c29
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