summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authormsaitoh <msaitoh@NetBSD.org>2015-10-02 05:22:49 +0000
committermsaitoh <msaitoh@NetBSD.org>2015-10-02 05:22:49 +0000
commit998866035fb2f446df656a6ae9e4b0ee4ddc445c (patch)
treed95622964c21680e079f5097dd6a20e673e3c349 /sys
parent058cde2471e6b21a2d85f267a5be1ec6b7a472b9 (diff)
PCI Extended Configuration stuff written by nonaka@:
- Add PCI Extended Configuration Space support into x86. - Check register offset of pci_conf_read() in MD part. It returns (pcireg_t)-1 if it isn't accessible. - Decode Extended Capability in PCI Extended Configuration Space. Currently the following extended capabilities are decoded: - Advanced Error Reporting - Virtual Channel - Device Serial Number - Power Budgeting - Root Complex Link Declaration - Root Complex Event Collector Association - Access Control Services - Alternative Routing-ID Interpretation - Address Translation Services - Single Root IO Virtualization - Page Request - TPH Requester - Latency Tolerance Reporting - Secondary PCI Express - Process Address Space ID - LN Requester - L1 PM Substates The following extended capabilities are not decoded yet: - Root Complex Internal Link Control - Multi-Function Virtual Channel - RCRB Header - Vendor Unique - Configuration Access Correction - Multiple Root IO Virtualization - Multicast - Resizable BAR - Dynamic Power Allocation - Protocol Multiplexing - Downstream Port Containment - Precision Time Management - M-PCIe - Function Reading Status Queueing - Readiness Time Reporting - Designated Vendor-Specific
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/algor/pci/vtpbc.c7
-rw-r--r--sys/arch/alpha/pci/apecs_pci.c10
-rw-r--r--sys/arch/alpha/pci/cia_pci.c10
-rw-r--r--sys/arch/alpha/pci/dwlpx_pci.c10
-rw-r--r--sys/arch/alpha/pci/irongate_pci.c13
-rw-r--r--sys/arch/alpha/pci/lca_pci.c10
-rw-r--r--sys/arch/alpha/pci/mcpcia_pci.c10
-rw-r--r--sys/arch/alpha/pci/tsp_pci.c10
-rw-r--r--sys/arch/alpha/pci/ttwoga_pci.c10
-rw-r--r--sys/arch/amiga/pci/cv3dpb.c8
-rw-r--r--sys/arch/amiga/pci/em4k.c8
-rw-r--r--sys/arch/amiga/pci/empb.c8
-rw-r--r--sys/arch/amiga/pci/mppb.c8
-rw-r--r--sys/arch/amiga/pci/p5pb.c8
-rw-r--r--sys/arch/arc/pci/necpb.c10
-rw-r--r--sys/arch/arm/broadcom/bcm53xx_pax.c8
-rw-r--r--sys/arch/arm/footbridge/footbridge_pci.c10
-rw-r--r--sys/arch/arm/gemini/gemini_pci.c8
-rw-r--r--sys/arch/arm/ixp12x0/ixp12x0_pci.c7
-rw-r--r--sys/arch/arm/marvell/pci_machdep.c13
-rw-r--r--sys/arch/arm/nvidia/tegra_pcie.c10
-rw-r--r--sys/arch/arm/s3c2xx0/s3c2800_pci.c8
-rw-r--r--sys/arch/arm/xscale/becc_pci.c7
-rw-r--r--sys/arch/arm/xscale/i80312_pci.c7
-rw-r--r--sys/arch/arm/xscale/i80321_pci.c7
-rw-r--r--sys/arch/arm/xscale/ixp425_pci.c10
-rw-r--r--sys/arch/atari/pci/pci_hades.c11
-rw-r--r--sys/arch/atari/pci/pci_milan.c11
-rw-r--r--sys/arch/cobalt/pci/pci_machdep.c10
-rw-r--r--sys/arch/dreamcast/dev/g2/gapspci_pci.c10
-rw-r--r--sys/arch/evbarm/ifpga/ifpga_pci.c10
-rw-r--r--sys/arch/evbmips/loongson/dev/glx.c10
-rw-r--r--sys/arch/evbmips/malta/dev/gt.c10
-rw-r--r--sys/arch/hpcmips/dev/plum.c10
-rw-r--r--sys/arch/hpcmips/vr/vrc4172pci.c10
-rw-r--r--sys/arch/hpcmips/vr/vrpciu.c11
-rw-r--r--sys/arch/hppa/dev/dino.c10
-rw-r--r--sys/arch/hppa/dev/elroy.c10
-rw-r--r--sys/arch/ia64/pci/pci_machdep.c10
-rw-r--r--sys/arch/macppc/pci/bandit.c10
-rw-r--r--sys/arch/macppc/pci/grackle.c10
-rw-r--r--sys/arch/macppc/pci/u3.c8
-rw-r--r--sys/arch/macppc/pci/uninorth.c16
-rw-r--r--sys/arch/mips/adm5120/dev/admpci.c8
-rw-r--r--sys/arch/mips/alchemy/dev/aupci.c7
-rw-r--r--sys/arch/mips/atheros/dev/arpci.c10
-rw-r--r--sys/arch/mips/bonito/bonito_pci.c7
-rw-r--r--sys/arch/mips/rmi/rmixl_pcie.c8
-rw-r--r--sys/arch/mips/rmi/rmixl_pcix.c7
-rw-r--r--sys/arch/mips/sibyte/pci/sbbrz_pci.c10
-rw-r--r--sys/arch/powerpc/booke/pci/pq3pci.c16
-rw-r--r--sys/arch/powerpc/ibm4xx/pci/pci_machdep.c10
-rw-r--r--sys/arch/powerpc/pci/pciconf_indirect.c10
-rw-r--r--sys/arch/powerpc/pci/pciconf_ofmethod.c10
-rw-r--r--sys/arch/prep/pci/prep_pciconf_direct.c10
-rw-r--r--sys/arch/sandpoint/pci/pci_machdep.c10
-rw-r--r--sys/arch/sgimips/gio/pci_gio.c10
-rw-r--r--sys/arch/sgimips/mace/pci_mace.c10
-rw-r--r--sys/arch/sh3/dev/shpcic.c10
-rw-r--r--sys/arch/sparc/sparc/pci_machdep.c14
-rw-r--r--sys/arch/sparc64/dev/psycho.c11
-rw-r--r--sys/arch/sparc64/dev/pyro.c9
-rw-r--r--sys/arch/sparc64/dev/schizo.c9
-rw-r--r--sys/arch/x86/acpi/acpi_machdep.c96
-rw-r--r--sys/arch/x86/pci/pci_machdep.c47
-rw-r--r--sys/dev/acpi/acpi.c10
-rw-r--r--sys/dev/acpi/acpi_mcfg.c697
-rw-r--r--sys/dev/acpi/acpi_mcfg.h58
-rw-r--r--sys/dev/acpi/files.acpi3
-rw-r--r--sys/dev/marvell/gtpci.c10
-rw-r--r--sys/dev/marvell/mvpex.c10
-rw-r--r--sys/dev/pci/pci.c44
-rw-r--r--sys/dev/pci/pci_subr.c1225
-rw-r--r--sys/dev/pci/pcireg.h500
-rw-r--r--sys/dev/pci/pcivar.h14
75 files changed, 3153 insertions, 169 deletions
diff --git a/sys/arch/algor/pci/vtpbc.c b/sys/arch/algor/pci/vtpbc.c
index f5e34781813..589f0363d64 100644
--- a/sys/arch/algor/pci/vtpbc.c
+++ b/sys/arch/algor/pci/vtpbc.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vtpbc.c,v 1.9 2012/10/27 17:17:25 chs Exp $ */
+/* $NetBSD: vtpbc.c,v 1.10 2015/10/02 05:22:49 msaitoh Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vtpbc.c,v 1.9 2012/10/27 17:17:25 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vtpbc.c,v 1.10 2015/10/02 05:22:49 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -165,6 +165,9 @@ vtpbc_conf_addr(struct vtpbc_config *vt, pcitag_t tag, int offset,
{
int b, d, f;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (1);
+
vtpbc_decompose_tag(vt, tag, &b, &d, &f);
if (b == 0) {
diff --git a/sys/arch/alpha/pci/apecs_pci.c b/sys/arch/alpha/pci/apecs_pci.c
index 1161db2176c..5cb66b2b0f3 100644
--- a/sys/arch/alpha/pci/apecs_pci.c
+++ b/sys/arch/alpha/pci/apecs_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: apecs_pci.c,v 1.25 2012/02/06 02:14:14 matt Exp $ */
+/* $NetBSD: apecs_pci.c,v 1.26 2015/10/02 05:22:49 msaitoh Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -29,7 +29,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: apecs_pci.c,v 1.25 2012/02/06 02:14:14 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: apecs_pci.c,v 1.26 2015/10/02 05:22:49 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -101,6 +101,9 @@ apecs_conf_read(void *cpv, pcitag_t tag, int offset)
int s, secondary, ba;
int32_t old_haxr2; /* XXX */
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
s = 0; /* XXX gcc -Wuninitialized */
old_haxr2 = 0; /* XXX gcc -Wuninitialized */
@@ -146,6 +149,9 @@ apecs_conf_write(void *cpv, pcitag_t tag, int offset, pcireg_t data)
int s, secondary;
int32_t old_haxr2; /* XXX */
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return;
+
s = 0; /* XXX gcc -Wuninitialized */
old_haxr2 = 0; /* XXX gcc -Wuninitialized */
diff --git a/sys/arch/alpha/pci/cia_pci.c b/sys/arch/alpha/pci/cia_pci.c
index 82bac7e0999..183c2bac735 100644
--- a/sys/arch/alpha/pci/cia_pci.c
+++ b/sys/arch/alpha/pci/cia_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cia_pci.c,v 1.32 2012/02/06 02:14:14 matt Exp $ */
+/* $NetBSD: cia_pci.c,v 1.33 2015/10/02 05:22:49 msaitoh Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -29,7 +29,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: cia_pci.c,v 1.32 2012/02/06 02:14:14 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cia_pci.c,v 1.33 2015/10/02 05:22:49 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -101,6 +101,9 @@ cia_conf_read(void *cpv, pcitag_t tag, int offset)
int s, secondary, ba;
uint32_t old_cfg, errbits;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
#ifdef __GNUC__
s = 0; /* XXX gcc -Wuninitialized */
old_cfg = 0; /* XXX gcc -Wuninitialized */
@@ -196,6 +199,9 @@ cia_conf_write(void *cpv, pcitag_t tag, int offset, pcireg_t data)
int s, secondary;
uint32_t old_cfg;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return;
+
#ifdef __GNUC__
s = 0; /* XXX gcc -Wuninitialized */
old_cfg = 0; /* XXX gcc -Wuninitialized */
diff --git a/sys/arch/alpha/pci/dwlpx_pci.c b/sys/arch/alpha/pci/dwlpx_pci.c
index 6fdb4729874..b04e2645b14 100644
--- a/sys/arch/alpha/pci/dwlpx_pci.c
+++ b/sys/arch/alpha/pci/dwlpx_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dwlpx_pci.c,v 1.18 2012/02/06 02:14:14 matt Exp $ */
+/* $NetBSD: dwlpx_pci.c,v 1.19 2015/10/02 05:22:49 msaitoh Exp $ */
/*
* Copyright (c) 1997 by Matthew Jacob
@@ -32,7 +32,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: dwlpx_pci.c,v 1.18 2012/02/06 02:14:14 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dwlpx_pci.c,v 1.19 2015/10/02 05:22:49 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -125,6 +125,9 @@ dwlpx_conf_read(void *cpv, pcitag_t tag, int offset)
int secondary, i, s = 0;
uint32_t rvp;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (data);
+
if (ccp == NULL) {
panic("NULL ccp in dwlpx_conf_read");
}
@@ -191,6 +194,9 @@ dwlpx_conf_write(void *cpv, pcitag_t tag, int offset, pcireg_t data)
int secondary, i, s = 0;
uint32_t rvp;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return;
+
if (ccp == NULL) {
panic("NULL ccp in dwlpx_conf_write");
}
diff --git a/sys/arch/alpha/pci/irongate_pci.c b/sys/arch/alpha/pci/irongate_pci.c
index 5ba5874f43e..e5af3ebc800 100644
--- a/sys/arch/alpha/pci/irongate_pci.c
+++ b/sys/arch/alpha/pci/irongate_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: irongate_pci.c,v 1.9 2012/02/06 02:14:14 matt Exp $ */
+/* $NetBSD: irongate_pci.c,v 1.10 2015/10/02 05:22:49 msaitoh Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: irongate_pci.c,v 1.9 2012/02/06 02:14:14 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: irongate_pci.c,v 1.10 2015/10/02 05:22:49 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -116,6 +116,9 @@ irongate_conf_read(void *ipv, pcitag_t tag, int offset)
{
int d;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
/*
* The AMD 751 appears in PCI configuration space, but
* that is ... counter-intuitive to the way we normally
@@ -136,6 +139,9 @@ irongate_conf_read0(void *ipv, pcitag_t tag, int offset)
pcireg_t data;
int s;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
PCI_CONF_LOCK(s);
REGVAL(PCI_CONF_ADDR) = (CONFADDR_ENABLE | tag | (offset & 0xff));
alpha_mb();
@@ -152,6 +158,9 @@ irongate_conf_write(void *ipv, pcitag_t tag, int offset, pcireg_t data)
{
int s;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return;
+
PCI_CONF_LOCK(s);
REGVAL(PCI_CONF_ADDR) = (CONFADDR_ENABLE | tag | (offset & 0xff));
alpha_mb();
diff --git a/sys/arch/alpha/pci/lca_pci.c b/sys/arch/alpha/pci/lca_pci.c
index 4de95c958f2..162ec5c65ae 100644
--- a/sys/arch/alpha/pci/lca_pci.c
+++ b/sys/arch/alpha/pci/lca_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: lca_pci.c,v 1.21 2012/02/06 02:14:14 matt Exp $ */
+/* $NetBSD: lca_pci.c,v 1.22 2015/10/02 05:22:49 msaitoh Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -29,7 +29,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: lca_pci.c,v 1.21 2012/02/06 02:14:14 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lca_pci.c,v 1.22 2015/10/02 05:22:49 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -103,6 +103,9 @@ lca_conf_read(void *cpv, pcitag_t tag, int offset)
pcireg_t *datap, data;
int s, secondary, device, ba;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
s = 0; /* XXX gcc -Wuninitialized */
/* secondary if bus # != 0 */
@@ -153,6 +156,9 @@ lca_conf_write(void *cpv, pcitag_t tag, int offset, pcireg_t data)
pcireg_t *datap;
int s, secondary, device;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return;
+
s = 0; /* XXX gcc -Wuninitialized */
/* secondary if bus # != 0 */
diff --git a/sys/arch/alpha/pci/mcpcia_pci.c b/sys/arch/alpha/pci/mcpcia_pci.c
index 71cc153ca2d..64618a0ce69 100644
--- a/sys/arch/alpha/pci/mcpcia_pci.c
+++ b/sys/arch/alpha/pci/mcpcia_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: mcpcia_pci.c,v 1.11 2012/02/06 02:14:14 matt Exp $ */
+/* $NetBSD: mcpcia_pci.c,v 1.12 2015/10/02 05:22:49 msaitoh Exp $ */
/*
* Copyright (c) 1998 by Matthew Jacob
@@ -32,7 +32,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: mcpcia_pci.c,v 1.11 2012/02/06 02:14:14 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mcpcia_pci.c,v 1.12 2015/10/02 05:22:49 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -108,6 +108,9 @@ mcpcia_conf_read(void *cpv, pcitag_t tag, int offset)
pcireg_t *dp, data = (pcireg_t) -1;
unsigned long paddr;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (data);
+
/*
* There's nothing in slot 0 on a primary bus- don't even try.
*/
@@ -136,6 +139,9 @@ mcpcia_conf_write(void *cpv, pcitag_t tag, int offset, pcireg_t data)
pcireg_t *dp;
unsigned long paddr;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return;
+
/*
* There's nothing in slot 0 on a primary bus- don't even try.
*/
diff --git a/sys/arch/alpha/pci/tsp_pci.c b/sys/arch/alpha/pci/tsp_pci.c
index 0dbc53c8c6a..6542a50e739 100644
--- a/sys/arch/alpha/pci/tsp_pci.c
+++ b/sys/arch/alpha/pci/tsp_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tsp_pci.c,v 1.9 2011/06/14 15:34:22 matt Exp $ */
+/* $NetBSD: tsp_pci.c,v 1.10 2015/10/02 05:22:49 msaitoh Exp $ */
/*-
* Copyright (c) 1999 by Ross Harvey. All rights reserved.
@@ -33,7 +33,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tsp_pci.c,v 1.9 2011/06/14 15:34:22 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tsp_pci.c,v 1.10 2015/10/02 05:22:49 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -110,6 +110,9 @@ tsp_conf_read(void *cpv, pcitag_t tag, int offset)
pcireg_t *datap, data;
struct tsp_config *pcp = cpv;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
datap = S_PAGE(pcp->pc_iobase | P_PCI_CONFIG | tag | (offset & ~3));
alpha_mb();
data = *datap;
@@ -123,6 +126,9 @@ tsp_conf_write(void *cpv, pcitag_t tag, int offset, pcireg_t data)
pcireg_t *datap;
struct tsp_config *pcp = cpv;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return;
+
datap = S_PAGE(pcp->pc_iobase | P_PCI_CONFIG | tag | (offset & ~3));
alpha_mb();
*datap = data;
diff --git a/sys/arch/alpha/pci/ttwoga_pci.c b/sys/arch/alpha/pci/ttwoga_pci.c
index bf2f90e8ce1..531afecf20b 100644
--- a/sys/arch/alpha/pci/ttwoga_pci.c
+++ b/sys/arch/alpha/pci/ttwoga_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ttwoga_pci.c,v 1.7 2012/02/06 02:14:15 matt Exp $ */
+/* $NetBSD: ttwoga_pci.c,v 1.8 2015/10/02 05:22:49 msaitoh Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: ttwoga_pci.c,v 1.7 2012/02/06 02:14:15 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ttwoga_pci.c,v 1.8 2015/10/02 05:22:49 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -146,6 +146,9 @@ ttwoga_conf_read(void *cpv, pcitag_t tag, int offset)
paddr_t addr;
uint64_t old_hae3;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
pci_decompose_tag(&tcp->tc_pc, tag, &b, &d, &f);
addr = b ? tag : ttwoga_make_type0addr(d, f);
@@ -198,6 +201,9 @@ ttwoga_conf_write(void *cpv, pcitag_t tag, int offset, pcireg_t data)
paddr_t addr;
uint64_t old_hae3;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return;
+
pci_decompose_tag(&tcp->tc_pc, tag, &b, &d, &f);
addr = b ? tag : ttwoga_make_type0addr(d, f);
diff --git a/sys/arch/amiga/pci/cv3dpb.c b/sys/arch/amiga/pci/cv3dpb.c
index a4546da5d76..c17a8090d6a 100644
--- a/sys/arch/amiga/pci/cv3dpb.c
+++ b/sys/arch/amiga/pci/cv3dpb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cv3dpb.c,v 1.2 2012/10/27 17:17:32 chs Exp $ */
+/* $NetBSD: cv3dpb.c,v 1.3 2015/10/02 05:22:49 msaitoh Exp $ */
/*-
* Copyright (c) 2011, 2012 The NetBSD Foundation, Inc.
@@ -150,6 +150,9 @@ cv3dpb_pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
{
uint32_t data;
uint32_t bus, dev, func;
+
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
pci_decompose_tag(pc, tag, &bus, &dev, &func);
@@ -167,6 +170,9 @@ void
cv3dpb_pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t val)
{
uint32_t bus, dev, func;
+
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
pci_decompose_tag(pc, tag, &bus, &dev, &func);
diff --git a/sys/arch/amiga/pci/em4k.c b/sys/arch/amiga/pci/em4k.c
index dc0c6e1d23a..8a05e39b3ad 100644
--- a/sys/arch/amiga/pci/em4k.c
+++ b/sys/arch/amiga/pci/em4k.c
@@ -1,4 +1,4 @@
-/* $NetBSD: em4k.c,v 1.3 2014/03/22 01:52:44 christos Exp $ */
+/* $NetBSD: em4k.c,v 1.4 2015/10/02 05:22:49 msaitoh Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -314,6 +314,9 @@ em4k_pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
{
uint32_t data;
uint32_t bus, dev, func;
+
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
pci_decompose_tag(pc, tag, &bus, &dev, &func);
@@ -333,6 +336,9 @@ em4k_pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t val)
{
uint32_t bus, dev, func;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
pci_decompose_tag(pc, tag, &bus, &dev, &func);
bus_space_write_4(pc->pci_conf_datat, pc->pci_conf_datah,
diff --git a/sys/arch/amiga/pci/empb.c b/sys/arch/amiga/pci/empb.c
index 1938f0674e5..50a72ed1fef 100644
--- a/sys/arch/amiga/pci/empb.c
+++ b/sys/arch/amiga/pci/empb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: empb.c,v 1.10 2013/01/29 00:49:43 rkujawa Exp $ */
+/* $NetBSD: empb.c,v 1.11 2015/10/02 05:22:49 msaitoh Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -394,6 +394,9 @@ empb_pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
struct empb_softc *sc;
int s;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
sc = pc->cookie;
pci_decompose_tag(pc, tag, &bus, &dev, &func);
@@ -424,6 +427,9 @@ empb_pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t val)
struct empb_softc *sc;
int s;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
sc = pc->cookie;
pci_decompose_tag(pc, tag, &bus, &dev, &func);
diff --git a/sys/arch/amiga/pci/mppb.c b/sys/arch/amiga/pci/mppb.c
index 91af8fefb63..3532d61c515 100644
--- a/sys/arch/amiga/pci/mppb.c
+++ b/sys/arch/amiga/pci/mppb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: mppb.c,v 1.7 2012/10/27 17:17:34 chs Exp $ */
+/* $NetBSD: mppb.c,v 1.8 2015/10/02 05:22:49 msaitoh Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -197,6 +197,9 @@ mppb_pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
{
uint32_t data;
uint32_t bus, dev, func;
+
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
pci_decompose_tag(pc, tag, &bus, &dev, &func);
@@ -215,6 +218,9 @@ mppb_pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t val)
{
uint32_t bus, dev, func;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
pci_decompose_tag(pc, tag, &bus, &dev, &func);
bus_space_write_4(pc->pci_conf_datat, pc->pci_conf_datah,
diff --git a/sys/arch/amiga/pci/p5pb.c b/sys/arch/amiga/pci/p5pb.c
index 56aa207be3c..c72da9c62d2 100644
--- a/sys/arch/amiga/pci/p5pb.c
+++ b/sys/arch/amiga/pci/p5pb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: p5pb.c,v 1.13 2014/03/22 01:52:44 christos Exp $ */
+/* $NetBSD: p5pb.c,v 1.14 2015/10/02 05:22:49 msaitoh Exp $ */
/*-
* Copyright (c) 2011, 2012 The NetBSD Foundation, Inc.
@@ -344,6 +344,9 @@ p5pb_pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
uint32_t bus, dev, func;
uint32_t offset;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return 0xFFFFFFFF;
+
pci_decompose_tag(pc, tag, &bus, &dev, &func);
offset = (OFF_PCI_DEVICE << dev) + reg;
@@ -376,6 +379,9 @@ p5pb_pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t val)
uint32_t bus, dev, func;
uint32_t offset;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
pci_decompose_tag(pc, tag, &bus, &dev, &func);
offset = (OFF_PCI_DEVICE << dev) + reg;
diff --git a/sys/arch/arc/pci/necpb.c b/sys/arch/arc/pci/necpb.c
index a9fd47c3b1a..48d99b5c0d4 100644
--- a/sys/arch/arc/pci/necpb.c
+++ b/sys/arch/arc/pci/necpb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: necpb.c,v 1.41 2014/03/29 19:28:26 christos Exp $ */
+/* $NetBSD: necpb.c,v 1.42 2015/10/02 05:22:49 msaitoh Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: necpb.c,v 1.41 2014/03/29 19:28:26 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: necpb.c,v 1.42 2015/10/02 05:22:49 msaitoh Exp $");
#include "opt_pci.h"
@@ -314,6 +314,9 @@ necpb_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
pcireg_t data;
int s;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
s = splhigh();
out32(RD94_SYS_PCI_CONFADDR, tag | reg);
data = in32(RD94_SYS_PCI_CONFDATA);
@@ -328,6 +331,9 @@ necpb_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
{
int s;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
s = splhigh();
out32(RD94_SYS_PCI_CONFADDR, tag | reg);
out32(RD94_SYS_PCI_CONFDATA, data);
diff --git a/sys/arch/arm/broadcom/bcm53xx_pax.c b/sys/arch/arm/broadcom/bcm53xx_pax.c
index 1053be60bbb..777abea0214 100644
--- a/sys/arch/arm/broadcom/bcm53xx_pax.c
+++ b/sys/arch/arm/broadcom/bcm53xx_pax.c
@@ -34,7 +34,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: bcm53xx_pax.c,v 1.14 2015/02/25 13:52:42 joerg Exp $");
+__KERNEL_RCSID(1, "$NetBSD: bcm53xx_pax.c,v 1.15 2015/10/02 05:22:49 msaitoh Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -435,6 +435,9 @@ bcmpax_conf_read(void *v, pcitag_t tag, int reg)
{
struct bcmpax_softc * const sc = v;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return 0xffffffff;
+
/*
* Even in RC mode, the PCI Express Root Complex return itself
* as BCM Ethernet Controller!. We could change ppb.c to match it
@@ -471,6 +474,9 @@ bcmpax_conf_write(void *v, pcitag_t tag, int reg, pcireg_t val)
{
struct bcmpax_softc * const sc = v;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
mutex_enter(sc->sc_cfg_lock);
bus_size_t data_reg = bcmpax_conf_addr_write(sc, tag | reg);
diff --git a/sys/arch/arm/footbridge/footbridge_pci.c b/sys/arch/arm/footbridge/footbridge_pci.c
index 198d1398d45..e6deee2b27f 100644
--- a/sys/arch/arm/footbridge/footbridge_pci.c
+++ b/sys/arch/arm/footbridge/footbridge_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: footbridge_pci.c,v 1.27 2014/03/30 01:19:20 christos Exp $ */
+/* $NetBSD: footbridge_pci.c,v 1.28 2015/10/02 05:22:49 msaitoh Exp $ */
/*
* Copyright (c) 1997,1998 Mark Brinicombe.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: footbridge_pci.c,v 1.27 2014/03/30 01:19:20 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: footbridge_pci.c,v 1.28 2015/10/02 05:22:49 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -180,6 +180,9 @@ footbridge_pci_conf_read(void *pcv, pcitag_t tag, int reg)
u_int address;
pcireg_t data;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return ((pcireg_t) -1);
+
footbridge_pci_decompose_tag(pcv, tag, &bus, &device, &function);
if (bus == 0)
/* Limited to 12 devices or we exceed type 0 config space */
@@ -204,6 +207,9 @@ footbridge_pci_conf_write(void *pcv, pcitag_t tag, int reg, pcireg_t data)
int bus, device, function;
u_int address;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
footbridge_pci_decompose_tag(pcv, tag, &bus, &device, &function);
if (bus == 0)
address = DC21285_PCI_TYPE_0_CONFIG_VBASE | (3 << 22) | (device << 11);
diff --git a/sys/arch/arm/gemini/gemini_pci.c b/sys/arch/arm/gemini/gemini_pci.c
index 3cfed9267eb..5c327fdf2cb 100644
--- a/sys/arch/arm/gemini/gemini_pci.c
+++ b/sys/arch/arm/gemini/gemini_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: gemini_pci.c,v 1.17 2014/03/30 01:19:20 christos Exp $ */
+/* $NetBSD: gemini_pci.c,v 1.18 2015/10/02 05:22:50 msaitoh Exp $ */
/* adapted from:
* NetBSD: i80312_pci.c,v 1.9 2005/12/11 12:16:51 christos Exp
@@ -44,7 +44,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gemini_pci.c,v 1.17 2014/03/30 01:19:20 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gemini_pci.c,v 1.18 2015/10/02 05:22:50 msaitoh Exp $");
#include "opt_gemini.h"
#include "opt_pci.h"
@@ -285,6 +285,10 @@ static int
gemini_pci_conf_setup(struct obio_softc *sc, pcitag_t tag, int offset,
struct pciconf_state *ps)
{
+
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (1);
+
gemini_pci_decompose_tag(sc, tag, &ps->ps_b, &ps->ps_d, &ps->ps_f);
ps->ps_addr_val =
diff --git a/sys/arch/arm/ixp12x0/ixp12x0_pci.c b/sys/arch/arm/ixp12x0/ixp12x0_pci.c
index e16920f1aa6..2842ef308e8 100644
--- a/sys/arch/arm/ixp12x0/ixp12x0_pci.c
+++ b/sys/arch/arm/ixp12x0/ixp12x0_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ixp12x0_pci.c,v 1.14 2013/08/18 15:58:19 matt Exp $ */
+/* $NetBSD: ixp12x0_pci.c,v 1.15 2015/10/02 05:22:50 msaitoh Exp $ */
/*
* Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ixp12x0_pci.c,v 1.14 2013/08/18 15:58:19 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ixp12x0_pci.c,v 1.15 2015/10/02 05:22:50 msaitoh Exp $");
/*
* PCI configuration support for IXP12x0 Network Processor chip.
@@ -164,6 +164,9 @@ ixp12x0_pci_conf_setup(void *v, struct ixp12x0_softc *sc, pcitag_t tag, int offs
int bus, device, function;
vaddr_t addr;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return 0;
+
ixp12x0_pci_decompose_tag(v, tag, &bus, &device, &function);
if (bus == 0) {
diff --git a/sys/arch/arm/marvell/pci_machdep.c b/sys/arch/arm/marvell/pci_machdep.c
index f75e36fce98..73d7a6f31b5 100644
--- a/sys/arch/arm/marvell/pci_machdep.c
+++ b/sys/arch/arm/marvell/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_machdep.c,v 1.8 2014/03/30 01:19:20 christos Exp $ */
+/* $NetBSD: pci_machdep.c,v 1.9 2015/10/02 05:22:50 msaitoh Exp $ */
/*
* Copyright (c) 2008 KIYOHARA Takashi
* All rights reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.8 2014/03/30 01:19:20 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.9 2015/10/02 05:22:50 msaitoh Exp $");
#include "opt_mvsoc.h"
#include "gtpci.h"
@@ -266,6 +266,9 @@ gtpci_mbus_conf_read(void *v, pcitag_t tag, int reg)
struct gtpci_softc *sc = v;
const pcireg_t addr = tag | reg;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return -1;
+
bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTPCI_MBUS_CA,
addr | GTPCI_CA_CONFIGEN);
if ((addr | GTPCI_CA_CONFIGEN) !=
@@ -281,6 +284,9 @@ gtpci_mbus_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
struct gtpci_softc *sc = v;
pcireg_t addr = tag | (reg & 0xfc);
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTPCI_MBUS_CA,
addr | GTPCI_CA_CONFIGEN);
if ((addr | GTPCI_CA_CONFIGEN) !=
@@ -374,6 +380,9 @@ mvpex_mbus_conf_read(void *v, pcitag_t tag, int reg)
uint32_t stat;
int bus, dev, func, pexbus, pexdev;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return -1;
+
mvpex_decompose_tag(v, tag, &bus, &dev, &func);
stat = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVPEX_STAT);
diff --git a/sys/arch/arm/nvidia/tegra_pcie.c b/sys/arch/arm/nvidia/tegra_pcie.c
index dfb9690ffb7..07dee9b221f 100644
--- a/sys/arch/arm/nvidia/tegra_pcie.c
+++ b/sys/arch/arm/nvidia/tegra_pcie.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_pcie.c,v 1.2 2015/05/03 01:26:44 jmcneill Exp $ */
+/* $NetBSD: tegra_pcie.c,v 1.3 2015/10/02 05:22:50 msaitoh Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@@ -29,7 +29,7 @@
#include "locators.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_pcie.c,v 1.2 2015/05/03 01:26:44 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_pcie.c,v 1.3 2015/10/02 05:22:50 msaitoh Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -298,6 +298,9 @@ tegra_pcie_conf_read(void *v, pcitag_t tag, int offset)
int b, d, f;
u_int reg;
+ if ((unsigned int)offset >= PCI_EXTCONF_SIZE)
+ return (pcireg_t) -1;
+
tegra_pcie_decompose_tag(v, tag, &b, &d, &f);
if (b == 0) {
@@ -319,6 +322,9 @@ tegra_pcie_conf_write(void *v, pcitag_t tag, int offset, pcireg_t val)
int b, d, f;
u_int reg;
+ if ((unsigned int)offset >= PCI_EXTCONF_SIZE)
+ return;
+
tegra_pcie_decompose_tag(v, tag, &b, &d, &f);
if (b == 0) {
diff --git a/sys/arch/arm/s3c2xx0/s3c2800_pci.c b/sys/arch/arm/s3c2xx0/s3c2800_pci.c
index 453b2cfaccd..b4539f43baf 100644
--- a/sys/arch/arm/s3c2xx0/s3c2800_pci.c
+++ b/sys/arch/arm/s3c2xx0/s3c2800_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: s3c2800_pci.c,v 1.21 2014/03/29 19:28:26 christos Exp $ */
+/* $NetBSD: s3c2800_pci.c,v 1.22 2015/10/02 05:22:50 msaitoh Exp $ */
/*
* Copyright (c) 2002 Fujitsu Component Limited
@@ -100,7 +100,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: s3c2800_pci.c,v 1.21 2014/03/29 19:28:26 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: s3c2800_pci.c,v 1.22 2015/10/02 05:22:50 msaitoh Exp $");
#include "opt_pci.h"
#include "pci.h"
@@ -445,6 +445,10 @@ s3c2800_pci_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp)
static vaddr_t
make_pci_conf_va(struct sspci_softc * sc, pcitag_t tag, int offset)
{
+
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (vaddr_t) -1;
+
if ((tag & BUSNO_MASK) == 0) {
/* configuration type 0 */
int devno = tag_to_devno(tag);
diff --git a/sys/arch/arm/xscale/becc_pci.c b/sys/arch/arm/xscale/becc_pci.c
index c5bd1b9dc90..118ef1f7fdb 100644
--- a/sys/arch/arm/xscale/becc_pci.c
+++ b/sys/arch/arm/xscale/becc_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: becc_pci.c,v 1.17 2014/03/30 21:52:09 htodd Exp $ */
+/* $NetBSD: becc_pci.c,v 1.18 2015/10/02 05:22:50 msaitoh Exp $ */
/*
* Copyright (c) 2001, 2002 Wasabi Systems, Inc.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: becc_pci.c,v 1.17 2014/03/30 21:52:09 htodd Exp $");
+__KERNEL_RCSID(0, "$NetBSD: becc_pci.c,v 1.18 2015/10/02 05:22:50 msaitoh Exp $");
#include "opt_pci.h"
#include "pci.h"
@@ -194,6 +194,9 @@ becc_pci_conf_setup(struct becc_softc *sc, pcitag_t tag, int offset,
struct pciconf_state *ps)
{
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (1);
+
becc_pci_decompose_tag(sc, tag, &ps->ps_b, &ps->ps_d, &ps->ps_f);
/*
diff --git a/sys/arch/arm/xscale/i80312_pci.c b/sys/arch/arm/xscale/i80312_pci.c
index 77b0a1ba829..75be0b1925c 100644
--- a/sys/arch/arm/xscale/i80312_pci.c
+++ b/sys/arch/arm/xscale/i80312_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: i80312_pci.c,v 1.15 2014/01/28 12:02:48 martin Exp $ */
+/* $NetBSD: i80312_pci.c,v 1.16 2015/10/02 05:22:50 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i80312_pci.c,v 1.15 2014/01/28 12:02:48 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i80312_pci.c,v 1.16 2015/10/02 05:22:50 msaitoh Exp $");
#include "opt_pci.h"
#include "pci.h"
@@ -180,6 +180,9 @@ i80312_pci_conf_setup(struct i80312_softc *sc, pcitag_t tag, int offset,
pcireg_t binfo;
int pbus, sbus;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (1);
+
i80312_pci_decompose_tag(sc, tag, &ps->ps_b, &ps->ps_d, &ps->ps_f);
binfo = bus_space_read_4(sc->sc_st, sc->sc_ppb_sh, PPB_REG_BUSINFO);
diff --git a/sys/arch/arm/xscale/i80321_pci.c b/sys/arch/arm/xscale/i80321_pci.c
index 8213dd5705d..75d6bb99cc2 100644
--- a/sys/arch/arm/xscale/i80321_pci.c
+++ b/sys/arch/arm/xscale/i80321_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: i80321_pci.c,v 1.15 2013/08/18 15:58:20 matt Exp $ */
+/* $NetBSD: i80321_pci.c,v 1.16 2015/10/02 05:22:50 msaitoh Exp $ */
/*
* Copyright (c) 2001, 2002 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i80321_pci.c,v 1.15 2013/08/18 15:58:20 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i80321_pci.c,v 1.16 2015/10/02 05:22:50 msaitoh Exp $");
#include "opt_pci.h"
#include "opt_i80321.h"
@@ -185,6 +185,9 @@ i80321_pci_conf_setup(struct i80321_softc *sc, pcitag_t tag, int offset,
{
uint32_t busno;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (1);
+
i80321_pci_decompose_tag(sc, tag, &ps->ps_b, &ps->ps_d, &ps->ps_f);
busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
diff --git a/sys/arch/arm/xscale/ixp425_pci.c b/sys/arch/arm/xscale/ixp425_pci.c
index a5e339c7633..3be0b6930e7 100644
--- a/sys/arch/arm/xscale/ixp425_pci.c
+++ b/sys/arch/arm/xscale/ixp425_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ixp425_pci.c,v 1.11 2012/11/12 18:00:38 skrll Exp $ */
+/* $NetBSD: ixp425_pci.c,v 1.12 2015/10/02 05:22:50 msaitoh Exp $ */
/*
* Copyright (c) 2003
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ixp425_pci.c,v 1.11 2012/11/12 18:00:38 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ixp425_pci.c,v 1.12 2015/10/02 05:22:50 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -187,6 +187,9 @@ ixp425_pci_conf_read(void *v, pcitag_t tag, int offset)
int i;
#endif
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
PCI_CONF_LOCK(s);
ixp425_pci_conf_setup(v, sc, tag, offset);
@@ -226,6 +229,9 @@ ixp425_pci_conf_write(void *v, pcitag_t tag, int offset, pcireg_t val)
uint32_t data;
int s;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return;
+
PCI_CONF_LOCK(s);
ixp425_pci_conf_setup(v, sc, tag, offset);
diff --git a/sys/arch/atari/pci/pci_hades.c b/sys/arch/atari/pci/pci_hades.c
index 1a38b8ceea8..86d0073de10 100644
--- a/sys/arch/atari/pci/pci_hades.c
+++ b/sys/arch/atari/pci/pci_hades.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_hades.c,v 1.13 2012/02/13 20:00:00 jdc Exp $ */
+/* $NetBSD: pci_hades.c,v 1.14 2015/10/02 05:22:50 msaitoh Exp $ */
/*
* Copyright (c) 1996 Leo Weppelman. All rights reserved.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_hades.c,v 1.13 2012/02/13 20:00:00 jdc Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_hades.c,v 1.14 2015/10/02 05:22:50 msaitoh Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -79,6 +79,9 @@ pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
{
u_long data;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return ((pcireg_t) -1);
+
data = *(u_long *)(pci_conf_addr + pci_config_offset(tag) + reg);
return (bswap32(data));
}
@@ -86,6 +89,10 @@ pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
void
pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
{
+
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
*((u_long *)(pci_conf_addr + pci_config_offset(tag) + reg))
= bswap32(data);
}
diff --git a/sys/arch/atari/pci/pci_milan.c b/sys/arch/atari/pci/pci_milan.c
index f2572aee5ed..61ca8a0a050 100644
--- a/sys/arch/atari/pci/pci_milan.c
+++ b/sys/arch/atari/pci/pci_milan.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_milan.c,v 1.13 2012/08/12 20:50:39 martin Exp $ */
+/* $NetBSD: pci_milan.c,v 1.14 2015/10/02 05:22:50 msaitoh Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_milan.c,v 1.13 2012/08/12 20:50:39 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_milan.c,v 1.14 2015/10/02 05:22:50 msaitoh Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -67,6 +67,9 @@ pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
{
u_long data;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return 0xffffffff;
+
data = bswap32(milan_pci_confread(tag | reg));
if ((plx_status) & 0xf9000000) {
/*
@@ -81,6 +84,10 @@ pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
void
pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
{
+
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
milan_pci_confwrite(tag | reg, bswap32(data));
}
diff --git a/sys/arch/cobalt/pci/pci_machdep.c b/sys/arch/cobalt/pci/pci_machdep.c
index 821d6970acc..25579852a59 100644
--- a/sys/arch/cobalt/pci/pci_machdep.c
+++ b/sys/arch/cobalt/pci/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_machdep.c,v 1.37 2015/06/09 22:47:59 matt Exp $ */
+/* $NetBSD: pci_machdep.c,v 1.38 2015/10/02 05:22:50 msaitoh Exp $ */
/*
* Copyright (c) 2000 Soren S. Jorvang. All rights reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.37 2015/06/09 22:47:59 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.38 2015/10/02 05:22:50 msaitoh Exp $");
#define _MIPS_BUS_DMA_PRIVATE
@@ -100,6 +100,9 @@ pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
KASSERT(pc != NULL);
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
pci_decompose_tag(pc, tag, &bus, &dev, &func);
/*
@@ -125,6 +128,9 @@ void
pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
{
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
bus_space_write_4(pc->pc_bst, pc->pc_bsh, GT_PCICFG_ADDR,
PCICFG_ENABLE | tag | reg);
bus_space_write_4(pc->pc_bst, pc->pc_bsh, GT_PCICFG_DATA, data);
diff --git a/sys/arch/dreamcast/dev/g2/gapspci_pci.c b/sys/arch/dreamcast/dev/g2/gapspci_pci.c
index 7ae8e97057c..0452e09cc25 100644
--- a/sys/arch/dreamcast/dev/g2/gapspci_pci.c
+++ b/sys/arch/dreamcast/dev/g2/gapspci_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: gapspci_pci.c,v 1.15 2014/03/31 13:12:55 christos Exp $ */
+/* $NetBSD: gapspci_pci.c,v 1.16 2015/10/02 05:22:50 msaitoh Exp $ */
/*-
* Copyright (c) 2001 Marcus Comstedt.
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: gapspci_pci.c,v 1.15 2014/03/31 13:12:55 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gapspci_pci.c,v 1.16 2015/10/02 05:22:50 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -162,6 +162,9 @@ gaps_conf_read(void *v, pcitag_t tag, int reg)
if (tag != GAPS_PCITAG_MAGIC)
return -1;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return -1;
+
if (reg == (PCI_MAPREG_START + 4)) {
/*
* We fake the BAR -- just return the physical address
@@ -181,6 +184,9 @@ gaps_conf_write(void *v, pcitag_t tag, int reg, pcireg_t val)
if (tag != GAPS_PCITAG_MAGIC)
return;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
/* Disallow writing to the "BAR" ... it doesn't actually exist. */
if (reg == (PCI_MAPREG_START + 4) && val != 0x01000000)
return;
diff --git a/sys/arch/evbarm/ifpga/ifpga_pci.c b/sys/arch/evbarm/ifpga/ifpga_pci.c
index 4cf0f7b7d93..440592b051b 100644
--- a/sys/arch/evbarm/ifpga/ifpga_pci.c
+++ b/sys/arch/evbarm/ifpga/ifpga_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ifpga_pci.c,v 1.18 2014/03/29 19:28:27 christos Exp $ */
+/* $NetBSD: ifpga_pci.c,v 1.19 2015/10/02 05:22:50 msaitoh Exp $ */
/*
* Copyright (c) 2001 ARM Ltd
@@ -64,7 +64,7 @@
#define _ARM32_BUS_DMA_PRIVATE
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ifpga_pci.c,v 1.18 2014/03/29 19:28:27 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ifpga_pci.c,v 1.19 2015/10/02 05:22:50 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -212,6 +212,9 @@ ifpga_pci_conf_read(void *pcv, pcitag_t tag, int reg)
int bus, device, function;
u_int address;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
ifpga_pci_decompose_tag(pcv, tag, &bus, &device, &function);
/* Reset the appertures so that we can talk to the register space. */
@@ -264,6 +267,9 @@ ifpga_pci_conf_write(void *pcv, pcitag_t tag, int reg, pcireg_t data)
pcv, tag, reg, data);
#endif
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
ifpga_pci_decompose_tag(pcv, tag, &bus, &device, &function);
/* Reset the appertures so that we can talk to the register space. */
diff --git a/sys/arch/evbmips/loongson/dev/glx.c b/sys/arch/evbmips/loongson/dev/glx.c
index 0bc23477e99..48715bd89df 100644
--- a/sys/arch/evbmips/loongson/dev/glx.c
+++ b/sys/arch/evbmips/loongson/dev/glx.c
@@ -1,4 +1,4 @@
-/* $NetBSD: glx.c,v 1.4 2012/03/11 00:02:04 mrg Exp $ */
+/* $NetBSD: glx.c,v 1.5 2015/10/02 05:22:50 msaitoh Exp $ */
/* $OpenBSD: glx.c,v 1.6 2010/10/14 21:23:04 pirofti Exp $ */
/*
@@ -22,7 +22,7 @@
* XXX too many hardcoded numbers... need to expand glxreg.h
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: glx.c,v 1.4 2012/03/11 00:02:04 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: glx.c,v 1.5 2015/10/02 05:22:50 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -215,6 +215,9 @@ glx_pci_read_hook(void *v, pcitag_t tag, int offset)
int bus, dev, fn;
pcireg_t data;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
/*
* Do not get in the way of MSR programming
*/
@@ -260,6 +263,9 @@ glx_pci_write_hook(void *v, pcitag_t tag,
{
int bus, dev, fn;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return;
+
/*
* Do not get in the way of MSR programming
*/
diff --git a/sys/arch/evbmips/malta/dev/gt.c b/sys/arch/evbmips/malta/dev/gt.c
index dc9163a66f1..61888e72d44 100644
--- a/sys/arch/evbmips/malta/dev/gt.c
+++ b/sys/arch/evbmips/malta/dev/gt.c
@@ -1,4 +1,4 @@
-/* $NetBSD: gt.c,v 1.14 2015/06/07 07:19:21 matt Exp $ */
+/* $NetBSD: gt.c,v 1.15 2015/10/02 05:22:50 msaitoh Exp $ */
/*
* Copyright 2002 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gt.c,v 1.14 2015/06/07 07:19:21 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gt.c,v 1.15 2015/10/02 05:22:50 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -164,6 +164,9 @@ gt_conf_read(void *v, pcitag_t tag, int offset)
pcireg_t data;
int bus, dev, func, s;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return ((pcireg_t) -1);
+
gt_decompose_tag(NULL /* XXX */, tag, &bus, &dev, &func);
/* The galileo has problems accessing device 31. */
@@ -196,6 +199,9 @@ gt_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data)
{
int bus, dev, func, s;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return;
+
gt_decompose_tag(NULL /* XXX */, tag, &bus, &dev, &func);
/* The galileo has problems accessing device 31. */
diff --git a/sys/arch/hpcmips/dev/plum.c b/sys/arch/hpcmips/dev/plum.c
index 72eeef4cb41..3248598e24c 100644
--- a/sys/arch/hpcmips/dev/plum.c
+++ b/sys/arch/hpcmips/dev/plum.c
@@ -1,4 +1,4 @@
-/* $NetBSD: plum.c,v 1.14 2012/10/27 17:17:52 chs Exp $ */
+/* $NetBSD: plum.c,v 1.15 2015/10/02 05:22:50 msaitoh Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: plum.c,v 1.14 2012/10/27 17:17:52 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: plum.c,v 1.15 2015/10/02 05:22:50 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -172,6 +172,9 @@ plum_conf_read(bus_space_tag_t t, bus_space_handle_t h, int o)
{
plumreg_t reg;
+ if ((unsigned int)o >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
reg = bus_space_read_4(t, h, o);
return (reg);
@@ -181,6 +184,9 @@ void
plum_conf_write(bus_space_tag_t t, bus_space_handle_t h, int o, plumreg_t v)
{
+ if ((unsigned int)o >= PCI_CONF_SIZE)
+ return;
+
bus_space_write_4(t, h, o, v);
}
diff --git a/sys/arch/hpcmips/vr/vrc4172pci.c b/sys/arch/hpcmips/vr/vrc4172pci.c
index 566f1c2aec9..b0d60c03ec3 100644
--- a/sys/arch/hpcmips/vr/vrc4172pci.c
+++ b/sys/arch/hpcmips/vr/vrc4172pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vrc4172pci.c,v 1.17 2014/03/29 19:28:28 christos Exp $ */
+/* $NetBSD: vrc4172pci.c,v 1.18 2015/10/02 05:22:51 msaitoh Exp $ */
/*-
* Copyright (c) 2002 TAKEMURA Shin
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vrc4172pci.c,v 1.17 2014/03/29 19:28:28 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vrc4172pci.c,v 1.18 2015/10/02 05:22:51 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -261,6 +261,9 @@ vrc4172pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
struct vrc4172pci_softc *sc = device_private(pc->pc_dev);
u_int32_t val;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return ((pcireg_t) -1);
+
#ifdef VRC4172PCI_MCR700_SUPPORT
if (sc->sc_fake_baseaddr != 0 &&
tag == vrc4172pci_make_tag(pc, 0, 0, 1) &&
@@ -293,6 +296,9 @@ vrc4172pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg,
DPRINTF(("%s: conf_write: tag = 0x%08x, reg = 0x%x, val = 0x%08x\n",
device_xname(sc->sc_dev), (u_int32_t)tag, reg, (u_int32_t)data));
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
#ifdef VRC4172PCI_MCR700_SUPPORT
if (sc->sc_fake_baseaddr != 0 &&
tag == vrc4172pci_make_tag(pc, 0, 0, 1) &&
diff --git a/sys/arch/hpcmips/vr/vrpciu.c b/sys/arch/hpcmips/vr/vrpciu.c
index 6753e37c781..09533ba8502 100644
--- a/sys/arch/hpcmips/vr/vrpciu.c
+++ b/sys/arch/hpcmips/vr/vrpciu.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vrpciu.c,v 1.21 2014/03/31 20:46:41 christos Exp $ */
+/* $NetBSD: vrpciu.c,v 1.22 2015/10/02 05:22:51 msaitoh Exp $ */
/*-
* Copyright (c) 2001 Enami Tsugutomo.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vrpciu.c,v 1.21 2014/03/31 20:46:41 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vrpciu.c,v 1.22 2015/10/02 05:22:51 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -424,6 +424,9 @@ vrpciu_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
u_int32_t val;
int bus, device, function;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return ((pcireg_t) -1);
+
pci_decompose_tag(pc, tag, &bus, &device, &function);
if (bus == 0) {
if (device > 21)
@@ -452,6 +455,10 @@ vrpciu_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg,
printf("%s: conf_write: tag = 0x%08x, reg = 0x%x, val = 0x%08x\n",
device_xname(sc->sc_dev), (u_int32_t)tag, reg, (u_int32_t)data);
#endif
+
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
vrpciu_decompose_tag(pc, tag, &bus, &device, &function);
if (bus == 0) {
if (device > 21)
diff --git a/sys/arch/hppa/dev/dino.c b/sys/arch/hppa/dev/dino.c
index df656221590..aa18252658d 100644
--- a/sys/arch/hppa/dev/dino.c
+++ b/sys/arch/hppa/dev/dino.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dino.c,v 1.2 2014/03/31 20:51:20 christos Exp $ */
+/* $NetBSD: dino.c,v 1.3 2015/10/02 05:22:51 msaitoh Exp $ */
/* $OpenBSD: dino.c,v 1.5 2004/02/13 20:39:31 mickey Exp $ */
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dino.c,v 1.2 2014/03/31 20:51:20 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dino.c,v 1.3 2015/10/02 05:22:51 msaitoh Exp $");
/* #include "cardbus.h" */
@@ -338,6 +338,9 @@ dino_conf_read(void *v, pcitag_t tag, int reg)
pcireg_t data;
uint32_t pamr;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
/* fix arbitration errata by disabling all pci devs on config read */
pamr = r->pamr;
r->pamr = 0;
@@ -358,6 +361,9 @@ dino_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
volatile struct dino_regs *r = sc->sc_regs;
uint32_t pamr;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
/* fix arbitration errata by disabling all pci devs on config read */
pamr = r->pamr;
r->pamr = 0;
diff --git a/sys/arch/hppa/dev/elroy.c b/sys/arch/hppa/dev/elroy.c
index 1dc6f366341..da7b3be065b 100644
--- a/sys/arch/hppa/dev/elroy.c
+++ b/sys/arch/hppa/dev/elroy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: elroy.c,v 1.1 2014/02/24 07:23:42 skrll Exp $ */
+/* $NetBSD: elroy.c,v 1.2 2015/10/02 05:22:51 msaitoh Exp $ */
/* $OpenBSD: elroy.c,v 1.5 2009/03/30 21:24:57 kettenis Exp $ */
@@ -257,6 +257,10 @@ elroy_conf_read(void *v, pcitag_t tag, int reg)
pcireg_t data;
/* printf("elroy_conf_read(%p, 0x%08x, 0x%x)", v, tag, reg); */
+
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return ((pcireg_t) -1);
+
arb_mask = elroy_read32(&r->arb_mask);
err_cfg = elroy_read32(&r->err_cfg);
control = elroy_read32(&r->control);
@@ -291,6 +295,10 @@ elroy_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
uint32_t arb_mask, err_cfg, control;
/* printf("elroy_conf_write(%p, 0x%08x, 0x%x, 0x%x)\n", v, tag, reg, data); */
+
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
arb_mask = elroy_read32(&r->arb_mask);
err_cfg = elroy_read32(&r->err_cfg);
control = elroy_read32(&r->control);
diff --git a/sys/arch/ia64/pci/pci_machdep.c b/sys/arch/ia64/pci/pci_machdep.c
index d7e921e3eaa..c75d4ff4214 100644
--- a/sys/arch/ia64/pci/pci_machdep.c
+++ b/sys/arch/ia64/pci/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_machdep.c,v 1.3 2013/01/12 08:40:51 kiyohara Exp $ */
+/* $NetBSD: pci_machdep.c,v 1.4 2015/10/02 05:22:51 msaitoh Exp $ */
/*
* Copyright (c) 2009, 2010 KIYOHARA Takashi
* All rights reserved.
@@ -25,7 +25,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.3 2013/01/12 08:40:51 kiyohara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.4 2015/10/02 05:22:51 msaitoh Exp $");
#include <machine/bus.h>
#include <machine/sal.h>
@@ -78,6 +78,9 @@ pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
{
struct ia64_sal_result res;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return -1;
+
res = ia64_sal_entry(SAL_PCI_CONFIG_READ,
tag | reg, sizeof(pcireg_t), 0, 0, 0, 0, 0);
if (res.sal_status < 0)
@@ -91,6 +94,9 @@ pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t val)
{
struct ia64_sal_result res;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
res = ia64_sal_entry(SAL_PCI_CONFIG_WRITE,
tag | reg, sizeof(pcireg_t), val, 0, 0, 0, 0);
if (res.sal_status < 0)
diff --git a/sys/arch/macppc/pci/bandit.c b/sys/arch/macppc/pci/bandit.c
index 561d8e62f65..5a81d6cf53c 100644
--- a/sys/arch/macppc/pci/bandit.c
+++ b/sys/arch/macppc/pci/bandit.c
@@ -1,4 +1,4 @@
-/* $NetBSD: bandit.c,v 1.30 2011/10/26 04:56:23 macallan Exp $ */
+/* $NetBSD: bandit.c,v 1.31 2015/10/02 05:22:51 msaitoh Exp $ */
/*-
* Copyright (c) 2000 Tsubai Masanari. All rights reserved.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bandit.c,v 1.30 2011/10/26 04:56:23 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bandit.c,v 1.31 2015/10/02 05:22:51 msaitoh Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -156,6 +156,9 @@ bandit_conf_read(void *cookie, pcitag_t tag, int reg)
int bus, dev, func, s;
uint32_t x;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
pci_decompose_tag(pc, tag, &bus, &dev, &func);
/*
@@ -195,6 +198,9 @@ bandit_conf_write(void *cookie, pcitag_t tag, int reg, pcireg_t data)
int bus, dev, func, s;
u_int32_t x;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
pci_decompose_tag(pc, tag, &bus, &dev, &func);
if (func > 7)
diff --git a/sys/arch/macppc/pci/grackle.c b/sys/arch/macppc/pci/grackle.c
index bdefc881b1e..61530925273 100644
--- a/sys/arch/macppc/pci/grackle.c
+++ b/sys/arch/macppc/pci/grackle.c
@@ -1,4 +1,4 @@
-/* $NetBSD: grackle.c,v 1.15 2011/10/26 04:56:23 macallan Exp $ */
+/* $NetBSD: grackle.c,v 1.16 2015/10/02 05:22:51 msaitoh Exp $ */
/*-
* Copyright (c) 2000 Tsubai Masanari. All rights reserved.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: grackle.c,v 1.15 2011/10/26 04:56:23 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: grackle.c,v 1.16 2015/10/02 05:22:51 msaitoh Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -155,6 +155,9 @@ grackle_conf_read(void *cookie, pcitag_t tag, int reg)
pcireg_t data;
int s;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
s = splhigh();
out32rb(pc->pc_addr, tag | reg);
@@ -174,6 +177,9 @@ grackle_conf_write(void *cookie, pcitag_t tag, int reg, pcireg_t data)
pci_chipset_tag_t pc = cookie;
int s;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
s = splhigh();
out32rb(pc->pc_addr, tag | reg);
diff --git a/sys/arch/macppc/pci/u3.c b/sys/arch/macppc/pci/u3.c
index af74e93499a..1733080c9aa 100644
--- a/sys/arch/macppc/pci/u3.c
+++ b/sys/arch/macppc/pci/u3.c
@@ -1,4 +1,4 @@
-/* $NetBSD: u3.c,v 1.7 2013/04/30 10:16:25 macallan Exp $ */
+/* $NetBSD: u3.c,v 1.8 2015/10/02 05:22:51 msaitoh Exp $ */
/*
* Copyright 2006 Kyma Systems LLC.
@@ -171,6 +171,9 @@ ibmcpc_conf_read(void *cookie, pcitag_t tag, int reg)
pcireg_t data;
u_int32_t bus, dev, func, x, devfn;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
pci_decompose_tag(pc, tag, &bus, &dev, &func);
devfn = PCI_DEVFN(dev, func);
@@ -201,6 +204,9 @@ ibmcpc_conf_write(void *cookie, pcitag_t tag, int reg, pcireg_t data)
u_int32_t bus, dev, func;
u_int32_t x, devfn;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
pci_decompose_tag(pc, tag, &bus, &dev, &func);
devfn = PCI_DEVFN(dev, func);
diff --git a/sys/arch/macppc/pci/uninorth.c b/sys/arch/macppc/pci/uninorth.c
index 2736e5eb91a..276fa76ae07 100644
--- a/sys/arch/macppc/pci/uninorth.c
+++ b/sys/arch/macppc/pci/uninorth.c
@@ -1,4 +1,4 @@
-/* $NetBSD: uninorth.c,v 1.17 2013/05/01 14:24:48 macallan Exp $ */
+/* $NetBSD: uninorth.c,v 1.18 2015/10/02 05:22:51 msaitoh Exp $ */
/*-
* Copyright (c) 2000 Tsubai Masanari. All rights reserved.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uninorth.c,v 1.17 2013/05/01 14:24:48 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uninorth.c,v 1.18 2015/10/02 05:22:51 msaitoh Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -194,6 +194,9 @@ uninorth_conf_read(void *cookie, pcitag_t tag, int reg)
int bus, dev, func, s;
uint32_t x;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
/* UniNorth seems to have a 64bit data port */
if (reg & 0x04)
daddr++;
@@ -236,6 +239,9 @@ uninorth_conf_write(void *cookie, pcitag_t tag, int reg, pcireg_t data)
int bus, dev, func, s;
uint32_t x;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
/* UniNorth seems to have a 64bit data port */
if (reg & 0x04)
daddr++;
@@ -272,6 +278,9 @@ uninorth_conf_read_v3(void *cookie, pcitag_t tag, int reg)
int bus, dev, func, s;
uint32_t x;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
/* UniNorth seems to have a 64bit data port */
if (reg & 0x04)
daddr++;
@@ -304,6 +313,9 @@ uninorth_conf_write_v3(void *cookie, pcitag_t tag, int reg, pcireg_t data)
int bus, dev, func, s;
uint32_t x;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
/* UniNorth seems to have a 64bit data port */
if (reg & 0x04)
daddr++;
diff --git a/sys/arch/mips/adm5120/dev/admpci.c b/sys/arch/mips/adm5120/dev/admpci.c
index e1284947373..672fb5801c4 100644
--- a/sys/arch/mips/adm5120/dev/admpci.c
+++ b/sys/arch/mips/adm5120/dev/admpci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: admpci.c,v 1.12 2015/06/26 22:20:58 matt Exp $ */
+/* $NetBSD: admpci.c,v 1.13 2015/10/02 05:22:51 msaitoh Exp $ */
/*-
* Copyright (c) 2007 David Young. All rights reserved.
@@ -61,7 +61,7 @@
#include "pci.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: admpci.c,v 1.12 2015/06/26 22:20:58 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: admpci.c,v 1.13 2015/10/02 05:22:51 msaitoh Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -324,6 +324,10 @@ admpci_tag_to_addr(void *v, pcitag_t tag, int reg, bus_addr_t *addrp)
int bus, device, function;
KASSERT(addrp != NULL);
+
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return -1;
+
/* panics if tag is not well-formed */
admpci_decompose_tag(v, tag, &bus, &device, &function);
if (reg > __SHIFTOUT_MASK(ADMPCI_TAG_REGISTER_MASK))
diff --git a/sys/arch/mips/alchemy/dev/aupci.c b/sys/arch/mips/alchemy/dev/aupci.c
index f5424e7e5de..c11c7aa3b5d 100644
--- a/sys/arch/mips/alchemy/dev/aupci.c
+++ b/sys/arch/mips/alchemy/dev/aupci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: aupci.c,v 1.16 2015/06/27 03:33:18 matt Exp $ */
+/* $NetBSD: aupci.c,v 1.17 2015/10/02 05:22:51 msaitoh Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@@ -35,7 +35,7 @@
#include "pci.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: aupci.c,v 1.16 2015/06/27 03:33:18 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: aupci.c,v 1.17 2015/10/02 05:22:51 msaitoh Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -334,6 +334,9 @@ aupci_conf_access(void *v, int dir, pcitag_t tag, int reg, pcireg_t *datap)
int b, d, f;
bus_space_handle_t h;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return false;
+
aupci_decompose_tag(v, tag, &b, &d, &f);
if (b) {
/* configuration type 1 */
diff --git a/sys/arch/mips/atheros/dev/arpci.c b/sys/arch/mips/atheros/dev/arpci.c
index 813384fe8f6..e3e0a6fdf35 100644
--- a/sys/arch/mips/atheros/dev/arpci.c
+++ b/sys/arch/mips/atheros/dev/arpci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: arpci.c,v 1.4 2015/06/26 22:20:58 matt Exp $ */
+/* $NetBSD: arpci.c,v 1.5 2015/10/02 05:22:51 msaitoh Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -30,7 +30,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: arpci.c,v 1.4 2015/06/26 22:20:58 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arpci.c,v 1.5 2015/10/02 05:22:51 msaitoh Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -133,6 +133,9 @@ arpci_conf_read(void *v, pcitag_t tag, int reg)
struct arpci_softc * const sc = v;
pcireg_t rv = 0xffffffff;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return rv;
+
if ((tag & 0x00ff0001) == 1) {
KASSERT(((tag >> 11) & 31) > 20);
/*
@@ -176,6 +179,9 @@ arpci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
{
struct arpci_softc * const sc = v;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
if ((tag & 0x00ff0001) == 1) {
KASSERT(((tag >> 11) & 31) > 20);
/*
diff --git a/sys/arch/mips/bonito/bonito_pci.c b/sys/arch/mips/bonito/bonito_pci.c
index 02671404654..3e77cc63419 100644
--- a/sys/arch/mips/bonito/bonito_pci.c
+++ b/sys/arch/mips/bonito/bonito_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: bonito_pci.c,v 1.11 2014/03/11 08:19:45 mrg Exp $ */
+/* $NetBSD: bonito_pci.c,v 1.12 2015/10/02 05:22:51 msaitoh Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bonito_pci.c,v 1.11 2014/03/11 08:19:45 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bonito_pci.c,v 1.12 2015/10/02 05:22:51 msaitoh Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -119,6 +119,9 @@ bonito_conf_addr(struct bonito_config *bc, pcitag_t tag, int offset,
{
int b, d, f;
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return true;
+
bonito_decompose_tag(bc, tag, &b, &d, &f);
if (b == 0) {
diff --git a/sys/arch/mips/rmi/rmixl_pcie.c b/sys/arch/mips/rmi/rmixl_pcie.c
index 31437af5f8f..1e9017afcd5 100644
--- a/sys/arch/mips/rmi/rmixl_pcie.c
+++ b/sys/arch/mips/rmi/rmixl_pcie.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rmixl_pcie.c,v 1.11 2014/04/04 01:41:05 christos Exp $ */
+/* $NetBSD: rmixl_pcie.c,v 1.12 2015/10/02 05:22:51 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rmixl_pcie.c,v 1.11 2014/04/04 01:41:05 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rmixl_pcie.c,v 1.12 2015/10/02 05:22:51 msaitoh Exp $");
#include "opt_pci.h"
#include "pci.h"
@@ -953,7 +953,9 @@ rmixl_pcie_conf_setup(struct rmixl_pcie_softc *sc,
ecfg_oba = ba;
}
bsh = ecfg_bsh;
- } else {
+ } else if ((*offp > 0x700) && (*offp <= PCI_EXTCONF_SIZE)) {
+ return -1;
+ } else {
#ifdef DEBUG
panic("%s: offset %#x: unknown", __func__, *offp);
#endif
diff --git a/sys/arch/mips/rmi/rmixl_pcix.c b/sys/arch/mips/rmi/rmixl_pcix.c
index 69dfd874b86..e735d717305 100644
--- a/sys/arch/mips/rmi/rmixl_pcix.c
+++ b/sys/arch/mips/rmi/rmixl_pcix.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rmixl_pcix.c,v 1.12 2014/04/04 16:41:55 ozaki-r Exp $ */
+/* $NetBSD: rmixl_pcix.c,v 1.13 2015/10/02 05:22:51 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rmixl_pcix.c,v 1.12 2014/04/04 16:41:55 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rmixl_pcix.c,v 1.13 2015/10/02 05:22:51 msaitoh Exp $");
#include "opt_pci.h"
#include "pci.h"
@@ -693,9 +693,6 @@ rmixl_pcix_conf_setup(rmixl_pcix_softc_t *sc,
}
bsh = cfg_bsh;
} else {
-#ifdef DEBUG
- panic("%s: offset %#x: unknown", __func__, *offp);
-#endif
return -1;
}
diff --git a/sys/arch/mips/sibyte/pci/sbbrz_pci.c b/sys/arch/mips/sibyte/pci/sbbrz_pci.c
index 9ebf885035f..94401a34d3d 100644
--- a/sys/arch/mips/sibyte/pci/sbbrz_pci.c
+++ b/sys/arch/mips/sibyte/pci/sbbrz_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sbbrz_pci.c,v 1.5 2014/03/29 19:28:29 christos Exp $ */
+/* $NetBSD: sbbrz_pci.c,v 1.6 2015/10/02 05:22:51 msaitoh Exp $ */
/*
* Copyright 2000, 2001
@@ -64,7 +64,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: sbbrz_pci.c,v 1.5 2014/03/29 19:28:29 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sbbrz_pci.c,v 1.6 2015/10/02 05:22:51 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -181,6 +181,9 @@ sbbrz_pci_conf_read(void *cpv, pcitag_t tag, int offset)
panic ("pci_conf_read: misaligned");
#endif
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return 0xffffffff;
+
addr = A_PHYS_LDTPCI_CFG_MATCH_BITS + tag + offset;
addr = MIPS_PHYS_TO_XKPHYS(MIPS3_TLB_ATTR_UNCACHED, addr);
@@ -202,6 +205,9 @@ sbbrz_pci_conf_write(void *cpv, pcitag_t tag, int offset, pcireg_t data)
panic ("pci_conf_write: misaligned");
#endif
+ if ((unsigned int)offset >= PCI_CONF_SIZE)
+ return;
+
addr = A_PHYS_LDTPCI_CFG_MATCH_BITS + tag + offset;
addr = MIPS_PHYS_TO_XKPHYS(MIPS3_TLB_ATTR_UNCACHED, addr);
diff --git a/sys/arch/powerpc/booke/pci/pq3pci.c b/sys/arch/powerpc/booke/pci/pq3pci.c
index eb2cdf0849f..23ca163ee68 100644
--- a/sys/arch/powerpc/booke/pci/pq3pci.c
+++ b/sys/arch/powerpc/booke/pci/pq3pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pq3pci.c,v 1.20 2014/12/27 16:19:33 nonaka Exp $ */
+/* $NetBSD: pq3pci.c,v 1.21 2015/10/02 05:22:51 msaitoh Exp $ */
/*-
* Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -44,7 +44,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pq3pci.c,v 1.20 2014/12/27 16:19:33 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pq3pci.c,v 1.21 2015/10/02 05:22:51 msaitoh Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -1058,8 +1058,10 @@ pq3pci_conf_read(void *v, pcitag_t tag, int reg)
struct pq3pci_softc * const sc = v;
struct genppc_pci_chipset * const pc = &sc->sc_pc;
- if (reg >= 256) {
- if (!sc->sc_pcie)
+ if (reg < 0)
+ return 0xffffffff;
+ if (reg >= PCI_CONF_SIZE) {
+ if (!sc->sc_pcie || reg >= PCI_EXTCONF_SIZE)
return 0xffffffff;
reg = (reg & 0xff) | ((reg & 0xf00) << 16);
}
@@ -1096,8 +1098,10 @@ pq3pci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
struct pq3pci_softc * const sc = v;
struct genppc_pci_chipset * const pc = &sc->sc_pc;
- if (reg >= 256) {
- if (!sc->sc_pcie)
+ if (reg < 0)
+ return;
+ if (reg >= PCI_CONF_SIZE) {
+ if (!sc->sc_pcie || reg >= PCI_EXTCONF_SIZE)
return;
reg = (reg & 0xff) | ((reg & 0xf00) << 16);
}
diff --git a/sys/arch/powerpc/ibm4xx/pci/pci_machdep.c b/sys/arch/powerpc/ibm4xx/pci/pci_machdep.c
index d17bae7dea1..e59f392185d 100644
--- a/sys/arch/powerpc/ibm4xx/pci/pci_machdep.c
+++ b/sys/arch/powerpc/ibm4xx/pci/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_machdep.c,v 1.10 2011/06/22 18:06:34 matt Exp $ */
+/* $NetBSD: pci_machdep.c,v 1.11 2015/10/02 05:22:51 msaitoh Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.10 2011/06/22 18:06:34 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.11 2015/10/02 05:22:51 msaitoh Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -131,6 +131,9 @@ ibm4xx_pci_conf_read(void *v, pcitag_t tag, int reg)
{
pcireg_t data;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
/* 405GT BIOS disables interrupts here. Should we? --Art */
bus_space_write_4(&pci_iot, pci_ioh, PCIC_CFGADDR, tag | reg);
data = bus_space_read_4(&pci_iot, pci_ioh, PCIC_CFGDATA);
@@ -143,6 +146,9 @@ void
ibm4xx_pci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
{
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
bus_space_write_4(&pci_iot, pci_ioh, PCIC_CFGADDR, tag | reg);
bus_space_write_4(&pci_iot, pci_ioh, PCIC_CFGDATA, data);
/* 405GP pass2 errata #6 */
diff --git a/sys/arch/powerpc/pci/pciconf_indirect.c b/sys/arch/powerpc/pci/pciconf_indirect.c
index ee1d547384a..d9d218ecd8a 100644
--- a/sys/arch/powerpc/pci/pciconf_indirect.c
+++ b/sys/arch/powerpc/pci/pciconf_indirect.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pciconf_indirect.c,v 1.5 2011/06/18 06:41:43 matt Exp $ */
+/* $NetBSD: pciconf_indirect.c,v 1.6 2015/10/02 05:22:52 msaitoh Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pciconf_indirect.c,v 1.5 2011/06/18 06:41:43 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pciconf_indirect.c,v 1.6 2015/10/02 05:22:52 msaitoh Exp $");
#define _POWERPC_BUS_DMA_PRIVATE
@@ -107,6 +107,9 @@ genppc_pci_indirect_conf_read(void *v, pcitag_t tag, int reg)
pcireg_t data;
int s;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
s = splhigh();
out32rb(pc->pc_addr, tag | reg);
data = in32rb(pc->pc_data);
@@ -122,6 +125,9 @@ genppc_pci_indirect_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
pci_chipset_tag_t pc = (pci_chipset_tag_t)v;
int s;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
s = splhigh();
out32rb(pc->pc_addr, tag | reg);
out32rb(pc->pc_data, data);
diff --git a/sys/arch/powerpc/pci/pciconf_ofmethod.c b/sys/arch/powerpc/pci/pciconf_ofmethod.c
index e0b95122e1e..43317dbae8f 100644
--- a/sys/arch/powerpc/pci/pciconf_ofmethod.c
+++ b/sys/arch/powerpc/pci/pciconf_ofmethod.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pciconf_ofmethod.c,v 1.4 2011/06/18 06:41:43 matt Exp $ */
+/* $NetBSD: pciconf_ofmethod.c,v 1.5 2015/10/02 05:22:52 msaitoh Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pciconf_ofmethod.c,v 1.4 2011/06/18 06:41:43 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pciconf_ofmethod.c,v 1.5 2015/10/02 05:22:52 msaitoh Exp $");
#define _POWERPC_BUS_DMA_PRIVATE
@@ -103,6 +103,9 @@ genppc_pci_ofmethod_conf_read(void *v, pcitag_t tag, int reg)
pci_chipset_tag_t pc = (pci_chipset_tag_t)v;
pcireg_t data;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
tag &= OFW_PCI_PHYS_HI_BUSMASK | OFW_PCI_PHYS_HI_DEVICEMASK |
OFW_PCI_PHYS_HI_FUNCTIONMASK;
tag |= reg & OFW_PCI_PHYS_HI_REGISTERMASK;
@@ -117,6 +120,9 @@ genppc_pci_ofmethod_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
{
pci_chipset_tag_t pc = (pci_chipset_tag_t)v;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
tag &= OFW_PCI_PHYS_HI_BUSMASK | OFW_PCI_PHYS_HI_DEVICEMASK |
OFW_PCI_PHYS_HI_FUNCTIONMASK;
tag |= reg & OFW_PCI_PHYS_HI_REGISTERMASK;
diff --git a/sys/arch/prep/pci/prep_pciconf_direct.c b/sys/arch/prep/pci/prep_pciconf_direct.c
index b90441f93ed..b9a593571ec 100644
--- a/sys/arch/prep/pci/prep_pciconf_direct.c
+++ b/sys/arch/prep/pci/prep_pciconf_direct.c
@@ -1,4 +1,4 @@
-/* $NetBSD: prep_pciconf_direct.c,v 1.8 2011/07/01 16:56:52 dyoung Exp $ */
+/* $NetBSD: prep_pciconf_direct.c,v 1.9 2015/10/02 05:22:52 msaitoh Exp $ */
/*
* Copyright (c) 2002 Klaus J. Klein. All rights reserved.
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: prep_pciconf_direct.c,v 1.8 2011/07/01 16:56:52 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: prep_pciconf_direct.c,v 1.9 2015/10/02 05:22:52 msaitoh Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -158,6 +158,9 @@ prep_pci_direct_conf_read(void *v, pcitag_t tag, int reg)
int bus, device, function;
int s;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) ~0;
+
prep_pci_direct_decompose_tag(v, tag, &bus, &device, &function);
if (bus == 0) {
@@ -186,6 +189,9 @@ prep_pci_direct_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
DPRINTF(("prep_pci_direct_conf_write(0x%lx, 0x%x, 0x%02x, 0x%08lx) ",
(unsigned long)v, tag, reg, (unsigned long)data));
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
prep_pci_direct_decompose_tag(v, tag, &bus, &device, &function);
if (bus == 0) {
diff --git a/sys/arch/sandpoint/pci/pci_machdep.c b/sys/arch/sandpoint/pci/pci_machdep.c
index 7e33b2d369b..479d666b9ae 100644
--- a/sys/arch/sandpoint/pci/pci_machdep.c
+++ b/sys/arch/sandpoint/pci/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_machdep.c,v 1.33 2014/03/29 19:28:30 christos Exp $ */
+/* $NetBSD: pci_machdep.c,v 1.34 2015/10/02 05:22:52 msaitoh Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.33 2014/03/29 19:28:30 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.34 2015/10/02 05:22:52 msaitoh Exp $");
#include "opt_pci.h"
@@ -213,6 +213,9 @@ pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
{
pcireg_t data;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
out32rb(SANDPOINT_PCI_CONFIG_ADDR, tag | reg);
data = in32rb(SANDPOINT_PCI_CONFIG_DATA);
out32rb(SANDPOINT_PCI_CONFIG_ADDR, 0);
@@ -223,6 +226,9 @@ void
pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
{
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
out32rb(SANDPOINT_PCI_CONFIG_ADDR, tag | reg);
out32rb(SANDPOINT_PCI_CONFIG_DATA, data);
out32rb(SANDPOINT_PCI_CONFIG_ADDR, 0);
diff --git a/sys/arch/sgimips/gio/pci_gio.c b/sys/arch/sgimips/gio/pci_gio.c
index bda69398116..2b018132295 100644
--- a/sys/arch/sgimips/gio/pci_gio.c
+++ b/sys/arch/sgimips/gio/pci_gio.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_gio.c,v 1.14 2015/02/18 16:47:58 macallan Exp $ */
+/* $NetBSD: pci_gio.c,v 1.15 2015/10/02 05:22:52 msaitoh Exp $ */
/*
* Copyright (c) 2006 Stephen M. Rumble
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_gio.c,v 1.14 2015/02/18 16:47:58 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_gio.c,v 1.15 2015/10/02 05:22:52 msaitoh Exp $");
/*
* Glue for PCI devices that are connected to the GIO bus by various little
@@ -250,6 +250,9 @@ giopci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
int bus, dev, func;
pcireg_t data;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
pci_decompose_tag(pc, tag, &bus, &dev, &func);
if (bus != 0 || dev != 0 || func != 0)
return (0);
@@ -273,6 +276,9 @@ giopci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
struct giopci_softc *sc = pc->cookie;
int bus, dev, func;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
pci_decompose_tag(pc, tag, &bus, &dev, &func);
if (bus != 0 || dev != 0 || func != 0)
return;
diff --git a/sys/arch/sgimips/mace/pci_mace.c b/sys/arch/sgimips/mace/pci_mace.c
index 5ffd466b5ad..c9b7059f162 100644
--- a/sys/arch/sgimips/mace/pci_mace.c
+++ b/sys/arch/sgimips/mace/pci_mace.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_mace.c,v 1.19 2015/09/24 17:56:59 macallan Exp $ */
+/* $NetBSD: pci_mace.c,v 1.20 2015/10/02 05:22:52 msaitoh Exp $ */
/*
* Copyright (c) 2001,2003 Christopher Sekiya
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_mace.c,v 1.19 2015/09/24 17:56:59 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_mace.c,v 1.20 2015/10/02 05:22:52 msaitoh Exp $");
#include "opt_pci.h"
#include "pci.h"
@@ -212,6 +212,9 @@ macepci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
{
pcireg_t data;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
bus_space_write_4(pc->iot, pc->ioh, MACE_PCI_CONFIG_ADDR, (tag | reg));
data = bus_space_read_4(pc->iot, pc->ioh, MACE_PCI_CONFIG_DATA);
bus_space_write_4(pc->iot, pc->ioh, MACE_PCI_CONFIG_ADDR, 0);
@@ -223,6 +226,9 @@ void
macepci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
{
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
bus_space_write_4(pc->iot, pc->ioh, MACE_PCI_CONFIG_ADDR, (tag | reg));
bus_space_write_4(pc->iot, pc->ioh, MACE_PCI_CONFIG_DATA, data);
bus_space_write_4(pc->iot, pc->ioh, MACE_PCI_CONFIG_ADDR, 0);
diff --git a/sys/arch/sh3/dev/shpcic.c b/sys/arch/sh3/dev/shpcic.c
index 04832b06fde..c7a34a75b35 100644
--- a/sys/arch/sh3/dev/shpcic.c
+++ b/sys/arch/sh3/dev/shpcic.c
@@ -1,4 +1,4 @@
-/* $NetBSD: shpcic.c,v 1.17 2012/01/27 18:53:01 para Exp $ */
+/* $NetBSD: shpcic.c,v 1.18 2015/10/02 05:22:52 msaitoh Exp $ */
/*-
* Copyright (C) 2005 NONAKA Kimihiro <nonaka@netbsd.org>
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: shpcic.c,v 1.17 2012/01/27 18:53:01 para Exp $");
+__KERNEL_RCSID(0, "$NetBSD: shpcic.c,v 1.18 2015/10/02 05:22:52 msaitoh Exp $");
#include "opt_pci.h"
@@ -295,6 +295,9 @@ shpcic_conf_read(void *v, pcitag_t tag, int reg)
pcireg_t data;
int s;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return (pcireg_t) -1;
+
s = splhigh();
_reg_write_4(SH4_PCIPAR, tag | reg);
data = _reg_read_4(SH4_PCIPDR);
@@ -309,6 +312,9 @@ shpcic_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
{
int s;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
s = splhigh();
_reg_write_4(SH4_PCIPAR, tag | reg);
_reg_write_4(SH4_PCIPDR, data);
diff --git a/sys/arch/sparc/sparc/pci_machdep.c b/sys/arch/sparc/sparc/pci_machdep.c
index fd1b344f9f7..2856743bd19 100644
--- a/sys/arch/sparc/sparc/pci_machdep.c
+++ b/sys/arch/sparc/sparc/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_machdep.c,v 1.20 2014/03/29 19:28:30 christos Exp $ */
+/* $NetBSD: pci_machdep.c,v 1.21 2015/10/02 05:22:52 msaitoh Exp $ */
/*
* Copyright (c) 1999, 2000 Matthew R. Green
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.20 2014/03/29 19:28:30 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.21 2015/10/02 05:22:52 msaitoh Exp $");
#if defined(DEBUG) && !defined(SPARC_PCI_DEBUG)
#define SPARC_PCI_DEBUG
@@ -347,8 +347,6 @@ pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
#ifdef DIAGNOSTIC
if (reg & 0x3)
panic("pci_conf_read: reg %x unaligned", reg);
- if (reg & ~0xff)
- panic("pci_conf_read: reg %x out of range", reg);
#endif
if (PCITAG_NODE(tag) == -1) {
@@ -356,6 +354,9 @@ pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
return ~0;
}
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return ~0;
+
mode1_addr = PCITAG_OFFSET(tag) | reg;
mode1_data_reg_pa = PCI_MODE1_DATA_REG_PA
| (reg & PCI_MODE1_DATA_REG_MASK);
@@ -384,8 +385,6 @@ pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
#ifdef DIAGNOSTIC
if (reg & 0x3)
panic("pci_conf_write: reg %x unaligned", reg);
- if (reg & ~0xff)
- panic("pci_conf_write: reg %x out of range", reg);
#endif
if (PCITAG_NODE(tag) == -1) {
@@ -393,6 +392,9 @@ pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
return;
}
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
mode1_addr = PCITAG_OFFSET(tag) | reg;
mode1_data_reg_pa = PCI_MODE1_DATA_REG_PA
| (reg & PCI_MODE1_DATA_REG_MASK);
diff --git a/sys/arch/sparc64/dev/psycho.c b/sys/arch/sparc64/dev/psycho.c
index 0a2f00ebe4b..d1e4186ab2a 100644
--- a/sys/arch/sparc64/dev/psycho.c
+++ b/sys/arch/sparc64/dev/psycho.c
@@ -1,4 +1,4 @@
-/* $NetBSD: psycho.c,v 1.120 2014/10/18 08:33:27 snj Exp $ */
+/* $NetBSD: psycho.c,v 1.121 2015/10/02 05:22:52 msaitoh Exp $ */
/*
* Copyright (c) 1999, 2000 Matthew R. Green
@@ -55,7 +55,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: psycho.c,v 1.120 2014/10/18 08:33:27 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: psycho.c,v 1.121 2015/10/02 05:22:52 msaitoh Exp $");
#include "opt_ddb.h"
@@ -1405,7 +1405,7 @@ psycho_pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
DPRINTF(PDB_CONF, ("%s: tag %lx reg %x ", __func__,
(long)tag, reg));
- if (PCITAG_NODE(tag) != -1) {
+ if (PCITAG_NODE(tag) != -1 && (unsigned int)reg < PCI_CONF_SIZE) {
DPRINTF(PDB_CONF, ("asi=%x addr=%qx (offset=%x) ...",
sc->sc_configaddr._asi,
@@ -1451,7 +1451,10 @@ psycho_pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data
DPRINTF(PDB_CONF, ("%s: bad addr", __func__));
return;
}
-
+
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
bus_space_write_4(sc->sc_configtag, sc->sc_configaddr,
PCITAG_OFFSET(tag) + reg, data);
}
diff --git a/sys/arch/sparc64/dev/pyro.c b/sys/arch/sparc64/dev/pyro.c
index c5d190fe196..730f633cd27 100644
--- a/sys/arch/sparc64/dev/pyro.c
+++ b/sys/arch/sparc64/dev/pyro.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pyro.c,v 1.15 2013/08/10 00:48:04 mrg Exp $ */
+/* $NetBSD: pyro.c,v 1.16 2015/10/02 05:22:52 msaitoh Exp $ */
/* from: $OpenBSD: pyro.c,v 1.20 2010/12/05 15:15:14 kettenis Exp $ */
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pyro.c,v 1.15 2013/08/10 00:48:04 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pyro.c,v 1.16 2015/10/02 05:22:52 msaitoh Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -295,7 +295,7 @@ pyro_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
int s;
DPRINTF(PDB_CONF, ("%s: tag %lx reg %x ", __func__, (long)tag, reg));
- if (PCITAG_NODE(tag) != -1) {
+ if (PCITAG_NODE(tag) != -1 && (unsigned int)reg < PCI_CONF_SIZE) {
s = splhigh();
ci->ci_pci_probe = true;
membar_Sync();
@@ -325,6 +325,9 @@ pyro_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
return;
}
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
bus_space_write_4(pp->pp_cfgt, pp->pp_cfgh,
(PCITAG_OFFSET(tag) << 4) + reg, data);
DPRINTF(PDB_CONF, (" .. done\n"));
diff --git a/sys/arch/sparc64/dev/schizo.c b/sys/arch/sparc64/dev/schizo.c
index c23df6ee9c4..2629e4b56ec 100644
--- a/sys/arch/sparc64/dev/schizo.c
+++ b/sys/arch/sparc64/dev/schizo.c
@@ -1,4 +1,4 @@
-/* $NetBSD: schizo.c,v 1.32 2014/09/21 16:39:12 christos Exp $ */
+/* $NetBSD: schizo.c,v 1.33 2015/10/02 05:22:52 msaitoh Exp $ */
/* $OpenBSD: schizo.c,v 1.55 2008/08/18 20:29:37 brad Exp $ */
/*
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: schizo.c,v 1.32 2014/09/21 16:39:12 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: schizo.c,v 1.33 2015/10/02 05:22:52 msaitoh Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -497,7 +497,7 @@ schizo_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
int s;
DPRINTF(SDB_CONF, ("%s: tag %lx reg %x ", __func__, (long)tag, reg));
- if (PCITAG_NODE(tag) != -1) {
+ if (PCITAG_NODE(tag) != -1 && (unsigned int)reg < PCI_CONF_SIZE) {
s = splhigh();
ci->ci_pci_probe = true;
membar_Sync();
@@ -527,6 +527,9 @@ schizo_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
return;
}
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
bus_space_write_4(sp->sp_cfgt, sp->sp_cfgh,
PCITAG_OFFSET(tag) + reg, data);
DPRINTF(SDB_CONF, (" .. done\n"));
diff --git a/sys/arch/x86/acpi/acpi_machdep.c b/sys/arch/x86/acpi/acpi_machdep.c
index 1ccca7d18cc..1b2d310000f 100644
--- a/sys/arch/x86/acpi/acpi_machdep.c
+++ b/sys/arch/x86/acpi/acpi_machdep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_machdep.c,v 1.8 2014/05/12 11:51:34 joerg Exp $ */
+/* $NetBSD: acpi_machdep.c,v 1.9 2015/10/02 05:22:52 msaitoh Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.8 2014/05/12 11:51:34 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.9 2015/10/02 05:22:52 msaitoh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -51,9 +51,11 @@ __KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.8 2014/05/12 11:51:34 joerg Exp $
#include <uvm/uvm_extern.h>
#include <machine/cpufunc.h>
+#include <machine/bootinfo.h>
#include <dev/acpi/acpica.h>
#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpi_mcfg.h>
#include <machine/acpi_machdep.h>
#include <machine/mpbiosvar.h>
@@ -338,6 +340,94 @@ acpi_md_ncpus(void)
return kcpuset_countset(kcpuset_attached);
}
+static bool
+acpi_md_mcfg_validate(uint64_t addr, int bus_start, int *bus_end)
+{
+ struct btinfo_memmap *bim;
+ uint64_t size, mapaddr, mapsize;
+ uint32_t type;
+ int i, n;
+
+ bim = lookup_bootinfo(BTINFO_MEMMAP);
+ if (bim == NULL)
+ return false;
+
+ size = (*bus_end - bus_start + 1) * ACPIMCFG_SIZE_PER_BUS;
+ for (i = 0; i < bim->num; i++) {
+ mapaddr = bim->entry[i].addr;
+ mapsize = bim->entry[i].size;
+ type = bim->entry[i].type;
+
+ aprint_debug("MCFG: MEMMAP: 0x%016" PRIx64 "-0x%016" PRIx64
+ ", size=0x%016" PRIx64 ", type=%d(%s)\n",
+ mapaddr, mapaddr + mapsize - 1, mapsize, type,
+ (type == BIM_Memory) ? "Memory" :
+ (type == BIM_Reserved) ? "Reserved" :
+ (type == BIM_ACPI) ? "ACPI" :
+ (type == BIM_NVS) ? "NVS" :
+ "unknown");
+
+ switch (type) {
+ case BIM_ACPI:
+ case BIM_Reserved:
+ if (addr < mapaddr || addr >= mapaddr + mapsize)
+ break;
+
+ /* full map */
+ if (addr + size <= mapaddr + mapsize)
+ return true;
+
+ /* partial map */
+ n = (mapsize - (addr - mapaddr)) /
+ ACPIMCFG_SIZE_PER_BUS;
+ /* bus_start == bus_end is not allowed. */
+ if (n > 1) {
+ *bus_end = bus_start + n - 1;
+ return true;
+ }
+ aprint_debug("MCFG: bus %d-%d, address 0x%016" PRIx64
+ ": invalid size: request 0x%016" PRIx64 ", "
+ "actual 0x%016" PRIx64 "\n",
+ bus_start, *bus_end, addr, size, mapsize);
+ break;
+ }
+ }
+ aprint_debug("MCFG: bus %d-%d, address 0x%016" PRIx64 ": "
+ "no valid region\n", bus_start, *bus_end, addr);
+ return false;
+}
+
+static uint32_t
+acpi_md_mcfg_read(bus_space_tag_t bst, bus_space_handle_t bsh, bus_addr_t addr)
+{
+ vaddr_t va = bsh + addr;
+ uint32_t data = (uint32_t) -1;
+
+ KASSERT(bst == x86_bus_space_mem);
+
+ __asm("movl %1, %0" : "=a" (data) : "m" (*(volatile uint32_t *)va));
+
+ return data;
+}
+
+static void
+acpi_md_mcfg_write(bus_space_tag_t bst, bus_space_handle_t bsh, bus_addr_t addr,
+ uint32_t data)
+{
+ vaddr_t va = bsh + addr;
+
+ KASSERT(bst == x86_bus_space_mem);
+
+ __asm("movl %1, %0" : "=m" (*(volatile uint32_t *)va) : "a" (data));
+}
+
+static const struct acpimcfg_ops acpi_md_mcfg_ops = {
+ .ao_validate = acpi_md_mcfg_validate,
+
+ .ao_read = acpi_md_mcfg_read,
+ .ao_write = acpi_md_mcfg_write,
+};
+
void
acpi_md_callback(struct acpi_softc *sc)
{
@@ -349,4 +439,6 @@ acpi_md_callback(struct acpi_softc *sc)
#ifndef XEN
acpi_md_sleep_init();
#endif
+
+ acpimcfg_init(x86_bus_space_mem, &acpi_md_mcfg_ops);
}
diff --git a/sys/arch/x86/pci/pci_machdep.c b/sys/arch/x86/pci/pci_machdep.c
index 08abef3c2f1..01cf0d4c92c 100644
--- a/sys/arch/x86/pci/pci_machdep.c
+++ b/sys/arch/x86/pci/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_machdep.c,v 1.70 2015/04/27 07:03:58 knakahara Exp $ */
+/* $NetBSD: pci_machdep.c,v 1.71 2015/10/02 05:22:52 msaitoh Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -73,7 +73,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.70 2015/04/27 07:03:58 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.71 2015/10/02 05:22:52 msaitoh Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -137,6 +137,10 @@ __KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.70 2015/04/27 07:03:58 knakahara E
#if NACPICA > 0
#include <machine/mpacpi.h>
+#if !defined(NO_PCI_EXTENDED_CONFIG)
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpi_mcfg.h>
+#endif
#endif
#include <machine/mpconfig.h>
@@ -509,6 +513,10 @@ pci_attach_hook(device_t parent, device_t self, struct pcibus_attach_args *pba)
pba->pba_flags &= ~PCI_FLAGS_MSIX_OKAY;
}
#endif /* __HAVE_PCI_MSI_MSIX */
+
+#if NACPICA > 0 && !defined(NO_PCI_EXTENDED_CONFIG)
+ acpimcfg_map_bus(self, pba->pba_pc, pba->pba_bus);
+#endif
}
int
@@ -604,6 +612,7 @@ pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
pci_chipset_tag_t ipc;
pcireg_t data;
struct pci_conf_lock ocl;
+ int dev;
KASSERT((reg & 0x3) == 0);
@@ -613,6 +622,23 @@ pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
return (*ipc->pc_ov->ov_conf_read)(ipc->pc_ctx, pc, tag, reg);
}
+ pci_decompose_tag(pc, tag, NULL, &dev, NULL);
+ if (__predict_false(pci_mode == 2 && dev >= 16))
+ return (pcireg_t) -1;
+
+ if (reg < 0)
+ return (pcireg_t) -1;
+ if (reg >= PCI_CONF_SIZE) {
+#if NACPICA > 0 && !defined(NO_PCI_EXTENDED_CONFIG)
+ if (reg >= PCI_EXTCONF_SIZE)
+ return (pcireg_t) -1;
+ acpimcfg_conf_read(pc, tag, reg, &data);
+ return data;
+#else
+ return (pcireg_t) -1;
+#endif
+ }
+
pci_conf_lock(&ocl, pci_conf_selector(tag, reg));
data = inl(pci_conf_port(tag, reg));
pci_conf_unlock(&ocl);
@@ -624,6 +650,7 @@ pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
{
pci_chipset_tag_t ipc;
struct pci_conf_lock ocl;
+ int dev;
KASSERT((reg & 0x3) == 0);
@@ -635,6 +662,22 @@ pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
return;
}
+ pci_decompose_tag(pc, tag, NULL, &dev, NULL);
+ if (__predict_false(pci_mode == 2 && dev >= 16)) {
+ return;
+ }
+
+ if (reg < 0)
+ return;
+ if (reg >= PCI_CONF_SIZE) {
+#if NACPICA > 0 && !defined(NO_PCI_EXTENDED_CONFIG)
+ if (reg >= PCI_EXTCONF_SIZE)
+ return;
+ acpimcfg_conf_write(pc, tag, reg, data);
+#endif
+ return;
+ }
+
pci_conf_lock(&ocl, pci_conf_selector(tag, reg));
outl(pci_conf_port(tag, reg), data);
pci_conf_unlock(&ocl);
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c
index 3780df0d982..d55896a8f6a 100644
--- a/sys/dev/acpi/acpi.c
+++ b/sys/dev/acpi/acpi.c
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi.c,v 1.260 2015/08/18 10:41:28 christos Exp $ */
+/* $NetBSD: acpi.c,v 1.261 2015/10/02 05:22:52 msaitoh Exp $ */
/*-
* Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
@@ -100,7 +100,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.260 2015/08/18 10:41:28 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.261 2015/10/02 05:22:52 msaitoh Exp $");
#include "opt_acpi.h"
#include "opt_pcifixup.h"
@@ -118,6 +118,7 @@ __KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.260 2015/08/18 10:41:28 christos Exp $");
#include <dev/acpi/acpireg.h>
#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpi_mcfg.h>
#include <dev/acpi/acpi_osd.h>
#include <dev/acpi/acpi_pci.h>
#include <dev/acpi/acpi_power.h>
@@ -483,6 +484,11 @@ acpi_attach(device_t parent, device_t self, void *aux)
*/
acpi_build_tree(sc);
+ /*
+ * Probe MCFG table
+ */
+ acpimcfg_probe(sc);
+
acpi_md_callback(sc);
/*
diff --git a/sys/dev/acpi/acpi_mcfg.c b/sys/dev/acpi/acpi_mcfg.c
new file mode 100644
index 00000000000..87d8153ee27
--- /dev/null
+++ b/sys/dev/acpi/acpi_mcfg.c
@@ -0,0 +1,697 @@
+/* $NetBSD: acpi_mcfg.c,v 1.1 2015/10/02 05:22:52 msaitoh Exp $ */
+
+/*-
+ * Copyright (C) 2015 NONAKA Kimihiro <nonaka@NetBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: acpi_mcfg.c,v 1.1 2015/10/02 05:22:52 msaitoh Exp $");
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/kmem.h>
+#include <sys/systm.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpi_mcfg.h>
+
+#include "locators.h"
+
+#define EXTCONF_OFFSET(d, f, r) ((((d) * 8 + (f)) * PCI_EXTCONF_SIZE) + (r))
+
+#define EXTCONF_SET_VALID(mb, d, f) ((mb)->valid_devs[(d)] |= __BIT((f)))
+#define EXTCONF_SET_INVALID(mb, d, f) ((mb)->valid_devs[(d)] &= ~__BIT((f)))
+#define EXTCONF_IS_VALID(mb, d, f) ((mb)->valid_devs[(d)] & __BIT((f)))
+
+struct mcfg_segment {
+ uint64_t ms_address; /* Base address */
+ int ms_segment; /* Segment # */
+ int ms_bus_start; /* Start bus # */
+ int ms_bus_end; /* End bus # */
+ bus_space_tag_t ms_bst;
+ struct mcfg_bus {
+ bus_space_handle_t bsh[32][8];
+ uint8_t valid_devs[32];
+ int valid_ndevs;
+ pcitag_t last_probed;
+ } *ms_bus;
+};
+
+static struct mcfg_segment *mcfg_segs;
+static int mcfg_nsegs;
+static ACPI_TABLE_MCFG *mcfg;
+static int mcfg_inited;
+static struct acpi_softc *acpi_sc;
+
+static const struct acpimcfg_ops mcfg_default_ops = {
+ .ao_validate = acpimcfg_default_validate,
+
+ .ao_read = acpimcfg_default_read,
+ .ao_write = acpimcfg_default_write,
+};
+static const struct acpimcfg_ops *mcfg_ops = &mcfg_default_ops;
+
+/*
+ * default operations.
+ */
+bool
+acpimcfg_default_validate(uint64_t address, int bus_start, int *bus_end)
+{
+
+ /* Always Ok */
+ return true;
+}
+
+uint32_t
+acpimcfg_default_read(bus_space_tag_t bst, bus_space_handle_t bsh,
+ bus_addr_t addr)
+{
+
+ return bus_space_read_4(bst, bsh, addr);
+}
+
+void
+acpimcfg_default_write(bus_space_tag_t bst, bus_space_handle_t bsh,
+ bus_addr_t addr, uint32_t data)
+{
+
+ bus_space_write_4(bst, bsh, addr, data);
+}
+
+
+/*
+ * Check MCFG memory region at system resource
+ */
+struct acpimcfg_memrange {
+ const char *hid;
+ uint64_t address;
+ int bus_start;
+ int bus_end;
+ bool found;
+};
+
+static ACPI_STATUS
+acpimcfg_parse_callback(ACPI_RESOURCE *res, void *ctx)
+{
+ struct acpimcfg_memrange *mr = ctx;
+ const char *type;
+ uint64_t size, mapaddr, mapsize;
+ int n;
+
+ switch (res->Type) {
+ case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+ type = "FIXED_MEMORY32";
+ mapaddr = res->Data.FixedMemory32.Address;
+ mapsize = res->Data.FixedMemory32.AddressLength;
+ break;
+
+ case ACPI_RESOURCE_TYPE_ADDRESS32:
+ /* XXX Only fixed size supported for now */
+ if (res->Data.Address32.Address.AddressLength == 0 ||
+ res->Data.Address32.ProducerConsumer != ACPI_CONSUMER)
+ goto out;
+
+ if (res->Data.Address32.ResourceType != ACPI_MEMORY_RANGE)
+ goto out;
+
+ if (res->Data.Address32.MinAddressFixed != ACPI_ADDRESS_FIXED ||
+ res->Data.Address32.MaxAddressFixed != ACPI_ADDRESS_FIXED)
+ goto out;
+
+ type = "ADDRESS32";
+ mapaddr = res->Data.Address32.Address.Minimum;
+ mapsize = res->Data.Address32.Address.AddressLength;
+ break;
+
+#ifdef _LP64
+ case ACPI_RESOURCE_TYPE_ADDRESS64:
+ /* XXX Only fixed size supported for now */
+ if (res->Data.Address64.Address.AddressLength == 0 ||
+ res->Data.Address64.ProducerConsumer != ACPI_CONSUMER)
+ goto out;
+
+ if (res->Data.Address64.ResourceType != ACPI_MEMORY_RANGE)
+ goto out;
+
+ if (res->Data.Address64.MinAddressFixed != ACPI_ADDRESS_FIXED ||
+ res->Data.Address64.MaxAddressFixed != ACPI_ADDRESS_FIXED)
+ goto out;
+
+ type = "ADDRESS64";
+ mapaddr = res->Data.Address64.Address.Minimum;
+ mapsize = res->Data.Address64.Address.AddressLength;
+ break;
+#endif
+
+ default:
+ out:
+ aprint_debug_dev(acpi_sc->sc_dev, "MCFG: %s: Type=%d\n",
+ mr->hid, res->Type);
+ return_ACPI_STATUS(AE_OK);
+ }
+
+ aprint_debug_dev(acpi_sc->sc_dev, "MCFG: %s: Type=%d(%s), "
+ "Address=0x%016" PRIx64 ", Length=0x%016" PRIx64 "\n",
+ mr->hid, res->Type, type, mapaddr, mapsize);
+
+ if (mr->address < mapaddr || mr->address >= mapaddr + mapsize)
+ return_ACPI_STATUS(AE_OK);
+
+ size = (mr->bus_end - mr->bus_start + 1) * ACPIMCFG_SIZE_PER_BUS;
+
+ /* full map */
+ if (mr->address + size <= mapaddr + mapsize) {
+ mr->found = true;
+ return_ACPI_STATUS(AE_CTRL_TERMINATE);
+ }
+
+ /* partial map */
+ n = (mapsize - (mr->address - mapaddr)) / ACPIMCFG_SIZE_PER_BUS;
+ /* bus_start == bus_end is not allowed. */
+ if (n > 1) {
+ mr->bus_end = mr->bus_start + n - 1;
+ mr->found = true;
+ return_ACPI_STATUS(AE_CTRL_TERMINATE);
+ }
+
+ aprint_debug_dev(acpi_sc->sc_dev, "MCFG: bus %d-%d, "
+ "address 0x%016" PRIx64 ": invalid size: request 0x%016" PRIx64
+ ", actual 0x%016" PRIx64 "\n",
+ mr->bus_start, mr->bus_end, mr->address, size, mapsize);
+
+ return_ACPI_STATUS(AE_OK);
+}
+
+static ACPI_STATUS
+acpimcfg_check_system_resource(ACPI_HANDLE handle, UINT32 level, void *ctx,
+ void **retval)
+{
+ struct acpimcfg_memrange *mr = ctx;
+ ACPI_STATUS status;
+
+ status = AcpiWalkResources(handle, "_CRS", acpimcfg_parse_callback, mr);
+ if (ACPI_FAILURE(status))
+ return_ACPI_STATUS(status);
+
+ if (mr->found)
+ return_ACPI_STATUS(AE_CTRL_TERMINATE);
+
+ aprint_debug_dev(acpi_sc->sc_dev, "MCFG: %s: bus %d-%d, "
+ "address 0x%016" PRIx64 ": no valid region\n", mr->hid,
+ mr->bus_start, mr->bus_end, mr->address);
+
+ return_ACPI_STATUS(AE_OK);
+}
+
+static bool
+acpimcfg_find_system_resource(uint64_t address, int bus_start, int *bus_end)
+{
+ static const char *system_resource_hid[] = {
+ "PNP0C01", /* System Board */
+ "PNP0C02" /* General ID for reserving resources */
+ };
+ struct acpimcfg_memrange mr;
+ ACPI_STATUS status;
+ int i;
+
+ mr.address = address;
+ mr.bus_start = bus_start;
+ mr.bus_end = *bus_end;
+ mr.found = false;
+
+ for (i = 0; i < __arraycount(system_resource_hid); i++) {
+ mr.hid = system_resource_hid[i];
+ status = AcpiGetDevices(__UNCONST(system_resource_hid[i]),
+ acpimcfg_check_system_resource, &mr, NULL);
+ if (ACPI_FAILURE(status))
+ continue;
+ if (mr.found) {
+ *bus_end = mr.bus_end;
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/*
+ * ACPI MCFG
+ */
+void
+acpimcfg_probe(struct acpi_softc *sc)
+{
+ ACPI_MCFG_ALLOCATION *ama;
+ ACPI_STATUS status;
+ uint32_t offset;
+ int i, nsegs;
+
+ if (acpi_sc != NULL)
+ panic("acpi_sc != NULL");
+ acpi_sc = sc;
+
+ status = AcpiGetTable(ACPI_SIG_MCFG, 0, (ACPI_TABLE_HEADER **)&mcfg);
+ if (ACPI_FAILURE(status)) {
+ mcfg = NULL;
+ return;
+ }
+
+ nsegs = 0;
+ offset = sizeof(ACPI_TABLE_MCFG);
+ ama = ACPI_ADD_PTR(ACPI_MCFG_ALLOCATION, mcfg, offset);
+ for (i = 0; offset < mcfg->Header.Length; i++) {
+ aprint_debug_dev(sc->sc_dev,
+ "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64 "\n",
+ ama->PciSegment, ama->StartBusNumber, ama->EndBusNumber,
+ ama->Address);
+ nsegs++;
+ offset += sizeof(ACPI_MCFG_ALLOCATION);
+ ama = ACPI_ADD_PTR(ACPI_MCFG_ALLOCATION, ama, offset);
+ }
+ if (nsegs == 0) {
+ mcfg = NULL;
+ return;
+ }
+
+ mcfg_segs = kmem_zalloc(sizeof(*mcfg_segs) * nsegs, KM_SLEEP);
+ mcfg_nsegs = nsegs;
+}
+
+int
+acpimcfg_init(bus_space_tag_t memt, const struct acpimcfg_ops *ops)
+{
+ ACPI_MCFG_ALLOCATION *ama;
+ struct mcfg_segment *seg;
+ uint32_t offset;
+ int i, n, nsegs, bus_end;
+
+ if (mcfg == NULL)
+ return ENXIO;
+
+ if (mcfg_inited)
+ return 0;
+
+ if (ops != NULL)
+ mcfg_ops = ops;
+
+ nsegs = 0;
+ offset = sizeof(ACPI_TABLE_MCFG);
+ ama = ACPI_ADD_PTR(ACPI_MCFG_ALLOCATION, mcfg, offset);
+ for (i = 0; offset < mcfg->Header.Length; i++) {
+#ifndef _LP64
+ if (ama->Address >= 0x100000000ULL) {
+ aprint_debug_dev(acpi_sc->sc_dev,
+ "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64
+ ": ignore (64bit address)\n", ama->PciSegment,
+ ama->StartBusNumber, ama->EndBusNumber,
+ ama->Address);
+ goto next;
+ }
+#endif
+ /*
+ * Some (broken?) BIOSen have an MCFG table for an empty
+ * bus range. Ignore those tables.
+ */
+ if (ama->StartBusNumber == ama->EndBusNumber) {
+ aprint_debug_dev(acpi_sc->sc_dev,
+ "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64
+ ": ignore (bus %d == %d)\n", ama->PciSegment,
+ ama->StartBusNumber, ama->EndBusNumber,
+ ama->Address, ama->StartBusNumber,
+ ama->EndBusNumber);
+ goto next;
+ }
+ if (ama->StartBusNumber > ama->EndBusNumber) {
+ aprint_debug_dev(acpi_sc->sc_dev,
+ "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64
+ ": ignore (bus %d > %d)\n", ama->PciSegment,
+ ama->StartBusNumber, ama->EndBusNumber,
+ ama->Address, ama->StartBusNumber,
+ ama->EndBusNumber);
+ goto next;
+ }
+
+ /* Validate MCFG memory range */
+ bus_end = ama->EndBusNumber;
+ if (mcfg_ops->ao_validate != NULL &&
+ !mcfg_ops->ao_validate(ama->Address, ama->StartBusNumber,
+ &bus_end)) {
+ if (!acpimcfg_find_system_resource( ama->Address,
+ ama->StartBusNumber, &bus_end)) {
+ aprint_debug_dev(acpi_sc->sc_dev,
+ "MCFG: segment %d, bus %d-%d, "
+ "address 0x%016" PRIx64
+ ": ignore (invalid address)\n",
+ ama->PciSegment,
+ ama->StartBusNumber, ama->EndBusNumber,
+ ama->Address);
+ goto next;
+ }
+ }
+ if (ama->EndBusNumber != bus_end) {
+ aprint_debug_dev(acpi_sc->sc_dev,
+ "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64
+ " -> bus %d-%d\n", ama->PciSegment,
+ ama->StartBusNumber, ama->EndBusNumber,
+ ama->Address, ama->StartBusNumber, bus_end);
+ }
+
+ if (ama->PciSegment != 0) {
+ aprint_debug_dev(acpi_sc->sc_dev,
+ "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64
+ ": ignore (non PCI segment 0)\n", ama->PciSegment,
+ ama->StartBusNumber, bus_end, ama->Address);
+ goto next;
+ }
+
+ seg = &mcfg_segs[nsegs++];
+ seg->ms_address = ama->Address;
+ seg->ms_segment = ama->PciSegment;
+ seg->ms_bus_start = ama->StartBusNumber;
+ seg->ms_bus_end = bus_end;
+ seg->ms_bst = memt;
+ n = seg->ms_bus_end - seg->ms_bus_start + 1;
+ seg->ms_bus = kmem_zalloc(sizeof(*seg->ms_bus) * n, KM_SLEEP);
+
+ next:
+ offset += sizeof(ACPI_MCFG_ALLOCATION);
+ ama = ACPI_ADD_PTR(ACPI_MCFG_ALLOCATION, ama, offset);
+ }
+ if (nsegs == 0)
+ return ENOENT;
+
+ for (i = 0; i < nsegs; i++) {
+ seg = &mcfg_segs[i];
+ aprint_verbose_dev(acpi_sc->sc_dev,
+ "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64 "\n",
+ seg->ms_segment, seg->ms_bus_start, seg->ms_bus_end,
+ seg->ms_address);
+ }
+
+ /* Update # of segment */
+ mcfg_nsegs = nsegs;
+ mcfg_inited = true;
+
+ return 0;
+}
+
+static int
+acpimcfg_ext_conf_is_aliased(pci_chipset_tag_t pc, pcitag_t tag)
+{
+ pcireg_t id;
+ int i;
+
+ id = pci_conf_read(pc, tag, PCI_ID_REG);
+ for (i = PCI_CONF_SIZE; i < PCI_EXTCONF_SIZE; i += PCI_CONF_SIZE) {
+ if (pci_conf_read(pc, tag, i) != id)
+ return false;
+ }
+ return true;
+}
+
+static struct mcfg_segment *
+acpimcfg_get_segment(int bus)
+{
+ struct mcfg_segment *seg;
+ int i;
+
+ for (i = 0; i < mcfg_nsegs; i++) {
+ seg = &mcfg_segs[i];
+ if (bus >= seg->ms_bus_start && bus <= seg->ms_bus_end)
+ return seg;
+ }
+ return NULL;
+}
+
+static int
+acpimcfg_device_probe(const struct pci_attach_args *pa)
+{
+ pci_chipset_tag_t pc = pa->pa_pc;
+ struct mcfg_segment *seg;
+ struct mcfg_bus *mb;
+ pcitag_t tag;
+ pcireg_t reg;
+ int bus = pa->pa_bus;
+ int dev = pa->pa_device;
+ int func = pa->pa_function;
+ int last_dev, last_func, end_func;
+ int alias = 0;
+ int i, j;
+
+ seg = acpimcfg_get_segment(bus);
+ if (seg == NULL)
+ return 0;
+
+ mb = &seg->ms_bus[bus - seg->ms_bus_start];
+ tag = pci_make_tag(pc, bus, dev, func);
+
+ /* Mark invalid between last probed device to probed device. */
+ pci_decompose_tag(pc, mb->last_probed, NULL, &last_dev, &last_func);
+ if (dev != 0 || func != 0) {
+ for (i = last_dev; i <= dev; i++) {
+ end_func = (i == dev) ? func : 8;
+ for (j = last_func; j < end_func; j++) {
+ if (i == last_dev && j == last_func)
+ continue;
+ EXTCONF_SET_INVALID(mb, i, j);
+ }
+ last_func = 0;
+ }
+ }
+ mb->last_probed = tag;
+
+ /* Probe extended configuration space. */
+ if (((reg = pci_conf_read(pc, tag, PCI_CONF_SIZE)) == (pcireg_t)-1) ||
+ (alias = acpimcfg_ext_conf_is_aliased(pc, tag))) {
+ aprint_debug_dev(acpi_sc->sc_dev,
+ "MCFG: %03d:%02d:%d: invalid config space "
+ "(cfg[0x%03x]=0x%08x, alias=%s)\n", bus, dev, func,
+ PCI_CONF_SIZE, reg, alias ? "true" : "false");
+ EXTCONF_SET_INVALID(mb, dev, func);
+ } else {
+ aprint_debug_dev(acpi_sc->sc_dev,
+ "MCFG: %03d:%02d:%d: Ok (cfg[0x%03x]=0x%08x)\n",
+ bus, dev, func, PCI_CONF_SIZE, reg);
+ mb->valid_ndevs++;
+ }
+
+ return 0;
+}
+
+static void
+acpimcfg_scan_bus(struct pci_softc *sc, pci_chipset_tag_t pc, int bus)
+{
+ static const int wildcard[PCICF_NLOCS] = {
+ PCICF_DEV_DEFAULT, PCICF_FUNCTION_DEFAULT
+ };
+
+ sc->sc_bus = bus; /* XXX */
+
+ pci_enumerate_bus(sc, wildcard, acpimcfg_device_probe, NULL);
+}
+
+int
+acpimcfg_map_bus(device_t self, pci_chipset_tag_t pc, int bus)
+{
+ struct pci_softc *sc = device_private(self);
+ struct mcfg_segment *seg = NULL;
+ struct mcfg_bus *mb;
+ bus_space_handle_t bsh;
+ bus_addr_t baddr;
+ int boff;
+ int last_dev, last_func;
+ int i, j;
+ int error;
+
+ if (!mcfg_inited)
+ return ENXIO;
+
+ seg = acpimcfg_get_segment(bus);
+ if (seg == NULL)
+ return ENOENT;
+
+ boff = bus - seg->ms_bus_start;
+ if (seg->ms_bus[boff].valid_ndevs > 0)
+ return 0;
+
+ mb = &seg->ms_bus[boff];
+ baddr = seg->ms_address + (boff * ACPIMCFG_SIZE_PER_BUS);
+
+ /* Map extended configration space of all dev/func. */
+ error = bus_space_map(seg->ms_bst, baddr, ACPIMCFG_SIZE_PER_BUS, 0,
+ &bsh);
+ if (error != 0)
+ return error;
+ for (i = 0; i < 32; i++) {
+ for (j = 0; j < 8; j++) {
+ error = bus_space_subregion(seg->ms_bst, bsh,
+ EXTCONF_OFFSET(i, j, 0), PCI_EXTCONF_SIZE,
+ &mb->bsh[i][j]);
+ if (error != 0)
+ break;
+ }
+ }
+ if (error != 0)
+ return error;
+
+ aprint_debug("\n");
+
+ /* Probe extended configuration space of all devices. */
+ memset(mb->valid_devs, 0xff, sizeof(mb->valid_devs));
+ mb->valid_ndevs = 0;
+ mb->last_probed = pci_make_tag(pc, bus, 0, 0);
+
+ acpimcfg_scan_bus(sc, pc, bus);
+
+ /* Unmap extended configration space of all dev/func. */
+ bus_space_unmap(seg->ms_bst, bsh, ACPIMCFG_SIZE_PER_BUS);
+ memset(mb->bsh, 0, sizeof(mb->bsh));
+
+ if (mb->valid_ndevs == 0) {
+ aprint_debug_dev(acpi_sc->sc_dev,
+ "MCFG: bus %d: no valid devices.\n", bus);
+ memset(mb->valid_devs, 0, sizeof(mb->valid_devs));
+ goto out;
+ }
+
+ /* Mark invalid on remaining all devices. */
+ pci_decompose_tag(pc, mb->last_probed, NULL, &last_dev, &last_func);
+ for (i = last_dev; i < 32; i++) {
+ for (j = last_func; j < 8; j++) {
+ if (i == last_dev && j == last_func) {
+ /* Don't mark invalid to last probed device. */
+ continue;
+ }
+ EXTCONF_SET_INVALID(mb, i, j);
+ }
+ last_func = 0;
+ }
+
+ /* Map extended configuration space per dev/func. */
+ for (i = 0; i < 32; i++) {
+ for (j = 0; j < 8; j++) {
+ if (!EXTCONF_IS_VALID(mb, i, j))
+ continue;
+ error = bus_space_map(seg->ms_bst,
+ baddr + EXTCONF_OFFSET(i, j, 0), PCI_EXTCONF_SIZE,
+ 0, &mb->bsh[i][j]);
+ if (error != 0) {
+ /* Unmap all handles when map failed. */
+ do {
+ while (--j >= 0) {
+ if (!EXTCONF_IS_VALID(mb, i, j))
+ continue;
+ bus_space_unmap(seg->ms_bst,
+ mb->bsh[i][j],
+ PCI_EXTCONF_SIZE);
+ }
+ j = 8;
+ } while (--i >= 0);
+ memset(mb->valid_devs, 0,
+ sizeof(mb->valid_devs));
+ goto out;
+ }
+ }
+ }
+
+ aprint_debug_dev(acpi_sc->sc_dev, "MCFG: bus %d: valid devices\n", bus);
+ for (i = 0; i < 32; i++) {
+ for (j = 0; j < 8; j++) {
+ if (EXTCONF_IS_VALID(mb, i, j)) {
+ aprint_debug_dev(acpi_sc->sc_dev,
+ "MCFG: %03d:%02d:%d\n", bus, i, j);
+ }
+ }
+ }
+
+ error = 0;
+out:
+ aprint_debug_dev(acpi_sc->sc_dev, "%s done", __func__);
+
+ return error;
+}
+
+int
+acpimcfg_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t *data)
+{
+ struct mcfg_segment *seg = NULL;
+ struct mcfg_bus *mb;
+ int bus, dev, func;
+
+ KASSERT(reg < PCI_EXTCONF_SIZE);
+ KASSERT((reg & 3) == 0);
+
+ if (!mcfg_inited) {
+ *data = -1;
+ return ENXIO;
+ }
+
+ pci_decompose_tag(pc, tag, &bus, &dev, &func);
+
+ seg = acpimcfg_get_segment(bus);
+ if (seg == NULL) {
+ *data = -1;
+ return ERANGE;
+ }
+
+ mb = &seg->ms_bus[bus - seg->ms_bus_start];
+ if (!EXTCONF_IS_VALID(mb, dev, func)) {
+ *data = -1;
+ return EINVAL;
+ }
+
+ *data = mcfg_ops->ao_read(seg->ms_bst, mb->bsh[dev][func], reg);
+ return 0;
+}
+
+int
+acpimcfg_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
+{
+ struct mcfg_segment *seg = NULL;
+ struct mcfg_bus *mb;
+ int bus, dev, func;
+
+ KASSERT(reg < PCI_EXTCONF_SIZE);
+ KASSERT((reg & 3) == 0);
+
+ if (!mcfg_inited)
+ return ENXIO;
+
+ pci_decompose_tag(pc, tag, &bus, &dev, &func);
+
+ seg = acpimcfg_get_segment(bus);
+ if (seg == NULL)
+ return ERANGE;
+
+ mb = &seg->ms_bus[bus - seg->ms_bus_start];
+ if (!EXTCONF_IS_VALID(mb, dev, func))
+ return EINVAL;
+
+ mcfg_ops->ao_write(seg->ms_bst, mb->bsh[dev][func], reg, data);
+ return 0;
+}
diff --git a/sys/dev/acpi/acpi_mcfg.h b/sys/dev/acpi/acpi_mcfg.h
new file mode 100644
index 00000000000..b67c360373c
--- /dev/null
+++ b/sys/dev/acpi/acpi_mcfg.h
@@ -0,0 +1,58 @@
+/* $NetBSD: acpi_mcfg.h,v 1.1 2015/10/02 05:22:52 msaitoh Exp $ */
+
+/*-
+ * Copyright (C) 2015 NONAKA Kimihiro <nonaka@NetBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_DEV_ACPI_ACPI_MCFG_H
+#define _SYS_DEV_ACPI_ACPI_MCFG_H
+
+struct acpimcfg_ops;
+void acpimcfg_probe(struct acpi_softc *);
+int acpimcfg_init(bus_space_tag_t, const struct acpimcfg_ops *);
+int acpimcfg_map_bus(device_t, pci_chipset_tag_t, int);
+
+int acpimcfg_conf_read(pci_chipset_tag_t, pcitag_t, int, pcireg_t *);
+int acpimcfg_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t);
+
+struct acpimcfg_ops {
+ /* validate MCFG memory region */
+ bool (*ao_validate)(uint64_t, int, int *);
+
+ /* override default bus_space(9) function */
+ uint32_t (*ao_read)(bus_space_tag_t, bus_space_handle_t,
+ bus_addr_t);
+ void (*ao_write)(bus_space_tag_t, bus_space_handle_t,
+ bus_addr_t, uint32_t);
+};
+
+#define ACPIMCFG_SIZE_PER_BUS (PCI_EXTCONF_SIZE * 32/*dev*/ * 8/*func*/)
+
+bool acpimcfg_default_validate(uint64_t, int, int *);
+uint32_t acpimcfg_default_read(bus_space_tag_t, bus_space_handle_t,
+ bus_addr_t);
+void acpimcfg_default_write(bus_space_tag_t, bus_space_handle_t,
+ bus_addr_t, uint32_t);
+
+#endif /* _SYS_DEV_ACPI_ACPI_PCI_H */
diff --git a/sys/dev/acpi/files.acpi b/sys/dev/acpi/files.acpi
index e08e4fed80d..514f27df64d 100644
--- a/sys/dev/acpi/files.acpi
+++ b/sys/dev/acpi/files.acpi
@@ -1,4 +1,4 @@
-# $NetBSD: files.acpi,v 1.96 2015/09/21 12:32:06 nonaka Exp $
+# $NetBSD: files.acpi,v 1.97 2015/10/02 05:22:52 msaitoh Exp $
include "dev/acpi/acpica/files.acpica"
@@ -18,6 +18,7 @@ device acpi: acpica, acpiapmbus, acpinodebus, acpiecdtbus, acpihpetbus, acpiwdrt
attach acpi at acpibus
file dev/acpi/acpi.c acpi
file dev/acpi/acpi_debug.c acpi
+file dev/acpi/acpi_mcfg.c acpi
file dev/acpi/acpi_pci.c acpi
file dev/acpi/acpi_pci_link.c acpi
file dev/acpi/acpi_power.c acpi
diff --git a/sys/dev/marvell/gtpci.c b/sys/dev/marvell/gtpci.c
index 5d52cd7f866..88014b130f0 100644
--- a/sys/dev/marvell/gtpci.c
+++ b/sys/dev/marvell/gtpci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: gtpci.c,v 1.31 2013/11/06 06:20:12 mrg Exp $ */
+/* $NetBSD: gtpci.c,v 1.32 2015/10/02 05:22:52 msaitoh Exp $ */
/*
* Copyright (c) 2008, 2009 KIYOHARA Takashi
* All rights reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gtpci.c,v 1.31 2013/11/06 06:20:12 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gtpci.c,v 1.32 2015/10/02 05:22:52 msaitoh Exp $");
#include "opt_pci.h"
#include "pci.h"
@@ -567,6 +567,9 @@ gtpci_conf_read(void *v, pcitag_t tag, int reg)
struct gtpci_softc *sc = v;
const pcireg_t addr = tag | reg;
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return -1;
+
GTPCI_WRITE(sc, GTPCI_CA, addr | GTPCI_CA_CONFIGEN);
if ((addr | GTPCI_CA_CONFIGEN) != GTPCI_READ(sc, GTPCI_CA))
return -1;
@@ -580,6 +583,9 @@ gtpci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
struct gtpci_softc *sc = v;
pcireg_t addr = tag | (reg & 0xfc);
+ if ((unsigned int)reg >= PCI_CONF_SIZE)
+ return;
+
GTPCI_WRITE(sc, GTPCI_CA, addr | GTPCI_CA_CONFIGEN);
if ((addr | GTPCI_CA_CONFIGEN) != GTPCI_READ(sc, GTPCI_CA))
return;
diff --git a/sys/dev/marvell/mvpex.c b/sys/dev/marvell/mvpex.c
index 2a697022ec3..f291b01ebea 100644
--- a/sys/dev/marvell/mvpex.c
+++ b/sys/dev/marvell/mvpex.c
@@ -1,4 +1,4 @@
-/* $NetBSD: mvpex.c,v 1.14 2015/07/28 01:57:55 knakahara Exp $ */
+/* $NetBSD: mvpex.c,v 1.15 2015/10/02 05:22:52 msaitoh Exp $ */
/*
* Copyright (c) 2008 KIYOHARA Takashi
* All rights reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mvpex.c,v 1.14 2015/07/28 01:57:55 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvpex.c,v 1.15 2015/10/02 05:22:52 msaitoh Exp $");
#include "opt_pci.h"
#include "pci.h"
@@ -507,6 +507,9 @@ mvpex_conf_read(void *v, pcitag_t tag, int reg)
uint32_t stat;
int bus, dev, func, pexbus, pexdev;
+ if ((unsigned int)reg >= PCI_EXTCONF_SIZE)
+ return -1;
+
mvpex_decompose_tag(v, tag, &bus, &dev, &func);
stat = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVPEX_STAT);
@@ -552,6 +555,9 @@ mvpex_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
uint32_t stat;
int bus, dev, func, pexbus, pexdev;
+ if ((unsigned int)reg >= PCI_EXTCONF_SIZE)
+ return;
+
mvpex_decompose_tag(v, tag, &bus, &dev, &func);
stat = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MVPEX_STAT);
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index ec928d5909e..674e1332623 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci.c,v 1.148 2015/08/24 23:55:04 pooka Exp $ */
+/* $NetBSD: pci.c,v 1.149 2015/10/02 05:22:53 msaitoh Exp $ */
/*
* Copyright (c) 1995, 1996, 1997, 1998
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.148 2015/08/24 23:55:04 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.149 2015/10/02 05:22:53 msaitoh Exp $");
#ifdef _KERNEL_OPT
#include "opt_pci.h"
@@ -68,9 +68,6 @@ int pciprint(void *, const char *);
#ifdef PCI_MACHDEP_ENUMERATE_BUS
#define pci_enumerate_bus PCI_MACHDEP_ENUMERATE_BUS
-#else
-int pci_enumerate_bus(struct pci_softc *, const int *,
- int (*)(const struct pci_attach_args *), struct pci_attach_args *);
#endif
/*
@@ -614,6 +611,43 @@ pci_msix_count(pci_chipset_tag_t pc, pcitag_t tag)
}
int
+pci_get_ext_capability(pci_chipset_tag_t pc, pcitag_t tag, int capid,
+ int *offset, pcireg_t *value)
+{
+ pcireg_t reg;
+ unsigned int ofs;
+
+ /* Only supported for PCI-express devices */
+ if (!pci_get_capability(pc, tag, PCI_CAP_PCIEXPRESS, NULL, NULL))
+ return 0;
+
+ ofs = PCI_EXTCAPLIST_BASE;
+ reg = pci_conf_read(pc, tag, ofs);
+ if (reg == 0xffffffff || reg == 0)
+ return 0;
+
+ for (;;) {
+#ifdef DIAGNOSTIC
+ if ((ofs & 3) || ofs < PCI_EXTCAPLIST_BASE)
+ panic("%s: invalid offset %u", __func__, ofs);
+#endif
+ if (PCI_EXTCAPLIST_CAP(reg) == capid) {
+ if (offset != NULL)
+ *offset = ofs;
+ if (value != NULL)
+ *value = reg;
+ return 1;
+ }
+ ofs = PCI_EXTCAPLIST_NEXT(reg);
+ if (ofs == 0)
+ break;
+ reg = pci_conf_read(pc, tag, ofs);
+ }
+
+ return 0;
+}
+
+int
pci_find_device(struct pci_attach_args *pa,
int (*match)(const struct pci_attach_args *))
{
diff --git a/sys/dev/pci/pci_subr.c b/sys/dev/pci/pci_subr.c
index a2353191c4a..20a8b669a66 100644
--- a/sys/dev/pci/pci_subr.c
+++ b/sys/dev/pci/pci_subr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_subr.c,v 1.134 2015/07/27 15:46:03 msaitoh Exp $ */
+/* $NetBSD: pci_subr.c,v 1.135 2015/10/02 05:22:53 msaitoh Exp $ */
/*
* Copyright (c) 1997 Zubin D. Dittia. All rights reserved.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.134 2015/07/27 15:46:03 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.135 2015/10/02 05:22:53 msaitoh Exp $");
#ifdef _KERNEL_OPT
#include "opt_pci.h"
@@ -56,6 +56,7 @@ __KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.134 2015/07/27 15:46:03 msaitoh Exp $
#include <pci.h>
#include <stdbool.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#endif
@@ -1841,6 +1842,26 @@ static struct {
{ PCI_CAP_PCIAF, "Advanced Features", pci_conf_print_pciaf_cap }
};
+static int
+pci_conf_find_cap(const pcireg_t *regs, int capoff, unsigned int capid,
+ int *offsetp)
+{
+ pcireg_t rval;
+ int off;
+
+ for (off = PCI_CAPLIST_PTR(regs[o2i(capoff)]);
+ off != 0;
+ off = PCI_CAPLIST_NEXT(rval)) {
+ rval = regs[o2i(off)];
+ if (capid == PCI_CAPLIST_CAP(rval)) {
+ if (offsetp != NULL)
+ *offsetp = off;
+ return 1;
+ }
+ }
+ return 0;
+}
+
static void
pci_conf_print_caplist(
#ifdef _KERNEL
@@ -1889,16 +1910,1177 @@ pci_conf_print_caplist(
* the same. This is required because some capabilities
* appear multiple times (e.g. HyperTransport capability).
*/
- for (off = PCI_CAPLIST_PTR(regs[o2i(capoff)]);
- off != 0;
- off = PCI_CAPLIST_NEXT(regs[o2i(off)])) {
+ if (pci_conf_find_cap(regs, capoff, i, &off)) {
rval = regs[o2i(off)];
- foundcap = PCI_CAPLIST_CAP(rval);
- if ((i == foundcap)
- && (pci_captab[foundcap].printfunc != NULL))
- pci_captab[foundcap].printfunc(regs, off);
+ if (pci_captab[i].printfunc != NULL)
+ pci_captab[i].printfunc(regs, off);
+ }
+ }
+}
+
+/* Extended Capability */
+
+static void
+pci_conf_print_aer_cap_uc(pcireg_t reg)
+{
+
+ onoff("Undefined", reg, PCI_AER_UC_UNDEFINED);
+ onoff("Data Link Protocol Error", reg, PCI_AER_UC_DL_PROTOCOL_ERROR);
+ onoff("Surprise Down Error", reg, PCI_AER_UC_SURPRISE_DOWN_ERROR);
+ onoff("Poisoned TLP", reg, PCI_AER_UC_POISONED_TLP);
+ onoff("Flow Control Protocol Error", reg, PCI_AER_UC_FC_PROTOCOL_ERROR);
+ onoff("Completion Timeout", reg, PCI_AER_UC_COMPLETION_TIMEOUT);
+ onoff("Completer Abort", reg, PCI_AER_UC_COMPLETER_ABORT);
+ onoff("Unexpected Completion", reg, PCI_AER_UC_UNEXPECTED_COMPLETION);
+ onoff("Receiver Overflow", reg, PCI_AER_UC_RECEIVER_OVERFLOW);
+ onoff("Malformed TLP", reg, PCI_AER_UC_MALFORMED_TLP);
+ onoff("ECRC Error", reg, PCI_AER_UC_ECRC_ERROR);
+ onoff("Unsupported Request Error", reg,
+ PCI_AER_UC_UNSUPPORTED_REQUEST_ERROR);
+ onoff("ACS Violation", reg, PCI_AER_UC_ACS_VIOLATION);
+ onoff("Uncorrectable Internal Error", reg, PCI_AER_UC_INTERNAL_ERROR);
+ onoff("MC Blocked TLP", reg, PCI_AER_UC_MC_BLOCKED_TLP);
+ onoff("AtomicOp Egress BLK", reg, PCI_AER_UC_ATOMIC_OP_EGRESS_BLOCKED);
+ onoff("TLP Prefix Blocked Error", reg,
+ PCI_AER_UC_TLP_PREFIX_BLOCKED_ERROR);
+}
+
+static void
+pci_conf_print_aer_cap_cor(pcireg_t reg)
+{
+
+ onoff("Receiver Error", reg, PCI_AER_COR_RECEIVER_ERROR);
+ onoff("Bad TLP", reg, PCI_AER_COR_BAD_TLP);
+ onoff("Bad DLLP", reg, PCI_AER_COR_BAD_DLLP);
+ onoff("REPLAY_NUM Rollover", reg, PCI_AER_COR_REPLAY_NUM_ROLLOVER);
+ onoff("Replay Timer Timeout", reg, PCI_AER_COR_REPLAY_TIMER_TIMEOUT);
+ onoff("Advisory Non-Fatal Error", reg, PCI_AER_COR_ADVISORY_NF_ERROR);
+ onoff("Corrected Internal Error", reg, PCI_AER_COR_INTERNAL_ERROR);
+ onoff("Header Log Overflow", reg, PCI_AER_COR_HEADER_LOG_OVERFLOW);
+}
+
+static void
+pci_conf_print_aer_cap_control(pcireg_t reg, bool *tlp_prefix_log)
+{
+
+ printf(" First Error Pointer: 0x%04x\n",
+ (pcireg_t)__SHIFTOUT(reg, PCI_AER_FIRST_ERROR_PTR));
+ onoff("ECRC Generation Capable", reg, PCI_AER_ECRC_GEN_CAPABLE);
+ onoff("ECRC Generation Enable", reg, PCI_AER_ECRC_GEN_ENABLE);
+ onoff("ECRC Check Capable", reg, PCI_AER_ECRC_CHECK_CAPABLE);
+ onoff("ECRC Check Enab", reg, PCI_AER_ECRC_CHECK_ENABLE);
+ onoff("Multiple Header Recording Capable", reg,
+ PCI_AER_MULT_HDR_CAPABLE);
+ onoff("Multiple Header Recording Enable", reg, PCI_AER_MULT_HDR_ENABLE);
+
+ /* This bit is RsvdP if the End-End TLP Prefix Supported bit is Clear */
+ if (!tlp_prefix_log)
+ return;
+ onoff("TLP Prefix Log Present", reg, PCI_AER_TLP_PREFIX_LOG_PRESENT);
+ *tlp_prefix_log = (reg & PCI_AER_TLP_PREFIX_LOG_PRESENT) ? true : false;
+}
+
+static void
+pci_conf_print_aer_cap_rooterr_cmd(pcireg_t reg)
+{
+
+ onoff("Correctable Error Reporting Enable", reg,
+ PCI_AER_ROOTERR_COR_ENABLE);
+ onoff("Non-Fatal Error Reporting Enable", reg,
+ PCI_AER_ROOTERR_NF_ENABLE);
+ onoff("Fatal Error Reporting Enable", reg, PCI_AER_ROOTERR_F_ENABLE);
+}
+
+static void
+pci_conf_print_aer_cap_rooterr_status(pcireg_t reg)
+{
+
+ onoff("ERR_COR Received", reg, PCI_AER_ROOTERR_COR_ERR);
+ onoff("Multiple ERR_COR Received", reg, PCI_AER_ROOTERR_MULTI_COR_ERR);
+ onoff("ERR_FATAL/NONFATAL_ERR Received", reg, PCI_AER_ROOTERR_UC_ERR);
+ onoff("Multiple ERR_FATAL/NONFATAL_ERR Received", reg,
+ PCI_AER_ROOTERR_MULTI_UC_ERR);
+ onoff("First Uncorrectable Fatal", reg, PCI_AER_ROOTERR_FIRST_UC_FATAL);
+ onoff("Non-Fatal Error Messages Received", reg, PCI_AER_ROOTERR_NF_ERR);
+ onoff("Fatal Error Messages Received", reg, PCI_AER_ROOTERR_F_ERR);
+ printf(" Advanced Error Interrupt Message Number: 0x%u\n",
+ (pcireg_t)__SHIFTOUT(reg, PCI_AER_ROOTERR_INT_MESSAGE));
+}
+
+static void
+pci_conf_print_aer_cap_errsrc_id(pcireg_t reg)
+{
+
+ printf(" Correctable Source ID: 0x%04x\n",
+ (pcireg_t)__SHIFTOUT(reg, PCI_AER_ERRSRC_ID_ERR_COR));
+ printf(" ERR_FATAL/NONFATAL Source ID: 0x%04x\n",
+ (pcireg_t)__SHIFTOUT(reg, PCI_AER_ERRSRC_ID_ERR_UC));
+}
+
+static void
+pci_conf_print_aer_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ pcireg_t reg;
+ int pcie_capoff;
+ int pcie_devtype = -1;
+ bool tlp_prefix_log = false;
+
+ if (pci_conf_find_cap(regs, capoff, PCI_CAP_PCIEXPRESS, &pcie_capoff)) {
+ reg = regs[o2i(pcie_capoff)];
+ pcie_devtype = reg & PCIE_XCAP_TYPE_MASK;
+ /* PCIe DW9 to DW14 is for PCIe 2.0 and newer */
+ if (__SHIFTOUT(reg, PCIE_XCAP_VER_MASK) >= 2) {
+ reg = regs[o2i(pcie_capoff + PCIE_DCAP2)];
+ /* End-End TLP Prefix Supported */
+ if (reg & PCIE_DCAP2_EETLP_PREF) {
+ tlp_prefix_log = true;
+ }
}
}
+
+ printf("\n Advanced Error Reporting Register\n");
+
+ reg = regs[o2i(extcapoff + PCI_AER_UC_STATUS)];
+ printf(" Uncorrectable Error Status register: 0x%08x\n", reg);
+ pci_conf_print_aer_cap_uc(reg);
+ reg = regs[o2i(extcapoff + PCI_AER_UC_MASK)];
+ printf(" Uncorrectable Error Mask register: 0x%08x\n", reg);
+ pci_conf_print_aer_cap_uc(reg);
+ reg = regs[o2i(extcapoff + PCI_AER_UC_SEVERITY)];
+ printf(" Uncorrectable Error Severity register: 0x%08x\n", reg);
+ pci_conf_print_aer_cap_uc(reg);
+
+ reg = regs[o2i(extcapoff + PCI_AER_COR_STATUS)];
+ printf(" Correctable Error Status register: 0x%08x\n", reg);
+ pci_conf_print_aer_cap_cor(reg);
+ reg = regs[o2i(extcapoff + PCI_AER_COR_MASK)];
+ printf(" Correctable Error Mask register: 0x%08x\n", reg);
+ pci_conf_print_aer_cap_cor(reg);
+
+ reg = regs[o2i(extcapoff + PCI_AER_CAP_CONTROL)];
+ printf(" Advanced Error Capabilities and Control register: 0x%08x\n",
+ reg);
+ pci_conf_print_aer_cap_control(reg, &tlp_prefix_log);
+ reg = regs[o2i(extcapoff + PCI_AER_HEADER_LOG)];
+ printf(" Header Log register:\n");
+ pci_conf_print_regs(regs, extcapoff + PCI_AER_HEADER_LOG,
+ extcapoff + PCI_AER_ROOTERR_CMD);
+
+ switch (pcie_devtype) {
+ case PCIE_XCAP_TYPE_ROOT: /* Root Port of PCI Express Root Complex */
+ case PCIE_XCAP_TYPE_ROOT_EVNTC: /* Root Complex Event Collector */
+ reg = regs[o2i(extcapoff + PCI_AER_ROOTERR_CMD)];
+ printf(" Root Error Command register: 0x%08x\n", reg);
+ pci_conf_print_aer_cap_rooterr_cmd(reg);
+ reg = regs[o2i(extcapoff + PCI_AER_ROOTERR_STATUS)];
+ printf(" Root Error Status register: 0x%08x\n", reg);
+ pci_conf_print_aer_cap_rooterr_status(reg);
+
+ reg = regs[o2i(extcapoff + PCI_AER_ERRSRC_ID)];
+ printf(" Error Source Identification: 0x%04x\n", reg);
+ pci_conf_print_aer_cap_errsrc_id(reg);
+ break;
+ }
+
+ if (tlp_prefix_log) {
+ reg = regs[o2i(extcapoff + PCI_AER_TLP_PREFIX_LOG)];
+ printf(" TLP Prefix Log register: 0x%08x\n", reg);
+ }
+}
+
+static void
+pci_conf_print_vc_cap_arbtab(const pcireg_t *regs, int off, const char *name,
+ pcireg_t parbsel, int parbsize)
+{
+ pcireg_t reg;
+ int num = 16 << parbsel;
+ int num_per_reg = sizeof(pcireg_t) / parbsize;
+ int i, j;
+
+ /* First, dump the table */
+ for (i = 0; i < num; i += num_per_reg) {
+ reg = regs[o2i(off + i / num_per_reg)];
+ printf(" %s Arbitration Table: 0x%08x\n", name, reg);
+ }
+ /* And then, decode each entry */
+ for (i = 0; i < num; i += num_per_reg) {
+ reg = regs[o2i(off + i / num_per_reg)];
+ for (j = 0; j < num_per_reg; j++)
+ printf(" Phase[%d]: %d\n", j, reg);
+ }
+}
+
+static void
+pci_conf_print_vc_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ pcireg_t reg, n;
+ int parbtab, parbsize;
+ pcireg_t parbsel;
+ int varbtab, varbsize;
+ pcireg_t varbsel;
+ int i, count;
+
+ printf("\n Virtual Channel Register\n");
+ reg = regs[o2i(extcapoff + PCI_VC_CAP1)];
+ printf(" Port VC Capability register 1: 0x%08x\n", reg);
+ count = __SHIFTOUT(reg, PCI_VC_CAP1_EXT_COUNT);
+ printf(" Extended VC Count: %d\n", count);
+ n = __SHIFTOUT(reg, PCI_VC_CAP1_LOWPRI_EXT_COUNT);
+ printf(" Low Priority Extended VC Count: %u\n", n);
+ n = __SHIFTOUT(reg, PCI_VC_CAP1_REFCLK);
+ printf(" Reference Clock: %s\n",
+ (n == PCI_VC_CAP1_REFCLK_100NS) ? "100" : "unknown");
+ parbsize = 1 << __SHIFTOUT(reg, PCI_VC_CAP1_PORT_ARB_TABLE_SIZE);
+ printf(" Port Arbitration Table Entry Size: %dbit\n", parbsize);
+
+ reg = regs[o2i(extcapoff + PCI_VC_CAP2)];
+ printf(" Port VC Capability register 2: 0x%08x\n", reg);
+ onoff("Hardware fixed arbitration scheme",
+ reg, PCI_VC_CAP2_ARB_CAP_HW_FIXED_SCHEME);
+ onoff("WRR arbitration with 32 phases",
+ reg, PCI_VC_CAP2_ARB_CAP_WRR_32);
+ onoff("WRR arbitration with 64 phases",
+ reg, PCI_VC_CAP2_ARB_CAP_WRR_64);
+ onoff("WRR arbitration with 128 phases",
+ reg, PCI_VC_CAP2_ARB_CAP_WRR_128);
+ varbtab = __SHIFTOUT(reg, PCI_VC_CAP2_ARB_TABLE_OFFSET);
+ printf(" VC Arbitration Table Offset: 0x%x\n", varbtab);
+
+ reg = regs[o2i(extcapoff + PCI_VC_CONTROL)] & 0xffff;
+ printf(" Port VC Control register: 0x%04x\n", reg);
+ varbsel = __SHIFTOUT(reg, PCI_VC_CONTROL_VC_ARB_SELECT);
+ printf(" VC Arbitration Select: 0x%x\n", varbsel);
+
+ reg = regs[o2i(extcapoff + PCI_VC_STATUS)] >> 16;
+ printf(" Port VC Status register: 0x%04x\n", reg);
+ onoff("VC Arbitration Table Status",
+ reg, PCI_VC_STATUS_LOAD_VC_ARB_TABLE);
+
+ for (i = 0; i < count + 1; i++) {
+ reg = regs[o2i(extcapoff + PCI_VC_RESOURCE_CAP(i))];
+ printf(" VC number %d\n", i);
+ printf(" VC Resource Capability Register: 0x%08x\n", reg);
+ onoff(" Non-configurable Hardware fixed arbitration scheme",
+ reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_HW_FIXED_SCHEME);
+ onoff(" WRR arbitration with 32 phases",
+ reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_32);
+ onoff(" WRR arbitration with 64 phases",
+ reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_64);
+ onoff(" WRR arbitration with 128 phases",
+ reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_128);
+ onoff(" Time-based WRR arbitration with 128 phases",
+ reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_TWRR_128);
+ onoff(" WRR arbitration with 256 phases",
+ reg, PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_256);
+ onoff(" Advanced Packet Switching",
+ reg, PCI_VC_RESOURCE_CAP_ADV_PKT_SWITCH);
+ onoff(" Reject Snoop Transaction",
+ reg, PCI_VC_RESOURCE_CAP_REJCT_SNOOP_TRANS);
+ n = __SHIFTOUT(reg, PCI_VC_RESOURCE_CAP_MAX_TIME_SLOTS) + 1;
+ printf(" Maximum Time Slots: %d\n", n);
+ parbtab = reg >> PCI_VC_RESOURCE_CAP_PORT_ARB_TABLE_OFFSET_S;
+ printf(" Port Arbitration Table offset: 0x%02x\n",
+ parbtab);
+
+ reg = regs[o2i(extcapoff + PCI_VC_RESOURCE_CTL(i))];
+ printf(" VC Resource Control Register: 0x%08x\n", reg);
+ printf(" TC/VC Map: %02x\n",
+ (pcireg_t)__SHIFTOUT(reg, PCI_VC_RESOURCE_CTL_TCVC_MAP));
+ /*
+ * The load Port Arbitration Table bit is used to update
+ * the Port Arbitration logic and it's always 0 on read, so
+ * we don't print it.
+ */
+ parbsel = __SHIFTOUT(reg, PCI_VC_RESOURCE_CTL_PORT_ARB_SELECT);
+ printf(" Port Arbitration Select: %x\n", parbsel);
+ n = __SHIFTOUT(reg, PCI_VC_RESOURCE_CTL_VC_ID);
+ printf(" VC ID %d\n", n);
+ onoff(" VC Enable", reg, PCI_VC_RESOURCE_CTL_VC_ENABLE);
+
+ reg = regs[o2i(extcapoff + PCI_VC_RESOURCE_STA(i))] >> 16;
+ printf(" VC Resource Status Register: 0x%08x\n", reg);
+ onoff(" Port Arbitration Table Status",
+ reg, PCI_VC_RESOURCE_STA_PORT_ARB_TABLE);
+ onoff(" VC Negotiation Pending",
+ reg, PCI_VC_RESOURCE_STA_VC_NEG_PENDING);
+
+ if ((parbtab != 0) && (parbsel != 0))
+ pci_conf_print_vc_cap_arbtab(regs, extcapoff + parbtab,
+ "Port", parbsel, parbsize);
+ }
+
+ varbsize = 8;
+ if ((varbtab != 0) && (varbsel != 0))
+ pci_conf_print_vc_cap_arbtab(regs, extcapoff + varbtab,
+ " VC", varbsel, varbsize);
+}
+
+static const char *
+pci_conf_print_pwrbdgt_base_power(uint8_t reg)
+{
+
+ switch (reg) {
+ case 0xf0:
+ return "250W";
+ case 0xf1:
+ return "275W";
+ case 0xf2:
+ return "300W";
+ default:
+ return "Unknown";
+ }
+}
+
+static const char *
+pci_conf_print_pwrbdgt_data_scale(uint8_t reg)
+{
+
+ switch (reg) {
+ case 0x00:
+ return "1.0x";
+ case 0x01:
+ return "0.1x";
+ case 0x02:
+ return "0.01x";
+ case 0x03:
+ return "0.001x";
+ default:
+ return "wrong value!";
+ }
+}
+
+static const char *
+pci_conf_print_pwrbdgt_type(uint8_t reg)
+{
+
+ switch (reg) {
+ case 0x00:
+ return "PME Aux";
+ case 0x01:
+ return "Auxilary";
+ case 0x02:
+ return "Idle";
+ case 0x03:
+ return "Sustained";
+ case 0x07:
+ return "Maximun";
+ default:
+ return "Unknown";
+ }
+}
+
+static const char *
+pci_conf_print_pwrbdgt_pwrrail(uint8_t reg)
+{
+
+ switch (reg) {
+ case 0x00:
+ return "Power(12V)";
+ case 0x01:
+ return "Power(3.3V)";
+ case 0x02:
+ return "Power(1.5V or 1.8V)";
+ case 0x07:
+ return "Thermal";
+ default:
+ return "Unknown";
+ }
+}
+
+static void
+pci_conf_print_pwrbdgt_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ pcireg_t reg;
+
+ printf("\n Power Budget Register\n");
+
+ reg = regs[o2i(extcapoff + PCI_PWRBDGT_DSEL)];
+ printf(" Data Select register: 0x%08x\n", reg);
+
+ reg = regs[o2i(extcapoff + PCI_PWRBDGT_DATA)];
+ printf(" Data register: 0x%08x\n", reg);
+ printf(" Base Power: %s\n",
+ pci_conf_print_pwrbdgt_base_power((uint8_t)reg));
+ printf(" Data Scale: %s\n",
+ pci_conf_print_pwrbdgt_data_scale(
+ (uint8_t)(__SHIFTOUT(reg, PCI_PWRBDGT_DATA_SCALE))));
+ printf(" PM Sub State: 0x%hhx\n",
+ (uint8_t)__SHIFTOUT(reg, PCI_PWRBDGT_PM_SUBSTAT));
+ printf(" PM State: D%u\n",
+ (unsigned int)__SHIFTOUT(reg, PCI_PWRBDGT_PM_STAT));
+ printf(" Type: %s\n",
+ pci_conf_print_pwrbdgt_type(
+ (uint8_t)(__SHIFTOUT(reg, PCI_PWRBDGT_TYPE))));
+ printf(" Power Rail: %s\n",
+ pci_conf_print_pwrbdgt_pwrrail(
+ (uint8_t)(__SHIFTOUT(reg, PCI_PWRBDGT_PWRRAIL))));
+
+ reg = regs[o2i(extcapoff + PCI_PWRBDGT_CAP)];
+ printf(" Power Budget Capability register: 0x%08x\n", reg);
+ onoff("System Allocated",
+ reg, PCI_PWRBDGT_CAP_SYSALLOC);
+}
+
+static const char *
+pci_conf_print_rclink_dcl_cap_elmtype(unsigned char type)
+{
+
+ switch (type) {
+ case 0x00:
+ return "Configuration Space Element";
+ case 0x01:
+ return "System Egress Port or internal sink (memory)";
+ case 0x02:
+ return "Internal Root Complex Link";
+ default:
+ return "Unknown";
+ }
+}
+
+static void
+pci_conf_print_rclink_dcl_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ pcireg_t reg;
+ unsigned char nent, linktype;
+ int i;
+
+ printf("\n Root Complex Link Declaration\n");
+
+ reg = regs[o2i(extcapoff + PCI_RCLINK_DCL_ESDESC)];
+ printf(" Element Self Description Register: 0x%08x\n", reg);
+ printf(" Element Type: %s\n",
+ pci_conf_print_rclink_dcl_cap_elmtype((unsigned char)reg));
+ nent = __SHIFTOUT(reg, PCI_RCLINK_DCL_ESDESC_NUMLINKENT);
+ printf(" Number of Link Entries: %hhu\n", nent);
+ printf(" Component ID: %hhu\n",
+ (uint8_t)__SHIFTOUT(reg, PCI_RCLINK_DCL_ESDESC_COMPID));
+ printf(" Port Number: %hhu\n",
+ (uint8_t)__SHIFTOUT(reg, PCI_RCLINK_DCL_ESDESC_PORTNUM));
+ for (i = 0; i < nent; i++) {
+ reg = regs[o2i(extcapoff + PCI_RCLINK_DCL_LINKDESC(i))];
+ printf(" Link Description Register: 0x%08x\n", reg);
+ onoff("Link Valid", reg,PCI_RCLINK_DCL_LINKDESC_LVALID);
+ linktype = reg & PCI_RCLINK_DCL_LINKDESC_LTYPE;
+ onoff2("Link Type", reg, PCI_RCLINK_DCL_LINKDESC_LTYPE,
+ "Configuration Space", "Memory-Mapped Space");
+ onoff("Associated RCRB Header", reg,
+ PCI_RCLINK_DCL_LINKDESC_ARCRBH);
+ printf(" Target Component ID: %hhu\n",
+ (unsigned char)__SHIFTOUT(reg,
+ PCI_RCLINK_DCL_LINKDESC_TCOMPID));
+ printf(" Target Port Number: %hhu\n",
+ (unsigned char)__SHIFTOUT(reg,
+ PCI_RCLINK_DCL_LINKDESC_TPNUM));
+
+ if (linktype == 0) {
+ /* Memory-Mapped Space */
+ reg = regs[o2i(extcapoff
+ + PCI_RCLINK_DCL_LINKADDR_LT0_LO(i))];
+ printf(" Link Address Low Register: 0x%08x\n", reg);
+ reg = regs[o2i(extcapoff
+ + PCI_RCLINK_DCL_LINKADDR_LT0_HI(i))];
+ printf(" Link Address High Register: 0x%08x\n",reg);
+ } else {
+ unsigned int nb;
+ pcireg_t lo, hi;
+
+ /* Configuration Space */
+ lo = regs[o2i(extcapoff
+ + PCI_RCLINK_DCL_LINKADDR_LT1_LO(i))];
+ printf(" Configuration Space Low Register: 0x%08x"
+ "\n", lo);
+ hi = regs[o2i(extcapoff
+ + PCI_RCLINK_DCL_LINKADDR_LT1_HI(i))];
+ printf(" Configuration Space High Register: 0x%08x"
+ "\n", hi);
+ nb = __SHIFTOUT(lo, PCI_RCLINK_DCL_LINKADDR_LT1_N);
+ printf(" N: %u\n", nb);
+ printf(" Func: %hhu\n",
+ (unsigned char)__SHIFTOUT(lo,
+ PCI_RCLINK_DCL_LINKADDR_LT1_FUNC));
+ printf(" Dev: %hhu\n",
+ (unsigned char)__SHIFTOUT(lo,
+ PCI_RCLINK_DCL_LINKADDR_LT1_DEV));
+ printf(" Bus: %hhu\n",
+ (unsigned char)__SHIFTOUT(lo,
+ PCI_RCLINK_DCL_LINKADDR_LT1_BUS(nb)));
+ lo &= PCI_RCLINK_DCL_LINKADDR_LT1_BAL(i);
+ printf(" Configuration Space Base Address: 0x%016"
+ PRIx64 "\n", ((uint64_t)hi << 32) + lo);
+ }
+ }
+}
+
+/* XXX pci_conf_print_rclink_ctl_cap */
+
+static void
+pci_conf_print_rcec_assoc_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ pcireg_t reg;
+
+ printf("\n Root Complex Event Collector Association\n");
+
+ reg = regs[o2i(extcapoff + PCI_RCEC_ASSOC_ASSOCBITMAP)];
+ printf(" Association Bitmap for Root Complex Integrated Devices:"
+ " 0x%08x\n", reg);
+}
+
+/* XXX pci_conf_print_mfvc_cap */
+/* XXX pci_conf_print_vc2_cap */
+/* XXX pci_conf_print_rcrb_cap */
+/* XXX pci_conf_print_vendor_cap */
+/* XXX pci_conf_print_cac_cap */
+
+static void
+pci_conf_print_acs_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ pcireg_t reg, cap, ctl;
+ unsigned int size, i;
+
+ printf("\n Access Control Services\n");
+
+ reg = regs[o2i(extcapoff + PCI_ACS_CAP)];
+ cap = reg & 0xffff;
+ ctl = reg >> 16;
+ printf(" ACS Capability register: 0x%08x\n", cap);
+ onoff("ACS Source Validation", cap, PCI_ACS_CAP_V);
+ onoff("ACS Transaction Blocking", cap, PCI_ACS_CAP_B);
+ onoff("ACS P2P Request Redirect", cap, PCI_ACS_CAP_R);
+ onoff("ACS P2P Completion Redirect", cap, PCI_ACS_CAP_C);
+ onoff("ACS Upstream Forwarding", cap, PCI_ACS_CAP_U);
+ onoff("ACS Egress Control", cap, PCI_ACS_CAP_E);
+ onoff("ACS Direct Translated P2P", cap, PCI_ACS_CAP_T);
+ size = __SHIFTOUT(cap, PCI_ACS_CAP_ECVSIZE);
+ if (size == 0)
+ size = 256;
+ printf(" Egress Control Vector Size: %u\n", size);
+ printf(" ACS Control register: 0x%08x\n", ctl);
+ onoff("ACS Source Validation Enable", ctl, PCI_ACS_CTL_V);
+ onoff("ACS Transaction Blocking Enable", ctl, PCI_ACS_CTL_B);
+ onoff("ACS P2P Request Redirect Enable", ctl, PCI_ACS_CTL_R);
+ onoff("ACS P2P Completion Redirect Enable", ctl, PCI_ACS_CTL_C);
+ onoff("ACS Upstream Forwarding Enable", ctl, PCI_ACS_CTL_U);
+ onoff("ACS Egress Control Enable", ctl, PCI_ACS_CTL_E);
+ onoff("ACS Direct Translated P2P Enable", ctl, PCI_ACS_CTL_T);
+
+ /*
+ * If the P2P Egress Control Capability bit is 0, ignore the Egress
+ * Control vector.
+ */
+ if ((cap & PCI_ACS_CAP_E) == 0)
+ return;
+ for (i = 0; i < size; i += 32)
+ printf(" Egress Control Vector [%u..%u]: %x\n", i + 31,
+ i, regs[o2i(extcapoff + PCI_ACS_ECV + (i / 32) * 4 )]);
+}
+
+static void
+pci_conf_print_ari_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ pcireg_t reg, cap, ctl;
+
+ printf("\n Alternative Routing-ID Interpretation Register\n");
+
+ reg = regs[o2i(extcapoff + PCI_ARI_CAP)];
+ cap = reg & 0xffff;
+ ctl = reg >> 16;
+ printf(" Capability register: 0x%08x\n", cap);
+ onoff("MVFC Function Groups Capability", reg, PCI_ARI_CAP_M);
+ onoff("ACS Function Groups Capability", reg, PCI_ARI_CAP_A);
+ printf(" Next Function Number: %u\n",
+ (unsigned int)__SHIFTOUT(reg, PCI_ARI_CAP_NXTFN));
+ printf(" Control register: 0x%08x\n", ctl);
+ onoff("MVFC Function Groups Enable", reg, PCI_ARI_CTL_M);
+ onoff("ACS Function Groups Enable", reg, PCI_ARI_CTL_A);
+ printf(" Function Group: %u\n",
+ (unsigned int)__SHIFTOUT(reg, PCI_ARI_CTL_FUNCGRP));
+}
+
+static void
+pci_conf_print_ats_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ pcireg_t reg, cap, ctl;
+ unsigned int num;
+
+ printf("\n Address Translation Services\n");
+
+ reg = regs[o2i(extcapoff + PCI_ARI_CAP)];
+ cap = reg & 0xffff;
+ ctl = reg >> 16;
+ printf(" Capability register: 0x%04x\n", cap);
+ num = __SHIFTOUT(reg, PCI_ATS_CAP_INVQDEPTH);
+ if (num == 0)
+ num = 32;
+ printf(" Invalidate Queue Depth: %u\n", num);
+ onoff("Page Aligned Request", reg, PCI_ATS_CAP_PALIGNREQ);
+
+ printf(" Control register: 0x%04x\n", ctl);
+ printf(" Smallest Translation Unit: %u\n",
+ (unsigned int)__SHIFTOUT(reg, PCI_ATS_CTL_STU));
+ onoff("Enable", reg, PCI_ATS_CTL_EN);
+}
+
+static void
+pci_conf_print_sernum_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ pcireg_t lo, hi;
+
+ printf("\n Device Serial Number Register\n");
+
+ lo = regs[o2i(extcapoff + PCI_SERIAL_LOW)];
+ hi = regs[o2i(extcapoff + PCI_SERIAL_HIGH)];
+ printf(" Serial Number: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n",
+ hi >> 24, (hi >> 16) & 0xff, (hi >> 8) & 0xff, hi & 0xff,
+ lo >> 24, (lo >> 16) & 0xff, (lo >> 8) & 0xff, lo & 0xff);
+}
+
+static void
+pci_conf_print_sriov_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ char buf[sizeof("99999 MB")];
+ pcireg_t reg;
+ pcireg_t total_vfs;
+ int i;
+ bool first;
+
+ printf("\n Single Root IO Virtualization Register\n");
+
+ reg = regs[o2i(extcapoff + PCI_SRIOV_CAP)];
+ printf(" Capabilities register: 0x%08x\n", reg);
+ onoff("VF Migration Capable", reg, PCI_SRIOV_CAP_VF_MIGRATION);
+ onoff("ARI Capable Hierarchy Preserved", reg,
+ PCI_SRIOV_CAP_ARI_CAP_HIER_PRESERVED);
+ if (reg & PCI_SRIOV_CAP_VF_MIGRATION) {
+ printf(" VF Migration Interrupt Message Number: 0x%u\n",
+ (pcireg_t)__SHIFTOUT(reg,
+ PCI_SRIOV_CAP_VF_MIGRATION_INTMSG_N));
+ }
+
+ reg = regs[o2i(extcapoff + PCI_SRIOV_CTL)] & 0xffff;
+ printf(" Control register: 0x%04x\n", reg);
+ onoff("VF Enable", reg, PCI_SRIOV_CTL_VF_ENABLE);
+ onoff("VF Migration Enable", reg, PCI_SRIOV_CTL_VF_MIGRATION_SUPPORT);
+ onoff("VF Migration Interrupt Enable", reg,
+ PCI_SRIOV_CTL_VF_MIGRATION_INT_ENABLE);
+ onoff("VF Memory Space Enable", reg, PCI_SRIOV_CTL_VF_MSE);
+ onoff("ARI Capable Hierarchy", reg, PCI_SRIOV_CTL_ARI_CAP_HIER);
+
+ reg = regs[o2i(extcapoff + PCI_SRIOV_STA)] >> 16;
+ printf(" Status register: 0x%04x\n", reg);
+ onoff("VF Migration Status", reg, PCI_SRIOV_STA_VF_MIGRATION);
+
+ reg = regs[o2i(extcapoff + PCI_SRIOV_INITIAL_VFS)] & 0xffff;
+ printf(" InitialVFs register: 0x%04x\n", reg);
+ total_vfs = reg = regs[o2i(extcapoff + PCI_SRIOV_TOTAL_VFS)] >> 16;
+ printf(" TotalVFs register: 0x%04x\n", reg);
+ reg = regs[o2i(extcapoff + PCI_SRIOV_NUM_VFS)] & 0xffff;
+ printf(" NumVFs register: 0x%04x\n", reg);
+
+ reg = regs[o2i(extcapoff + PCI_SRIOV_FUNC_DEP_LINK)] >> 16;
+ printf(" Function Dependency Link register: 0x%04x\n", reg);
+
+ reg = regs[o2i(extcapoff + PCI_SRIOV_VF_OFF)] & 0xffff;
+ printf(" First VF Offset register: 0x%04x\n", reg);
+ reg = regs[o2i(extcapoff + PCI_SRIOV_VF_STRIDE)] >> 16;
+ printf(" VF Stride register: 0x%04x\n", reg);
+
+ reg = regs[o2i(extcapoff + PCI_SRIOV_PAGE_CAP)];
+ printf(" Supported Page Sizes register: 0x%08x\n", reg);
+ printf(" Supported Page Size:");
+ for (i = 0, first = true; i < 32; i++) {
+ if (reg & __BIT(i)) {
+#ifdef _KERNEL
+ format_bytes(buf, sizeof(buf), 1LL << (i + 12));
+#else
+ humanize_number(buf, sizeof(buf), 1LL << (i + 12), "B",
+ HN_AUTOSCALE, 0);
+#endif
+ printf("%s %s", first ? "" : ",", buf);
+ first = false;
+ }
+ }
+ printf("\n");
+
+ reg = regs[o2i(extcapoff + PCI_SRIOV_PAGE_SIZE)];
+ printf(" System Page Sizes register: 0x%08x\n", reg);
+ printf(" Page Size: ");
+ if (reg != 0) {
+#ifdef _KERNEL
+ format_bytes(buf, sizeof(buf), 1LL << (ffs(reg) + 12));
+#else
+ humanize_number(buf, sizeof(buf), 1LL << (ffs(reg) + 12), "B",
+ HN_AUTOSCALE, 0);
+#endif
+ printf("%s", buf);
+ } else {
+ printf("unknown");
+ }
+ printf("\n");
+
+ for (i = 0; i < 6; i++) {
+ reg = regs[o2i(extcapoff + PCI_SRIOV_BAR(i))];
+ printf(" VF BAR%d register: 0x%08x\n", i, reg);
+ }
+
+ if (total_vfs > 0) {
+ reg = regs[o2i(extcapoff + PCI_SRIOV_VF_MIG_STA_AR)];
+ printf(" VF Migration State Array Offset register: 0x%08x\n",
+ reg);
+ printf(" VF Migration State Offset: 0x%08x\n",
+ (pcireg_t)__SHIFTOUT(reg, PCI_SRIOV_VF_MIG_STA_OFFSET));
+ i = __SHIFTOUT(reg, PCI_SRIOV_VF_MIG_STA_BIR);
+ printf(" VF Migration State BIR: ");
+ if (i >= 0 && i <= 5) {
+ printf("BAR%d", i);
+ } else {
+ printf("unknown BAR (%d)", i);
+ }
+ printf("\n");
+ }
+}
+
+/* XXX pci_conf_print_mriov_cap */
+/* XXX pci_conf_print_multicast_cap */
+
+static void
+pci_conf_print_page_req_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ pcireg_t reg, ctl, sta;
+
+ printf("\n Page Request\n");
+
+ reg = regs[o2i(extcapoff + PCI_PAGE_REQ_CTL)];
+ ctl = reg & 0xffff;
+ sta = reg >> 16;
+ printf(" Control Register: 0x%04x\n", ctl);
+ onoff("Enalbe", reg, PCI_PAGE_REQ_CTL_E);
+ onoff("Reset", reg, PCI_PAGE_REQ_CTL_R);
+
+ printf(" Status Register: 0x%04x\n", sta);
+ onoff("Response Failure", reg, PCI_PAGE_REQ_STA_RF);
+ onoff("Unexpected Page Request Group Index", reg,
+ PCI_PAGE_REQ_STA_UPRGI);
+ onoff("Stopped", reg, PCI_PAGE_REQ_STA_S);
+
+ reg = regs[o2i(extcapoff + PCI_PAGE_REQ_OUTSTCAPA)];
+ printf(" Outstanding Page Request Capacity: %u\n", reg);
+ reg = regs[o2i(extcapoff + PCI_PAGE_REQ_OUTSTALLOC)];
+ printf(" Outstanding Page Request Allocation: %u\n", reg);
+}
+
+/* XXX pci_conf_print_amd_cap */
+/* XXX pci_conf_print_resize_bar_cap */
+/* XXX pci_conf_print_dpa_cap */
+
+static const char *
+pci_conf_print_tph_req_cap_sttabloc(unsigned char val)
+{
+
+ switch (val) {
+ case 0x0:
+ return "Not Present";
+ case 0x1:
+ return "in the TPH Requester Capability Structure";
+ case 0x2:
+ return "in the MSI-X Table";
+ default:
+ return "Unknown";
+ }
+}
+
+static void
+pci_conf_print_tph_req_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ pcireg_t reg;
+ int size, i, j;
+
+ printf("\n TPH Requester Extended Capability\n");
+
+ reg = regs[o2i(extcapoff + PCI_TPH_REQ_CAP)];
+ printf(" TPH Requester Capabililty register: 0x%08x\n", reg);
+ onoff("No ST Mode Supported", reg, PCI_TPH_REQ_CAP_NOST);
+ onoff("Interrupt Vector Mode Supported", reg, PCI_TPH_REQ_CAP_INTVEC);
+ onoff("Device Specific Mode Supported", reg, PCI_TPH_REQ_CAP_DEVSPEC);
+ onoff("Extend TPH Reqester Supported", reg, PCI_TPH_REQ_CAP_XTPHREQ);
+ printf(" ST Table Location: %s\n",
+ pci_conf_print_tph_req_cap_sttabloc(
+ (unsigned char)__SHIFTOUT(reg, PCI_TPH_REQ_CAP_STTBLLOC)));
+ size = __SHIFTOUT(reg, PCI_TPH_REQ_CAP_STTBLSIZ) + 1;
+ printf(" ST Table Size: %d\n", size);
+ for (i = 0; i < size ; i += 2) {
+ reg = regs[o2i(extcapoff + PCI_TPH_REQ_STTBL + i / 2)];
+ for (j = 0; j < 2 ; j++) {
+ uint16_t entry = reg;
+
+ if (j != 0)
+ entry >>= 16;
+ entry &= 0xffff;
+ printf(" TPH ST Table Entry (%d): 0x%04hx\n",
+ i + j, entry);
+ }
+ }
+}
+
+static void
+pci_conf_print_ltr_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ pcireg_t reg;
+
+ printf("\n Latency Tolerance Reporting\n");
+ reg = regs[o2i(extcapoff + PCI_LTR_MAXSNOOPLAT)] & 0xffff;
+ printf(" Max Snoop Latency Register: 0x%04x\n", reg);
+ printf(" Max Snoop LatencyValue: %u\n",
+ (pcireg_t)__SHIFTOUT(reg, PCI_LTR_MAXSNOOPLAT_VAL));
+ printf(" Max Snoop LatencyScale: %uns\n",
+ PCI_LTR_SCALETONS(__SHIFTOUT(reg, PCI_LTR_MAXSNOOPLAT_SCALE)));
+ reg = regs[o2i(extcapoff + PCI_LTR_MAXNOSNOOPLAT)] >> 16;
+ printf(" Max No-Snoop Latency Register: 0x%04x\n", reg);
+ printf(" Max No-Snoop LatencyValue: %u\n",
+ (pcireg_t)__SHIFTOUT(reg, PCI_LTR_MAXNOSNOOPLAT_VAL));
+ printf(" Max No-Snoop LatencyScale: %uns\n",
+ PCI_LTR_SCALETONS(__SHIFTOUT(reg, PCI_LTR_MAXNOSNOOPLAT_SCALE)));
+}
+
+static void
+pci_conf_print_sec_pcie_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ int pcie_capoff;
+ pcireg_t reg;
+ int i, maxlinkwidth;
+
+ printf("\n Secondary PCI Express Register\n");
+
+ reg = regs[o2i(extcapoff + PCI_SECPCIE_LCTL3)];
+ printf(" Link Control 3 register: 0x%08x\n", reg);
+ onoff("Perform Equalization", reg, PCI_SECPCIE_LCTL3_PERFEQ);
+ onoff("Link Equalization Request Interrupt Enable",
+ reg, PCI_SECPCIE_LCTL3_LINKEQREQ_IE);
+
+ reg = regs[o2i(extcapoff + PCI_SECPCIE_LANEERR_STA)];
+ printf(" Lane Error Status register: 0x%08x\n", reg);
+
+ /* Get Max Link Width */
+ if (pci_conf_find_cap(regs, capoff, PCI_CAP_PCIEXPRESS, &pcie_capoff)){
+ reg = regs[o2i(pcie_capoff + PCIE_LCAP)];
+ maxlinkwidth = __SHIFTOUT(reg, PCIE_LCAP_MAX_WIDTH);
+ } else {
+ printf("error: falied to get PCIe capablity\n");
+ return;
+ }
+ for (i = 0; i < maxlinkwidth; i++) {
+ reg = regs[o2i(extcapoff + PCI_SECPCIE_EQCTL(i))];
+ if (i % 2 != 0)
+ reg >>= 16;
+ else
+ reg &= 0xffff;
+ printf(" Equalization Control Register (Link %d): %04x\n",
+ i, reg);
+ printf(" Downstream Port Transmit Preset: 0x%x\n",
+ (pcireg_t)__SHIFTOUT(reg,
+ PCI_SECPCIE_EQCTL_DP_XMIT_PRESET));
+ printf(" Downstream Port Receive Hint: 0x%x\n",
+ (pcireg_t)__SHIFTOUT(reg, PCI_SECPCIE_EQCTL_DP_RCV_HINT));
+ printf(" Upstream Port Transmit Preset: 0x%x\n",
+ (pcireg_t)__SHIFTOUT(reg,
+ PCI_SECPCIE_EQCTL_UP_XMIT_PRESET));
+ printf(" Upstream Port Receive Hint: 0x%x\n",
+ (pcireg_t)__SHIFTOUT(reg, PCI_SECPCIE_EQCTL_UP_RCV_HINT));
+ }
+}
+
+/* XXX pci_conf_print_pmux_cap */
+
+static void
+pci_conf_print_pasid_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ pcireg_t reg, cap, ctl;
+ unsigned int num;
+
+ printf("\n Process Address Space ID\n");
+
+ reg = regs[o2i(extcapoff + PCI_PASID_CAP)];
+ cap = reg & 0xffff;
+ ctl = reg >> 16;
+ printf(" PASID Capability Register: 0x%04x\n", cap);
+ onoff("Execute Permission Supported", reg, PCI_PASID_CAP_XPERM);
+ onoff("Privileged Mode Supported", reg, PCI_PASID_CAP_PRIVMODE);
+ num = (1 << __SHIFTOUT(reg, PCI_PASID_CAP_MAXPASIDW)) - 1;
+ printf(" Max PASID Width: %u\n", num);
+
+ printf(" PASID Control Register: 0x%04x\n", ctl);
+ onoff("PASID Enable", reg, PCI_PASID_CTL_PASID_EN);
+ onoff("Execute Permission Enable", reg, PCI_PASID_CTL_XPERM_EN);
+ onoff("Privileged Mode Enable", reg, PCI_PASID_CTL_PRIVMODE_EN);
+}
+
+static void
+pci_conf_print_lnr_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ pcireg_t reg, cap, ctl;
+ unsigned int num;
+
+ printf("\n LN Requester\n");
+
+ reg = regs[o2i(extcapoff + PCI_LNR_CAP)];
+ cap = reg & 0xffff;
+ ctl = reg >> 16;
+ printf(" LNR Capability register: 0x%04x\n", cap);
+ onoff("LNR-64 Supported", reg, PCI_LNR_CAP_64);
+ onoff("LNR-128 Supported", reg, PCI_LNR_CAP_128);
+ num = 1 << __SHIFTOUT(reg, PCI_LNR_CAP_REGISTMAX);
+ printf(" LNR Registration MAX: %u\n", num);
+
+ printf(" LNR Control register: 0x%04x\n", ctl);
+ onoff("LNR Enable", reg, PCI_LNR_CTL_EN);
+ onoff("LNR CLS", reg, PCI_LNR_CTL_CLS);
+ num = 1 << __SHIFTOUT(reg, PCI_LNR_CTL_REGISTLIM);
+ printf(" LNR Registration Limit: %u\n", num);
+}
+
+/* XXX pci_conf_print_dpc_cap */
+
+static int
+pci_conf_l1pm_cap_tposcale(unsigned char scale)
+{
+
+ /* Return scale in us */
+ switch (scale) {
+ case 0x0:
+ return 2;
+ case 0x1:
+ return 10;
+ case 0x2:
+ return 100;
+ default:
+ return -1;
+ }
+}
+
+static void
+pci_conf_print_l1pm_cap(const pcireg_t *regs, int capoff, int extcapoff)
+{
+ pcireg_t reg;
+ int scale, val;
+
+ printf("\n L1 PM Substates\n");
+
+ reg = regs[o2i(extcapoff + PCI_L1PM_CAP)];
+ printf(" L1 PM Substates Capability register: 0x%08x\n", reg);
+ onoff("PCI-PM L1.2 Supported", reg, PCI_L1PM_CAP_PCIPM12);
+ onoff("PCI-PM L1.1 Supported", reg, PCI_L1PM_CAP_PCIPM11);
+ onoff("ASPM L1.2 Supported", reg, PCI_L1PM_CAP_ASPM12);
+ onoff("ASPM L1.1 Supported", reg, PCI_L1PM_CAP_ASPM11);
+ onoff("L1 PM Substates Supported", reg, PCI_L1PM_CAP_L1PM);
+ printf(" Port Common Mode Restore Time: %uus\n",
+ (unsigned int)__SHIFTOUT(reg, PCI_L1PM_CAP_PCMRT));
+ scale = pci_conf_l1pm_cap_tposcale(
+ __SHIFTOUT(reg, PCI_L1PM_CAP_PTPOSCALE));
+ val = __SHIFTOUT(reg, PCI_L1PM_CAP_PTPOVAL);
+ printf(" Port T_POWER_ON: ");
+ if (scale == -1)
+ printf("unknown\n");
+ else
+ printf("%dus\n", val * scale);
+
+ reg = regs[o2i(extcapoff + PCI_L1PM_CTL1)];
+ printf(" L1 PM Substates Control register 1: 0x%08x\n", reg);
+ onoff("PCI-PM L1.2 Enable", reg, PCI_L1PM_CTL1_PCIPM12_EN);
+ onoff("PCI-PM L1.1 Enable", reg, PCI_L1PM_CTL1_PCIPM11_EN);
+ onoff("ASPM L1.2 Enable", reg, PCI_L1PM_CTL1_ASPM12_EN);
+ onoff("ASPM L1.1 Enable", reg, PCI_L1PM_CTL1_ASPM11_EN);
+ printf(" Common Mode Restore Time: %uus\n",
+ (unsigned int)__SHIFTOUT(reg, PCI_L1PM_CTL1_CMRT));
+ scale = PCI_LTR_SCALETONS(__SHIFTOUT(reg, PCI_L1PM_CTL1_LTRTHSCALE));
+ val = __SHIFTOUT(reg, PCI_L1PM_CTL1_LTRTHVAL);
+ printf(" LTR L1.2 THRESHOLD: %dus\n", val * scale);
+
+ reg = regs[o2i(extcapoff + PCI_L1PM_CTL2)];
+ printf(" L1 PM Substates Control register 2: 0x%08x\n", reg);
+ scale = pci_conf_l1pm_cap_tposcale(
+ __SHIFTOUT(reg, PCI_L1PM_CTL2_TPOSCALE));
+ val = __SHIFTOUT(reg, PCI_L1PM_CTL2_TPOVAL);
+ printf(" T_POWER_ON: ");
+ if (scale == -1)
+ printf("unknown\n");
+ else
+ printf("%dus\n", val * scale);
+}
+
+/* XXX pci_conf_print_ptm_cap */
+/* XXX pci_conf_print_mpcie_cap */
+/* XXX pci_conf_print_frsq_cap */
+/* XXX pci_conf_print_rtr_cap */
+/* XXX pci_conf_print_desigvndsp_cap */
+
+#undef MS
+#undef SM
+#undef RW
+
+static struct {
+ pcireg_t cap;
+ const char *name;
+ void (*printfunc)(const pcireg_t *, int, int);
+} pci_extcaptab[] = {
+ { 0, "reserved",
+ NULL },
+ { PCI_EXTCAP_AER, "Advanced Error Reporting",
+ pci_conf_print_aer_cap },
+ { PCI_EXTCAP_VC, "Virtual Channel",
+ pci_conf_print_vc_cap },
+ { PCI_EXTCAP_SERNUM, "Device Serial Number",
+ pci_conf_print_sernum_cap },
+ { PCI_EXTCAP_PWRBDGT, "Power Budgeting",
+ pci_conf_print_pwrbdgt_cap },
+ { PCI_EXTCAP_RCLINK_DCL,"Root Complex Link Declaration",
+ pci_conf_print_rclink_dcl_cap },
+ { PCI_EXTCAP_RCLINK_CTL,"Root Complex Internal Link Control",
+ NULL },
+ { PCI_EXTCAP_RCEC_ASSOC,"Root Complex Event Collector Association",
+ pci_conf_print_rcec_assoc_cap },
+ { PCI_EXTCAP_MFVC, "Multi-Function Virtual Channel",
+ NULL },
+ { PCI_EXTCAP_VC2, "Virtual Channel",
+ NULL },
+ { PCI_EXTCAP_RCRB, "RCRB Header",
+ NULL },
+ { PCI_EXTCAP_VENDOR, "Vendor Unique",
+ NULL },
+ { PCI_EXTCAP_CAC, "Configuration Access Correction",
+ NULL },
+ { PCI_EXTCAP_ACS, "Access Control Services",
+ pci_conf_print_acs_cap },
+ { PCI_EXTCAP_ARI, "Alternative Routing-ID Interpretation",
+ pci_conf_print_ari_cap },
+ { PCI_EXTCAP_ATS, "Address Translation Services",
+ pci_conf_print_ats_cap },
+ { PCI_EXTCAP_SRIOV, "Single Root IO Virtualization",
+ pci_conf_print_sriov_cap },
+ { PCI_EXTCAP_MRIOV, "Multiple Root IO Virtualization",
+ NULL },
+ { PCI_EXTCAP_MULTICAST, "Multicast",
+ NULL },
+ { PCI_EXTCAP_PAGE_REQ, "Page Request",
+ pci_conf_print_page_req_cap },
+ { PCI_EXTCAP_AMD, "Reserved for AMD",
+ NULL },
+ { PCI_EXTCAP_RESIZE_BAR,"Resizable BAR",
+ NULL },
+ { PCI_EXTCAP_DPA, "Dynamic Power Allocation",
+ NULL },
+ { PCI_EXTCAP_TPH_REQ, "TPH Requester",
+ pci_conf_print_tph_req_cap },
+ { PCI_EXTCAP_LTR, "Latency Tolerance Reporting",
+ pci_conf_print_ltr_cap },
+ { PCI_EXTCAP_SEC_PCIE, "Secondary PCI Express",
+ pci_conf_print_sec_pcie_cap },
+ { PCI_EXTCAP_PMUX, "Protocol Multiplexing",
+ NULL },
+ { PCI_EXTCAP_PASID, "Process Address Space ID",
+ pci_conf_print_pasid_cap },
+ { PCI_EXTCAP_LN_REQ, "LN Requester",
+ pci_conf_print_lnr_cap },
+ { PCI_EXTCAP_DPC, "Downstream Port Containment",
+ NULL },
+ { PCI_EXTCAP_L1PM, "L1 PM Substates",
+ pci_conf_print_l1pm_cap },
+ { PCI_EXTCAP_PTM, "Precision Time Management",
+ NULL },
+ { PCI_EXTCAP_MPCIE, "M-PCIe",
+ NULL },
+ { PCI_EXTCAP_FRSQ, "Function Reading Status Queueing",
+ NULL },
+ { PCI_EXTCAP_RTR, "Readiness Time Reporting",
+ NULL },
+ { PCI_EXTCAP_DESIGVNDSP, "Designated Vendor-Specific",
+ NULL },
+};
+
+static int
+pci_conf_find_extcap(const pcireg_t *regs, int capoff, unsigned int capid,
+ int *offsetp)
+{
+ int off;
+ pcireg_t rval;
+
+ for (off = PCI_EXTCAPLIST_BASE;
+ off != 0;
+ off = PCI_EXTCAPLIST_NEXT(rval)) {
+ rval = regs[o2i(off)];
+ if (capid == PCI_EXTCAPLIST_CAP(rval)) {
+ if (offsetp != NULL)
+ *offsetp = off;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void
+pci_conf_print_extcaplist(
+#ifdef _KERNEL
+ pci_chipset_tag_t pc, pcitag_t tag,
+#endif
+ const pcireg_t *regs, int capoff)
+{
+ int off;
+ pcireg_t foundcap;
+ pcireg_t rval;
+ bool foundtable[__arraycount(pci_extcaptab)];
+ unsigned int i;
+
+ /* Check Extended capability structure */
+ off = PCI_EXTCAPLIST_BASE;
+ rval = regs[o2i(off)];
+ if (rval == 0xffffffff || rval == 0)
+ return;
+
+ /* Clear table */
+ for (i = 0; i < __arraycount(pci_extcaptab); i++)
+ foundtable[i] = false;
+
+ /* Print extended capability register's offset and the type first */
+ for (;;) {
+ printf(" Extended Capability Register at 0x%02x\n", off);
+
+ foundcap = PCI_EXTCAPLIST_CAP(rval);
+ printf(" type: 0x%04x (", foundcap);
+ if (foundcap < __arraycount(pci_extcaptab)) {
+ printf("%s)\n", pci_extcaptab[foundcap].name);
+ /* Mark as found */
+ foundtable[foundcap] = true;
+ } else
+ printf("unknown)\n");
+ printf(" version: %d\n", PCI_EXTCAPLIST_VERSION(rval));
+
+ off = PCI_EXTCAPLIST_NEXT(rval);
+ if (off == 0)
+ break;
+ rval = regs[o2i(off)];
+ }
+
+ /*
+ * And then, print the detail of each capability registers
+ * in capability value's order.
+ */
+ for (i = 0; i < __arraycount(pci_extcaptab); i++) {
+ if (foundtable[i] == false)
+ continue;
+
+ /*
+ * The type was found. Search capability list again and
+ * print all capabilities that the capabiliy type is
+ * the same.
+ */
+ if (pci_conf_find_extcap(regs, capoff, i, &off) == 0)
+ continue;
+ rval = regs[o2i(off)];
+ if ((PCI_EXTCAPLIST_VERSION(rval) <= 0)
+ || (pci_extcaptab[i].printfunc == NULL))
+ continue;
+
+ pci_extcaptab[i].printfunc(regs, capoff, off);
+
+ }
}
/* Print the Secondary Status Register. */
@@ -2216,8 +3398,8 @@ pci_conf_print_type2(
printf(" Capability list pointer: 0x%02x\n",
PCI_CAPLIST_PTR(rval));
else
- printf(" Reserved @ 0x14: 0x%04" PRIxMAX "\n",
- __SHIFTOUT(rval, __BITS(15, 0)));
+ printf(" Reserved @ 0x14: 0x%04x\n",
+ (pcireg_t)__SHIFTOUT(rval, __BITS(15, 0)));
pci_conf_print_ssr(__SHIFTOUT(rval, __BITS(31, 16)));
rval = regs[o2i(PCI_BRIDGE_BUS_REG)];
@@ -2306,7 +3488,7 @@ pci_conf_print(
#endif
)
{
- pcireg_t regs[o2i(256)];
+ pcireg_t regs[o2i(PCI_EXTCONF_SIZE)];
int off, capoff, endoff, hdrtype;
const char *type_name;
#ifdef _KERNEL
@@ -2319,7 +3501,7 @@ pci_conf_print(
printf("PCI configuration registers:\n");
- for (off = 0; off < 256; off += 4) {
+ for (off = 0; off < PCI_EXTCONF_SIZE; off += 4) {
#ifdef _KERNEL
regs[o2i(off)] = pci_conf_read(pc, tag, off);
#else
@@ -2409,7 +3591,7 @@ pci_conf_print(
/* device-dependent header */
printf(" Device-dependent header:\n");
- pci_conf_print_regs(regs, endoff, 256);
+ pci_conf_print_regs(regs, endoff, PCI_CONF_SIZE);
printf("\n");
#ifdef _KERNEL
if (printfn)
@@ -2418,4 +3600,19 @@ pci_conf_print(
printf(" Don't know how to pretty-print device-dependent header.\n");
printf("\n");
#endif /* _KERNEL */
+
+ if (regs[o2i(PCI_EXTCAPLIST_BASE)] == 0xffffffff ||
+ regs[o2i(PCI_EXTCAPLIST_BASE)] == 0)
+ return;
+
+#ifdef _KERNEL
+ pci_conf_print_extcaplist(pc, tag, regs, capoff);
+#else
+ pci_conf_print_extcaplist(regs, capoff);
+#endif
+ printf("\n");
+
+ /* Extended Configuration Space, if present */
+ printf(" Extended Configuration Space:\n");
+ pci_conf_print_regs(regs, PCI_EXTCAPLIST_BASE, PCI_EXTCONF_SIZE);
}
diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h
index 90911e3e5be..d89c6e7da74 100644
--- a/sys/dev/pci/pcireg.h
+++ b/sys/dev/pci/pcireg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: pcireg.h,v 1.103 2015/07/27 15:46:03 msaitoh Exp $ */
+/* $NetBSD: pcireg.h,v 1.104 2015/10/02 05:22:53 msaitoh Exp $ */
/*
* Copyright (c) 1995, 1996, 1999, 2000
@@ -1319,7 +1319,7 @@ struct pci_rom {
#define PCI32_DMA_BOUNCE_THRESHOLD 0x100000000ULL
/*
- * PCI-X 2.0 Extended Capability List
+ * PCI-X 2.0/ PCI-express Extended Capability List
*/
#define PCI_EXTCAPLIST_BASE 0x100
@@ -1328,6 +1328,502 @@ struct pci_rom {
#define PCI_EXTCAPLIST_VERSION(ecr) (((ecr) >> 16) & 0xf)
#define PCI_EXTCAPLIST_NEXT(ecr) (((ecr) >> 20) & 0xfff)
+/* Extended Capability Identification Numbers */
+
+#define PCI_EXTCAP_AER 0x0001 /* Advanced Error Reporting */
+#define PCI_EXTCAP_VC 0x0002 /* Virtual Channel if MFVC Ext Cap not set */
+#define PCI_EXTCAP_SERNUM 0x0003 /* Device Serial Number */
+#define PCI_EXTCAP_PWRBDGT 0x0004 /* Power Budgeting */
+#define PCI_EXTCAP_RCLINK_DCL 0x0005 /* Root Complex Link Declaration */
+#define PCI_EXTCAP_RCLINK_CTL 0x0006 /* Root Complex Internal Link Control */
+#define PCI_EXTCAP_RCEC_ASSOC 0x0007 /* Root Complex Event Collector Association */
+#define PCI_EXTCAP_MFVC 0x0008 /* Multi-Function Virtual Channel */
+#define PCI_EXTCAP_VC2 0x0009 /* Virtual Channel if MFVC Ext Cap set */
+#define PCI_EXTCAP_RCRB 0x000a /* RCRB Header */
+#define PCI_EXTCAP_VENDOR 0x000b /* Vendor Unique */
+#define PCI_EXTCAP_CAC 0x000c /* Configuration Access Correction -- obsolete */
+#define PCI_EXTCAP_ACS 0x000d /* Access Control Services */
+#define PCI_EXTCAP_ARI 0x000e /* Alternative Routing-ID Interpretation */
+#define PCI_EXTCAP_ATS 0x000f /* Address Translation Services */
+#define PCI_EXTCAP_SRIOV 0x0010 /* Single Root IO Virtualization */
+#define PCI_EXTCAP_MRIOV 0x0011 /* Multiple Root IO Virtualization */
+#define PCI_EXTCAP_MULTICAST 0x0012 /* Multicast */
+#define PCI_EXTCAP_PAGE_REQ 0x0013 /* Page Request */
+#define PCI_EXTCAP_AMD 0x0014 /* Reserved for AMD */
+#define PCI_EXTCAP_RESIZE_BAR 0x0015 /* Resizable BAR */
+#define PCI_EXTCAP_DPA 0x0016 /* Dynamic Power Allocation */
+#define PCI_EXTCAP_TPH_REQ 0x0017 /* TPH Requester */
+#define PCI_EXTCAP_LTR 0x0018 /* Latency Tolerance Reporting */
+#define PCI_EXTCAP_SEC_PCIE 0x0019 /* Secondary PCI Express */
+#define PCI_EXTCAP_PMUX 0x001a /* Protocol Multiplexing */
+#define PCI_EXTCAP_PASID 0x001b /* Process Address Space ID */
+#define PCI_EXTCAP_LN_REQ 0x001c /* LN Requester */
+#define PCI_EXTCAP_DPC 0x001d /* Downstream Port Containment */
+#define PCI_EXTCAP_L1PM 0x001e /* L1 PM Substates */
+#define PCI_EXTCAP_PTM 0x001f /* Precision Time Management */
+#define PCI_EXTCAP_MPCIE 0x0020 /* M-PCIe */
+#define PCI_EXTCAP_FRSQ 0x0021 /* Function Reading Status Queueing */
+#define PCI_EXTCAP_RTR 0x0022 /* Readiness Time Reporting */
+#define PCI_EXTCAP_DESIGVNDSP 0x0023 /* Designated Vendor-Specific */
+
+/*
+ * Extended capability ID: 0x0001
+ * Advanced Error Reporting
+ */
+#define PCI_AER_UC_STATUS 0x04 /* Uncorrectable Error Status Register */
+#define PCI_AER_UC_UNDEFINED __BIT(0)
+#define PCI_AER_UC_DL_PROTOCOL_ERROR __BIT(4)
+#define PCI_AER_UC_SURPRISE_DOWN_ERROR __BIT(5)
+#define PCI_AER_UC_POISONED_TLP __BIT(12)
+#define PCI_AER_UC_FC_PROTOCOL_ERROR __BIT(13)
+#define PCI_AER_UC_COMPLETION_TIMEOUT __BIT(14)
+#define PCI_AER_UC_COMPLETER_ABORT __BIT(15)
+#define PCI_AER_UC_UNEXPECTED_COMPLETION __BIT(16)
+#define PCI_AER_UC_RECEIVER_OVERFLOW __BIT(17)
+#define PCI_AER_UC_MALFORMED_TLP __BIT(18)
+#define PCI_AER_UC_ECRC_ERROR __BIT(19)
+#define PCI_AER_UC_UNSUPPORTED_REQUEST_ERROR __BIT(20)
+#define PCI_AER_UC_ACS_VIOLATION __BIT(21)
+#define PCI_AER_UC_INTERNAL_ERROR __BIT(22)
+#define PCI_AER_UC_MC_BLOCKED_TLP __BIT(23)
+#define PCI_AER_UC_ATOMIC_OP_EGRESS_BLOCKED __BIT(24)
+#define PCI_AER_UC_TLP_PREFIX_BLOCKED_ERROR __BIT(25)
+#define PCI_AER_UC_MASK 0x08 /* Uncorrectable Error Mask Register */
+ /* Shares bits with UC_STATUS */
+#define PCI_AER_UC_SEVERITY 0x0c /* Uncorrectable Error Severity Register */
+ /* Shares bits with UC_STATUS */
+#define PCI_AER_COR_STATUS 0x10 /* Correctable Error Status Register */
+#define PCI_AER_COR_RECEIVER_ERROR __BIT(0)
+#define PCI_AER_COR_BAD_TLP __BIT(6)
+#define PCI_AER_COR_BAD_DLLP __BIT(7)
+#define PCI_AER_COR_REPLAY_NUM_ROLLOVER __BIT(8)
+#define PCI_AER_COR_REPLAY_TIMER_TIMEOUT __BIT(12)
+#define PCI_AER_COR_ADVISORY_NF_ERROR __BIT(13)
+#define PCI_AER_COR_INTERNAL_ERROR __BIT(14)
+#define PCI_AER_COR_HEADER_LOG_OVERFLOW __BIT(15)
+#define PCI_AER_COR_MASK 0x14 /* Correctable Error Mask Register */
+ /* Shares bits with COR_STATUS */
+#define PCI_AER_CAP_CONTROL 0x18 /* Advanced Error Capabilities and Control Register */
+#define PCI_AER_FIRST_ERROR_PTR __BITS(4, 0)
+#define PCI_AER_FIRST_ERROR_PTR_S 0
+#define PCI_AER_FIRST_ERROR_PTR_M 0x1f
+#define PCI_AER_ECRC_GEN_CAPABLE __BIT(5)
+#define PCI_AER_ECRC_GEN_ENABLE __BIT(6)
+#define PCI_AER_ECRC_CHECK_CAPABLE __BIT(7)
+#define PCI_AER_ECRC_CHECK_ENABLE __BIT(8)
+#define PCI_AER_MULT_HDR_CAPABLE __BIT(9)
+#define PCI_AER_MULT_HDR_ENABLE __BIT(10)
+#define PCI_AER_TLP_PREFIX_LOG_PRESENT __BIT(11)
+#define PCI_AER_HEADER_LOG 0x1c /* Header Log Register */
+#define PCI_AER_ROOTERR_CMD 0x2c /* Root Error Command Register */
+ /* Only for root complex ports */
+#define PCI_AER_ROOTERR_COR_ENABLE __BIT(0)
+#define PCI_AER_ROOTERR_NF_ENABLE __BIT(1)
+#define PCI_AER_ROOTERR_F_ENABLE __BIT(2)
+#define PCI_AER_ROOTERR_STATUS 0x30 /* Root Error Status Register */
+ /* Only for root complex ports */
+#define PCI_AER_ROOTERR_COR_ERR __BIT(0)
+#define PCI_AER_ROOTERR_MULTI_COR_ERR __BIT(1)
+#define PCI_AER_ROOTERR_UC_ERR __BIT(2)
+#define PCI_AER_ROOTERR_MULTI_UC_ERR __BIT(3)
+#define PCI_AER_ROOTERR_FIRST_UC_FATAL __BIT(4)
+#define PCI_AER_ROOTERR_NF_ERR __BIT(5)
+#define PCI_AER_ROOTERR_F_ERR __BIT(6)
+#define PCI_AER_ROOTERR_INT_MESSAGE __BITS(31, 27)
+#define PCI_AER_ROOTERR_INT_MESSAGE_S 27
+#define PCI_AER_ROOTERR_INT_MESSAGE_M 0x1f
+#define PCI_AER_ERRSRC_ID 0x34 /* Error Source Identification Register */
+#define PCI_AER_ERRSRC_ID_ERR_COR __BITS(15, 0)
+#define PCI_AER_ERRSRC_ID_ERR_COR_S 0
+#define PCI_AER_ERRSRC_ID_ERR_COR_M 0xffff
+#define PCI_AER_ERRSRC_ID_ERR_UC __BITS(31, 16)
+#define PCI_AER_ERRSRC_ID_ERR_UC_S 16
+#define PCI_AER_ERRSRC_ID_ERR_UC_M 0xffff
+ /* Only for root complex ports */
+#define PCI_AER_TLP_PREFIX_LOG 0x38 /*TLP Prefix Log Register */
+ /* Only for TLP prefix functions */
+
+/*
+ * Extended capability ID: 0x0002, 0x0009
+ * Virtual Channel
+ */
+#define PCI_VC_CAP1 0x04 /* Port VC Capability Register 1 */
+#define PCI_VC_CAP1_EXT_COUNT __BITS(2, 0)
+#define PCI_VC_CAP1_EXT_COUNT_S 0
+#define PCI_VC_CAP1_EXT_COUNT_M 0x7
+#define PCI_VC_CAP1_LOWPRI_EXT_COUNT __BITS(6, 4)
+#define PCI_VC_CAP1_LOWPRI_EXT_COUNT_S 4
+#define PCI_VC_CAP1_LOWPRI_EXT_COUNT_M 0x7
+#define PCI_VC_CAP1_REFCLK __BITS(9, 8)
+#define PCI_VC_CAP1_REFCLK_S 8
+#define PCI_VC_CAP1_REFCLK_M 0x3
+#define PCI_VC_CAP1_REFCLK_100NS 0x0
+#define PCI_VC_CAP1_PORT_ARB_TABLE_SIZE __BITS(11, 10)
+#define PCI_VC_CAP1_PORT_ARB_TABLE_SIZE_S 10
+#define PCI_VC_CAP1_PORT_ARB_TABLE_SIZE_M 0x3
+#define PCI_VC_CAP2 0x08 /* Port VC Capability Register 2 */
+#define PCI_VC_CAP2_ARB_CAP_HW_FIXED_SCHEME __BIT(0)
+#define PCI_VC_CAP2_ARB_CAP_WRR_32 __BIT(1)
+#define PCI_VC_CAP2_ARB_CAP_WRR_64 __BIT(2)
+#define PCI_VC_CAP2_ARB_CAP_WRR_128 __BIT(3)
+#define PCI_VC_CAP2_ARB_TABLE_OFFSET __BITS(31, 24)
+#define PCI_VC_CAP2_ARB_TABLE_OFFSET_S 24
+#define PCI_VC_CAP2_ARB_TABLE_OFFSET_M 0xff
+#define PCI_VC_CONTROL 0x0c /* Port VC Control Register (16bit) */
+#define PCI_VC_CONTROL_LOAD_VC_ARB_TABLE __BIT(0)
+#define PCI_VC_CONTROL_VC_ARB_SELECT __BITS(3, 1)
+#define PCI_VC_CONTROL_VC_ARB_SELECT_S 1
+#define PCI_VC_CONTROL_VC_ARB_SELECT_M 0x7
+#define PCI_VC_STATUS 0x0e /* Port VC Status Register (16bit) */
+#define PCI_VC_STATUS_LOAD_VC_ARB_TABLE __BIT(0)
+#define PCI_VC_RESOURCE_CAP(n) (0x10 + ((n) * 0x0c)) /* VC Resource Capability Register */
+#define PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_HW_FIXED_SCHEME __BIT(0)
+#define PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_32 __BIT(1)
+#define PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_64 __BIT(2)
+#define PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_128 __BIT(3)
+#define PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_TWRR_128 __BIT(4)
+#define PCI_VC_RESOURCE_CAP_PORT_ARB_CAP_WRR_256 __BIT(5)
+#define PCI_VC_RESOURCE_CAP_ADV_PKT_SWITCH __BIT(14)
+#define PCI_VC_RESOURCE_CAP_REJCT_SNOOP_TRANS __BIT(15)
+#define PCI_VC_RESOURCE_CAP_MAX_TIME_SLOTS __BITS(22, 16)
+#define PCI_VC_RESOURCE_CAP_MAX_TIME_SLOTS_S 16
+#define PCI_VC_RESOURCE_CAP_MAX_TIME_SLOTS_M 0x7f
+#define PCI_VC_RESOURCE_CAP_PORT_ARB_TABLE_OFFSET __BITS(31, 24)
+#define PCI_VC_RESOURCE_CAP_PORT_ARB_TABLE_OFFSET_S 24
+#define PCI_VC_RESOURCE_CAP_PORT_ARB_TABLE_OFFSET_M 0xff
+#define PCI_VC_RESOURCE_CTL(n) (0x14 + ((n) * 0x0c)) /* VC Resource Control Register */
+#define PCI_VC_RESOURCE_CTL_TCVC_MAP __BITS(7, 0)
+#define PCI_VC_RESOURCE_CTL_TCVC_MAP_S 0
+#define PCI_VC_RESOURCE_CTL_TCVC_MAP_M 0xff
+#define PCI_VC_RESOURCE_CTL_LOAD_PORT_ARB_TABLE __BIT(16)
+#define PCI_VC_RESOURCE_CTL_PORT_ARB_SELECT __BITS(19, 17)
+#define PCI_VC_RESOURCE_CTL_PORT_ARB_SELECT_S 17
+#define PCI_VC_RESOURCE_CTL_PORT_ARB_SELECT_M 0x7
+#define PCI_VC_RESOURCE_CTL_VC_ID __BITS(26, 24)
+#define PCI_VC_RESOURCE_CTL_VC_ID_S 24
+#define PCI_VC_RESOURCE_CTL_VC_ID_M 0x7
+#define PCI_VC_RESOURCE_CTL_VC_ENABLE __BIT(31)
+#define PCI_VC_RESOURCE_STA(n) (0x18 + ((n) * 0x0c)) /* VC Resource Status Register */
+#define PCI_VC_RESOURCE_STA_PORT_ARB_TABLE __BIT(0)
+#define PCI_VC_RESOURCE_STA_VC_NEG_PENDING __BIT(1)
+
+/*
+ * Extended capability ID: 0x0003
+ * Serial Number
+ */
+#define PCI_SERIAL_LOW 0x04
+#define PCI_SERIAL_HIGH 0x08
+
+/*
+ * Extended capability ID: 0x0004
+ * Power Budgeting
+ */
+#define PCI_PWRBDGT_DSEL 0x04 /* Data Select */
+#define PCI_PWRBDGT_DATA 0x08 /* Data */
+#define PCI_PWRBDGT_DATA_BASEPWR __BITS(7, 0) /* Base Power */
+#define PCI_PWRBDGT_DATA_SCALE __BITS(9, 8) /* Data Scale */
+#define PCI_PWRBDGT_PM_SUBSTAT __BITS(12, 10) /* PM Sub State */
+#define PCI_PWRBDGT_PM_STAT __BITS(14, 13) /* PM State */
+#define PCI_PWRBDGT_TYPE __BITS(17, 15) /* Type */
+#define PCI_PWRBDGT_PWRRAIL __BITS(20, 18) /* Power Rail */
+#define PCI_PWRBDGT_CAP 0x0c /* Capability */
+#define PCI_PWRBDGT_CAP_SYSALLOC __BIT(0) /* System Allocated */
+
+/*
+ * Extended capability ID: 0x0005
+ * Root Complex Link Declaration
+ */
+#define PCI_RCLINK_DCL_ESDESC 0x04 /* Element Self Description */
+#define PCI_RCLINK_DCL_ESDESC_ELMTYPE __BITS(3, 0) /* Element Type */
+#define PCI_RCLINK_DCL_ESDESC_NUMLINKENT __BITS(15, 8) /* Num of Link Entries*/
+#define PCI_RCLINK_DCL_ESDESC_COMPID __BITS(23, 16) /* Component ID */
+#define PCI_RCLINK_DCL_ESDESC_PORTNUM __BITS(31, 24) /* Port Number */
+#define PCI_RCLINK_DCL_LINKENTS 0x10 /* Link Entries */
+#define PCI_RCLINK_DCL_LINKDESC(x) /* Link Description */ \
+ (PCI_RCLINK_DCL_LINKENTS + ((x) * 16))
+#define PCI_RCLINK_DCL_LINKDESC_LVALID __BIT(0) /* Link Valid */
+#define PCI_RCLINK_DCL_LINKDESC_LTYPE __BIT(1) /* Link Type */
+#define PCI_RCLINK_DCL_LINKDESC_ARCRBH __BIT(2) /* Associate RCRB Header */
+#define PCI_RCLINK_DCL_LINKDESC_TCOMPID __BITS(23, 16) /* Target Component ID*/
+#define PCI_RCLINK_DCL_LINKDESC_TPNUM __BITS(31, 24) /* Target Port Number */
+#define PCI_RCLINK_DCL_LINKADDR_LT0_LO(x) /* LT0: Link Address Low */ \
+ (PCI_RCLINK_DCL_LINKENTS + ((x) * 16) + 0x08)
+#define PCI_RCLINK_DCL_LINKADDR_LT0_HI(x) /* LT0: Link Address High */ \
+ (PCI_RCLINK_DCL_LINKENTS + ((x) * 16) + 0x0c)
+#define PCI_RCLINK_DCL_LINKADDR_LT1_LO(x) /* LT1: Config Space (low) */ \
+ (PCI_RCLINK_DCL_LINKENTS + ((x) * 16) + 0x08)
+#define PCI_RCLINK_DCL_LINKADDR_LT1_N __BITS(2, 0) /* N */
+#define PCI_RCLINK_DCL_LINKADDR_LT1_FUNC __BITS(14, 12) /* Function Number */
+#define PCI_RCLINK_DCL_LINKADDR_LT1_DEV __BITS(19, 15) /* Device Number */
+#define PCI_RCLINK_DCL_LINKADDR_LT1_BUS(N) __BITS(19 + (N), 20) /* Bus Number*/
+#define PCI_RCLINK_DCL_LINKADDR_LT1_BAL(N) __BITS(31, 20 + (N)) /* BAddr(L) */
+#define PCI_RCLINK_DCL_LINKADDR_LT1_HI(x) /* LT1: Config Space Base Addr(H) */\
+ (PCI_RCLINK_DCL_LINKENTS + ((x) * 16) + 0x0c)
+
+/*
+ * Extended capability ID: 0x0006
+ * Root Complex Internal Link Control
+ */
+
+/*
+ * Extended capability ID: 0x0007
+ * Root Complex Event Collector Association
+ */
+#define PCI_RCEC_ASSOC_ASSOCBITMAP 0x04
+
+/*
+ * Extended capability ID: 0x0008
+ * Multi-Function Virtual Channel
+ */
+
+/*
+ * Extended capability ID: 0x0009
+ * Virtual Channel if MFVC Ext Cap set
+ */
+
+/*
+ * Extended capability ID: 0x000a
+ * RCRB Header
+ */
+
+/*
+ * Extended capability ID: 0x000b
+ * Vendor Unique
+ */
+
+/*
+ * Extended capability ID: 0x000c
+ * Configuration Access Correction
+ */
+
+/*
+ * Extended capability ID: 0x000d
+ * Access Control Services
+ */
+#define PCI_ACS_CAP 0x04 /* Capability Register */
+#define PCI_ACS_CAP_V __BIT(0) /* Source Validation */
+#define PCI_ACS_CAP_B __BIT(1) /* Transaction Blocking */
+#define PCI_ACS_CAP_R __BIT(2) /* P2P Request Redirect */
+#define PCI_ACS_CAP_C __BIT(3) /* P2P Completion Redirect */
+#define PCI_ACS_CAP_U __BIT(4) /* Upstream Forwarding */
+#define PCI_ACS_CAP_E __BIT(5) /* Egress Control */
+#define PCI_ACS_CAP_T __BIT(6) /* Direct Translated P2P */
+#define PCI_ACS_CAP_ECVSIZE __BITS(15, 8) /* Egress Control Vector Size */
+#define PCI_ACS_CTL 0x04 /* Control Register */
+#define PCI_ACS_CTL_V __BIT(0 + 16) /* Source Validation Enable */
+#define PCI_ACS_CTL_B __BIT(1 + 16) /* Transaction Blocking Enable */
+#define PCI_ACS_CTL_R __BIT(2 + 16) /* P2P Request Redirect Enable */
+#define PCI_ACS_CTL_C __BIT(3 + 16) /* P2P Completion Redirect Enable */
+#define PCI_ACS_CTL_U __BIT(4 + 16) /* Upstream Forwarding Enable */
+#define PCI_ACS_CTL_E __BIT(5 + 16) /* Egress Control Enable */
+#define PCI_ACS_CTL_T __BIT(6 + 16) /* Direct Translated P2P Enable */
+#define PCI_ACS_ECV 0x08 /* Egress Control Vector */
+
+/*
+ * Extended capability ID: 0x000e
+ * ARI
+ */
+#define PCI_ARI_CAP 0x04 /* Capability Register */
+#define PCI_ARI_CAP_M __BIT(0) /* MFVC Function Groups Cap. */
+#define PCI_ARI_CAP_A __BIT(1) /* ACS Function Groups Cap. */
+#define PCI_ARI_CAP_NXTFN __BITS(15, 8) /* Next Function Number */
+#define PCI_ARI_CTL 0x04 /* Control Register */
+#define PCI_ARI_CTL_M __BIT(16) /* MFVC Function Groups Ena. */
+#define PCI_ARI_CTL_A __BIT(17) /* ACS Function Groups Ena. */
+#define PCI_ARI_CTL_FUNCGRP __BITS(31, 24) /* Function Group */
+
+/*
+ * Extended capability ID: 0x000f
+ * Address Translation Services
+ */
+#define PCI_ATS_CAP 0x04 /* Capability Register */
+#define PCI_ATS_CAP_INVQDEPTH __BITS(4, 0) /* Invalidate Queue Depth */
+#define PCI_ATS_CAP_PALIGNREQ __BIT(5) /* Page Aligned Request */
+#define PCI_ATS_CTL 0x04 /* Control Register */
+#define PCI_ATS_CTL_STU __BITS(20, 16) /* Smallest Translation Unit */
+#define PCI_ATS_CTL_EN __BIT(31) /* Enable */
+
+/*
+ * Extended capability ID: 0x0010
+ * SR-IOV
+ */
+#define PCI_SRIOV_CAP 0x04 /* SR-IOV Capabilities */
+#define PCI_SRIOV_CAP_VF_MIGRATION __BIT(0)
+#define PCI_SRIOV_CAP_ARI_CAP_HIER_PRESERVED __BIT(1)
+#define PCI_SRIOV_CAP_VF_MIGRATION_INTMSG_N __BITS(31, 21)
+#define PCI_SRIOV_CAP_VF_MIGRATION_INTMSG_N_S 21
+#define PCI_SRIOV_CAP_VF_MIGRATION_INTMSG_N_M 0x7ff
+#define PCI_SRIOV_CTL 0x08 /* SR-IOV Control (16bit) */
+#define PCI_SRIOV_CTL_VF_ENABLE __BIT(0)
+#define PCI_SRIOV_CTL_VF_MIGRATION_SUPPORT __BIT(1)
+#define PCI_SRIOV_CTL_VF_MIGRATION_INT_ENABLE __BIT(2)
+#define PCI_SRIOV_CTL_VF_MSE __BIT(3)
+#define PCI_SRIOV_CTL_ARI_CAP_HIER __BIT(4)
+#define PCI_SRIOV_STA 0x0a /* SR-IOV Status (16bit) */
+#define PCI_SRIOV_STA_VF_MIGRATION __BIT(0)
+#define PCI_SRIOV_INITIAL_VFS 0x0c /* InitialVFs (16bit) */
+#define PCI_SRIOV_TOTAL_VFS 0x0e /* TotalVFs (16bit) */
+#define PCI_SRIOV_NUM_VFS 0x10 /* NumVFs (16bit) */
+#define PCI_SRIOV_FUNC_DEP_LINK 0x12 /* Function Dependency Link (16bit) */
+#define PCI_SRIOV_VF_OFF 0x14 /* First VF Offset (16bit) */
+#define PCI_SRIOV_VF_STRIDE 0x16 /* VF Stride (16bit) */
+#define PCI_SRIOV_VF_DID 0x1a /* VF Device ID (16bit) */
+#define PCI_SRIOV_PAGE_CAP 0x1c /* Supported Page Sizes */
+#define PCI_SRIOV_PAGE_SIZE 0x20 /* System Page Size */
+#define PCI_SRIOV_BASE_PAGE_SHIFT 12
+#define PCI_SRIOV_BARS 0x24 /* VF BAR0-5 */
+#define PCI_SRIOV_BAR(x) (PCI_SRIOV_BARS + ((x) * 4))
+#define PCI_SRIOV_VF_MIG_STA_AR 0x3c /* VF Migration State Array Offset */
+#define PCI_SRIOV_VF_MIG_STA_OFFSET __BITS(31, 3)
+#define PCI_SRIOV_VF_MIG_STA_OFFSET_S 3
+#define PCI_SRIOV_VF_MIG_STA_OFFSET_M 0x1fffffff
+#define PCI_SRIOV_VF_MIG_STA_BIR __BITS(2, 0)
+#define PCI_SRIOV_VF_MIG_STA_BIR_S 0
+#define PCI_SRIOV_VF_MIG_STA_BIR_M 0x7
+
+/*
+ * Extended capability ID: 0x0011
+ * Multiple Root IO Virtualization
+ */
+
+/*
+ * Extended capability ID: 0x0012
+ * Multicast
+ */
+
+/*
+ * Extended capability ID: 0x0013
+ * Page Request
+ */
+#define PCI_PAGE_REQ_CTL 0x04 /* Control Register */
+#define PCI_PAGE_REQ_CTL_E __BIT(0) /* Enalbe */
+#define PCI_PAGE_REQ_CTL_R __BIT(1) /* Reset */
+#define PCI_PAGE_REQ_STA 0x04 /* Status Register */
+#define PCI_PAGE_REQ_STA_RF __BIT(0+16) /* Response Failure */
+#define PCI_PAGE_REQ_STA_UPRGI __BIT(1+16) /* Unexpected Page Req Grp Idx */
+#define PCI_PAGE_REQ_STA_S __BIT(8+16) /* Stopped */
+#define PCI_PAGE_REQ_OUTSTCAPA 0x08 /* Outstanding Page Request Capacity */
+#define PCI_PAGE_REQ_OUTSTALLOC 0x0c /* Outstanding Page Request Allocation */
+
+/*
+ * Extended capability ID: 0x0014
+ * (Reserved for AMD)
+ */
+
+/*
+ * Extended capability ID: 0x0015
+ * Resizable BAR
+ */
+
+/*
+ * Extended capability ID: 0x0016
+ * Dynamic Power Allocation
+ */
+
+/*
+ * Extended capability ID: 0x0017
+ * TPH Requester
+ */
+#define PCI_TPH_REQ_CAP 0x04 /* TPH Requester Capability */
+#define PCI_TPH_REQ_CAP_NOST __BIT(0) /* No ST Mode Supported */
+#define PCI_TPH_REQ_CAP_INTVEC __BIT(1) /* Intr Vec Mode Supported */
+#define PCI_TPH_REQ_CAP_DEVSPEC __BIT(2) /* Device Specific Mode Supported */
+#define PCI_TPH_REQ_CAP_XTPHREQ __BIT(8) /* Extend TPH Reqester Supported */
+#define PCI_TPH_REQ_CAP_STTBLLOC __BITS(10, 9) /* ST Table Location */
+#define PCI_TPH_REQ_CAP_STTBLSIZ __BITS(26, 16) /* ST Table Size */
+#define PCI_TPH_REQ_CTL 0x08 /* TPH Requester Control */
+#define PCI_TPH_REQ_CTL_STSEL _BITS(2, 0) /* ST Mode Select */
+#define PCI_TPH_REQ_CTL_TPHREQEN _BITS(9, 8) /* TPH Requester Enable */
+#define PCI_TPH_REQ_STTBL 0x0c /* TPH ST Table */
+
+/*
+ * Extended capability ID: 0x0018
+ * Latency Tolerance Reporting
+ */
+#define PCI_LTR_MAXSNOOPLAT 0x04 /* Max Snoop Latency */
+#define PCI_LTR_MAXSNOOPLAT_VAL __BITS(9, 0) /* Max Snoop LatencyValue */
+#define PCI_LTR_MAXSNOOPLAT_SCALE __BITS(12, 10) /* Max Snoop LatencyScale */
+#define PCI_LTR_MAXNOSNOOPLAT 0x04 /* Max No-Snoop Latency */
+#define PCI_LTR_MAXNOSNOOPLAT_VAL __BITS(25, 16) /* Max No-Snoop LatencyValue*/
+#define PCI_LTR_MAXNOSNOOPLAT_SCALE __BITS(28, 26) /*Max NoSnoop LatencyScale*/
+#define PCI_LTR_SCALETONS(x) ((32 << (x)) / 32)
+
+/*
+ * Extended capability ID: 0x0019
+ * Seconday PCI Express Extended Capability
+ */
+#define PCI_SECPCIE_LCTL3 0x04 /* Link Control 3 */
+#define PCI_SECPCIE_LCTL3_PERFEQ __BIT(0) /* Perform Equalization */
+#define PCI_SECPCIE_LCTL3_LINKEQREQ_IE __BIT(1) /* Link Eq. Req. Int. Ena. */
+#define PCI_SECPCIE_LANEERR_STA 0x08 /* Lane Error Status */
+#define PCI_SECPCIE_EQCTLS 0x0c /* Equalization Control [0-maxlane] */
+#define PCI_SECPCIE_EQCTL(x) (PCI_SECPCIE_EQCTLS + ((x) * 2))
+#define PCI_SECPCIE_EQCTL_DP_XMIT_PRESET __BITS(3, 0) /* DwnStPort Xmit Pres */
+#define PCI_SECPCIE_EQCTL_DP_RCV_HINT __BITS(6, 4) /* DwnStPort Rcv PreHnt */
+#define PCI_SECPCIE_EQCTL_UP_XMIT_PRESET __BITS(11, 8) /* UpStPort Xmit Pres */
+#define PCI_SECPCIE_EQCTL_UP_RCV_HINT __BITS(14, 12) /* UpStPort Rcv PreHnt*/
+
+/*
+ * Extended capability ID: 0x001a
+ * Protocol Multiplexing
+ */
+
+/*
+ * Extended capability ID: 0x001b
+ * Process Address Space ID
+ */
+#define PCI_PASID_CAP 0x04 /* Capability Register */
+#define PCI_PASID_CAP_XPERM __BIT(1) /* Execute Permission Supported */
+#define PCI_PASID_CAP_PRIVMODE __BIT(2) /* Privileged Mode Supported */
+#define PCI_PASID_CAP_MAXPASIDW __BITS(12, 8) /* Max PASID Width */
+#define PCI_PASID_CTL 0x04 /* Control Register */
+#define PCI_PASID_CTL_PASID_EN __BIT(0) /* PASID Enable */
+#define PCI_PASID_CTL_XPERM_EN __BIT(1) /* Execute Permission Enable */
+#define PCI_PASID_CTL_PRIVMODE_EN __BIT(2) /* Privileged Mode Enable */
+
+/*
+ * Extended capability ID: 0x001c
+ * LN Requester
+ */
+#define PCI_LNR_CAP 0x04 /* Capability Register */
+#define PCI_LNR_CAP_64 __BIT(0) /* LNR-64 Supported */
+#define PCI_LNR_CAP_128 __BIT(1) /* LNR-128 Supported */
+#define PCI_LNR_CAP_REGISTMAX __BITS(12, 8) /* LNR Registration MAX */
+#define PCI_LNR_CTL 0x04 /* Control Register */
+#define PCI_LNR_CTL_EN __BIT(0+16) /* LNR Enable */
+#define PCI_LNR_CTL_CLS __BIT(1+16) /* LNR CLS */
+#define PCI_LNR_CTL_REGISTLIM __BITS(28, 24) /* LNR Registration Limit */
+
+/*
+ * Extended capability ID: 0x001d
+ * Downstream Port Containment
+ */
+
+/*
+ * Extended capability ID: 0x001e
+ * L1 PM Substates
+ */
+#define PCI_L1PM_CAP 0x04 /* Capabilities Register */
+#define PCI_L1PM_CAP_PCIPM12 __BIT(0) /* PCI-PM L1.2 Supported */
+#define PCI_L1PM_CAP_PCIPM11 __BIT(1) /* PCI-PM L1.1 Supported */
+#define PCI_L1PM_CAP_ASPM12 __BIT(2) /* ASPM L1.2 Supported */
+#define PCI_L1PM_CAP_ASPM11 __BIT(3) /* ASPM L1.1 Supported */
+#define PCI_L1PM_CAP_L1PM __BIT(4) /* L1 PM Substates Supported */
+#define PCI_L1PM_CAP_PCMRT __BITS(15, 8) /*Port Common Mode Restore Time*/
+#define PCI_L1PM_CAP_PTPOSCALE __BITS(17, 16) /* Port T_POWER_ON Scale */
+#define PCI_L1PM_CAP_PTPOVAL __BITS(23, 19) /* Port T_POWER_ON Value */
+#define PCI_L1PM_CTL1 0x08 /* Control Register 1 */
+#define PCI_L1PM_CTL1_PCIPM12_EN __BIT(0) /* PCI-PM L1.2 Enable */
+#define PCI_L1PM_CTL1_PCIPM11_EN __BIT(1) /* PCI-PM L1.1 Enable */
+#define PCI_L1PM_CTL1_ASPM12_EN __BIT(2) /* ASPM L1.2 Enable */
+#define PCI_L1PM_CTL1_ASPM11_EN __BIT(3) /* ASPM L1.1 Enable */
+#define PCI_L1PM_CTL1_CMRT __BITS(15, 8) /* Common Mode Restore Time */
+#define PCI_L1PM_CTL1_LTRTHVAL __BITS(25, 16) /* LTR L1.2 THRESHOLD Value */
+#define PCI_L1PM_CTL1_LTRTHSCALE __BITS(31, 29) /* LTR L1.2 THRESHOLD Scale */
+#define PCI_L1PM_CTL2 0x0c /* Control Register 2 */
+#define PCI_L1PM_CTL2_TPOSCALE __BITS(1, 0) /* T_POWER_ON Scale */
+#define PCI_L1PM_CTL2_TPOVAL __BITS(7, 3) /* T_POWER_ON Value */
+
/*
* Local constants
*/
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index 8bd2fcb1e5d..5bdd392cf75 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: pcivar.h,v 1.104 2015/08/17 06:16:03 knakahara Exp $ */
+/* $NetBSD: pcivar.h,v 1.105 2015/10/02 05:22:53 msaitoh Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -278,14 +278,22 @@ int pci_find_rom(const struct pci_attach_args *, bus_space_tag_t,
bus_space_handle_t, bus_size_t,
int, bus_space_handle_t *, bus_size_t *);
-int pci_get_capability(pci_chipset_tag_t, pcitag_t, int, int *, pcireg_t *);
-int pci_get_ht_capability(pci_chipset_tag_t, pcitag_t, int, int *, pcireg_t *);
+int pci_get_capability(pci_chipset_tag_t, pcitag_t, int, int *, pcireg_t *);
+int pci_get_ht_capability(pci_chipset_tag_t, pcitag_t, int, int *,
+ pcireg_t *);
+int pci_get_ext_capability(pci_chipset_tag_t, pcitag_t, int, int *,
+ pcireg_t *);
+
int pci_msi_count(pci_chipset_tag_t, pcitag_t);
int pci_msix_count(pci_chipset_tag_t, pcitag_t);
/*
* Helper functions for autoconfiguration.
*/
+#ifndef PCI_MACHDEP_ENUMERATE_BUS
+int pci_enumerate_bus(struct pci_softc *, const int *,
+ int (*)(const struct pci_attach_args *), struct pci_attach_args *);
+#endif
int pci_probe_device(struct pci_softc *, pcitag_t tag,
int (*)(const struct pci_attach_args *),
struct pci_attach_args *);