1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/kernel.h>
4 #include <asm/pci-direct.h>
6 #include <asm/pci_x86.h>
8 /* Direct PCI access. This is used for PCI accesses in early boot before
9 the PCI subsystem works. */
11 u32
read_pci_config(u8 bus
, u8 slot
, u8 func
, u8 offset
)
14 outl(0x80000000 | (bus
<<16) | (slot
<<11) | (func
<<8) | offset
, 0xcf8);
19 u8
read_pci_config_byte(u8 bus
, u8 slot
, u8 func
, u8 offset
)
22 outl(0x80000000 | (bus
<<16) | (slot
<<11) | (func
<<8) | offset
, 0xcf8);
23 v
= inb(0xcfc + (offset
&3));
27 u16
read_pci_config_16(u8 bus
, u8 slot
, u8 func
, u8 offset
)
30 outl(0x80000000 | (bus
<<16) | (slot
<<11) | (func
<<8) | offset
, 0xcf8);
31 v
= inw(0xcfc + (offset
&2));
35 void write_pci_config(u8 bus
, u8 slot
, u8 func
, u8 offset
,
38 outl(0x80000000 | (bus
<<16) | (slot
<<11) | (func
<<8) | offset
, 0xcf8);
42 void write_pci_config_byte(u8 bus
, u8 slot
, u8 func
, u8 offset
, u8 val
)
44 outl(0x80000000 | (bus
<<16) | (slot
<<11) | (func
<<8) | offset
, 0xcf8);
45 outb(val
, 0xcfc + (offset
&3));
48 void write_pci_config_16(u8 bus
, u8 slot
, u8 func
, u8 offset
, u16 val
)
50 outl(0x80000000 | (bus
<<16) | (slot
<<11) | (func
<<8) | offset
, 0xcf8);
51 outw(val
, 0xcfc + (offset
&2));
54 int early_pci_allowed(void)
56 return (pci_probe
& (PCI_PROBE_CONF1
|PCI_PROBE_NOEARLY
)) ==
60 void early_dump_pci_device(u8 bus
, u8 slot
, u8 func
)
66 printk(KERN_INFO
"pci 0000:%02x:%02x.%d config space:",
69 for (i
= 0; i
< 256; i
+= 4) {
73 val
= read_pci_config(bus
, slot
, func
, i
);
74 for (j
= 0; j
< 4; j
++) {
75 printk(" %02x", val
& 0xff);
82 void early_dump_pci_devices(void)
84 unsigned bus
, slot
, func
;
86 if (!early_pci_allowed())
89 for (bus
= 0; bus
< 256; bus
++) {
90 for (slot
= 0; slot
< 32; slot
++) {
91 for (func
= 0; func
< 8; func
++) {
95 class = read_pci_config(bus
, slot
, func
,
97 if (class == 0xffffffff)
100 early_dump_pci_device(bus
, slot
, func
);
103 type
= read_pci_config_byte(bus
, slot
,