Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions posix/include/rtos/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,21 @@
*/

/** \brief Indicates we should return DMA-able memory. */
#define SOF_MEM_FLAG_DMA BIT(0)
#define SOF_MEM_FLAG_DMA BIT(0)
/** \brief Indicates that original content should not be copied by realloc. */
#define SOF_MEM_FLAG_NO_COPY BIT(1)
#define SOF_MEM_FLAG_NO_COPY BIT(1)
/** \brief Indicates that if we should return uncached address. */
#define SOF_MEM_FLAG_COHERENT BIT(2)
#define SOF_MEM_FLAG_COHERENT BIT(2)
/** \brief Indicates that if we should return L3 address. */
#define SOF_MEM_FLAG_L3 BIT(3)
#define SOF_MEM_FLAG_L3 BIT(3)
/** \brief Indicates that if we should return Low power memory address. */
#define SOF_MEM_FLAG_LOW_POWER BIT(4)
#define SOF_MEM_FLAG_LOW_POWER BIT(4)
/** \brief Indicates that if we should return kernel memory address. */
#define SOF_MEM_FLAG_KERNEL BIT(5)
#define SOF_MEM_FLAG_KERNEL BIT(5)
/** \brief Indicates that if we should return user memory address. */
#define SOF_MEM_FLAG_USER BIT(6)
#define SOF_MEM_FLAG_USER BIT(6)
/** \brief Indicates that if we should return shared user memory address. */
#define SOF_MEM_FLAG_USER_SHARED_BUFFER BIT(7)

/** @} */

Expand Down
108 changes: 108 additions & 0 deletions posix/include/rtos/userspace_helper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright(c) 2025 Intel Corporation. All rights reserved.
*
* Author: Jaroslaw Stelter <jaroslaw.stelter@intel.com>
* Adrian Warecki <adrian.warecki@intel.com>
*/

/**
* \brief Userspace support functions.
*/
#ifndef __RTOS_USERSPACE_HELPER_H__
#define __RTOS_USERSPACE_HELPER_H__

#include <stdint.h>
#include <stddef.h>

#include <rtos/alloc.h>

struct sys_heap;

#ifdef CONFIG_USERSPACE
/**
* Initialize private processing module heap.
* @param N/A.
* @return pointer to the sys_heap structure.
*
* @note
* Function used only when CONFIG_USERSPACE is set.
* The private heap is used only for non-privileged modules for all processing module allocations
* that should be isolated. The heap helps to accumulate all dynamic allocations in single memory
* region which is then added to modules memory domain.
*/
static inline struct sys_heap *module_driver_heap_init(void)
{
return NULL;
}

#endif

/**
* Allocates memory block from private module sys_heap if exists, otherwise call rballoc_align().
* @param sys_heap - pointer to the sys_heap structure
* @param flags - Flags, see SOF_MEM_FLAG_...
* @param bytes - Size in bytes.
* @param alignment - Alignment in bytes.
* @return Pointer to the allocated memory or NULL if failed.
*
* @note When CONFIG_USERSPACE not set function calls rballoc_align()
*/
static inline void *module_driver_heap_aligned_alloc(struct sys_heap *mod_drv_heap, uint32_t flags,
size_t bytes, uint32_t align)
{
return rballoc_align(flags, bytes, align);
}

/**
* Allocates memory block from private module sys_heap if exists, otherwise call rmalloc.
* @param sys_heap - pointer to the sys_heap structure
* @param flags - Flags, see SOF_MEM_FLAG_...
* @param bytes - Size in bytes.
* @return - Pointer to the allocated memory or NULL if failed.
*
* * @note When CONFIG_USERSPACE not set function calls rmalloc()
*/
static inline void *module_driver_heap_rmalloc(struct sys_heap *mod_drv_heap, uint32_t flags,
size_t bytes)
{
return rmalloc(flags, bytes);
}

