Re: [PATCH 13/21] ASoC: SOF: amd: Add support for SOF firmware authentication

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Nov 17, 2021 at 1:38 AM Daniel Baluta <daniel.baluta@xxxxxxxxxxx> wrote:
>
> From: Ajit Kumar Pandey <AjitKumar.Pandey@xxxxxxx>
>
> 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@xxxxxxx>
> Signed-off-by: Ajit Kumar Pandey <AjitKumar.Pandey@xxxxxxx>
> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@xxxxxxxxxxxxxxx>
> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@xxxxxxxxxxxxxxx>
> Reviewed-by: Curtis Malainey <curtis@xxxxxxxxxxxx>

Sorry github must be attached to the wrong email, please use

Reviewed-by: Curtis Malainey <cujomalainey@xxxxxxxxxxxx>

> Signed-off-by: Daniel Baluta <daniel.baluta@xxxxxxx>
> ---
>  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
>



[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux