요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
============================================
AMD HSMP interface
============================================
Newer Fam19h(model 0x00-0x1f, 0x30-0x3f, 0x90-0x9f, 0xa0-0xaf),
Fam1Ah(model 0x00-0x1f) EPYC server line of processors from AMD support
system management functionality via HSMP (Host System Management Port).
The Host System Management Port (HSMP) is an interface to provide
OS-level software with access to system management functions via a
set of mailbox registers.
More details on the interface can be found in chapter
"7 Host System Management Port (HSMP)" of the family/model PPR
Eg: https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/programmer-references/55898_B1_pub_0_50.zip
HSMP interface is supported on EPYC line of server CPUs and MI300A (APU).
HSMP device
============================================
amd_hsmp driver under drivers/platforms/x86/amd/hsmp/ has separate driver files
for ACPI object based probing, platform device based probing and for the common
code for these two drivers.
Kconfig option CONFIG_AMD_HSMP_PLAT compiles plat.c and creates amd_hsmp.ko.
Kconfig option CONFIG_AMD_HSMP_ACPI compiles acpi.c and creates hsmp_acpi.ko.
Selecting any of these two configs automatically selects CONFIG_AMD_HSMP. This
compiles common code hsmp.c and creates hsmp_common.ko module.
Both the ACPI and plat drivers create the miscdevice /dev/hsmp to let
user space programs run hsmp mailbox commands.
The ACPI object format supported by the driver is defined below.
$ ls -al /dev/hsmp
crw-r--r-- 1 root root 10, 123 Jan 21 21:41 /dev/hsmp
Characteristics of the dev node:
* Write mode is used for running set/configure commands
* Read mode is used for running get/status monitor commands
Access restrictions:
* Only root user is allowed to open the file in write mode.
* The file can be opened in read mode by all the users.
In-kernel integration:
* Other subsystems in the kernel can use the exported transport
function hsmp_send_message().
* Locking across callers is taken care by the driver.
HSMP sysfs interface
====================
1. Metrics table binary sysfs
AMD MI300A MCM provides GET_METRICS_TABLE message to retrieve
most of the system management information from SMU in one go.
The metrics table is made available as hexadecimal sysfs binary file
under per socket sysfs directory created at
/sys/devices/platform/amd_hsmp/socket%d/metrics_bin
Note: lseek() is not supported as entire metrics table is read.
Metrics table definitions will be documented as part of Public PPR.
The same is defined in the amd_hsmp.h header.
2. HSMP telemetry sysfs files
Following sysfs files are available at /sys/devices/platform/AMDI0097:0X/.
* c0_residency_input: Percentage of cores in C0 state.
* prochot_status: Reports 1 if the processor is at thermal threshold value,
0 otherwise.
* smu_fw_version: SMU firmware version.
* protocol_version: HSMP interface version.
* ddr_max_bw: Theoretical maximum DDR bandwidth in GB/s.
* ddr_utilised_bw_input: Current utilized DDR bandwidth in GB/s.
* ddr_utilised_bw_perc_input(%): Percentage of current utilized DDR bandwidth.
* mclk_input: Memory clock in MHz.
* fclk_input: Fabric clock in MHz.
* clk_fmax: Maximum frequency of socket in MHz.
* clk_fmin: Minimum frequency of socket in MHz.
* cclk_freq_limit_input: Core clock frequency limit per socket in MHz.
* pwr_current_active_freq_limit: Current active frequency limit of socket
in MHz.
* pwr_current_active_freq_limit_source: Source of current active frequency
limit.
ACPI device object format
=========================
The ACPI object format expected from the amd_hsmp driver
for socket with ID00 is given below::
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}
}
})
}
HSMP HWMON interface
====================
HSMP power sensors are registered with the hwmon interface. A separate hwmon
directory is created for each socket and the following files are generated
within the hwmon directory.
- power1_input (read only)
- power1_cap_max (read only)
- power1_cap (read, write)
An example
==========
To access hsmp device from a C program.
First, you need to include the headers::
#include <linux/amd_hsmp.h>
Which defines the supported messages/message IDs.
Next thing, open the device file, as follows::
int file;
file = open("/dev/hsmp", O_RDWR);
if (file < 0) {
/* ERROR HANDLING; you can check errno to see what went wrong */
exit(1);
}
The following IOCTL is defined:
``ioctl(file, HSMP_IOCTL_CMD, struct hsmp_message *msg)``
The argument is a pointer to a::
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 */
};
The ioctl would return a non-zero on failure; you can read errno to see
what happened. The transaction returns 0 on success.
More details on the interface and message definitions can be found in chapter
"7 Host System Management Port (HSMP)" of the respective family/model PPR
eg: https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/programmer-references/55898_B1_pub_0_50.zip
User space C-APIs are made available by linking against the esmi library,
which is provided by the E-SMS project https://www.amd.com/en/developer/e-sms.html.
See: https://github.com/amd/esmi_ib_library
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
AMD HSMP interface 개요
1-22이 문서는 `GPL-2.0`으로 배포됩니다. AMD의 newer Fam19h(model `0x00-0x1f`, `0x30-0x3f`, `0x90-0x9f`, `0xa0-0xaf`) 및 Fam1Ah(model `0x00-0x1f`) EPYC server processor는 HSMP(Host System Management Port)를 통해 system-management 기능을 지원합니다.
HSMP는 mailbox register 집합을 통해 OS-level software가 system-management function에 접근하도록 제공하는 interface입니다.
interface의 자세한 내용은 해당 family/model PPR의 chapter `7 Host System Management Port (HSMP)`에 있습니다. 예시 문서는 `https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/programmer-references/55898_B1_pub_0_50.zip`입니다.
HSMP interface는 EPYC server CPU 제품군과 MI300A APU에서 지원됩니다.
driver module과 /dev/hsmp 접근 정책
23-56`drivers/platforms/x86/amd/hsmp/` 아래의 `amd_hsmp` driver는 ACPI object 기반 probing, platform-device 기반 probing, 두 driver가 공유하는 common code를 각각 별도 file로 구현합니다.
| Kconfig | compile 대상 | 생성 module |
|---|---|---|
| `CONFIG_AMD_HSMP_PLAT` | `plat.c` | `amd_hsmp.ko` |
| `CONFIG_AMD_HSMP_ACPI` | `acpi.c` | `hsmp_acpi.ko` |
| `CONFIG_AMD_HSMP` | `hsmp.c` common code | `hsmp_common.ko` |
앞의 두 config 중 하나를 선택하면 `CONFIG_AMD_HSMP`가 자동으로 선택됩니다. ACPI driver와 plat driver는 모두 userspace program이 HSMP mailbox command를 실행할 수 있도록 miscdevice `/dev/hsmp`를 만듭니다.
$ ls -al /dev/hsmp
crw-r--r-- 1 root root 10, 123 Jan 21 21:41 /dev/hsmp
device node의 access mode별 용도는 다음과 같습니다.
- write mode는 set/configure command 실행에 사용합니다.
- read mode는 get/status-monitor command 실행에 사용합니다.
접근 권한은 다음과 같이 제한됩니다.
- root user만 file을 write mode로 열 수 있습니다.
- 모든 user가 file을 read mode로 열 수 있습니다.
kernel 내부 integration은 다음 transport 규칙을 따릅니다.
- 다른 kernel subsystem은 export된 `hsmp_send_message()` function을 사용할 수 있습니다.
- caller 사이의 locking은 driver가 처리합니다.
metrics table binary sysfs
57-73AMD MI300A MCM은 SMU의 system-management information 대부분을 한 번에 가져오는 `GET_METRICS_TABLE` message를 제공합니다.
metrics table은 socket별 sysfs directory 아래의 hexadecimal binary file `/sys/devices/platform/amd_hsmp/socket%d/metrics_bin`으로 노출됩니다.
항상 metrics table 전체를 읽으므로 `lseek()`는 지원되지 않습니다.
metrics table 정의는 public PPR의 일부로 문서화될 예정이며 같은 정의가 `amd_hsmp.h` header에도 있습니다.
HSMP telemetry sysfs file
74-95다음 telemetry sysfs file은 `/sys/devices/platform/AMDI0097:0X/`에 제공됩니다.
| file | 보고 값 |
|---|---|
| `c0_residency_input` | C0 state에 있는 core의 비율입니다. |
| `prochot_status` | processor가 thermal threshold value에 있으면 1, 아니면 0입니다. |
| `smu_fw_version` | SMU firmware version입니다. |
| `protocol_version` | HSMP interface version입니다. |
| `ddr_max_bw` | 이론상 최대 DDR bandwidth(GB/s)입니다. |
| `ddr_utilised_bw_input` | 현재 사용 중인 DDR bandwidth(GB/s)입니다. |
| `ddr_utilised_bw_perc_input(%)` | 현재 사용 중인 DDR bandwidth의 비율입니다. |
| `mclk_input` | memory clock(MHz)입니다. |
| `fclk_input` | fabric clock(MHz)입니다. |
| `clk_fmax` | socket의 최대 frequency(MHz)입니다. |
| `clk_fmin` | socket의 최소 frequency(MHz)입니다. |
| `cclk_freq_limit_input` | socket별 core clock frequency limit(MHz)입니다. |
| `pwr_current_active_freq_limit` | socket의 현재 active frequency limit(MHz)입니다. |
| `pwr_current_active_freq_limit_source` | 현재 active frequency limit의 source입니다. |
ACPI device object format
96-140socket ID가 `ID00`일 때 `amd_hsmp` driver가 기대하는 ACPI object format은 다음과 같습니다.
원문 ACPI definition의 object와 역할을 구조화했습니다. 아래 표와 이어지는 원문 code block은 같은 구성을 나타냅니다.
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}
}
})
}
HSMP HWMON power sensor
141-149HSMP power sensor는 hwmon interface에 등록됩니다. socket마다 별도 hwmon directory가 생성되고 다음 file이 만들어집니다.
| file | access |
|---|---|
| `power1_input` | read only |
| `power1_cap_max` | read only |
| `power1_cap` | read, write |
C program에서 device 열기
150-169C program에서 HSMP device에 접근하려면 먼저 지원 message와 message ID를 정의하는 `<linux/amd_hsmp.h>` header를 include합니다.
#include <linux/amd_hsmp.h>
그다음 `/dev/hsmp`를 `O_RDWR`로 엽니다. 실패하면 `errno`로 원인을 확인하고 적절히 error handling합니다.
int file;
file = open("/dev/hsmp", O_RDWR);
if (file < 0) {
/* ERROR HANDLING; you can check errno to see what went wrong */
exit(1);
}
HSMP_IOCTL_CMD와 hsmp_message
170-184정의된 ioctl 형식은 `ioctl(file, HSMP_IOCTL_CMD, struct hsmp_message *msg)`입니다. 마지막 argument는 다음 `struct hsmp_message`를 가리키는 pointer입니다.
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 */
};
`msg_id`는 message ID, `num_args`는 input argument word 수, `response_sz`는 예상 output/response word 수입니다. `args[HSMP_MAX_MSG_LEN]`은 argument와 response가 공유하는 buffer이고 `sock_ind`는 socket number입니다.
ioctl은 실패하면 non-zero를 반환하며 `errno`에서 원인을 읽을 수 있습니다. transaction이 성공하면 0을 반환합니다.
PPR과 userspace library
185-192interface와 message 정의의 자세한 내용은 해당 family/model PPR의 chapter `7 Host System Management Port (HSMP)`를 참조합니다. 예시는 `https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/programmer-references/55898_B1_pub_0_50.zip`입니다.
userspace C API는 E-SMS project가 제공하는 esmi library를 link해 사용할 수 있습니다. project는 `https://www.amd.com/en/developer/e-sms.html`, library source는 `https://github.com/amd/esmi_ib_library`에서 확인할 수 있습니다.
요약과 해설
amd_hsmp.rst:1-192HSMP는 AMD EPYC server CPU와 MI300A APU에서 mailbox register를 통해 OS-level system-management 기능을 제공하는 interface입니다. Linux driver는 ACPI 또는 platform probing으로 `/dev/hsmp`를 만들며 set/configure는 root write access, get/status monitoring은 일반 user의 read access를 허용합니다.
MI300A는 socket별 `metrics_bin`에서 metrics table 전체를 binary로 제공하고, `AMDI0097` ACPI device 아래에는 C0 residency, thermal state, SMU/HSMP version, DDR bandwidth, memory/fabric/core clock limit 같은 telemetry가 노출됩니다. power sensor는 socket별 hwmon directory에도 등록됩니다.
userspace는 `<linux/amd_hsmp.h>`의 `HSMP_IOCTL_CMD`와 `struct hsmp_message`로 `/dev/hsmp`에 command를 보냅니다. kernel subsystem은 locking이 포함된 `hsmp_send_message()` transport를 사용할 수 있고, higher-level userspace C API는 E-SMS의 esmi library가 제공합니다.