summaryrefslogtreecommitdiff
path: root/sound/soc/sof/ipc3.c
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@linux.intel.com>2022-04-26 01:11:21 +0300
committerMark Brown <broonie@kernel.org>2022-04-29 15:06:08 +0300
commitd2458baa799fff377660d86323dd20a3f4deecb4 (patch)
tree33ce5258bd6896201a2da203d9c7b516d4e33b95 /sound/soc/sof/ipc3.c
parent61bafd1c4571ceb9cdf1830a257eac873d0b68ee (diff)
downloadlinux-d2458baa799fff377660d86323dd20a3f4deecb4.tar.xz
ASoC: SOF: ipc3-loader: Implement firmware parsing and loading
Add the IPC3 dependent implementation of validating the firmware image, parsing the ext manifest and to load modules via memcpy. The code introduced by this commit is the IPC dependent code from the loader.c, which is going to be removed later. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Rander Wang <rander.wang@intel.com> Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Link: https://lore.kernel.org/r/20220425221129.124615-3-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof/ipc3.c')
-rw-r--r--sound/soc/sof/ipc3.c62
1 files changed, 57 insertions, 5 deletions
diff --git a/sound/soc/sof/ipc3.c b/sound/soc/sof/ipc3.c
index 7d28bfa3d231..efcd201597fa 100644
--- a/sound/soc/sof/ipc3.c
+++ b/sound/soc/sof/ipc3.c
@@ -11,6 +11,7 @@
#include <sound/sof/control.h>
#include "sof-priv.h"
#include "sof-audio.h"
+#include "ipc3-priv.h"
#include "ipc3-ops.h"
#include "ops.h"
@@ -475,8 +476,8 @@ static int sof_ipc3_set_get_data(struct snd_sof_dev *sdev, void *data, size_t da
return ret;
}
-static int sof_ipc3_get_ext_windows(struct snd_sof_dev *sdev,
- const struct sof_ipc_ext_data_hdr *ext_hdr)
+int sof_ipc3_get_ext_windows(struct snd_sof_dev *sdev,
+ const struct sof_ipc_ext_data_hdr *ext_hdr)
{
const struct sof_ipc_window *w =
container_of(ext_hdr, struct sof_ipc_window, ext_hdr);
@@ -500,8 +501,8 @@ static int sof_ipc3_get_ext_windows(struct snd_sof_dev *sdev,
return 0;
}
-static int sof_ipc3_get_cc_info(struct snd_sof_dev *sdev,
- const struct sof_ipc_ext_data_hdr *ext_hdr)
+int sof_ipc3_get_cc_info(struct snd_sof_dev *sdev,
+ const struct sof_ipc_ext_data_hdr *ext_hdr)
{
int ret;
@@ -735,6 +736,56 @@ static int ipc3_init_reply_data_buffer(struct snd_sof_dev *sdev)
return 0;
}
+int sof_ipc3_validate_fw_version(struct snd_sof_dev *sdev)
+{
+ struct sof_ipc_fw_ready *ready = &sdev->fw_ready;
+ struct sof_ipc_fw_version *v = &ready->version;
+
+ dev_info(sdev->dev,
+ "Firmware info: version %d:%d:%d-%s\n", v->major, v->minor,
+ v->micro, v->tag);
+ dev_info(sdev->dev,
+ "Firmware: ABI %d:%d:%d Kernel ABI %d:%d:%d\n",
+ SOF_ABI_VERSION_MAJOR(v->abi_version),
+ SOF_ABI_VERSION_MINOR(v->abi_version),
+ SOF_ABI_VERSION_PATCH(v->abi_version),
+ SOF_ABI_MAJOR, SOF_ABI_MINOR, SOF_ABI_PATCH);
+
+ if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, v->abi_version)) {
+ dev_err(sdev->dev, "incompatible FW ABI version\n");
+ return -EINVAL;
+ }
+
+ if (SOF_ABI_VERSION_MINOR(v->abi_version) > SOF_ABI_MINOR) {
+ if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) {
+ dev_warn(sdev->dev, "FW ABI is more recent than kernel\n");
+ } else {
+ dev_err(sdev->dev, "FW ABI is more recent than kernel\n");
+ return -EINVAL;
+ }
+ }
+
+ if (ready->flags & SOF_IPC_INFO_BUILD) {
+ dev_info(sdev->dev,
+ "Firmware debug build %d on %s-%s - options:\n"
+ " GDB: %s\n"
+ " lock debug: %s\n"
+ " lock vdebug: %s\n",
+ v->build, v->date, v->time,
+ (ready->flags & SOF_IPC_INFO_GDB) ?
+ "enabled" : "disabled",
+ (ready->flags & SOF_IPC_INFO_LOCKS) ?
+ "enabled" : "disabled",
+ (ready->flags & SOF_IPC_INFO_LOCKSV) ?
+ "enabled" : "disabled");
+ }
+
+ /* copy the fw_version into debugfs at first boot */
+ memcpy(&sdev->fw_version, v, sizeof(*v));
+
+ return 0;
+}
+
static int ipc3_fw_ready(struct snd_sof_dev *sdev, u32 cmd)
{
struct sof_ipc_fw_ready *fw_ready = &sdev->fw_ready;
@@ -767,7 +818,7 @@ static int ipc3_fw_ready(struct snd_sof_dev *sdev, u32 cmd)
}
/* make sure ABI version is compatible */
- ret = snd_sof_ipc_valid(sdev);
+ ret = sof_ipc3_validate_fw_version(sdev);
if (ret < 0)
return ret;
@@ -1019,6 +1070,7 @@ const struct sof_ipc_ops ipc3_ops = {
.tplg = &ipc3_tplg_ops,
.pm = &ipc3_pm_ops,
.pcm = &ipc3_pcm_ops,
+ .fw_loader = &ipc3_loader_ops,
.tx_msg = sof_ipc3_tx_msg,
.rx_msg = sof_ipc3_rx_msg,