【我所认知的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这个函数可以做了很多事情哦。这个函数里面我会分几个章节来介绍它所做的工作。

你可能感兴趣的:(汇编,IO,function,table,byte,interface)