谁帮详细解释所有发给ec的60/64命令号码和意义
bini殇,能帮详细解释一下bios post过程中的所有发给ec的60/64命令号码和意义吗?数据量比较大,截不住。 转个别人发的,不知道LZ能不能用上:)4.2.7 Command
通过8042芯片,可以:
向8042芯片发布命令(通过64h),并通过60h读取命令的返回结果(如果有的话),或通过60h端口写入命令所需的数据(如果需要的话)。
读取Status Register的内容(通过64h);
向8048发布命令(通过60h);
读取来自于Keyboard的数据(通过60h)。这些数据包括Scan Code(由按键和释放键引起的),对8048发送的命令的确认字节(ACK)及回复数据。
再次强调一遍,Command(命令)分为发送给8042芯片的命令和发送给8048的命令。它们是不相同的,并且使用的端口也是不相同的(分别为64h和60h)。
* 64h端口(读操作)
对64h端口进行读操作,会读取Status Register的内容。
inb %0x64
执行这个指令之后,AL寄存器中存放的就是Status Register的内容。
* 64h端口(写操作)
向64h端口写入的字节,被认为是对8042芯片发布的命令(Command):
Ÿ
写入的字节将会被存放在Input Register中;
Ÿ
同时会引起Status Register的Bit-3自动被设置为1,表示现在放在Input Register中的数据是一个Command,而不是一个Data;
Ÿ
在向64h端口写某些命令之前必须确保键盘是被禁止的,因为这些被写入的命令的返回结果将会放到Output Register中,而键盘如果不被禁止,则也会将数据放入到Output Register中,会引起相互之间的数据覆盖;
Ÿ
在向64h端口写数据之前必须确保Input Register是空的(通过判断Status Register的Bit-1是否为0)。
void wait_input_empty(void)
{
char __b;
do{
__b = inb(0x64);
}while(!(__b&0x02));
}
void disable_keyboard(void)
{
wait_input_empty();
outb(0x64, 0xAD);
}
* 60h端口(读操作)
对60h端口进行读操作,将会读取Output Register的内容。Output Register的内容可能是:
Ÿ 来自于8048的数据。这些数据包括Scan Code,对8048发送的命令的确认字节(ACK)及回复数据。
Ÿ 通过64h端口对8042发布的命令的返回结果。
在向60h端口读取数据之前必须确保Output Register中有数据(通过判断Status Register的Bit-0是否为1)。
void wait_output_full(void)
{
char __b;
do{
__b = inb(0x64);
}while(__b&0x01);
}
unsigned char read_output(void)
{
wait_output_full();
return inb(0x60);
}
* 60h端口(写操作)
向60h端口写入的字节,有两种可能:
1.如果之前通过64h端口向8042芯片发布的命令需要进一步的数据,则此时写入的字节就被认为是数据;
2.否则,此字节被认为是发送给8048的命令。
在向60h端口写数据之前,必须确保Input Register是空的(通过判断Status Register的Bit-1是否为0)。
4.2.7.1 发给8042的命令
* 20h
准备读取8042芯片的Command Byte;其行为是将当前8042 Command Byte的内容放置于Output Register中,下一个从60H端口的读操作将会将其读取出来。
unsigned char read_command_byte(void)
{
wait_input_empty();
outb(0x64,0x20);
wait_output_full();
return inb(0x60);
}
* 60h
准备写入8042芯片的Command Byte;下一个通过60h写入的字节将会被放入Command Byte。
void write_command_byte(unsigned char command_byte)
{
wait_input_empty();
outb(0x64,0x60);
wait_input_empty();
outb(0x60,command_byte);
}
* A4h
测试一下键盘密码是否被设置;测试结果放置在Output Register,然后可以通过60h读取出来。测试结果可以有两种值:FAh=密码被设置;F1h=没有密码。
bool is_set_password(void)
{
wait_input_empty();
outb(0x64,0xA4);
wait_output_full();
return inb(0x60)==0xFA?true:false;
}
* A5h
设置键盘密码。其结果被按照顺序通过60h端口一个一个被放置在Input Register中。密码的最后是一个空字节(内容为0)。
void set_password(unsigned char* password)
{
char* p = password;
if(p == NULL)
return;
wait_input_empty();
outb(0x64,0xA5);
do{
wait_input_empty();
outb(0x60, *p);
}while(*p++ != 0);
}
* A6h
让密码生效。在发布这个命令之前,必须首先使用A5h命令设置密码。
void enable_password(void)
{
if(!is_set_password())
return;
wait_input_empty();
outb(0x64,0xA6);
}
* AAh
自检。诊断结果放置在Output Register中,可以通过60h读取。55h=OK。
bool is_test_ok(void)
{
wait_input_empty();
outb(0x64,0xAA);
wait_output_full();
return inb(0x60)==0x55?true:false;
}
* ADh
禁止键盘接口。Command Byte的bit-4被设置。当此命令被发布后,Keyboard将被禁止发送数据到Output Register。
void disable_keyboard(void)
{
wait_input_empty();
outb(0x64,0xAD);
}
* AEh
打开键盘接口。Command Byte的bit-4被清除。当此命令被发布后,Keyboard将被允许发送数据到Output Register。
void enable_keyboard(void)
{
wait_input_empty();
outb(0x64,0xAE);
}
* C0h
准备读取Input Port。Input Port的内容被放置于Output Register中,随后可以通过60h端口读取。
unsigned char read_input_port(void)
{
wait_input_empty();
outb(0x64,0xC0);
wait_output_full();
return inb(0x60);
}
* D0h
准备读取Outport端口。结果被放在Output Register中,随后通过60h端口读取出来。
unsigned char read_output_port(void)
{
wait_input_empty();
outb(0x64,0xD0);
wait_output_full();
return inb(0x60);
}
* D1h
准备写Output端口。随后通过60h端口写入的字节,会被放置在Output Port中。
void write_output_port(unsigned char __c)
{
wait_input_empty();
outb(0x64,0xD1);
wait_input_empty();
outb(0x60,__c);
}
* D2h
准备写数据到Output Register中。随后通过60h写入到Input Register的字节会被放入到Output Register中,此功能被用来模拟来自于Keyboard发送的数据。如果中断被允许,则会触发一个中断。
void put_data_to_output_register(unsigned char __data)
{
wait_input_empty();
outb(0x64,0xD2);
wait_input_empty();
outb(0x60,__c);
}
4.2.7.2 发给8048的命令
* EDh
设置LED。Keyboard收到此命令后,一个LED设置会话开始。Keyboard首先回复一个ACK(FAh),然后等待从60h端口写入的LED设置字节,如果等到一个,则再次回复一个ACK,然后根据此字节设置LED。然后接着等待。。。直到等到一个非LED设置字节(高位被设置),此时LED设置会话结束。
* EEh
诊断Echo。此命令纯粹为了检测Keyboard是否正常,如果正常,当Keyboard收到此命令后,将会回复一个EEh字节。
* F0h
选择Scan code set。Keyboard系统共可能有3个Scan code set。当Keyboard收到此命令后,将回复一个ACK,然后等待一个来自于60h端口的Scan code set代码。系统必须在此命令之后发送给Keyboard一个Scan code set代码。当Keyboard收到此代码后,将再次回复一个ACK,然后将Scan code set设置为收到的Scan code set代码所要求的。
* F2
读取Keyboard ID。由于8042芯片后不仅仅能够接Keyboard。此命令是为了读取8042后所接的设备ID。设备ID为2个字节,Keyboard ID为83ABh。当键盘收到此命令后,会首先回复一个ACK,然后,将2字节的Keyboard ID一个一个回复回去。
* F3h
设置Typematic Rate/Delay。当Keyboard收到此命令后,将回复一个ACK。然后等待来自于60h的设置字节。一旦收到,将回复一个ACK,然后将Keyboard Rate/Delay设置为相应的值。
* F4h
清理键盘的Output Buffer。一旦Keyboard收到此命令,将会将Output buffer清空,然后回复一个ACK。然后继续接受Keyboard的击键。
* F5h
设置默认状态(w/Disable)。一旦Keyboard收到此命令,将会将Keyboard完全初始化成默认状态。之前所有对它的设置都将失效——Output buffer被清空,Typematic Rate/Delay被设置成默认值。然后回复一个ACK,接着等待下一个命令。需要注意的是,这个命令被执行后,键盘的击键接受是禁止的。如果想让键盘接受击键输入,必须Enable Keyboard。
* F6h
设置默认状态。和F5命令唯一不同的是,当此命令被执行之后,键盘的击键接收是允许的。
* FEh
Resend。如果Keyboard收到此命令,则必须将刚才发送到8042 Output Register中的数据重新发送一遍。当系统检测到一个来自于Keyboard的错误之后,可以使用自命令让Keyboard重新发送刚才发送的字节。
* FFh
Reset Keyboard。如果Keyboard收到此命令,则首先回复一个ACK,然后启动自身的Reset程序,并进行自身基本正确性检测(BAT-Basic Assurance Test)。等这一切结束之后,将返回给系统一个单字节的结束码(AAh=Success, FCh=Failed),并将键盘的Scan code set设置为2。 好贴!
非常详细!
谢谢! 2楼好帖!在helppc的Hardware Data and Specifications栏里有相应的寄存器和命令详细描述。
我的问题是,上述描述应该是针对老的8042的,在目前的使用EC的系统中,这些status register和command描述在哪个文档中可以找到?比如intel的santarosa,使用renessas的H8s 2104 EC,按道理上述状态寄存器,命令等的描述应该在2104 datasheet里,但是我怎么找都没有。还是有某个spec定义了这些命令格式?新手问题,高手莫笑:(
页:
[1]