|
BIOS知识点滴Follow Bini系列之---系统重启
[复制链接]
本帖最后由 paulhyde 于 2014-9-15 08:55 编辑
1、KBC Reset
这是软件实现的一种重启方法,是AT系统的遗产。此种重启工作顺序为:软件发送0xFE至KBC,KBC收到后发送信息给南桥,南桥下拉CPU INIT# 大约16个PCI Clock让系统重启。代码如下:
- ;----------------------------------------------
- ; 文件名:KBCReset.asm
- ;----------------------------------------------
- ; 2007-12-11 bini.Yi/易祝兵 For teaching
- ;----------------------------------------------
- .386
- .model tiny
- .code
- org 100h
- ;; 如下代码参照 《PC技术内幕》第8章 键盘系统
- START:
- mov bl, 0FEh ; KBC Reset命令
- call keyboard_cmd ; 不应该有返回
- hlt
- IODELAY MACRO
- out 0EDh, al
- ENDM
- ;----------------------------------------------
- ; keyboard_cmd()
- ;----------------------------------------------
- ; 如果由于缓冲区满超时,则 ah 返回非零
- ; 调用 bl = 命令字节
- ; ds = cs
- ;
- ; 返回 如果 ah =0,则成功
- ; 如果 ah =1,则失败
- ;----------------------------------------------
- keyboard_cmd PROC NEAR
- xor cx, cx ; 超时计数器(64K)
- cmd_wait:
- in al, 64h ; 获取控制器状态
- IODELAY
- test al, 2 ; bit1,输入缓冲区满?(控制器是否有数据没处理完)
- jz cmd_send ; 缓冲区空,准备接收命令.
- loop cmd_wait ; 缓冲区满,重试
- jmp cmd_error ; 超时,失败
- cmd_send:
- mov al, bl ; 取 bl 中的命令字节
- out 64h, al ; 发送命令字节
- IODELAY
- xor cx, cx ; 超时计数器(64K)
- cmd_accept:
- in al, 64h ; 获取控制器状态
- IODELAY
- test al, 2 ; bit1,输入缓冲区满?(控制器是否有数据没处理完)
- jz cmd_ok ; 缓冲区空,处理完
- loop cmd_accept ; 缓冲区满,重试
- cmd_error: ; 超时失败
- mov ah, 1 ; 失败返回状态非零
- jmp cmd_exit
- cmd_ok:
- xor ah, ah ; 成功返回零
- cmd_exit:
- ret
- keyboard_cmd ENDP
- END START
复制代码
|
|