All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Baluta <daniel.baluta@oss.nxp.com>
To: broonie@kernel.org, alsa-devel@alsa-project.org
Cc: pierre-louis.bossart@linux.intel.com, lgirdwood@gmail.com,
	daniel.baluta@nxp.com, daniel.baluta@gmail.com,
	AjitKumar.Pandey@amd.com, Balakishore.pati@amd.com,
	vsreddy@amd.com, Julian.Schroeder@amd.com,
	vishnuvardhanrao.ravulapati@amd.com,
	linux-kernel@vger.kernel.org, yc.hung@mediatek.com,
	linux-mediatek@lists.infradead.org,
	Ranjani Sridharan <ranjani.sridharan@linux.intel.com>,
	Curtis Malainey <curtis@malainey.com>
Subject: [PATCH 13/21] ASoC: SOF: amd: Add support for SOF firmware authentication
Date: Wed, 17 Nov 2021 11:37:26 +0200	[thread overview]
Message-ID: <20211117093734.17407-14-daniel.baluta@oss.nxp.com> (raw)
In-Reply-To: <20211117093734.17407-1-daniel.baluta@oss.nxp.com>

From: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>

Add callback to notify PSP after loading firmware on DSP. PSP will
validate the loaded firmware and set qualifier bit to run firmware
on secured AMD systems.

Signed-off-by: Julian Schroeder <Julian.Schroeder@amd.com>
Signed-off-by: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Curtis Malainey <curtis@malainey.com>
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
---
 sound/soc/sof/amd/acp-dsp-offset.h |  4 ++
 sound/soc/sof/amd/acp.c            | 66 +++++++++++++++++++++++++++++-
 sound/soc/sof/amd/acp.h            | 21 ++++++++++
 sound/soc/sof/amd/pci-rn.c         |  5 +++
 4 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/sound/soc/sof/amd/acp-dsp-offset.h b/sound/soc/sof/amd/acp-dsp-offset.h
index 1d11e9d69dce..63f13c111b24 100644
--- a/sound/soc/sof/amd/acp-dsp-offset.h
+++ b/sound/soc/sof/amd/acp-dsp-offset.h
@@ -54,6 +54,9 @@
 #define ACP_PGFSM_STATUS			0x1420
 
 /* Registers from ACP_INTR block */
+#define ACP_EXTERNAL_INTR_ENB			0x1800
+#define ACP_EXTERNAL_INTR_CNTL			0x1804
+#define ACP_EXTERNAL_INTR_STAT			0x1808
 #define ACP_DSP_SW_INTR_CNTL			0x1814
 #define ACP_DSP_SW_INTR_STAT                    0x1818
 #define ACP_SW_INTR_TRIG                        0x181C
@@ -68,6 +71,7 @@
 #define ACP_SHA_DMA_CMD_STS			0x1CC0
 #define ACP_SHA_DMA_ERR_STATUS			0x1CC4
 #define ACP_SHA_TRANSFER_BYTE_CNT		0x1CC8
+#define ACP_SHA_PSP_ACK                         0x1C74
 
 #define ACP_SCRATCH_REG_0			0x10000
 
diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c
index 74ede28aa8d8..4c5550e8d364 100644
--- a/sound/soc/sof/amd/acp.c
+++ b/sound/soc/sof/amd/acp.c
@@ -20,6 +20,22 @@
 #include "acp.h"
 #include "acp-dsp-offset.h"
 
+static int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data)
+{
+	pci_write_config_dword(dev, 0x60, smn_addr);
+	pci_write_config_dword(dev, 0x64, data);
+
+	return 0;
+}
+
+static int smn_read(struct pci_dev *dev, u32 smn_addr, u32 *data)
+{
+	pci_write_config_dword(dev, 0x60, smn_addr);
+	pci_read_config_dword(dev, 0x64, data);
+
+	return 0;
+}
+
 static void configure_acp_groupregisters(struct acp_dev_data *adata)
 {
 	struct snd_sof_dev *sdev = adata->dev;
@@ -135,6 +151,25 @@ int configure_and_run_dma(struct acp_dev_data *adata, unsigned int src_addr,
 	return ret;
 }
 
+static int psp_fw_validate(struct acp_dev_data *adata)
+{
+	struct snd_sof_dev *sdev = adata->dev;
+	int timeout;
+	u32 data;
+
+	smn_write(adata->smn_dev, MP0_C2PMSG_26_REG, MBOX_ACP_SHA_DMA_COMMAND);
+
+	for (timeout = ACP_PSP_TIMEOUT_COUNTER; timeout > 0; timeout--) {
+		msleep(20);
+		smn_read(adata->smn_dev, MP0_C2PMSG_26_REG, &data);
+		if (data & MBOX_READY_MASK)
+			return 0;
+	}
+
+	dev_err(sdev->dev, "FW validation timedout: status %x\n", data & MBOX_STATUS_MASK);
+	return -ETIMEDOUT;
+}
+
 int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
 			      unsigned int start_addr, unsigned int dest_addr,
 			      unsigned int image_length)
