Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux kernel 关于访问pci配置空间,宏pci\u CONF1\u地址让我感到困惑_Linux Kernel_Pci_Pci Bus - Fatal编程技术网

Linux kernel 关于访问pci配置空间,宏pci\u CONF1\u地址让我感到困惑

Linux kernel 关于访问pci配置空间,宏pci\u CONF1\u地址让我感到困惑,linux-kernel,pci,pci-bus,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, r

我正在学习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;
}
/*
*用于访问PCI基本数据(前256字节)和扩展数据的函数
*(每个PCI函数4096字节)类型为1的配置空间
*访问。
*/
#定义PCI_CONF1_地址(总线、devfn、寄存器)\
(0x8000000 |((注册号&0xF00)4095)){
*值=-1;
返回-艾因瓦尔;
}
自旋锁irqsave(&pci配置锁,标志);
outl(PCI_CONF1_地址(总线、devfn、寄存器),0xCF8);
开关(透镜){
案例1:
*值=inb(0xCFC+(reg&3));
打破
案例2:
*值=inw(0xCFC+(注册号&2));
打破
案例4:
*值=inl(0xCFC);
打破
}
自旋解锁irqrestore(&pci配置锁定,标志);
返回0;
}
内核版本是2.6.18,所以宏PCI_CONF1_地址让我感到困惑。如您所知,当使用IO端口CF8/CFC时,它只能访问pci配置空间的前256字节,如果要访问256~4095字节之间的空间,必须使用ECAM(增强配置访问机制),但上面的注释说明:

扩展(每个PCI函数4096字节)配置空间,具有类型1访问

这是否意味着在使用IO端口CF8/CFC时,它可以访问pci配置空间的所有4096字节?但是为什么PCI本地总线规范从来没有提到这一点

同时,我也对这句话感到困惑:


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


关于((reg&0xF00)这是AMD CPU和芯片组的非标准功能。AFAIK它在Intel平台上不起作用。至少从Linux内核代码中我可以理解,使用CF8/CFC IO地址访问扩展配置空间是可能的

关于((reg&0xF00)