【我所認知的BIOS】->反彙編BIOS之Bootblock(3)

【我所認知的BIOS->反彙編BIOSBootblock(3)

--initialize some chipset register

By Lightseed

5/13/2010

在上一篇中,我和大家探討了下面代碼中的BT_CPU_Init這個函數,它主要是一些特殊CPUmicro codeupdate。那麼我們繼續往下走,就會發現初始化chipset寄存器的函數,如_F000:E1C3這行所示。這裏是用ROM_CALL來調用的。

_F000:E1B8       mov    sp, 0E1BEh       ; First Use ROM_CALL

_F000:E1BB       jmp    BT_CPU_Init       ; Save esp (Return    Address)

_F000:E1BB ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

_F000:E1BE       dw 0E1C0h

_F000:E1C0 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

Call    Chipset_Reg_Init_Early ;僞代碼

Chipset_Reg_Init_Early函數的代碼要反彙編也很容易啦,雙擊或者是點中它回車即可。反彙編並加註如下:

; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

_F000:F600

_F000:F600 Chipset_Reg_Init_Early:        ; CODE XREF:   _F000:E1C3j

_F000:F604       mov    si, 0F6DCh        ; Get the chipset register initial table offset

_F000:F607

_F000:F607 Init_Chipset_Ren_loop:         ; CODE XREF:   _F000:F629j

_F000:F607       mov    cx, cs:[si]       ; Get the DEV#,FUNC#,REG#

Call    Get_Pci_Byte     ; ROM_CALL to get byte from chipset.僞代碼,取回值存在AL

_F000:F612       and    al, cs:[si+2]

_F000:F616       or     al, cs:[si+3]

Call    Set_Pci_byte      ;僞代碼

_F000:F622       add    si, 4

_F000:F625       cmp    si, 0F740h        ; Is   init table end?

_F000:F629       jnz    Init_Chipset_Ren_loop ; No, go on looping

上面這個函數其實註釋已經把90%的內容都說清楚了,不過我還是要再強調一下其中的一點,在_F000:F604中,是爲了找到一個table。在這個table中存放着一系列的寄存器的地址以及BIOS需要initialize的值。我詳細加註如下:

Chipset_Reg_Init_table dw 0F01Ch   ; Bus 0# Dev  30#, Func 0#, Reg 1CH .PCI to PCI bridge  register 1ch

_F000:F6DE       db  0 ;          ; Clear all bit

_F000:F6DF       db  10h ;         ; Set the IO   base is    10h, it    means base address is 1000h

_F000:F6DF                  ;

_F000:F6E0       dw 0F004h         ; Bus 0# Dev   30#, Func 0#, Reg 1CH .PCI to PCI bridge  register 04h

_F000:F6E2       db  0 ;          ; Clear all bits

_F000:F6E3       db  1 ;          ; I/O space enable

_F000:F6E3                  ;

_F000:F6E4       dw 0FB20h         ; Bus 0# Dev   31#, Func 3#, Reg 20H .  SMBUS controller register 20h

_F000:F6E6       db  0 ; 

_F000:F6E7       db  0 ;          ; The low byte of SMBUS controller base address is 0h

_F000:F6E7                  ;

_F000:F6E8       dw 0FB21h         ; Bus 0# Dev   31#, Func 3#, Reg 21H .  SMBUS controller register 21h

_F000:F6EA       db  0 ; 

_F000:F6EB       db  50h ; P       ; The high byte of SMBUS controller base address is 50h,

_F000:F6EB                          ; So   we can know the   SMBUS base address is 5000h on the platform.

_F000:F6EC       dw 0FB40h         ; Bus 0# Dev   31#, Func 3#, Reg 40H .  SMBUS controller register 40h

_F000:F6EE       db  0 ; 

_F000:F6EF       db  1 ;          ; Enable SMBUS host controller

_F000:F6EF                  ;

_F000:F6F0       dw 0FB04h         ; Bus 0# Dev   31#, Func 3#, Reg 4H . SMBUS controller    register 4h

_F000:F6F2       db  0 ; 