@@ -174,7 +209,9 @@ int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
 		return ret;
 	}
 
-	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DSP_FW_QUALIFIER, DSP_FW_RUN_ENABLE);
+	ret = psp_fw_validate(adata);
+	if (ret)
+		return ret;
 
 	fw_qualifier = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SHA_DSP_FW_QUALIFIER);
 	if (!(fw_qualifier & DSP_FW_RUN_ENABLE)) {
@@ -238,6 +275,13 @@ static irqreturn_t acp_irq_thread(int irq, void *context)
 	struct snd_sof_dev *sdev = context;
 	unsigned int val;
 
+	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_EXTERNAL_INTR_STAT);
+	if (val & ACP_SHA_STAT) {
+		/* Clear SHA interrupt raised by PSP */
+		snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_EXTERNAL_INTR_STAT, val);
+		return IRQ_HANDLED;
+	}
+
 	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT);
 	if (val & ACP_DSP_TO_HOST_IRQ) {
 		sof_ops(sdev)->irq_thread(irq, sdev);
@@ -326,6 +370,7 @@ int amd_sof_acp_probe(struct snd_sof_dev *sdev)
 {
 	struct pci_dev *pci = to_pci_dev(sdev->dev);
 	struct acp_dev_data *adata;
+	const struct sof_amd_acp_desc *chip;
 	unsigned int addr;
 	int ret;
 
@@ -346,18 +391,32 @@ int amd_sof_acp_probe(struct snd_sof_dev *sdev)
 
 	sdev->pdata->hw_pdata = adata;
 
+	chip = get_chip_info(sdev->pdata);
+	if (!chip) {
+		dev_err(sdev->dev, "no such device supported, chip id:%x\n", pci->device);
+		return -EIO;
+	}
+
+	adata->smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, chip->host_bridge_id, NULL);
+	if (!adata->smn_dev) {
+		dev_err(sdev->dev, "Failed to get host bridge device\n");
+		return -ENODEV;
+	}
+
 	sdev->ipc_irq = pci->irq;
 	ret = request_threaded_irq(sdev->ipc_irq, acp_irq_handler, acp_irq_thread,
 				   IRQF_SHARED, "AudioDSP", sdev);
 	if (ret < 0) {
 		dev_err(sdev->dev, "failed to register IRQ %d\n",
 			sdev->ipc_irq);
+		pci_dev_put(adata->smn_dev);
 		return ret;
 	}
 
 	ret = acp_init(sdev);
 	if (ret < 0) {
 		free_irq(sdev->ipc_irq, sdev);
+		pci_dev_put(adata->smn_dev);
 		return ret;
 	}
 
@@ -371,6 +430,11 @@ EXPORT_SYMBOL_NS(amd_sof_acp_probe, SND_SOC_SOF_AMD_COMMON);
 
 int amd_sof_acp_remove(struct snd_sof_dev *sdev)
 {
+	struct acp_dev_data *adata = sdev->pdata->hw_pdata;
+
+	if (adata->smn_dev)
+		pci_dev_put(adata->smn_dev);
+
 	if (sdev->ipc_irq)
 		free_irq(sdev->ipc_irq, sdev);
 
diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
index fd923f72a01a..a2f8e4219066 100644
--- a/sound/soc/sof/amd/acp.h
+++ b/sound/soc/sof/amd/acp.h
@@ -52,6 +52,15 @@
 
 #define ACP_DSP_TO_HOST_IRQ			0x04
 
+#define HOST_BRIDGE_CZN				0x1630
+#define ACP_SHA_STAT				0x8000
+#define ACP_PSP_TIMEOUT_COUNTER			5
+#define ACP_EXT_INTR_ERROR_STAT			0x20000000
+#define MP0_C2PMSG_26_REG			0x03810570
+#define MBOX_ACP_SHA_DMA_COMMAND		0x330000
+#define MBOX_READY_MASK				0x80000000
+#define MBOX_STATUS_MASK			0xFFFF
+
 struct  acp_atu_grp_pte {
 	u32 low;
 	u32 high;
@@ -140,6 +149,7 @@ struct acp_dev_data {
 	struct dma_descriptor dscr_info[ACP_MAX_DESC];
 	struct acp_dsp_stream stream_buf[ACP_MAX_STREAM];
 	struct acp_dsp_stream *dtrace_stream;
+	struct pci_dev *smn_dev;
 };
 
 void memcpy_to_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *src, size_t bytes);
@@ -202,4 +212,15 @@ int snd_amd_acp_find_config(struct pci_dev *pci);
 /* Trace */
 int acp_sof_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag);
 int acp_sof_trace_release(struct snd_sof_dev *sdev);
+
+struct sof_amd_acp_desc {
+	unsigned int host_bridge_id;
+};
+
+static inline const struct sof_amd_acp_desc *get_chip_info(struct snd_sof_pdata *pdata)
+{
+	const struct sof_dev_desc *desc = pdata->desc;
+
+	return desc->chip_info;
+}
 #endif
diff --git a/sound/soc/sof/amd/pci-rn.c b/sound/soc/sof/amd/pci-rn.c
index 3c379a5ef231..392ffbdf6417 100644
--- a/sound/soc/sof/amd/pci-rn.c
+++ b/sound/soc/sof/amd/pci-rn.c
@@ -43,12 +43,17 @@ static const struct resource renoir_res[] = {
 	},
 };
 
