超级输入输出芯片(SIO)一般位于主板左下方或者左上方。主要使用的芯片有Winbond、ITE,它为主板上的标准I/O接口提供控制处理功能。
Super这里所说的“超级”是指它集成了PS/2键盘、PS/2鼠标、串口COM、并口LPT接口等处理功能,而这些接口都是计算机中的慢速I/O设备。它们全部位于主板后部右边。它的主要功能包括负责处理从键盘、鼠标、串行接口等设备传输来的串行数据,将它们转换成为并行数据,同时也负责并行接口、软驱接口数据的传输与处理。
SIO芯片通过LPC连接在南桥,台式机主板EC ROM 挂载在SIO下,所以LPC初始化的时候要包含SIO的初始化和EC的初始化,当然现在先不说这个,现在主要讲怎么实现SIO的初始化,它的初始化意味着SIO下的PS/2键盘、串口、并口、以及通过一些LED、Beep、风扇控制等等。下面就smart fan 为例子,看下SIO的运行流程(ITE8738)。
1、 可以在Spec里面搜PnP Mode找到基地址,Address Port一般是2E,Data Port 一般是2F,如果有RW工具的话,可以进入IO Space,输入地址2E,然后在0x00位置依次输入(87h, 01h, 55h, 55h),进入MB PnP 模式。可能你发现你每输一个,它会自动变为0xff,不要以为没生效,其实它已经进入PnP Mode了。比如你输玩87h,确定后,马上变回00,不要慌,继续输入01h确定。
2、使能 EC(LDN=04h, Index 30h=01)通过看SPEC,可以发现逻辑设备选择寄存器是07h,它的逻辑设备号是04h,这时候,进入IO Space,输入2E,在控制寄存器2E地址即0x00位置输入07h,然后在数据寄存器2F地址即0x01位置输入04h,在控制寄存器2E地址即0x00位置输入30h,在数据寄存器2F地址即0x01位置输入01h,使EC生效。
Environment Controller Configuration Registers (LDN=04h)
Environment Controller Activate (Index=30h, Default=00h)
Bit Description:
7-1 Reserved
0 Environment Controller Enable
1: Enable
0: Disable
This is a read/write register
3、得到EC Base Address,可以从SPEC中看出,基地址是需要从60h,61h寄存器读出来的,60h是高八位,61h是低八位,合起来就是基地址base。然后我们的EC控制器的地址端口地址就是base+05h,数据端口就是base+06h。
基地址由逻辑设备寄存器确定(index=60h, 61h)。地址端口(Base+05h),数据端口(Base+06h)。
4、Smart Fan逻辑配置。
5、 退出MB PnP 模式(index=02h,default=02h)这个也可以在SPEC里面看到,这个退出PnP Mode在2E/2F端口里面的02h部分设置为01h。
至此,风扇控制就完毕了。
看下部分的代码怎么写的(包含库就不写了),功能不是smartfan,只是将风扇转速开到了最大。
static unsigned char linux_inb(unsigned long port)
{
return (*(volatile unsigned char *)(0x90000efdfc000000 + port));
}
#define linux_outb(port,val) \
do {\
*(volatile unsigned char *)(0x90000efdfc000000 + (port)) = (val); \
}
while(0)
void EnterCOonfigMode(void)
{
linux_outb(0x2E, 0x87);
linux_outb(0x2E, 0x01);
linux_outb(0x2E, 0x55);
linux_outb(0x2E, 0x55);
return;
}
void ExitConfigMode (void)
{
UINT8 RegData = 0x00;
linux_outb (0x2E, 0x02);
RegData = linux_inb (0x2F) | BIT1;
linux_outb (0x2E, 0x02);
linux_outb (0x2F, RegData);
return;
}
void SmartFanFunction(void)
{
UINT16 addr;
UINT8 base1,base2;
UINT8 fandata1,fandata2;
EnterConfigMode();
//LDN Selection
linux_outb(0x2E,0x07);
linux_outb(0x2F,0x04);
//Enable Environment Controller
linux_outb(0x2E,0x30);
linux_outb(0x2F,0x01);
//Get BaseAddress 0x290
linux_outb(0x2E,0x60);
base1=linux_inb(0x2F);
DEBUG((EFI_D_INFO, "base1: 0x%x\n", base1));
linux_outb(0x2E,0x61);
base2=linux_inb(0x2F);
DEBUG((EFI_D_INFO, "base2: 0x%x\n", base2));
addr=(base1<<8&0xFF00)|base2;
DEBUG((EFI_D_INFO, "GetFanBaseAddress: 0x%x\n", addr));
//Open ON/OFF mode
linux_outb(addr+5,0x13);
fandata1=linux_inb(addr+6);
DEBUG((EFI_D_INFO, "fandata1: 0x%x\n", fandata1));
linux_outb(addr+6,0x00);
//Open ON control and FAN_CTL polarity high
linux_outb(addr+5,0x14);
fandata2=linux_inb(addr+6);
DEBUG((EFI_D_INFO, "fandata2: 0x%x\n", fandata2));
linux_outb(addr+6,0x87);
ExitConfigMode();
}
void main()
{
SmartFanFunction();
return;
}
--------------2022年2月28日22:26:05-----------------
接之前的beep和LED,这次准备深入Smart fan的功能实现,首先需要理解,这个smart fan的运作机制,它就是监控机器的温度,然后根据温度的不同,对风扇的转速进行调节,根据文档,我们找到9.5节,其实大多数都是为这个smart fan开辟的IO space。
下面的位置就是操作smart fan需要用到的
每个寄存器都有相应的描述:
这里2-0对应3-1,6-4对应3-1,不要弄反了,这些英文都能看得懂,一个一个去看就行了,具体怎么操作不想记录了,反正就是按着步骤和自己的编程思维来就行。