19. AMD HSMP 接口¶
较新的 Fam19h(型号 0x00-0x1f、0x30-0x3f、0x90-0x9f、0xa0-0xaf)、Fam1Ah(型号 0x00-0x1f)来自 AMD 的 EPYC 服务器系列处理器通过 HSMP(主机系统管理端口)支持系统管理功能。
主机系统管理端口 (HSMP) 是一个接口,通过一组邮箱寄存器为操作系统级软件提供对系统管理功能的访问。
有关该接口的更多详细信息,请参见系列/型号 PPR 的“7 主机系统管理端口 (HSMP)”章节,例如: https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/programmer-references/55898_B1_pub_0_50.zip
HSMP 接口在 EPYC 系列服务器 CPU 和 MI300A (APU) 上受支持。
19.1. HSMP 设备¶
drivers/platforms/x86/amd/hsmp/ 下的 amd_hsmp 驱动程序具有单独的驱动程序文件,用于基于 ACPI 对象的探测、基于平台设备的探测以及这两个驱动程序的通用代码。
Kconfig 选项 CONFIG_AMD_HSMP_PLAT 编译 plat.c 并创建 amd_hsmp.ko。Kconfig 选项 CONFIG_AMD_HSMP_ACPI 编译 acpi.c 并创建 hsmp_acpi.ko。选择这两个配置中的任何一个都会自动选择 CONFIG_AMD_HSMP。这会编译通用代码 hsmp.c 并创建 hsmp_common.ko 模块。
ACPI 和 plat 驱动程序都会创建 miscdevice /dev/hsmp,以允许用户空间程序运行 hsmp 邮箱命令。
下面定义了驱动程序支持的 ACPI 对象格式。
$ ls -al /dev/hsmp crw-r--r-- 1 root root 10, 123 1月 21 21:41 /dev/hsmp
- 设备节点的特征
写入模式用于运行 set/configure 命令
读取模式用于运行 get/status monitor 命令
- 访问限制
只允许 root 用户以写入模式打开该文件。
所有用户都可以以读取模式打开该文件。
- 内核集成
内核中的其他子系统可以使用导出的传输函数 hsmp_send_message()。
调用者之间的锁定由驱动程序负责。
19.2. HSMP sysfs 接口¶
指标表二进制 sysfs
AMD MI300A MCM 提供 GET_METRICS_TABLE 消息,以便一次性从 SMU 检索大部分系统管理信息。
指标表以十六进制 sysfs 二进制文件形式提供,位于在 /sys/devices/platform/amd_hsmp/socket%d/metrics_bin 创建的每个套接字 sysfs 目录下
注意:不支持 lseek(),因为会读取整个指标表。
指标表定义将作为公共 PPR 的一部分进行记录。该定义也在 amd_hsmp.h 标头中定义。
19.3. ACPI 设备对象格式¶
以下是 amd_hsmp 驱动程序针对 ID 为 00 的套接字所期望的 ACPI 对象格式
Device(HSMP)
{
Name(_HID, "AMDI0097")
Name(_UID, "ID00")
Name(HSE0, 0x00000001)
Name(RBF0, ResourceTemplate()
{
Memory32Fixed(ReadWrite, 0xxxxxxx, 0x00100000)
})
Method(_CRS, 0, NotSerialized)
{
Return(RBF0)
}
Method(_STA, 0, NotSerialized)
{
If(LEqual(HSE0, One))
{
Return(0x0F)
}
Else
{
Return(Zero)
}
}
Name(_DSD, Package(2)
{
Buffer(0x10)
{
0x9D, 0x61, 0x4D, 0xB7, 0x07, 0x57, 0xBD, 0x48,
0xA6, 0x9F, 0x4E, 0xA2, 0x87, 0x1F, 0xC2, 0xF6
},
Package(3)
{
Package(2) {"MsgIdOffset", 0x00010934},
Package(2) {"MsgRspOffset", 0x00010980},
Package(2) {"MsgArgOffset", 0x000109E0}
}
})
}
19.4. 一个示例¶
要从 C 程序访问 hsmp 设备。首先,您需要包含标头
#include <linux/amd_hsmp.h>
它定义了支持的消息/消息 ID。
接下来,打开设备文件,如下所示
int file;
file = open("/dev/hsmp", O_RDWR);
if (file < 0) {
/* ERROR HANDLING; you can check errno to see what went wrong */
exit(1);
}
定义了以下 IOCTL
ioctl(file, HSMP_IOCTL_CMD, struct hsmp_message *msg)
该参数是指向以下内容的指针
struct hsmp_message { __u32 msg_id; /* Message ID */ __u16 num_args; /* Number of input argument words in message */ __u16 response_sz; /* Number of expected output/response words */ __u32 args[HSMP_MAX_MSG_LEN]; /* argument/response buffer */ __u16 sock_ind; /* socket number */ };
ioctl 在失败时会返回非零值;您可以读取 errno 以查看发生了什么。事务在成功时返回 0。
有关接口和消息定义的更多详细信息,请参见相应系列/型号 PPR 的“7 主机系统管理端口 (HSMP)”章节,例如: https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/programmer-references/55898_B1_pub_0_50.zip
用户空间 C-API 通过链接 esmi 库提供,该库由 E-SMS 项目提供 https://www.amd.com/en/developer/e-sms.html。请参见: https://github.com/amd/esmi_ib_library