+static const struct sof_amd_acp_desc renoir_chip_info = {
+	.host_bridge_id = HOST_BRIDGE_CZN,
+};
+
 static const struct sof_dev_desc renoir_desc = {
 	.machines		= snd_soc_acpi_amd_sof_machines,
 	.resindex_lpe_base	= 0,
 	.resindex_pcicfg_base	= -1,
 	.resindex_imr_base	= -1,
 	.irqindex_host_ipc	= -1,
+	.chip_info		= &renoir_chip_info,
 	.default_fw_path	= "amd/sof",
 	.default_tplg_path	= "amd/sof-tplg",
 	.default_fw_filename	= "sof-rn.ri",
-- 
2.27.0


WARNING: multiple messages have this Message-ID (diff)
From: Daniel Baluta <daniel.baluta@oss.nxp.com>
To: broonie@kernel.org, alsa-devel@alsa-project.org
Cc: pierre-louis.bossart@linux.intel.com, lgirdwood@gmail.com,
	daniel.baluta@nxp.com, daniel.baluta@gmail.com,
	AjitKumar.Pandey@amd.com, Balakishore.pati@amd.com,
	vsreddy@amd.com, Julian.Schroeder@amd.com,
	vishnuvardhanrao.ravulapati@amd.com,
	linux-kernel@vger.kernel.org, yc.hung@mediatek.com,
	linux-mediatek@lists.infradead.org,
	Ranjani Sridharan <ranjani.sridharan@linux.intel.com>,
	Curtis Malainey <curtis@malainey.com>
Subject: [PATCH 13/21] ASoC: SOF: amd: Add support for SOF firmware authentication
Date: Wed, 17 Nov 2021 11:37:26 +0200	[thread overview]
Message-ID: <20211117093734.17407-14-daniel.baluta@oss.nxp.com> (raw)
In-Reply-To: <20211117093734.17407-1-daniel.baluta@oss.nxp.com>

From: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>

Add callback to notify PSP after loading firmware on DSP. PSP will
validate the loaded firmware and set qualifier bit to run firmware
on secured AMD systems.

Signed-off-by: Julian Schroeder <Julian.Schroeder@amd.com>
Signed-off-by: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Curtis Malainey <curtis@malainey.com>
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
---
 sound/soc/sof/amd/acp-dsp-offset.h |  4 ++
 sound/soc/sof/amd/acp.c            | 66 +++++++++++++++++++++++++++++-
 sound/soc/sof/amd/acp.h            | 21 ++++++++++
 sound/soc/sof/amd/pci-rn.c         |  5 +++
 4 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/sound/soc/sof/amd/acp-dsp-offset.h b/sound/soc/sof/amd/acp-dsp-offset.h
index 1d11e9d69dce..63f13c111b24 100644
--- a/sound/soc/sof/amd/acp-dsp-offset.h
+++ b/sound/soc/sof/amd/acp-dsp-offset.h
@@ -54,6 +54,9 @@
 #define ACP_PGFSM_STATUS			0x1420
 
 /* Registers from ACP_INTR block */
+#define ACP_EXTERNAL_INTR_ENB			0x1800
+#define ACP_EXTERNAL_INTR_CNTL			0x1804
+#define ACP_EXTERNAL_INTR_STAT			0x1808
 #define ACP_DSP_SW_INTR_CNTL			0x1814
 #define ACP_DSP_SW_INTR_STAT                    0x1818
 #define ACP_SW_INTR_TRIG                        0x181C
@@ -68,6 +71,7 @@
 #define ACP_SHA_DMA_CMD_STS			0x1CC0
 #define ACP_SHA_DMA_ERR_STATUS			0x1CC4
 #define ACP_SHA_TRANSFER_BYTE_CNT		0x1CC8
+#define ACP_SHA_PSP_ACK                         0x1C74
 
 #define ACP_SCRATCH_REG_0			0x10000
 
diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c
index 74ede28aa8d8..4c5550e8d364 100644
--- a/sound/soc/sof/amd/acp.c
+++ b/sound/soc/sof/amd/acp.c
@@ -20,6 +20,22 @@
 #include "acp.h"
 #include "acp-dsp-offset.h"
 
+static int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data)
+{
+	pci_write_config_dword(dev, 0x60, smn_addr);
+	pci_write_config_dword(dev, 0x64, data);
+
+	return 0;
+}
+
+static int smn_read(struct pci_dev *dev, u32 smn_addr, u32 *data)
+{
+	pci_write_config_dword(dev, 0x60, smn_addr);
+	pci_read_config_dword(dev, 0x64, data);
+
+	return 0;
+}
+
 static void configure_acp_groupregisters(struct acp_dev_data *adata)
 {
 	struct snd_sof_dev *sdev = adata->dev;
@@ -135,6 +151,25 @@ int configure_and_run_dma(struct acp_dev_data *adata, unsigned int src_addr,
 	return ret;
 }
 
+static int psp_fw_validate(struct acp_dev_data *adata)
+{
+	struct snd_sof_dev *sdev = adata->dev;
+	int timeout;
+	u32 data;
+
+	smn_write(adata->smn_dev, MP0_C2PMSG_26_REG, MBOX_ACP_SHA_DMA_COMMAND);
+
+	for (timeout = ACP_PSP_TIMEOUT_COUNTER; timeout > 0; timeout--) {
+		msleep(20);
+		smn_read(adata->smn_dev, MP0_C2PMSG_26_REG, &data);
+		if (data & MBOX_READY_MASK)
+			return 0;
+	}
+
+	dev_err(sdev->dev, "FW validation timedout: status %x\n", data & MBOX_STATUS_MASK);
+	return -ETIMEDOUT;
+}
+
 int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
 			      unsigned int start_addr, unsigned int dest_addr,
 			      unsigned int image_length)
