SMBUS读取内存SPD信息
SMBUS(System Management BUS,系统管理总线)在1995年由Intel公司提出来,被应用于移动PC与桌面PC系统的低速率通信。通过两条信号线来控制主板上的设备以及收集相应的信息。两条信号线分别为SMBCLK和SMBDAT,即一条时钟线和一条数据线,两条线合在一起称为一条总线。两条信号线支持双向通信,当总线空闲时,两条信号线都是高电平。SMBUS总线规范在I2C的总线规范的基础上有所区别。首先SMBUS和I2C总线在时序特性上存在一些差别。SMBUS需要一定数据保持时间,而I2C则是从内部延长数据保持时间;SMBUS具有超时功能,当SCL太低而超过35ms时,从器件将复位正在进行的通信,相反,I2C会采用硬件复位;SMBUS具有一种报警响应地址,因此当从器件产生一个中断时,它不会马上清除中断,而是一直保持到其收到一个由主器件发送的含有其地址的报警响应地址为止。SMBUS的工作频率从10KHz到最高的100KHz,最低工作频率由SMBUS的超时功能决定。
SMBUS设备可以支持三种不同的最大总线速度之一中的一种:100 kHz、400 kHz和1 MHz。
SMBUS由于是基于I2C协议的基础上研究的,因此SMBUS协议中的特性和时序与I2C一致。
SPD芯片
SPD(Serial Presence Detect串行预设侦测)芯片,是一个具有8个针脚的EEPROM(Electrically Erasable Programmable ROM电可擦写可编程只读存储器)芯片。该芯片中储存着一些诸如内存的速度、容量、电压与行、列地址宽度等参数,可以让主板BIOS根据其内的参数自动设定BIOS(当然前提是在BIOS中设定为自动)中内存相关的选项。BIOS在上电检测阶段读取这些参数,然后自动地调整CMOS Chipset Features(CMOS芯片集特性)屏中的有关选项,从而兼顾到最高性能和最大可靠性。
在offset 20处,为SMB Base Address
根据在RW中实际读取到的值为EFA1,但是bit 0为固定值,实际的IO地址值为EFA0.
根据SPEC,我们可以通过IO方式访问
参照SPEC读取SPD步骤
例如读取主板上DIMM1内存的SPD 信息
读一个字节
每次读取之前先要在偏移0x00处写入0xFE来清除数据。
1.首先在(SMBUS基地址+0x04)的位置写入(从设备号+1),位0置1表示读操作。
2.然后将需要读取数据的那个寄存器(存储着SPD信息的寄存器)的偏移量写入(SMBUS基地址+0x03)这个位置。
3.在(SMBUS基地址+0x02)这个位置写入操作方式,读一个字节则写入0x48。(offset 02,bit 6 = 1 bit2:4=010)
4.在(SMBUS基地址+0x05)这个位置则可以读出对应寄存器里的数据。
写一个字节
首先在(SMBUS基地址+0x04)的位置写入(从设备号),位0置零表示写操作。
2.然后将需要写入数据的那个寄存器(存储着SPD信息的寄存器)的偏移量写入(SMBUS基地址+0x03)这个位置。
-
在(SMBUS基地址+0x05)这个位置写入将要写入指定寄存器的数据。
-
在(SMBUS基地址+0x02)这个位置写入操作方式,写一个字节则写入0x48。
在dos下,也可以根据IO的方式来实际读取SPD的信息。
#include<stdio.h>
#include<conio.h>
#include<dos.h>
#define Smbus_Base_Addr 0xEFA0
#define Hst_Sta_Addr 0x00
#define Trans_Slave_Addr 0x04
#define Host_Comm_Reg 0x03
#define Host_Contr_Reg 0x02
#define DATA0_Reg 0x05
#define DATA1_Reg 0x06
#define Host_Bloc_Data 0x07
// ASCII printable character check
#define IS_PRINTABLE(c) ((c) >= 32 && (c) <= 126)
void delay() {
int i;
for(i=100; i>0; i--);
}
void</