PCI配置空間簡介

2022-02-16 09:51:10 字數 3695 閱讀 8358

配置空間中最重要的有:

vendor id:廠商id。知名的裝置廠商的id。ffffh是乙個非法廠商id,可它來判斷pci裝置是否存在。

device id:裝置id。某廠商生產的裝置的id。作業系統就是憑著 vendor id和device id 找到對應驅動程式的。

class code:類**。共三位元組,分別是 類**、子類**、程式設計介面。類**不僅用於區分裝置型別,還是程式設計介面的規範,這就是為什麼會有通用驅動程式。

irq line:irq編號。pc機以前是靠兩片8259晶元來管理16個硬體中斷。現在為了支援對稱多處理器,有了apic(高階可程式設計中斷控制器),它支援管理24個中斷。

irq pin:中斷引腳。pci有4個中斷引腳,該暫存器表明該裝置連線的是哪個引腳。

如何訪問配置空間呢?可通過訪問0xcf8h、0xcfch埠來實現。

config_address暫存器格式:

31 位: enabled位。

23:16 位: 匯流排編號。

15:11 位: 裝置編號。

10: 8 位:功能編號。

7: 2 位:配置空間暫存器編號。

1: 0 位:恒為「00」。這是因為cf8h、cfch埠是32位埠。

現在有個難題——cf8h、cfch埠是32位埠,可像turbo c之類的16位c語言編譯器都不支援32位埠訪問。怎麼辦?我們可以使用_ _ emit _ _在程式中插入機器碼。每次都_ _ emit _ _一下肯定很麻煩,所以我們應該將它封裝成函式。**如下(注意66h是32位指令字首)

/* 讀32位埠 */

dword inpd(int portid)

/* 寫32位埠 */

void outpd(int portid, dword dwval)

怎麼列舉pci裝置呢?我們可以嘗試所有的 bus/dev/func 組合,然後判斷得到的廠商id是否為ffffh。下面這個程式就是使用該方法列舉pci裝置的。同時為了便於分析資料,將每個裝置的配置空間資訊儲存到檔案,這樣可以慢慢分析。

#include #include typedef unsigned char byte;

typedef unsigned int word;

typedef unsigned long dword;

/* pci裝置索引。bus/dev/func 共16位,為了方便處理可放在乙個word中 */

#define pdi_bus_shift 8

#define pdi_bus_size 8

#define pdi_bus_max 0xff

#define pdi_bus_mask 0xff00

#define pdi_device_shift 3

#define pdi_device_size 5

#define pdi_device_max 0x1f

#define pdi_device_mask 0x00f8

#define pdi_function_shift 0

#define pdi_function_size 3

#define pdi_function_max 0x7

#define pdi_function_mask 0x0007

#define mk_pdi(bus,dev,func) (word)((bus&pdi_bus_max)<>16);

/* class code */

outpd(pci_config_address, dwaddr | 0x8);

dwdata = inpd(pci_config_data);

printf("%6.6lx\t", dwdata>>8);

/* irq/intpin */

outpd(pci_config_address, dwaddr | 0x3c);

dwdata = inpd(pci_config_data);

printf("%d\t", (byte)dwdata);

printf("%d", (byte)(dwdata>>8));

printf("\n");

/* 寫檔案 */

sprintf(szfile, "pci%2.2x%2.2x%x.bin", bus, dev, func);

hf = fopen(szfile, "wb");

if (hf != null)

fclose(hf);}}

}}}return 0;

}

匯流排編號為0的都是主機板上固有的晶元(主要是南橋),非主機板裝置的典型是——顯示卡。windowsxp的裝置管理器中也可以看到pci資訊。啟動「裝置管理器」,最好將檢視方式設為「依連線檢視裝置(v)」。找到我的顯示卡,雙擊檢視屬性。切換到「詳細資訊」頁,定位組合框為「硬體id」。可看到其中一行為「pci/ven_10de&dev_0110&cc_030000」,表示廠商id為「10de」、裝置id為「0110」、類**為「030000」,與程式得到的結果一致。

#include#include#include#include#define pci_max_bus 255

#define pci_max_dev 31

#define pci_max_fun 7

#define pci_base_addr 0x80000000l

#define config_addr 0xcf8

#define config_data 0xcfc

typedef unsigned long dword;

typedef unsigned int word;

int main()

for (bus = 0; bus <= pci_max_bus; bus++)

for (dev = 0; dev <= pci_max_dev; dev++)

for (fun = 0; fun <= pci_max_fun; fun++)

}if (iopl(0) < 0 )

return 0;

}

PCI的配置空間

pci的配置空間 主要討論如何去訪問pci配置空間和描述pci裝置的配置空間的定義和使用規則。理論上如何訪問pci配置空間的問題是屬於匯流排操作的一部分,但是和配置空間有著密切聯絡,有必要一起討論。下圖是pci架構的級聯圖。不同的bus就是通過bridge來連線的。每個pci bus上都可以掛載多個...

PCI配置空間讀取

1.拼湊出32位位址 bus有8位,dev有5位,fun有3位,最高位bit位為使能。最高位要置1,也就是bit31置1,bit23 16是寫入bus number,bit15 11是device number,bit10 8是寫入function number.如果要訪問pci裝置中bus num...

PCI裝置配置空間問題

pc機中包括三種空間 儲存器空間 i o空間 配置空間。儲存器空間主要包括記憶體 視訊記憶體 擴充套件rom 裝置緩衝區等,一般用於存放大量資料和進行資料塊交換。i o空間主要包括裝置的控制暫存器和狀態暫存器,一般用於控制和查詢裝置的工作狀態以及少量資料的交換。配置空間主要用於向系統提供裝置自身的基...