@@ -174,7 +209,9 @@ int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
 		return ret;
 	}
 
-	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DSP_FW_QUALIFIER, DSP_FW_RUN_ENABLE);
+	ret = psp_fw_validate(adata);
+	if (ret)
+		return ret;
 
 	fw_qualifier = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SHA_DSP_FW_QUALIFIER);
 	if (!(fw_qualifier & DSP_FW_RUN_ENABLE)) {
@@ -238,6 +275,13 @@ static irqreturn_t acp_irq_thread(int irq, void *context)
 	struct snd_sof_dev *sdev = context;
 	unsigned int val;
 
+	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_EXTERNAL_INTR_STAT);
+	if (val & ACP_SHA_STAT) {
+		/* Clear SHA interrupt raised by PSP */
+		snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_EXTERNAL_INTR_STAT, val);
+		return IRQ_HANDLED;
+	}
+
 	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT);
 	if (val & ACP_DSP_TO_HOST_IRQ) {
 		sof_ops(sdev)->irq_thread(irq, sdev);
@@ -326,6 +370,7 @@ int amd_sof_acp_probe(struct snd_sof_dev *sdev)
 {
 	struct pci_dev *pci = to_pci_dev(sdev->dev);
 	struct acp_dev_data *adata;
+	const struct sof_amd_acp_desc *chip;
 	unsigned int addr;
 	int ret;
 
@@ -346,18 +391,32 @@ int amd_sof_acp_probe(struct snd_sof_dev *sdev)
 
 	sdev->pdata->hw_pdata = adata;
 
+	chip = get_chip_info(sdev->pdata);
+	if (!chip) {
+		dev_err(sdev->dev, "no such device supported, chip id:%x\n", pci->device);
+		return -EIO;
+	}
+
+	adata->smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, chip->host_bridge_id, NULL);
+	if (!adata->smn_dev) {
+		dev_err(sdev->dev, "Failed to get host bridge device\n");
+		return -ENODEV;
+	}
+
 	sdev->ipc_irq = pci->irq;
 	ret = request_threaded_irq(sdev->ipc_irq, acp_irq_handler, acp_irq_thread,
 				   IRQF_SHARED, "AudioDSP", sdev);
 	if (ret < 0) {
 		dev_err(sdev->dev, "failed to register IRQ %d\n",
 			sdev->ipc_irq);
+		pci_dev_put(adata->smn_dev);
 		return ret;
 	}
 
 	ret = acp_init(sdev);
 	if (ret < 0) {
 		free_irq(sdev->ipc_irq, sdev);
+		pci_dev_put(adata->smn_dev);
 		return ret;
 	}
 
@@ -371,6 +430,11 @@ EXPORT_SYMBOL_NS(amd_sof_acp_probe, SND_SOC_SOF_AMD_COMMON);
 
 int amd_sof_acp_remove(struct snd_sof_dev *sdev)
 {
+	struct acp_dev_data *adata = sdev->pdata->hw_pdata;
+
+	if (adata->smn_dev)
+		pci_dev_put(adata->smn_dev);
+
 	if (sdev->ipc_irq)
 		free_irq(sdev->ipc_irq, sdev);
 
diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
index fd923f72a01a..a2f8e4219066 100644
--- a/sound/soc/sof/amd/acp.h
+++ b/sound/soc/sof/amd/acp.h
@@ -52,6 +52,15 @@
 
 #define ACP_DSP_TO_HOST_IRQ			0x04
 
+#define HOST_BRIDGE_CZN				0x1630
+#define ACP_SHA_STAT				0x8000
+#define ACP_PSP_TIMEOUT_COUNTER			5
+#define ACP_EXT_INTR_ERROR_STAT			0x20000000
+#define MP0_C2PMSG_26_REG			0x03810570
+#define MBOX_ACP_SHA_DMA_COMMAND		0x330000
+#define MBOX_READY_MASK				0x80000000
+#define MBOX_STATUS_MASK			0xFFFF
+
 struct  acp_atu_grp_pte {
 	u32 low;
 	u32 high;
@@ -140,6 +149,7 @@ struct acp_dev_data {
 	struct dma_descriptor dscr_info[ACP_MAX_DESC];
 	struct acp_dsp_stream stream_buf[ACP_MAX_STREAM];
 	struct acp_dsp_stream *dtrace_stream;
+	struct pci_dev *smn_dev;
 };
 
 void memcpy_to_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *src, size_t bytes);
@@ -202,4 +212,15 @@ int snd_amd_acp_find_config(struct pci_dev *pci);
 /* Trace */
 int acp_sof_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag);
 int acp_sof_trace_release(struct snd_sof_dev *sdev);
+
+struct sof_amd_acp_desc {
+	unsigned int host_bridge_id;
+};
+
+static inline const struct sof_amd_acp_desc *get_chip_info(struct snd_sof_pdata *pdata)
+{
+	const struct sof_dev_desc *desc = pdata->desc;
+
+	return desc->chip_info;
+}
 #endif
diff --git a/sound/soc/sof/amd/pci-rn.c b/sound/soc/sof/amd/pci-rn.c
index 3c379a5ef231..392ffbdf6417 100644
--- a/sound/soc/sof/amd/pci-rn.c
+++ b/sound/soc/sof/amd/pci-rn.c
@@ -43,12 +43,17 @@ static const struct resource renoir_res[] = {
 	},
 };
 
