From 4a5217b22dbc82a0e455b2b71d655e26e98935e5 Mon Sep 17 00:00:00 2001 From: Grzegorz Bernat Date: Mon, 15 Apr 2024 14:01:16 +0200 Subject: [PATCH] Audio: basefw: Implemented ipc4 libraries info get Added support for ipc4 query no 16. This makes it possible to get information about the current basefw library. Signed-off-by: Grzegorz Bernat --- src/audio/base_fw.c | 55 +++++++++++++++++++ src/include/ipc4/base_fw.h | 25 +++++++++ src/include/ipc4/base_fw_platform.h | 9 ++- src/include/sof/lib_manager.h | 3 + src/platform/intel/ace/lib/base_fw_platform.c | 9 +++ src/platform/posix/base_fw_platform.c | 8 +++ 6 files changed, 108 insertions(+), 1 deletion(-) diff --git a/src/audio/base_fw.c b/src/audio/base_fw.c index 2bcd539b9cf4..daeaf7927ee0 100644 --- a/src/audio/base_fw.c +++ b/src/audio/base_fw.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #if defined(CONFIG_SOC_SERIES_INTEL_ADSP_ACE) @@ -426,6 +428,57 @@ 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) +{ + if (sizeof(struct ipc4_libraries_info) + + LIB_MANAGER_MAX_LIBS * sizeof(struct ipc4_library_props) > + SOF_IPC_MSG_MAX_SIZE) { + tr_err(&basefw_comp_tr, "Error with message size"); + return -ENOMEM; + } + + struct ipc4_libraries_info *const libs_info = (struct ipc4_libraries_info *)data; + const struct sof_man_fw_desc *desc; + int lib_counter = 0; + + for (int lib_id = 0; lib_id < LIB_MANAGER_MAX_LIBS; ++lib_id) { + if (lib_id == 0) { + desc = platform_base_fw_get_manifest(); + } else { +#if CONFIG_LIBRARY_MANAGER + desc = (struct sof_man_fw_desc *)lib_manager_get_library_manifest(lib_id); +#else + desc = NULL; +#endif + } + + if (!desc) + continue; + + libs_info->libraries[lib_id].id = lib_id; + memcpy_s(libs_info->libraries[lib_counter].name, + SOF_MAN_FW_HDR_FW_NAME_LEN, desc->header.name, sizeof(desc->header.name)); + libs_info->libraries[lib_counter].major_version = + desc->header.major_version; + libs_info->libraries[lib_counter].minor_version = + desc->header.minor_version; + libs_info->libraries[lib_counter].hotfix_version = + desc->header.hotfix_version; + libs_info->libraries[lib_counter].build_version = + desc->header.build_version; + libs_info->libraries[lib_counter].num_module_entries = + desc->header.num_module_entries; + + lib_counter++; + } + + libs_info->library_count = lib_counter; + *data_offset = + sizeof(libs_info) + libs_info->library_count * sizeof(libs_info->libraries[0]); + + return 0; +} + static int fw_config_set_force_l1_exit(const struct sof_tlv *tlv) { #if defined(CONFIG_SOC_SERIES_INTEL_ADSP_ACE) @@ -605,7 +658,9 @@ static int basefw_get_large_config(struct comp_dev *dev, case IPC4_MODULES_INFO_GET: case IPC4_PIPELINE_PROPS_GET: case IPC4_GATEWAYS_INFO_GET: + break; 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 1d1648d73cd0..576672f3a1be 100644 --- a/src/include/ipc4/base_fw.h +++ b/src/include/ipc4/base_fw.h @@ -637,6 +637,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[8]; + /* 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; +} __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[0]; +} __packed __aligned(4); + struct ipc4_log_state_info { /* * Specifies how frequently FW sends Log Buffer Status diff --git a/src/include/ipc4/base_fw_platform.h b/src/include/ipc4/base_fw_platform.h index 717f9e337211..d653b1997d50 100644 --- a/src/include/ipc4/base_fw_platform.h +++ b/src/include/ipc4/base_fw_platform.h @@ -22,4 +22,11 @@ */ int platform_basefw_hw_config(uint32_t *data_offset, char *data); -#endif +/** + * \brief Platform specific routine which return the pointer to + * the boot base manifest. + * \return pointer to struct if successful, null otherwise. + */ +struct sof_man_fw_desc *platform_base_fw_get_manifest(void); + +#endif /* __SOF_IPC4_BASE_FW_PLATFORM_H__ */ diff --git a/src/include/sof/lib_manager.h b/src/include/sof/lib_manager.h index cae001d676cf..adf482f83f25 100644 --- a/src/include/sof/lib_manager.h +++ b/src/include/sof/lib_manager.h @@ -118,6 +118,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) + return NULL; + return _ext_lib->desc[lib_id]; } diff --git a/src/platform/intel/ace/lib/base_fw_platform.c b/src/platform/intel/ace/lib/base_fw_platform.c index 3a7ff02b0675..47dd97b809e3 100644 --- a/src/platform/intel/ace/lib/base_fw_platform.c +++ b/src/platform/intel/ace/lib/base_fw_platform.c @@ -30,3 +30,12 @@ int platform_basefw_hw_config(uint32_t *data_offset, char *data) return 0; } + +struct sof_man_fw_desc *platform_base_fw_get_manifest(void) +{ + struct sof_man_fw_desc *desc; + + desc = (struct sof_man_fw_desc *)IMR_BOOT_LDR_MANIFEST_BASE; + + return desc; +} diff --git a/src/platform/posix/base_fw_platform.c b/src/platform/posix/base_fw_platform.c index c398449e4988..16981e6ff2a7 100644 --- a/src/platform/posix/base_fw_platform.c +++ b/src/platform/posix/base_fw_platform.c @@ -5,6 +5,7 @@ // Author: Kai Vehmanen #include +#include #include int platform_basefw_hw_config(uint32_t *data_offset, char *data) @@ -13,3 +14,10 @@ int platform_basefw_hw_config(uint32_t *data_offset, char *data) return 0; } + +struct sof_man_fw_desc *platform_base_fw_get_manifest(void) +{ + struct sof_man_fw_desc *desc = NULL; + + return desc; +}