Re: [PATCH 5/7] firmware: arm_scmi: imx: Support getting syslog of MISC protocol
From: Peng Fan <hidden>
Date: 2025-06-30 01:59:06
Also in:
arm-scmi, imx, lkml
Hi Cristian, On Fri, Jun 27, 2025 at 02:44:00PM +0100, Cristian Marussi wrote:
On Fri, Jun 27, 2025 at 02:03:48PM +0800, Peng Fan wrote:quoted
MISC protocol supports getting system log regarding system sleep latency ,wakeup interrupt and etc. Add the API for user to retrieve the information from SM. Signed-off-by: Peng Fan <peng.fan@nxp.com> --- .../firmware/arm_scmi/vendors/imx/imx-sm-misc.c | 78 ++++++++++++++++++++++ include/linux/scmi_imx_protocol.h | 19 ++++++ 2 files changed, 97 insertions(+)diff --git a/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c b/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c index d5b24bc4d4ca6c19f4cddfaea6e9d9b32a4c92f7..1a6d75357b76ce6bb7d06461999b368c27f1fa43 100644 --- a/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c +++ b/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c@@ -28,6 +28,7 @@ enum scmi_imx_misc_protocol_cmd { SCMI_IMX_MISC_DISCOVER_BUILDINFO = 0x6, SCMI_IMX_MISC_SI_INFO = 0xB, SCMI_IMX_MISC_CFG_INFO = 0xC, + SCMI_IMX_MISC_SYSLOG = 0xD, SCMI_IMX_MISC_CTRL_NOTIFY = 0x8, };@@ -87,6 +88,19 @@ struct scmi_imx_misc_si_info_out { u8 siname[MISC_MAX_SINAME]; }; +struct scmi_imx_misc_syslog_in { + __le32 flags; + __le32 index; +}; + +#define REMAINING(x) le32_get_bits((x), GENMASK(31, 20)) +#define RETURNED(x) le32_get_bits((x), GENMASK(11, 0)) + +struct scmi_imx_misc_syslog_out { + __le32 numlogflags; + __le32 syslog[]; +}; + static int scmi_imx_misc_attributes_get(const struct scmi_protocol_handle *ph, struct scmi_imx_misc_info *mi) {@@ -368,6 +382,69 @@ static int scmi_imx_misc_silicon_info(const struct scmi_protocol_handle *ph, return ret; } +struct scmi_imx_misc_syslog_ipriv { + u32 *array; +}; + +static void iter_misc_syslog_prepare_message(void *message, u32 desc_index, + const void *priv) +{ + struct scmi_imx_misc_syslog_in *msg = message; + + msg->flags = cpu_to_le32(0); + msg->index = cpu_to_le32(desc_index); +} + +static int iter_misc_syslog_update_state(struct scmi_iterator_state *st, + const void *response, void *priv) +{ + const struct scmi_imx_misc_syslog_out *r = response; + + st->num_returned = RETURNED(r->numlogflags); + st->num_remaining = REMAINING(r->numlogflags); + + return 0; +} + +static int +iter_misc_syslog_process_response(const struct scmi_protocol_handle *ph, + const void *response, + struct scmi_iterator_state *st, void *priv) +{ + const struct scmi_imx_misc_syslog_out *r = response; + struct scmi_imx_misc_syslog_ipriv *p = priv; + + p->array[st->desc_index + st->loop_idx] = + le32_to_cpu(r->syslog[st->loop_idx]); + + return 0; +} + +static int scmi_imx_misc_syslog(const struct scmi_protocol_handle *ph, u16 size, + void *array) +{...so this size...quoted
+ struct scmi_iterator_ops ops = { + .prepare_message = iter_misc_syslog_prepare_message, + .update_state = iter_misc_syslog_update_state, + .process_response = iter_misc_syslog_process_response, + }; + struct scmi_imx_misc_syslog_ipriv ipriv = { + .array = array, + }; + void *iter; + + if (!array || !size) + return -EINVAL; +...which cannot be zero and is passed down to the iterator as max_resources is meant to repreent also the length of tthe array passed here as an argument and filled-in by the iterators ? ...and so basically array bounds-checking is enforced by the iterators core code, because no matter what, it is always enforced that (returned + remaining <= max_resources (size)
Right. I think set size to 0 does not make sense, so add a '(!size)' check
...I am fine with this, I am just trying to understand and see if I can find a mishap :Dquoted
+ iter = ph->hops->iter_response_init(ph, &ops, size, SCMI_IMX_MISC_SYSLOG, + sizeof(struct scmi_imx_misc_syslog_in), + &ipriv); + if (IS_ERR(iter)) + return PTR_ERR(iter); + + return ph->hops->iter_response_run(iter); +} + static const struct scmi_imx_misc_proto_ops scmi_imx_misc_proto_ops = { .misc_cfg_info = scmi_imx_misc_cfg_info, .misc_ctrl_set = scmi_imx_misc_ctrl_set,@@ -375,6 +452,7 @@ static const struct scmi_imx_misc_proto_ops scmi_imx_misc_proto_ops = { .misc_ctrl_req_notify = scmi_imx_misc_ctrl_notify, .misc_discover_build_info = scmi_imx_discover_build_info, .misc_silicon_info = scmi_imx_misc_silicon_info, + .misc_syslog = scmi_imx_misc_syslog, }; static int scmi_imx_misc_protocol_init(const struct scmi_protocol_handle *ph)diff --git a/include/linux/scmi_imx_protocol.h b/include/linux/scmi_imx_protocol.h index 0e639dfb5d16e281e2ccf006a63694b316c431f4..ff34d974046aa982fa9f5d46fc673412e01a532d 100644 --- a/include/linux/scmi_imx_protocol.h +++ b/include/linux/scmi_imx_protocol.h@@ -71,6 +71,23 @@ struct scmi_imx_misc_system_info { u8 siname[MISC_MAX_SINAME]; }; +struct scmi_imx_misc_sys_sleep_rec { + u32 sleepentryusec; + u32 sleepexitusec; + u32 sleepcnt; + u32 wakesource; + u32 mixpwrstat; + u32 mempwrstat; + u32 pllpwrstat; + u32 syssleepmode; + u32 syssleepflags; +};So where is this used ? later in the series ?quoted
+ +struct scmi_imx_misc_syslog { + struct scmi_imx_misc_sys_sleep_rec syssleeprecord;
Included here, but used in last patch in the patchset.
quoted
+ uint32_t deverrlog; +}; + struct scmi_imx_misc_proto_ops { int (*misc_cfg_info)(const struct scmi_protocol_handle *ph, struct scmi_imx_misc_system_info *info);@@ -84,6 +101,8 @@ struct scmi_imx_misc_proto_ops { struct scmi_imx_misc_system_info *info); int (*misc_silicon_info)(const struct scmi_protocol_handle *ph, struct scmi_imx_misc_system_info *info); + int (*misc_syslog)(const struct scmi_protocol_handle *ph, u16 size, + void *array); };
Thanks, Peng
Thanks, Cristian