_F000:F6F3       db  3 ;          ; SM    bus  Memory and   IO space enable

_F000:F6F3                  ;

_F000:F6F4       dw 0F841h         ; Bus 0# Dev   31#, Func 0#, Reg 41H .  LPC interface bridge register 41h

_F000:F6F4                          ; ACPI IO base address reg

_F000:F6F6       db  0 ; 

_F000:F6F7       db  40h ; @       ; ACPI io base address is 4000h

_F000:F6F7                  ;

_F000:F6F8       dw 0F844h         ; Bus 0# Dev   31#, Func 0#, Reg 44H .  LPC interface bridge register 44h

_F000:F6FA       db  0 ; 

_F000:F6FB       db  80h ;        ; Decode of the I/O range pointed to   by the ACPI base register is enabled, and the ACPI power

_F000:F6FB                          ; management  function is enabled.

_F000:F6FB                          ;

_F000:F6FC       dw 0F848h         ; Bus 0# Dev  31#, Func 0#, Reg 48H .  LPC interface bridge register 48h

_F000:F6FC                          ; low byte of GPIO base address

_F000:F6FE       db  0 ; 

_F000:F6FF       db  80h ;        ; The low byte of GPIO base is 80h

_F000:F6FF                  ;

_F000:F700       dw 0F849h         ; Bus 0# Dev  31#, Func 0#, Reg 49H .  LPC interface bridge register 49h

_F000:F700                          ; High byte of GPIO base address

_F000:F702       db  0 ; 

_F000:F703       db  40h ; @          ; High byte of GPIO base address is 40h, So GPIO base add is  4080h

_F000:F703                  ;

_F000:F704       dw 0F84Ch         ; Bus 0# Dev   31#, Func 0#, Reg 4cH .  LPC interface bridge register 4ch

_F000:F704                          ; GPIO Control Register

_F000:F706       db  0 ; 

_F000:F707       db  10h ;         ; Enables decode of the I/O range pointed to  by the

_F000:F707                          ; GPIO Base Address register    (D31:F0:48h) and enables the GPIO function

_F000:F708       dw 0F864h         ; Bus 0# Dev   31#, Func 0#, Reg 64H .  LPC interface bridge register 64h

_F000:F708                          ; Serial IRQ  Control    Register

_F000:F70A       db  0 ; 

_F000:F70B       db 0C0h ; ?       ; Enable serial IRQ and set it in continuous  mode

_F000:F70B                  ;

_F000:F70C       dw 0F8D9h         ; Bus 0# Dev   31#, Func 0#, Reg D9H .  LPC interface bridge registerD9h

_F000:F70C                          ; Firmware Hub Decode Enable    Register

_F000:F70E       db  0 ; 

_F000:F70F       db 0C0h ; ?       ; Enable decoding F000

_F000:F70F                  ;

_F000:F710       dw 0F8DCh         ; Bus 0# Dev   31#, Func 0#, Reg DCH .  LPC interface bridge registerDCh

_F000:F710                          ; bios controller Register

_F000:F712       db  0 ; 

_F000:F713       db  0 ;          ; Setting the BIOSWE  will not cause SMIs

_F000:F713                          ; Only read cycles result in    Firmware Hub I/F cycles.

_F000:F714       dw 0F8B8h         ; Bus 0# Dev   31#, Func 0#, Reg B8H .  LPC interface bridge register B8h

_F000:F714                          ; GPI Routing control Register

_F000:F716       db  0 ; 

_F000:F717       db  55h ; U          ; GPI 0 SMI

_F000:F717                  ;

_F000:F718       dw 0F8B9h

_F000:F71A       db  0 ; 

_F000:F71B       db  55h ; U          ; GPI 1 SMI

_F000:F71B                  ;

_F000:F71C       dw 0F8BAh

_F000:F71E       db  0 ; 

_F000:F71F       db  55h ; U          ; GPI 2 SMI

_F000:F71F                  ;

_F000:F720       dw 0F8BBh

_F000:F722       db  0 ; 

_F000:F723       db  55h ; U          ; GPI 3 SMI

_F000:F723                  ;

