diff options
author | Peter Ujfalusi <peter.ujfalusi@linux.intel.com> | 2022-10-20 15:12:28 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2022-10-21 13:05:01 +0100 |
commit | 5a932cfce4401491c942ddcb7fd3ca669e507b4d (patch) | |
tree | df88b86c7f6a1e2a154c86a8aefc1526ba9899c8 /sound/soc/sof/ipc4-loader.c | |
parent | b0a12fa905fad870bd941df2726953edafb489f3 (diff) |
ASoC: SOF: ipc4: Convert the firmware handling (loader) to library convention
With IPC4 each DSP loadable binary is a library, which contains
ext_manifest section and loadable modules.
The basefw is no exception, it is always library 0 and it can contain
several modules, depending on the firmware build.
The current code assumes only one binary, which is the basefw and has no
concept of libraries.
This patch introduces the library+modules abstraction and represents the
basefw as library for the IPC4 loader codebase.
The basefw loading and handling is not changing, it is still done by the
generic code, but it's information is cloned under the library
representation.
The libraries are managed via XArray to offload the list and ID management.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Chao Song <chao.song@intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20221020121238.18339-10-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof/ipc4-loader.c')
-rw-r--r-- | sound/soc/sof/ipc4-loader.c | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/sound/soc/sof/ipc4-loader.c b/sound/soc/sof/ipc4-loader.c index 2495a205ef78..5506ec997328 100644 --- a/sound/soc/sof/ipc4-loader.c +++ b/sound/soc/sof/ipc4-loader.c @@ -14,11 +14,12 @@ #include "sof-priv.h" #include "ops.h" -static size_t sof_ipc4_fw_parse_ext_man(struct snd_sof_dev *sdev) +static size_t sof_ipc4_fw_parse_ext_man(struct snd_sof_dev *sdev, + struct sof_ipc4_fw_library *fw_lib) { struct sof_ipc4_fw_data *ipc4_data = sdev->private; + const struct firmware *fw = fw_lib->sof_fw.fw; struct sof_man4_fw_binary_header *fw_header; - const struct firmware *fw = sdev->basefw.fw; struct sof_ext_manifest4_hdr *ext_man_hdr; struct sof_man4_module_config *fm_config; struct sof_ipc4_fw_module *fw_module; @@ -76,14 +77,13 @@ static size_t sof_ipc4_fw_parse_ext_man(struct snd_sof_dev *sdev) dev_dbg(sdev->dev, "Firmware name: %s, header length: %u, module count: %u\n", fw_header->name, fw_header->len, fw_header->num_module_entries); - ipc4_data->fw_modules = devm_kmalloc_array(sdev->dev, - fw_header->num_module_entries, - sizeof(*fw_module), GFP_KERNEL); - if (!ipc4_data->fw_modules) + fw_lib->modules = devm_kmalloc_array(sdev->dev, fw_header->num_module_entries, + sizeof(*fw_module), GFP_KERNEL); + if (!fw_lib->modules) return -ENOMEM; - ipc4_data->num_fw_modules = fw_header->num_module_entries; - fw_module = ipc4_data->fw_modules; + fw_lib->num_modules = fw_header->num_module_entries; + fw_module = fw_lib->modules; fm_entry = (struct sof_man4_module *)((u8 *)fw_header + fw_header->len); remaining -= fw_header->len; @@ -133,6 +133,33 @@ static size_t sof_ipc4_fw_parse_ext_man(struct snd_sof_dev *sdev) return ext_man_hdr->len; } +static size_t sof_ipc4_fw_parse_basefw_ext_man(struct snd_sof_dev *sdev) +{ + struct sof_ipc4_fw_data *ipc4_data = sdev->private; + struct sof_ipc4_fw_library *fw_lib; + size_t payload_offset; + int ret; + + fw_lib = devm_kzalloc(sdev->dev, sizeof(*fw_lib), GFP_KERNEL); + if (!fw_lib) + return -ENOMEM; + + fw_lib->sof_fw.fw = sdev->basefw.fw; + + payload_offset = sof_ipc4_fw_parse_ext_man(sdev, fw_lib); + if (payload_offset > 0) { + fw_lib->sof_fw.payload_offset = payload_offset; + + /* basefw ID is 0 */ + fw_lib->id = 0; + ret = xa_insert(&ipc4_data->fw_lib_xa, 0, fw_lib, GFP_KERNEL); + if (ret) + return ret; + } + + return payload_offset; +} + static int sof_ipc4_validate_firmware(struct snd_sof_dev *sdev) { struct sof_ipc4_fw_data *ipc4_data = sdev->private; @@ -224,6 +251,6 @@ out: const struct sof_ipc_fw_loader_ops ipc4_loader_ops = { .validate = sof_ipc4_validate_firmware, - .parse_ext_manifest = sof_ipc4_fw_parse_ext_man, + .parse_ext_manifest = sof_ipc4_fw_parse_basefw_ext_man, .query_fw_configuration = sof_ipc4_query_fw_configuration, }; |