PCIe配置空間和PCI裝置中的暫存器
阿新 • • 發佈:2019-01-04
1、訪問PCI配置空間,PCI基本配置空間的讀寫使用下列函式: 原型定義在<linux/pci.h>
int pci_read_config_byte(struct pci_dev *pdev, intwhere, u8 *val);
int pci_read_config_word(struct pci_dev *pdev, intwhere, u8 *val);
int pci_read_config_dword(struct pci_dev *pdev, intwhere, u8 *val); 通過8位、16位或32位的資料傳輸訪問配置空間。 從由pdev標識的裝置空間讀入一個、兩個或四個位元組的資料。 引數where是從配置空間起始位置計算的位元組偏移量。 從配置空間獲得的值通過指標val返回。 函式本身的返回值是錯誤程式碼。
int pci_write_config_byte(struct pci_dev *pdev, intwhere, u8 *val); int pci_write_config_word(struct pci_dev *pdev, intwhere, u8 *val); int pci_write_config_dword(struct pci_dev *pdev, intwhere, 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(structpci_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基本配置空間
這樣就可以完成配置空間的訪問,而且通過PCI配置空間中的6個基地址暫存器,我們可以在CPU側通過MEM讀寫訪問PCIE裝置。