SuperIo的调试
SuperIo简称SIO,是一款Lpc设备芯片,支持多接口扩展.
文章目录
- SuperIo的调试
- SIO 包含哪些功能?
- 如何通过Lpc来初始化SIO?
- Global Controller Register
- UART Func
SIO 包含哪些功能?
虽不同款芯片支持的功能可能不尽相同,但是大体流程和基本功能还是很相近的,下面以Nct6106D为例:
- FDC: FOLPPY DISK CONTROLLER,软盘控制器.
- PRT: PARALLEL PORT, 也称打印机接口逻辑.
- UART: Universal Asynchronous Receiver/Transmitter, 标准异步收发器,俗称串口.
- KBC: KEYBOARD CONTROLLRT, 键盘控制器, PS/2.
- CIR: CONSUMER INFRARED REMOTE , 谷歌翻译为:消费者红外遥控器,暂时没用过,猜测是一种红外传感器吧.
- GPIO: General Purpose Input Output.通用型输入输出.
- GPIO,WDT: WatchDog Timer, 支持一个8位可编程的超时计数器.
- ACPI: 简称电源管理, 信号连接到南桥(7A芯片组),用于将系统从S1~S5唤醒睡眠状态.
- others: 包含SmartFan,Led等功能,就不详细说了.
这款芯片虽然集成了好多功能,但是使用有限,加之之前调试过几个常用功能,那我们就摘之为例进行详细介绍:
如何通过Lpc来初始化SIO?
SIO,按照手册来讲,不单单支持LPC接口,也支持SMBUS,那么如果我们将SIO接到LPC总线上,我们如何控制它呢?
- 1.他作为一个IO设备,我们需要通过LpcIo的方式进行通讯,在龙芯处理器,Lpc的Io物理地址->虚拟地址(0x18000000->0xefdfc000000,通过X1Bar配置窗口映射到HT1的IO空间),所以LpcIo的访问我们使用UNCACHE_ADDR(0xefdfc000000)).
- 2.通过SIO芯片控制逻辑进行功能选择:AccessSio逻辑图与代码逻辑如下:
VOID
Nct6106d_write(
UINT8 dev,
UINT8 addr,
UINT8 data)
{
/*enter*/
outb(BONITO_PCIIO_BASE_VA + OFFSET_2E_4E + 0x002e,0x87);
outb(BONITO_PCIIO_BASE_VA + OFFSET_2E_4E + 0x002e,0x87);
if(dev != 0xff)
{
/*select logic dev reg */
outb(BONITO_PCIIO_BASE_VA + OFFSET_2E_4E + 0x002e,0x7);
outb(BONITO_PCIIO_BASE_VA + OFFSET_2E_4E + 0x002f,dev);
}
/*access reg */
outb(BONITO_PCIIO_BASE_VA + OFFSET_2E_4E + 0x002e,addr);
outb(BONITO_PCIIO_BASE_VA + OFFSET_2E_4E + 0x002f,data);
/*exit*/
outb(BONITO_PCIIO_BASE_VA + OFFSET_2E_4E + 0x002e,0xaa);
outb(BONITO_PCIIO_BASE_VA + OFFSET_2E_4E + 0x002e,0xaa);
}
相信大家也都看明白了,如果你是一名软件人员,在这里有个注意的,那就是需要查看硬件原理图来确定究竟是0x2E,0x2F,还是0x4E,0x4F的端口.这是硬件的地址引脚来决定的.
上图代码中的dev标志着SIO内的逻辑设备控制器,addr是逻辑设备控制器内offset设备ID对照表:
Global Control register的操作方式我们已经在代码中以dev=0xff的形式进行了区分,你在上图中应该已经发现.
Global Controller Register
简单介绍一下该组控制寄存器,以代码为例:
Nct6106d_write(0xff,0x02,0x01);//reset
Nct6106d_write(0xff,0x26,0xc3);//2e_4e
Nct6106d_write(0xff,0x29,0xff);//disable legacy mode
Nct6106d_write(0xff,0x1a,0x00);//ps/2
Nct6106d_write(0xff,0x1c,0x1e);//uart
- 0x02: Reset SIO 寄存器
- 0x1a: MutliFunc 引脚复用寄存器,举例:如若使用PS/2,那么首先就需要将对应引脚设置为PS/2的功能.
其他寄存器就先不详细说了,简单上图0x1a举例:
UART Func
UART就不多介绍了,异步通讯收发器: 我们俗用串口输出调试,也有一些产品上将之作为串行打印机,串行鼠标键盘等.Nct61061d这款芯片共集成了6个UART控制器,UARTA~UARTF.访问UARTA见下图SIO手册及代码:
//Nct6106d_UARTA
Nct6106d_write(2,0x30,0x01);
Nct6106d_write(2,0x60,0x03);
Nct6106d_write(2,0x61,0xf8);
Nct6106d_write(2,0x70,0x4);
Nct6106d_write(2,0xf0,0x2);
配置流程:
- 1 通过0x30将UARTA进行功能Enable
- 2 通过0x60,0x61将UARTA的该组寄存器映射到LpcIo的地址端口上,比如配置的0x3f8,那么如果我们想要访问UART控制器组的话,就需要通过UNCACHE_ADDR(0xefdfc000000+0x3f8)进行访问了,关于UART寄存器组都是按照协议规范定义的,可以正常使用标准协议驱动.
- 3 通过0x70,我们来分配该UARTA的中断号. 在龙芯平台上, 中断号0-15已经分配给了Lpc下面的设备哦.
- 4 通过0xf0,可以对UARTA进行时钟分频.
先写到这里,关于UARTA的配置及SIO的详细寄存器组我相信或多或少都有了解,所有的功能都大同小异,通过Lpc配置SIO,每款SIO芯片可能Access逻辑稍有区别,但是SIO内部的逻辑设备符合标准驱动模型.