概述¶
平台环境控制接口(PECI)是 Intel 处理器和管理控制器(例如,基板管理控制器,BMC)之间的通信接口。PECI 提供服务,允许管理控制器通过访问各种寄存器来配置、监视和调试平台。它定义了一种专用的命令协议,其中管理控制器充当 PECI 发起者,而处理器则充当 PECI 响应者。PECI 可用于单处理器和多处理器系统。
注意:Intel PECI 规范未作为专用文档发布,而是作为给定 Intel CPU 的外部设计规范 (EDS) 的一部分。外部设计规范通常不公开。
PECI 线¶
PECI 线接口使用单根线进行自计时和数据传输。它不需要任何额外的控制线 - 物理层是自计时的单线总线信号,每个位都以从接近零伏特的空闲状态驱动的上升沿开始。驱动高电平信号的持续时间允许确定位值是逻辑“0”还是逻辑“1”。PECI 线还包括每个消息建立的可变数据速率。
对于 PECI 线,每个处理器封装将在定义的范围内使用唯一的固定地址,并且该地址应与处理器插槽 ID 具有固定的关系 - 如果移除其中一个处理器,则不会影响其余处理器的地址。
PECI 子系统内部¶
-
struct peci_controller_ops¶
PECI 控制器特定方法
定义:
struct peci_controller_ops {
int (*xfer)(struct peci_controller *controller, u8 addr, struct peci_request *req);
};
成员
xfer
PECI 传输函数
描述
PECI 控制器可能具有不同的硬件接口 - 实现 PECI 控制器的驱动程序可以使用此结构来通过为 PECI 核心公开通用接口来抽象这些差异。
-
struct peci_controller¶
PECI 控制器
定义:
struct peci_controller {
struct device dev;
const struct peci_controller_ops *ops;
struct mutex bus_lock;
u8 id;
};
成员
dev
将 PECI 控制器注册到设备模型的设备对象
ops
指向设备特定控制器操作的指针
bus_lock
用于保护多个调用者的锁
id
PECI 控制器 ID
描述
PECI 控制器通常使用非 PECI 总线(例如平台总线)连接到它们的驱动程序。每个 PECI 控制器都可以与一个或多个 PECI 设备通信。
-
struct peci_device¶
PECI 设备
定义:
struct peci_device {
struct device dev;
struct {
u32 x86_vfm;
u8 peci_revision;
u8 socket_id;
} info;
u8 addr;
bool deleted;
};
成员
dev
将 PECI 设备注册到设备模型的设备对象
info
PECI 设备特性
info.x86_vfm
设备供应商-系列-型号
info.peci_revision
PECI 设备支持的 PECI 修订版
info.socket_id
PECI 设备表示的插槽 ID
addr
在连接到父控制器的 PECI 总线上使用的地址
deleted
指示 PECI 设备已被删除
描述
peci_device 标识连接到 PECI 总线的单个设备(即 CPU)。暴露给系统其余部分的行为由管理设备的 PECI 驱动程序定义。
-
struct peci_request¶
PECI 请求
定义:
struct peci_request {
struct peci_device *device;
struct {
u8 buf[PECI_REQUEST_MAX_BUF_SIZE];
u8 len;
} rx, tx;
};
成员
device
将请求发送到的 PECI 设备
rx
RX 缓冲区特定数据
rx.buf
RX 缓冲区
rx.len
接收到的数据长度(以字节为单位)
tx
TX 缓冲区特定数据
tx.buf
TX 缓冲区
tx.len
传输数据长度(以字节为单位)
描述
peci_request 表示由 PECI 发起者 (TX) 发出的请求以及从 PECI 响应者 (RX) 接收的响应。
-
struct peci_device_id¶
要匹配的 PECI 设备数据
定义:
struct peci_device_id {
const void *data;
u32 x86_vfm;
};
成员
data
指向特定于设备的驱动程序私有数据的指针
x86_vfm
设备供应商-系列-型号
-
struct peci_driver¶
PECI 驱动程序
定义:
struct peci_driver {
struct device_driver driver;
int (*probe)(struct peci_device *device, const struct peci_device_id *id);
void (*remove)(struct peci_device *device);
const struct peci_device_id *id_table;
};
成员
driver
继承设备驱动程序
probe
探针回调
remove
移除回调
id_table
PECI 设备匹配表,用于确定要绑定哪个设备
-
peci_driver_register¶
peci_driver_register (driver)
注册 PECI 驱动程序
参数
driver
要注册的驱动程序
描述
不需要在模块初始化中执行任何特殊操作的 PECI 驱动程序应使用方便的 “module_peci_driver” 宏。
返回
成功时返回零,否则返回负错误代码。
-
module_peci_driver¶
module_peci_driver (__peci_driver)
用于注册模块化 PECI 驱动程序的辅助宏
参数
__peci_driver
peci_driver 结构
描述
用于 PECI 驱动程序的辅助宏,这些驱动程序在模块初始化/退出时不做任何特殊操作。这消除了大量样板代码。每个模块只能使用此宏一次,并且调用它会替换 module_init()
和 module_exit()
-
struct peci_controller *devm_peci_controller_add(struct device *dev, const struct peci_controller_ops *ops)¶
添加 PECI 控制器
参数
struct device *dev
用于 devm 操作的设备
const struct peci_controller_ops *ops
指向控制器特定方法的指针
描述
在其 probe() 的最后阶段,peci_controller 驱动程序调用 devm_peci_controller_add()
将自身注册到 PECI 总线。
返回
指向新分配的控制器的指针,如果失败,则返回 ERR_PTR()
。
-
int peci_request_status(struct peci_request *req)¶
基于 PECI 完成代码返回 -errno
参数
struct peci_request *req
包含带有完成代码的响应数据的 PECI 请求
描述
它不能用于 Ping()、GetDIB() 和 GetTemp() - 对于这些命令,我们不希望响应中包含完成代码。
返回
-errno
-
struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u8 rx_len)¶
分配
struct peci_requests
参数
struct peci_device *device
将要发送请求的 PECI 设备
u8 tx_len
TX 长度
u8 rx_len
RX 长度
返回
成功时,返回指向新分配的 struct peci_request
的指针,否则返回 NULL。
-
void peci_request_free(struct peci_request *req)¶
释放 peci_request
参数
struct peci_request *req
要释放的 PECI 请求
PECI CPU 驱动 API¶
-
int peci_temp_read(struct peci_device *device, s16 *temp_raw)¶
从 PECI 目标设备读取最大管芯温度
参数
struct peci_device *device
将要发送请求的 PECI 设备
s16 *temp_raw
存储读取温度的位置
描述
它使用 GetTemp PECI 命令。
返回
成功时返回 0,错误时返回其他值。
-
int peci_pcs_read(struct peci_device *device, u8 index, u16 param, u32 *data)¶
读取 PCS 寄存器
参数
struct peci_device *device
将要发送请求的 PECI 设备
u8 index
PCS 索引
u16 param
PCS 参数
u32 *data
存储读取数据的位置
描述
它使用 RdPkgConfig PECI 命令。
返回
成功时返回 0,错误时返回其他值。
-
int peci_pci_local_read(struct peci_device *device, u8 bus, u8 dev, u8 func, u16 reg, u32 *data)¶
使用原始地址读取 32 位内存位置
参数
struct peci_device *device
将要发送请求的 PECI 设备
u8 bus
总线
u8 dev
device
u8 func
功能
u16 reg
寄存器
u32 *data
存储读取数据的位置
描述
它使用 RdPCIConfigLocal PECI 命令。
返回
成功时返回 0,错误时返回其他值。
-
int peci_ep_pci_local_read(struct peci_device *device, u8 seg, u8 bus, u8 dev, u8 func, u16 reg, u32 *data)¶
使用原始地址读取 32 位内存位置
参数
struct peci_device *device
将要发送请求的 PECI 设备
u8 seg
PCI 段
u8 bus
总线
u8 dev
device
u8 func
功能
u16 reg
寄存器
u32 *data
存储读取数据的位置
描述
类似于peci_pci_local_read
,但它使用 RdEndpointConfig PECI 命令。
返回
成功时返回 0,错误时返回其他值。
-
int peci_mmio_read(struct peci_device *device, u8 bar, u8 seg, u8 bus, u8 dev, u8 func, u64 address, u32 *data)¶
使用 64 位 bar 偏移地址读取 32 位内存位置
参数
struct peci_device *device
将要发送请求的 PECI 设备
u8 bar
PCI bar
u8 seg
PCI 段
u8 bus
总线
u8 dev
device
u8 func
功能
u64 address
64 位 MMIO 地址
u32 *data
存储读取数据的位置
描述
它使用 RdEndpointConfig PECI 命令。
返回
成功时返回 0,错误时返回其他值。