From 54789e0bfa5c2444fb0e5fe6434096edc48fb43b Mon Sep 17 00:00:00 2001 From: Wojciech Jablonski Date: Thu, 26 Feb 2026 16:15:27 +0100 Subject: [PATCH 1/2] ipc4: base_fw: send modules info of libraries Currently SOF sends info about built-in modules only while handling MODULES_INFO_GET property of LargeConfigGet msg. However, the IPC4 spec says the message should contain info about all the available modules. This change removes this gap. Additionally, a check for max payload size is added. Signed-off-by: Wojciech Jablonski --- src/audio/base_fw_intel.c | 44 ++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/src/audio/base_fw_intel.c b/src/audio/base_fw_intel.c index 3601d0c5bd72..63b5ccd2c834 100644 --- a/src/audio/base_fw_intel.c +++ b/src/audio/base_fw_intel.c @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -37,6 +38,9 @@ struct ipc4_modules_info { struct sof_man_module modules[0]; } __packed __aligned(4); +/* Sanity check because a subtraction of those sizes is performed later on */ +STATIC_ASSERT(sizeof(struct ipc4_modules_info) < SOF_IPC_MSG_MAX_SIZE, + invalid_modules_info_struct_size); /* * TODO: default to value of ACE1.x platforms. This is defined * in multiple places in Zephyr, mm_drv_intel_adsp.h and @@ -137,22 +141,42 @@ __cold int basefw_vendor_modules_info_get(uint32_t *data_offset, char *data) { assert_can_be_cold(); - struct sof_man_fw_desc *desc = basefw_vendor_get_manifest(); + struct ipc4_modules_info *const module_info = (struct ipc4_modules_info *)data; + const struct sof_man_fw_desc *desc; + uint32_t curr_mod_cnt, curr_cpy_size, total_mod_cnt = 0; + uint32_t total_size_left = SOF_IPC_MSG_MAX_SIZE - sizeof(struct ipc4_modules_info); + int ret; + + for (int lib_id = 0; lib_id < LIB_MANAGER_MAX_LIBS; ++lib_id) { + if (lib_id == 0) { + desc = basefw_vendor_get_manifest(); + } else { +#if CONFIG_LIBRARY_MANAGER + desc = lib_manager_get_library_manifest(LIB_MANAGER_PACK_LIB_ID(lib_id)); +#else + desc = NULL; +#endif + } - if (!desc) - return IPC4_ERROR_INVALID_PARAM; + if (!desc) + continue; - struct ipc4_modules_info *const module_info = (struct ipc4_modules_info *)data; + curr_mod_cnt = desc->header.num_module_entries; + curr_cpy_size = sizeof(struct sof_man_module) * curr_mod_cnt; - module_info->modules_count = desc->header.num_module_entries; + ret = memcpy_s(&module_info->modules[total_mod_cnt], total_size_left, + (char *)desc + SOF_MAN_MODULE_OFFSET(0), curr_cpy_size); + if (ret) { + tr_err(&basefw_comp_tr, "Couldn't copy module info for %d lib", lib_id); + return IPC4_OUT_OF_MEMORY; + } - for (int idx = 0; idx < module_info->modules_count; ++idx) { - struct sof_man_module *module_entry = - (struct sof_man_module *)((char *)desc + SOF_MAN_MODULE_OFFSET(idx)); - memcpy_s(&module_info->modules[idx], sizeof(module_info->modules[idx]), - module_entry, sizeof(struct sof_man_module)); + total_mod_cnt += curr_mod_cnt; + total_size_left -= curr_cpy_size; } + module_info->modules_count = total_mod_cnt; + *data_offset = sizeof(*module_info) + module_info->modules_count * sizeof(module_info->modules[0]); return IPC4_SUCCESS; From 487ada24ac5542afe1708accb84f05ba369ea619 Mon Sep 17 00:00:00 2001 From: Wojciech Jablonski Date: Fri, 27 Feb 2026 10:39:44 +0100 Subject: [PATCH 2/2] ipc4: base_fw: send info about modules IDs The MODULES_INFO_GET property of LargeConfigGet IPC4 msg has slightly different format than module info encoded into the binary manifest. In the binary manifest struct_id has always the same value while LargeConfigGet message structure requires sending module ID instead. This change fixes this issue by generating module IDs in a loop while handling the IPC4 message. Signed-off-by: Wojciech Jablonski --- src/audio/base_fw_intel.c | 9 +++++++++ src/include/sof/lib_manager.h | 4 +++- tools/rimage/src/include/rimage/sof/user/manifest.h | 10 +++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/audio/base_fw_intel.c b/src/audio/base_fw_intel.c index 63b5ccd2c834..efe7e18bc764 100644 --- a/src/audio/base_fw_intel.c +++ b/src/audio/base_fw_intel.c @@ -171,6 +171,15 @@ __cold int basefw_vendor_modules_info_get(uint32_t *data_offset, char *data) return IPC4_OUT_OF_MEMORY; } + /* replace structure id ("$AME" tag) with runtime info */ + for (uint32_t idx = 0; idx < curr_mod_cnt; ++idx) { + uint32_t mod_id = LIB_MANAGER_PACK_MODULE_ID(lib_id, idx); + + module_info->modules[total_mod_cnt + idx].runtime_info.module_id = mod_id; + /* TODO: set bit[0] for modules loaded into ADSP memory */ + module_info->modules[total_mod_cnt + idx].runtime_info.state_flags = 0x0; + } + total_mod_cnt += curr_mod_cnt; total_size_left -= curr_cpy_size; } diff --git a/src/include/sof/lib_manager.h b/src/include/sof/lib_manager.h index d96171ac9fd6..29c226eb61a7 100644 --- a/src/include/sof/lib_manager.h +++ b/src/include/sof/lib_manager.h @@ -77,7 +77,9 @@ #define LIB_MANAGER_GET_LIB_ID(module_id) (((module_id) & 0xF000) >> LIB_MANAGER_LIB_ID_SHIFT) #define LIB_MANAGER_GET_MODULE_INDEX(module_id) ((module_id) & 0xFFF) -#define LIB_MANAGER_PACK_LIB_ID(lib_index) (((lib_index) << LIB_MANAGER_LIB_ID_SHIFT) & 0xF000) +#define LIB_MANAGER_PACK_MODULE_ID(lib_index, module_index) (((module_index) & 0xFFF) | \ + (((lib_index) << LIB_MANAGER_LIB_ID_SHIFT) & 0xF000)) +#define LIB_MANAGER_PACK_LIB_ID(lib_index) LIB_MANAGER_PACK_MODULE_ID(lib_index, 0x0) #ifdef CONFIG_LIBRARY_MANAGER struct ipc_lib_msg { diff --git a/tools/rimage/src/include/rimage/sof/user/manifest.h b/tools/rimage/src/include/rimage/sof/user/manifest.h index 9abae6894901..3f20d89ff495 100644 --- a/tools/rimage/src/include/rimage/sof/user/manifest.h +++ b/tools/rimage/src/include/rimage/sof/user/manifest.h @@ -103,11 +103,19 @@ struct sof_man_uuid { uint8_t d[8]; }; +struct sof_man_runtime_info { + uint16_t module_id; + uint16_t state_flags; +}; + /* * Each module has an entry in the FW header. Used by ROM - Immutable. */ struct sof_man_module { - uint8_t struct_id[SOF_MAN_MOD_ID_LEN]; /* SOF_MAN_MOD_ID */ + union { + uint8_t struct_id[SOF_MAN_MOD_ID_LEN]; /* SOF_MAN_MOD_ID */ + struct sof_man_runtime_info runtime_info; + }; uint8_t name[SOF_MAN_MOD_NAME_LEN]; struct sof_man_uuid uuid; struct sof_man_module_type type;