diff --git a/src/audio/buffers/audio_buffer.c b/src/audio/buffers/audio_buffer.c index af882accaae8..f63a9a7c93b6 100644 --- a/src/audio/buffers/audio_buffer.c +++ b/src/audio/buffers/audio_buffer.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -92,9 +93,8 @@ void audio_buffer_free(struct sof_audio_buffer *buffer) audio_buffer_free(buffer->secondary_buffer_sink); audio_buffer_free(buffer->secondary_buffer_source); #endif /* CONFIG_PIPELINE_2_0 */ - if (buffer->ops->free) - buffer->ops->free(buffer); - rfree(buffer); + /* "virtual destructor": free the buffer internals and buffer memory */ + buffer->ops->free(buffer); } static @@ -196,6 +196,7 @@ void audio_buffer_init(struct sof_audio_buffer *buffer, uint32_t buffer_type, bo CORE_CHECK_STRUCT_INIT(&buffer, is_shared); buffer->buffer_type = buffer_type; buffer->ops = audio_buffer_ops; + assert(audio_buffer_ops->free); buffer->audio_stream_params = audio_stream_params; buffer->is_shared = is_shared; diff --git a/src/audio/buffers/comp_buffer.c b/src/audio/buffers/comp_buffer.c index 02b44e5dcdce..232e26cbec8a 100644 --- a/src/audio/buffers/comp_buffer.c +++ b/src/audio/buffers/comp_buffer.c @@ -158,6 +158,7 @@ static void comp_buffer_free(struct sof_audio_buffer *audio_buffer) notifier_unregister_all(NULL, buffer); rfree(buffer->stream.addr); + rfree(buffer); } static struct source_ops comp_buffer_source_ops = { diff --git a/src/audio/buffers/ring_buffer.c b/src/audio/buffers/ring_buffer.c index 52acc91a11f4..d7bd251b3c23 100644 --- a/src/audio/buffers/ring_buffer.c +++ b/src/audio/buffers/ring_buffer.c @@ -96,6 +96,7 @@ static void ring_buffer_free(struct sof_audio_buffer *audio_buffer) container_of(audio_buffer, struct ring_buffer, audio_buffer); rfree((__sparse_force void *)ring_buffer->_data_buffer); + rfree(ring_buffer); } static void ring_buffer_reset(struct sof_audio_buffer *audio_buffer) @@ -239,6 +240,21 @@ static int ring_buffer_release_data(struct sof_source *source, size_t free_size) return 0; } +int ring_buffer_module_unbind(struct sof_sink *sink) +{ + struct ring_buffer *ring_buffer = ring_buffer_from_sink(sink); + + CORE_CHECK_STRUCT(&ring_buffer->audio_buffer); + + /* in case of disconnection, invalidate all cache. This method is guaranteed be called on + * core that have been using sink API + */ + ring_buffer_invalidate_shared(ring_buffer, ring_buffer->_data_buffer, + ring_buffer->data_buffer_size); + + return 0; +} + static struct source_ops ring_buffer_source_ops = { .get_data_available = ring_buffer_get_data_available, .get_data = ring_buffer_get_data, @@ -249,6 +265,7 @@ static struct sink_ops ring_buffer_sink_ops = { .get_free_size = ring_buffer_get_free_size, .get_buffer = ring_buffer_get_buffer, .commit_buffer = ring_buffer_commit_buffer, + .on_unbind = ring_buffer_module_unbind, }; static const struct audio_buffer_ops audio_buffer_ops = { diff --git a/src/audio/copier/copier.c b/src/audio/copier/copier.c index bc6f92db62df..5d4b47a1d5fc 100644 --- a/src/audio/copier/copier.c +++ b/src/audio/copier/copier.c @@ -1173,9 +1173,9 @@ __cold static int copier_get_hw_params(struct comp_dev *dev, struct sof_ipc_stre return dai_common_get_hw_params(dd, dev, params, dir); } -__cold static int copier_bind(struct processing_module *mod, void *data) +__cold static int copier_bind(struct processing_module *mod, struct bind_info *bind_data) { - const struct ipc4_module_bind_unbind *const bu = (struct ipc4_module_bind_unbind *)data; + const struct ipc4_module_bind_unbind *const bu = bind_data->ipc4_data; const uint32_t src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id); const uint32_t src_queue_id = bu->extension.r.src_queue; struct copier_data *cd = module_get_private_data(mod); @@ -1202,7 +1202,7 @@ __cold static int copier_bind(struct processing_module *mod, void *data) return -ENODEV; } -__cold static int copier_unbind(struct processing_module *mod, void *data) +__cold static int copier_unbind(struct processing_module *mod, struct bind_info *unbind_data) { struct copier_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; @@ -1212,7 +1212,7 @@ __cold static int copier_unbind(struct processing_module *mod, void *data) if (dev->ipc_config.type == SOF_COMP_DAI) { struct dai_data *dd = cd->dd[0]; - return dai_zephyr_unbind(dd, dev, data); + return dai_zephyr_unbind(dd, dev, unbind_data); } return 0; diff --git a/src/audio/copier/dai_copier.h b/src/audio/copier/dai_copier.h index a03970288b1b..0ec7f04ae6ac 100644 --- a/src/audio/copier/dai_copier.h +++ b/src/audio/copier/dai_copier.h @@ -69,7 +69,7 @@ static inline int dai_zephyr_unbind(struct dai_data *dd, struct comp_dev *dev, v int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev, struct comp_buffer *multi_endpoint_buffer, int num_endpoints); -int dai_zephyr_unbind(struct dai_data *dd, struct comp_dev *dev, void *data); +int dai_zephyr_unbind(struct dai_data *dd, struct comp_dev *dev, struct bind_info *unbind_data); #endif diff --git a/src/audio/dai-zephyr.c b/src/audio/dai-zephyr.c index c36a89a9c57b..3d9ac2212158 100644 --- a/src/audio/dai-zephyr.c +++ b/src/audio/dai-zephyr.c @@ -1961,14 +1961,15 @@ static uint64_t dai_get_processed_data(struct comp_dev *dev, uint32_t stream_no, } #ifdef CONFIG_IPC_MAJOR_4 -__cold int dai_zephyr_unbind(struct dai_data *dd, struct comp_dev *dev, void *data) +__cold +int dai_zephyr_unbind(struct dai_data *dd, struct comp_dev *dev, struct bind_info *unbind_data) { struct ipc4_module_bind_unbind *bu; int buf_id; assert_can_be_cold(); - bu = (struct ipc4_module_bind_unbind *)data; + bu = unbind_data->ipc4_data; buf_id = IPC4_COMP_ID(bu->extension.r.src_queue, bu->extension.r.dst_queue); if (dd && dd->local_buffer) { diff --git a/src/audio/kpb.c b/src/audio/kpb.c index 61f85c34bca3..28a7423786fb 100644 --- a/src/audio/kpb.c +++ b/src/audio/kpb.c @@ -333,10 +333,10 @@ static int kpb_get_attribute(struct comp_dev *dev, /** * \brief Initialize KPB sinks when binding. * \param[in] dev - component device pointer. - * \param[in] data - ipc4 bind/unbind data. + * \param[in] bind_data - bind/unbind data. * \return: none. */ -static int kpb_bind(struct comp_dev *dev, void *data) +static int kpb_bind(struct comp_dev *dev, struct bind_info *bind_data) { struct comp_data *kpb = comp_get_drvdata(dev); struct ipc4_module_bind_unbind *bu; @@ -345,7 +345,7 @@ static int kpb_bind(struct comp_dev *dev, void *data) comp_dbg(dev, "kpb_bind()"); - bu = (struct ipc4_module_bind_unbind *)data; + bu = bind_data->ipc4_data; buf_id = IPC4_COMP_ID(bu->extension.r.src_queue, bu->extension.r.dst_queue); /* We're assuming here that KPB Real Time sink (kpb->sel_sink) is @@ -383,7 +383,7 @@ static int kpb_bind(struct comp_dev *dev, void *data) * \param[in] data - ipc4 bind/unbind data. * \return: none. */ -static int kpb_unbind(struct comp_dev *dev, void *data) +static int kpb_unbind(struct comp_dev *dev, struct bind_info *unbind_data) { struct comp_data *kpb = comp_get_drvdata(dev); struct ipc4_module_bind_unbind *bu; @@ -391,7 +391,7 @@ static int kpb_unbind(struct comp_dev *dev, void *data) comp_dbg(dev, "kpb_bind()"); - bu = (struct ipc4_module_bind_unbind *)data; + bu = unbind_data->ipc4_data; buf_id = IPC4_COMP_ID(bu->extension.r.src_queue, bu->extension.r.dst_queue); /* Reset sinks when unbinding */ diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index 0bbceebba3c1..82ff7acfb030 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -784,7 +784,7 @@ static int mixout_prepare(struct processing_module *mod, return 0; } -static int mixout_bind(struct processing_module *mod, void *data) +static int mixout_bind(struct processing_module *mod, struct bind_info *bind_data) { struct ipc4_module_bind_unbind *bu; struct comp_dev *mixin; @@ -792,9 +792,7 @@ static int mixout_bind(struct processing_module *mod, void *data) int src_id; struct mixout_data *mixout_data; - comp_dbg(mod->dev, "mixout_bind() %p", data); - - bu = (struct ipc4_module_bind_unbind *)data; + bu = bind_data->ipc4_data; src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id); /* we are only interested in bind for mixin -> mixout pair */ @@ -833,7 +831,7 @@ static int mixout_bind(struct processing_module *mod, void *data) return 0; } -static int mixout_unbind(struct processing_module *mod, void *data) +static int mixout_unbind(struct processing_module *mod, struct bind_info *unbind_data) { struct ipc4_module_bind_unbind *bu; struct comp_dev *mixin; @@ -843,7 +841,7 @@ static int mixout_unbind(struct processing_module *mod, void *data) comp_dbg(mod->dev, "mixout_unbind()"); - bu = (struct ipc4_module_bind_unbind *)data; + bu = unbind_data->ipc4_data; src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id); /* we are only interested in unbind for mixin -> mixout pair */ diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index f81fd42d3766..1e806a1d4915 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -493,22 +493,52 @@ int module_set_configuration(struct processing_module *mod, } EXPORT_SYMBOL(module_set_configuration); -int module_bind(struct processing_module *mod, void *data) +int module_bind(struct processing_module *mod, struct bind_info *bind_data) { + int ret; const struct module_interface *const ops = mod->dev->drv->adapter_ops; + switch (bind_data->bind_type) { + case COMP_BIND_TYPE_SINK: + ret = sink_bind(bind_data->sink, mod); + break; + case COMP_BIND_TYPE_SOURCE: + ret = source_bind(bind_data->source, mod); + break; + default: + ret = -EINVAL; + } + if (ret) + return ret; + if (ops->bind) - return ops->bind(mod, data); - return 0; + ret = ops->bind(mod, bind_data); + + return ret; } -int module_unbind(struct processing_module *mod, void *data) +int module_unbind(struct processing_module *mod, struct bind_info *unbind_data) { + int ret; const struct module_interface *const ops = mod->dev->drv->adapter_ops; + switch (unbind_data->bind_type) { + case COMP_BIND_TYPE_SINK: + ret = sink_unbind(unbind_data->sink); + break; + case COMP_BIND_TYPE_SOURCE: + ret = source_unbind(unbind_data->source); + break; + default: + ret = -EINVAL; + } + if (ret) + return ret; + if (ops->unbind) - return ops->unbind(mod, data); - return 0; + ret = ops->unbind(mod, unbind_data); + + return ret; } void module_update_buffer_position(struct input_stream_buffer *input_buffers, diff --git a/src/audio/module_adapter/module_adapter_ipc4.c b/src/audio/module_adapter/module_adapter_ipc4.c index fb7642212f4f..a50b78ff7714 100644 --- a/src/audio/module_adapter/module_adapter_ipc4.c +++ b/src/audio/module_adapter/module_adapter_ipc4.c @@ -242,12 +242,12 @@ static bool module_adapter_multi_sink_source_prepare(struct comp_dev *dev) return false; } -int module_adapter_bind(struct comp_dev *dev, void *data) +int module_adapter_bind(struct comp_dev *dev, struct bind_info *bind_data) { struct processing_module *mod = comp_mod(dev); int ret; - ret = module_bind(mod, data); + ret = module_bind(mod, bind_data); if (ret < 0) return ret; @@ -257,12 +257,12 @@ int module_adapter_bind(struct comp_dev *dev, void *data) } EXPORT_SYMBOL(module_adapter_bind); -int module_adapter_unbind(struct comp_dev *dev, void *data) +int module_adapter_unbind(struct comp_dev *dev, struct bind_info *unbind_data) { struct processing_module *mod = comp_mod(dev); int ret; - ret = module_unbind(mod, data); + ret = module_unbind(mod, unbind_data); if (ret < 0) return ret; diff --git a/src/debug/tester/tester.c b/src/debug/tester/tester.c index bcbda904fcf7..575e339646a8 100644 --- a/src/debug/tester/tester.c +++ b/src/debug/tester/tester.c @@ -188,24 +188,24 @@ static int tester_free(struct processing_module *mod) return ret; } -static int tester_bind(struct processing_module *mod, void *data) +static int tester_bind(struct processing_module *mod, struct bind_info *bind_data) { struct tester_module_data *cd = module_get_private_data(mod); int ret = 0; if (cd->tester_case_interface->bind) - ret = cd->tester_case_interface->bind(cd->test_case_ctx, mod, data); + ret = cd->tester_case_interface->bind(cd->test_case_ctx, mod, bind_data); return ret; } -static int tester_unbind(struct processing_module *mod, void *data) +static int tester_unbind(struct processing_module *mod, struct bind_info *unbind_data) { struct tester_module_data *cd = module_get_private_data(mod); int ret = 0; if (cd->tester_case_interface->unbind) - ret = cd->tester_case_interface->unbind(cd->test_case_ctx, mod, data); + ret = cd->tester_case_interface->unbind(cd->test_case_ctx, mod, unbind_data); return ret; } diff --git a/src/debug/tester/tester.h b/src/debug/tester/tester.h index ccfb8fabdc5a..79a65b65a7b2 100644 --- a/src/debug/tester/tester.h +++ b/src/debug/tester/tester.h @@ -75,12 +75,12 @@ struct tester_test_case_interface { /** * copy of module bind method, with additional ctx param */ - int (*bind)(void *ctx, struct processing_module *mod, void *data); + int (*bind)(void *ctx, struct processing_module *mod, struct bind_info *bind_data); /** * copy of module unbind method, with additional ctx param */ - int (*unbind)(void *ctx, struct processing_module *mod, void *data); + int (*unbind)(void *ctx, struct processing_module *mod, struct bind_info *unbind_data); /** * copy of module trigger method, with additional ctx param diff --git a/src/idc/idc.c b/src/idc/idc.c index 68efb2ee2f75..8250175bfcb7 100644 --- a/src/idc/idc.c +++ b/src/idc/idc.c @@ -86,14 +86,14 @@ static int idc_ipc4_bind(uint32_t comp_id) { struct ipc_comp_dev *ipc_dev; struct idc_payload *payload; - struct ipc4_module_bind_unbind *bu; + struct bind_info *bu; ipc_dev = ipc_get_comp_by_id(ipc_get(), comp_id); if (!ipc_dev) return -ENODEV; payload = idc_payload_get(*idc_get(), cpu_get_id()); - bu = (struct ipc4_module_bind_unbind *)payload; + bu = (struct bind_info *)payload; return comp_bind(ipc_dev->cd, bu); } @@ -102,14 +102,14 @@ static int idc_ipc4_unbind(uint32_t comp_id) { struct ipc_comp_dev *ipc_dev; struct idc_payload *payload; - struct ipc4_module_bind_unbind *bu; + struct bind_info *bu; ipc_dev = ipc_get_comp_by_id(ipc_get(), comp_id); if (!ipc_dev) return -ENODEV; payload = idc_payload_get(*idc_get(), cpu_get_id()); - bu = (struct ipc4_module_bind_unbind *)payload; + bu = (struct bind_info *)payload; return comp_unbind(ipc_dev->cd, bu); } diff --git a/src/include/module/audio/sink_api.h b/src/include/module/audio/sink_api.h index 839111abc536..527fd1dc11c6 100644 --- a/src/include/module/audio/sink_api.h +++ b/src/include/module/audio/sink_api.h @@ -51,6 +51,7 @@ struct sof_sink; struct sof_audio_stream_params; struct sof_ipc_stream_params; +struct processing_module; /** * this is a definition of internals of sink API @@ -101,6 +102,14 @@ struct sink_ops { int (*set_alignment_constants)(struct sof_sink *sink, const uint32_t byte_align, const uint32_t frame_align_req); + + /** + * OPTIONAL + * events called when a module is starting / finishing using of the API + * on the core that the module and API will executed on + */ + int (*on_bind)(struct sof_sink *sink, struct processing_module *module); + int (*on_unbind)(struct sof_sink *sink); }; /** internals of sink API. NOT TO BE MODIFIED OUTSIDE OF sink_api.c */ @@ -111,6 +120,7 @@ struct sof_sink { size_t min_free_space; /** minimum buffer space required by the module using sink * it is module's OBS as declared in module bind IPC */ + struct processing_module *bound_module; /* a pointer module that is using sink API */ struct sof_audio_stream_params *audio_stream_params; /** pointer to audio params */ }; @@ -291,4 +301,51 @@ static inline uint32_t sink_get_pipeline_id(struct sof_sink *sink) return sink->audio_stream_params->pipeline_id; } +/** + * @brief hook to be called when a module connects to the API + * + * NOTE! it MUST be called at core that a module is bound to + */ +static inline int sink_bind(struct sof_sink *sink, struct processing_module *module) +{ + int ret = 0; + + if (sink->bound_module) + return -EBUSY; + + if (sink->ops->on_bind) + ret = sink->ops->on_bind(sink, module); + + if (!ret) + sink->bound_module = module; + + return ret; +} + +/** + * @brief hook to be called when a module disconnects from the API + * + * NOTE! it MUST be called at core that a module is bound to + */ +static inline int sink_unbind(struct sof_sink *sink) +{ + int ret = 0; + + if (!sink->bound_module) + return -EINVAL; + + if (sink->ops->on_unbind) + ret = sink->ops->on_unbind(sink); + + if (!ret) + sink->bound_module = NULL; + + return ret; +} + +static inline struct processing_module *sink_get_bound_module(struct sof_sink *sink) +{ + return sink->bound_module; +} + #endif /* __MODULE_AUDIO_SINK_API_H__ */ diff --git a/src/include/module/audio/source_api.h b/src/include/module/audio/source_api.h index cb82cab457f3..336535e1be26 100644 --- a/src/include/module/audio/source_api.h +++ b/src/include/module/audio/source_api.h @@ -51,6 +51,7 @@ struct sof_source; struct sof_audio_stream_params; struct sof_ipc_stream_params; +struct processing_module; /** * this is a definition of internals of source API @@ -101,6 +102,14 @@ struct source_ops { int (*set_alignment_constants)(struct sof_source *source, const uint32_t byte_align, const uint32_t frame_align_req); + + /** + * OPTIONAL + * events called when a module is starting / finishing using of the API + * on the core that the module and API will executed on + */ + int (*on_bind)(struct sof_source *source, struct processing_module *module); + int (*on_unbind)(struct sof_source *source); }; /** internals of source API. NOT TO BE MODIFIED OUTSIDE OF source_api.c */ @@ -112,7 +121,7 @@ struct sof_source { * source * it is module's IBS as declared in module bind IPC */ - + struct processing_module *bound_module; /* a pointer module that is using source API */ struct sof_audio_stream_params *audio_stream_params; }; @@ -267,4 +276,51 @@ static inline uint32_t source_get_pipeline_id(struct sof_source *source) return source->audio_stream_params->pipeline_id; } +/** + * @brief hook to be called when a module connects to the API + * + * NOTE! it MUST be called at core that a module is bound to + */ +static inline int source_bind(struct sof_source *source, struct processing_module *module) +{ + int ret = 0; + + if (source->bound_module) + return -EBUSY; + + if (source->ops->on_bind) + ret = source->ops->on_bind(source, module); + + if (!ret) + source->bound_module = module; + + return ret; +} + +/** + * @brief hook to be called when a module disconnects from the API + * + * NOTE! it MUST be called at core that a module is bound to + */ +static inline int source_unbind(struct sof_source *source) +{ + int ret = 0; + + if (!source->bound_module) + return -EINVAL; + + if (source->ops->on_unbind) + ret = source->ops->on_unbind(source); + + if (!ret) + source->bound_module = NULL; + + return ret; +} + +static inline struct processing_module *source_get_bound_module(struct sof_source *source) +{ + return source->bound_module; +} + #endif /* __MODULE_AUDIO_SOURCE_API_H__ */ diff --git a/src/include/module/module/interface.h b/src/include/module/module/interface.h index 75b4621c716c..26c176aee9b1 100644 --- a/src/include/module/module/interface.h +++ b/src/include/module/module/interface.h @@ -65,6 +65,8 @@ struct output_stream_buffer { struct processing_module; struct sof_source; struct sof_sink; +struct bind_info; +struct bind_info; /* * This structure may be used by modules to carry short 16bit parameters. @@ -266,13 +268,13 @@ struct module_interface { * (optional) Module specific bind procedure, called when modules are bound with each other. * Usually can be __cold */ - int (*bind)(struct processing_module *mod, void *data); + int (*bind)(struct processing_module *mod, struct bind_info *bind_data); /** * (optional) Module specific unbind procedure, called when modules are disconnected from * one another. Usually can be __cold */ - int (*unbind)(struct processing_module *mod, void *data); + int (*unbind)(struct processing_module *mod, struct bind_info *unbind_data); /** * (optional) Module specific trigger procedure, called when modules are triggered. Usually diff --git a/src/include/sof/audio/audio_buffer.h b/src/include/sof/audio/audio_buffer.h index 4984c3dee99a..e7fc6e7e1c5d 100644 --- a/src/include/sof/audio/audio_buffer.h +++ b/src/include/sof/audio/audio_buffer.h @@ -21,8 +21,8 @@ struct sof_audio_buffer; struct audio_buffer_ops { /** * @brief this method must free all structures allocated by buffer implementation - * it must not free the buffer memory itself - * OPTIONAL + * and the buffer itself + * OBLIGATORY */ void (*free)(struct sof_audio_buffer *buffer); diff --git a/src/include/sof/audio/component.h b/src/include/sof/audio/component.h index 0091419cc442..337730ccae7d 100644 --- a/src/include/sof/audio/component.h +++ b/src/include/sof/audio/component.h @@ -271,6 +271,40 @@ enum comp_copy_type { struct comp_driver; struct comp_ipc_config; union ipc_config_specific; +struct ipc4_module_bind_unbind; + +enum bind_type { + COMP_BIND_TYPE_SOURCE, + COMP_BIND_TYPE_SINK +}; + +struct bind_info { + /* pointer to IPC4 bind/unbind data */ + struct ipc4_module_bind_unbind *ipc4_data; + + /* type of binding + * bind call will be called twice for every component, first when binding a data source, + * than when binding data sink. + * + * bind_type is indicating type of binding + */ + enum bind_type bind_type; + + /* pointers to sink or source API of the data provider/consumer + * that is being bound to the module + * + * if bind_type == COMP_BIND_TYPE_SOURCE, the pointer points to source being bound/unbound + * if bind_type == COMP_BIND_TYPE_SINK, the pointer points to sink being bound/unbound + * + * NOTE! As in pipeline2.0 there may be a binding between modules, + * without a buffer in between, it cannot be a pointer to any buffer type, module should + * use sink/source API + */ + union { + struct sof_source *source; + struct sof_sink *sink; + }; +}; /** * Audio component operations. @@ -481,7 +515,7 @@ struct comp_ops { * * Usually can be __cold. */ - int (*bind)(struct comp_dev *dev, void *data); + int (*bind)(struct comp_dev *dev, struct bind_info *bind_data); /** * Unbind, atomic - used to notify component of unbind event. @@ -490,7 +524,7 @@ struct comp_ops { * * Usually can be __cold. */ - int (*unbind)(struct comp_dev *dev, void *data); + int (*unbind)(struct comp_dev *dev, struct bind_info *unbind_data); /** * Gets config in component. diff --git a/src/include/sof/audio/component_ext.h b/src/include/sof/audio/component_ext.h index d66854f4b27d..c33f792f075a 100644 --- a/src/include/sof/audio/component_ext.h +++ b/src/include/sof/audio/component_ext.h @@ -432,58 +432,59 @@ static inline struct comp_driver_list *comp_drivers_get(void) } #if CONFIG_IPC_MAJOR_4 -static inline int comp_ipc4_bind_remote(struct comp_dev *dev, void *data) +static inline int comp_ipc4_bind_remote(struct comp_dev *dev, struct bind_info *bind_data) { struct idc_msg msg = { IDC_MSG_BIND, IDC_EXTENSION(dev->ipc_config.id), dev->ipc_config.core, - sizeof(struct ipc4_module_bind_unbind), data}; + sizeof(*bind_data), bind_data}; return idc_send_msg(&msg, IDC_BLOCKING); } #endif -static inline int comp_bind(struct comp_dev *dev, void *data) +static inline int comp_bind(struct comp_dev *dev, struct bind_info *bind_data) { #if CONFIG_IPC_MAJOR_4 if (dev->drv->ops.bind) return cpu_is_me(dev->ipc_config.core) ? - dev->drv->ops.bind(dev, data) : comp_ipc4_bind_remote(dev, data); + dev->drv->ops.bind(dev, bind_data) : comp_ipc4_bind_remote(dev, bind_data); return 0; #else int ret = 0; if (dev->drv->ops.bind) - ret = dev->drv->ops.bind(dev, data); + ret = dev->drv->ops.bind(dev, bind_data); return ret; #endif } #if CONFIG_IPC_MAJOR_4 -static inline int comp_ipc4_unbind_remote(struct comp_dev *dev, void *data) +static inline int comp_ipc4_unbind_remote(struct comp_dev *dev, struct bind_info *unbind_data) { struct idc_msg msg = { IDC_MSG_UNBIND, IDC_EXTENSION(dev->ipc_config.id), dev->ipc_config.core, - sizeof(struct ipc4_module_bind_unbind), data}; + sizeof(*unbind_data), unbind_data}; return idc_send_msg(&msg, IDC_BLOCKING); } #endif -static inline int comp_unbind(struct comp_dev *dev, void *data) +static inline int comp_unbind(struct comp_dev *dev, struct bind_info *unbind_data) { #if CONFIG_IPC_MAJOR_4 if (dev->drv->ops.unbind) return cpu_is_me(dev->ipc_config.core) ? - dev->drv->ops.unbind(dev, data) : comp_ipc4_unbind_remote(dev, data); + dev->drv->ops.unbind(dev, unbind_data) : + comp_ipc4_unbind_remote(dev, unbind_data); return 0; #else int ret = 0; if (dev->drv->ops.unbind) - ret = dev->drv->ops.unbind(dev, data); + ret = dev->drv->ops.unbind(dev, unbind_data); return ret; #endif diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index 60906685a21a..fb7f4ca02202 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -205,8 +205,8 @@ int module_set_configuration(struct processing_module *mod, enum module_cfg_fragment_position pos, size_t data_offset_size, const uint8_t *fragment, size_t fragment_size, uint8_t *response, size_t response_size); -int module_bind(struct processing_module *mod, void *data); -int module_unbind(struct processing_module *mod, void *data); +int module_bind(struct processing_module *mod, struct bind_info *bind_data); +int module_unbind(struct processing_module *mod, struct bind_info *unbind_data); struct comp_dev *module_adapter_new(const struct comp_driver *drv, const struct comp_ipc_config *config, const void *spec); @@ -246,13 +246,13 @@ int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_ } static inline -int module_adapter_bind(struct comp_dev *dev, void *data) +int module_adapter_bind(struct comp_dev *dev, struct bind_info *bind_data) { return 0; } static inline -int module_adapter_unbind(struct comp_dev *dev, void *data) +int module_adapter_unbind(struct comp_dev *dev, struct bind_info *unbind_data) { return 0; } @@ -281,8 +281,8 @@ int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_ bool last_block, uint32_t *data_offset, char *data); int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *value); int module_adapter_set_attribute(struct comp_dev *dev, uint32_t type, void *value); -int module_adapter_bind(struct comp_dev *dev, void *data); -int module_adapter_unbind(struct comp_dev *dev, void *data); +int module_adapter_bind(struct comp_dev *dev, struct bind_info *bind_data); +int module_adapter_unbind(struct comp_dev *dev, struct bind_info *unbind_data); uint64_t module_adapter_get_total_data_processed(struct comp_dev *dev, uint32_t stream_no, bool input); diff --git a/src/ipc/ipc4/helper.c b/src/ipc/ipc4/helper.c index 09de3e448aa2..ed4fff79fb2d 100644 --- a/src/ipc/ipc4/helper.c +++ b/src/ipc/ipc4/helper.c @@ -476,6 +476,7 @@ static int ll_wait_finished_on_core(struct comp_dev *dev) __cold int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) { struct ipc4_module_bind_unbind *bu; + struct bind_info bind_data; struct comp_buffer *buffer; struct comp_dev *source; struct comp_dev *sink; @@ -652,11 +653,16 @@ __cold int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) } /* these might call comp_ipc4_bind_remote() if necessary */ - ret = comp_bind(source, bu); + bind_data.ipc4_data = bu; + bind_data.bind_type = COMP_BIND_TYPE_SINK; + bind_data.sink = audio_buffer_get_sink(&buffer->audio_buffer); + ret = comp_bind(source, &bind_data); if (ret < 0) goto e_src_bind; - ret = comp_bind(sink, bu); + bind_data.bind_type = COMP_BIND_TYPE_SOURCE; + bind_data.source = audio_buffer_get_source(&buffer->audio_buffer); + ret = comp_bind(sink, &bind_data); if (ret < 0) goto e_sink_bind; @@ -677,7 +683,10 @@ __cold int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) return IPC4_SUCCESS; e_sink_bind: - comp_unbind(source, bu); + /* sink bind was already called */ + bind_data.bind_type = COMP_BIND_TYPE_SINK; + bind_data.sink = audio_buffer_get_sink(&buffer->audio_buffer); + comp_unbind(source, &bind_data); e_src_bind: pipeline_disconnect(sink, buffer, PPL_CONN_DIR_BUFFER_TO_COMP); e_sink_connect: @@ -704,6 +713,7 @@ __cold int ipc_comp_disconnect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) uint32_t flags = 0; int ret, ret1; bool cross_core_unbind; + struct bind_info unbind_data; assert_can_be_cold(); @@ -717,11 +727,6 @@ __cold int ipc_comp_disconnect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) return IPC4_INVALID_RESOURCE_ID; } - if (src->pipeline == sink->pipeline) { - tr_warn(&ipc_tr, "ignoring unbinding of src %x and dst %x", src_id, sink_id); - return 0; - } - cross_core_unbind = src->ipc_config.core != sink->ipc_config.core; /* Pass IPC to target core if both modules has the same target core, @@ -773,8 +778,14 @@ __cold int ipc_comp_disconnect(struct ipc *ipc, ipc_pipe_comp_connect *_connect) pipeline_disconnect(src, buffer, PPL_CONN_DIR_COMP_TO_BUFFER); pipeline_disconnect(sink, buffer, PPL_CONN_DIR_BUFFER_TO_COMP); /* these might call comp_ipc4_bind_remote() if necessary */ - ret = comp_unbind(src, bu); - ret1 = comp_unbind(sink, bu); + unbind_data.ipc4_data = bu; + unbind_data.bind_type = COMP_BIND_TYPE_SINK; + unbind_data.sink = audio_buffer_get_sink(&buffer->audio_buffer); + ret = comp_unbind(src, &unbind_data); + + unbind_data.bind_type = COMP_BIND_TYPE_SOURCE; + unbind_data.source = audio_buffer_get_source(&buffer->audio_buffer); + ret1 = comp_unbind(sink, &unbind_data); ll_unblock(cross_core_unbind, flags); diff --git a/zephyr/include/sof/lib/regions_mm.h b/zephyr/include/sof/lib/regions_mm.h index 3cc8766f4d78..fcd738414470 100644 --- a/zephyr/include/sof/lib/regions_mm.h +++ b/zephyr/include/sof/lib/regions_mm.h @@ -44,33 +44,6 @@ */ #define DEFAULT_CONFIG_ALOCATORS_COUNT 5 -/** @struct vmh_heap - * - * @brief This structure holds all information about virtual memory heap - * it aggregates information about its allocations and - * physical mappings. - * - * @var node generic list member used for list operations - * @var virtual_region pointer to virtual region information, it holds its - * attributes size and beginning ptr provided by zephyr. - * @var physical_blocks_allocators[] a table of block allocators - * each representing a virtual regions part in blocks of a given size - * governed by sys_mem_blocks API. - * @var allocation_sizes[] a table of bit arrays representing sizes of allocations - * made in physical_blocks_allocators directly related to physical_blocks_allocators - * @var core_id id of the core that heap was created on - * @var allocating_continuously configuration value deciding if heap allocations - * will be contiguous or single block. - */ -struct vmh_heap { - struct list_item node; - const struct sys_mm_drv_region *virtual_region; - struct sys_mem_blocks *physical_blocks_allocators[MAX_MEMORY_ALLOCATORS_COUNT]; - struct sys_bitarray *allocation_sizes[MAX_MEMORY_ALLOCATORS_COUNT]; - int core_id; - bool allocating_continuously; -}; - /** @struct vmh_block_bundle_descriptor * * @brief This is a struct describing one bundle of blocks @@ -104,16 +77,12 @@ struct vmh_heap_config { struct vmh_block_bundle_descriptor block_bundles_table[MAX_MEMORY_ALLOCATORS_COUNT]; }; -struct vmh_heap *vmh_init_heap(const struct vmh_heap_config *cfg, - int memory_region_attribute, int core_id, bool allocating_continuously); +struct vmh_heap *vmh_init_heap(const struct vmh_heap_config *cfg, bool allocating_continuously); void *vmh_alloc(struct vmh_heap *heap, uint32_t alloc_size); int vmh_free_heap(struct vmh_heap *heap); int vmh_free(struct vmh_heap *heap, void *ptr); -struct vmh_heap *vmh_reconfigure_heap(struct vmh_heap *heap, - struct vmh_heap_config *cfg, int core_id, bool allocating_continuously); void vmh_get_default_heap_config(const struct sys_mm_drv_region *region, struct vmh_heap_config *cfg); -struct vmh_heap *vmh_get_heap_by_attribute(uint32_t attr, uint32_t core_id); /** * @brief Checks if ptr is in range of given memory range * diff --git a/zephyr/lib/alloc.c b/zephyr/lib/alloc.c index 3cfc6eb97296..899730e312e0 100644 --- a/zephyr/lib/alloc.c +++ b/zephyr/lib/alloc.c @@ -21,8 +21,8 @@ #if CONFIG_VIRTUAL_HEAP #include -struct vmh_heap *virtual_buffers_heap[CONFIG_MP_MAX_NUM_CPUS]; -struct k_spinlock vmh_lock; +struct vmh_heap; +struct vmh_heap *virtual_buffers_heap; #undef HEAPMEM_SIZE /* Buffers are allocated from virtual space so we can safely reduce the heap size. @@ -251,12 +251,11 @@ static bool is_virtual_heap_pointer(void *ptr) static void virtual_heap_free(void *ptr) { - struct vmh_heap *const heap = virtual_buffers_heap[cpu_get_id()]; int ret; ptr = (__sparse_force void *)sys_cache_cached_ptr_get(ptr); - ret = vmh_free(heap, ptr); + ret = vmh_free(virtual_buffers_heap, ptr); if (ret) { tr_err(&zephyr_tr, "Unable to free %p! %d", ptr, ret); k_panic(); @@ -279,17 +278,10 @@ static const struct vmh_heap_config static_hp_buffers = { static int virtual_heap_init(void) { - int core; - - k_spinlock_init(&vmh_lock); - - for (core = 0; core < CONFIG_MP_MAX_NUM_CPUS; core++) { - struct vmh_heap *heap = vmh_init_heap(&static_hp_buffers, MEM_REG_ATTR_CORE_HEAP, - core, false); - if (!heap) - tr_err(&zephyr_tr, "Unable to init virtual heap for core %d!", core); - - virtual_buffers_heap[core] = heap; + virtual_buffers_heap = vmh_init_heap(&static_hp_buffers, false); + if (!virtual_buffers_heap) { + tr_err(&zephyr_tr, "Unable to init virtual heap"); + return -ENOMEM; } return 0; @@ -490,9 +482,6 @@ EXPORT_SYMBOL(rzalloc); void *rballoc_align(uint32_t flags, uint32_t caps, size_t bytes, uint32_t align) { -#if CONFIG_VIRTUAL_HEAP - struct vmh_heap *virtual_heap; -#endif struct k_heap *heap; /* choose a heap */ @@ -510,9 +499,8 @@ void *rballoc_align(uint32_t flags, uint32_t caps, size_t bytes, #if CONFIG_VIRTUAL_HEAP /* Use virtual heap if it is available */ - virtual_heap = virtual_buffers_heap[cpu_get_id()]; - if (virtual_heap) - return virtual_heap_alloc(virtual_heap, flags, caps, bytes, align); + if (virtual_buffers_heap) + return virtual_heap_alloc(virtual_buffers_heap, flags, caps, bytes, align); #endif /* CONFIG_VIRTUAL_HEAP */ if (flags & SOF_MEM_FLAG_COHERENT) diff --git a/zephyr/lib/regions_mm.c b/zephyr/lib/regions_mm.c index b921b9c24a96..797e49d45af8 100644 --- a/zephyr/lib/regions_mm.c +++ b/zephyr/lib/regions_mm.c @@ -10,8 +10,30 @@ #if defined(CONFIG_MM_DRV) #include -/* list of vmh_heap objects created */ -static struct list_item vmh_list = LIST_INIT(vmh_list); + +/** @struct vmh_heap + * + * @brief This structure holds all information about virtual memory heap + * it aggregates information about its allocations and + * physical mappings. + * + * @var virtual_region pointer to virtual region information, it holds its + * attributes size and beginning ptr provided by zephyr. + * @var physical_blocks_allocators[] a table of block allocators + * each representing a virtual regions part in blocks of a given size + * governed by sys_mem_blocks API. + * @var allocation_sizes[] a table of bit arrays representing sizes of allocations + * made in physical_blocks_allocators directly related to physical_blocks_allocators + * @var allocating_continuously configuration value deciding if heap allocations + * will be contiguous or single block. + */ +struct vmh_heap { + struct k_mutex lock; + const struct sys_mm_drv_region *virtual_region; + struct sys_mem_blocks *physical_blocks_allocators[MAX_MEMORY_ALLOCATORS_COUNT]; + struct sys_bitarray *allocation_sizes[MAX_MEMORY_ALLOCATORS_COUNT]; + bool allocating_continuously; +}; /** * @brief Initialize new heap @@ -20,52 +42,33 @@ static struct list_item vmh_list = LIST_INIT(vmh_list); * and config. The heap size overall must be aligned to physical page * size. * @param cfg Configuration structure with block structure for the heap - * @param memory_region_attribute A zephyr defined virtual region identifier - * @param core_id Core id of a heap that will be created * @param allocating_continuously Flag deciding if heap can do contiguous allocation. * * @retval ptr to a new heap if successful. * @retval NULL on creation failure. */ -struct vmh_heap *vmh_init_heap(const struct vmh_heap_config *cfg, - int memory_region_attribute, int core_id, bool allocating_continuously) +struct vmh_heap *vmh_init_heap(const struct vmh_heap_config *cfg, bool allocating_continuously) { const struct sys_mm_drv_region *virtual_memory_regions = sys_mm_drv_query_memory_regions(); int i; - /* Check if we haven't created heap for this region already */ - if (vmh_get_heap_by_attribute(memory_region_attribute, core_id)) - return NULL; - struct vmh_heap *new_heap = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*new_heap)); if (!new_heap) return NULL; - new_heap->core_id = core_id; - list_init(&new_heap->node); + k_mutex_init(&new_heap->lock); struct vmh_heap_config new_config = {0}; + const struct sys_mm_drv_region *region; - /* Search for matching attribute so we place heap on right - * virtual region. - * In case of core heaps regions we count theme from 0 to max - * available cores - */ - if (memory_region_attribute == MEM_REG_ATTR_CORE_HEAP) { - new_heap->virtual_region = &virtual_memory_regions[core_id]; - } else { - for (i = CONFIG_MP_MAX_NUM_CPUS; - i < CONFIG_MP_MAX_NUM_CPUS + VIRTUAL_REGION_COUNT; i++) { - - if (memory_region_attribute == virtual_memory_regions[i].attr) { - new_heap->virtual_region = &virtual_memory_regions[i]; - break; - } + SYS_MM_DRV_MEMORY_REGION_FOREACH(virtual_memory_regions, region) { + if (region->attr == MEM_REG_ATTR_SHARED_HEAP) { + new_heap->virtual_region = region; + break; } } - if (!new_heap->virtual_region) goto fail; @@ -193,9 +196,6 @@ struct vmh_heap *vmh_init_heap(const struct vmh_heap_config *cfg, new_heap->allocating_continuously = allocating_continuously; - /* Save the new heap pointer to a linked list */ - list_item_append(&vmh_list, &new_heap->node); - return new_heap; fail: for (i = 0; i < MAX_MEMORY_ALLOCATORS_COUNT; i++) { @@ -377,7 +377,7 @@ static int vmh_unmap_region(struct sys_mem_blocks *region, void *ptr, size_t siz } /** - * @brief Alloc function + * @brief Alloc function, not reentrant * * Allocates memory on heap from provided heap pointer. * Check if we need to map physical memory for given allocation @@ -388,13 +388,10 @@ static int vmh_unmap_region(struct sys_mem_blocks *region, void *ptr, size_t siz * @retval ptr to allocated memory if successful * @retval NULL on allocation failure */ -void *vmh_alloc(struct vmh_heap *heap, uint32_t alloc_size) +static void *_vmh_alloc(struct vmh_heap *heap, uint32_t alloc_size) { if (!alloc_size) return NULL; - /* Only operations on the same core are allowed */ - if (heap->core_id != cpu_get_id()) - return NULL; void *ptr = NULL; int mem_block_iterator, allocation_error_code = -ENOMEM; @@ -509,6 +506,20 @@ void *vmh_alloc(struct vmh_heap *heap, uint32_t alloc_size) return ptr; } +/** + * @brief Alloc function, reentrant + * see _vmh_alloc comment for details + */ +void *vmh_alloc(struct vmh_heap *heap, uint32_t alloc_size) +{ + k_mutex_lock(&heap->lock, K_FOREVER); + + void *ret = _vmh_alloc(heap, alloc_size); + + k_mutex_unlock(&heap->lock); + return ret; +} + /** * @brief Free virtual memory heap * @@ -539,13 +550,12 @@ int vmh_free_heap(struct vmh_heap *heap) rfree(heap->allocation_sizes[i]); } } - list_item_del(&heap->node); rfree(heap); return 0; } /** - * @brief Free ptr allocated on given heap + * @brief Free ptr allocated on given heap, not reentrant * * Free the ptr allocation. After free action is complete * check if any physical memory block can be freed up as @@ -556,13 +566,10 @@ int vmh_free_heap(struct vmh_heap *heap) * @retval 0 on success; * @retval -ENOTEMPTY on heap having active allocations. */ -int vmh_free(struct vmh_heap *heap, void *ptr) +static int _vmh_free(struct vmh_heap *heap, void *ptr) { int retval; - if (heap->core_id != cpu_get_id()) - return -EINVAL; - size_t mem_block_iter, i, size_to_free, block_size, ptr_bit_array_offset, ptr_bit_array_position, blocks_to_free; bool ptr_range_found; @@ -677,29 +684,17 @@ int vmh_free(struct vmh_heap *heap, void *ptr) } /** - * @brief Reconfigure heap with given config - * - * This will destroy the heap from the pointer and recreate it - * using provided config. Individual region attribute is the - * "anchor" to the virtual space we use. - * - * @param heap Ptr to the heap that should be reconfigured - * @param cfg heap blocks configuration - * @param allocating_continuously allow contiguous on the reconfigured heap - * - * @retval heap_pointer Returns new heap pointer on success - * @retval NULL when reconfiguration failed + * @brief Free ptr function, reentrant + * see _vmh_free comment for details */ -struct vmh_heap *vmh_reconfigure_heap( - struct vmh_heap *heap, struct vmh_heap_config *cfg, - int core_id, bool allocating_continuously) +int vmh_free(struct vmh_heap *heap, void *ptr) { - uint32_t region_attribute = heap->virtual_region->attr; + k_mutex_lock(&heap->lock, K_FOREVER); - if (vmh_free_heap(heap)) - return NULL; + int ret = _vmh_free(heap, ptr); - return vmh_init_heap(cfg, region_attribute, core_id, allocating_continuously); + k_mutex_unlock(&heap->lock); + return ret; } /** @@ -730,47 +725,4 @@ void vmh_get_default_heap_config(const struct sys_mm_drv_region *region, } } -/** - * @brief Gets pointer to already created heap identified by - * provided attribute. - * - * @param attr Virtual memory region attribute. - * @param core_id id of the core that heap was created for (core heap specific). - * - * @retval heap ptr on success - * @retval NULL if there was no heap created fitting the attr. - */ -struct vmh_heap *vmh_get_heap_by_attribute(uint32_t attr, uint32_t core_id) -{ - struct list_item *vm_heaps_iterator; - struct vmh_heap *retval; - - if (attr == MEM_REG_ATTR_CORE_HEAP) { - /* if we look up cpu heap we need to match its cpuid with addr - * we know that regions keep cpu heaps from 0 to max so we match - * the region of the cpu id with lists one to find match - */ - const struct sys_mm_drv_region *virtual_memory_region = - sys_mm_drv_query_memory_regions(); - /* we move ptr to cpu vmr */ - virtual_memory_region = &virtual_memory_region[core_id]; - - list_for_item(vm_heaps_iterator, &vmh_list) { - retval = - CONTAINER_OF(vm_heaps_iterator, struct vmh_heap, node); - - if (retval->virtual_region->addr == virtual_memory_region->addr) - return retval; - } - } else { - list_for_item(vm_heaps_iterator, &vmh_list) { - retval = - CONTAINER_OF(vm_heaps_iterator, struct vmh_heap, node); - if (retval->virtual_region->attr == attr) - return retval; - } - } - return NULL; -} - #endif /* if defined (CONFIG_MM_DRV) */ diff --git a/zephyr/test/vmh.c b/zephyr/test/vmh.c index c7d3d1882cc6..26e044a2d9f0 100644 --- a/zephyr/test/vmh.c +++ b/zephyr/test/vmh.c @@ -17,16 +17,14 @@ #include LOG_MODULE_DECLARE(sof_boot_test, CONFIG_SOF_LOG_LEVEL); +struct vmh_heap; /* Test creating and freeing a virtual memory heap */ -static void test_vmh_init_and_free_heap(int memory_region_attribute, - struct vmh_heap_config *config, - int core_id, +static void test_vmh_init_and_free_heap(struct vmh_heap_config *config, bool allocating_continuously, bool expect_success) { - struct vmh_heap *heap = vmh_init_heap(config, memory_region_attribute, - core_id, allocating_continuously); + struct vmh_heap *heap = vmh_init_heap(config, allocating_continuously); if (expect_success) { zassert_not_null(heap, "Heap initialization expected to succeed but failed"); @@ -146,7 +144,7 @@ static void test_vmh_multiple_allocs(struct vmh_heap *heap, int num_allocs, static void test_vmh_alloc_multiple_times(bool allocating_continuously) { struct vmh_heap *heap = - vmh_init_heap(NULL, MEM_REG_ATTR_CORE_HEAP, 0, allocating_continuously); + vmh_init_heap(NULL, allocating_continuously); zassert_not_null(heap, "Heap initialization failed"); @@ -170,7 +168,7 @@ static void test_vmh_alloc_multiple_times(bool allocating_continuously) static void test_vmh_alloc_free(bool allocating_continuously) { struct vmh_heap *heap = - vmh_init_heap(NULL, MEM_REG_ATTR_CORE_HEAP, 0, allocating_continuously); + vmh_init_heap(NULL, allocating_continuously); zassert_not_null(heap, "Heap initialization failed"); @@ -194,7 +192,7 @@ static void test_vmh_alloc_free(bool allocating_continuously) /* Test case for vmh_alloc and vmh_free with and without config */ static void test_heap_creation(void) { - test_vmh_init_and_free_heap(MEM_REG_ATTR_CORE_HEAP, NULL, 0, false, true); + test_vmh_init_and_free_heap(NULL, 0, false, true); /* Try to setup with pre defined heap config */ struct vmh_heap_config config = {0}; @@ -207,7 +205,7 @@ static void test_heap_creation(void) config.block_bundles_table[1].number_of_blocks = 512; - test_vmh_init_and_free_heap(MEM_REG_ATTR_CORE_HEAP, &config, 0, false, true); + test_vmh_init_and_free_heap(&config, 0, false, true); } /* Test case for alloc/free on configured heap */ @@ -223,7 +221,7 @@ static void test_alloc_on_configured_heap(bool allocating_continuously) /* Create continuous allocation heap for success test */ struct vmh_heap *heap = - vmh_init_heap(&config, MEM_REG_ATTR_CORE_HEAP, 0, allocating_continuously); + vmh_init_heap(&config, allocating_continuously); /* Will succeed on continuous and fail with single block alloc */ test_vmh_alloc_free_check(heap, 512, allocating_continuously); @@ -233,42 +231,9 @@ static void test_alloc_on_configured_heap(bool allocating_continuously) zassert_equal(ret, 0, "Failed to free heap"); } -/* Test cases for initializing heaps on all available regions */ -static void test_vmh_init_all_heaps(void) -{ - int num_regions = CONFIG_MP_MAX_NUM_CPUS + VIRTUAL_REGION_COUNT; - int i; - const struct sys_mm_drv_region *virtual_memory_region = - sys_mm_drv_query_memory_regions(); - - /* Test initializing all types of heaps */ - for (i = 0; i < num_regions; i++) { - - /* Zeroed size symbolizes end of regions table */ - if (!virtual_memory_region[i].size) - break; - - struct vmh_heap *heap = vmh_init_heap(NULL, virtual_memory_region[i].attr, - i, true); - - zassert_not_null(heap, "Heap initialization expected to succeed but failed"); - - /* Test if it fails when heap already exists */ - test_vmh_init_and_free_heap(virtual_memory_region[i].attr, NULL, i, true, - false); - - if (heap) { - int ret = vmh_free_heap(heap); - - zassert_equal(ret, 0, "Failed to free heap"); - } - } -} - ZTEST(sof_boot, virtual_memory_heap) { test_heap_creation(); - test_vmh_init_all_heaps(); test_alloc_on_configured_heap(true); test_alloc_on_configured_heap(false); test_vmh_alloc_free(true);