ASoC: SOF: amd: Add support for signed fw image loading
authorVenkata Prasad Potturu <venkataprasad.potturu@amd.com>
Wed, 9 Aug 2023 12:35:21 +0000 (18:05 +0530)
committerMark Brown <broonie@kernel.org>
Mon, 21 Aug 2023 15:05:48 +0000 (16:05 +0100)
Add support for signed firmware code bin and data bin
loading for amd platforms.

Signed-off-by: Venkata Prasad Potturu <venkataprasad.potturu@amd.com>
Link: https://lore.kernel.org/r/20230809123534.287707-2-venkataprasad.potturu@amd.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/amd/acp-dsp-offset.h
sound/soc/sof/amd/acp-loader.c
sound/soc/sof/amd/acp.c
sound/soc/sof/amd/acp.h

index 19ef2b4..a913f1c 100644 (file)
@@ -87,6 +87,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_DMA_INCLUDE_HDR         0x1CCC
 #define ACP_SHA_PSP_ACK                         0x1C74
 
 #define ACP_SCRATCH_REG_0                      0x10000
index a4bce5a..a63c00b 100644 (file)
@@ -3,7 +3,7 @@
 // This file is provided under a dual BSD/GPLv2 license. When using or
 // redistributing this file, you may do so under either license.
 //
-// Copyright(c) 2021 Advanced Micro Devices, Inc.
+// Copyright(c) 2021, 2023 Advanced Micro Devices, Inc.
 //
 // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
 
@@ -158,7 +158,11 @@ int acp_dsp_pre_fw_run(struct snd_sof_dev *sdev)
        int ret;
 
        adata = sdev->pdata->hw_pdata;
-       size_fw = adata->fw_bin_size;
+
+       if (adata->signed_fw_image)
+               size_fw = adata->fw_bin_size - ACP_FIRMWARE_SIGNATURE;
+       else
+               size_fw = adata->fw_bin_size;
 
        page_count = PAGE_ALIGN(size_fw) >> PAGE_SHIFT;
        adata->fw_bin_page_count = page_count;
@@ -219,3 +223,34 @@ int acp_sof_dsp_run(struct snd_sof_dev *sdev)
        return 0;
 }
 EXPORT_SYMBOL_NS(acp_sof_dsp_run, SND_SOC_SOF_AMD_COMMON);
+
+int acp_sof_load_signed_firmware(struct snd_sof_dev *sdev)
+{
+       struct snd_sof_pdata *plat_data = sdev->pdata;
+       struct acp_dev_data *adata = plat_data->hw_pdata;
+       int ret;
+
+       ret = request_firmware(&sdev->basefw.fw, adata->fw_code_bin, sdev->dev);
+       if (ret < 0) {
+               dev_err(sdev->dev, "sof signed firmware code bin is missing\n");
+               return ret;
+       } else {
+               dev_dbg(sdev->dev, "request_firmware %s successful\n", adata->fw_code_bin);
+       }
+       ret = snd_sof_dsp_block_write(sdev, SOF_FW_BLK_TYPE_IRAM, 0,
+                                     (void *)sdev->basefw.fw->data, sdev->basefw.fw->size);
+
+       ret = request_firmware(&adata->fw_dbin, adata->fw_data_bin, sdev->dev);
+       if (ret < 0) {
+               dev_err(sdev->dev, "sof signed firmware data bin is missing\n");
+               return ret;
+
+       } else {
+               dev_dbg(sdev->dev, "request_firmware %s successful\n", adata->fw_data_bin);
+       }
+
+       ret = snd_sof_dsp_block_write(sdev, SOF_FW_BLK_TYPE_DRAM, 0,
+                                     (void *)adata->fw_dbin->data, adata->fw_dbin->size);
+       return ret;
+}
+EXPORT_SYMBOL_NS(acp_sof_load_signed_firmware, SND_SOC_SOF_AMD_COMMON);
index c450931..0072a62 100644 (file)
@@ -3,7 +3,7 @@
 // This file is provided under a dual BSD/GPLv2 license. When using or
 // redistributing this file, you may do so under either license.
 //
-// Copyright(c) 2021 Advanced Micro Devices, Inc. All rights reserved.
+// Copyright(c) 2021, 2023 Advanced Micro Devices, Inc. All rights reserved.
 //
 // Authors: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
 //         Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
@@ -235,6 +235,9 @@ int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
                }
        }
 
+       if (adata->signed_fw_image)
+               snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_INCLUDE_HDR, ACP_SHA_HEADER);
+
        snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_STRT_ADDR, start_addr);
        snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_DESTINATION_ADDR, dest_addr);
        snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_MSG_LENGTH, image_length);
@@ -527,6 +530,7 @@ int amd_sof_acp_probe(struct snd_sof_dev *sdev)
        sdev->debug_box.offset = sdev->host_box.offset + sdev->host_box.size;
        sdev->debug_box.size = BOX_SIZE_1024;
 
+       adata->signed_fw_image = false;
        acp_memory_init(sdev);
 
        acp_dsp_stream_init(sdev);
index 73c3e13..8421053 100644 (file)
@@ -41,6 +41,7 @@
 #define DSP_FW_RUN_ENABLE                      0x01
 #define ACP_SHA_RUN                            0x01
 #define ACP_SHA_RESET                          0x02
+#define ACP_SHA_HEADER                         0x01
 #define ACP_DMA_CH_RST                         0x01
 #define ACP_DMA_CH_GRACEFUL_RST_EN             0x10
 #define ACP_ATU_CACHE_INVALID                  0x01
@@ -82,6 +83,8 @@
 #define SRAM1_SIZE                             0x13A000
 #define PROBE_STATUS_BIT                       BIT(31)
 
+#define ACP_FIRMWARE_SIGNATURE                 0x100
+
 enum clock_source {
        ACP_CLOCK_96M = 0,
        ACP_CLOCK_48M,
@@ -181,15 +184,19 @@ struct sof_amd_acp_desc {
 /* Common device data struct for ACP devices */
 struct acp_dev_data {
        struct snd_sof_dev  *dev;
+       const struct firmware *fw_dbin;
        /* DMIC device */
        struct platform_device *dmic_dev;
        unsigned int fw_bin_size;
        unsigned int fw_data_bin_size;
+       const char *fw_code_bin;
+       const char *fw_data_bin;
        u32 fw_bin_page_count;
        dma_addr_t sha_dma_addr;
        u8 *bin_buf;
        dma_addr_t dma_addr;
        u8 *data_buf;
+       bool signed_fw_image;
        struct dma_descriptor dscr_info[ACP_MAX_DESC];
        struct acp_dsp_stream stream_buf[ACP_MAX_STREAM];
        struct acp_dsp_stream *dtrace_stream;
@@ -214,6 +221,7 @@ int amd_sof_acp_remove(struct snd_sof_dev *sdev);
 /* DSP Loader callbacks */
 int acp_sof_dsp_run(struct snd_sof_dev *sdev);
 int acp_dsp_pre_fw_run(struct snd_sof_dev *sdev);
+int acp_sof_load_signed_firmware(struct snd_sof_dev *sdev);
 int acp_get_bar_index(struct snd_sof_dev *sdev, u32 type);
 
 /* Block IO callbacks */