diff --git a/src/audio/base_fw_intel.c b/src/audio/base_fw_intel.c index 3601d0c5bd72..efe7e18bc764 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,51 @@ __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; + } + + /* 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); - 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)); + 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; } + module_info->modules_count = total_mod_cnt; + *data_offset = sizeof(*module_info) + module_info->modules_count * sizeof(module_info->modules[0]); return IPC4_SUCCESS; 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;