diff --git a/app/prj.conf b/app/prj.conf index 8ee02c6eb64f..0968553dfbd8 100644 --- a/app/prj.conf +++ b/app/prj.conf @@ -62,3 +62,5 @@ CONFIG_DAI=y CONFIG_HEAP_MEM_POOL_SIZE=2048 CONFIG_SAMPLE_SMART_AMP=n + +CONFIG_MODULES=y diff --git a/lmdk/cmake/build.cmake b/lmdk/cmake/build.cmake index b135ef57d4d9..a66c9186e4c0 100644 --- a/lmdk/cmake/build.cmake +++ b/lmdk/cmake/build.cmake @@ -22,7 +22,7 @@ foreach(MODULE ${MODULES_LIST}) add_library(${MODULE} SHARED) include(${SOF_BASE}/src/samples/audio/pic-${MODULE}.cmake) - target_compile_options(${MODULE} PRIVATE -imacros${ZEPHYR_BUILD}/include/generated/autoconf.h) + target_compile_options(${MODULE} PRIVATE -imacros${ZEPHYR_BUILD}/include/generated/autoconf.h -save-temps -O2) target_compile_definitions(${MODULE} PRIVATE ${MODULE_COMPILE_DEF}) set_target_properties(${MODULE} PROPERTIES ${MODULE_PROPERTIES}) @@ -68,10 +68,18 @@ foreach(MODULE ${MODULES_LIST}) #"-Wl,--no-undefined" "-Wl,--unresolved-symbols=report-all" "-Wl,--error-unresolved-symbols" #"-Wl,--gc-sections" # may remove .bss and that will result in rimage error, do not use for now "-Wl,-Map,$.map" # optional: just for debug - "-T" "${MODULE}_ldscripts/elf32xtensa.x" + #"-T" "${MODULE}_ldscripts/elf32xtensa.x" + # FIXME: use a script to calculate values + "-Wl,-Ttext=0xa06ca000" + "-Wl,-Tdata=0xa06cb000" + "-Wl,--section-start=.rodata=0xa06cb100" ) - set(LIB_LIST ${LIB_LIST} lib${MODULE}.so) + add_custom_command(TARGET ${MODULE} POST_BUILD + COMMAND ${CMAKE_STRIP} -R .xt.* -o lib${MODULE}_out.so lib${MODULE}.so + ) + + set(LIB_LIST ${LIB_LIST} lib${MODULE}_out.so) sof_append_relative_path_definitions(${MODULE}) endforeach() diff --git a/lmdk/cmake/config.cmake b/lmdk/cmake/config.cmake index 5c7305c05133..e0c4d3a07057 100644 --- a/lmdk/cmake/config.cmake +++ b/lmdk/cmake/config.cmake @@ -14,5 +14,13 @@ cmake_path(ABSOLUTE_PATH LMDK_BASE NORMALIZE) set(SOF_BASE ${LMDK_BASE}/..) cmake_path(ABSOLUTE_PATH SOF_BASE NORMALIZE) +# zephyr root dir +set(ZEPHYR_BASE ${SOF_BASE}/../../../zephyr) +cmake_path(ABSOLUTE_PATH ZEPHYR_BASE NORMALIZE) + +# zephyr build root dir +set(ZEPHYR_BUILD ${BUILD_DIR}/zephyr) +cmake_path(ABSOLUTE_PATH ZEPHYR_BUILD NORMALIZE) + set(RIMAGE_INCLUDE_DIR ${SOF_BASE}/rimage/src/include) cmake_path(ABSOLUTE_PATH RIMAGE_INCLUDE_DIR NORMALIZE) diff --git a/lmdk/cmake/xtensa-toolchain.cmake b/lmdk/cmake/xtensa-toolchain.cmake index c5058b331ad4..29314a6f06b7 100644 --- a/lmdk/cmake/xtensa-toolchain.cmake +++ b/lmdk/cmake/xtensa-toolchain.cmake @@ -1,5 +1,8 @@ # Xtensa CMake toolchain file. Apply it using CMAKE_TOOLCHAIN_FILE variable. +set(CMAKE_C_COMPILER_WORKS 1) +set(CMAKE_CXX_COMPILER_WORKS 1) + set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_VERSION 1) @@ -9,20 +12,24 @@ if(NOT XTENSA_TOOLCHAIN_PATH) set(XTENSA_TOOLCHAIN_PATH $ENV{XTENSA_TOOLCHAIN_PATH}) endif() -if(NOT XTENSA_TOOLCHAIN_PATH) - message(FATAL_ERROR "Failed to find Xtensa toolchain: XTENSA_TOOLCHAIN_PATH (env or CMake) variable not defined.") +if(XTENSA_TOOLCHAIN_PATH) + cmake_path(CONVERT ${XTENSA_TOOLCHAIN_PATH} TO_CMAKE_PATH_LIST XTENSA_TOOLCHAIN_PATH) + cmake_path(APPEND XTENSA_TOOLCHAIN_PATH "XtensaTools" OUTPUT_VARIABLE TOOLCHAIN_BASE) +else() + cmake_path(CONVERT $ENV{XTENSA_SDK} TO_CMAKE_PATH_LIST TOOLCHAIN_BASE) + cmake_path(CONVERT $ENV{XTENSA_TOOLS} TO_CMAKE_PATH_LIST XTENSA_TOOLS) endif() -cmake_path(CONVERT ${XTENSA_TOOLCHAIN_PATH} TO_CMAKE_PATH_LIST XTENSA_TOOLCHAIN_PATH) -cmake_path(APPEND XTENSA_TOOLCHAIN_PATH "XtensaTools" OUTPUT_VARIABLE TOOLCHAIN_BASE) -set(CROSS_COMPILE xt-) +cmake_path(CONVERT $ENV{XTENSA_ROOT} TO_CMAKE_PATH_LIST XTENSA_ROOT) +set(CROSS_COMPILE ${XTENSA_TOOLS}/xtensa-intel_ace15_mtpm_zephyr-elf-) +set(SYSROOT_DIR ${XTENSA_ROOT}) # clang or xcc -find_program(CMAKE_C_COMPILER NAMES ${CROSS_COMPILE}xcc +find_program(CMAKE_C_COMPILER NAMES ${CROSS_COMPILE}gcc PATHS ${TOOLCHAIN_BASE} PATH_SUFFIXES "bin" REQUIRED NO_DEFAULT_PATH ) # clang++ or xc++ -find_program(CMAKE_CXX_COMPILER NAMES ${CROSS_COMPILE}xc++ +find_program(CMAKE_CXX_COMPILER NAMES ${CROSS_COMPILE}g++ PATHS ${TOOLCHAIN_BASE} PATH_SUFFIXES "bin" REQUIRED NO_DEFAULT_PATH ) find_program(CMAKE_LD NAMES ${CROSS_COMPILE}ld @@ -43,6 +50,9 @@ find_program(CMAKE_OBJDUMP NAMES ${CROSS_COMPILE}objdump find_program(CMAKE_NM NAMES ${CROSS_COMPILE}nm PATHS ${TOOLCHAIN_BASE} PATH_SUFFIXES "bin" REQUIRED NO_DEFAULT_PATH ) +find_program(CMAKE_STRIP NAMES ${CROSS_COMPILE}strip + PATHS ${TOOLCHAIN_BASE} PATH_SUFFIXES "bin" REQUIRED NO_DEFAULT_PATH +) cmake_path(APPEND TOOLCHAIN_BASE "xtensa-elf" OUTPUT_VARIABLE XTENSA_ELF_ROOT) set(CMAKE_FIND_ROOT_PATH ${XTENSA_ELF_ROOT}) diff --git a/src/audio/component.c b/src/audio/component.c index 51e6b4250f9b..274c187fd92a 100644 --- a/src/audio/component.c +++ b/src/audio/component.c @@ -20,6 +20,7 @@ #include #include #include +#include #if defined(__XCC__) #include @@ -49,6 +50,7 @@ int comp_register(struct comp_driver_info *drv) return 0; } +EXPORT_SYMBOL(comp_register); void comp_unregister(struct comp_driver_info *drv) { diff --git a/src/audio/data_blob.c b/src/audio/data_blob.c index cbe86cd2c395..899f9f85e70e 100644 --- a/src/audio/data_blob.c +++ b/src/audio/data_blob.c @@ -11,6 +11,7 @@ #include #include #include +#include LOG_MODULE_REGISTER(data_blob, CONFIG_SOF_LOG_LEVEL); @@ -426,6 +427,7 @@ int ipc4_comp_data_blob_set(struct comp_data_blob_handler *blob_handler, return 0; } +EXPORT_SYMBOL(comp_data_blob_set); int comp_data_blob_set_cmd(struct comp_data_blob_handler *blob_handler, struct sof_ipc_ctrl_data *cdata) @@ -645,6 +647,7 @@ comp_data_blob_handler_new_ext(struct comp_dev *dev, bool single_blob, return handler; } +EXPORT_SYMBOL(comp_data_blob_handler_new_ext); void comp_data_blob_handler_free(struct comp_data_blob_handler *blob_handler) { @@ -655,3 +658,4 @@ void comp_data_blob_handler_free(struct comp_data_blob_handler *blob_handler) rfree(blob_handler); } +EXPORT_SYMBOL(comp_data_blob_handler_free); diff --git a/src/audio/eq_fir/eq_fir.c b/src/audio/eq_fir/eq_fir.c index 5fad4db4babf..193e4df391c1 100644 --- a/src/audio/eq_fir/eq_fir.c +++ b/src/audio/eq_fir/eq_fir.c @@ -636,7 +636,7 @@ static int eq_fir_reset(struct processing_module *mod) return 0; } -static struct module_interface eq_fir_interface = { +static const struct module_interface eq_fir_interface = { .init = eq_fir_init, .free = eq_fir_free, .set_configuration = eq_fir_set_config, diff --git a/src/audio/eq_iir/eq_iir.c b/src/audio/eq_iir/eq_iir.c index 1ff8ed6879e6..a7be98112b56 100644 --- a/src/audio/eq_iir/eq_iir.c +++ b/src/audio/eq_iir/eq_iir.c @@ -960,7 +960,7 @@ static int eq_iir_reset(struct processing_module *mod) return 0; } -static struct module_interface eq_iir_interface = { +static const struct module_interface eq_iir_interface = { .init = eq_iir_init, .prepare = eq_iir_prepare, .process_audio_stream = eq_iir_process, diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index 78d69223de56..eca267725737 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -856,7 +856,7 @@ static int mixin_set_config(struct processing_module *mod, uint32_t config_id, return 0; } -static struct module_interface mixin_interface = { +static const struct module_interface mixin_interface = { .init = mixin_init, .prepare = mixin_prepare, .process_audio_stream = mixin_process, @@ -868,7 +868,7 @@ static struct module_interface mixin_interface = { DECLARE_MODULE_ADAPTER(mixin_interface, mixin_uuid, mixin_tr); SOF_MODULE_INIT(mixin, sys_comp_module_mixin_interface_init); -static struct module_interface mixout_interface = { +static const struct module_interface mixout_interface = { .init = mixout_init, .prepare = mixout_prepare, .process_audio_stream = mixout_process, diff --git a/src/audio/module_adapter/library/native_system_agent.c b/src/audio/module_adapter/library/native_system_agent.c index b2d798c14238..58c24fadf31a 100644 --- a/src/audio/module_adapter/library/native_system_agent.c +++ b/src/audio/module_adapter/library/native_system_agent.c @@ -30,9 +30,6 @@ void *native_system_agent_start(uint32_t *sys_service, native_sys_agent.log_handle = log_handle; void *system_agent_p = &native_sys_agent; - uint32_t **sys_service_p = &sys_service; - - *sys_service_p = (uint32_t *)(&native_sys_agent.system_service); native_create_instance_f ci = (native_create_instance_f)entry_point; diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index 760652982245..f7b62f086cc4 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -75,7 +75,7 @@ int module_load_config(struct comp_dev *dev, const void *cfg, size_t size) return ret; } -int module_init(struct processing_module *mod, struct module_interface *interface) +int module_init(struct processing_module *mod, const struct module_interface *interface) { int ret; struct module_data *md = &mod->priv; @@ -99,7 +99,7 @@ int module_init(struct processing_module *mod, struct module_interface *interfac if (!interface->init || !interface->prepare || !interface->reset || !interface->free || (!!interface->process + !!interface->process_audio_stream + - !!interface->process_raw_data != 1)) { + !!interface->process_raw_data < 1)) { comp_err(dev, "module_init(): comp %d is missing mandatory interfaces", dev_comp_id(dev)); return -EIO; @@ -222,8 +222,7 @@ int module_prepare(struct processing_module *mod, * as it has been applied during the procedure - it is safe to * free it. */ - if (md->cfg.data) - rfree(md->cfg.data); + rfree(md->cfg.data); md->cfg.avail = false; md->cfg.data = NULL; diff --git a/src/audio/module_adapter/module/modules.c b/src/audio/module_adapter/module/modules.c index 865aa945baea..069c27c79293 100644 --- a/src/audio/module_adapter/module/modules.c +++ b/src/audio/module_adapter/module/modules.c @@ -63,6 +63,11 @@ static int modules_init(struct processing_module *mod) const struct ipc4_base_module_cfg *src_cfg = &md->cfg.base_cfg; int ret = 0; byte_array_t mod_cfg; + const struct ipc4_base_module_extended_cfg *base_cfg = md->cfg.init_data; + + comp_info(mod->dev, "modules_init() start, pins %d %d", + base_cfg->base_cfg_ext.nb_input_pins, + base_cfg->base_cfg_ext.nb_output_pins); mod_cfg.data = (uint8_t *)md->cfg.init_data; /* Intel modules expects DW size here */ @@ -78,10 +83,9 @@ static int modules_init(struct processing_module *mod) return -EINVAL; } md->module_entry_point = module_entry_point; - comp_info(mod->dev, "modules_init() start"); - uint32_t module_id = IPC4_MOD_ID(mod->dev->ipc_config.id); - uint32_t instance_id = IPC4_INST_ID(mod->dev->ipc_config.id); + uint32_t module_id = IPC4_MOD_ID(config->id); + uint32_t instance_id = IPC4_INST_ID(config->id); uint32_t log_handle = (uint32_t) mod->dev->drv->tctx; /* Connect loadable module interfaces with module adapter entity. */ /* Check if native Zephyr lib is loaded */ @@ -92,17 +96,11 @@ static int modules_init(struct processing_module *mod) comp_err(dev, "modules_init(): Failed to load manifest"); return -ENOMEM; } - struct sof_man_module *module_entry = - (struct sof_man_module *)((char *)desc + SOF_MAN_MODULE_OFFSET(0)); - - struct sof_module_api_build_info *mod_buildinfo = - (struct sof_module_api_build_info *) - (module_entry->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr); void *mod_adp; - /* Check if module is FDK*/ - if (mod_buildinfo->api_version_number.fields.major < SOF_MODULE_API_MAJOR_VERSION) { + /* Check if module is FDK */ + if (0/*mod_buildinfo->api_version_number.fields.major < SOF_MODULE_API_MAJOR_VERSION*/) { mod_adp = system_agent_start(md->module_entry_point, module_id, instance_id, 0, log_handle, &mod_cfg); } else { @@ -111,6 +109,9 @@ static int modules_init(struct processing_module *mod) mod_adp = native_system_agent_start(mod->sys_service, md->module_entry_point, module_id, instance_id, 0, log_handle, &mod_cfg); + comp_info(mod->dev, "modules_init() got %p, init %p, need %u and %u", + mod_adp, ((const struct module_interface *)mod_adp)->init, + src_cfg->ibs, src_cfg->obs); } md->module_adapter = mod_adp; @@ -136,10 +137,23 @@ static int modules_init(struct processing_module *mod) struct module_interface *mod_in = (struct module_interface *)md->module_adapter; + if (mod_in->process) + mod->proc_type = MODULE_PROCESS_TYPE_SOURCE_SINK; + else if (mod_in->process_audio_stream) + mod->proc_type = MODULE_PROCESS_TYPE_STREAM; + else if (mod_in->process_raw_data) + mod->proc_type = MODULE_PROCESS_TYPE_RAW; + else + return -EINVAL; + + comp_info(mod->dev, "modules_init() calling %p @ %p, mod %p type %u", + mod_in->init, &mod_in->init, mod, mod->proc_type); + ret = mod_in->init(mod); } else { ret = iadk_wrapper_init(md->module_adapter); } + return ret; } @@ -168,7 +182,7 @@ static int modules_prepare(struct processing_module *mod, struct module_interface *mod_in = (struct module_interface *)mod->priv.module_adapter; - ret = mod_in->prepare(mod, NULL, 0, NULL, 0); + ret = mod_in->prepare(mod, sources, num_of_sources, sinks, num_of_sinks); } else { ret = iadk_wrapper_prepare(mod->priv.module_adapter); } @@ -189,18 +203,45 @@ static int modules_init_process(struct processing_module *mod) return 0; } +static int modules_process(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) +{ + if (!mod->is_native_sof) + return -EOPNOTSUPP; + + struct module_interface *mod_in = (struct module_interface *)mod->priv.module_adapter; + + return mod_in->process(mod, sources, num_of_sources, sinks, num_of_sinks); +} + +static int modules_process_audio_stream(struct processing_module *mod, + struct input_stream_buffer *input_buffers, + int num_input_buffers, + struct output_stream_buffer *output_buffers, + int num_output_buffers) +{ + if (!mod->is_native_sof) + return -EOPNOTSUPP; + + struct module_interface *mod_in = (struct module_interface *)mod->priv.module_adapter; + + return mod_in->process_audio_stream(mod, input_buffers, num_input_buffers, + output_buffers, num_output_buffers); +} + /* - * \brief modules_process. + * \brief modules_process_raw. * \param[in] mod - processing module pointer. * * \return: zero on success * error code on failure */ -static int modules_process(struct processing_module *mod, - struct input_stream_buffer *input_buffers, - int num_input_buffers, - struct output_stream_buffer *output_buffers, - int num_output_buffers) +static int modules_process_raw(struct processing_module *mod, + struct input_stream_buffer *input_buffers, + int num_input_buffers, + struct output_stream_buffer *output_buffers, + int num_output_buffers) { struct comp_dev *dev = mod->dev; struct module_data *md = &mod->priv; @@ -374,11 +415,13 @@ static int modules_reset(struct processing_module *mod) return iadk_wrapper_reset(mod->priv.module_adapter); } -/* Processing Module Adapter API*/ +/* Processing Module Adapter API */ static struct module_interface interface = { - .init = modules_init, + .init = modules_init, .prepare = modules_prepare, - .process_raw_data = modules_process, + .process_raw_data = modules_process_raw, + .process = modules_process, + .process_audio_stream = modules_process_audio_stream, .set_processing_mode = modules_set_processing_mode, .get_processing_mode = modules_get_processing_mode, .set_configuration = modules_set_configuration, diff --git a/src/audio/module_adapter/module/volume/volume.c b/src/audio/module_adapter/module/volume/volume.c index 471dd89bca92..7583f8d8200b 100644 --- a/src/audio/module_adapter/module/volume/volume.c +++ b/src/audio/module_adapter/module/volume/volume.c @@ -1657,7 +1657,7 @@ DECLARE_MODULE_ADAPTER(volume_interface, volume_uuid, volume_tr); SOF_MODULE_INIT(volume, sys_comp_module_volume_interface_init); #if CONFIG_COMP_GAIN -static struct module_interface gain_interface = { +static const struct module_interface gain_interface = { .init = volume_init, .prepare = volume_prepare, .process_audio_stream = volume_process, diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index 51f26fc35f91..022d2ab1dacf 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -21,6 +21,7 @@ #include #include #include +#include LOG_MODULE_REGISTER(module_adapter, CONFIG_SOF_LOG_LEVEL); @@ -28,14 +29,9 @@ LOG_MODULE_REGISTER(module_adapter, CONFIG_SOF_LOG_LEVEL); * helpers to determine processing type * Needed till all the modules use PROCESSING_MODE_SINK_SOURCE */ -#define IS_PROCESSING_MODE_AUDIO_STREAM(mod) \ - (!!((struct module_data *)&(mod)->priv)->ops->process_audio_stream) - -#define IS_PROCESSING_MODE_RAW_DATA(mod) \ - (!!((struct module_data *)&(mod)->priv)->ops->process_raw_data) - -#define IS_PROCESSING_MODE_SINK_SOURCE(mod) \ - (!!((struct module_data *)&(mod)->priv)->ops->process) +#define IS_PROCESSING_MODE_AUDIO_STREAM(mod) ((mod)->proc_type == MODULE_PROCESS_TYPE_STREAM) +#define IS_PROCESSING_MODE_RAW_DATA(mod) ((mod)->proc_type == MODULE_PROCESS_TYPE_RAW) +#define IS_PROCESSING_MODE_SINK_SOURCE(mod) ((mod)->proc_type == MODULE_PROCESS_TYPE_SOURCE_SINK) /* * \brief Create a module adapter component. @@ -46,14 +42,14 @@ LOG_MODULE_REGISTER(module_adapter, CONFIG_SOF_LOG_LEVEL); */ struct comp_dev *module_adapter_new(const struct comp_driver *drv, const struct comp_ipc_config *config, - struct module_interface *interface, const void *spec) + const struct module_interface *interface, const void *spec) { int ret; struct comp_dev *dev; struct processing_module *mod; struct module_config *dst; - comp_cl_dbg(drv, "module_adapter_new() start"); + comp_cl_dbg(drv, "module_adapter_new() start, type %u", drv->type); if (!config) { comp_cl_err(drv, "module_adapter_new(), wrong input params! drv = %x config = %x", @@ -122,17 +118,16 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, } /* Copy initial config */ - if (size) { - ret = module_load_config(dev, data, size); - if (ret) { - comp_err(dev, "module_adapter_new() error %d: config loading has failed.", - ret); - goto err; - } - dst->init_data = dst->data; - } else { + if (!size) + goto err; + + ret = module_load_config(dev, data, size); + if (ret) { + comp_err(dev, "module_adapter_new() error %d: config loading has failed.", + ret); goto err; } + dst->init_data = dst->data; #else if (drv->type == SOF_COMP_MODULE_ADAPTER) { const struct ipc_config_process *ipc_module_adapter = spec; @@ -151,6 +146,15 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, mod->max_sources = 1; mod->max_sinks = 1; + if (interface->process) + mod->proc_type = MODULE_PROCESS_TYPE_SOURCE_SINK; + else if (interface->process_audio_stream) + mod->proc_type = MODULE_PROCESS_TYPE_STREAM; + else if (interface->process_raw_data) + mod->proc_type = MODULE_PROCESS_TYPE_RAW; + else + goto err; + /* Init processing module */ ret = module_init(mod, interface); if (ret) { @@ -172,6 +176,7 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, rfree(dev); return NULL; } +EXPORT_SYMBOL(module_adapter_new); static int module_adapter_sink_src_prepare(struct comp_dev *dev) { @@ -515,6 +520,7 @@ int module_adapter_prepare(struct comp_dev *dev) rfree(mod->input_buffers); return ret; } +EXPORT_SYMBOL(module_adapter_prepare); int module_adapter_params(struct comp_dev *dev, struct sof_ipc_stream_params *params) { @@ -556,6 +562,7 @@ int module_adapter_params(struct comp_dev *dev, struct sof_ipc_stream_params *pa #endif return 0; } +EXPORT_SYMBOL(module_adapter_params); /* * Function to copy from source buffer to the module buffer @@ -1170,8 +1177,6 @@ static int module_adapter_raw_data_type_copy(struct comp_dev *dev) int module_adapter_copy(struct comp_dev *dev) { - comp_dbg(dev, "module_adapter_copy(): start"); - struct processing_module *mod = comp_get_drvdata(dev); if (IS_PROCESSING_MODE_AUDIO_STREAM(mod)) @@ -1186,6 +1191,7 @@ int module_adapter_copy(struct comp_dev *dev) comp_err(dev, "module_adapter_copy(): unknown processing_data_type"); return -EINVAL; } +EXPORT_SYMBOL(module_adapter_copy); static int module_adapter_get_set_params(struct comp_dev *dev, struct sof_ipc_ctrl_data *cdata, bool set) @@ -1309,6 +1315,7 @@ int module_adapter_cmd(struct comp_dev *dev, int cmd, void *data, int max_data_s comp_dbg(dev, "module_adapter_cmd() done"); return ret; } +EXPORT_SYMBOL(module_adapter_cmd); #if CONFIG_IPC_MAJOR_3 static int module_source_status_count(struct comp_dev *dev, uint32_t status) @@ -1383,6 +1390,7 @@ int module_adapter_trigger(struct comp_dev *dev, int cmd) #endif return comp_set_state(dev, cmd); } +EXPORT_SYMBOL(module_adapter_trigger); int module_adapter_reset(struct comp_dev *dev) { @@ -1430,6 +1438,7 @@ int module_adapter_reset(struct comp_dev *dev) return comp_set_state(dev, COMP_TRIGGER_RESET); } +EXPORT_SYMBOL(module_adapter_reset); void module_adapter_free(struct comp_dev *dev) { @@ -1458,6 +1467,7 @@ void module_adapter_free(struct comp_dev *dev) rfree(mod); rfree(dev); } +EXPORT_SYMBOL(module_adapter_free); /* * \brief Get DAI hw params @@ -1480,6 +1490,7 @@ int module_adapter_get_hw_params(struct comp_dev *dev, struct sof_ipc_stream_par return -EOPNOTSUPP; } +EXPORT_SYMBOL(module_adapter_get_hw_params); /* * \brief Get stream position @@ -1500,6 +1511,7 @@ int module_adapter_position(struct comp_dev *dev, struct sof_ipc_stream_posn *po return -EOPNOTSUPP; } +EXPORT_SYMBOL(module_adapter_position); /* * \brief DAI timestamp configure @@ -1519,6 +1531,7 @@ int module_adapter_ts_config_op(struct comp_dev *dev) return -EOPNOTSUPP; } +EXPORT_SYMBOL(module_adapter_ts_config_op); /* * \brief DAI timestamp start @@ -1538,6 +1551,7 @@ int module_adapter_ts_start_op(struct comp_dev *dev) return -EOPNOTSUPP; } +EXPORT_SYMBOL(module_adapter_ts_start_op); /* * \brief DAI timestamp stop @@ -1557,6 +1571,7 @@ int module_adapter_ts_stop_op(struct comp_dev *dev) return -EOPNOTSUPP; } +EXPORT_SYMBOL(module_adapter_ts_stop_op); /* * \brief Get DAI timestamp @@ -1577,6 +1592,7 @@ int module_adapter_ts_get_op(struct comp_dev *dev, struct timestamp_data *tsd) return -EOPNOTSUPP; } +EXPORT_SYMBOL(module_adapter_ts_get_op); #if CONFIG_IPC_MAJOR_4 int module_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, @@ -1615,6 +1631,7 @@ int module_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_ fragment_size, NULL, 0); return 0; } +EXPORT_SYMBOL(module_set_large_config); int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, bool last_block, uint32_t *data_offset_size, char *data) @@ -1641,6 +1658,7 @@ int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_ (uint8_t *)data, fragment_size); return 0; } +EXPORT_SYMBOL(module_get_large_config); int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *value) { @@ -1657,6 +1675,7 @@ int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *valu return 0; } +EXPORT_SYMBOL(module_adapter_get_attribute); static bool module_adapter_multi_sink_source_check(struct comp_dev *dev) { @@ -1739,6 +1758,7 @@ int module_adapter_bind(struct comp_dev *dev, void *data) return 0; } +EXPORT_SYMBOL(module_adapter_bind); int module_adapter_unbind(struct comp_dev *dev, void *data) { @@ -1780,6 +1800,7 @@ int module_adapter_unbind(struct comp_dev *dev, void *data) return 0; } +EXPORT_SYMBOL(module_adapter_unbind); uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, uint32_t stream_no, bool input) @@ -1795,6 +1816,7 @@ uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, else return mod->total_data_consumed; } +EXPORT_SYMBOL(module_adapter_get_total_data_processed); #else int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *value) { diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index bfcf32c92a76..f714489af4d0 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -155,7 +155,7 @@ struct module_data { void *private; /**< self object, memory tables etc here */ void *runtime_params; struct module_config cfg; /**< module configuration data */ - struct module_interface *ops; /**< module specific operations */ + const struct module_interface *ops; /**< module specific operations */ struct module_memory memory; /**< memory allocated by module */ struct module_processing_data mpd; /**< shared data comp <-> module */ void *module_adapter; /**ops.set_large_config = module_set_large_config;\ (comp_dynamic_module)->ops.get_large_config = module_get_large_config;\ (comp_dynamic_module)->ops.get_attribute = module_adapter_get_attribute; \ + (comp_dynamic_module)->ops.bind = module_adapter_bind; \ + (comp_dynamic_module)->ops.unbind = module_adapter_unbind; \ + (comp_dynamic_module)->ops.get_total_data_processed = module_adapter_get_total_data_processed; \ + (comp_dynamic_module)->ops.dai_get_hw_params = module_adapter_get_hw_params; \ + (comp_dynamic_module)->ops.position = module_adapter_position; \ + (comp_dynamic_module)->ops.dai_ts_config = module_adapter_ts_config_op; \ + (comp_dynamic_module)->ops.dai_ts_start = module_adapter_ts_start_op; \ + (comp_dynamic_module)->ops.dai_ts_stop = module_adapter_ts_stop_op; \ + (comp_dynamic_module)->ops.dai_ts_get = module_adapter_ts_get_op; \ } while (0) #endif /* __SOF_AUDIO_MODULES__ */ diff --git a/src/ipc/ipc-helper.c b/src/ipc/ipc-helper.c index 0098a36cc8ad..c17c38c7bd6f 100644 --- a/src/ipc/ipc-helper.c +++ b/src/ipc/ipc-helper.c @@ -32,6 +32,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL); @@ -168,6 +169,7 @@ int comp_verify_params(struct comp_dev *dev, uint32_t flag, return 0; } +EXPORT_SYMBOL(comp_verify_params); int comp_buffer_connect(struct comp_dev *comp, uint32_t comp_core, struct comp_buffer *buffer, uint32_t dir) diff --git a/src/ipc/ipc4/handler.c b/src/ipc/ipc4/handler.c index 705e0f2c259a..791b83dabe11 100644 --- a/src/ipc/ipc4/handler.c +++ b/src/ipc/ipc4/handler.c @@ -496,6 +496,7 @@ static int ipc4_set_pipeline_state(struct ipc4_message_request *ipc4) } #if CONFIG_LIBRARY_MANAGER +#include #include static int ipc4_load_library(struct ipc4_message_request *ipc4) @@ -507,22 +508,32 @@ static int ipc4_load_library(struct ipc4_message_request *ipc4) library.data.dat = ipc4->extension.dat; ret = lib_manager_load_library(library.header.r.dma_id, library.header.r.lib_id); - tr_info(&ipc_tr, "ipc: ipc4_load_library %d", ret); + tr_info(&ipc_tr, "ipc: ipc4_load_library %d: %d", library.header.r.lib_id, ret); -#if 0 if (!ret) { struct sof_man_fw_desc *ldesc = - lib_manager_get_library_module_desc(library.header.r.lib_id); - struct sof_man_module *mod = (struct sof_man_module *)((char *)desc + - SOF_MAN_MODULE_OFFSET(entry_index)); -#error where does the module begin?? - struct module_buf_stream mbs = MODULE_BUF_STREAM(); - struct module *m; - - /* FIXME: get a name from the manifest */ - ret = module_load(&mbs.stream, "SMATEST", &m); + lib_manager_get_library_module_desc(library.header.r.lib_id << + LIB_MANAGER_LIB_ID_SHIFT); + struct sof_man_module *mod = (struct sof_man_module *)((char *)ldesc + + SOF_MAN_MODULE_OFFSET(0)); + + tr_info(&ipc_tr, "dyn: ID %x len %u name %x offs %x", + *(uint32_t *)ldesc->header.header_id, ldesc->header.header_len, + *(uint32_t *)ldesc->header.name, ldesc->header.load_offset); + tr_info(&ipc_tr, "dyn: ID %x UUID %x name %x entry %x", + *(uint32_t *)mod->struct_id, *(uint32_t *)mod->uuid, + *(uint32_t *)mod->name, mod->entry_point); + tr_info(&ipc_tr, "dyn: base %x offset %x flags %x ELF %x", + mod->segment[0].v_base_addr, + mod->segment[0].file_offset, mod->segment[0].flags.ul, + *(uint32_t *)((uint8_t *)ldesc + 0x6000)); + tr_info(&ipc_tr, "dyn: base %x offset %x flags %x", + mod->segment[1].v_base_addr, + mod->segment[1].file_offset, mod->segment[1].flags.ul); + tr_info(&ipc_tr, "dyn: base %x offset %x flags %x", + mod->segment[2].v_base_addr, + mod->segment[2].file_offset, mod->segment[2].flags.ul); } -#endif return ret; } @@ -706,7 +717,7 @@ static int ipc4_process_glb_message(struct ipc4_message_request *ipc4) static int ipc4_init_module_instance(struct ipc4_message_request *ipc4) { - struct ipc4_module_init_instance module_init = {}; + struct ipc4_module_init_instance module_init; struct comp_dev *dev; /* we only need the common header here, all we have from the IPC */ int ret = memcpy_s(&module_init, sizeof(module_init), ipc4, sizeof(*ipc4)); diff --git a/src/ipc/ipc4/helper.c b/src/ipc/ipc4/helper.c index 182fb81a1c2f..ffe16f630bf6 100644 --- a/src/ipc/ipc4/helper.c +++ b/src/ipc/ipc4/helper.c @@ -20,6 +20,7 @@ #include #include #include +#include /* TODO: Remove platform-specific code, see https://github.com/thesofproject/sof/issues/7549 */ #if defined(CONFIG_SOC_SERIES_INTEL_ACE) || defined(CONFIG_INTEL_ADSP_CAVS) @@ -827,6 +828,7 @@ void ipc4_base_module_cfg_to_stream_params(const struct ipc4_base_module_cfg *ba for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) params->chmap[i] = (base_cfg->audio_fmt.ch_map >> i * 4) & 0xf; } +EXPORT_SYMBOL(ipc4_base_module_cfg_to_stream_params); void ipc4_update_buffer_format(struct comp_buffer __sparse_cache *buf_c, const struct ipc4_audio_format *fmt) @@ -850,3 +852,4 @@ void ipc4_update_buffer_format(struct comp_buffer __sparse_cache *buf_c, buf_c->hw_params_configured = true; } +EXPORT_SYMBOL(ipc4_update_buffer_format); diff --git a/src/lib/lib.c b/src/lib/lib.c index 62d92c214d8c..67a961fe643b 100644 --- a/src/lib/lib.c +++ b/src/lib/lib.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -20,6 +21,7 @@ void *memcpy(void *dest, const void *src, size_t n) arch_memcpy(dest, src, n); return dest; } +EXPORT_SYMBOL(memcpy); /* generic memset */ void *memset(void *s, int c, size_t n) @@ -50,6 +52,7 @@ void *memset(void *s, int c, size_t n) return s; } +EXPORT_SYMBOL(memset); int memcmp(const void *p, const void *q, size_t count) { @@ -65,6 +68,7 @@ int memcmp(const void *p, const void *q, size_t count) } return 0; } +EXPORT_SYMBOL(memcmp); #endif diff --git a/src/library_manager/lib_manager.c b/src/library_manager/lib_manager.c index 49fa4bb4140a..90f68bcd5584 100644 --- a/src/library_manager/lib_manager.c +++ b/src/library_manager/lib_manager.c @@ -59,15 +59,25 @@ static struct ext_library loader_ext_lib; static int lib_manager_load_data_from_storage(void __sparse_cache *vma, void *s_addr, uint32_t size, uint32_t flags) { - int ret = sys_mm_drv_map_region((__sparse_force void *)vma, POINTER_TO_UINT(NULL), - size, flags); - if (ret < 0) + tr_info(&lib_manager_tr, "map %u at %p to %p", size, s_addr, vma); + + size_t pre_pad_size = (uintptr_t)vma & (CONFIG_MM_DRV_PAGE_SIZE - 1); + void *aligned_vma = (__sparse_force uint8_t *)vma - pre_pad_size; + int ret = sys_mm_drv_map_region(aligned_vma, + POINTER_TO_UINT(NULL/*s_addr*/)/* - pre_pad_size*/, + ALIGN_UP(pre_pad_size + size, CONFIG_MM_DRV_PAGE_SIZE), + flags); + if (ret < 0) { + tr_err(&lib_manager_tr, "cannot map %u of %p", size, vma); return ret; + } ret = memcpy_s((__sparse_force void *)vma, size, s_addr, size); if (ret < 0) return ret; + /* Some data can be accessed as uncached, in fact that's the default */ + /* Both D- and I-caches have been invalidated */ dcache_writeback_region(vma, size); /* TODO: Change attributes for memory to FLAGS */ @@ -82,36 +92,50 @@ static int lib_manager_load_module(uint32_t module_id, struct sof_man_module *mo size_t load_offset = (size_t)((void *)ext_lib->desc[lib_id]); void __sparse_cache *va_base_text = (void __sparse_cache *) mod->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr; - void *src_txt = (void *)(mod->segment[SOF_MAN_SEGMENT_TEXT].file_offset + load_offset); + void *src_txt = (void *)(mod->segment[SOF_MAN_SEGMENT_TEXT].file_offset + + load_offset + SOF_MAN_ELF_TEXT_OFFSET); size_t st_text_size = mod->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length; - void __sparse_cache *va_base_rodata = (void __sparse_cache *) - mod->segment[SOF_MAN_SEGMENT_RODATA].v_base_addr; - void *src_rodata = - (void *)(mod->segment[SOF_MAN_SEGMENT_RODATA].file_offset + load_offset); - size_t st_rodata_size = mod->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length; + void __sparse_cache *va_base_data = (void __sparse_cache *) + mod->segment[SOF_MAN_SEGMENT_DATA].v_base_addr; + void *src_data = + (void *)(mod->segment[SOF_MAN_SEGMENT_DATA].file_offset + + load_offset + SOF_MAN_ELF_TEXT_OFFSET); + size_t st_data_size = mod->segment[SOF_MAN_SEGMENT_DATA].flags.r.length; int ret; - st_text_size = st_text_size * CONFIG_MM_DRV_PAGE_SIZE; - st_rodata_size = st_rodata_size * CONFIG_MM_DRV_PAGE_SIZE; + st_text_size = ALIGN_UP(st_text_size, CONFIG_MM_DRV_PAGE_SIZE); + st_data_size = ALIGN_UP(st_data_size, CONFIG_MM_DRV_PAGE_SIZE); - tr_info(&lib_manager_tr, "offset 0x%08x text %p rodata %p", - load_offset, va_base_text, va_base_rodata); + tr_info(&lib_manager_tr, "text %p -> %p data %p -> %p", + src_txt, va_base_text, src_data, va_base_data); + + /* + * FIXME: we could map the module in-place, but the .rodata section + * isn't page-aligned. Using objcopy --set-section-alignment + * .rodata=4096 didn't help. + */ /* Copy Code */ - ret = lib_manager_load_data_from_storage(va_base_text, src_txt, - st_text_size, SYS_MM_MEM_PERM_RW | SYS_MM_MEM_PERM_EXEC); + ret = lib_manager_load_data_from_storage(va_base_text, src_txt, st_text_size, + SYS_MM_MEM_PERM_RW | SYS_MM_MEM_PERM_EXEC); if (ret < 0) - goto err; + return ret; - /* Copy RODATA */ - ret = lib_manager_load_data_from_storage(va_base_rodata, src_rodata, - st_rodata_size, SYS_MM_MEM_PERM_RW); + /* Copy DATA */ + ret = lib_manager_load_data_from_storage(va_base_data, src_data, + st_data_size, SYS_MM_MEM_PERM_RW); if (ret < 0) - goto err; + goto e_text; + + tr_info(&lib_manager_tr, "free %#x code %x cnt %u", load_offset, mod->type.lib_code, + ext_lib->mods_exec_load_cnt); + rfree((void *)load_offset); /* There are modules marked as lib_code. This is code shared between several modules inside - * the library. Load all lib_code modules with first none lib_code module load. + * the library. Load all lib_code modules with first non-lib_code module load. */ + /* FIXME: what's this? */ + mod->type.lib_code = 1; if (!mod->type.lib_code) ext_lib->mods_exec_load_cnt++; @@ -132,8 +156,9 @@ static int lib_manager_load_module(uint32_t module_id, struct sof_man_module *mo return 0; err: + sys_mm_drv_unmap_region((__sparse_force void *)va_base_data, st_data_size); +e_text: sys_mm_drv_unmap_region((__sparse_force void *)va_base_text, st_text_size); - sys_mm_drv_unmap_region((__sparse_force void *)va_base_rodata, st_rodata_size); return ret; } @@ -151,8 +176,8 @@ static int lib_manager_unload_module(uint32_t module_id, struct sof_man_module * size_t st_rodata_size = mod->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length; int ret; - st_text_size = st_text_size * CONFIG_MM_DRV_PAGE_SIZE; - st_rodata_size = st_rodata_size * CONFIG_MM_DRV_PAGE_SIZE; + st_text_size = ALIGN_UP(st_text_size, CONFIG_MM_DRV_PAGE_SIZE); + st_rodata_size = ALIGN_UP(st_rodata_size, CONFIG_MM_DRV_PAGE_SIZE); ret = sys_mm_drv_unmap_region((__sparse_force void *)va_base_text, st_text_size); if (ret < 0) @@ -193,7 +218,7 @@ static void __sparse_cache *lib_manager_get_instance_bss_address(uint32_t module { uint32_t instance_bss_size = mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length / mod->instance_max_count; - uint32_t inst_offset = instance_bss_size * CONFIG_MM_DRV_PAGE_SIZE * instance_id; + uint32_t inst_offset = ALIGN_UP(instance_bss_size, CONFIG_MM_DRV_PAGE_SIZE) * instance_id; void __sparse_cache *va_base = (void __sparse_cache *)(mod->segment[SOF_MAN_SEGMENT_BSS].v_base_addr + inst_offset); @@ -208,18 +233,17 @@ static void __sparse_cache *lib_manager_get_instance_bss_address(uint32_t module static int lib_manager_allocate_module_instance(uint32_t module_id, uint32_t instance_id, uint32_t is_pages, struct sof_man_module *mod) { - uint32_t bss_size = - (mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length / mod->instance_max_count) - * CONFIG_MM_DRV_PAGE_SIZE; + uint32_t bss_size = ALIGN_UP(mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length / + mod->instance_max_count, CONFIG_MM_DRV_PAGE_SIZE); void __sparse_cache *va_base = lib_manager_get_instance_bss_address(module_id, instance_id, mod); - +#if 0 if ((is_pages * CONFIG_MM_DRV_PAGE_SIZE) > bss_size) { - tr_err(&lib_manager_tr, "is_pages (%d) invalid, required: %d", + tr_err(&lib_manager_tr, "is_pages (%d) invalid, required: %d", is_pages, bss_size / CONFIG_MM_DRV_PAGE_SIZE); return -ENOMEM; } - +#endif /* * Map bss memory and clear it. */ @@ -235,9 +259,8 @@ static int lib_manager_allocate_module_instance(uint32_t module_id, uint32_t ins static int lib_manager_free_module_instance(uint32_t module_id, uint32_t instance_id, struct sof_man_module *mod) { - uint32_t bss_size = - (mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length / mod->instance_max_count) - * CONFIG_MM_DRV_PAGE_SIZE; + uint32_t bss_size = ALIGN_UP(mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length / + mod->instance_max_count, CONFIG_MM_DRV_PAGE_SIZE); void __sparse_cache *va_base = lib_manager_get_instance_bss_address(module_id, instance_id, mod); /* @@ -246,6 +269,9 @@ static int lib_manager_free_module_instance(uint32_t module_id, uint32_t instanc return sys_mm_drv_unmap_region((__sparse_force void *)va_base, bss_size); } +#include +#include + uint32_t lib_manager_allocate_module(const struct comp_driver *drv, struct comp_ipc_config *ipc_config, const void *ipc_specific_config) @@ -257,27 +283,76 @@ uint32_t lib_manager_allocate_module(const struct comp_driver *drv, uint32_t module_id = IPC4_MOD_ID(ipc_config->id); uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id); - tr_dbg(&lib_manager_tr, "lib_manager_allocate_module() mod_id: 0x%x", ipc_config->id); - desc = lib_manager_get_library_module_desc(module_id); if (!desc) { tr_err(&lib_manager_tr, "lib_manager_get_library_module_desc() failed: NULL"); return 0; } + size_t mod_size = desc->header.preload_page_count * CONFIG_MM_DRV_PAGE_SIZE; + /* FIXME: where does the module begin?? */ + struct module_buf_stream mbs = MODULE_BUF_STREAM((uint8_t *)desc - + SOF_MAN_ELF_TEXT_OFFSET + 0x8000 + /*mod->segment[0].file_offset + 0x84*/, + mod_size); + struct module *m; + + /* FIXME: get a name from the manifest */ + ret = module_load(&mbs.stream, "SMATEST", &m); + if (ret < 0) + return ret; + + const struct sof_man_module_manifest *mod_manifest = module_peak(&mbs.stream, + m->module_offset); + mod = (struct sof_man_module *)((char *)desc + SOF_MAN_MODULE_OFFSET(entry_index)); + mod->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr = mbs.stream.sects[MOD_SECT_TEXT].sh_addr; + mod->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length = mbs.stream.sects[MOD_SECT_TEXT].sh_size; + mod->segment[SOF_MAN_SEGMENT_TEXT].file_offset = (uintptr_t)m->mem[MOD_MEM_TEXT] - + (uintptr_t)desc; + + tr_dbg(&lib_manager_tr, ".text: start: %#x size %#x offset %#x", + mod->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr, + mod->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length, + mod->segment[SOF_MAN_SEGMENT_TEXT].file_offset); + + mod->segment[SOF_MAN_SEGMENT_DATA].v_base_addr = mbs.stream.sects[MOD_SECT_RODATA].sh_addr; + mod->segment[SOF_MAN_SEGMENT_DATA].flags.r.length = mod_size - + mbs.stream.sects[MOD_SECT_TEXT].sh_size; + mod->segment[SOF_MAN_SEGMENT_DATA].file_offset = (uintptr_t)m->mem[MOD_MEM_RODATA] - + (uintptr_t)desc; + + tr_dbg(&lib_manager_tr, ".data: start: %#x size %#x offset %#x", + mod->segment[SOF_MAN_SEGMENT_DATA].v_base_addr, + mod->segment[SOF_MAN_SEGMENT_DATA].flags.r.length, + mod->segment[SOF_MAN_SEGMENT_DATA].file_offset); + + tr_dbg(&lib_manager_tr, "lib_manager_allocate_module() mod_id: %#x desc %#x name %s", + ipc_config->id, *(uint32_t *)mod->struct_id, mod->name); + + /* Map .text and the rest as .data */ ret = lib_manager_load_module(module_id, mod, desc); if (ret < 0) return 0; + /* Map .bss */ ret = lib_manager_allocate_module_instance(module_id, IPC4_INST_ID(ipc_config->id), base_cfg->is_pages, mod); if (ret < 0) { tr_err(&lib_manager_tr, "lib_manager_allocate_module() failed: %d", ret); return 0; } - return mod->entry_point; + + tr_dbg(&ipc_tr, "name %s entry %#x: %#x %#x", mod_manifest->module.name, + mod_manifest->module.entry_point, + ((uint32_t *)mod_manifest->module.entry_point)[0], + ((uint32_t *)mod_manifest->module.entry_point)[1]); + + void *(*entry)(void *mod_cfg, void *parent_ppl, void **mod_ptr) = + (void *)mod_manifest->module.entry_point; + + return (uint32_t)entry/*mod->entry_point*/; } int lib_manager_free_module(const struct comp_driver *drv, @@ -320,6 +395,8 @@ struct sof_man_fw_desc *lib_manager_get_library_module_desc(int module_id) struct ext_library *_ext_lib = ext_lib_get(); uint8_t *buffptr = (uint8_t *)_ext_lib->desc[lib_id]; + tr_dbg(&lib_manager_tr, "module %x lib %x buf %p", module_id, lib_id, (void*)buffptr); + if (!buffptr) return NULL; return (struct sof_man_fw_desc *)(buffptr + SOF_MAN_ELF_TEXT_OFFSET); @@ -329,6 +406,8 @@ static void lib_manager_update_sof_ctx(struct sof_man_fw_desc *desc, uint32_t li { struct ext_library *_ext_lib = ext_lib_get(); + tr_dbg(&lib_manager_tr, "lib %x buf %p", lib_id, desc); + _ext_lib->desc[lib_id] = desc; /* TODO: maybe need to call here dcache_writeback here? */ } @@ -573,21 +652,10 @@ static int lib_manager_store_library(struct lib_manager_dma_ext *dma_ext, struct uint32_t preload_size = man_desc->header.preload_page_count * CONFIG_MM_DRV_PAGE_SIZE; int ret; - /* DEBUG */ - if (preload_size > 100) { - tr_info(&lib_manager_tr, "lib_manager_store_library(): preload %u", - preload_size); - return -ENOMEM; - } else if (!preload_size) { - tr_err(&lib_manager_tr, "lib_manager_store_library(): preload %u", - preload_size); - return -EINVAL; - } - /* Prepare storage memory, note: it is never freed, library unloading is unsupported */ library_base_address = lib_manager_allocate_store_mem(preload_size, 0); - tr_err(&lib_manager_tr, "lib_manager_store_library(): pointer: %p", - (__sparse_force void *)library_base_address); + tr_info(&lib_manager_tr, "lib_manager_store_library(): preload %u pointer: %p ID %u", + preload_size, (__sparse_force void *)library_base_address, lib_id); if (!library_base_address) return -ENOMEM; @@ -627,9 +695,6 @@ int lib_manager_load_library(uint32_t dma_id, uint32_t lib_id) lib_manager_init(); - /* DEBUG */ - return 0; - ret = lib_manager_dma_init(&dma_ext, dma_id); if (ret < 0) return ret; diff --git a/src/math/numbers.c b/src/math/numbers.c index 3f297681dc70..77ef023f6479 100644 --- a/src/math/numbers.c +++ b/src/math/numbers.c @@ -13,6 +13,7 @@ #include #include #include +#include /* This function returns the greatest common divisor of two numbers * If both parameters are 0, gcd(0, 0) returns 0 @@ -72,6 +73,7 @@ int gcd(int a, int b) /* restore common factors of 2 */ return a << k; } +EXPORT_SYMBOL(gcd); #if CONFIG_NUMBERS_VECTOR_FIND diff --git a/src/samples/audio/smart_amp_test_ipc4.c b/src/samples/audio/smart_amp_test_ipc4.c index f8a9f8da1732..bc66cb630dce 100644 --- a/src/samples/audio/smart_amp_test_ipc4.c +++ b/src/samples/audio/smart_amp_test_ipc4.c @@ -39,6 +39,8 @@ struct smart_amp_data { uint32_t out_channels; }; +static int keep_bss; + static int smart_amp_init(struct processing_module *mod) { struct smart_amp_data *sad; @@ -49,7 +51,11 @@ static int smart_amp_init(struct processing_module *mod) int ret; const struct ipc4_base_module_extended_cfg *base_cfg = mod_data->cfg.init_data; - comp_dbg(dev, "smart_amp_init()"); + if (!base_cfg) { + comp_err(dev, "smart_amp_init(): no rzalloc %d", ++keep_bss); + return -EINVAL; + } + sad = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*sad)); if (!sad) return -ENOMEM; @@ -65,7 +71,9 @@ static int smart_amp_init(struct processing_module *mod) if (base_cfg->base_cfg_ext.nb_input_pins != SMART_AMP_NUM_IN_PINS || base_cfg->base_cfg_ext.nb_output_pins != SMART_AMP_NUM_OUT_PINS) { - comp_err(dev, "smart_amp_init(): Invalid pin configuration"); + comp_err(dev, "smart_amp_init(): Invalid pin configuration: %d %d %d", + base_cfg->base_cfg_ext.nb_input_pins, + base_cfg->base_cfg_ext.nb_output_pins, ++keep_bss); ret = -EINVAL; goto sad_fail; } @@ -105,6 +113,7 @@ static void smart_amp_set_params(struct processing_module *mod) sink_c = buffer_acquire(sink); ipc4_update_buffer_format(sink_c, &out_fmt); + comp_info(dev, "smart_amp_set_params() %p", sink); params->frame_fmt = audio_stream_get_frm_fmt(&sink_c->stream); buffer_release(sink_c); } @@ -118,7 +127,7 @@ static int smart_amp_set_config(struct processing_module *mod, uint32_t config_i struct comp_dev *dev = mod->dev; struct smart_amp_data *sad = module_get_private_data(mod); - comp_dbg(dev, "smart_amp_set_config()"); + comp_dbg(dev, "smart_amp_set_config(): %u", config_id); switch (config_id) { case SMART_AMP_SET_MODEL: @@ -182,7 +191,9 @@ static int smart_amp_params(struct processing_module *mod) comp_dbg(dev, "smart_amp_params()"); smart_amp_set_params(mod); + ret = comp_verify_params(dev, BUFF_PARAMS_CHANNELS, params); + comp_dbg(dev, "smart_amp_params(): %d", ret); if (ret < 0) { comp_err(dev, "smart_amp_params(): pcm params verification failed."); return -EINVAL; @@ -366,6 +377,7 @@ static int smart_amp_prepare(struct processing_module *mod, source_buffer = container_of(blist, struct comp_buffer, sink_list); buffer_c = buffer_acquire(source_buffer); + comp_dbg(dev, "smart_amp_prepare() init source %p", source_buffer); audio_stream_init_alignment_constants(1, 1, &buffer_c->stream); if (IPC4_SINK_QUEUE_ID(buffer_c->id) == SOF_SMART_AMP_FEEDBACK_QUEUE_ID) { audio_stream_set_channels(&buffer_c->stream, sad->config.feedback_channels); @@ -377,6 +389,7 @@ static int smart_amp_prepare(struct processing_module *mod, sink_buffer = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); buffer_c = buffer_acquire(sink_buffer); + comp_dbg(dev, "smart_amp_prepare() init sink %p", sink_buffer); sad->out_channels = audio_stream_get_channels(&buffer_c->stream); audio_stream_init_alignment_constants(1, 1, &buffer_c->stream); sad->process = get_smart_amp_process(dev, buffer_c); @@ -389,8 +402,8 @@ static int smart_amp_prepare(struct processing_module *mod, return ret; } -static struct module_interface smart_amp_interface = { - .init = smart_amp_init, +static const struct module_interface smart_amp_interface = { + .init = smart_amp_init, .prepare = smart_amp_prepare, .process_audio_stream = smart_amp_process, .set_configuration = smart_amp_set_config, @@ -404,7 +417,7 @@ SOF_MODULE_INIT(smart_amp_test, sys_comp_module_smart_amp_interface_init); #ifdef MAJOR_IADSP_API_VERSION #include -static void *loadable_module_main(void *mod_cfg, void *parent_ppl, void **mod_ptr) +static const void *loadable_module_main(void *mod_cfg, void *parent_ppl, void **mod_ptr) { return &smart_amp_interface; } diff --git a/zephyr/lib/alloc.c b/zephyr/lib/alloc.c index e6435c7b0b4a..bc2bc849f372 100644 --- a/zephyr/lib/alloc.c +++ b/zephyr/lib/alloc.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -272,6 +273,7 @@ void *rmalloc(enum mem_zone zone, uint32_t flags, uint32_t caps, size_t bytes) return ptr; } +EXPORT_SYMBOL(rmalloc); /* Use SOF_MEM_ZONE_BUFFER at the moment */ void *rbrealloc_align(void *ptr, uint32_t flags, uint32_t caps, size_t bytes, @@ -320,6 +322,7 @@ void *rzalloc(enum mem_zone zone, uint32_t flags, uint32_t caps, size_t bytes) return ptr; } +EXPORT_SYMBOL(rzalloc); /** * Allocates memory block from SOF_MEM_ZONE_BUFFER. @@ -337,6 +340,7 @@ void *rballoc_align(uint32_t flags, uint32_t caps, size_t bytes, return (__sparse_force void *)heap_alloc_aligned_cached(&sof_heap, align, bytes); } +EXPORT_SYMBOL(rballoc_align); /* * Free's memory allocated by above alloc calls. @@ -355,6 +359,7 @@ void rfree(void *ptr) heap_free(&sof_heap, ptr); } +EXPORT_SYMBOL(rfree); static int heap_init(void) {