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-next>] [day] [month] [year] [list]
Message-Id: <1703490474-84730-1-git-send-email-quic_qianyu@quicinc.com>
Date: Mon, 25 Dec 2023 15:47:54 +0800
From: Qiang Yu <quic_qianyu@...cinc.com>
To: mani@...nel.org, quic_jhugo@...cinc.com
Cc: mhi@...ts.linux.dev, linux-arm-msm@...r.kernel.org,
        linux-kernel@...r.kernel.org, quic_cang@...cinc.com,
        quic_mrana@...cinc.com, Bhaumik Bhatt <quic_bbhatt@...cinc.com>,
        Qiang Yu <quic_qianyu@...cinc.com>
Subject: [PATCH] bus: mhi: host: Add sysfs entry to force device to enter EDL

From: Bhaumik Bhatt <quic_bbhatt@...cinc.com>

Forcing the device (eg. SDX75) to enter Emergency Download Mode involves
writing the 0xEDEDEDED cookie to the channel 91 doorbell register and
forcing an SOC reset afterwards. Allow users of the MHI bus to exercise the
sequence using a sysfs entry.

Signed-off-by: Bhaumik Bhatt <quic_bbhatt@...cinc.com>
Signed-off-by: Qiang Yu <quic_qianyu@...cinc.com>
---
 drivers/bus/mhi/host/init.c     | 37 +++++++++++++++++++++++++++++++++++++
 drivers/bus/mhi/host/internal.h |  1 +
 include/linux/mhi.h             |  2 ++
 3 files changed, 40 insertions(+)

diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c
index 65ceac1..4654bc5 100644
--- a/drivers/bus/mhi/host/init.c
+++ b/drivers/bus/mhi/host/init.c
@@ -120,10 +120,46 @@ static ssize_t soc_reset_store(struct device *dev,
 }
 static DEVICE_ATTR_WO(soc_reset);
 
+static ssize_t force_edl_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	struct mhi_device *mhi_dev = to_mhi_device(dev);
+	struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
+	unsigned long val;
+	int ret;
+
+	ret = kstrtoul(buf, 10, &val);
+	if (ret < 0) {
+		dev_err(dev, "Could not parse string: %d\n", ret);
+		return ret;
+	}
+
+	if (!val)
+		return count;
+
+	ret = mhi_device_get_sync(mhi_cntrl->mhi_dev);
+	if (ret)
+		return ret;
+
+	pm_wakeup_event(&mhi_cntrl->mhi_dev->dev, 0);
+	mhi_cntrl->runtime_get(mhi_cntrl);
+
+	mhi_write_db(mhi_cntrl, mhi_cntrl->edl_db, 0xEDEDEDED);
+	mhi_soc_reset(mhi_cntrl);
+
+	mhi_cntrl->runtime_put(mhi_cntrl);
+	mhi_device_put(mhi_cntrl->mhi_dev);
+
+	return count;
+}
+static DEVICE_ATTR_WO(force_edl);
+
 static struct attribute *mhi_dev_attrs[] = {
 	&dev_attr_serial_number.attr,
 	&dev_attr_oem_pk_hash.attr,
 	&dev_attr_soc_reset.attr,
+	&dev_attr_force_edl.attr,
 	NULL,
 };
 ATTRIBUTE_GROUPS(mhi_dev);
@@ -524,6 +560,7 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl)
 
 	/* Setup wake db */
 	mhi_cntrl->wake_db = base + val + (8 * MHI_DEV_WAKE_DB);
+	mhi_cntrl->edl_db = base + val + (8 * MHI_EDL_DB);
 	mhi_cntrl->wake_set = false;
 
 	/* Setup channel db address for each channel in tre_ring */
diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/internal.h
index 30ac415..c414ebf 100644
--- a/drivers/bus/mhi/host/internal.h
+++ b/drivers/bus/mhi/host/internal.h
@@ -128,6 +128,7 @@ enum mhi_pm_state {
 #define CMD_EL_PER_RING					128
 #define PRIMARY_CMD_RING				0
 #define MHI_DEV_WAKE_DB					127
+#define MHI_EDL_DB					91
 #define MHI_MAX_MTU					0xffff
 #define MHI_RANDOM_U32_NONZERO(bmsk)			(get_random_u32_inclusive(1, bmsk))
 
diff --git a/include/linux/mhi.h b/include/linux/mhi.h
index d0f9b522..c754d32 100644
--- a/include/linux/mhi.h
+++ b/include/linux/mhi.h
@@ -298,6 +298,7 @@ struct mhi_controller_config {
  * @bhi: Points to base of MHI BHI register space
  * @bhie: Points to base of MHI BHIe register space
  * @wake_db: MHI WAKE doorbell register address
+ * @edl_db: MHI EDL channel 91 doorbell register address
  * @iova_start: IOMMU starting address for data (required)
  * @iova_stop: IOMMU stop address for data (required)
  * @fw_image: Firmware image name for normal booting (optional)
@@ -387,6 +388,7 @@ struct mhi_controller {
 	void __iomem *bhi;
 	void __iomem *bhie;
 	void __iomem *wake_db;
+	void __iomem *edl_db;
 
 	dma_addr_t iova_start;
 	dma_addr_t iova_stop;
-- 
2.7.4


Powered by blists - more mailing lists