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对照表:

huananzhi b75进bios页面_芯片

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手册及代码:

huananzhi b75进bios页面_龙芯处理器_02

//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内部的逻辑设备符合标准驱动模型.