Skip to content

Commit d5b295e

Browse files
jxsteltersoftwarecki
authored andcommitted
alloc: userspace: Introduce MMU shared memory heap
In case of CONFIG_USERSPACE enabled, all memory is accessible form kernel space. For accessing it from user space we need to grant access to its explicitly. However there are some infrastructure components that could be shared between kernel and user spaces. This patch splits system heap into two sections. One section which will contatin shareable data will be located in separate memory partition. Each non-privilidged module will obtain it in its private memory domain. Signed-off-by: Jaroslaw Stelter <Jaroslaw.Stelter@intel.com> Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
1 parent 800f6ce commit d5b295e

4 files changed

Lines changed: 118 additions & 21 deletions

File tree

posix/include/rtos/alloc.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,21 @@
3333
*/
3434

3535
/** \brief Indicates we should return DMA-able memory. */
36-
#define SOF_MEM_FLAG_DMA BIT(0)
36+
#define SOF_MEM_FLAG_DMA BIT(0)
3737
/** \brief Indicates that original content should not be copied by realloc. */
38-
#define SOF_MEM_FLAG_NO_COPY BIT(1)
38+
#define SOF_MEM_FLAG_NO_COPY BIT(1)
3939
/** \brief Indicates that if we should return uncached address. */
40-
#define SOF_MEM_FLAG_COHERENT BIT(2)
40+
#define SOF_MEM_FLAG_COHERENT BIT(2)
4141
/** \brief Indicates that if we should return L3 address. */
42-
#define SOF_MEM_FLAG_L3 BIT(3)
42+
#define SOF_MEM_FLAG_L3 BIT(3)
4343
/** \brief Indicates that if we should return Low power memory address. */
44-
#define SOF_MEM_FLAG_LOW_POWER BIT(4)
44+
#define SOF_MEM_FLAG_LOW_POWER BIT(4)
4545
/** \brief Indicates that if we should return kernel memory address. */
46-
#define SOF_MEM_FLAG_KERNEL BIT(5)
46+
#define SOF_MEM_FLAG_KERNEL BIT(5)
4747
/** \brief Indicates that if we should return user memory address. */
48-
#define SOF_MEM_FLAG_USER BIT(6)
48+
#define SOF_MEM_FLAG_USER BIT(6)
49+
/** \brief Indicates that if we should return shared user memory address. */
50+
#define SOF_MEM_FLAG_USER_SHARED BIT(7)
4951

5052
/** @} */
5153

zephyr/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,18 @@ config SOF_ZEPHYR_HEAP_SIZE
4141
NOTE: Keep in mind that the heap size should not be greater than the physical
4242
memory size of the system defined in DT (and this includes baseFW text/data).
4343

44+
config SOF_ZEPHYR_SHARED_HEAP_SIZE
45+
hex "Size of the Zephyr shared heap for SOF userspace modules"
46+
default 0x1E000 if SOC_INTEL_ACE15_MTPM || SOC_INTEL_ACE20_LNL
47+
default 0x1A000 if SOC_INTEL_ACE30
48+
default 0x0
49+
help
50+
The size of the zephyr heap portion designated as the shared heap. This heap
51+
is shared between the sof and userspace modules. It is used exclusively for
52+
allocating audio buffers between the kernel and userspace modules.
53+
NOTE: Keep in mind that the shared heap size should not be greater than the
54+
heap size.
55+
4456
config SOF_ZEPHYR_VIRTUAL_HEAP_SIZE
4557
hex "Size of the Zephyr virtual heap for SOF"
4658
depends on VIRTUAL_HEAP

zephyr/include/rtos/alloc.h

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,21 @@
2424
*/
2525

