关于访问pci配置空间,宏PCI_CONF1_ADDRESS让我感到困惑

时间:2012-08-27 04:25:25

标签: linux-kernel pci pci-bus

我正在学习linux内核代码,关于pci的部分,我读了/arch/x86/pci/Direct.c文件,有些代码让我困惑:

/*
* Functions for accessing PCI base (first 256 bytes) and extended
* (4096 bytes per PCI function) configuration space with type 1
* accesses.
*/
#define PCI_CONF1_ADDRESS(bus, devfn, reg) \
(0x80000000 | ((reg & 0xF00) << 16) | (bus << 16) \
| (devfn << 8) | (reg & 0xFC))

static int pci_conf1_read(unsigned int seg, unsigned int bus,
          unsigned int devfn, int reg, int len, u32 *value)
{
unsigned long flags;

if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
    *value = -1;
    return -EINVAL;
}

spin_lock_irqsave(&pci_config_lock, flags);

outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);

switch (len) {
case 1:
    *value = inb(0xCFC + (reg & 3));
    break;
case 2:
    *value = inw(0xCFC + (reg & 2));
    break;
case 4:
    *value = inl(0xCFC);
    break;
}

spin_unlock_irqrestore(&pci_config_lock, flags);

return 0;
}

内核版本是2.6.18,因此,宏PCI_CONF1_ADDRESS让我感到困惑。如您所知,在使用IO端口CF8 / CFC时,它只能访问pci配置空间的第一个256字节,如果要访问256~4095字节之间的空间,则必须使用ECAM(增强配置访问)机制),但上面的注释说:

  

扩展(每个PCI功能4096字节)配置空间,类型1访问。

这是否意味着在使用IO端口CF8 / CFC时它可以访问所有4096字节的pci配置空间?但为什么PCI LOCAL BUS SPECIFICATION从未提及过这个问题?

与此同时,我也对这个表达感到困惑:

  

((reg&amp; 0xF00)&lt;&lt; 16)

使用这种方式生成pci配置地址,我从未在任何书籍或规范中看到过这个表达。

1 个答案:

答案 0 :(得分:4)

这是AMD CPU和芯片组的非标准功能。 AFAIK它无法在英特尔平台上运行。至少从Linux内核代码中我可以理解,可以使用CF8 / CFC IO地址访问扩展配置空间。

patch from AMD

关于((reg&amp; 0xF00)&lt;&lt; 16) - 看起来像AMD用来存储部分地址的CF8配置地址端口的保留位30:24。