Skip to content

Commit a226676

Browse files
committed
lib-manager: handle unaligned .text and .data sections
Currently only page size-aligned .text and .rodata sections are supported. Remove this limitation by prepadding the address to restore the alignment. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
1 parent 0e54702 commit a226676

1 file changed

Lines changed: 36 additions & 19 deletions

File tree

src/library_manager/lib_manager.c

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,39 @@ static struct ext_library loader_ext_lib;
5151

5252
#define PAGE_SZ CONFIG_MM_DRV_PAGE_SIZE
5353

54+
static int lib_manager_align_map(void __sparse_cache *vma, size_t size, uint32_t flags)
55+
{
56+
size_t pre_pad_size = (uintptr_t)vma & (PAGE_SZ - 1);
57+
void *aligned_vma = (__sparse_force uint8_t *)vma - pre_pad_size;
58+
59+
return sys_mm_drv_map_region(aligned_vma, POINTER_TO_UINT(NULL),
60+
ALIGN_UP(pre_pad_size + size, PAGE_SZ), flags);
61+
}
62+
63+
static int lib_manager_align_unmap(void __sparse_cache *vma, size_t size)
64+
{
65+
size_t pre_pad_size = (uintptr_t)vma & (PAGE_SZ - 1);
66+
void *aligned_vma = (__sparse_force uint8_t *)vma - pre_pad_size;
67+
68+
return sys_mm_drv_unmap_region(aligned_vma, ALIGN_UP(pre_pad_size + size, PAGE_SZ));
69+
}
70+
5471
static int lib_manager_load_data_from_storage(void __sparse_cache *vma, void *s_addr,
55-
uint32_t size, uint32_t flags)
72+
size_t size, uint32_t flags)
5673
{
57-
int ret = sys_mm_drv_map_region((__sparse_force void *)vma, POINTER_TO_UINT(NULL),
58-
size, flags);
59-
if (ret < 0)
74+
int ret = lib_manager_align_map(vma, size, flags);
75+
76+
if (ret < 0) {
77+
tr_err(&lib_manager_tr, "cannot map %u of %p", size, (__sparse_force void *)vma);
6078
return ret;
79+
}
6180

6281
ret = memcpy_s((__sparse_force void *)vma, size, s_addr, size);
6382
if (ret < 0)
6483
return ret;
6584

85+
/* Some data can be accessed as uncached, in fact that's the default */
86+
/* Both D- and I-caches have been invalidated */
6687
dcache_writeback_region(vma, size);
6788

6889
/* TODO: Change attributes for memory to FLAGS */
@@ -172,9 +193,9 @@ static int lib_manager_load_module(uint32_t module_id, struct sof_man_module *mo
172193
return 0;
173194

174195
e_rodata:
175-
sys_mm_drv_unmap_region((__sparse_force void *)va_base_rodata, st_rodata_size);
196+
lib_manager_align_unmap(va_base_rodata, st_rodata_size);
176197
e_text:
177-
sys_mm_drv_unmap_region((__sparse_force void *)va_base_text, st_text_size);
198+
lib_manager_align_unmap(va_base_text, st_text_size);
178199

179200
return ret;
180201
}
@@ -194,11 +215,11 @@ static int lib_manager_unload_module(uint32_t module_id, struct sof_man_module *
194215
st_text_size = st_text_size * PAGE_SZ;
195216
st_rodata_size = st_rodata_size * PAGE_SZ;
196217

197-
ret = sys_mm_drv_unmap_region((__sparse_force void *)va_base_text, st_text_size);
218+
ret = lib_manager_align_unmap(va_base_text, st_text_size);
198219
if (ret < 0)
199220
return ret;
200221

201-
ret = sys_mm_drv_unmap_region((__sparse_force void *)va_base_rodata, st_rodata_size);
222+
ret = lib_manager_align_unmap(va_base_rodata, st_rodata_size);
202223
if (ret < 0)
203224
return ret;
204225

@@ -229,7 +250,7 @@ static void __sparse_cache *lib_manager_get_instance_bss_address(uint32_t module
229250
static int lib_manager_allocate_module_instance(uint32_t module_id, uint32_t instance_id,
230251
uint32_t is_pages, struct sof_man_module *mod)
231252
{
232-
uint32_t bss_size =
253+
size_t bss_size =
233254
(mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length / mod->instance_max_count)
234255
* PAGE_SZ;
235256
void __sparse_cache *va_base = lib_manager_get_instance_bss_address(module_id,
@@ -242,11 +263,8 @@ static int lib_manager_allocate_module_instance(uint32_t module_id, uint32_t ins
242263
return -ENOMEM;
243264
}
244265

245-
/*
246-
* Map bss memory and clear it.
247-
*/
248-
if (sys_mm_drv_map_region((__sparse_force void *)va_base, POINTER_TO_UINT(NULL),
249-
bss_size, SYS_MM_MEM_PERM_RW) < 0)
266+
/* Map bss memory and clear it. */
267+
if (lib_manager_align_map(va_base, bss_size, SYS_MM_MEM_PERM_RW) < 0)
250268
return -ENOMEM;
251269

252270
memset((__sparse_force void *)va_base, 0, bss_size);
@@ -257,15 +275,14 @@ static int lib_manager_allocate_module_instance(uint32_t module_id, uint32_t ins
257275
static int lib_manager_free_module_instance(uint32_t module_id, uint32_t instance_id,
258276
struct sof_man_module *mod)
259277
{
260-
uint32_t bss_size =
278+
size_t bss_size =
261279
(mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length / mod->instance_max_count)
262280
* PAGE_SZ;
263281
void __sparse_cache *va_base = lib_manager_get_instance_bss_address(module_id,
264282
instance_id, mod);
265-
/*
266-
* Unmap bss memory.
267-
*/
268-
return sys_mm_drv_unmap_region((__sparse_force void *)va_base, bss_size);
283+
284+
/* Unmap bss memory. */
285+
return lib_manager_align_unmap(va_base, bss_size);
269286
}
270287

271288
uint32_t lib_manager_allocate_module(const struct comp_driver *drv,

0 commit comments

Comments
 (0)