+static const struct sof_amd_acp_desc renoir_chip_info = {
+	.host_bridge_id = HOST_BRIDGE_CZN,
+};
+
 static const struct sof_dev_desc renoir_desc = {
 	.machines		= snd_soc_acpi_amd_sof_machines,
 	.resindex_lpe_base	= 0,
 	.resindex_pcicfg_base	= -1,
 	.resindex_imr_base	= -1,
 	.irqindex_host_ipc	= -1,
+	.chip_info		= &renoir_chip_info,
 	.default_fw_path	= "amd/sof",
 	.default_tplg_path	= "amd/sof-tplg",
 	.default_fw_filename	= "sof-rn.ri",
-- 
2.27.0


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

WARNING: multiple messages have this Message-ID (diff)
From: Daniel Baluta <daniel.baluta@oss.nxp.com>
To: broonie@kernel.org, alsa-devel@alsa-project.org
Cc: daniel.baluta@gmail.com, AjitKumar.Pandey@amd.com,
	Curtis Malainey <curtis@malainey.com>,
	linux-kernel@vger.kernel.org,
	pierre-louis.bossart@linux.intel.com, lgirdwood@gmail.com,
	Julian.Schroeder@amd.com, linux-mediatek@lists.infradead.org,
	Ranjani Sridharan <ranjani.sridharan@linux.intel.com>,
	Balakishore.pati@amd.com, yc.hung@mediatek.com,
	vishnuvardhanrao.ravulapati@amd.com, vsreddy@amd.com,
	daniel.baluta@nxp.com
Subject: [PATCH 13/21] ASoC: SOF: amd: Add support for SOF firmware authentication
Date: Wed, 17 Nov 2021 11:37:26 +0200	[thread overview]
Message-ID: <20211117093734.17407-14-daniel.baluta@oss.nxp.com> (raw)
In-Reply-To: <20211117093734.17407-1-daniel.baluta@oss.nxp.com>

From: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>

Add callback to notify PSP after loading firmware on DSP. PSP will
validate the loaded firmware and set qualifier bit to run firmware
on secured AMD systems.

Signed-off-by: Julian Schroeder <Julian.Schroeder@amd.com>
Signed-off-by: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Curtis Malainey <curtis@malainey.com>
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
---
 sound/soc/sof/amd/acp-dsp-offset.h |  4 ++
 sound/soc/sof/amd/acp.c            | 66 +++++++++++++++++++++++++++++-
 sound/soc/sof/amd/acp.h            | 21 ++++++++++
 sound/soc/sof/amd/pci-rn.c         |  5 +++
 4 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/sound/soc/sof/amd/acp-dsp-offset.h b/sound/soc/sof/amd/acp-dsp-offset.h
index 1d11e9d69dce..63f13c111b24 100644
--- a/sound/soc/sof/amd/acp-dsp-offset.h
+++ b/sound/soc/sof/amd/acp-dsp-offset.h
@@ -54,6 +54,9 @@
 #define ACP_PGFSM_STATUS			0x1420
 
 /* Registers from ACP_INTR block */
+#define ACP_EXTERNAL_INTR_ENB			0x1800
+#define ACP_EXTERNAL_INTR_CNTL			0x1804
+#define ACP_EXTERNAL_INTR_STAT			0x1808
 #define ACP_DSP_SW_INTR_CNTL			0x1814
 #define ACP_DSP_SW_INTR_STAT                    0x1818
 #define ACP_SW_INTR_TRIG                        0x181C
@@ -68,6 +71,7 @@
 #define ACP_SHA_DMA_CMD_STS			0x1CC0
 #define ACP_SHA_DMA_ERR_STATUS			0x1CC4
 #define ACP_SHA_TRANSFER_BYTE_CNT		0x1CC8
+#define ACP_SHA_PSP_ACK                         0x1C74
 
 #define ACP_SCRATCH_REG_0			0x10000
 
diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c
index 74ede28aa8d8..4c5550e8d364 100644
--- a/sound/soc/sof/amd/acp.c
+++ b/sound/soc/sof/amd/acp.c
@@ -20,6 +20,22 @@
 #include "acp.h"
 #include "acp-dsp-offset.h"
 
+static int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data)
+{
+	pci_write_config_dword(dev, 0x60, smn_addr);
+	pci_write_config_dword(dev, 0x64, data);
+
+	return 0;
+}
+
+static int smn_read(struct pci_dev *dev, u32 smn_addr, u32 *data)
+{
+	pci_write_config_dword(dev, 0x60, smn_addr);
+	pci_read_config_dword(dev, 0x64, data);
+
+	return 0;
+}
+
 static void configure_acp_groupregisters(struct acp_dev_data *adata)
 {
 	struct snd_sof_dev *sdev = adata->dev;
@@ -135,6 +151,25 @@ int configure_and_run_dma(struct acp_dev_data *adata, unsigned int src_addr,
 	return ret;
 }
 
+static int psp_fw_validate(struct acp_dev_data *adata)
+{
+	struct snd_sof_dev *sdev = adata->dev;
+	int timeout;
+	u32 data;
+
+	smn_write(adata->smn_dev, MP0_C2PMSG_26_REG, MBOX_ACP_SHA_DMA_COMMAND);
+
+	for (timeout = ACP_PSP_TIMEOUT_COUNTER; timeout > 0; timeout--) {
+		msleep(20);
+		smn_read(adata->smn_dev, MP0_C2PMSG_26_REG, &data);
+		if (data & MBOX_READY_MASK)
+			return 0;
+	}
+
+	dev_err(sdev->dev, "FW validation timedout: status %x\n", data & MBOX_STATUS_MASK);
+	return -ETIMEDOUT;
+}
+
 int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
 			      unsigned int start_addr, unsigned int dest_addr,
 			      unsigned int image_length)
