diff --git a/src/audio/mux/mux.c b/src/audio/mux/mux.c index bd2ae7d5c7d1..8d65b2b2698d 100644 --- a/src/audio/mux/mux.c +++ b/src/audio/mux/mux.c @@ -475,7 +475,7 @@ static const struct module_interface demux_interface = { DECLARE_MODULE_ADAPTER(demux_interface, demux_uuid, demux_tr); SOF_MODULE_INIT(demux, sys_comp_module_demux_interface_init); -#if CONFIG_COMP_VOLUME_MODULE +#if CONFIG_COMP_MUX_MODULE /* modular: llext dynamic link */ #include @@ -486,13 +486,21 @@ SOF_MODULE_INIT(demux, sys_comp_module_demux_interface_init); 0xE2, 0xA2, 0xF4, 0x2E, 0x30, 0x69 SOF_LLEXT_MOD_ENTRY(mux, &mux_interface); -#define UUID_DEMUX 0x68, 0x68, 0xB2, 0xC4, 0x30, 0x14, 0x0E, 0x47, 0x89, 0xA0, \ - 0x15, 0xD1, 0xC7, 0x7F, 0x85, 0x1A -SOF_LLEXT_MOD_ENTRY(demux, &demux_interface); +/* + * The demux entry is removed because mtl.toml doesn't have an entry + * for it. Once that is fixed, the manifest line below can be + * re-activated: + * #define UUID_DEMUX 0x68, 0x68, 0xB2, 0xC4, 0x30, 0x14, 0x0E, 0x47, 0x89, 0xA0, \ + * 0x15, 0xD1, 0xC7, 0x7F, 0x85, 0x1A + * SOF_LLEXT_MOD_ENTRY(demux, &demux_interface); + */ static const struct sof_man_module_manifest mod_manifest[] __section(".module") __used = { SOF_LLEXT_MODULE_MANIFEST("MUX", mux_llext_entry, 1, UUID_MUX, 15), - SOF_LLEXT_MODULE_MANIFEST("DEMUX", demux_llext_entry, 1, UUID_DEMUX, 15), + /* + * See comment above for a demux deactivation reason + * SOF_LLEXT_MODULE_MANIFEST("DEMUX", demux_llext_entry, 1, UUID_DEMUX, 15), + */ }; SOF_LLEXT_BUILDINFO; diff --git a/src/include/sof/lib_manager.h b/src/include/sof/lib_manager.h index eb7bc21856d2..ba1f8eadbfb0 100644 --- a/src/include/sof/lib_manager.h +++ b/src/include/sof/lib_manager.h @@ -95,12 +95,18 @@ struct lib_manager_segment_desc { size_t size; }; -struct lib_manager_mod_ctx { - void *base_addr; +struct lib_manager_module { + unsigned int start_idx; const struct sof_man_module_manifest *mod_manifest; struct lib_manager_segment_desc segment[LIB_MANAGER_N_SEGMENTS]; }; +struct lib_manager_mod_ctx { + void *base_addr; + unsigned int n_mod; + struct lib_manager_module *mod; +}; + struct ext_library { struct k_spinlock lock; /* last locking CPU record */ struct lib_manager_mod_ctx *desc[LIB_MANAGER_MAX_LIBS]; diff --git a/src/library_manager/llext_manager.c b/src/library_manager/llext_manager.c index 1644fb36a369..0aaa0797419f 100644 --- a/src/library_manager/llext_manager.c +++ b/src/library_manager/llext_manager.c @@ -37,14 +37,6 @@ #include #include -/* - * FIXME: this definition is copied from tools/rimage/src/include/rimage/manifest.h - * which we cannot easily include here, because it also pulls in - * tools/rimage/src/include/rimage/elf.h which then conflicts with - * zephyr/include/zephyr/llext/elf.h - */ -#define FILE_TEXT_OFFSET_V1_8 0x8000 - LOG_MODULE_DECLARE(lib_manager, CONFIG_SOF_LOG_LEVEL); extern struct tr_ctx lib_manager_tr; @@ -125,24 +117,22 @@ static int llext_manager_load_data_from_storage(const struct llext *ext, } static int llext_manager_load_module(const struct llext *ext, const struct llext_buf_loader *ebl, - uint32_t module_id) + const struct lib_manager_module *mctx) { - struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id); - /* Executable code (.text) */ void __sparse_cache *va_base_text = (void __sparse_cache *) - ctx->segment[LIB_MANAGER_TEXT].addr; - size_t text_size = ctx->segment[LIB_MANAGER_TEXT].size; + mctx->segment[LIB_MANAGER_TEXT].addr; + size_t text_size = mctx->segment[LIB_MANAGER_TEXT].size; /* Read-only data (.rodata and others) */ void __sparse_cache *va_base_rodata = (void __sparse_cache *) - ctx->segment[LIB_MANAGER_RODATA].addr; - size_t rodata_size = ctx->segment[LIB_MANAGER_RODATA].size; + mctx->segment[LIB_MANAGER_RODATA].addr; + size_t rodata_size = mctx->segment[LIB_MANAGER_RODATA].size; /* Writable data (.data, .bss and others) */ void __sparse_cache *va_base_data = (void __sparse_cache *) - ctx->segment[LIB_MANAGER_DATA].addr; - size_t data_size = ctx->segment[LIB_MANAGER_DATA].size; + mctx->segment[LIB_MANAGER_DATA].addr; + size_t data_size = mctx->segment[LIB_MANAGER_DATA].size; /* .bss, should be within writable data above */ void __sparse_cache *bss_addr = (void __sparse_cache *) @@ -201,23 +191,22 @@ static int llext_manager_load_module(const struct llext *ext, const struct llext return ret; } -static int llext_manager_unload_module(uint32_t module_id) +static int llext_manager_unload_module(const struct lib_manager_module *mctx) { - struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id); /* Executable code (.text) */ void __sparse_cache *va_base_text = (void __sparse_cache *) - ctx->segment[LIB_MANAGER_TEXT].addr; - size_t text_size = ctx->segment[LIB_MANAGER_TEXT].size; + mctx->segment[LIB_MANAGER_TEXT].addr; + size_t text_size = mctx->segment[LIB_MANAGER_TEXT].size; /* Read-only data (.rodata, etc.) */ void __sparse_cache *va_base_rodata = (void __sparse_cache *) - ctx->segment[LIB_MANAGER_RODATA].addr; - size_t rodata_size = ctx->segment[LIB_MANAGER_RODATA].size; + mctx->segment[LIB_MANAGER_RODATA].addr; + size_t rodata_size = mctx->segment[LIB_MANAGER_RODATA].size; /* Writable data (.data, .bss, etc.) */ void __sparse_cache *va_base_data = (void __sparse_cache *) - ctx->segment[LIB_MANAGER_DATA].addr; - size_t data_size = ctx->segment[LIB_MANAGER_DATA].size; + mctx->segment[LIB_MANAGER_DATA].addr; + size_t data_size = mctx->segment[LIB_MANAGER_DATA].size; int err = 0, ret; ret = llext_manager_align_unmap(va_base_text, text_size); @@ -240,15 +229,14 @@ static bool llext_manager_section_detached(const elf_shdr_t *shdr) return shdr->sh_addr < SOF_MODULE_DRAM_LINK_END; } -static int llext_manager_link(struct llext_buf_loader *ebl, - const char *name, uint32_t module_id, struct module_data *md, +static int llext_manager_link(struct llext_buf_loader *ebl, const char *name, + struct lib_manager_module *mctx, struct module_data *md, const void **buildinfo, const struct sof_man_module_manifest **mod_manifest) { - struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id); /* Identify if this is the first time loading this module */ struct llext_load_param ldr_parm = { - .relocate_local = !ctx->segment[LIB_MANAGER_TEXT].size, + .relocate_local = !mctx->segment[LIB_MANAGER_TEXT].size, .pre_located = true, .section_detached = llext_manager_section_detached, }; @@ -257,30 +245,30 @@ static int llext_manager_link(struct llext_buf_loader *ebl, if (ret) return ret; - ctx->segment[LIB_MANAGER_TEXT].addr = ebl->loader.sects[LLEXT_MEM_TEXT].sh_addr; - ctx->segment[LIB_MANAGER_TEXT].size = ebl->loader.sects[LLEXT_MEM_TEXT].sh_size; + mctx->segment[LIB_MANAGER_TEXT].addr = ebl->loader.sects[LLEXT_MEM_TEXT].sh_addr; + mctx->segment[LIB_MANAGER_TEXT].size = ebl->loader.sects[LLEXT_MEM_TEXT].sh_size; tr_dbg(&lib_manager_tr, ".text: start: %#lx size %#x", - ctx->segment[LIB_MANAGER_TEXT].addr, - ctx->segment[LIB_MANAGER_TEXT].size); + mctx->segment[LIB_MANAGER_TEXT].addr, + mctx->segment[LIB_MANAGER_TEXT].size); /* All read-only data sections */ - ctx->segment[LIB_MANAGER_RODATA].addr = + mctx->segment[LIB_MANAGER_RODATA].addr = ebl->loader.sects[LLEXT_MEM_RODATA].sh_addr; - ctx->segment[LIB_MANAGER_RODATA].size = ebl->loader.sects[LLEXT_MEM_RODATA].sh_size; + mctx->segment[LIB_MANAGER_RODATA].size = ebl->loader.sects[LLEXT_MEM_RODATA].sh_size; tr_dbg(&lib_manager_tr, ".rodata: start: %#lx size %#x", - ctx->segment[LIB_MANAGER_RODATA].addr, - ctx->segment[LIB_MANAGER_RODATA].size); + mctx->segment[LIB_MANAGER_RODATA].addr, + mctx->segment[LIB_MANAGER_RODATA].size); /* All writable data sections */ - ctx->segment[LIB_MANAGER_DATA].addr = + mctx->segment[LIB_MANAGER_DATA].addr = ebl->loader.sects[LLEXT_MEM_DATA].sh_addr; - ctx->segment[LIB_MANAGER_DATA].size = ebl->loader.sects[LLEXT_MEM_DATA].sh_size; + mctx->segment[LIB_MANAGER_DATA].size = ebl->loader.sects[LLEXT_MEM_DATA].sh_size; tr_dbg(&lib_manager_tr, ".data: start: %#lx size %#x", - ctx->segment[LIB_MANAGER_DATA].addr, - ctx->segment[LIB_MANAGER_DATA].size); + mctx->segment[LIB_MANAGER_DATA].addr, + mctx->segment[LIB_MANAGER_DATA].size); ssize_t binfo_o = llext_find_section(&ebl->loader, ".mod_buildinfo"); @@ -295,35 +283,131 @@ static int llext_manager_link(struct llext_buf_loader *ebl, return binfo_o >= 0 && mod_o >= 0 ? 0 : -EPROTO; } +static int llext_manager_mod_init(struct lib_manager_mod_ctx *ctx, + const struct sof_man_fw_desc *desc, + const struct sof_man_module *mod_array) +{ + unsigned int i, n_mod; + size_t offs; + + /* count modules */ + for (i = 0, n_mod = 0, offs = ~0; i < desc->header.num_module_entries; i++) + if (mod_array[i].segment[LIB_MANAGER_TEXT].file_offset != offs) { + offs = mod_array[i].segment[LIB_MANAGER_TEXT].file_offset; + n_mod++; + } + + /* + * Loadable modules are loaded to DRAM once and never unloaded from it. + * Context, related to them, is never freed + */ + ctx->mod = rmalloc(SOF_MEM_ZONE_RUNTIME_SHARED, SOF_MEM_FLAG_COHERENT, + SOF_MEM_CAPS_RAM, n_mod * sizeof(ctx->mod[0])); + if (!ctx->mod) + return -ENOMEM; + + ctx->n_mod = n_mod; + + for (i = 0, n_mod = 0, offs = ~0; i < desc->header.num_module_entries; i++) + if (mod_array[i].segment[LIB_MANAGER_TEXT].file_offset != offs) { + offs = mod_array[i].segment[LIB_MANAGER_TEXT].file_offset; + ctx->mod[n_mod].segment[LIB_MANAGER_TEXT].size = 0; + ctx->mod[n_mod++].start_idx = i; + } + + return 0; +} + +static unsigned int llext_manager_mod_find(const struct lib_manager_mod_ctx *ctx, unsigned int idx) +{ + unsigned int i; + + for (i = 0; i < ctx->n_mod; i++) + if (ctx->mod[i].start_idx > idx) + break; + + return i - 1; +} + uintptr_t llext_manager_allocate_module(struct processing_module *proc, const struct comp_ipc_config *ipc_config, const void *ipc_specific_config) { uint32_t module_id = IPC4_MOD_ID(ipc_config->id); struct sof_man_fw_desc *desc = (struct sof_man_fw_desc *)lib_manager_get_library_manifest(module_id); - struct sof_man_module *mod_array; - int ret; - uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id); struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id); - const struct sof_module_api_build_info *buildinfo; + + if (!ctx || !desc) { + tr_err(&lib_manager_tr, "failed to get module descriptor"); + return 0; + } + + struct sof_man_module *mod_array = (struct sof_man_module *)((char *)desc + + SOF_MAN_MODULE_OFFSET(0)); + uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id); + size_t mod_offset = mod_array[entry_index].segment[LIB_MANAGER_TEXT].file_offset; const struct sof_man_module_manifest *mod_manifest; - size_t mod_size = desc->header.preload_page_count * PAGE_SZ - FILE_TEXT_OFFSET_V1_8; - uintptr_t dram_base = (uintptr_t)desc - SOF_MAN_ELF_TEXT_OFFSET; - struct llext_buf_loader ebl = LLEXT_BUF_LOADER((uint8_t *)dram_base + FILE_TEXT_OFFSET_V1_8, - mod_size); + const struct sof_module_api_build_info *buildinfo; struct module_data *md = &proc->priv; + size_t mod_size; + int i, inst_idx; + int ret; tr_dbg(&lib_manager_tr, "mod_id: %#x", ipc_config->id); - if (!ctx || !desc) { - tr_err(&lib_manager_tr, "failed to get module descriptor"); + if (!ctx->mod) + llext_manager_mod_init(ctx, desc, mod_array); + + if (entry_index >= desc->header.num_module_entries) { + tr_err(&lib_manager_tr, "Invalid driver index %u exceeds %d", + entry_index, desc->header.num_module_entries - 1); return 0; } - mod_array = (struct sof_man_module *)((char *)desc + SOF_MAN_MODULE_OFFSET(0)); + unsigned int mod_idx = llext_manager_mod_find(ctx, entry_index); + struct lib_manager_module *mctx = ctx->mod + mod_idx; + + /* + * We don't know the number of ELF files that this library is built of. + * We know the number of module drivers, but each of those ELF files can + * also contain multiple such drivers. Each driver brings two copies of + * its manifest with it: one in the ".module" ELF section and one in an + * array of manifests at the beginning of the library. This latter array + * is created from a TOML configuration file. The order is preserved - + * this is guaranteed by rimage. + * All module drivers within a single ELF file have equal .file_offset, + * this makes it possible to find borders between them. + * We know the global index of the requested driver in that array, but + * we need to find the matching manifest in ".module" because only it + * contains the entry point. For safety we calculate the ELF driver + * index and then also check the driver name. + * We also need the driver size. For this we search the manifest array + * for the next ELF file, then the difference between offsets gives us + * the driver size. + */ + for (i = entry_index - 1; i >= 0; i--) + if (mod_array[i].segment[LIB_MANAGER_TEXT].file_offset != mod_offset) + break; + + /* Driver index within a single module */ + inst_idx = entry_index - i - 1; + + /* Find the next module or stop at the end */ + for (i = entry_index + 1; i < desc->header.num_module_entries; i++) + if (mod_array[i].segment[LIB_MANAGER_TEXT].file_offset != mod_offset) + break; - /* LLEXT linking is only needed once for all the modules in the library */ - ret = llext_manager_link(&ebl, mod_array[0].name, module_id, md, + if (i == desc->header.num_module_entries) + mod_size = desc->header.preload_page_count * PAGE_SZ - mod_offset; + else + mod_size = ALIGN_UP(mod_array[i].segment[LIB_MANAGER_TEXT].file_offset - mod_offset, + PAGE_SZ); + + uintptr_t dram_base = (uintptr_t)desc - SOF_MAN_ELF_TEXT_OFFSET; + struct llext_buf_loader ebl = LLEXT_BUF_LOADER((uint8_t *)dram_base + mod_offset, mod_size); + + /* LLEXT linking is only needed once for all the drivers in each module */ + ret = llext_manager_link(&ebl, mod_array[entry_index - inst_idx].name, mctx, md, (const void **)&buildinfo, &mod_manifest); if (ret < 0) { tr_err(&lib_manager_tr, "linking failed: %d", ret); @@ -339,26 +423,43 @@ uintptr_t llext_manager_allocate_module(struct processing_module *proc, } /* Map executable code and data */ - ret = llext_manager_load_module(md->llext, &ebl, module_id); + ret = llext_manager_load_module(md->llext, &ebl, mctx); if (ret < 0) return 0; - /* ctx->mod_manifest points to a const array of module manifests */ - ctx->mod_manifest = mod_manifest; + /* mctx->mod_manifest points to a const array of module manifests */ + mctx->mod_manifest = mod_manifest; } - return ctx->mod_manifest[entry_index].module.entry_point; + if (strncmp(mod_array[entry_index].name, mctx->mod_manifest[inst_idx].module.name, + sizeof(mod_array[0].name))) { + tr_err(&lib_manager_tr, "Name mismatch %s vs. %s", + mod_array[entry_index].name, mctx->mod_manifest[inst_idx].module.name); + return 0; + } + + return mctx->mod_manifest[inst_idx].module.entry_point; } int llext_manager_free_module(const uint32_t component_id) { const uint32_t module_id = IPC4_MOD_ID(component_id); - const unsigned int base_module_id = LIB_MANAGER_GET_LIB_ID(module_id) << - LIB_MANAGER_LIB_ID_SHIFT; + struct sof_man_fw_desc *desc = (struct sof_man_fw_desc *)lib_manager_get_library_manifest(module_id); + struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id); + uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id); + + if (entry_index >= desc->header.num_module_entries) { + tr_err(&lib_manager_tr, "Invalid driver index %u exceeds %d", + entry_index, desc->header.num_module_entries - 1); + return -ENOENT; + } + + unsigned int mod_idx = llext_manager_mod_find(ctx, entry_index); + struct lib_manager_module *mctx = ctx->mod + mod_idx; tr_dbg(&lib_manager_tr, "mod_id: %#x", component_id); - return llext_manager_unload_module(base_module_id); + return llext_manager_unload_module(mctx); } bool comp_is_llext(struct comp_dev *comp) diff --git a/tools/rimage/src/manifest.c b/tools/rimage/src/manifest.c index 52b328e85ca7..88d37df73c67 100644 --- a/tools/rimage/src/manifest.c +++ b/tools/rimage/src/manifest.c @@ -195,29 +195,11 @@ static int man_copy_elf_sections(struct image *image, struct manifest_module *mo return 0; } -static int man_get_module_manifest(struct image *image, struct manifest_module *module, - struct sof_man_module *man_module) +static void man_get_section_manifest(struct image *image, + const struct sof_man_module_manifest *sof_mod, + struct sof_man_module *man_module) { - struct elf_section section; struct sof_man_segment_desc *segment; - const struct sof_man_module_manifest *sof_mod; - int ret; - - fprintf(stdout, "Module Write: %s\n", module->file.elf.filename); - - /* load in module manifest data */ - ret = elf_section_read_by_name(&module->file.elf, ".module", §ion); - if (ret) { - fprintf(stderr, "error: can't read module manifest from '.module' section.\n"); - return ret; - } - - if (sizeof(*sof_mod) > section.header.data.size) { - fprintf(stderr, "error: Invalid module manifest in '.module' section.\n"); - ret = -ENODATA; - goto error; - } - sof_mod = section.data; /* configure man_module with sofmod data */ memcpy(man_module->struct_id, "$AME", 4); @@ -225,14 +207,12 @@ static int man_get_module_manifest(struct image *image, struct manifest_module * memcpy(man_module->name, sof_mod->module.name, SOF_MAN_MOD_NAME_LEN); memcpy(man_module->uuid, sof_mod->module.uuid, 16); man_module->affinity_mask = sof_mod->module.affinity_mask; + man_module->instance_max_count = sof_mod->module.instance_max_count; man_module->type.auto_start = sof_mod->module.type.auto_start; man_module->type.domain_dp = sof_mod->module.type.domain_dp; man_module->type.domain_ll = sof_mod->module.type.domain_ll; man_module->type.load_type = sof_mod->module.type.load_type; - /* read out text_fixup_size from memory mapping */ - module->text_fixup_size = sof_mod->text_size; - /* text segment */ segment = &man_module->segment[SOF_MAN_SEGMENT_TEXT]; segment->flags.r.contents = 1; @@ -257,6 +237,35 @@ static int man_get_module_manifest(struct image *image, struct manifest_module * segment->flags.r.type = SOF_MAN_SEGMENT_BSS; fprintf(stdout, " Entry point 0x%8.8x\n", man_module->entry_point); +} + +static int man_get_module_manifest(struct image *image, struct manifest_module *module, + struct sof_man_module *man_module) +{ + struct elf_section section; + const struct sof_man_module_manifest *sof_mod; + int ret; + + fprintf(stdout, "Module Write: %s\n", module->file.elf.filename); + + /* load in module manifest data */ + ret = elf_section_read_by_name(&module->file.elf, ".module", §ion); + if (ret) { + fprintf(stderr, "error: can't read module manifest from '.module' section.\n"); + return ret; + } + + if (sizeof(*sof_mod) > section.header.data.size) { + fprintf(stderr, "error: Invalid module manifest in '.module' section.\n"); + ret = -ENODATA; + goto error; + } + + sof_mod = section.data; + man_get_section_manifest(image, sof_mod, man_module); + + /* read out text_fixup_size from memory mapping */ + module->text_fixup_size = sof_mod->text_size; error: elf_section_free(§ion); @@ -449,23 +458,12 @@ static int man_module_create(struct image *image, struct manifest_module *module return 0; } -static int man_module_create_reloc(struct image *image, struct manifest_module *module, - struct sof_man_module *man_module) +static void man_module_fill_reloc(const struct manifest_module *module, + struct sof_man_module *man_module) { - /* create module and segments */ - int err; - - image->image_end = 0; - - err = man_get_module_manifest(image, module, man_module); - if (err < 0) - return err; - /* stack size ??? convert sizes to PAGES */ man_module->instance_bss_size = 1; - module_print_zones(&module->file); - /* main module */ /* text section is first */ man_module->segment[SOF_MAN_SEGMENT_TEXT].file_offset = @@ -483,6 +481,67 @@ static int man_module_create_reloc(struct image *image, struct manifest_module * man_module->segment[SOF_MAN_SEGMENT_BSS].file_offset = 0; man_module->segment[SOF_MAN_SEGMENT_BSS].v_base_addr = 0; man_module->segment[SOF_MAN_SEGMENT_BSS].flags.r.length = 0; +} + +static int man_module_create_reloc(struct image *image, struct manifest_module *module, + struct sof_man_module **man_module) +{ + /* create module and segments */ + const struct sof_man_module_manifest *sof_mod; + struct elf_section section; + int err; + + /* load in module manifest data */ + err = elf_section_read_by_name(&module->file.elf, ".module", §ion); + if (err) { + fprintf(stderr, "error: can't read module manifest from '.module' section.\n"); + return err; + } + + unsigned int n_mod = section.header.data.size / sizeof(*sof_mod); + + if (!n_mod || n_mod * sizeof(*sof_mod) != section.header.data.size) { + fprintf(stderr, "error: Invalid module manifests in '.module' section.\n"); + return -ENOEXEC; + } + + unsigned int i; + + for (i = 0, sof_mod = section.data; i < n_mod; i++, sof_mod++) { + char name[SOF_MAN_MOD_NAME_LEN + 1]; + unsigned int j; + + strncpy(name, (char *)sof_mod->module.name, SOF_MAN_MOD_NAME_LEN); + + for (j = 0; j < image->adsp->modules->mod_man_count; j++) { + if (!strncmp(name, (char *)image->adsp->modules->mod_man[j].name, + SOF_MAN_MOD_NAME_LEN)) { + /* Found a TOML manifest, matching ELF */ + if (i) + (*man_module)++; + /* Use manifest created using toml files as template */ + **man_module = image->adsp->modules->mod_man[j]; + /* Use .manifest to update individual fields */ + man_get_section_manifest(image, sof_mod, *man_module); + man_module_fill_reloc(module, *man_module); + break; + } + } + + if (j == image->adsp->modules->mod_man_count) { + fprintf(stderr, "error: cannot find %s in manifest.\n", name); + return -ENOEXEC; + } + } + + elf_section_free(§ion); + + module_print_zones(&module->file); + + image->image_end = module->foffset + module->file.elf.file_size; + + /* round module end up to nearest page */ + image->image_end = ALIGN_UP(image->image_end, MAN_PAGE_SIZE); fprintf(stdout, "\tNo\tAddress\t\tSize\t\tFile\tType\n"); @@ -496,15 +555,11 @@ static int man_module_create_reloc(struct image *image, struct manifest_module * 0, module->file.elf.file_size, 0, "DATA"); fprintf(stdout, "\n"); - image->image_end = module->foffset + module->file.elf.file_size; - - /* round module end up to nearest page */ - image->image_end = ALIGN_UP(image->image_end, MAN_PAGE_SIZE); fprintf(stdout, " Total pages text %d data %d bss %d module file limit: 0x%x\n\n", - man_module->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length, - man_module->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length, - man_module->segment[SOF_MAN_SEGMENT_BSS].flags.r.length, + (*man_module)->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length, + (*man_module)->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length, + (*man_module)->segment[SOF_MAN_SEGMENT_BSS].flags.r.length, image->image_end); return 0; } @@ -581,16 +636,11 @@ static int man_create_modules(struct image *image, struct sof_man_fw_desc *desc, offset = 1; } - for (; i < image->num_modules; i++) { - man_module = (void *)desc + SOF_MAN_MODULE_OFFSET(i - offset); - - /* Some platforms dont have modules configuration in toml file */ - if (image->adsp->modules) { - /* Use manifest created using toml files as template */ - assert(i < image->adsp->modules->mod_man_count); - memcpy(man_module, &image->adsp->modules->mod_man[i], sizeof(*man_module)); - } + image->image_end = 0; + for (man_module = (struct sof_man_module *)((uint8_t *)desc + SOF_MAN_MODULE_OFFSET(i - offset)); + i < image->num_modules; + i++, man_module++) { module = &image->module[i]; if (i == 0) @@ -598,11 +648,19 @@ static int man_create_modules(struct image *image, struct sof_man_fw_desc *desc, else module->foffset = image->image_end; - if (image->reloc) - err = man_module_create_reloc(image, module, - man_module); - else + if (image->reloc) { + err = man_module_create_reloc(image, module, &man_module); + } else { + /* Some platforms don't have modules configuration in toml file */ + if (image->adsp->modules) { + /* Use manifest created using toml files as template */ + assert(i < image->adsp->modules->mod_man_count); + memcpy(man_module, &image->adsp->modules->mod_man[i], + sizeof(*man_module)); + } + err = man_module_create(image, module, man_module); + } if (err < 0) return err; @@ -622,12 +680,15 @@ static void man_create_modules_in_config(struct image *image, struct sof_man_fw_ if (!modules) return; - /* skip modules passed as parameters. Their manifests have already been copied by the - * man_create_modules function. */ - for (i = image->num_modules; i < modules->mod_man_count; i++) { - man_module = (void *)desc + SOF_MAN_MODULE_OFFSET(i); - memcpy(man_module, &modules->mod_man[i], sizeof(*man_module)); - } + if (!image->loadable_module) + /* skip modules passed as parameters. Their manifests have + * already been copied by the man_create_modules function. */ + for (i = image->num_modules; i < modules->mod_man_count; i++) { + man_module = (void *)desc + SOF_MAN_MODULE_OFFSET(i); + memcpy(man_module, &modules->mod_man[i], sizeof(*man_module)); + } + else + i = modules->mod_man_count; /* We need to copy the configurations for all modules. */ cfg_start = (void *)desc + SOF_MAN_MODULE_OFFSET(i);