3 PCI PCI PCI type 0 PCI type 1 PCI type 2 PCI CardBus PCI 16 6 Device ID Vendor ID 00h Status Register Command Register 04h Class Code Revision ID 08h BIST Header Type Latency Timer Cache Line Size 0ch 3ch 6 PCI 16 Linux include/linux/pci.h 16 1 ID ID #define PCI_VENDOR_ID 0x00 16 bits #define PCI_DEVICE_ID 0x02 16 bits 2 #define PCI_COMMAND 0x04 16 bits #define PCI_COMMAND_IO 0x1 Enable response in I/O space #define PCI_COMMAND_MEMORY 0x2 Enable response in Memory space #define PCI_COMMAND_MASTER0x4 Enable bus mastering #define PCI_COMMAND_SPECIAL0x8 Enable response to special cycles #define PCI_COMMAND_INVALIDATE 0x10 Use memory write and invalidate #define PCI_COMMAND_VGA_PALETTE 0x20 Enable palette snooping #define PCI_COMMAND_PARITY 0x40 Enable parity checking #define PCI_COMMAND_WAIT 0x80 Enable address/data stepping #define PCI_COMMAND_SERR 0x100 Enable SERR #define PCI_COMMAND_FAST_BACK 0x200 Enable back-to-back writes PCI_COMMAND PCI 10 PCI_COMMAND_XXX PCI 10 PCI 3 #define PCI_STATUS 0x06 16 bits #define PCI_STATUS_CAP_LIST 0x10 Support Capability List
#define PCI_STATUS_66MHZ 0x20 Support 66 Mhz PCI 2.1 bus #define PCI_STATUS_UDF 0x40 Support User Definable Features [obsolete] #define PCI_STATUS_FAST_BACK 0x80 Accept fast-back to back #define PCI_STATUS_PARITY 0x100 Detected parity error #define PCI_STATUS_DEVSEL_MASK 0x600 DEVSEL timing #define PCI_STATUS_DEVSEL_FAST 0x000 #define PCI_STATUS_DEVSEL_MEDIUM 0x200 #define PCI_STATUS_DEVSEL_SLOW 0x400 #define PCI_STATUS_SIG_TARGET_ABORT 0x800 Set on target abort #define PCI_STATUS_REC_TARGET_ABORT 0x1000 Master ack of " #define PCI_STATUS_REC_MASTER_ABORT 0x2000 Set on master abort #define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 Set when we drive SERR #define PCI_STATUS_DETECTED_PARITY 0x8000 Set on parity error PCI_STATUS PCI_STATUS_XXX PCI 12 4 4 #define PCI_CLASS_REVISION 0x08 High 24 bits are class, low 8 revision #define PCI_REVISION_ID 0x08 Revision ID #define PCI_CLASS_PROG 0x09 Reg. Level Programming Interface #define PCI_CLASS_DEVICE 0x0a Device class PCI_CLASS_REVISION PCI PCI_REVISION_ID RevisionID PCI_CLASS_PROG ClassCode PCI_CLASS_DEVICE word PCI 5 PCI_CACHE_LINE_SIZE Cache Line Size 6 PCI_LATENCY_TIMER Latency Timer 7 PCI_HEADER_TYPE HeaderType HeaderType 7 00h PCI 01h PCI-to-PCI 02h CardBus 8 PCI_BIST BIST Built In Self-Test BIST bit 3 0 bit 7 BIST bit 6 BIST 2 #define PCI_CACHE_LINE_SIZE 0x0c 8 bits #define PCI_LATENCY_TIMER 0x0d 8 bits #define PCI_HEADER_TYPE 0x0e 8 bits #define PCI_HEADER_TYPE_NORMAL0 #define PCI_HEADER_TYPE_BRIDGE 1 #define PCI_HEADER_TYPE_CARDBUS 2
#define PCI_BIST 0x0f 8 bits #define PCI_BIST_CODE_MASK 0x0f Return result #define PCI_BIST_START 0x40 1 to start BIST, 2 secs or less #define PCI_BIST_CAPABLE 0x80 1 if BIST capable 3.1 BAR PCI_BASE_ADDRESS_0 PCI_BASE_ADDRESS_5 0 5 PCI_BASE_ADDRESS_2 5 PCI 0 PCI_BASE_ADDRESS_0~1 0 1 BAR bit 0 BAR I/O Memory PCI_BASE_ADDRESS_SPACE BAR bit 0 PCI_BASE_ADDRESS_SPACE_IO PCI_BASE_ADDRESS_SPACE_MEMORY bit 0 I/O BAR BAR bit 2 1 PCI_BASE_ADDRESS_MEM_TYPE_MASK bit 2 1 PCI_BASE_ADDRESS_MEM_TYPE_32/1M/64 BAR bit 3 Prefetchable PCI_BASE_ADDRESS_MEM_PREFETCH PCI_BASE_ADDRESS_MEM_MASK 0x0fUL 0xfffffff0 BAR PCI 256 PCI_BASE_ADDRESS_IO_MASK 0x03UL=0xfffffff8 I/O BAR I/O PCI I/O 8 * Base addresses specify locations in memory or I/O space. * Decoded size can be determined by writing a value of * 0xffffffff to the register, and reading it back. Only * 1 bits are decoded. #define PCI_BASE_ADDRESS_00x10 32 bits #define PCI_BASE_ADDRESS_10x14 32 bits [htype 0,1 only] #define PCI_BASE_ADDRESS_20x18 32 bits [htype 0 only] #define PCI_BASE_ADDRESS_30x1c 32 bits #define PCI_BASE_ADDRESS_40x20 32 bits #define PCI_BASE_ADDRESS_50x24 32 bits #define PCI_BASE_ADDRESS_SPACE 0x01 0 = memory, 1 = I/O #define PCI_BASE_ADDRESS_SPACE_IO 0x01 #define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00 #define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06 #define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 32 bit address #define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 Below 1M [obsolete] #define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 64 bit address #define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 prefetchable? #define PCI_BASE_ADDRESS_MEM_MASK(~0x0fUL)
#define PCI_BASE_ADDRESS_IO_MASK bit 1 is reserved if address_space = 1 (~0x03UL) 3.2 0 PCI 0 Header type 0 (normal devices) #define PCI_CARDBUS_CIS 0x28 #define PCI_SUBSYSTEM_VENDOR_ID 0x2c #define PCI_SUBSYSTEM_ID 0x2e #define PCI_ROM_ADDRESS 0x30 Bits 31..11 are address, 10..1 reserved #define PCI_ROM_ADDRESS_ENABLE 0x01 #define PCI_ROM_ADDRESS_MASK (~0x7ffUL) #define PCI_CAPABILITY_LIST 0x34 Offset of first capability list entry 0x35-0x3b are reserved #define PCI_INTERRUPT_LINE 0x3c 8 bits #define PCI_INTERRUPT_PIN 0x3d 8 bits #define PCI_MIN_GNT 0x3e 8 bits #define PCI_MAX_LAT 0x3f 8 bits ROM 0 ROM 0x30 bit 31 11 bit 10 1 bit 0 PCI ROM bit 0 1 bit 0 0 bit 31 11 3.3 1 1 PCI-PCI 24 0 BAR0 BAR1 40 0x18 0x39 1 7 7 1 1 PCI_PRIMARY_BUS PCI_SECONDARY_BUS PCI_SUBORDINATE_BUS PCI_SEC_LATENCY_TIMER SecondaryLatencyTimer Header type 1 (PCI-to-PCI bridges) #define PCI_PRIMARY_BUS 0x18 Primary bus number #define PCI_SECONDARY_BUS 0x19 Secondary bus number #define PCI_SUBORDINATE_BUS 0x1a Highest bus number behind the bridge #define PCI_SEC_LATENCY_TIMER 0x1b Latency timer for secondary interface 2 PCI IO
64KB I/O I/O Base I/O LIMIT 8 bit 3 0 I/O 0h 16 I/O 1h 32 I/O 2h fh bit 7 4 I/O 16 I/O bit 15 12 Linux PCI_IO_BASE PCI_IO_LIMIT I/O I/O Limit PCI_IO_RANGE_TYPE_MASK 8 bit 3 0 PCI_IO_RANGE_TYPE_16 32 bit 3 0 0h 1h 16 I O 32 I/O PCI_IO_RANGE_MASK 0x0f 0xf0 4 32 I/O I/O Base Upper 16 Bits I/O Limit Upper 16 Bits 32 I O 16 bit 31 16 Linux PCI_IO_BASE_UPPER16 PCI_IO_LIMIT_UPPER16 #define PCI_IO_BASE 0x1c I/O range behind the bridge #define PCI_IO_LIMIT 0x1d #define PCI_IO_RANGE_TYPE_MASK 0x0f I/O bridging type #define PCI_IO_RANGE_TYPE_16 0x00 #define PCI_IO_RANGE_TYPE_32 0x01 #define PCI_IO_RANGE_MASK ~0x0f #define PCI_SEC_STATUS 0x1e Secondary status register, only bit 14 used #define PCI_MEMORY_BASE 0x20 Memory range behind #define PCI_MEMORY_LIMIT 0x22 #define PCI_MEMORY_RANGE_TYPE_MASK 0x0f #define PCI_MEMORY_RANGE_MASK ~0x0f #define PCI_PREF_MEMORY_BASE 0x24 Prefetchable memory range behind #define PCI_PREF_MEMORY_LIMIT 0x26 #define PCI_PREF_RANGE_TYPE_MASK 0x0f #define PCI_PREF_RANGE_TYPE_32 0x00 #define PCI_PREF_RANGE_TYPE_64 0x01 #define PCI_PREF_RANGE_MASK ~0x0f #define PCI_PREF_BASE_UPPER32 0x28 Upper half of prefetchable memory range #define PCI_PREF_LIMIT_UPPER32 0x2c #define PCI_IO_BASE_UPPER16 0x30 Upper half of I/O addresses #define PCI_IO_LIMIT_UPPER16 0x32 3 PCI I/O PCI I/O Memory Base Memory Limit 16 bit 3 0 bit 15 4 12 32 bit 31 20 I O 1MB Linux PCI_MEM_BASE PCI_MEM_LIMIT Memory Base Memory Limit PCI_MEM_RANGE_TYPE_MASK 4 bit 3 0 PCI_MEMORY_RANGE_MASK 0x0f 0xfff0 12 4 PCI PCI Prefectable Memory Base Prefetchable
Memory Limit 16 bit 3 0 0h 32 1h 64 bit 15 4 32 12 bit 31 20 Linux PCI_PREF_MEMORY_BASE PCI_PREF_MEMORY_LIMIT Prefectable Memory Base Prefetchable Memory Limit PCI_PREF_RANGE_TYPE_MASK 4 PCI_PREF_RANGE_TYPE_32 64 4 32 64 PCI_PREF_RANGE_MASK 12 64 Prefetchable Base Upper 32 Bits Prefetchable Limit Upper 32 Bits 64 32 Linux PCI_PREF_BASE_UPPER_32 PCI_PREF_LIMIT_UPPER32 5 PCI_SEC_STATUS 1 Secondary Status 1 0x34 0 PCI_CAPABILITY_LIST 1 0x35-0x37 0x38 ROM 0 ROM Linux PCI_ROM_ADDRESS1 1 0x3c 0x3d 0 PCI_INTERRUPT_LINE PCI_INTERRUPT_PIN 1 0x3e Linux PCI_BRIDGE_CONTROL 0x34 same as for htype 0 0x35-0x3b is reserved #define PCI_ROM_ADDRESS1 0x38 Same as PCI_ROM_ADDRESS, but for htype 1 0x3c-0x3d are same as for htype 0 #define PCI_BRIDGE_CONTROL 0x3e #define PCI_BRIDGE_CTL_PARITY 0x01 Enable parity detection on secondary interface #define PCI_BRIDGE_CTL_SERR 0x02 The same for SERR forwarding #define PCI_BRIDGE_CTL_NO_ISA 0x04 Disable bridging of ISA ports #define PCI_BRIDGE_CTL_VGA 0x08 Forward VGA addresses #define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 Report master aborts #define PCI_BRIDGE_CTL_BUS_RESET 0x40 Secondary bus reset #define PCI_BRIDGE_CTL_FAST_BACK 0x80 Fast Back2Back enabled on secondary interface 3.4 2 3.5
Capability lists #define PCI_CAP_LIST_ID 0 Capability ID #define PCI_CAP_ID_PM 0x01 Power Management #define PCI_CAP_ID_AGP 0x02 Accelerated Graphics Port #define PCI_CAP_ID_VPD 0x03 Vital Product Data #define PCI_CAP_ID_SLOTID 0x04 Slot Identification #define PCI_CAP_ID_MSI 0x05 Message Signalled Interrupts #define PCI_CAP_ID_CHSWP 0x06 CompactPCI HotSwap #define PCI_CAP_LIST_NEXT 1 Next capability in the list #define PCI_CAP_FLAGS 2 Capability defined flags (16 bits) #define PCI_CAP_SIZEOF 4 Power Management Registers #define PCI_PM_CAP_VER_MASK 0x0007 Version #define PCI_PM_CAP_PME_CLOCK 0x0008 PME clock required #define PCI_PM_CAP_AUX_POWER 0x0010 Auxilliary power support #define PCI_PM_CAP_DSI 0x0020 Device specific initialization #define PCI_PM_CAP_D1 0x0200 D1 power state support #define PCI_PM_CAP_D2 0x0400 D2 power state support #define PCI_PM_CAP_PME 0x0800 PME pin supported #define PCI_PM_CTRL 4 PM control and status register #define PCI_PM_CTRL_STATE_MASK 0x0003 Current power state (D0 to D3) #define PCI_PM_CTRL_PME_ENABLE 0x0100 PME pin enable #define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 Data select (??) #define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 Data scale (??) #define PCI_PM_CTRL_PME_STATUS 0x8000 PME pin status #define PCI_PM_PPB_EXTENSIONS 6 PPB support extensions (??) #define PCI_PM_PPB_B2_B3 0x40 Stop clock when in D3hot (??) #define PCI_PM_BPCC_ENABLE 0x80 Bus power/clock control enable (??) #define PCI_PM_DATA_REGISTER 7 (??) #define PCI_PM_SIZEOF 8 AGP registers #define PCI_AGP_VERSION 2 BCD version number #define PCI_AGP_RFU 3 Rest of capability flags #define PCI_AGP_STATUS 4 Status register #define PCI_AGP_STATUS_RQ_MASK 0xff000000 Maximum number of requests - 1 #define PCI_AGP_STATUS_SBA 0x0200 Sideband addressing supported #define PCI_AGP_STATUS_64BIT 0x0020 64-bit addressing supported #define PCI_AGP_STATUS_FW 0x0010 FW transfers supported #define PCI_AGP_STATUS_RATE4 0x0004 4x transfer rate supported #define PCI_AGP_STATUS_RATE2 0x0002 2x transfer rate supported #define PCI_AGP_STATUS_RATE1 0x0001 1x transfer rate supported
#define PCI_AGP_COMMAND 8 Control register #define PCI_AGP_COMMAND_RQ_MASK 0xff000000 Master: Maximum number of requests #define PCI_AGP_COMMAND_SBA 0x0200 Sideband addressing enabled #define PCI_AGP_COMMAND_AGP 0x0100 Allow processing of AGP transactions #define PCI_AGP_COMMAND_64BIT 0x0020 Allow processing of 64-bit addresses #define PCI_AGP_COMMAND_FW 0x0010 Force FW transfers #define PCI_AGP_COMMAND_RATE4 0x0004 Use 4x rate #define PCI_AGP_COMMAND_RATE2 0x0002 Use 4x rate #define PCI_AGP_COMMAND_RATE1 0x0001 Use 4x rate #define PCI_AGP_SIZEOF 12 PCI 3.6 pci_ids.h 1 PCI 2 PCI-SIG ID PCI ID 3.7 PCI 32 PCI 8 PCI 256 PCI device number 0 255 bit 7 3 bit 2 0 Linux PCI_SLOT() 0 255 0 31 PCI_FUNC 0 255 0 7 PCI_DEVFN() * The PCI interface treats multi-function devices as independent * devices. The slot/function address of each device is encoded * in a single byte as follows: * * 7:3 = slot * 2:0 = function #define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) ((func) & 0x07)) #define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) #define PCI_FUNC(devfn) ((devfn) & 0x07) #ifdef KERNEL #endif
4 PCI PCI CPU Host/PCI PCI 1 Host/PCI CPU Host/PCI 0xcf8 0xcfc PCI PCI Specification 2.2 2 2 PCI PCI Specification 2.2 3 PCI BIOS Linux backward compability 1 3 CPU PCI Linux pci_ops 6 pci_bus ops pci_ops PCI PCI PCI PCI PCI 1 2 3 1 1 2 1 2 PCI BIOS X86 linux/arch/i386/kernel/pci_pc.c 4 1 pci_ops 6 6 include/linux/pci.h struct pci_ops int (*read_byte)(struct pci_dev *, int where, u8 *val); int (*read_word)(struct pci_dev *, int where, u16 *val); int (*read_dword)(struct pci_dev *, int where, u32 *val); int (*write_byte)(struct pci_dev *, int where, u8 val); int (*write_word)(struct pci_dev *, int where, u16 val); int (*write_dword)(struct pci_dev *, int where, u32 val); ; where 4 2 1 1 2 PCI #ifdef CONFIG_PCI_DIRECT #endif pci_conf1_read(write)_config_byte(word dword) pci_conf2_read(write)_config_byte(word dword) 1 arch/i386/kernel/pci-pc.c * Direct access to PCI hardware...
#ifdef CONFIG_PCI_DIRECT * Functions for accessing PCI configuration space with type 1 accesses #define CONFIG_CMD(dev, where) (0x80000000 (dev->bus->number << 16) (dev->devfn << 8) (where & ~3)) static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value) outl(config_cmd(dev,where), 0xCF8); *value = inb(0xcfc + (where&3)); return PCIBIOS_SUCCESSFUL; static int pci_conf1_read_config_word(struct pci_dev *dev, int where, u16 *value) outl(config_cmd(dev,where), 0xCF8); *value = inw(0xcfc + (where&2)); return PCIBIOS_SUCCESSFUL; static int pci_conf1_read_config_dword(struct pci_dev *dev, int where, u32 *value) outl(config_cmd(dev,where), 0xCF8); *value = inl(0xcfc); return PCIBIOS_SUCCESSFUL; static int pci_conf1_write_config_byte(struct pci_dev *dev, int where, u8 value) outl(config_cmd(dev,where), 0xCF8); outb(value, 0xCFC + (where&3)); return PCIBIOS_SUCCESSFUL; static int pci_conf1_write_config_word(struct pci_dev *dev, int where, u16 value) outl(config_cmd(dev,where), 0xCF8); outw(value, 0xCFC + (where&2)); return PCIBIOS_SUCCESSFUL; static int pci_conf1_write_config_dword(struct pci_dev *dev, int where, u32 value)
outl(config_cmd(dev,where), 0xCF8); outl(value, 0xCFC); return PCIBIOS_SUCCESSFUL; #undef CONFIG_CMD static struct pci_ops pci_direct_conf1 = pci_conf1_read_config_byte, pci_conf1_read_config_word, pci_conf1_read_config_dword, pci_conf1_write_config_byte, pci_conf1_write_config_word, pci_conf1_write_config_dword ; * Functions for accessing PCI configuration space with type 2 accesses #endif pci_conf1_read/write_config_byte/word/dword pci_conf1_read_config_byte() CPU 1 PCI 1. 32 0xcf8 1 2. 32 0xcfc I/O Host/PCI PCI PCI pci_conf1_read_config_byte() outl 32 I O 0xcf8 CONFIG_CMD(dev,where) PCI where where 4 0 255 4 CONFIG_CMD where 2 4 CONFIG_CMD() pci_conf1_read_config_byte inb() 0xcfc~0xcff where 2 pci_conf1_read_config_byte() PCIBIOS_SUCCESSFUL 0 pci_conf1_read/write_config_byte/word/dword() 6 Linux 1 pci_ops pci_direct_conf1 PCI pci_bus ops pci_direct_conf1 PCI 1 PCI PCI
4 3 2 Linux 2 2 pci_conf2_read/write_config_byte/word/dword() 6 Linux 2 pci_ops pci_direct_conf2 PCI pci_bus ops pci_direct_conf2 PCI 2 PCI PCI pci_direct_conf2 static struct pci_ops pci_direct_conf2 = pci_conf2_read_config_byte, pci_conf2_read_config_word, pci_conf2_read_config_dword, pci_conf2_write_config_byte, pci_conf2_write_config_word, pci_conf2_write_config_dword ; 4 4 PCI PCI Linux PCI pci_check_direct() PCI 1 2 1 PCI Spec2.2 Host/PCI 1 pci_check_direct() 1 1 1 2 1 2 pci_check_direct() PCI init (arch/i386/kernel/pci-pc.c) static struct pci_ops * init pci_check_direct(void) unsigned int tmp; unsigned long flags; save_flags(flags); cli(); * Check if configuration type 1 works. if (pci_probe & PCI_PROBE_CONF1) outb (0x01, 0xCFB); tmp = inl (0xCF8); outl (0x80000000, 0xCF8); if (inl (0xCF8) == 0x80000000 && pci_sanity_check(&pci_direct_conf1)) outl (tmp, 0xCF8); restore_flags(flags);
printk("pci: Using configuration type 1\n"); request_region(0xcf8, 8, "PCI conf1"); return &pci_direct_conf1; outl (tmp, 0xCF8); * Check if configuration type 2 works. if (pci_probe & PCI_PROBE_CONF2) outb (0x00, 0xCFB); outb (0x00, 0xCF8); outb (0x00, 0xCFA); if (inb (0xCF8) == 0x00 && inb (0xCFA) == 0x00 && pci_sanity_check(&pci_direct_conf2)) restore_flags(flags); printk("pci: Using configuration type 2\n"); request_region(0xcf8, 4, "PCI conf2"); return &pci_direct_conf2; restore_flags(flags); return NULL; 1 save_flags() cli() 2 pci_probe PCI PCI BIOS 1 2 pci-pc.c unsigned int pci_probe = PCI_PROBE_BIOS PCI_PROBE_CONF1 PCI_PROBE_CONF2; 3 pci_probe PCI_PROBE_CONF1 1 pci_probe 1 bit 31 1 Host/PCI 0 Host/PCI 0x80000000 1 pci_direct_conf1 pci_sanity_check() 0 PCI 1 1 request_region() ioport_resource I/O 0xcf8 0xcff 8 PCI 1 pci_direct_conf1 4 pci_check_direct() 1 3 2 Host/PCI 2 pci_direct_conf2
5 4 1 2 NULL pci_sanity_check() 0 PCI PCI SMP 0 PCI root bus 0 Host/PCI VGA PCI ID INTEL Compaq PCI o 1 0 arch/i386/kernel/pci-pc.c * Before we decide to use direct hardware access mechanisms, we try to do some * trivial checks to ensure it at least _seems_ to be working -- we just test * whether bus 00 contains a host bridge (this is similar to checking * techniques used in XFree86, but ours should be more reliable since we * attempt to make use of direct access hints provided by the PCI BIOS). * * This should be close to trivial, but it isn't, because there are buggy * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID. static int init pci_sanity_check(struct pci_ops *o) u16 x; struct pci_bus bus; Fake bus and device struct pci_dev dev; if (pci_probe & PCI_NO_CHECKS) return 1; bus.number = 0; dev.bus = &bus; for(dev.devfn=0; dev.devfn < 0x100; dev.devfn++) if ((!o->read_word(&dev, PCI_CLASS_DEVICE, &x) && (x == PCI_CLASS_BRIDGE_HOST x == PCI_CLASS_DISPLAY_VGA)) (!o->read_word(&dev, PCI_VENDOR_ID, &x) && (x == PCI_VENDOR_ID_INTEL x == PCI_VENDOR_ID_COMPAQ))) return 1; DBG("PCI: Sanity check failed\n"); return 0; 4 5 PCI BIOS PCI BIOS PCI BIOS PCI Linux BIOS BIOS pci_bios_read/write_config_byte/word/dword() Linux PCI BIOS PCI BIOS pci_ops
pci_bios_access arch/i386/kernel/pci-pc.c * Function table for BIOS32 access static struct pci_ops pci_bios_access = pci_bios_read_config_byte, pci_bios_read_config_word, pci_bios_read_config_dword, pci_bios_write_config_byte, pci_bios_write_config_word, pci_bios_write_config_dword ; Linux pci_direct_conf1 pci_direct_conf2 pci_bios_access pci_bus ops PCI PCI PCI pci_direct_conf1 pci_direct_conf2 pci_bios_access 1 2 Linux PCI BIOS BIOS Host/PCI