Skip to content

Commit bde2726

Browse files
kv2019ilgirdwood
authored andcommitted
ipc4: add user-space command-forwarding context
Add the struct ipc_user descriptor (and its ipc_user_pdata slot in struct ipc) that the IPC4 kernel handler uses to forward commands to the user-space IPC thread: the two IPC4 message words, the reply fields, and a user-readable copy of the resolved comp_driver + tr_ctx used by user-space component creation. In ipc4 helper, allow component buffers to be allocated from the LL user heap (ipc->ll_alloc) and create them on the component's configured core rather than the current CPU, so buffer creation works from the user thread when CONFIG_SOF_USERSPACE_LL is enabled. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
1 parent 54d5db0 commit bde2726

2 files changed

Lines changed: 42 additions & 1 deletion

File tree

src/include/sof/ipc/common.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <stdbool.h>
2323
#include <stdint.h>
2424

25+
struct comp_driver;
2526
struct dma_sg_elem_array;
2627
struct ipc_msg;
2728

@@ -53,6 +54,37 @@ extern struct tr_ctx ipc_tr;
5354
#define IPC_TASK_SECONDARY_CORE BIT(2)
5455
#define IPC_TASK_POWERDOWN BIT(3)
5556

57+
struct ipc_user {
58+
struct k_thread *thread;
59+
struct k_sem *sem;
60+
struct k_event *event;
61+
/** @brief Copy of IPC4 message primary word forwarded to user thread */
62+
uint32_t ipc_msg_pri;
63+
/** @brief Copy of IPC4 message extension word forwarded to user thread */
64+
uint32_t ipc_msg_ext;
65+
/** @brief Result code from user thread processing */
66+
int result;
67+
/** @brief Reply extension word from user thread (e.g. CONFIG_GET result) */
68+
uint32_t reply_ext;
69+
/** @brief Reply TX data size from user thread (e.g. LARGE_CONFIG_GET result) */
70+
uint32_t reply_tx_size;
71+
/** @brief Reply TX data pointer from user thread (e.g. LARGE_CONFIG_GET result) */
72+
void *reply_tx_data;
73+
struct ipc *ipc;
74+
struct k_thread *audio_thread;
75+
/** @brief Original kernel driver pointer for restoring dev->drv after create */
76+
const struct comp_driver *init_drv;
77+
/**
78+
* @brief User-accessible copy of comp_driver + tr_ctx for create().
79+
*
80+
* The comp_driver and tr_ctx structs reside in kernel memory
81+
* (.rodata/.data) which is not user-readable. The kernel handler
82+
* copies them here before forwarding to the user thread.
83+
* Size verified by BUILD_ASSERT in handler-user.c.
84+
*/
85+
uint8_t init_drv_data[160] __aligned(4);
86+
};
87+
5688
struct ipc {
5789
struct k_spinlock lock; /* locking mechanism */
5890
void *comp_data;
@@ -75,6 +107,7 @@ struct ipc {
75107
#endif
76108

77109
#ifdef CONFIG_SOF_USERSPACE_LL
110+
struct ipc_user *ipc_user_pdata;
78111
struct mod_alloc_ctx *ll_alloc;
79112
#endif
80113

src/ipc/ipc4/helper.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,10 @@ __cold static struct comp_buffer *ipc4_create_buffer(struct comp_dev *src, bool
572572
ipc_buf.size = buf_size;
573573
ipc_buf.comp.id = IPC4_COMP_ID(src_queue, dst_queue);
574574
ipc_buf.comp.pipeline_id = src->ipc_config.pipeline_id;
575-
ipc_buf.comp.core = cpu_get_id();
575+
576+
assert(IS_ENABLED(CONFIG_SOF_USERSPACE_LL) || src->ipc_config.core == cpu_get_id());
577+
ipc_buf.comp.core = src->ipc_config.core;
578+
576579
return buffer_new(alloc, &ipc_buf, is_shared);
577580
}
578581

@@ -715,6 +718,11 @@ __cold int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
715718
#else
716719
alloc = NULL;
717720
#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */
721+
722+
#ifdef CONFIG_SOF_USERSPACE_LL
723+
if (!alloc)
724+
alloc = ipc->ll_alloc;
725+
#endif
718726
bool cross_core_bind = source->ipc_config.core != sink->ipc_config.core;
719727

720728
/* If both components are on same core -- process IPC on that core,

0 commit comments

Comments
 (0)