lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <e847c9cf-e3ec-4f0c-a7c9-0a827333a4be@linaro.org>
Date:   Thu, 30 Nov 2023 10:51:55 +0100
From:   Neil Armstrong <neil.armstrong@...aro.org>
To:     Andy Gross <agross@...nel.org>,
        Bjorn Andersson <andersson@...nel.org>,
        Konrad Dybcio <konrad.dybcio@...aro.org>
Cc:     linux-kernel@...r.kernel.org, linux-arm-msm@...r.kernel.org
Subject: Re: [PATCH] soc: qcom: add ADSP PDCharger ULOG driver

Hi Bjorn,

On 08/09/2023 12:53, Neil Armstrong wrote:
> The Qualcomm PMIC PDCharger ULOG driver provides access to logs of
> the ADSP firmware PDCharger module in charge of Battery and Power
> Delivery on modern systems.
> 
> Implement trace events as a simple rpmsg driver with an 1s interval
> to retrieve the messages.
> 
> The interface allows filtering the messages by subsystem and priority
> level, this could be implemented later on.

Any thoughts on this? It's pretty handy to debug PDCharger firmware events,
even more with enhanced usage of UCSI.

Neil

> 
> Signed-off-by: Neil Armstrong <neil.armstrong@...aro.org>
> ---
>   drivers/soc/qcom/Kconfig               |  12 +++
>   drivers/soc/qcom/Makefile              |   1 +
>   drivers/soc/qcom/pmic_pdcharger_ulog.c | 166 +++++++++++++++++++++++++++++++++
>   drivers/soc/qcom/pmic_pdcharger_ulog.h |  36 +++++++
>   4 files changed, 215 insertions(+)
> 
> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
> index e597799e8121..5f63df3d5d6f 100644
> --- a/drivers/soc/qcom/Kconfig
> +++ b/drivers/soc/qcom/Kconfig
> @@ -93,6 +93,18 @@ config QCOM_PDR_HELPERS
>   	select QCOM_QMI_HELPERS
>   	depends on NET
>   
> +config QCOM_PMIC_PDCHARGER_ULOG
> +	tristate "Qualcomm PMIC PDCharger ULOG driver"
> +	depends on RPMSG
> +	depends on EVENT_TRACING
> +	help
> +	  The Qualcomm PMIC PDCharger ULOG driver provides access to logs of
> +	  the ADSP firmware PDCharger module in charge of Battery and Power
> +	  Delivery on modern systems.
> +
> +	  Say yes here to support PDCharger ULOG event tracing on modern
> +	  Qualcomm platforms.
> +
>   config QCOM_PMIC_GLINK
>   	tristate "Qualcomm PMIC GLINK driver"
>   	depends on RPMSG
> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
> index 99114c71092b..44f6efe9a48c 100644
> --- a/drivers/soc/qcom/Makefile
> +++ b/drivers/soc/qcom/Makefile
> @@ -10,6 +10,7 @@ obj-$(CONFIG_QCOM_OCMEM)	+= ocmem.o
>   obj-$(CONFIG_QCOM_PDR_HELPERS)	+= pdr_interface.o
>   obj-$(CONFIG_QCOM_PMIC_GLINK)	+= pmic_glink.o
>   obj-$(CONFIG_QCOM_PMIC_GLINK)	+= pmic_glink_altmode.o
> +obj-$(CONFIG_QCOM_PMIC_PDCHARGER_ULOG)	+= pmic_pdcharger_ulog.o
>   obj-$(CONFIG_QCOM_QMI_HELPERS)	+= qmi_helpers.o
>   qmi_helpers-y	+= qmi_encdec.o qmi_interface.o
>   obj-$(CONFIG_QCOM_RAMP_CTRL)	+= ramp_controller.o
> diff --git a/drivers/soc/qcom/pmic_pdcharger_ulog.c b/drivers/soc/qcom/pmic_pdcharger_ulog.c
> new file mode 100644
> index 000000000000..f1aaacf05005
> --- /dev/null
> +++ b/drivers/soc/qcom/pmic_pdcharger_ulog.c
> @@ -0,0 +1,166 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2019-2022, The Linux Foundation. All rights reserved.
> + * Copyright (c) 2023, Linaro Ltd
> + */
> +#include <linux/of_device.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/rpmsg.h>
> +#include <linux/slab.h>
> +#include <linux/soc/qcom/pdr.h>
> +#include <linux/debugfs.h>
> +
> +#define CREATE_TRACE_POINTS
> +#include "pmic_pdcharger_ulog.h"
> +
> +#define MSG_OWNER_CHG_ULOG		32778
> +#define MSG_TYPE_REQ_RESP		1
> +
> +#define GET_CHG_ULOG_REQ		0x18
> +#define SET_CHG_ULOG_PROP_REQ		0x19
> +
> +#define LOG_DEFAULT_TIME_MS		1000
> +
> +#define MAX_ULOG_SIZE			8192
> +
> +struct pmic_pdcharger_ulog_hdr {
> +	__le32 owner;
> +	__le32 type;
> +	__le32 opcode;
> +};
> +
> +struct pmic_pdcharger_ulog {
> +	struct rpmsg_device *rpdev;
> +	struct delayed_work ulog_work;
> +};
> +
> +struct get_ulog_req_msg {
> +	struct pmic_pdcharger_ulog_hdr	hdr;
> +	u32				log_size;
> +};
> +
> +struct get_ulog_resp_msg {
> +	struct pmic_pdcharger_ulog_hdr	hdr;
> +	u8				buf[MAX_ULOG_SIZE];
> +};
> +
> +static int pmic_pdcharger_ulog_write_async(struct pmic_pdcharger_ulog *pg, void *data, size_t len)
> +{
> +	return rpmsg_send(pg->rpdev->ept, data, len);
> +}
> +
> +static int pmic_pdcharger_ulog_request(struct pmic_pdcharger_ulog *pg)
> +{
> +	struct get_ulog_req_msg req_msg = {
> +		.hdr = {
> +			.owner = MSG_OWNER_CHG_ULOG,
> +			.type = MSG_TYPE_REQ_RESP,
> +			.opcode = GET_CHG_ULOG_REQ
> +		},
> +		.log_size = MAX_ULOG_SIZE
> +	};
> +
> +	return pmic_pdcharger_ulog_write_async(pg, &req_msg, sizeof(req_msg));
> +}
> +
> +static void pmic_pdcharger_ulog_work(struct work_struct *work)
> +{
> +	struct pmic_pdcharger_ulog *pg = container_of(work, struct pmic_pdcharger_ulog,
> +						      ulog_work.work);
> +	int rc;
> +
> +	rc = pmic_pdcharger_ulog_request(pg);
> +	if (rc) {
> +		dev_err(&pg->rpdev->dev, "Error requesting ulog, rc=%d\n", rc);
> +		return;
> +	}
> +}
> +
> +static void pmic_pdcharger_ulog_handle_message(struct pmic_pdcharger_ulog *pg,
> +					       struct get_ulog_resp_msg *resp_msg,
> +					       size_t len)
> +{
> +	char *token, *buf = resp_msg->buf;
> +
> +	if (len != sizeof(*resp_msg)) {
> +		dev_err(&pg->rpdev->dev, "Expected data length: %zu, received: %zu\n",
> +			sizeof(*resp_msg), len);
> +		return;
> +	}
> +
> +	buf[MAX_ULOG_SIZE - 1] = '\0';
> +
> +	do {
> +		token = strsep((char **)&buf, "\n");
> +		if (token && strlen(token))
> +			trace_pmic_pdcharger_ulog_msg(token);
> +	} while (token);
> +}
> +
> +static int pmic_pdcharger_ulog_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
> +					      int len, void *priv, u32 addr)
> +{
> +	struct pmic_pdcharger_ulog *pg = dev_get_drvdata(&rpdev->dev);
> +	struct pmic_pdcharger_ulog_hdr *hdr = data;
> +	u32 opcode;
> +
> +	opcode = le32_to_cpu(hdr->opcode);
> +
> +	switch (opcode) {
> +	case GET_CHG_ULOG_REQ:
> +		schedule_delayed_work(&pg->ulog_work, msecs_to_jiffies(LOG_DEFAULT_TIME_MS));
> +		pmic_pdcharger_ulog_handle_message(pg, data, len);
> +		break;
> +	default:
> +		dev_err(&pg->rpdev->dev, "Unknown opcode %u\n", opcode);
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
> +static int pmic_pdcharger_ulog_rpmsg_probe(struct rpmsg_device *rpdev)
> +{
> +	struct pmic_pdcharger_ulog *pg;
> +	struct device *dev = &rpdev->dev;
> +
> +	pg = devm_kzalloc(dev, sizeof(*pg), GFP_KERNEL);
> +	if (!pg)
> +		return -ENOMEM;
> +
> +	pg->rpdev = rpdev;
> +	INIT_DELAYED_WORK(&pg->ulog_work, pmic_pdcharger_ulog_work);
> +
> +	dev_set_drvdata(dev, pg);
> +
> +	pmic_pdcharger_ulog_request(pg);
> +
> +	return 0;
> +}
> +
> +static void pmic_pdcharger_ulog_rpmsg_remove(struct rpmsg_device *rpdev)
> +{
> +	struct pmic_pdcharger_ulog *pg = dev_get_drvdata(&rpdev->dev);
> +
> +	cancel_delayed_work_sync(&pg->ulog_work);
> +}
> +
> +static const struct rpmsg_device_id pmic_pdcharger_ulog_rpmsg_id_match[] = {
> +	{ "PMIC_LOGS_ADSP_APPS" },
> +	{}
> +};
> +
> +static struct rpmsg_driver pmic_pdcharger_ulog_rpmsg_driver = {
> +	.probe = pmic_pdcharger_ulog_rpmsg_probe,
> +	.remove = pmic_pdcharger_ulog_rpmsg_remove,
> +	.callback = pmic_pdcharger_ulog_rpmsg_callback,
> +	.id_table = pmic_pdcharger_ulog_rpmsg_id_match,
> +	.drv  = {
> +		.name  = "qcom_pmic_pdcharger_ulog_rpmsg",
> +	},
> +};
> +
> +module_rpmsg_driver(pmic_pdcharger_ulog_rpmsg_driver);
> +MODULE_DESCRIPTION("Qualcomm PMIC ChargerPD ULOG driver");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/soc/qcom/pmic_pdcharger_ulog.h b/drivers/soc/qcom/pmic_pdcharger_ulog.h
> new file mode 100644
> index 000000000000..9d5d9af4fbe4
> --- /dev/null
> +++ b/drivers/soc/qcom/pmic_pdcharger_ulog.h
> @@ -0,0 +1,36 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2023, Linaro Ltd
> + */
> +
> +#if !defined(_TRACE_PMIC_PDCHARGER_ULOG_H) || defined(TRACE_HEADER_MULTI_READ)
> +#define _TRACE_PMIC_PDCHARGER_ULOG_H
> +
> +#include <linux/tracepoint.h>
> +
> +#undef TRACE_SYSTEM
> +#define TRACE_SYSTEM pmic_pdcharger_ulog
> +
> +TRACE_EVENT(pmic_pdcharger_ulog_msg,
> +	TP_PROTO(char *msg),
> +	TP_ARGS(msg),
> +	TP_STRUCT__entry(
> +		__string(msg, msg)
> +	),
> +	TP_fast_assign(
> +		__assign_str(msg, msg);
> +	),
> +	TP_printk("%s", __get_str(msg))
> +);
> +
> +#endif /* _TRACE_PMIC_PDCHARGER_ULOG_H */
> +
> +/* This part must be outside protection */
> +
> +#undef TRACE_INCLUDE_PATH
> +#define TRACE_INCLUDE_PATH .
> +
> +#undef TRACE_INCLUDE_FILE
> +#define TRACE_INCLUDE_FILE pmic_pdcharger_ulog
> +
> +#include <trace/define_trace.h>
> 
> ---
> base-commit: 2dde18cd1d8fac735875f2e4987f11817cc0bc2c
> change-id: 20230908-topic-sm8550-upstream-pdcharge-ulog-21ece9292474
> 
> Best regards,

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