@@ -174,7 +209,9 @@ int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
 		return ret;
 	}
 
-	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DSP_FW_QUALIFIER, DSP_FW_RUN_ENABLE);
+	ret = psp_fw_validate(adata);
+	if (ret)
+		return ret;
 
 	fw_qualifier = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SHA_DSP_FW_QUALIFIER);
 	if (!(fw_qualifier & DSP_FW_RUN_ENABLE)) {
@@ -238,6 +275,13 @@ static irqreturn_t acp_irq_thread(int irq, void *context)
 	struct snd_sof_dev *sdev = context;
 	unsigned int val;
 
+	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_EXTERNAL_INTR_STAT);
+	if (val & ACP_SHA_STAT) {
+		/* Clear SHA interrupt raised by PSP */
+		snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_EXTERNAL_INTR_STAT, val);
+		return IRQ_HANDLED;
+	}
+
 	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT);
 	if (val & ACP_DSP_TO_HOST_IRQ) {
 		sof_ops(sdev)->irq_thread(irq, sdev);
@@ -326,6 +370,7 @@ int amd_sof_acp_probe(struct snd_sof_dev *sdev)
 {
 	struct pci_dev *pci = to_pci_dev(sdev->dev);
 	struct acp_dev_data *adata;
+	const struct sof_amd_acp_desc *chip;
 	unsigned int addr;
 	int ret;
 
@@ -346,18 +391,32 @@ int amd_sof_acp_probe(struct snd_sof_dev *sdev)
 
 	sdev->pdata->hw_pdata = adata;
 
+	chip = get_chip_info(sdev->pdata);
+	if (!chip) {
+		dev_err(sdev->dev, "no such device supported, chip id:%x\n", pci->device);
+		return -EIO;
+	}
+
+	adata->smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, chip->host_bridge_id, NULL);
+	if (!adata->smn_dev) {
+		dev_err(sdev->dev, "Failed to get host bridge device\n");
+		return -ENODEV;
+	}
+
 	sdev->ipc_irq = pci->irq;
 	ret = request_threaded_irq(sdev->ipc_irq, acp_irq_handler, acp_irq_thread,
 				   IRQF_SHARED, "AudioDSP", sdev);
 	if (ret < 0) {
 		dev_err(sdev->dev, "failed to register IRQ %d\n",
 			sdev->ipc_irq);
+		pci_dev_put(adata->smn_dev);
 		return ret;
 	}
 
 	ret = acp_init(sdev);
 	if (ret < 0) {
 		free_irq(sdev->ipc_irq, sdev);
+		pci_dev_put(adata->smn_dev);
 		return ret;
 	}
 
@@ -371,6 +430,11 @@ EXPORT_SYMBOL_NS(amd_sof_acp_probe, SND_SOC_SOF_AMD_COMMON);
 
 int amd_sof_acp_remove(struct snd_sof_dev *sdev)
 {
+	struct acp_dev_data *adata = sdev->pdata->hw_pdata;
+
+	if (adata->smn_dev)
+		pci_dev_put(adata->smn_dev);
+
 	if (sdev->ipc_irq)
 		free_irq(sdev->ipc_irq, sdev);
 
diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
index fd923f72a01a..a2f8e4219066 100644
--- a/sound/soc/sof/amd/acp.h
+++ b/sound/soc/sof/amd/acp.h
@@ -52,6 +52,15 @@
 
 #define ACP_DSP_TO_HOST_IRQ			0x04
 
+#define HOST_BRIDGE_CZN				0x1630
+#define ACP_SHA_STAT				0x8000
+#define ACP_PSP_TIMEOUT_COUNTER			5
+#define ACP_EXT_INTR_ERROR_STAT			0x20000000
+#define MP0_C2PMSG_26_REG			0x03810570
+#define MBOX_ACP_SHA_DMA_COMMAND		0x330000
+#define MBOX_READY_MASK				0x80000000
+#define MBOX_STATUS_MASK			0xFFFF
+
 struct  acp_atu_grp_pte {
 	u32 low;
 	u32 high;
@@ -140,6 +149,7 @@ struct acp_dev_data {
 	struct dma_descriptor dscr_info[ACP_MAX_DESC];
 	struct acp_dsp_stream stream_buf[ACP_MAX_STREAM];
 	struct acp_dsp_stream *dtrace_stream;
+	struct pci_dev *smn_dev;
 };
 
 void memcpy_to_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *src, size_t bytes);
@@ -202,4 +212,15 @@ int snd_amd_acp_find_config(struct pci_dev *pci);
 /* Trace */
 int acp_sof_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag);
 int acp_sof_trace_release(struct snd_sof_dev *sdev);
+
+struct sof_amd_acp_desc {
+	unsigned int host_bridge_id;
+};
+
+static inline const struct sof_amd_acp_desc *get_chip_info(struct snd_sof_pdata *pdata)
+{
+	const struct sof_dev_desc *desc = pdata->desc;
+
+	return desc->chip_info;
+}
 #endif
diff --git a/sound/soc/sof/amd/pci-rn.c b/sound/soc/sof/amd/pci-rn.c
index 3c379a5ef231..392ffbdf6417 100644
--- a/sound/soc/sof/amd/pci-rn.c
+++ b/sound/soc/sof/amd/pci-rn.c
@@ -43,12 +43,17 @@ static const struct resource renoir_res[] = {
 	},
 };
 
