戏说BIOS之Clock Generator
1. Introduction
Clock Generator是主板上面一颗极为重要的IC,说它极为重要一点都不为过,因为Clock generator负责提供主板上的clock, 一旦Clock Generator除了问题,板子基本上就完蛋了。Clock generator供给的clock部件有CPU clock,PCI clock,AGP clock,PCIE clock,SATA clock,USB clock等。
2. How to work?
Clock generator 是一颗IC,它有一颗外接晶振,内部会有锁相环放大调整电路,可以将外接的晶振产生的clock放大调整然后再分频输出到各个外围器件和总线,提供器件和总线工作所需的clock。Clock generator的工作原理如下图1所示:
Clock generator通常是一个smbus device,接在SB的smbus controller上所以通过SB的smbus controller,使用标准的smbus protocol就可以存取Clock generator上的configure data从而达到配置各个外围器件Clock的目的。鉴于clock generator的重要性,所以BIOS在非常早的阶段就会配置它(boot block阶段),让CPU memory等的工作有一个稳定的clock。下面我就以VIA平台为例演示Clock generator读取过程:
下述code演示了获得smbus contoller base address的过程:
;----------------------------------------------------------------------------
; get smbus base address
; used registers:eax,edx
; called with: NULL
;-----------------------------------------------------------------------------
get_smbus_bar proc near
push edx
push eax
mov dx,PCI_CFG_ADD
mov eax,PCI_SMBUS_ADD
out dx,eax
mov dx,PCI_CFG_DAT
in eax,dx
and eax,0FFFEh
mov SMBUS_REG_BAR,ax
pop eax
pop edx
ret
get_smbus_bar endp
下面的code演示使用read block protocol读取clock generator configure
data的过程:
;----------------------------------------------------------------------------
; read via clock gen data by read block protocol
; called with: NULL
; used registers: ax,dx,bx,cx
;-----------------------------------------------------------------------------
read_via_smbus_block proc near
push dx
push cx
push bx
push ax
call get_smbus_bar
;reset host status registers
mov dx,SMBUS_REG_BAR
or dl,SMBUS_HSTS_REG;(00h)
mov al,05eh
out dx,al
;set smbus slave address
mov dx,SMBUS_REG_BAR
or dl,SMBUS_HADD_REG
mov al,SLAVE_ADDRESS
or al,01h
out dx,al
call io_delay
;clear smbus status
mov dx,SMBUS_REG_BAR
or dl,SMBUS_HSTS_REG;(00h)
mov al,05eh
out dx,al
call io_delay
;clear smbus command byte
mov dx,SMBUS_REG_BAR
or dl,SMBUS_HCMD_REG;(03h)
mov al,00h
out dx,al
;block read protocol
mov dx,SMBUS_REG_BAR
or dl,SMBUS_HCTL_REG;(02h)
mov al,54h
out dx,al
call io_delay
;wait for smbus finished
mov dx,SMBUS_REG_BAR
or dl,SMBUS_HSTS_REG;(00h)
rvsb_wait_smbus_fi:
in al, dx
call io_delay
test al, 01h
jnz rvsb_wait_smbus_fi
;read data count
mov dx,SMBUS_REG_BAR
or dl,SMBUS_HDA0_REG
in al,dx
;read data from smbus block data
mov cl,14h
mov bx,offset REGSTR
rvsb_read_data:
mov dx,SMBUS_REG_BAR
or dl,SMBUS_BLKDA_REG
in al,dx
call hex2asc
dec cl
inc bx
inc bx
cmp cl,01h
jae rvsb_read_data
pop ax
pop bx
pop cx
pop dx
ret
read_via_smbus_block endp
下图2演示ClockGen.exe运行时的状况:
图 2
ClockGen.asm只演示了VIA platforma + ICS9UM700的dump过程,至于其它的平台,有兴趣的朋友可以如法炮制。那么这只tool可不可以做成通用的呢?当然可以,只要从PCI configure space读出Vendor id识别出平台然后再根据具体的平台spec去获取smbus controller bar(可能要多看几份spec了J)然后就可以操作smbus了,clock generator slave address可以让用户输入(我看到的几个都是42h,但是也会有特例)。我比较懒,有兴趣的朋友可以试着完善它。最后依旧是开放完整的source code和可执行文件供有兴趣的朋友下载。
Enjoy it!
That’s all!
Peter