2626
/** \brief Indicates we should return DMA-able memory. */
27-
#define SOF_MEM_FLAG_DMA BIT(0)
27+
#define SOF_MEM_FLAG_DMA BIT(0)
2828
/** \brief Indicates that original content should not be copied by realloc. */
29-
#define SOF_MEM_FLAG_NO_COPY BIT(1)
29+
#define SOF_MEM_FLAG_NO_COPY BIT(1)
3030
/** \brief Indicates that if we should return uncached address. */
31-
#define SOF_MEM_FLAG_COHERENT BIT(2)
31+
#define SOF_MEM_FLAG_COHERENT BIT(2)
3232
/** \brief Indicates that if we should return L3 address. */
33-
#define SOF_MEM_FLAG_L3 BIT(3)
33+
#define SOF_MEM_FLAG_L3 BIT(3)
3434
/** \brief Indicates that if we should return Low power memory address. */
35-
#define SOF_MEM_FLAG_LOW_POWER BIT(4)
35+
#define SOF_MEM_FLAG_LOW_POWER BIT(4)
3636
/** \brief Indicates that if we should return kernel memory address. */
37-
#define SOF_MEM_FLAG_KERNEL BIT(5)
37+
#define SOF_MEM_FLAG_KERNEL BIT(5)
3838
/** \brief Indicates that if we should return user memory address. */
39-
#define SOF_MEM_FLAG_USER BIT(6)
39+
#define SOF_MEM_FLAG_USER BIT(6)
40+
/** \brief Indicates that if we should return shared user memory address. */
41+
#define SOF_MEM_FLAG_USER_SHARED BIT(7)
4042

4143
/** @} */
4244

@@ -111,4 +113,21 @@ static inline void heap_trace_all(int force) {}
111113

112114
/** @}*/
113115

116+
#if CONFIG_USERSPACE
117+
/**
118+
* Returns the start address of shared memory heap.
119+
*
120+
* @return pointer to shared memory heap start
121+
*/
122+
uintptr_t get_shared_heap_start(void);
123+
124+
/**
125+
* Returns the size of shared memory heap.
126+
*
127+
* @return size of shared memory heap start
128+
*/
129+
size_t get_shared_heap_size(void);
130+
131+
#endif
132+
114133
#endif /* __ZEPHYR_RTOS_ALLOC_H__ */

zephyr/lib/alloc.c

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include <rtos/symbol.h>
2020
#include <rtos/wait.h>
2121

22+
#define SHARED_HEAP_MEM_SIZE 0
23+
2224
#if CONFIG_VIRTUAL_HEAP
2325
#include <sof/lib/regions_mm.h>
2426

@@ -98,7 +100,14 @@ static uint8_t __aligned(PLATFORM_DCACHE_ALIGN) heapmem[HEAPMEM_SIZE];
98100
* to allow memory management driver to control unused
99101
* memory pages.
100102
*/
101-
__section(".heap_mem") static uint8_t __aligned(PLATFORM_DCACHE_ALIGN) heapmem[HEAPMEM_SIZE];
103+
#if CONFIG_USERSPACE
104+
#undef SHARED_HEAP_MEM_SIZE
105+
#define SHARED_HEAP_MEM_SIZE ROUND_UP(CONFIG_SOF_ZEPHYR_SHARED_HEAP_SIZE, HOST_PAGE_SIZE)
106+
__section(".shared_heap_mem")
107+
static uint8_t __aligned(HOST_PAGE_SIZE) shared_heapmem[SHARED_HEAP_MEM_SIZE];
108+
#endif /* CONFIG_USERSPACE */
109+
__section(".heap_mem") static uint8_t __aligned(HOST_PAGE_SIZE) heapmem[HEAPMEM_SIZE -
110+
SHARED_HEAP_MEM_SIZE];
102111

103112
#elif defined(CONFIG_ARCH_POSIX)
104113

@@ -125,6 +134,40 @@ extern char _end[], _heap_sentry[];
125134

126135
static struct k_heap sof_heap;
127136

