@@ -58,14 +58,80 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv,
5858#define PAGE_SZ HOST_PAGE_SIZE
5959#endif
6060
61- static struct vregion * module_adapter_dp_heap_new (const struct comp_ipc_config * config ,
62- size_t * heap_size )
61+ struct vregion * z_impl_module_adapter_vreg_new (const struct comp_ipc_config * config ,
62+ uintptr_t * vreg_start , size_t * vreg_size )
6363{
6464 /* src-lite with 8 channels has been seen allocating 14k in one go */
6565 /* FIXME: the size will be derived from configuration */
6666 const size_t buf_size = 28 * 1024 ;
67+ struct vregion * vr = vregion_create (buf_size );
6768
68- return vregion_create (buf_size );
69+ if (!vr )
70+ return NULL ;
71+
72+ #ifdef CONFIG_SOF_USERSPACE_LL
73+ vregion_mem_info (vr , vreg_size , vreg_start );
74+
75+ /*
76+ * In the userspace LL case allocations are also performed by the
77+ * userspace IPC thread, which is also the one, executing this syscall
78+ */
79+ struct k_mem_partition part = {
80+ .start = * vreg_start ,
81+ .size = * vreg_size ,
82+ .attr = K_MEM_PARTITION_P_RW_U_RW | XTENSA_MMU_CACHED_WB ,
83+ };
84+ int ret = k_mem_domain_add_partition (zephyr_ll_mem_domain (), & part );
85+
86+ if (ret < 0 ) {
87+ vregion_put (vr );
88+ return NULL ;
89+ }
90+
91+ part .start = (uintptr_t )sys_cache_uncached_ptr_get ((void * )part .start );
92+ part .attr = K_MEM_PARTITION_P_RW_U_RW ;
93+
94+ ret = k_mem_domain_add_partition (zephyr_ll_mem_domain (), & part );
95+ if (ret < 0 ) {
96+ vregion_put (vr );
97+ return NULL ;
98+ }
99+ #else
100+ ARG_UNUSED (vreg_start );
101+ ARG_UNUSED (vreg_size );
102+ #endif
103+
104+ return vr ;
105+ }
106+
107+ void z_impl_module_adapter_vreg_unmap (const struct mod_alloc_ctx * alloc )
108+ {
109+ #ifdef CONFIG_SOF_USERSPACE_LL
110+ struct k_mem_partition part = {
111+ .start = alloc -> vreg_start ,
112+ .size = alloc -> vreg_size ,
113+ .attr = K_MEM_PARTITION_P_RW_U_RW | XTENSA_MMU_CACHED_WB ,
114+ };
115+
116+ k_mem_domain_remove_partition (zephyr_ll_mem_domain (), & part );
117+
118+ part .start = (uintptr_t )sys_cache_uncached_ptr_get ((void * )part .start );
119+ part .attr = K_MEM_PARTITION_P_RW_U_RW ;
120+
121+ k_mem_domain_remove_partition (zephyr_ll_mem_domain (), & part );
122+ #else
123+ ARG_UNUSED (alloc );
124+ #endif
125+ }
126+
127+ void module_adapter_vreg_free (struct mod_alloc_ctx * alloc )
128+ {
129+ if (vregion_put (alloc -> vreg ))
130+ return ;
131+
132+ module_adapter_vreg_unmap (alloc );
133+
134+ sof_heap_free (alloc -> heap , alloc );
69135}
70136
71137static struct processing_module * module_adapter_mem_alloc (const struct comp_driver * drv ,
@@ -84,11 +150,12 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
84150 */
85151 uint32_t flags = config -> proc_domain == COMP_PROCESSING_DOMAIN_DP ?
86152 SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT : SOF_MEM_FLAG_USER ;
87- size_t heap_size ;
153+ size_t vreg_size ;
154+ uintptr_t vreg_start ;
88155
89156 if (config -> proc_domain == COMP_PROCESSING_DOMAIN_DP && IS_ENABLED (CONFIG_SOF_VREGIONS ) &&
90157 IS_ENABLED (CONFIG_USERSPACE ) && !IS_ENABLED (CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP )) {
91- mod_vreg = module_adapter_dp_heap_new (config , & heap_size );
158+ mod_vreg = module_adapter_vreg_new (config , & vreg_start , & vreg_size );
92159 if (!mod_vreg ) {
93160 comp_cl_err (drv , "Failed to allocate DP module heap / vregion" );
94161 return NULL ;
@@ -101,7 +168,6 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
101168#else
102169 mod_heap = drv -> user_heap ;
103170#endif
104- heap_size = 0 ;
105171 mod_vreg = NULL ;
106172 }
107173
@@ -125,6 +191,8 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
125191 memset (mod , 0 , sizeof (* mod ));
126192 alloc -> heap = mod_heap ;
127193 alloc -> vreg = mod_vreg ;
194+ alloc -> vreg_start = vreg_start ;
195+ alloc -> vreg_size = vreg_size ;
128196 mod -> priv .resources .alloc = alloc ;
129197 mod_resource_init (mod );
130198
@@ -165,6 +233,25 @@ static struct processing_module *module_adapter_mem_alloc(const struct comp_driv
165233 return NULL ;
166234}
167235
236+ #ifdef CONFIG_USERSPACE
237+ #include <zephyr/internal/syscall_handler.h>
238+ struct vregion * z_vrfy_module_adapter_vreg_new (const struct comp_ipc_config * config ,
239+ uintptr_t * vreg_start , size_t * vreg_size )
240+ {
241+ K_OOPS (K_SYSCALL_MEMORY_WRITE (vreg_start , sizeof (* vreg_start )));
242+ K_OOPS (K_SYSCALL_MEMORY_WRITE (vreg_size , sizeof (* vreg_size )));
243+ K_OOPS (K_SYSCALL_MEMORY_READ (config , sizeof (* config )));
244+ return z_impl_module_adapter_vreg_new (config , vreg_start , vreg_size );
245+ }
246+ #include <zephyr/syscalls/module_adapter_vreg_new_mrsh.c>
247+ void z_vrfy_module_adapter_vreg_unmap (const struct mod_alloc_ctx * alloc )
248+ {
249+ K_OOPS (K_SYSCALL_MEMORY_READ (alloc , sizeof (* alloc )));
250+ z_impl_module_adapter_vreg_unmap (alloc );
251+ }
252+ #include <zephyr/syscalls/module_adapter_vreg_unmap_mrsh.c>
253+ #endif
254+
168255static void module_adapter_mem_free (struct processing_module * mod )
169256{
170257 struct mod_alloc_ctx * alloc = mod -> priv .resources .alloc ;
@@ -182,8 +269,7 @@ static void module_adapter_mem_free(struct processing_module *mod)
182269
183270 vregion_free (mod_vreg , mod -> dev );
184271 vregion_free (mod_vreg , mod );
185- if (!vregion_put (mod_vreg ))
186- sof_heap_free (alloc -> heap , alloc );
272+ module_adapter_vreg_free (alloc );
187273 } else {
188274 sof_heap_free (mod_heap , mod -> dev );
189275 sof_heap_free (mod_heap , mod );
0 commit comments