Skip to content
Open
6 changes: 6 additions & 0 deletions app/overlays/ptl/ll_userspace_overlay.conf
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,9 @@ CONFIG_CROSS_CORE_STREAM=n
CONFIG_INTEL_ADSP_MIC_PRIVACY=n
CONFIG_XRUN_NOTIFICATIONS_ENABLE=n
CONFIG_ZEPHYR_DP_SCHEDULER=n

# Extend the shared LL user-space heap to 0.5MB. This
# is current maximum for PTL builds with virtual heap
# enabled and uses the vmh allocation intended for KBP.
# TODO: needs some better solution to allocate
CONFIG_SOF_ZEPHYR_SYS_USER_HEAP_SIZE=0x80000
2 changes: 1 addition & 1 deletion src/audio/google/google_hotword_detect.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ static struct comp_dev *ghd_create(const struct comp_driver *drv,
cd->event.event_type = SOF_CTRL_EVENT_KD;
cd->event.num_elems = 0;

cd->msg = ipc_msg_init(cd->event.rhdr.hdr.cmd, cd->event.rhdr.hdr.size);
cd->msg = ipc_msg_init(NULL, cd->event.rhdr.hdr.cmd, cd->event.rhdr.hdr.size);
if (!cd->msg) {
comp_err(dev, "ipc_msg_init failed");
goto cd_fail;
Expand Down
2 changes: 1 addition & 1 deletion src/audio/host-legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ int host_common_new(struct host_data *hd, struct comp_dev *dev,
ipc_build_stream_posn(&hd->posn, SOF_IPC_STREAM_POSITION, config_id);

#if CONFIG_HOST_DMA_IPC_POSITION_UPDATES
hd->msg = ipc_msg_init(hd->posn.rhdr.hdr.cmd, hd->posn.rhdr.hdr.size);
hd->msg = ipc_msg_init(NULL, hd->posn.rhdr.hdr.cmd, hd->posn.rhdr.hdr.size);
if (!hd->msg) {
comp_err(dev, "ipc_msg_init failed");
dma_put(hd->dma);
Expand Down
2 changes: 1 addition & 1 deletion src/audio/host-zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ __cold int host_common_new(struct host_data *hd, struct comp_dev *dev,
ipc_build_stream_posn(&hd->posn, SOF_IPC_STREAM_POSITION, config_id);

#if CONFIG_HOST_DMA_IPC_POSITION_UPDATES
hd->msg = ipc_msg_init(hd->posn.rhdr.hdr.cmd, sizeof(hd->posn));
hd->msg = ipc_msg_init(hd->heap, hd->posn.rhdr.hdr.cmd, sizeof(hd->posn));
if (!hd->msg) {
comp_err(dev, "ipc_msg_init failed");
sof_dma_put(hd->dma);
Expand Down
2 changes: 1 addition & 1 deletion src/audio/mfcc/mfcc.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ static int mfcc_free(struct processing_module *mod)
struct mfcc_comp_data *cd = module_get_private_data(mod);

comp_info(mod->dev, "entry");
ipc_msg_free(cd->msg);
mod_ipc_msg_free(mod, cd->msg);
cd->msg = NULL;
mod_data_blob_handler_free(mod, cd->model_handler);
mfcc_free_buffers(mod);
Expand Down
8 changes: 4 additions & 4 deletions src/audio/mfcc/mfcc_ipc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ int mfcc_ipc_notification_init(struct processing_module *mod)
primary->r.type = SOF_IPC4_GLB_NOTIFICATION;
primary->r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST;
primary->r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG;
cd->msg = ipc_msg_w_ext_init(msg_proto.header, msg_proto.extension,
sizeof(struct sof_ipc4_notify_module_data) +
sizeof(struct sof_ipc4_control_msg_payload) +
sizeof(struct sof_ipc4_ctrl_value_chan));
cd->msg = mod_ipc_msg_w_ext_init(mod, msg_proto.header, msg_proto.extension,
sizeof(struct sof_ipc4_notify_module_data) +
sizeof(struct sof_ipc4_control_msg_payload) +
sizeof(struct sof_ipc4_ctrl_value_chan));
if (!cd->msg) {
comp_err(dev, "Failed to initialize VAD notification");
return -ENOMEM;
Expand Down
6 changes: 3 additions & 3 deletions src/audio/module_adapter/module/cadence_ipc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ static struct ipc_msg *cadence_codec_notification_init(struct processing_module
primary.r.type = SOF_IPC4_GLB_NOTIFICATION;
primary.r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST;
primary.r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG;
msg = ipc_msg_w_ext_init(primary.dat, 0, sizeof(*msg_module_data));
msg = mod_ipc_msg_w_ext_init(mod, primary.dat, 0, sizeof(*msg_module_data));
if (!msg)
return NULL;

Expand Down Expand Up @@ -366,7 +366,7 @@ static int cadence_codec_init(struct processing_module *mod)
if (setup_cfg)
mod_free(mod, setup_cfg->data);
free_notification:
ipc_msg_free(cd->msg);
mod_ipc_msg_free(mod, cd->msg);
free_cd:
mod_free(mod, cd);

Expand Down Expand Up @@ -568,7 +568,7 @@ static int ipc4_cadence_codec_free(struct processing_module *mod)
{
struct cadence_codec_data *cd = module_get_private_data(mod);

ipc_msg_free(cd->msg);
mod_ipc_msg_free(mod, cd->msg);

return cadence_codec_free(mod);
}
Expand Down
92 changes: 81 additions & 11 deletions src/audio/pipeline/pipeline-graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <rtos/interrupt.h>
#include <rtos/symbol.h>
#include <rtos/alloc.h>
#include <rtos/userspace_helper.h>
#include <sof/lib/mm_heap.h>
#include <sof/lib/uuid.h>
#include <sof/compiler_attributes.h>
Expand Down Expand Up @@ -44,20 +45,69 @@ DECLARE_TR_CTX(pipe_tr, SOF_UUID(pipe_uuid), LOG_LEVEL_INFO);
/* lookup table to determine busy/free pipeline metadata objects */
struct pipeline_posn {
bool posn_offset[PPL_POSN_OFFSETS]; /**< available offsets */
#ifndef CONFIG_SOF_USERSPACE_LL
struct k_spinlock lock; /**< lock mechanism */
#endif
};
/* the pipeline position lookup table */
static SHARED_DATA struct pipeline_posn pipeline_posn_shared;
static APP_SYSUSER_BSS SHARED_DATA struct pipeline_posn pipeline_posn_shared;

#ifdef CONFIG_SOF_USERSPACE_LL
/* Mutex pointer in user-accessible partition so user-space threads
* can read the pointer for syscalls. Kept outside the SHARED_DATA
* struct to avoid kernel object tracking issues.
*/
static APP_SYSUSER_BSS struct k_mutex *pipeline_posn_mutex;
#endif

/**
* \brief Retrieves pipeline position structure.
* \return Pointer to pipeline position structure.
*/
static inline struct pipeline_posn *pipeline_posn_get(void)
{
#ifdef CONFIG_SOF_USERSPACE_LL
return &pipeline_posn_shared;
#else
return sof_get()->pipeline_posn;
#endif
}

/*
* Position table locking. User-space LL cannot use a spinlock (disabling
* interrupts is privileged), so it uses a mutex; the config split is kept
* here so the callers below stay identical for both configurations.
*/
#ifdef CONFIG_SOF_USERSPACE_LL
typedef int pipeline_posn_key_t;

static inline pipeline_posn_key_t pipeline_posn_lock(struct pipeline_posn *posn)
{
(void)posn;
k_mutex_lock(pipeline_posn_mutex, K_FOREVER);
return 0;
}

static inline void pipeline_posn_unlock(struct pipeline_posn *posn, pipeline_posn_key_t key)
{
(void)posn;
(void)key;
k_mutex_unlock(pipeline_posn_mutex);
}
#else
typedef k_spinlock_key_t pipeline_posn_key_t;

static inline pipeline_posn_key_t pipeline_posn_lock(struct pipeline_posn *posn)
{
return k_spin_lock(&posn->lock);
}

static inline void pipeline_posn_unlock(struct pipeline_posn *posn, pipeline_posn_key_t key)
{
k_spin_unlock(&posn->lock, key);
}
#endif

/**
* \brief Retrieves first free pipeline position offset.
* \param[in,out] posn_offset Pipeline position offset to be set.
Expand All @@ -68,9 +118,7 @@ static inline int pipeline_posn_offset_get(uint32_t *posn_offset)
struct pipeline_posn *pipeline_posn = pipeline_posn_get();
int ret = -EINVAL;
uint32_t i;
k_spinlock_key_t key;

key = k_spin_lock(&pipeline_posn->lock);
pipeline_posn_key_t key = pipeline_posn_lock(pipeline_posn);

for (i = 0; i < PPL_POSN_OFFSETS; ++i) {
if (!pipeline_posn->posn_offset[i]) {
Expand All @@ -81,8 +129,7 @@ static inline int pipeline_posn_offset_get(uint32_t *posn_offset)
}
}


k_spin_unlock(&pipeline_posn->lock, key);
pipeline_posn_unlock(pipeline_posn, key);

return ret;
}
Expand All @@ -95,20 +142,34 @@ static inline void pipeline_posn_offset_put(uint32_t posn_offset)
{
struct pipeline_posn *pipeline_posn = pipeline_posn_get();
int i = posn_offset / sizeof(struct sof_ipc_stream_posn);
k_spinlock_key_t key;

key = k_spin_lock(&pipeline_posn->lock);
pipeline_posn_key_t key = pipeline_posn_lock(pipeline_posn);

pipeline_posn->posn_offset[i] = false;

k_spin_unlock(&pipeline_posn->lock, key);
pipeline_posn_unlock(pipeline_posn, key);
}

void pipeline_posn_init(struct sof *sof)
{
sof->pipeline_posn = &pipeline_posn_shared;
#ifdef CONFIG_SOF_USERSPACE_LL
pipeline_posn_mutex = k_object_alloc(K_OBJ_MUTEX);
if (!pipeline_posn_mutex) {
pipe_cl_err("pipeline posn mutex alloc failed");
k_panic();
}
k_mutex_init(pipeline_posn_mutex);
#else
k_spinlock_init(&sof->pipeline_posn->lock);
#endif
}

#ifdef CONFIG_SOF_USERSPACE_LL
void pipeline_posn_grant_access(struct k_thread *thread)
{
k_thread_access_grant(thread, pipeline_posn_mutex);
}
#endif

/* create new pipeline - returns pipeline id or negative error */
struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_t priority,
Expand Down Expand Up @@ -140,12 +201,21 @@ struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_
p->pipeline_id = pipeline_id;
p->status = COMP_STATE_INIT;
p->trigger.cmd = COMP_TRIGGER_NO_ACTION;

#ifndef CONFIG_SOF_USERSPACE_LL
/*
* pipe_tr lives in the .trace_ctx section, which is not mapped into
* the sysuser partition, so it cannot be read from a user-mode thread.
* The copy is also unnecessary in that configuration: with Zephyr
* logging the pipe_*() macros use the global pipe_tr, not p->tctx.
*/
ret = memcpy_s(&p->tctx, sizeof(struct tr_ctx), &pipe_tr,
sizeof(struct tr_ctx));
if (ret < 0) {
pipe_err(p, "failed to copy trace settings");
goto free;
}
#endif

ret = pipeline_posn_offset_get(&p->posn_offset);
if (ret < 0) {
Expand All @@ -158,7 +228,7 @@ struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_
ipc_build_stream_posn(&posn, SOF_IPC_STREAM_TRIG_XRUN, p->comp_id);

if (posn.rhdr.hdr.size) {
p->msg = ipc_msg_init(posn.rhdr.hdr.cmd, posn.rhdr.hdr.size);
p->msg = ipc_msg_init(heap, posn.rhdr.hdr.cmd, posn.rhdr.hdr.size);
if (!p->msg) {
pipe_err(p, "ipc_msg_init failed");
goto free;
Expand Down
6 changes: 3 additions & 3 deletions src/audio/sound_dose/sound_dose-ipc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ static struct ipc_msg *sound_dose_notification_init(struct processing_module *mo
primary->r.type = SOF_IPC4_GLB_NOTIFICATION;
primary->r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST;
primary->r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG;
msg = ipc_msg_w_ext_init(msg_proto.header, msg_proto.extension,
sizeof(struct sof_ipc4_notify_module_data) +
sizeof(struct sof_ipc4_control_msg_payload));
msg = mod_ipc_msg_w_ext_init(mod, msg_proto.header, msg_proto.extension,
sizeof(struct sof_ipc4_notify_module_data) +
sizeof(struct sof_ipc4_control_msg_payload));
if (!msg)
return NULL;

Expand Down
2 changes: 1 addition & 1 deletion src/audio/sound_dose/sound_dose.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ __cold static int sound_dose_free(struct processing_module *mod)
comp_dbg(mod->dev, "entry");

sound_dose_filters_free(cd);
ipc_msg_free(cd->msg);
mod_ipc_msg_free(mod, cd->msg);
rfree(cd->abi);
rfree(cd);
return 0;
Expand Down
4 changes: 2 additions & 2 deletions src/audio/tdfb/tdfb.c
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ static int tdfb_init(struct processing_module *mod)
err:
/* These are null if not used for IPC version */
mod_free(mod, cd->ctrl_data);
ipc_msg_free(cd->msg);
mod_ipc_msg_free(mod, cd->msg);
mod_data_blob_handler_free(mod, cd->model_handler);

err_free_cd:
Expand All @@ -691,7 +691,7 @@ static int tdfb_free(struct processing_module *mod)

comp_dbg(mod->dev, "entry");

ipc_msg_free(cd->msg);
mod_ipc_msg_free(mod, cd->msg);
tdfb_free_delaylines(mod);
mod_data_blob_handler_free(mod, cd->model_handler);
tdfb_direction_free(mod);
Expand Down
4 changes: 2 additions & 2 deletions src/audio/tdfb/tdfb_direction.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@
* from output files tdfb_iir_emphasis_48k.h and tdfb_iir_emphasis_16k.h.
*/

uint32_t iir_emphasis_48k[20] = {
static const uint32_t iir_emphasis_48k[20] = {
0x00000002, 0x00000002, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0xc8cf47b5, 0x7689916a,
0x1dc95968, 0xc46d4d30, 0x1dc95968, 0x00000000,
0x00004000, 0xe16f20ea, 0x51e57f66, 0x01966267,
0x032cc4ce, 0x01966267, 0xfffffffe, 0x00004222
};

uint32_t iir_emphasis_16k[20] = {
static const uint32_t iir_emphasis_16k[20] = {
0x00000002, 0x00000002, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0xd6f418ae, 0x63e7b85c,
0x19ae069b, 0xcca3f2ca, 0x19ae069b, 0x00000000,
Expand Down
2 changes: 1 addition & 1 deletion src/audio/tdfb/tdfb_ipc3.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ static int init_get_ctl_ipc(struct processing_module *mod)

cd->ctrl_data->rhdr.hdr.cmd = SOF_IPC_GLB_COMP_MSG | SOF_IPC_COMP_GET_VALUE | comp_id;
cd->ctrl_data->rhdr.hdr.size = TDFB_GET_CTRL_DATA_SIZE;
cd->msg = ipc_msg_init(cd->ctrl_data->rhdr.hdr.cmd, cd->ctrl_data->rhdr.hdr.size);
cd->msg = mod_ipc_msg_init(mod, cd->ctrl_data->rhdr.hdr.cmd, cd->ctrl_data->rhdr.hdr.size);

cd->ctrl_data->comp_id = comp_id;
cd->ctrl_data->type = SOF_CTRL_TYPE_VALUE_CHAN_GET;
Expand Down
4 changes: 2 additions & 2 deletions src/audio/tdfb/tdfb_ipc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ static struct ipc_msg *tdfb_notification_init(struct processing_module *mod,
primary->r.type = SOF_IPC4_GLB_NOTIFICATION;
primary->r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST;
primary->r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG;
msg = ipc_msg_w_ext_init(msg_proto.header, msg_proto.extension,
sizeof(struct sof_ipc4_notify_module_data) +
msg = mod_ipc_msg_w_ext_init(mod, msg_proto.header, msg_proto.extension,
sizeof(struct sof_ipc4_notify_module_data) +
sizeof(struct sof_ipc4_control_msg_payload) +
sizeof(struct sof_ipc4_ctrl_value_chan));
if (!msg)
Expand Down
17 changes: 17 additions & 0 deletions src/include/ipc4/notification.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,4 +297,21 @@ void send_mixer_underrun_notif_msg(uint32_t resource_id, uint32_t eos_flag, uint
uint32_t expected_data_mixed);
void ipc4_update_notification_mask(uint32_t ntfy_mask, uint32_t enabled_mask);

#ifdef CONFIG_SOF_USERSPACE_LL

__syscall bool send_resource_notif(uint32_t resource_id, uint32_t event_type,
uint32_t resource_type, void *data, uint32_t data_size);

bool z_impl_send_resource_notif(uint32_t resource_id, uint32_t event_type,
uint32_t resource_type, void *data, uint32_t data_size);

#include <zephyr/syscalls/notification.h>

#else

bool send_resource_notif(uint32_t resource_id, uint32_t event_type,
uint32_t resource_type, void *data, uint32_t data_size);

#endif /* CONFIG_SOF_USERSPACE_LL */

#endif /* __IPC4_NOTIFICATION_H__ */
Loading
Loading