137+
#if CONFIG_USERSPACE
138+
static struct k_heap shared_heap;
139+
140+
static bool is_shd_heap_pointer(void *ptr)
141+
{
142+
uintptr_t shd_heap_start = POINTER_TO_UINT(shared_heapmem);
143+
uintptr_t shd_heap_end = POINTER_TO_UINT(shared_heapmem + SHARED_HEAP_MEM_SIZE);
144+
145+
if (is_cached(ptr))
146+
ptr = sys_cache_uncached_ptr_get((__sparse_force void __sparse_cache *)ptr);
147+
148+
return (POINTER_TO_UINT(ptr) >= shd_heap_start) && (POINTER_TO_UINT(ptr) < shd_heap_end);
149+
}
150+
151+
/**
152+
* Returns the start of HPSRAM Shared memory heap.
153+
* @return Pointer to the HPSRAM Shared memory location which can be used
154+
* for HPSRAM Shared heap.
155+
*/
156+
uintptr_t get_shared_heap_start(void)
157+
{
158+
return ROUND_UP(POINTER_TO_UINT(shared_heapmem), HOST_PAGE_SIZE);
159+
}
160+
161+
/**
162+
* Returns the size of HPSRAM Shared memory heap.
163+
* @return Size of the HPSRAM Shared memory region which can be used for HPSRAM Shared heap.
164+
*/
165+
size_t get_shared_heap_size(void)
166+
{
167+
return ROUND_DOWN(SHARED_HEAP_MEM_SIZE, HOST_PAGE_SIZE);
168+
}
169+
#endif /* CONFIG_USERSPACE */
170+
128171
#if CONFIG_L3_HEAP
129172
static struct k_heap l3_heap;
130173
static struct k_heap l3_heap_copy __imrdata;
@@ -243,15 +286,17 @@ static void *virtual_heap_alloc(struct vmh_heap *heap, uint32_t flags, size_t by
243286
return mem;
244287
}
245288

289+
extern int _unused_ram_start_marker;
290+
246291
/**
247292
* Checks whether pointer is from virtual memory range.
248293
* @param ptr Pointer to memory being checked.
249294
* @return True if pointer falls into virtual memory region, false otherwise.
250295
*/
251296
static bool is_virtual_heap_pointer(void *ptr)
252297
{
253-
uintptr_t virtual_heap_start = POINTER_TO_UINT(sys_cache_cached_ptr_get(&heapmem)) +
254-
HEAPMEM_SIZE;
298+
uintptr_t virtual_heap_start = POINTER_TO_UINT(
299+
sys_cache_cached_ptr_get(&_unused_ram_start_marker));
255300
uintptr_t virtual_heap_end = CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_SIZE;
256301

257302
if (!is_cached(ptr))
@@ -393,6 +438,10 @@ void *rmalloc(uint32_t flags, size_t bytes)
393438
return ptr;
394439
#else
395440
k_panic();
441+
#endif
442+
#if CONFIG_USERSPACE
443+
} else if (flags & SOF_MEM_FLAG_USER_SHARED) {
444+
heap = &shared_heap;
396445
#endif
397446
} else {
398447
heap = &sof_heap;
@@ -477,16 +526,20 @@ void *rballoc_align(uint32_t flags, size_t bytes,
477526
tr_err(&zephyr_tr, "L3_HEAP not available.");
478527
return NULL;
479528
#endif
529+
#if CONFIG_USERSPACE
530+
} else if (flags & SOF_MEM_FLAG_USER_SHARED) {
531+
heap = &shared_heap;
532+
#endif /* CONFIG_USERSPACE */
480533
} else {
481-
heap = &sof_heap;
482-
}
483-
484534
#if CONFIG_VIRTUAL_HEAP
485535
/* Use virtual heap if it is available */
486536
if (virtual_buffers_heap)
487537
return virtual_heap_alloc(virtual_buffers_heap, flags, bytes, align);
488538
#endif /* CONFIG_VIRTUAL_HEAP */
489539

540+
heap = &sof_heap;
541+
}
542+
490543
if (flags & SOF_MEM_FLAG_COHERENT)
491544
return heap_alloc_aligned(heap, align, bytes);
492545

@@ -516,13 +569,24 @@ void rfree(void *ptr)
516569
}
517570
#endif
518571

572+
#if CONFIG_USERSPACE
573+
if (is_shd_heap_pointer(ptr)) {
574+
heap_free(&shared_heap, ptr);
575+
return;
576+
}
577+
#endif
578+
519579
heap_free(&sof_heap, ptr);
520580
}
521581
EXPORT_SYMBOL(rfree);
522582

523583
static int heap_init(void)
524584
{
525-
sys_heap_init(&sof_heap.heap, heapmem, HEAPMEM_SIZE);
585+
sys_heap_init(&sof_heap.heap, heapmem, HEAPMEM_SIZE - SHARED_HEAP_MEM_SIZE);
586+
587+
#if CONFIG_USERSPACE
588+
sys_heap_init(&shared_heap.heap, shared_heapmem, SHARED_HEAP_MEM_SIZE);
589+
#endif
526590

527591
#if CONFIG_L3_HEAP
528592
if (l3_heap_copy.heap.heap)

0 commit comments

Comments
 (0)