差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

cpp:pci:scan_pci [2015/09/03 20:16]
tony [範例]
cpp:pci:scan_pci [2023/06/25 09:48]
行 1: 行 1:
-{{tag>​cpp pci}} 
-====== How to scan PCI device? ====== 
-之前因為修bug,有接觸到與PCI有關的Code,我用容易懂的方式把它紀錄下來。並以一個簡單的範例來教導大家如何去存取PCI Device。 
-===== 原理 ===== 
-根據PCI Spec(我沒翻過),我們可以透過0xfc8(index register)設定要讀取的位置,設定完之後透過0xcfc(data register)去取得資料。\\ 
-要設定給0xfc8的位置,擁有以下意義:\\ 
-<​code>​ 
-31 Enabled 
-30 Reserved 24  
-23 Bus      16  
-15 Device ​  ​11 ​ 
-10 Func     ​8 ​ 
-7  Reg      2 
-1  0 
-0  0 
-</​code>​ 
-PS. PCI裝置都由Bus+Device+Func去辨別 
  
-===== 範例 ===== 
-我們目標是去讀到ICH10 GPIO Base Address。 
-根據[[http://​www.intel.com/​content/​dam/​doc/​datasheet/​io-controller-hub-10-family-datasheet.pdf|ICH10 Spec]], 
-GPIO Base Address在LPC Interface Bridge Registers中,LPC在Bus=0,Devices=31,Fun=0的位置,也就是0x8000F800。 
-而儲存GPIO Base Address在0x8000F800+0x48的位置。因此首先設定0xcf8為0x8000F800+0x48,接著再從0xcfc讀值出來。\\ 
-在Linux下可以這樣做: 
-<code cpp> 
-unsigned long index_reg_addr = 0xcf8; 
-unsigned long data_reg_addr = 0xcfc; 
-// Set address to pci configuration space 
-unsigned long address = 0x8000f800+0x48;​ 
-if(!ioperm(index_reg_addr , 4, 1)){ 
-  outl(index_reg_addr , address); 
-} 
-// Read data 
-unsigned int *result; 
-if(!ioperm(data_reg_addr,​ 4, 1)){ 
-  *result= inl(data_reg_addr);​ 
-} 
-</​code>​ 
-如果要讀不同的PCI Device出來,僅要跑一個for loop,從0x80000000開始,每一個interval加0x800即可。每一次所增加的0x800代表著Device加1。\\ 
-在Windows上可以透過WinIO去存取IO Port。 
-===== Reference ===== 
-  - [[http://​gdemon.blogspot.com/​2008/​07/​pciprobing.html|關於PCI的probing]] 
-  - [[http://​blog.csdn.net/​lightseed/​article/​details/​4219244|【我所認知的BIOS】—>​PCI SCAN]] 
- 
-=====    ===== 
----- 
-\\ 
-~~DISQUS~~