Skip to content

Commit 612ab8f

Browse files
committed
ipc: place global IPC context in user-accessible memory for user-space LL
When CONFIG_SOF_USERSPACE_LL is enabled the IPC context must live in user-accessible application memory rather than being allocated from the kernel heap and reached via sof->ipc. Place struct ipc in a dedicated K_APP_BMEM partition and provide an out-of-line ipc_get() returning it; drop the sof->ipc pointer in this configuration. Add the generic ll_alloc allocation context to struct ipc and set it up in ipc_init() from the LL user heap, so LL components (host, dai, chain_dma) can allocate their buffers from a user-accessible heap. IPC objects (the context itself and comp_data) are allocated accordingly. A no-op ipc_user_init() stub is added here and implemented later. No IPC-major-specific knowledge is added here. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
1 parent cf8d4a0 commit 612ab8f

3 files changed

Lines changed: 82 additions & 16 deletions

File tree

src/include/sof/ipc/common.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ struct ipc {
7474
struct task ipc_task;
7575
#endif
7676

77+
#ifdef CONFIG_SOF_USERSPACE_LL
78+
struct mod_alloc_ctx *ll_alloc;
79+
#endif
80+
7781
#ifdef CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS
7882
/* io performance measurement */
7983
struct io_perf_data_item *io_perf_in_msg_count;
@@ -95,6 +99,12 @@ struct ipc {
9599

96100
extern struct task_ops ipc_task_ops;
97101

102+
#ifdef CONFIG_SOF_USERSPACE_LL
103+
104+
struct ipc *ipc_get(void);
105+
106+
#else
107+
98108
/**
99109
* \brief Get the IPC global context.
100110
* @return The global IPC context.
@@ -104,6 +114,8 @@ static inline struct ipc *ipc_get(void)
104114
return sof_get()->ipc;
105115
}
106116

117+
#endif /* CONFIG_SOF_USERSPACE_LL */
118+
107119
/**
108120
* \brief Initialise global IPC context.
109121
* @param[in,out] sof Global SOF context.

src/ipc/ipc-common.c

Lines changed: 68 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <sof/lib/memory.h>
2525
#include <sof/list.h>
2626
#include <sof/platform.h>
27+
#include <sof/schedule/ll_schedule.h>
28+
#include <sof/schedule/ll_schedule_domain.h>
2729
#include <rtos/sof.h>
2830
#include <rtos/spinlock.h>
2931
#include <ipc/dai.h>
@@ -35,6 +37,15 @@
3537
#include <stddef.h>
3638
#include <stdint.h>
3739

40+
#ifdef __ZEPHYR__
41+
#include <zephyr/kernel.h>
42+
#endif
43+
44+
#ifdef CONFIG_SOF_USERSPACE_LL
45+
#include <rtos/userspace_helper.h>
46+
#include <sof/schedule/ll_schedule_domain.h>
47+
#endif
48+
3849
#include <sof/debug/telemetry/performance_monitor.h>
3950

4051
LOG_MODULE_REGISTER(ipc, CONFIG_SOF_LOG_LEVEL);
@@ -43,6 +54,17 @@ SOF_DEFINE_REG_UUID(ipc);
4354

4455
DECLARE_TR_CTX(ipc_tr, SOF_UUID(ipc_uuid), LOG_LEVEL_INFO);
4556

57+
#ifdef CONFIG_SOF_USERSPACE_LL
58+
K_APPMEM_PARTITION_DEFINE(ipc_context_part);
59+
60+
K_APP_BMEM(ipc_context_part) static struct ipc ipc_context;
61+
62+
struct ipc *ipc_get(void)
63+
{
64+
return &ipc_context;
65+
}
66+
#endif
67+
4668
int ipc_process_on_core(uint32_t core, bool blocking)
4769
{
4870
struct ipc *ipc = ipc_get();
@@ -288,34 +310,61 @@ void ipc_schedule_process(struct ipc *ipc)
288310
#endif
289311
}
290312

313+
static int ipc_user_init(void)
314+
{
315+
return 0;
316+
}
317+
291318
__cold int ipc_init(struct sof *sof)
292319
{
320+
struct k_heap *heap;
321+
struct ipc *ipc;
322+
293323
assert_can_be_cold();
294324

295325
tr_dbg(&ipc_tr, "entry");
296326

297327
#if CONFIG_SOF_BOOT_TEST_STANDALONE
298-
LOG_INF("SOF_BOOT_TEST_STANDALONE, disabling IPC.");
328+
LOG_INF("SOF_BOOT_TEST_STANDALONE, skipping platform IPC init.");
299329
return 0;
300330
#endif
301331

332+
#ifdef CONFIG_SOF_USERSPACE_LL
333+
heap = zephyr_ll_user_heap();
334+
335+
ipc = ipc_get();
336+
memset(ipc, 0, sizeof(*ipc));
337+
ipc->ll_alloc = sof_heap_alloc(heap, SOF_MEM_FLAG_USER, sizeof(*ipc->ll_alloc), 0);
338+
if (!ipc->ll_alloc) {
339+
tr_err(&ipc_tr, "Unable to allocate IPC ll_alloc");
340+
return -ENOMEM;
341+
}
342+
ipc->ll_alloc->heap = heap;
343+
ipc->ll_alloc->vreg = NULL;
344+
#else
345+
heap = NULL;
346+
302347
/* init ipc data */
303-
sof->ipc = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*sof->ipc));
304-
if (!sof->ipc) {
348+
ipc = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*ipc));
349+
if (!ipc) {
305350
tr_err(&ipc_tr, "Unable to allocate IPC data");
306351
return -ENOMEM;
307352
}
308-
sof->ipc->comp_data = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT,
309-
SOF_IPC_MSG_MAX_SIZE);
310-
if (!sof->ipc->comp_data) {
353+
sof->ipc = ipc;
354+
#endif
355+
356+
ipc->comp_data = sof_heap_alloc(heap, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT,
357+
SOF_IPC_MSG_MAX_SIZE, 0);
358+
if (!ipc->comp_data) {
311359
tr_err(&ipc_tr, "Unable to allocate IPC component data");
312-
rfree(sof->ipc);
360+
sof_heap_free(heap, ipc);
313361
return -ENOMEM;
314362
}
363+
memset(ipc->comp_data, 0, SOF_IPC_MSG_MAX_SIZE);
315364

316-
k_spinlock_init(&sof->ipc->lock);
317-
list_init(&sof->ipc->msg_list);
318-
list_init(&sof->ipc->comp_list);
365+
k_spinlock_init(&ipc->lock);
366+
list_init(&ipc->msg_list);
367+
list_init(&ipc->comp_list);
319368

320369
#ifdef CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS
321370
struct io_perf_data_item init_data = {IO_PERF_IPC_ID,
@@ -324,15 +373,16 @@ __cold int ipc_init(struct sof *sof)
324373
IO_PERF_POWERED_UP_ENABLED,
325374
IO_PERF_D0IX_POWER_MODE,
326375
0, 0, 0 };
327-
io_perf_monitor_init_data(&sof->ipc->io_perf_in_msg_count, &init_data);
376+
io_perf_monitor_init_data(&ipc->io_perf_in_msg_count, &init_data);
328377
init_data.direction = IO_PERF_OUTPUT_DIRECTION;
329-
io_perf_monitor_init_data(&sof->ipc->io_perf_out_msg_count, &init_data);
378+
io_perf_monitor_init_data(&ipc->io_perf_out_msg_count, &init_data);
330379
#endif
331380

332381
#ifdef __ZEPHYR__
333-
struct k_thread *thread = &sof->ipc->ipc_send_wq.thread;
382+
struct k_thread *thread = &ipc->ipc_send_wq.thread;
334383

335-
k_work_queue_start(&sof->ipc->ipc_send_wq, ipc_send_wq_stack,
384+
k_work_queue_init(&ipc->ipc_send_wq);
385+
k_work_queue_start(&ipc->ipc_send_wq, ipc_send_wq_stack,
336386
K_THREAD_STACK_SIZEOF(ipc_send_wq_stack), 1, NULL);
337387

338388
k_thread_suspend(thread);
@@ -344,10 +394,12 @@ __cold int ipc_init(struct sof *sof)
344394

345395
k_thread_resume(thread);
346396

347-
k_work_init_delayable(&sof->ipc->z_delayed_work, ipc_work_handler);
397+
k_work_init_delayable(&ipc->z_delayed_work, ipc_work_handler);
348398
#endif
349399

350-
return platform_ipc_init(sof->ipc);
400+
ipc_user_init();
401+
402+
return platform_ipc_init(ipc);
351403
}
352404

353405
/* Locking: call with ipc->lock held and interrupts disabled */

zephyr/include/rtos/sof.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ struct sof {
4646
int argc;
4747
char **argv;
4848

49+
#ifndef CONFIG_SOF_USERSPACE_LL
4950
/* ipc */
5051
struct ipc *ipc;
52+
#endif
5153

5254
/* system agent */
5355
struct sa *sa;

0 commit comments

Comments
 (0)