/**
* Similar to user_rmalloc(), guarantees that returned block is zeroed.
*
* @note When CONFIG_USERSPACE not set function calls rzalloc()
*/
static inline void *module_driver_heap_rzalloc(struct sys_heap *mod_drv_heap, uint32_t flags,
size_t bytes)
{
return rzalloc(flags, bytes);
}

/**
* Frees the memory block from private module sys_heap if exists. Otherwise call rfree.
* @param ptr Pointer to the memory block.
*
* @note User should take care to not free memory allocated from sys_heap
* with module_driver_heap set to NULL. It will cause exception.
*
* When CONFIG_USERSPACE not set function calls rfree()
*/
static inline void module_driver_heap_free(struct sys_heap *mod_drv_heap, void *mem)
{
rfree(mem);
}

/**
* Free private processing module heap.
* @param sys_heap pointer to the sys_heap structure.
*
* @note
* Function used only when CONFIG_USERSPACE is set.
* Frees private module heap.
*/
static inline void module_driver_heap_remove(struct sys_heap *mod_drv_heap)
{ }

#endif /* __RTOS_USERSPACE_HELPER_H__ */
15 changes: 8 additions & 7 deletions src/audio/buffers/ring_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <sof/lib/uuid.h>

#include <sof/audio/ring_buffer.h>
#include <sof/audio/component.h>

#include <rtos/alloc.h>
#include <ipc/topology.h>
Expand Down Expand Up @@ -279,17 +280,16 @@ static const struct audio_buffer_ops audio_buffer_ops = {
.reset = ring_buffer_reset
};

