Skip to content

Commit 54d5db0

Browse files
kv2019ilgirdwood
authored andcommitted
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 350fc41 commit 54d5db0

3 files changed

Lines changed: 81 additions & 17 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: 67 additions & 17 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,14 @@
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+
#endif
47+
3848
#include <sof/debug/telemetry/performance_monitor.h>
3949

4050
LOG_MODULE_REGISTER(ipc, CONFIG_SOF_LOG_LEVEL);
@@ -43,6 +53,17 @@ SOF_DEFINE_REG_UUID(ipc);
4353

4454
DECLARE_TR_CTX(ipc_tr, SOF_UUID(ipc_uuid), LOG_LEVEL_INFO);
4555

56+
#ifdef CONFIG_SOF_USERSPACE_LL
57+
K_APPMEM_PARTITION_DEFINE(ipc_context_part);
58+
59+
K_APP_BMEM(ipc_context_part) static struct ipc ipc_context;
60+
61+
struct ipc *ipc_get(void)
62+
{
63+
return &ipc_context;
64+
}
65+
#endif
66+
4667
int ipc_process_on_core(uint32_t core, bool blocking)
4768
{
4869
struct ipc *ipc = ipc_get();
@@ -288,34 +309,60 @@ void ipc_schedule_process(struct ipc *ipc)
288309
#endif
289310
}
290311

312+
static void ipc_user_init(void)
313+
{
314+
}
315+
291316
__cold int ipc_init(struct sof *sof)
292317
{
318+
struct k_heap *heap;
319+
struct ipc *ipc;
320+
293321
assert_can_be_cold();
294322

295323
tr_dbg(&ipc_tr, "entry");
296324

297325
#if CONFIG_SOF_BOOT_TEST_STANDALONE
298-
LOG_INF("SOF_BOOT_TEST_STANDALONE, disabling IPC.");
326+
LOG_INF("SOF_BOOT_TEST_STANDALONE, skipping platform IPC init.");
299327
return 0;
300328
#endif
301329

330+
#ifdef CONFIG_SOF_USERSPACE_LL
331+
heap = zephyr_ll_user_heap();
332+
333+
ipc = ipc_get();
334+
memset(ipc, 0, sizeof(*ipc));
335+
ipc->ll_alloc = sof_heap_alloc(heap, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT,
336+
sizeof(*ipc->ll_alloc), 0);
337+
if (!ipc->ll_alloc) {
338+
tr_err(&ipc_tr, "Unable to allocate IPC ll_alloc");
339+
sof_panic(SOF_IPC_PANIC_IPC);
340+
}
341+
ipc->ll_alloc->heap = heap;
342+
ipc->ll_alloc->vreg = NULL;
343+
#else
344+
heap = NULL;
345+
302346
/* init ipc data */
303-
sof->ipc = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*sof->ipc));
304-
if (!sof->ipc) {
347+
ipc = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*ipc));
348+
if (!ipc) {
305349
tr_err(&ipc_tr, "Unable to allocate IPC data");
306350
return -ENOMEM;
307351
}
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) {
352+
sof->ipc = ipc;
353+
#endif
354+
355+
ipc->comp_data = sof_heap_alloc(heap, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT,
356+
SOF_IPC_MSG_MAX_SIZE, 0);
357+
if (!ipc->comp_data) {
311358
tr_err(&ipc_tr, "Unable to allocate IPC component data");
312-
rfree(sof->ipc);
313-
return -ENOMEM;
359+
sof_panic(SOF_IPC_PANIC_IPC);
314360
}
361+
memset(ipc->comp_data, 0, SOF_IPC_MSG_MAX_SIZE);
315362

316-
k_spinlock_init(&sof->ipc->lock);
317-
list_init(&sof->ipc->msg_list);
318-
list_init(&sof->ipc->comp_list);
363+
k_spinlock_init(&ipc->lock);
364+
list_init(&ipc->msg_list);
365+
list_init(&ipc->comp_list);
319366

320367
#ifdef CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS
321368
struct io_perf_data_item init_data = {IO_PERF_IPC_ID,
@@ -324,18 +371,19 @@ __cold int ipc_init(struct sof *sof)
324371
IO_PERF_POWERED_UP_ENABLED,
325372
IO_PERF_D0IX_POWER_MODE,
326373
0, 0, 0 };
327-
io_perf_monitor_init_data(&sof->ipc->io_perf_in_msg_count, &init_data);
374+
io_perf_monitor_init_data(&ipc->io_perf_in_msg_count, &init_data);
328375
init_data.direction = IO_PERF_OUTPUT_DIRECTION;
329-
io_perf_monitor_init_data(&sof->ipc->io_perf_out_msg_count, &init_data);
376+
io_perf_monitor_init_data(&ipc->io_perf_out_msg_count, &init_data);
330377
#endif
331378

332379
#ifdef __ZEPHYR__
333380
k_tid_t thread;
334381

335-
k_work_queue_start(&sof->ipc->ipc_send_wq, ipc_send_wq_stack,
382+
k_work_queue_init(&ipc->ipc_send_wq);
383+
k_work_queue_start(&ipc->ipc_send_wq, ipc_send_wq_stack,
336384
K_THREAD_STACK_SIZEOF(ipc_send_wq_stack), 1, NULL);
337385

338-
thread = k_work_queue_thread_get(&sof->ipc->ipc_send_wq);
386+
thread = k_work_queue_thread_get(&ipc->ipc_send_wq);
339387

340388
k_thread_suspend(thread);
341389

@@ -346,10 +394,12 @@ __cold int ipc_init(struct sof *sof)
346394

347395
k_thread_resume(thread);
348396

349-
k_work_init_delayable(&sof->ipc->z_delayed_work, ipc_work_handler);
397+
k_work_init_delayable(&ipc->z_delayed_work, ipc_work_handler);
350398
#endif
351399

352-
return platform_ipc_init(sof->ipc);
400+
ipc_user_init();
401+
402+
return platform_ipc_init(ipc);
353403
}
354404

355405
/* 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)