@@ -116,8 +116,8 @@ static inline uintptr_t get_l3_heap_start(void)
116116 * - main_fw_load_offset
117117 * - main fw size in manifest
118118 */
119- return (uintptr_t )z_soc_uncached_ptr (( __sparse_force void __sparse_cache * )
120- ROUND_UP (IMR_L3_HEAP_BASE , L3_MEM_PAGE_SIZE ));
119+ return (uintptr_t )(( void __sparse_cache * )
120+ ROUND_UP (IMR_L3_HEAP_BASE , L3_MEM_PAGE_SIZE ));
121121}
122122
123123/**
@@ -145,14 +145,67 @@ static bool is_l3_heap_pointer(void *ptr)
145145 uintptr_t l3_heap_start = get_l3_heap_start ();
146146 uintptr_t l3_heap_end = l3_heap_start + get_l3_heap_size ();
147147
148- if (is_cached (ptr ))
149- ptr = z_soc_uncached_ptr ((__sparse_force void __sparse_cache * )ptr );
150-
151148 if ((POINTER_TO_UINT (ptr ) >= l3_heap_start ) && (POINTER_TO_UINT (ptr ) < l3_heap_end ))
152149 return true;
153150
154151 return false;
155152}
153+
154+ static void * l3_heap_alloc_aligned (struct k_heap * h , size_t min_align , size_t bytes )
155+ {
156+ k_spinlock_key_t key ;
157+ void * ret ;
158+ #if CONFIG_SYS_HEAP_RUNTIME_STATS && CONFIG_IPC_MAJOR_4
159+ struct sys_memory_stats stats ;
160+ #endif
161+ if (!cpu_is_primary (arch_proc_id ())) {
162+ tr_err (& zephyr_tr , "L3_HEAP available only for primary core!" );
163+ return NULL ;
164+ }
165+
166+ key = k_spin_lock (& h -> lock );
167+ ret = sys_heap_aligned_alloc (& h -> heap , min_align , bytes );
168+ k_spin_unlock (& h -> lock , key );
169+
170+ #if CONFIG_SYS_HEAP_RUNTIME_STATS && CONFIG_IPC_MAJOR_4
171+ sys_heap_runtime_stats_get (& h -> heap , & stats );
172+ tr_info (& zephyr_tr , "heap allocated: %u free: %u max allocated: %u" ,
173+ stats .allocated_bytes , stats .free_bytes , stats .max_allocated_bytes );
174+ #endif
175+
176+ return ret ;
177+ }
178+
179+ static void __sparse_cache * l3_heap_alloc_aligned_cached (struct k_heap * h ,
180+ size_t min_align , size_t bytes )
181+ {
182+ /*
183+ * Zephyr sys_heap stores metadata at start of each
184+ * heap allocation. To ensure no allocated cached buffer
185+ * overlaps the same cacheline with the metadata chunk,
186+ * align both allocation start and size of allocation
187+ * to cacheline. Only cached allocations are supported in
188+ * l3_heap.
189+ */
190+ min_align = MAX (PLATFORM_DCACHE_ALIGN , min_align );
191+ bytes = ALIGN_UP (bytes , min_align );
192+
193+ return (void __sparse_cache * )l3_heap_alloc_aligned (h , min_align , bytes );
194+ }
195+
196+ static void l3_heap_free (struct k_heap * h , void * mem )
197+ {
198+ if (!cpu_is_primary (arch_proc_id ())) {
199+ tr_err (& zephyr_tr , "L3_HEAP available only for primary core!" );
200+ return ;
201+ }
202+
203+ k_spinlock_key_t key = k_spin_lock (& h -> lock );
204+
205+ sys_heap_free (& h -> heap , mem );
206+ k_spin_unlock (& h -> lock , key );
207+ }
208+
156209#endif
157210
158211static void * heap_alloc_aligned (struct k_heap * h , size_t min_align , size_t bytes )
@@ -251,6 +304,17 @@ void *rmalloc(enum mem_zone zone, uint32_t flags, uint32_t caps, size_t bytes)
251304 if (caps & SOF_MEM_CAPS_L3 ) {
252305#if CONFIG_L3_HEAP
253306 heap = & l3_heap ;
307+ /* Uncached L3_HEAP should be not used */
308+ if (!zone_is_cached (zone )) {
309+ tr_err (& zephyr_tr , "L3_HEAP available for cached zones only!" );
310+ return NULL ;
311+ }
312+ ptr = (__sparse_force void * )l3_heap_alloc_aligned_cached (heap , 0 , bytes );
313+
314+ if (!ptr && zone == SOF_MEM_ZONE_SYS )
315+ k_panic ();
316+
317+ return ptr ;
254318#else
255319 k_panic ();
256320#endif
@@ -352,7 +416,7 @@ void rfree(void *ptr)
352416
353417#if CONFIG_L3_HEAP
354418 if (is_l3_heap_pointer (ptr )) {
355- heap_free (& l3_heap , ptr );
419+ l3_heap_free (& l3_heap , ptr );
356420 return ;
357421 }
358422#endif
0 commit comments