struct ring_buffer *ring_buffer_create(size_t min_available, size_t min_free_space, bool is_shared,
struct ring_buffer *ring_buffer_create(struct comp_dev *dev, size_t min_available,
size_t min_free_space, bool is_shared,
uint32_t id)
{
struct ring_buffer *ring_buffer;
int memory_flags = (is_shared ? SOF_MEM_FLAG_COHERENT : 0) |
user_get_buffer_memory_region(dev->drv);

/* allocate ring_buffer structure */
if (is_shared)
ring_buffer = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT,
sizeof(*ring_buffer));
else
ring_buffer = rzalloc(SOF_MEM_FLAG_USER, sizeof(*ring_buffer));
ring_buffer = rzalloc(memory_flags, sizeof(*ring_buffer));
if (!ring_buffer)
return NULL;

Expand Down Expand Up @@ -359,7 +359,8 @@ struct ring_buffer *ring_buffer_create(size_t min_available, size_t min_free_spa
ring_buffer->data_buffer_size =
ALIGN_UP(ring_buffer->data_buffer_size, PLATFORM_DCACHE_ALIGN);
ring_buffer->_data_buffer = (__sparse_force __sparse_cache void *)
rballoc_align(SOF_MEM_FLAG_USER, ring_buffer->data_buffer_size, PLATFORM_DCACHE_ALIGN);
rballoc_align(memory_flags, ring_buffer->data_buffer_size,
PLATFORM_DCACHE_ALIGN);
if (!ring_buffer->_data_buffer)
goto err;

Expand Down
16 changes: 8 additions & 8 deletions src/audio/module_adapter/module_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
int flags = config->proc_domain == COMP_PROCESSING_DOMAIN_DP ?
SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER;

mod = rzalloc(flags, sizeof(*mod));
mod = module_driver_heap_rzalloc(drv->user_heap, flags, sizeof(*mod));
if (!mod) {
comp_err(dev, "module_adapter_new(), failed to allocate memory for module");
goto err;
Expand Down Expand Up @@ -210,6 +210,7 @@ int module_adapter_prepare(struct comp_dev *dev)
struct list_item *blist, *_blist;
uint32_t buff_periods;
uint32_t buff_size; /* size of local buffer */
int memory_flags;
int i = 0;

comp_dbg(dev, "module_adapter_prepare() start");
Expand Down Expand Up @@ -342,11 +343,11 @@ int module_adapter_prepare(struct comp_dev *dev)

module_adapter_check_data(mod, dev, sink);

memory_flags = user_get_buffer_memory_region(dev->drv);
/* allocate memory for input buffers */
if (mod->max_sources) {
mod->input_buffers =
rzalloc(SOF_MEM_FLAG_USER,
sizeof(*mod->input_buffers) * mod->max_sources);
rzalloc(memory_flags, sizeof(*mod->input_buffers) * mod->max_sources);
if (!mod->input_buffers) {
comp_err(dev, "failed to allocate input buffers");
return -ENOMEM;
Expand All @@ -358,8 +359,7 @@ int module_adapter_prepare(struct comp_dev *dev)
/* allocate memory for output buffers */
if (mod->max_sinks) {
mod->output_buffers =
rzalloc(SOF_MEM_FLAG_USER,
sizeof(*mod->output_buffers) * mod->max_sinks);
rzalloc(memory_flags, sizeof(*mod->output_buffers) * mod->max_sinks);
if (!mod->output_buffers) {
comp_err(dev, "failed to allocate output buffers");
ret = -ENOMEM;
Expand Down Expand Up @@ -425,7 +425,7 @@ int module_adapter_prepare(struct comp_dev *dev)
list_for_item(blist, &dev->bsource_list) {
size_t size = MAX(mod->deep_buff_bytes, mod->period_bytes);

mod->input_buffers[i].data = rballoc(SOF_MEM_FLAG_USER, size);
mod->input_buffers[i].data = rballoc(memory_flags, size);
if (!mod->input_buffers[i].data) {
comp_err(mod->dev, "Failed to alloc input buffer data");
ret = -ENOMEM;
Expand All @@ -437,7 +437,7 @@ int module_adapter_prepare(struct comp_dev *dev)
/* allocate memory for output buffer data */
i = 0;
list_for_item(blist, &dev->bsink_list) {
mod->output_buffers[i].data = rballoc(SOF_MEM_FLAG_USER, md->mpd.out_buff_size);
mod->output_buffers[i].data = rballoc(memory_flags, md->mpd.out_buff_size);
if (!mod->output_buffers[i].data) {
comp_err(mod->dev, "Failed to alloc output buffer data");
ret = -ENOMEM;
Expand All @@ -450,7 +450,7 @@ int module_adapter_prepare(struct comp_dev *dev)
if (list_is_empty(&mod->raw_data_buffers_list)) {
for (i = 0; i < mod->num_of_sinks; i++) {
/* allocate not shared buffer */
struct comp_buffer *buffer = buffer_alloc(buff_size, SOF_MEM_FLAG_USER,
struct comp_buffer *buffer = buffer_alloc(buff_size, memory_flags,
PLATFORM_DCACHE_ALIGN, false);
uint32_t flags;

Expand Down
4 changes: 3 additions & 1 deletion src/audio/module_adapter/module_adapter_ipc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ int module_adapter_init_data(struct comp_dev *dev,
if (cfgsz == (sizeof(*cfg) + pinsz)) {
dst->nb_input_pins = n_in;
dst->nb_output_pins = n_out;
dst->input_pins = rmalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, pinsz);
dst->input_pins = module_driver_heap_rmalloc(dev->drv->user_heap,
SOF_MEM_FLAG_USER |
SOF_MEM_FLAG_COHERENT, pinsz);
if (!dst->input_pins)
return -ENOMEM;

Expand Down
16 changes: 13 additions & 3 deletions src/include/sof/audio/component.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <sof/audio/pipeline.h>
#include <sof/debug/telemetry/telemetry.h>
#include <rtos/idc.h>
#include <rtos/userspace_helper.h>
#include <sof/lib/dai.h>
#include <sof/schedule/schedule.h>
#include <ipc/control.h>
Expand Down Expand Up @@ -590,6 +591,7 @@ struct comp_driver {
* Intended to replace the ops field.
* Currently used by module_adapter.
*/
struct sys_heap *user_heap; /**< Userspace heap */
};

/** \brief Holds constant pointer to component driver */
Expand Down Expand Up @@ -853,16 +855,16 @@ static inline enum sof_comp_type dev_comp_type(const struct comp_dev *dev)
* @param bytes Size of the component device in bytes.
* @return Pointer to the component device.
*/
static inline struct comp_dev *comp_alloc(const struct comp_driver *drv,
size_t bytes)
static inline struct comp_dev *comp_alloc(const struct comp_driver *drv, size_t bytes)
{
struct comp_dev *dev = NULL;

/*
* Use uncached address everywhere to access components to rule out
* multi-core failures. TODO: verify if cached alias may be used in some cases
*/
dev = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, bytes);
dev = module_driver_heap_rzalloc(drv->user_heap, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT,
bytes);
if (!dev)
return NULL;
dev->size = bytes;
Expand Down Expand Up @@ -1192,4 +1194,12 @@ void comp_init_performance_data(struct comp_dev *dev);
*/
bool comp_update_performance_data(struct comp_dev *dev, uint32_t cycles_used);

static inline int user_get_buffer_memory_region(const struct comp_driver *drv)
{
#if CONFIG_USERSPACE
return drv->user_heap ? SOF_MEM_FLAG_USER_SHARED_BUFFER : SOF_MEM_FLAG_USER;
#else
return SOF_MEM_FLAG_USER;
#endif
}
#endif /* __SOF_AUDIO_COMPONENT_H__ */
32 changes: 22 additions & 10 deletions src/include/sof/audio/module_adapter/module/generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,33 @@ int module_prepare(struct processing_module *mod,
struct sof_source **sources, int num_of_sources,
struct sof_sink **sinks, int num_of_sinks);

static inline
bool generic_module_is_ready_to_process(struct processing_module *mod,
struct sof_source **sources,
int num_of_sources,
struct sof_sink **sinks,
int num_of_sinks)
{
int i;

for (i = 0; i < num_of_sources; i++)
if (source_get_data_available(sources[i]) < source_get_min_available(sources[i]))
return false;

for (i = 0; i < num_of_sinks; i++)
if (sink_get_free_size(sinks[i]) < sink_get_min_free_space(sinks[i]))
return false;

return true;
}

static inline
bool module_is_ready_to_process(struct processing_module *mod,
struct sof_source **sources,
int num_of_sources,
struct sof_sink **sinks,
int num_of_sinks)
{
int i;
const struct module_interface *const ops = mod->dev->drv->adapter_ops;

/* LL module has to be always ready for processing */
Expand All @@ -182,15 +201,8 @@ bool module_is_ready_to_process(struct processing_module *mod,
/* default action - the module is ready if there's enough data for processing and enough
* space to store result. IBS/OBS as declared in init_instance
*/
for (i = 0; i < num_of_sources; i++)
if (source_get_data_available(sources[i]) < source_get_min_available(sources[i]))
return false;

for (i = 0; i < num_of_sinks; i++)
if (sink_get_free_size(sinks[i]) < sink_get_min_free_space(sinks[i]))
return false;

return true;
return generic_module_is_ready_to_process(mod, sources, num_of_sources, sinks,
num_of_sinks);
}

int module_process_sink_src(struct processing_module *mod,
Expand Down
5 changes: 4 additions & 1 deletion src/include/sof/audio/ring_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
* always means "buffer full"
*/

struct comp_dev;
struct ring_buffer;
struct sof_audio_stream_params;

Expand All @@ -114,6 +115,7 @@ struct ring_buffer {

/**
*
* @param dev pointer to the DP module device structure
* @param min_available minimum data available in queue required by the module using
* ring_buffer's source api
* @param min_free_space minimum buffer space in queue required by the module using
Expand All @@ -122,7 +124,8 @@ struct ring_buffer {
* @param id a stream ID, accessible later by sink_get_id/source_get_id
*
*/
struct ring_buffer *ring_buffer_create(size_t min_available, size_t min_free_space, bool is_shared,
struct ring_buffer *ring_buffer_create(struct comp_dev *dev, size_t min_available,
size_t min_free_space, bool is_shared,
uint32_t id);

#endif /* __SOF_RING_BUFFER_H__ */
Loading
Loading