diff --git a/src/audio/base_fw.c b/src/audio/base_fw.c index 3940672396bb..6c3c5ff83cf0 100644 --- a/src/audio/base_fw.c +++ b/src/audio/base_fw.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include #if defined(CONFIG_SOC_SERIES_INTEL_ADSP_ACE) @@ -419,6 +421,45 @@ static int basefw_power_state_info_get(uint32_t *data_offset, char *data) return 0; } +static int basefw_libraries_info_get(uint32_t *data_offset, char *data) +{ + struct ipc4_libraries_info *const libs_info = (struct ipc4_libraries_info *)data; + struct sof_man_fw_desc *desc = NULL; + + libs_info->library_count = 0; + + for (int lib_id = 0; lib_id < LIB_MANAGER_MAX_LIBS; ++lib_id) { + + if (lib_id == 0) + desc = (struct sof_man_fw_desc *)IMR_BOOT_LDR_MANIFEST_BASE; + else + desc = lib_manager_get_library_module_desc(lib_id); + + if (desc == NULL) + continue; + + libs_info->libraries[libs_info->library_count].id = lib_id; + memcpy_s(libs_info->libraries[libs_info->library_count].name, SOF_MAN_FW_HDR_FW_NAME_LEN, desc->header.name, + sizeof(desc->header.name)); + libs_info->libraries[libs_info->library_count].major_version = + desc->header.major_version; + libs_info->libraries[libs_info->library_count].minor_version = + desc->header.minor_version; + libs_info->libraries[libs_info->library_count].hotfix_version = + desc->header.hotfix_version; + libs_info->libraries[libs_info->library_count].build_version = + desc->header.build_version; + libs_info->libraries[libs_info->library_count].num_module_entries = + desc->header.num_module_entries; + + libs_info->library_count++; + } + + *data_offset = + sizeof(uint32_t) + libs_info->library_count * sizeof(struct ipc4_library_props); + return 0; +} + static int fw_config_set_force_l1_exit(const struct sof_tlv *tlv) { #if defined(CONFIG_SOC_SERIES_INTEL_ADSP_ACE) @@ -502,6 +543,7 @@ static int basefw_get_large_config(struct comp_dev *dev, case IPC4_SCHEDULERS_INFO_GET: case IPC4_GATEWAYS_INFO_GET: case IPC4_LIBRARIES_INFO_GET: + return basefw_libraries_info_get(data_offset, data); case IPC4_PERF_MEASUREMENTS_STATE: case IPC4_GLOBAL_PERF_DATA: COMPILER_FALLTHROUGH; diff --git a/src/include/ipc4/base_fw.h b/src/include/ipc4/base_fw.h index 5aa1f168b675..8934b0bfcb8a 100644 --- a/src/include/ipc4/base_fw.h +++ b/src/include/ipc4/base_fw.h @@ -17,6 +17,8 @@ #ifndef __SOF_IPC4_BASE_FW_H__ #define __SOF_IPC4_BASE_FW_H__ +#include + /* Three clk src states :low power XTAL, low power ring * and high power ring oscillator */ @@ -637,6 +639,31 @@ enum ipc4_alh_version { IPC4_ALH_CAVS_1_8 = 0x10000, }; +struct ipc4_library_props { + /* Library run-time identifier, depends on order of loading. */ + /* Base FW is always reported with id 0. */ + uint32_t id; + /* Name of the library. */ + uint8_t name[SOF_MAN_FW_HDR_FW_NAME_LEN]; + /* Major version of the library. */ + uint16_t major_version; + /* Minor version of the library. */ + uint16_t minor_version; + /* Hotfix version of the library. */ + uint16_t hotfix_version; + /* Build version of the library. */ + uint16_t build_version; + /* Number of modules packed into the library. */ + uint32_t num_module_entries; +} __attribute__((packed, aligned(4))); + +struct ipc4_libraries_info{ + /* Specifies number of items in libraries array. */ + uint32_t library_count; + /* Array of libraries properties. */ + struct ipc4_library_props libraries[1]; +} __attribute__((packed, aligned(4))); + struct ipc4_log_state_info { /* * Specifies how frequently FW sends Log Buffer Status diff --git a/src/include/sof/lib_manager.h b/src/include/sof/lib_manager.h index a396c1daf282..9041a00543ca 100644 --- a/src/include/sof/lib_manager.h +++ b/src/include/sof/lib_manager.h @@ -115,6 +115,9 @@ static inline struct lib_manager_mod_ctx *lib_manager_get_mod_ctx(int module_id) uint32_t lib_id = LIB_MANAGER_GET_LIB_ID(module_id); struct ext_library *_ext_lib = ext_lib_get(); + if (_ext_lib == NULL) + return NULL; + return _ext_lib->desc[lib_id]; } #endif