@@ -51,132 +51,91 @@ static struct ext_library loader_ext_lib;
5151
5252#define PAGE_SZ CONFIG_MM_DRV_PAGE_SIZE
5353
54- static int lib_manager_load_data_from_storage (void __sparse_cache * vma , void * s_addr ,
55- uint32_t size , uint32_t flags )
54+ static int lib_manager_load_data_from_storage (void * vma , void * s_addr , uint32_t size ,
55+ uint32_t flags )
5656{
57- int ret = sys_mm_drv_map_region ((__sparse_force void * )vma , POINTER_TO_UINT (NULL ),
58- size , flags );
57+ /* Region must be first mapped as writable in order to initialize its contents. */
58+ int ret = sys_mm_drv_map_region (vma , POINTER_TO_UINT (NULL ), size ,
59+ flags | SYS_MM_MEM_PERM_RW );
5960 if (ret < 0 )
6061 return ret ;
6162
62- ret = memcpy_s (( __sparse_force void * ) vma , size , s_addr , size );
63+ ret = memcpy_s (vma , size , s_addr , size );
6364 if (ret < 0 )
6465 return ret ;
6566
6667 dcache_writeback_region (vma , size );
6768
68- /* TODO: Change attributes for memory to FLAGS */
69+ /* TODO: Change attributes for memory to FLAGS. Implementation of required function in tlb
70+ * driver in progress.
71+ sys_mm_drv_update_region_flags(vma, size, flags); */
6972 return 0 ;
7073}
7174
72- static int lib_manager_load_module (uint32_t module_id , struct sof_man_module * mod ,
73- struct sof_man_fw_desc * desc )
75+ static int lib_manager_load_module (const uint32_t module_id ,
76+ const struct sof_man_module * const mod )
7477{
75- struct ext_library * ext_lib = ext_lib_get ();
76- uint32_t lib_id = LIB_MANAGER_GET_LIB_ID (module_id );
77- size_t load_offset = (size_t )((void * )ext_lib -> desc [lib_id ]);
78- void __sparse_cache * va_base_text = (void __sparse_cache * )
79- mod -> segment [SOF_MAN_SEGMENT_TEXT ].v_base_addr ;
80- void * src_txt = (void * )(mod -> segment [SOF_MAN_SEGMENT_TEXT ].file_offset + load_offset );
81- size_t st_text_size = mod -> segment [SOF_MAN_SEGMENT_TEXT ].flags .r .length ;
82- void __sparse_cache * va_base_rodata = (void __sparse_cache * )
83- mod -> segment [SOF_MAN_SEGMENT_RODATA ].v_base_addr ;
84- void * src_rodata =
85- (void * )(mod -> segment [SOF_MAN_SEGMENT_RODATA ].file_offset + load_offset );
86- size_t st_rodata_size = mod -> segment [SOF_MAN_SEGMENT_RODATA ].flags .r .length ;
87- int ret ;
88-
89- st_text_size = st_text_size * PAGE_SZ ;
90- st_rodata_size = st_rodata_size * PAGE_SZ ;
91-
92- /* Copy Code */
93- ret = lib_manager_load_data_from_storage (va_base_text , src_txt , st_text_size ,
94- SYS_MM_MEM_PERM_RW | SYS_MM_MEM_PERM_EXEC );
95- if (ret < 0 )
96- goto err ;
97-
98- /* Copy RODATA */
99- ret = lib_manager_load_data_from_storage (va_base_rodata , src_rodata ,
100- st_rodata_size , SYS_MM_MEM_PERM_RW );
101- if (ret < 0 )
102- goto err ;
103-
104- /* There are modules marked as lib_code. This is code shared between several modules inside
105- * the library. Load all lib_code modules with first none lib_code module load.
106- */
107- if (!mod -> type .lib_code )
108- ext_lib -> mods_exec_load_cnt ++ ;
109-
110- if (ext_lib -> mods_exec_load_cnt == 1 ) {
111- struct sof_man_module * module_entry =
112- (struct sof_man_module * )((char * )desc + SOF_MAN_MODULE_OFFSET (0 ));
113- for (size_t idx = 0 ; idx < desc -> header .num_module_entries ;
114- ++ idx , ++ module_entry ) {
115- if (module_entry -> type .lib_code ) {
116- ret = lib_manager_load_module (lib_id << LIB_MANAGER_LIB_ID_SHIFT |
117- idx , mod , desc );
118- if (ret < 0 )
119- goto err ;
120- }
121- }
78+ const struct ext_library * const ext_lib = ext_lib_get ();
79+ const uint32_t lib_id = LIB_MANAGER_GET_LIB_ID (module_id );
80+ const uintptr_t load_offset = POINTER_TO_UINT (ext_lib -> desc [lib_id ]);
81+ void * src , * va_base ;
82+ size_t size ;
83+ uint32_t flags ;
84+ int ret , idx ;
85+
86+ for (idx = 0 ; idx < ARRAY_SIZE (mod -> segment ); ++ idx ) {
87+ if (!mod -> segment [idx ].flags .r .load )
88+ continue ;
89+
90+ flags = 0 ;
91+
92+ if (mod -> segment [idx ].flags .r .code )
93+ flags = SYS_MM_MEM_PERM_EXEC ;
94+ else if (!mod -> segment [idx ].flags .r .readonly )
95+ flags = SYS_MM_MEM_PERM_RW ;
96+
97+ src = UINT_TO_POINTER (mod -> segment [idx ].file_offset + load_offset );
98+ va_base = UINT_TO_POINTER (mod -> segment [idx ].v_base_addr );
99+ size = mod -> segment [idx ].flags .r .length * PAGE_SZ ;
100+ ret = lib_manager_load_data_from_storage (va_base , src , size , flags );
101+ if (ret < 0 )
102+ goto err ;
122103 }
123104
124105 return 0 ;
125106
126107err :
127- sys_mm_drv_unmap_region ((__sparse_force void * )va_base_text , st_text_size );
128- sys_mm_drv_unmap_region ((__sparse_force void * )va_base_rodata , st_rodata_size );
108+ for (-- idx ; idx >= 0 ; -- idx ) {
109+ if (!mod -> segment [idx ].flags .r .load )
110+ continue ;
111+
112+ va_base = UINT_TO_POINTER (mod -> segment [idx ].v_base_addr );
113+ size = mod -> segment [idx ].flags .r .length * PAGE_SZ ;
114+ sys_mm_drv_unmap_region (va_base , size );
115+ }
129116
130117 return ret ;
131118}
132119
133- static int lib_manager_unload_module (uint32_t module_id , struct sof_man_module * mod ,
134- struct sof_man_fw_desc * desc )
120+ static int lib_manager_unload_module (const struct sof_man_module * const mod )
135121{
136- struct ext_library * ext_lib = ext_lib_get ();
137- uint32_t lib_id = LIB_MANAGER_GET_LIB_ID (module_id );
138- void __sparse_cache * va_base_text = (void __sparse_cache * )
139- mod -> segment [SOF_MAN_SEGMENT_TEXT ].v_base_addr ;
140- size_t st_text_size = mod -> segment [SOF_MAN_SEGMENT_TEXT ].flags .r .length ;
141- void __sparse_cache * va_base_rodata = (void __sparse_cache * )
142- mod -> segment [SOF_MAN_SEGMENT_RODATA ].v_base_addr ;
143- size_t st_rodata_size = mod -> segment [SOF_MAN_SEGMENT_RODATA ].flags .r .length ;
122+ void * va_base ;
123+ size_t size ;
124+ uint32_t idx ;
144125 int ret ;
145126
146- st_text_size = st_text_size * PAGE_SZ ;
147- st_rodata_size = st_rodata_size * PAGE_SZ ;
127+ for (idx = 0 ; idx < ARRAY_SIZE (mod -> segment ); ++ idx ) {
128+ if (!mod -> segment [idx ].flags .r .load )
129+ continue ;
148130
149- ret = sys_mm_drv_unmap_region ((__sparse_force void * )va_base_text , st_text_size );
150- if (ret < 0 )
151- return ret ;
152-
153- ret = sys_mm_drv_unmap_region ((__sparse_force void * )va_base_rodata , st_rodata_size );
154- if (ret < 0 )
155- return ret ;
156-
157- /* There are modules marked as lib_code. This is code shared between several modules inside
158- * the library. Unload all lib_code modules with last none lib_code module unload.
159- */
160- if (mod -> type .lib_code )
161- return ret ;
162-
163- if (!mod -> type .lib_code && ext_lib -> mods_exec_load_cnt > 0 )
164- ext_lib -> mods_exec_load_cnt -- ;
165-
166- if (ext_lib -> mods_exec_load_cnt == 0 ) {
167- struct sof_man_module * module_entry =
168- (struct sof_man_module * )((char * )desc + SOF_MAN_MODULE_OFFSET (0 ));
169- for (size_t idx = 0 ; idx < desc -> header .num_module_entries ;
170- ++ idx , ++ module_entry ) {
171- if (module_entry -> type .lib_code ) {
172- ret =
173- lib_manager_unload_module (lib_id << LIB_MANAGER_LIB_ID_SHIFT |
174- idx , mod , desc );
175- }
176- }
131+ va_base = UINT_TO_POINTER (mod -> segment [idx ].v_base_addr );
132+ size = mod -> segment [idx ].flags .r .length * PAGE_SZ ;
133+ ret = sys_mm_drv_unmap_region (va_base , size );
134+ if (ret < 0 )
135+ return ret ;
177136 }
178137
179- return ret ;
138+ return 0 ;
180139}
181140
182141static void __sparse_cache * lib_manager_get_instance_bss_address (uint32_t module_id ,
@@ -262,7 +221,7 @@ uint32_t lib_manager_allocate_module(const struct comp_driver *drv,
262221
263222 mod = (struct sof_man_module * )((char * )desc + SOF_MAN_MODULE_OFFSET (entry_index ));
264223
265- ret = lib_manager_load_module (module_id , mod , desc );
224+ ret = lib_manager_load_module (module_id , mod );
266225 if (ret < 0 )
267226 return 0 ;
268227
@@ -271,9 +230,13 @@ uint32_t lib_manager_allocate_module(const struct comp_driver *drv,
271230 if (ret < 0 ) {
272231 tr_err (& lib_manager_tr ,
273232 "lib_manager_allocate_module(): module allocation failed: %d" , ret );
274- return 0 ;
233+ goto err ;
275234 }
276235 return mod -> entry_point ;
236+
237+ err :
238+ lib_manager_unload_module (mod );
239+ return 0 ;
277240}
278241
279242int lib_manager_free_module (const struct comp_driver * drv ,
@@ -290,7 +253,7 @@ int lib_manager_free_module(const struct comp_driver *drv,
290253 desc = lib_manager_get_library_module_desc (module_id );
291254 mod = (struct sof_man_module * )((char * )desc + SOF_MAN_MODULE_OFFSET (entry_index ));
292255
293- ret = lib_manager_unload_module (module_id , mod , desc );
256+ ret = lib_manager_unload_module (mod );
294257 if (ret < 0 )
295258 return ret ;
296259
0 commit comments