BIOS实战之Super IO-Smart Fan

超级输入输出芯片(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,不要弄反了,这些英文都能看得懂,一个一个去看就行了,具体怎么操作不想记录了,反正就是按着步骤和自己的编程思维来就行。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值