_F000:F724       dw 0F885h         ; Bus 0# Dev  31#, Func 0#, Reg 85H .  LPC interface bridge register 85h

_F000:F724                          ; LPC I/F Generic Decode Range 1 Register

_F000:F726       db  0 ; 

_F000:F727       db  4 ;          ; The high byte of decode range base   address

_F000:F727                  ;

_F000:F728       dw 0F884h

_F000:F72A       db  0 ; 

_F000:F72B       db  81h ; ?       ; The low byte of decode range base address,  So decode range  is (480h-500h)

_F000:F72B                          ; bit 0 : Enable the GEN1 I/O range to be forwarded to the LPC I/F

_F000:F72B                          ;

_F000:F72C       dw 0F889h

_F000:F72E       db  0 ; 

_F000:F72F       db  2 ; 

_F000:F730       dw 0F888h

_F000:F732       db  0 ; 

_F000:F733       db  91h ; ?       ; The low byte of decode range base address,  So decode range  is (290h-3100h)

_F000:F733                          ; bit 0 : Enable the GEN1 I/O range to be forwarded to the LPC I/F

_F000:F733                          ;

_F000:F734       dw 0F882h         ; Bus 0# Dev  31#, Func 0#, Reg 82H .  LPC interface bridge register 82h

_F000:F734                          ; LPC I/F Enables Register

_F000:F736       db  0 ; 

_F000:F737       db  8 ;          ;  Enable Floppy Drive

_F000:F737                  ;

_F000:F738       dw 0F883h         ; Bus 0# Dev   31#, Func 0#, Reg 83H .  LPC interface bridge register 83h

_F000:F738                          ; LPC I/F Enables Register

_F000:F73A       db  0 ; 

_F000:F73B       db  34h ; 4       ; Enable KBC,micro controller2, Super io decode

_F000:F73B                          ;

_F000:F73C       dw 0F881h         ; Bus 0# Dev   31#, Func 0#, Reg 81H .  LPC interface bridge register 81h

_F000:F73C                          ; I/O Decode  Ranges Register

_F000:F73E       db 0EFh ; ?       ; FDD use 3F0h

_F000:F73F       db  0 ; 

_F000:F740 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

我想有了這個table的加註,去理解怎麼初始化這些寄存器的話,應該不是難事了。

我們再來看看,其實在這個函數裏,邏輯都很簡單,只是對HW的操作比較具體,所以需要對照SPEC來看看。着重要說的一個是Get_Pci_Byte這個函數,這個函數我們可以從上面的代碼中看出,它的輸入參數是CX,而CX裏面存的是pcidevice No. function No.register No.但是卻沒包含BUS No.原因是爲什麼呢?讓我們跟如到裏面去看看究竟。

(關於這段反匯編出來的code,其實很簡單的。不過考慮到不太方便,所以您自己根據自己反匯編出來的code再研究吧。大致就是不需要輸入BUS number就可以訪問PCI設備的配置空間了。因爲南橋原本就是在bus 0上。)

我們來看看_F000:F76F這行,這是對即將要訪問的PCI BUS No.的賦值,很明顯是直接給了0,從此我們也可以推測出,Get_Pci_Byte這個函數是且僅僅是訪問PCI BUS 0#上的PCI device 設備。(再擴展一下,其實就是North bridgeSouth bridge兩個芯片裏的各個PCI device了。)而且還可以知道,CXbit 0~7是要訪問的register number等等,和PCI spec裏面的那個map是對應的。

至此關於Chipset的一些些(爲什麼說一些些呢?因爲還有很多寄存器馬上還要繼續初始化,從

_F000:F6A6       mov    bx, 0F6ACh        ; There do not use ROM_CALL

_F000:F6A9       jmp    Other_Register_Init

這兩行中Other_Register_Init跟進去看。)寄存器初始化就算告一段落了。

呵呵。。。預先提醒一下大家,Other_Register_Init這個函數可以做了很多事情哦。這個函數裏面我會分幾個章節來介紹它所做的工作。

發佈了61 篇原創文章 · 獲贊 11 · 訪問量 77萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章