From 35ac2034db72bbbc73609aab5f05ff6e0d38fdd0 Mon Sep 17 00:00:00 2001 From: Akshay Gupta Date: Mon, 28 Apr 2025 06:30:30 +0000 Subject: misc: amd-sbi: Add support for AMD_SBI IOCTL The present sbrmi module only support reporting power via hwmon. However, AMD data center range of processors support various system management functionality using custom protocols defined in Advanced Platform Management Link (APML) specification. Register a miscdevice, which creates a device /dev/sbrmiX with an IOCTL interface for the user space to invoke the APML Mailbox protocol, which is already defined in sbrmi_mailbox_xfer(). The APML protocols depend on a set of RMI registers. Having an IOCTL as a single entry point will help in providing synchronization among these protocols as multiple transactions on RMI register set may create race condition. Support for other protocols will be added in subsequent patches. APML mailbox protocol returns additional error codes written by SMU firmware in the out-bound register 0x37. These errors include, invalid core, message not supported over platform and others. This additional error codes can be used to provide more details to user space. Open-sourced and widely used https://github.com/amd/esmi_oob_library will continue to provide user-space programmable API. Reviewed-by: Naveen Krishna Chatradhi Signed-off-by: Akshay Gupta Link: https://lore.kernel.org/r/20250428063034.2145566-7-akshay.gupta@amd.com Signed-off-by: Greg Kroah-Hartman --- include/uapi/misc/amd-apml.h | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 include/uapi/misc/amd-apml.h (limited to 'include/uapi') diff --git a/include/uapi/misc/amd-apml.h b/include/uapi/misc/amd-apml.h new file mode 100644 index 000000000000..a5f086f84b06 --- /dev/null +++ b/include/uapi/misc/amd-apml.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Copyright (C) 2021-2024 Advanced Micro Devices, Inc. + */ +#ifndef _AMD_APML_H_ +#define _AMD_APML_H_ + +#include + +/* Mailbox data size for data_in and data_out */ +#define AMD_SBI_MB_DATA_SIZE 4 + +struct apml_mbox_msg { + /* + * Mailbox Message ID + */ + __u32 cmd; + /* + * [0]...[3] mailbox 32bit input/output data + */ + __u32 mb_in_out; + /* + * Error code is returned in case of soft mailbox error + */ + __u32 fw_ret_code; +}; + +/* + * AMD sideband interface base IOCTL + */ +#define SB_BASE_IOCTL_NR 0xF9 + +/** + * DOC: SBRMI_IOCTL_MBOX_CMD + * + * @Parameters + * + * @struct apml_mbox_msg + * Pointer to the &struct apml_mbox_msg that will contain the protocol + * information + * + * @Description + * IOCTL command for APML messages using generic _IOWR + * The IOCTL provides userspace access to AMD sideband mailbox protocol + * - Mailbox message read/write(0x0~0xFF) + * - returning "-EFAULT" if none of the above + * "-EPROTOTYPE" error is returned to provide additional error details + */ +#define SBRMI_IOCTL_MBOX_CMD _IOWR(SB_BASE_IOCTL_NR, 0, struct apml_mbox_msg) + +#endif /*_AMD_APML_H_*/ -- cgit v1.3 From bb13a84ed6b78200952b264b4d7a024b730e8246 Mon Sep 17 00:00:00 2001 From: Akshay Gupta Date: Mon, 28 Apr 2025 06:30:31 +0000 Subject: misc: amd-sbi: Add support for CPUID protocol - AMD provides custom protocol to read Processor feature capabilities and configuration information through side band. The information is accessed by providing CPUID Function, extended function and thread ID to the protocol. Undefined function returns 0. Reviewed-by: Naveen Krishna Chatradhi Signed-off-by: Akshay Gupta Link: https://lore.kernel.org/r/20250428063034.2145566-8-akshay.gupta@amd.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/amd-sbi/rmi-core.c | 168 ++++++++++++++++++++++++++++++++++++++++ drivers/misc/amd-sbi/rmi-core.h | 5 +- include/uapi/misc/amd-apml.h | 37 +++++++++ 3 files changed, 209 insertions(+), 1 deletion(-) (limited to 'include/uapi') diff --git a/drivers/misc/amd-sbi/rmi-core.c b/drivers/misc/amd-sbi/rmi-core.c index 7d13c049c98d..471f50f0c368 100644 --- a/drivers/misc/amd-sbi/rmi-core.c +++ b/drivers/misc/amd-sbi/rmi-core.c @@ -17,11 +17,160 @@ /* Mask for Status Register bit[1] */ #define SW_ALERT_MASK 0x2 +/* Mask to check H/W Alert status bit */ +#define HW_ALERT_MASK 0x80 /* Software Interrupt for triggering */ #define START_CMD 0x80 #define TRIGGER_MAILBOX 0x01 +/* Default message lengths as per APML command protocol */ +/* CPUID */ +#define CPUID_RD_DATA_LEN 0x8 +#define CPUID_WR_DATA_LEN 0x8 +#define CPUID_RD_REG_LEN 0xa +#define CPUID_WR_REG_LEN 0x9 + +/* CPUID MSR Command Ids */ +#define CPUID_MCA_CMD 0x73 +#define RD_CPUID_CMD 0x91 + +/* CPUID MCAMSR mask & index */ +#define CPUID_MCA_THRD_MASK GENMASK(15, 0) +#define CPUID_MCA_THRD_INDEX 32 +#define CPUID_MCA_FUNC_MASK GENMASK(31, 0) +#define CPUID_EXT_FUNC_INDEX 56 + +/* input for bulk write to CPUID protocol */ +struct cpu_msr_indata { + u8 wr_len; /* const value */ + u8 rd_len; /* const value */ + u8 proto_cmd; /* const value */ + u8 thread; /* thread number */ + union { + u8 reg_offset[4]; /* input value */ + u32 value; + } __packed; + u8 ext; /* extended function */ +}; + +/* output for bulk read from CPUID protocol */ +struct cpu_msr_outdata { + u8 num_bytes; /* number of bytes return */ + u8 status; /* Protocol status code */ + union { + u64 value; + u8 reg_data[8]; + } __packed; +}; + +static inline void prepare_cpuid_input_message(struct cpu_msr_indata *input, + u8 thread_id, u32 func, + u8 ext_func) +{ + input->rd_len = CPUID_RD_DATA_LEN; + input->wr_len = CPUID_WR_DATA_LEN; + input->proto_cmd = RD_CPUID_CMD; + input->thread = thread_id << 1; + input->value = func; + input->ext = ext_func; +} + +static int sbrmi_get_rev(struct sbrmi_data *data) +{ + unsigned int rev; + u16 offset = SBRMI_REV; + int ret; + + ret = regmap_read(data->regmap, offset, &rev); + if (ret < 0) + return ret; + + data->rev = rev; + return 0; +} + +/* Read CPUID function protocol */ +static int rmi_cpuid_read(struct sbrmi_data *data, + struct apml_cpuid_msg *msg) +{ + struct cpu_msr_indata input = {0}; + struct cpu_msr_outdata output = {0}; + int val = 0; + int ret, hw_status; + u16 thread; + + mutex_lock(&data->lock); + /* cache the rev value to identify if protocol is supported or not */ + if (!data->rev) { + ret = sbrmi_get_rev(data); + if (ret < 0) + goto exit_unlock; + } + /* CPUID protocol for REV 0x10 is not supported*/ + if (data->rev == 0x10) { + ret = -EOPNOTSUPP; + goto exit_unlock; + } + + thread = msg->cpu_in_out << CPUID_MCA_THRD_INDEX & CPUID_MCA_THRD_MASK; + + /* Thread > 127, Thread128 CS register, 1'b1 needs to be set to 1 */ + if (thread > 127) { + thread -= 128; + val = 1; + } + ret = regmap_write(data->regmap, SBRMI_THREAD128CS, val); + if (ret < 0) + goto exit_unlock; + + prepare_cpuid_input_message(&input, thread, + msg->cpu_in_out & CPUID_MCA_FUNC_MASK, + msg->cpu_in_out >> CPUID_EXT_FUNC_INDEX); + + ret = regmap_bulk_write(data->regmap, CPUID_MCA_CMD, + &input, CPUID_WR_REG_LEN); + if (ret < 0) + goto exit_unlock; + + /* + * For RMI Rev 0x20, new h/w status bit is introduced. which is used + * by firmware to indicate completion of commands (0x71, 0x72, 0x73). + * wait for the status bit to be set by the hardware before + * reading the data out. + */ + ret = regmap_read_poll_timeout(data->regmap, SBRMI_STATUS, hw_status, + hw_status & HW_ALERT_MASK, 500, 2000000); + if (ret) + goto exit_unlock; + + ret = regmap_bulk_read(data->regmap, CPUID_MCA_CMD, + &output, CPUID_RD_REG_LEN); + if (ret < 0) + goto exit_unlock; + + ret = regmap_write(data->regmap, SBRMI_STATUS, + HW_ALERT_MASK); + if (ret < 0) + goto exit_unlock; + + if (output.num_bytes != CPUID_RD_REG_LEN - 1) { + ret = -EMSGSIZE; + goto exit_unlock; + } + if (output.status) { + ret = -EPROTOTYPE; + msg->fw_ret_code = output.status; + goto exit_unlock; + } + msg->cpu_in_out = output.value; +exit_unlock: + if (ret < 0) + msg->cpu_in_out = 0; + mutex_unlock(&data->lock); + return ret; +} + int rmi_mailbox_xfer(struct sbrmi_data *data, struct apml_mbox_msg *msg) { @@ -123,6 +272,23 @@ static int apml_mailbox_xfer(struct sbrmi_data *data, struct apml_mbox_msg __use return copy_to_user(arg, &msg, sizeof(struct apml_mbox_msg)); } +static int apml_cpuid_xfer(struct sbrmi_data *data, struct apml_cpuid_msg __user *arg) +{ + struct apml_cpuid_msg msg = { 0 }; + int ret; + + /* Copy the structure from user */ + if (copy_from_user(&msg, arg, sizeof(struct apml_cpuid_msg))) + return -EFAULT; + + /* CPUID Protocol */ + ret = rmi_cpuid_read(data, &msg); + if (ret && ret != -EPROTOTYPE) + return ret; + + return copy_to_user(arg, &msg, sizeof(struct apml_cpuid_msg)); +} + static long sbrmi_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; @@ -132,6 +298,8 @@ static long sbrmi_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) switch (cmd) { case SBRMI_IOCTL_MBOX_CMD: return apml_mailbox_xfer(data, argp); + case SBRMI_IOCTL_CPUID_CMD: + return apml_cpuid_xfer(data, argp); default: return -ENOTTY; } diff --git a/drivers/misc/amd-sbi/rmi-core.h b/drivers/misc/amd-sbi/rmi-core.h index 8ab31c6852d1..975ae858e9fd 100644 --- a/drivers/misc/amd-sbi/rmi-core.h +++ b/drivers/misc/amd-sbi/rmi-core.h @@ -15,7 +15,8 @@ /* SB-RMI registers */ enum sbrmi_reg { - SBRMI_CTRL = 0x01, + SBRMI_REV, + SBRMI_CTRL, SBRMI_STATUS, SBRMI_OUTBNDMSG0 = 0x30, SBRMI_OUTBNDMSG1, @@ -34,6 +35,7 @@ enum sbrmi_reg { SBRMI_INBNDMSG6, SBRMI_INBNDMSG7, SBRMI_SW_INTERRUPT, + SBRMI_THREAD128CS = 0x4b, }; /* @@ -56,6 +58,7 @@ struct sbrmi_data { struct mutex lock; u32 pwr_limit_max; u8 dev_static_addr; + u8 rev; }; int rmi_mailbox_xfer(struct sbrmi_data *data, struct apml_mbox_msg *msg); diff --git a/include/uapi/misc/amd-apml.h b/include/uapi/misc/amd-apml.h index a5f086f84b06..bb57dc75758a 100644 --- a/include/uapi/misc/amd-apml.h +++ b/include/uapi/misc/amd-apml.h @@ -25,6 +25,24 @@ struct apml_mbox_msg { __u32 fw_ret_code; }; +struct apml_cpuid_msg { + /* + * CPUID input + * [0]...[3] cpuid func, + * [4][5] cpuid: thread + * [6] cpuid: ext function & read eax/ebx or ecx/edx + * [7:0] -> bits [7:4] -> ext function & + * bit [0] read eax/ebx or ecx/edx + * CPUID output + */ + __u64 cpu_in_out; + /* + * Status code for CPUID read + */ + __u32 fw_ret_code; + __u32 pad; +}; + /* * AMD sideband interface base IOCTL */ @@ -48,4 +66,23 @@ struct apml_mbox_msg { */ #define SBRMI_IOCTL_MBOX_CMD _IOWR(SB_BASE_IOCTL_NR, 0, struct apml_mbox_msg) +/** + * DOC: SBRMI_IOCTL_CPUID_CMD + * + * @Parameters + * + * @struct apml_cpuid_msg + * Pointer to the &struct apml_cpuid_msg that will contain the protocol + * information + * + * @Description + * IOCTL command for APML messages using generic _IOWR + * The IOCTL provides userspace access to AMD sideband cpuid protocol + * - CPUID protocol to get CPU details for Function/Ext Function + * at thread level + * - returning "-EFAULT" if none of the above + * "-EPROTOTYPE" error is returned to provide additional error details + */ +#define SBRMI_IOCTL_CPUID_CMD _IOWR(SB_BASE_IOCTL_NR, 1, struct apml_cpuid_msg) + #endif /*_AMD_APML_H_*/ -- cgit v1.3 From 69b1ba83d21c4a89f6fcfbca1d515a60df65cf9e Mon Sep 17 00:00:00 2001 From: Akshay Gupta Date: Mon, 28 Apr 2025 06:30:32 +0000 Subject: misc: amd-sbi: Add support for read MCA register protocol - AMD provides custom protocol to read Machine Check Architecture(MCA) registers over sideband. The information is accessed for range of MCA registers by passing register address and thread ID to the protocol. MCA register read command using the register address to access Core::X86::Msr::MCG_CAP which determines the number of MCA banks. Access is read-only Reviewed-by: Naveen Krishna Chatradhi Signed-off-by: Akshay Gupta Link: https://lore.kernel.org/r/20250428063034.2145566-9-akshay.gupta@amd.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/amd-sbi/rmi-core.c | 114 ++++++++++++++++++++++++++++++++++++++++ include/uapi/misc/amd-apml.h | 33 ++++++++++++ 2 files changed, 147 insertions(+) (limited to 'include/uapi') diff --git a/drivers/misc/amd-sbi/rmi-core.c b/drivers/misc/amd-sbi/rmi-core.c index 471f50f0c368..171d6e871373 100644 --- a/drivers/misc/amd-sbi/rmi-core.c +++ b/drivers/misc/amd-sbi/rmi-core.c @@ -30,10 +30,16 @@ #define CPUID_WR_DATA_LEN 0x8 #define CPUID_RD_REG_LEN 0xa #define CPUID_WR_REG_LEN 0x9 +/* MSR */ +#define MSR_RD_REG_LEN 0xa +#define MSR_WR_REG_LEN 0x8 +#define MSR_RD_DATA_LEN 0x8 +#define MSR_WR_DATA_LEN 0x7 /* CPUID MSR Command Ids */ #define CPUID_MCA_CMD 0x73 #define RD_CPUID_CMD 0x91 +#define RD_MCA_CMD 0x86 /* CPUID MCAMSR mask & index */ #define CPUID_MCA_THRD_MASK GENMASK(15, 0) @@ -76,6 +82,16 @@ static inline void prepare_cpuid_input_message(struct cpu_msr_indata *input, input->ext = ext_func; } +static inline void prepare_mca_msr_input_message(struct cpu_msr_indata *input, + u8 thread_id, u32 data_in) +{ + input->rd_len = MSR_RD_DATA_LEN; + input->wr_len = MSR_WR_DATA_LEN; + input->proto_cmd = RD_MCA_CMD; + input->thread = thread_id << 1; + input->value = data_in; +} + static int sbrmi_get_rev(struct sbrmi_data *data) { unsigned int rev; @@ -171,6 +187,85 @@ exit_unlock: return ret; } +/* MCA MSR protocol */ +static int rmi_mca_msr_read(struct sbrmi_data *data, + struct apml_mcamsr_msg *msg) +{ + struct cpu_msr_outdata output = {0}; + struct cpu_msr_indata input = {0}; + int ret, val = 0; + int hw_status; + u16 thread; + + mutex_lock(&data->lock); + /* cache the rev value to identify if protocol is supported or not */ + if (!data->rev) { + ret = sbrmi_get_rev(data); + if (ret < 0) + goto exit_unlock; + } + /* MCA MSR protocol for REV 0x10 is not supported*/ + if (data->rev == 0x10) { + ret = -EOPNOTSUPP; + goto exit_unlock; + } + + thread = msg->mcamsr_in_out << CPUID_MCA_THRD_INDEX & CPUID_MCA_THRD_MASK; + + /* Thread > 127, Thread128 CS register, 1'b1 needs to be set to 1 */ + if (thread > 127) { + thread -= 128; + val = 1; + } + ret = regmap_write(data->regmap, SBRMI_THREAD128CS, val); + if (ret < 0) + goto exit_unlock; + + prepare_mca_msr_input_message(&input, thread, + msg->mcamsr_in_out & CPUID_MCA_FUNC_MASK); + + ret = regmap_bulk_write(data->regmap, CPUID_MCA_CMD, + &input, MSR_WR_REG_LEN); + if (ret < 0) + goto exit_unlock; + + /* + * For RMI Rev 0x20, new h/w status bit is introduced. which is used + * by firmware to indicate completion of commands (0x71, 0x72, 0x73). + * wait for the status bit to be set by the hardware before + * reading the data out. + */ + ret = regmap_read_poll_timeout(data->regmap, SBRMI_STATUS, hw_status, + hw_status & HW_ALERT_MASK, 500, 2000000); + if (ret) + goto exit_unlock; + + ret = regmap_bulk_read(data->regmap, CPUID_MCA_CMD, + &output, MSR_RD_REG_LEN); + if (ret < 0) + goto exit_unlock; + + ret = regmap_write(data->regmap, SBRMI_STATUS, + HW_ALERT_MASK); + if (ret < 0) + goto exit_unlock; + + if (output.num_bytes != MSR_RD_REG_LEN - 1) { + ret = -EMSGSIZE; + goto exit_unlock; + } + if (output.status) { + ret = -EPROTOTYPE; + msg->fw_ret_code = output.status; + goto exit_unlock; + } + msg->mcamsr_in_out = output.value; + +exit_unlock: + mutex_unlock(&data->lock); + return ret; +} + int rmi_mailbox_xfer(struct sbrmi_data *data, struct apml_mbox_msg *msg) { @@ -289,6 +384,23 @@ static int apml_cpuid_xfer(struct sbrmi_data *data, struct apml_cpuid_msg __user return copy_to_user(arg, &msg, sizeof(struct apml_cpuid_msg)); } +static int apml_mcamsr_xfer(struct sbrmi_data *data, struct apml_mcamsr_msg __user *arg) +{ + struct apml_mcamsr_msg msg = { 0 }; + int ret; + + /* Copy the structure from user */ + if (copy_from_user(&msg, arg, sizeof(struct apml_mcamsr_msg))) + return -EFAULT; + + /* MCAMSR Protocol */ + ret = rmi_mca_msr_read(data, &msg); + if (ret && ret != -EPROTOTYPE) + return ret; + + return copy_to_user(arg, &msg, sizeof(struct apml_mcamsr_msg)); +} + static long sbrmi_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; @@ -300,6 +412,8 @@ static long sbrmi_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) return apml_mailbox_xfer(data, argp); case SBRMI_IOCTL_CPUID_CMD: return apml_cpuid_xfer(data, argp); + case SBRMI_IOCTL_MCAMSR_CMD: + return apml_mcamsr_xfer(data, argp); default: return -ENOTTY; } diff --git a/include/uapi/misc/amd-apml.h b/include/uapi/misc/amd-apml.h index bb57dc75758a..f718675d3966 100644 --- a/include/uapi/misc/amd-apml.h +++ b/include/uapi/misc/amd-apml.h @@ -43,6 +43,21 @@ struct apml_cpuid_msg { __u32 pad; }; +struct apml_mcamsr_msg { + /* + * MCAMSR input + * [0]...[3] mca msr func, + * [4][5] thread + * MCAMSR output + */ + __u64 mcamsr_in_out; + /* + * Status code for MCA/MSR access + */ + __u32 fw_ret_code; + __u32 pad; +}; + /* * AMD sideband interface base IOCTL */ @@ -85,4 +100,22 @@ struct apml_cpuid_msg { */ #define SBRMI_IOCTL_CPUID_CMD _IOWR(SB_BASE_IOCTL_NR, 1, struct apml_cpuid_msg) +/** + * DOC: SBRMI_IOCTL_MCAMSR_CMD + * + * @Parameters + * + * @struct apml_mcamsr_msg + * Pointer to the &struct apml_mcamsr_msg that will contain the protocol + * information + * + * @Description + * IOCTL command for APML messages using generic _IOWR + * The IOCTL provides userspace access to AMD sideband MCAMSR protocol + * - MCAMSR protocol to get MCA bank details for Function at thread level + * - returning "-EFAULT" if none of the above + * "-EPROTOTYPE" error is returned to provide additional error details + */ +#define SBRMI_IOCTL_MCAMSR_CMD _IOWR(SB_BASE_IOCTL_NR, 2, struct apml_mcamsr_msg) + #endif /*_AMD_APML_H_*/ -- cgit v1.3 From cf141287b77485ed7624ac1756b85cc801748c7c Mon Sep 17 00:00:00 2001 From: Akshay Gupta Date: Mon, 28 Apr 2025 06:30:33 +0000 Subject: misc: amd-sbi: Add support for register xfer - Provide user register access over IOCTL. Both register read and write are supported. - APML interface does not provide a synchronization method. By defining, a register access path, we use APML modules and library for all APML transactions. Without having to use external tools such as i2c-tools, which may cause race conditions. Reviewed-by: Naveen Krishna Chatradhi Signed-off-by: Akshay Gupta Link: https://lore.kernel.org/r/20250428063034.2145566-10-akshay.gupta@amd.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/amd-sbi/rmi-core.c | 29 +++++++++++++++++++++++++++++ include/uapi/misc/amd-apml.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) (limited to 'include/uapi') diff --git a/drivers/misc/amd-sbi/rmi-core.c b/drivers/misc/amd-sbi/rmi-core.c index 171d6e871373..b653a21a909e 100644 --- a/drivers/misc/amd-sbi/rmi-core.c +++ b/drivers/misc/amd-sbi/rmi-core.c @@ -350,6 +350,33 @@ exit_unlock: return ret; } +static int apml_rmi_reg_xfer(struct sbrmi_data *data, + struct apml_reg_xfer_msg __user *arg) +{ + struct apml_reg_xfer_msg msg = { 0 }; + unsigned int data_read; + int ret; + + /* Copy the structure from user */ + if (copy_from_user(&msg, arg, sizeof(struct apml_reg_xfer_msg))) + return -EFAULT; + + mutex_lock(&data->lock); + if (msg.rflag) { + ret = regmap_read(data->regmap, msg.reg_addr, &data_read); + if (!ret) + msg.data_in_out = data_read; + } else { + ret = regmap_write(data->regmap, msg.reg_addr, msg.data_in_out); + } + + mutex_unlock(&data->lock); + + if (msg.rflag && !ret) + return copy_to_user(arg, &msg, sizeof(struct apml_reg_xfer_msg)); + return ret; +} + static int apml_mailbox_xfer(struct sbrmi_data *data, struct apml_mbox_msg __user *arg) { struct apml_mbox_msg msg = { 0 }; @@ -414,6 +441,8 @@ static long sbrmi_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) return apml_cpuid_xfer(data, argp); case SBRMI_IOCTL_MCAMSR_CMD: return apml_mcamsr_xfer(data, argp); + case SBRMI_IOCTL_REG_XFER_CMD: + return apml_rmi_reg_xfer(data, argp); default: return -ENOTTY; } diff --git a/include/uapi/misc/amd-apml.h b/include/uapi/misc/amd-apml.h index f718675d3966..745b3338fc06 100644 --- a/include/uapi/misc/amd-apml.h +++ b/include/uapi/misc/amd-apml.h @@ -58,6 +58,21 @@ struct apml_mcamsr_msg { __u32 pad; }; +struct apml_reg_xfer_msg { + /* + * RMI register address offset + */ + __u16 reg_addr; + /* + * Register data for read/write + */ + __u8 data_in_out; + /* + * Register read or write + */ + __u8 rflag; +}; + /* * AMD sideband interface base IOCTL */ @@ -118,4 +133,20 @@ struct apml_mcamsr_msg { */ #define SBRMI_IOCTL_MCAMSR_CMD _IOWR(SB_BASE_IOCTL_NR, 2, struct apml_mcamsr_msg) +/** + * DOC: SBRMI_IOCTL_REG_XFER_CMD + * + * @Parameters + * + * @struct apml_reg_xfer_msg + * Pointer to the &struct apml_reg_xfer_msg that will contain the protocol + * information + * + * @Description + * IOCTL command for APML messages using generic _IOWR + * The IOCTL provides userspace access to AMD sideband register xfer protocol + * - Register xfer protocol to get/set hardware register for given offset + */ +#define SBRMI_IOCTL_REG_XFER_CMD _IOWR(SB_BASE_IOCTL_NR, 3, struct apml_reg_xfer_msg) + #endif /*_AMD_APML_H_*/ -- cgit v1.3