英语

概述

平台环境控制接口(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,错误时返回其他值。