+static const struct sof_amd_acp_desc renoir_chip_info = {
+	.host_bridge_id = HOST_BRIDGE_CZN,
+};
+
 static const struct sof_dev_desc renoir_desc = {
 	.machines		= snd_soc_acpi_amd_sof_machines,
 	.resindex_lpe_base	= 0,
 	.resindex_pcicfg_base	= -1,
 	.resindex_imr_base	= -1,
 	.irqindex_host_ipc	= -1,
+	.chip_info		= &renoir_chip_info,
 	.default_fw_path	= "amd/sof",
 	.default_tplg_path	= "amd/sof-tplg",
 	.default_fw_filename	= "sof-rn.ri",
-- 
2.27.0


  parent reply	other threads:[~2021-11-17  9:39 UTC|newest]

Thread overview: 99+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-17  9:37 [PATCH 00/21] ASoC: SOF: Platform updates for AMD and Mediatek Daniel Baluta
2021-11-17  9:37 ` Daniel Baluta
2021-11-17  9:37 ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 01/21] ASoC: SOF: amd: Add Renoir ACP HW support Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 02/21] ASoC: SOF: amd: Add helper callbacks for ACP's DMA configuration Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 03/21] ASoC: SOF: amd: Add fw loader and renoir dsp ops to load firmware Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 04/21] ASoC: SOF: amd: Add IPC support for ACP IP block Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 05/21] ASoC: SOF: amd: Add dai driver dsp ops callback for Renoir Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 06/21] ASoC: SOF: amd: Add PCM stream callback for Renoir dai's Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 07/21] ASoC: amd: Add module to determine ACP configuration Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-30 16:41   ` Geert Uytterhoeven
2021-11-30 16:41     ` Geert Uytterhoeven
2021-11-30 16:41     ` Geert Uytterhoeven
2021-11-30 16:49     ` Pierre-Louis Bossart
2021-11-30 16:49       ` Pierre-Louis Bossart
2021-11-30 16:49       ` Pierre-Louis Bossart
2021-11-30 17:05       ` Mark Brown
2021-11-30 17:05         ` Mark Brown
2021-11-30 17:05         ` Mark Brown
2021-11-30 17:41         ` Daniel Baluta
2021-11-30 17:41           ` Daniel Baluta
2021-11-30 17:41           ` Daniel Baluta
2021-12-01 10:20         ` Geert Uytterhoeven
2021-12-01 10:20           ` Geert Uytterhoeven
2021-12-01 10:20           ` Geert Uytterhoeven
2021-11-17  9:37 ` [PATCH 08/21] ASoC: SOF: amd: Add machine driver dsp ops for Renoir platform Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 09/21] ASoC: SOF: amd: Add Renoir PCI driver interface Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 10/21] ASoC: amd: acp-config: Remove legacy acpi based machine struct Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 11/21] ASoC: SOF: topology: Add support for AMD ACP DAIs Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 12/21] ASoC: SOF: amd: Add trace logger support Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` Daniel Baluta [this message]
2021-11-17  9:37   ` [PATCH 13/21] ASoC: SOF: amd: Add support for SOF firmware authentication Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17 19:08   ` Curtis Malainey
2021-11-17 19:08     ` Curtis Malainey
2021-11-17 19:08     ` Curtis Malainey
2021-11-17  9:37 ` [PATCH 14/21] ASoC: SOF: mediatek: Add mt8195 hardware support Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 15/21] ASoC: SOF: tokens: add token for Mediatek AFE Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 16/21] ASoC: SOF: topology: Add support for Mediatek AFE DAI Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17 17:29   ` Mark Brown
2021-11-17 17:29     ` Mark Brown
2021-11-17 17:29     ` Mark Brown
2021-11-17 17:32     ` Daniel Baluta
2021-11-17 17:32       ` Daniel Baluta
2021-11-17 17:32       ` Daniel Baluta
2021-11-18  9:34       ` Daniel Baluta
2021-11-18  9:34         ` Daniel Baluta
2021-11-18  9:34         ` Daniel Baluta
2021-11-18  9:48         ` Daniel Baluta
2021-11-18  9:48           ` Daniel Baluta
2021-11-18  9:48           ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 17/21] ASoC: SOF: mediatek: Add fw loader and mt8195 dsp ops to load firmware Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 18/21] ASoC: SOF: Add mt8195 device descriptor Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 19/21] ASoC: SOF: mediatek: Add dai driver dsp ops callback for mt8195 Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 20/21] ASoC: SOF: mediatek: Add mt8195 dsp clock support Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37 ` [PATCH 21/21] ASoC: SOF: mediatek: Add DSP system PM callback for mt8195 Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17  9:37   ` Daniel Baluta
2021-11-17 22:31 ` [PATCH 00/21] ASoC: SOF: Platform updates for AMD and Mediatek Mark Brown
2021-11-17 22:31   ` Mark Brown
2021-11-17 22:31   ` Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211117093734.17407-14-daniel.baluta@oss.nxp.com \
    --to=daniel.baluta@oss.nxp.com \
    --cc=AjitKumar.Pandey@amd.com \
    --cc=Balakishore.pati@amd.com \
    --cc=Julian.Schroeder@amd.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=curtis@malainey.com \
    --cc=daniel.baluta@gmail.com \
    --cc=daniel.baluta@nxp.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=pierre-louis.bossart@linux.intel.com \
    --cc=ranjani.sridharan@linux.intel.com \
    --cc=vishnuvardhanrao.ravulapati@amd.com \
    --cc=vsreddy@amd.com \
    --cc=yc.hung@mediatek.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.