配置空間中最重要的有:
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位指令字首):
怎麼列舉pci裝置呢?我們可以嘗試所有的 bus/dev/func 組合,然後判斷得到的廠商id是否為ffffh。下面這個程式就是使用該方法列舉pci裝置的。同時為了便於分析資料,將每個裝置的配置空間資訊儲存到檔案,這樣可以慢慢分析。/* 讀32位埠 */
dword inpd(int portid)
/* 寫32位埠 */
void outpd(int portid, dword dwval)
匯流排編號為0的都是主機板上固有的晶元(主要是南橋),非主機板裝置的典型是——顯示卡。windowsxp的裝置管理器中也可以看到pci資訊。啟動「裝置管理器」,最好將檢視方式設為「依連線檢視裝置(v)」。找到我的顯示卡,雙擊檢視屬性。切換到「詳細資訊」頁,定位組合框為「硬體id」。可看到其中一行為「pci/ven_10de&dev_0110&cc_030000」,表示廠商id為「10de」、裝置id為「0110」、類**為「030000」,與程式得到的結果一致。#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;
}
#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空間主要包括裝置的控制暫存器和狀態暫存器,一般用於控制和查詢裝置的工作狀態以及少量資料的交換。配置空間主要用於向系統提供裝置自身的基...