Note17PECI(Platform Environment Control Interface)
Posted 码农编程录
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Note17PECI(Platform Environment Control Interface)相关的知识,希望对你有一定的参考价值。
文章目录
1.模式和命令介绍
peci是 intel提供的私有协议,openbmc是由intel授权的,其他不授权是不能用的。硬件上是由一根线,不像i2c是有2根线。peci1.1只支持CPU温度,2.0增加支持MSR相关寄存器,3.0增加支持读intel的PCI配置。PCI主要根据intel的BDF【Bus/Device/Function (PCI technology)】确定读pcie设备里的寄存器地址
。如下peci有两个请求方式:AMIbmc是A,obmc用的B。
1.PCH模式
:cpu一般有一个ME地址挂在smlink上,-b就是挂的bus号(简单理解就是i2c的bus号),-t是挂的地址,一般都是0x2c。BMC通过IPMI给ME发一个raw date命令,ME再发pcie命令到cpu
。实际是ME不停给cpu发一些peci命令来获取它需要的数据,它把这些数据做一个缓存在它自己内部,bmc向它访问数据的话,me会直接把缓存的数据回到bmc上,如下raw 6 1 是读ME的版本号。
2.PECI模式
:obmc上有一个peci-util命令,通过这命令直接访问到cpu内部,peci-util虽说是二进制命令,但是底层调用libpeci库(https://github.com/openbmc/libpeci.git),通过libpeci 访问 /dev/peci-0节点进行IO操作即那根数据线发peci指令。Openbmc中使能PECI需要同时修改kernel.cfg和image.bb文件
:在image.bb IMAGE_INSTALL 变量中追加”peci-util-v2”来安装peci-util 命令,在kernel.cfg中增加CONFIG_PECI相关宏来使能PECI驱动,如下图:
如下peci3.0支持的方式,如下10个命令也不是所有cpu平台都支持,具体还要看cpu手册,因为cpu平台功能划分比较细,不是所有平台都支持所有功能,前5个全平台支持。
2.通过peci读cpu温度
cpu温度使用RdPkgconfig()命令(read page config),通过peci读到cpu的最大值(tjmax)和一个偏移量(Tcontrol)(距离当前设定的最大值还差多少值),这两个的差值作为cpu实际温度。如下在intel芯片手册中:
如下6,7是两个字节。
0x10(十六进制) = 16(十进制)。info是偏移量。如下0x30是cpu的id,第一个cpu就是0x30,cpu2的话就是0x31,第一个05写长度,oxa1表示现在是read config操作(固定的)。
3.通过peci读DIMM温度
DIMM温度不涉及偏差多少,直接读实时温度,也是用RdPkgconfig()命令。DIMM每个channel可以插两个DIMM即DIMM0和DIMM1。14对应0x0E,$1对应传入0或者1,后面就是十六进制换算。
4.通过peci读MSR
客户给的不止msr,还有pcie寄存器一些读法,lerrLoggingReg通过查cpu手册,发现是pcie寄存器,BDFO四个变量才能确定一个地址,带外方式用RdPCIConfigLocal()读PCIE寄存器。如下地址换算值就是三个字节地址(根据BDF获得)。
如下就是读cpu上pcie寄存器都能用带外方式读了,临终遗言需要读lerrLoggingReg和MCerrLoggingReg寄存器都是一样这样读取。
如上四个值或(有1为1)一下得到三个字节值。
PTSTS(Power And Reset)
是cpu内部寄存器,带外方式读不了。如下C语言也可以发送PECI命令,参数用数组传入。
MSR(Model Specific Register)是x86架构中的概念,指的是在x86架构处理器中,一系列用于控制CPU运行、功能开关、调试、跟踪程序执行、监测CPU性能等方面的寄存器。MSR使用RdIAMSR()命令
。
如下是所有msr寄存器,0-15个物理核,项目是0-4个物理核相当于5个cpu,逻辑核心是0-7,现在项目只读物理核。我们一般只负责读出寄存器值,具体解析bios做,我们数据给他,他们自己去查。
# dumplwt.sh
. /usr/local/bin/openbmc-utils.sh
renice -20 -p $$ >/dev/null 2>&1
do_msr_deal()
echo
echo CPU MSR DUMP:
echo ==============
echo
echo "MCA_ERR_SRC_LOG"
peci-util 0x30 0x05 0x05 0xA1 0x00 0x00 0x05 0x00
echo
echo "IerrLoggingReg"
peci-util 0x30 0x05 0x05 0xE1 0x00 0xA4 0x50 0x18
echo
echo "MCerrLoggingReg"
peci-util 0x30 0x05 0x05 0xE1 0x00 0xA8 0x50 0x18
echo
echo "********************************************************"
echo "* MC index 00 *"
echo "********************************************************"
echo " IA32_MC0_CTL, ProcessorID from 0 to 4 "
peci-util 0x30 0x05 0x09 0xB1 0x00 0x00 0x00 0x04 # 倒数第三个是ProcessorID
peci-util 0x30 0x05 0x09 0xB1 0x00 0x01 0x00 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x02 0x00 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x03 0x00 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x04 0x00 0x04
echo " IA32_MC0_CTL2, ProcessorID from 0 to 4 "
peci-util 0x30 0x05 0x09 0xB1 0x00 0x00 0x80 0x02
peci-util 0x30 0x05 0x09 0xB1 0x00 0x01 0x80 0x02
peci-util 0x30 0x05 0x09 0xB1 0x00 0x02 0x80 0x02
peci-util 0x30 0x05 0x09 0xB1 0x00 0x03 0x80 0x02
peci-util 0x30 0x05 0x09 0xB1 0x00 0x04 0x80 0x02
echo " IA32_MC0_STATUS, ProcessorID from 0 to 4 "
peci-util 0x30 0x05 0x09 0xB1 0x00 0x00 0x01 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x01 0x01 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x02 0x01 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x03 0x01 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x04 0x01 0x04
echo " IA32_MC0_ADDR, ProcessorID from 0 to 4 "
peci-util 0x30 0x05 0x09 0xB1 0x00 0x00 0x02 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x01 0x02 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x02 0x02 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x03 0x02 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x04 0x02 0x04
echo " IA32_MC0_MISC, ProcessorID from 0 to 4 "
peci-util 0x30 0x05 0x09 0xB1 0x00 0x00 0x03 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x01 0x03 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x02 0x03 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x03 0x03 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x04 0x03 0x04
echo "********************************************************"
echo "* MC index 01 *"
echo "********************************************************"
echo " IA32_MC1_CTL, ProcessorID from 0 to 4 "
peci-util 0x30 0x05 0x09 0xB1 0x00 0x00 0x04 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x01 0x04 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x02 0x04 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x03 0x04 0x04
peci-util 0x30 0x05 0x09 0xB1 0x00 0x04 0x04 0x04
echo " IA32_MC1_CTL2, ProcessorID from 0 to 4 "
peci-util 0x30 0x05 0x09 0xB1 0x00 0x00 0x81 0x02
peci-util 0x30 0x05 0x09 0xB1 0x00 0x01 0x81 0x02
peci-util 0x30 0x05 0x09 0xB1 0x00 0x02 0x81 0x02
peci-util 0x30 0x05 0x09 0xB1 0x00 0x03 0x81 0x02
peci-util 0x30 0x05 0x09 0xB1 0x00 0x04 0x81 0x02
do_peci_select 7 #peci通道提前手动选择,在openbmc-utils.sh里source了一些borad.sh一些共用的脚本接口
do_msr_deal
do_peci_select 8
do_msr_deal
# 如下0x400是MC0,0x404是MC1....
IA32_MCi_CTL=(0x400 0x404 0x408 0x40c 0x410 0x414 0x418 0x41c 0x420 0x424 0x428)
mce_log()
modprobe msr
mcelog --daemon # 手动启动mcelog。查看mcelog日志:vim /var/log/mcelog
i=$#IA32_MCi_CTL[@]
echo "read IA32_MCi_CTL register begin $IA32_MCi_CTL[*]"
for ((cpu=0;cpu<8;cpu++));do
echo "cpu $cpu read IA32_MCi_CTL register"
for ((row=0;row<i;row++));do
rdmsr -p $cpu $IA32_MCi_CTL[row] -x
done
done
echo "read IA32_MCi_CTL register end"
mce_log
5.rdmsr读CPU温度
原方案从 /sys/class/hwmon/下读取CPU温度,该目录下有hwmon0、hwmon1、hwmon2三个文件,其中hwmon2目录下有记录CPU温度的文件temp_input,从该文件能直接读CPU温度。后发现temp_input文件有时在hwmon1下,有时在hwmon2下,不同环境位置不一样。不想再用直接读文件获取温度的方法,查看CPU手册找到了读寄存器获取温度的方法,该方案比较稳定。
rdmsr方案
:intel cpu有以下两个寄存器可供实现读CPU温度。CPU温度 = TCC_ACTIVATION_TEMP - TEMPERATURE。
0x1A2
:寄存器的bit23-16记录了TCC_ACTIVATION_TEMP值,改值可理解为CPU触发调温手段的阈值,该阈值出厂时设置;
0x19C
:寄存器的bit22-16记录了 TEMPERATURE值,这个值是CPU温度相对于TCC_ACTIVATION_TEMP的温度值;
#define TEMP_TARGET_MSR_REG (0x1a2)
#define TEMP_STATUS_MSR_REG (0x19c)
static int get_cpu_msr_temp_info(void) //接口直接返回CPU实际温度
int ucTempOffset;
int ucTempActivation;
int dwValh=0,dwVall=0;
rdmsr(TEMP_TARGET_MSR_REG, dwVall, dwValh);
/*bit23-16*/
dwVall &= 0x00FF0000;
ucTempActivation = (dwVall>>16)&0xff;
dwVall=0;
dwValh=0;
rdmsr(TEMP_STATUS_MSR_REG, dwVall, dwValh);
/*bit22-16*/
dwVall &= 0x007F0000;
ucTempOffset = (dwVall>>16)&0xff;
return (ucTempActivation-ucTempOffset);
以上是关于Note17PECI(Platform Environment Control Interface)的主要内容,如果未能解决你的问题,请参考以下文章
Shell1shell语法,ssh/build/scp/upgrade,环境变量,自动升级,wtd节点,busybox,PECI,软连接
ls(envir = envir, all.names = private) 中的错误:R 中的“envir”参数无效
Android adb 找不到我的 Galaxy Note 10.1