PCIe配置空间和PCI设备中的寄存器

1、访问PCI配置空间,PCI基本配置空间的读写使用下列函数: 原型定义在<linux/pci.h>

int pci_read_config_byte(struct pci_dev *pdev, int where, u8 *val);
int pci_read_config_word(struct pci_dev *pdev, int where, u8 *val);
int pci_read_config_dword(struct pci_dev *pdev, int where, u8 *val);
通过8位、16位或32位的数据传输访问配置空间。
从由pdev标识的设备空间读入一个、两个或四个字节的数据。
参数where是从配置空间起始位置计算的字节偏移量。
从配置空间获得的值通过指针val返回。
函数本身的返回值是错误代码。
int pci_write_config_byte(struct pci_dev *pdev, int where, u8 *val);
int pci_write_config_word(struct pci_dev *pdev, int where, u8 *val);
int pci_write_config_dword(struct pci_dev *pdev, int where, u8 *val);
向由pdev标识的设备配置空间写入一个、两个或四个字节。
where是偏移量
指针val是要写入的值

2、访问PCI设备的IO或内存空间。

     一个PCI设备可实现多达6个IO基地址寄存器,每个寄存器可以是内存地址也可以是IO地址。

     PCI配置空间中的6个基地址寄存器,每个都为32位,它们代表PCI的6个IO区域。在linux内核中,PCI设备的IO区域已被集成到通用资源管理,所以要想获得PCI设备的基地址在存储器域的物理地址,要通过下面的函数:

unsigned long pci_resource_start(struct pci_dev *pdev, int bar);
该函数返回6个PCI IO区域中的第bar个的基地址值(存储器域的物理地址)。bar代表基地址寄存器(base address register),取值为0到5.

unsigned long pci_resource_start(struct pci_dev *pdev, int bar);
该函数返回6个PCI IO区域中的第bar个的尾地址值(存储器域的物理地址)。bar代表基地址寄存器(base address register),取值为0到5.
// 将存储器域的物理地址映射为虚拟地址;
// mem = ioremap(phymem, pci_resource_len(pdev, 0));
void *ioremap(unsigned long phys_addr, unsigned long size)
3、PCI基本配置空间

PCIe配置空间和PCI设备中的寄存器

这样就可以完成配置空间的访问,而且通过PCI配置空间中的6个基地址寄存器,我们可以在CPU侧通过MEM读写访问PCIE设备。