diff --git a/rimage/CMakeLists.txt b/rimage/CMakeLists.txt index dc5d3ac794f8..abc32f69c25f 100644 --- a/rimage/CMakeLists.txt +++ b/rimage/CMakeLists.txt @@ -32,6 +32,7 @@ add_executable(rimage hash.c pkcs1_5.c manifest.c + ext_manifest.c elf.c rimage.c ) diff --git a/rimage/elf.c b/rimage/elf.c index a00ab7452efb..589fc09a0cf2 100644 --- a/rimage/elf.c +++ b/rimage/elf.c @@ -470,11 +470,11 @@ int elf_validate_modules(struct image *image) return 0; } -int elf_find_section(struct image *image, struct module *module, +int elf_find_section(const struct image *image, const struct module *module, const char *name) { - Elf32_Ehdr *hdr = &module->hdr; - Elf32_Shdr *section, *s; + const Elf32_Ehdr *hdr = &module->hdr; + const Elf32_Shdr *section, *s; char *buffer; size_t count; int ret, i; diff --git a/rimage/ext_manifest.c b/rimage/ext_manifest.c new file mode 100644 index 000000000000..329a25f90e1f --- /dev/null +++ b/rimage/ext_manifest.c @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2020 Intel Corporation. All rights reserved. +// +// Author: Karol Trzcinski + +#include +#include +#include +#include + +#include "kernel/ext_manifest.h" +#include "ext_manifest.h" +#include "ipc/info.h" +#include "rimage.h" + +const struct ext_man_header ext_man_template = { + .magic = EXT_MAN_MAGIC_NUMBER, + .header_version = EXT_MAN_VERSION, + .header_size = sizeof(struct ext_man_header), + .full_size = 0, /* runtime variable */ +}; + +static int ext_man_open_file(struct image *image) +{ + /* open extended manifest outfile for writing */ + sprintf(image->out_ext_man_file, "%s.xman", image->out_file); + unlink(image->out_ext_man_file); + + image->out_ext_man_fd = fopen(image->out_ext_man_file, "wb"); + if (!image->out_ext_man_fd) { + fprintf(stderr, "error: unable to open %s for writing %d\n", + image->out_ext_man_file, errno); + return errno; + } + + return 0; +} + +static struct module *ext_man_get_module(struct image *image) +{ + struct module *module; + int i; + + for (i = image->num_modules > 1 ? 1 : 0; i < image->num_modules; i++) { + module = &image->module[i]; + + if (elf_find_section(image, module, ".fw_metadata") > 0) + return module; + } + + return NULL; +} + +static int ext_man_validate(uint32_t section_size, const void *section_data) +{ + uint8_t *sbuf = (uint8_t *)section_data; + struct ext_man_elem_header head; + uint32_t offset = 0; + + /* copy each head to local struct to omit memory align issues */ + while (offset < section_size) { + memcpy(&head, &sbuf[offset], sizeof(head)); + fprintf(stdout, "Extended manifest found module, type: 0x%04X size: 0x%04X (%4d) offset: 0x%04X\n", + head.type, head.elem_size, head.elem_size, offset); + if (head.elem_size == 0 || head.elem_size % EXT_MAN_ALIGN) { + fprintf(stderr, + "error: invalid extended manifest element size\n"); + return -EINVAL; + } + offset += head.elem_size; + } + + /* sum of packets size != section size */ + if (offset != section_size) { + fprintf(stderr, + "error: fw_metadata section is inconsistent, section size: 0x%04X != 0x%04X sum of packets size\n", + section_size, offset); + return -EINVAL; + } else { + return 0; + } +} + +static int ext_man_build(const struct image *image, const struct module *module, + struct ext_man_header **dst_buff) +{ + struct ext_man_header ext_man; + const Elf32_Shdr *section; + uint8_t *buffer = NULL; + int fw_metadata_index; + size_t offset; + size_t read; + int ret = 0; + + /* find .fw_metadata section */ + fw_metadata_index = elf_find_section(image, module, ".fw_metadata"); + if (fw_metadata_index < 0) { + fprintf(stderr, "error: unable to find .fw_metadata section: %d\n", + fw_metadata_index); + ret = fw_metadata_index; + goto out; + } + section = &module->section[fw_metadata_index]; + + /* fill ext_man, size aligned to 4 to avoid unaligned accesses */ + memcpy(&ext_man, &ext_man_template, sizeof(struct ext_man_header)); + ext_man.full_size = ext_man.header_size; + ext_man.full_size += section->size; + if (ext_man.full_size % 4) { + fprintf(stderr, + "error: extended manifest size must be aligned to 4\n"); + ret = -EINVAL; + goto out; + } + + /* alloc buffer for ext_man */ + buffer = calloc(1, ext_man.full_size); + if (!buffer) { + ret = -ENOMEM; + goto out; + } + + /* fill buffer with ext_man header and section content */ + memcpy(buffer, &ext_man, ext_man.header_size); + offset = ext_man.header_size; + + fseek(module->fd, section->off, SEEK_SET); + read = fread(buffer + offset, 1, section->size, module->fd); + if (read != section->size) { + fprintf(stderr, + "error: can't read fw_metadata section %d\n", + -errno); + free(buffer); + ret = -errno; + } + + *dst_buff = (struct ext_man_header *)buffer; + +out: + return ret; +} + +int ext_man_write(struct image *image) +{ + struct ext_man_header *ext_man = NULL; + struct module *module; + int count; + int ret; + + module = ext_man_get_module(image); + if (!module) { + fprintf(stderr, "error: firmware metadata section not found\n"); + ret = -EINVAL; + goto out; + } + + ret = ext_man_open_file(image); + if (ret) + goto out; + + ret = ext_man_build(image, module, &ext_man); + if (ret) + goto out; + + /* validate metadata section */ + ret = ext_man_validate(ext_man->full_size - ext_man->header_size, + (char *)ext_man + ext_man->header_size); + if (ret) { + ret = -errno; + goto out; + } + + /* write extended metadata to file */ + count = fwrite(ext_man, 1, ext_man->full_size, image->out_ext_man_fd); + + if (count != ext_man->full_size) { + fprintf(stderr, + "error: can't write extended manifest to file %d\n", + -errno); + ret = -errno; + goto out; + } + + fprintf(stdout, "Extended manifest saved to file %s size 0x%04X (%d) bytes\n\n", + image->out_ext_man_file, ext_man->full_size, + ext_man->full_size); + +out: + if (ext_man) + free(ext_man); + if (image->out_ext_man_fd) + fclose(image->out_ext_man_fd); + return ret; +} diff --git a/rimage/ext_manifest.h b/rimage/ext_manifest.h new file mode 100644 index 000000000000..16bebcf87f69 --- /dev/null +++ b/rimage/ext_manifest.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2020 Intel Corporation. All rights reserved. + * + * Author: Karol Trzcinski + */ + +/* + * Extended manifest is a place to store metadata about firmware, known during + * compilation time - for example firmware version or used compiler. + * Given information are read on host side before firmware startup. + * This part of output binary is not signed. + * + * To add new content to ext_man, in firmware code define struct which starts + * with ext_man_elem_head followed by usage dependent content and place whole + * struct in "fw_metadata" section. Moreover kernel code should be modified to + * properly read new packet. + * + * Extended manifest designed to be extensible. In header there is a field which + * describe header length, so after appending some data to header then it can be + * easily skipped by device with older version of this header. + * From other side, unknown ext_man elements should be just skipped by host, + * to be backward compatible. Field ext_man_elem_header.elem_size should be + * used in such a situation. + */ + +#ifndef __EXT_MAN_H__ +#define __EXT_MAN_H__ + +#include "rimage.h" + +int ext_man_write(struct image *image); + +#endif /* __EXT_MAN_H__ */ diff --git a/rimage/file_simple.c b/rimage/file_simple.c index 06ce7732e5f4..46f52b09fbd2 100644 --- a/rimage/file_simple.c +++ b/rimage/file_simple.c @@ -194,10 +194,16 @@ static int simple_write_module(struct image *image, struct module *module) if (!(module->section[i].flags & valid)) continue; + if (section->vaddr == 0) + continue; + /* dont write bss */ if (section->type == SHT_NOBITS) continue; + if (section->type == SHT_NOBITS) + continue; + err = write_block(image, module, section); if (err < 0) { fprintf(stderr, "error: failed to write section #%d\n", diff --git a/rimage/rimage.c b/rimage/rimage.c index f5997fd1d750..0144132fc781 100644 --- a/rimage/rimage.c +++ b/rimage/rimage.c @@ -8,6 +8,7 @@ #include #include +#include "ext_manifest.h" #include "rimage.h" #include "file_format.h" #include "manifest.h" @@ -150,6 +151,18 @@ int main(int argc, char *argv[]) ret = image.adsp->write_firmware_meu(&image); else ret = image.adsp->write_firmware(&image); + if (ret) { + fprintf(stderr, "error: unable to write firmware, %d\n", + errno); + goto out; + } + + ret = ext_man_write(&image); + if (ret) { + fprintf(stderr, "error: unable to write extended manifest, %d\n", + errno); + goto out; + } out: /* close files */ diff --git a/rimage/rimage.h b/rimage/rimage.h index c65d116b5526..78a9a3134a43 100644 --- a/rimage/rimage.h +++ b/rimage/rimage.h @@ -115,9 +115,11 @@ struct image { void *rom_image; FILE *out_rom_fd; FILE *out_man_fd; + FILE *out_ext_man_fd; FILE *out_unsigned_fd; char out_rom_file[256]; char out_man_file[256]; + char out_ext_man_file[256]; char out_unsigned_file[256]; }; @@ -171,8 +173,8 @@ int elf_parse_module(struct image *image, int module_index, const char *name); void elf_free_module(struct image *image, int module_index); int elf_is_rom(struct image *image, Elf32_Shdr *section); int elf_validate_modules(struct image *image); -int elf_find_section(struct image *image, struct module *module, - const char *name); +int elf_find_section(const struct image *image, const struct module *module, + const char *name); int elf_validate_section(struct image *image, struct module *module, Elf32_Shdr *section, int index); diff --git a/src/arch/xtensa/CMakeLists.txt b/src/arch/xtensa/CMakeLists.txt index e68146a8ea8b..4913d1bf3dde 100644 --- a/src/arch/xtensa/CMakeLists.txt +++ b/src/arch/xtensa/CMakeLists.txt @@ -441,11 +441,27 @@ else() add_custom_target(run_meu DEPENDS run_rimage) endif() +if(CMAKE_HOST_WIN32) + set(GLUE_CMD copy /b sof-${fw_name}.ri.xman + sof-${fw_name}.ri sof-${fw_name}.ri.temp) +else() + set(GLUE_CMD cat sof-${fw_name}.ri.xman sof-${fw_name}.ri > sof-${fw_name}.ri.temp) +endif() + +add_custom_target( + ext_man_glue ALL + COMMAND ${GLUE_CMD} + COMMAND ${CMAKE_COMMAND} -E copy sof-${fw_name}.ri.temp sof-${fw_name}.ri + COMMAND ${CMAKE_COMMAND} -E remove sof-${fw_name}.ri.temp + DEPENDS run_meu + VERBATIM + USES_TERMINAL +) + add_custom_target( bin ALL COMMAND ${CMAKE_COMMAND} -E copy sof-${fw_name}.ri ${PROJECT_BINARY_DIR}/sof-${fw_name}.ri COMMAND ${CMAKE_COMMAND} -E copy sof-${fw_name}.ldc ${PROJECT_BINARY_DIR}/sof-${fw_name}.ldc - DEPENDS run_meu bin_extras + DEPENDS ext_man_glue bin_extras VERBATIM USES_TERMINAL ) diff --git a/src/include/kernel/ext_manifest.h b/src/include/kernel/ext_manifest.h new file mode 100644 index 000000000000..fb2425ae9312 --- /dev/null +++ b/src/include/kernel/ext_manifest.h @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2020 Intel Corporation. All rights reserved. + * + * Author: Karol Trzcinski + */ + +/* + * Extended manifest is a place to store metadata about firmware, known during + * compilation time - for example firmware version or used compiler. + * Given information are read on host side before firmware startup. + * This part of output binary is not signed. + * + * To add new content to ext_man, in firmware code define struct which starts + * with ext_man_elem_head followed by usage dependent content and place whole + * struct in "fw_metadata" section. Moreover kernel code should be modified to + * properly read new packet. + * + * Extended manifest is designed to be extensible. In header there is a field + * which describe header length, so after appending some data to header then it + * can be easily skipped by device with older version of this header. + * Unknown ext_man elements should be just skipped by host, + * to be backward compatible. Field `ext_man_elem_header.elem_size` should be + * used in such a situation. + */ + +#ifndef __KERNEL_EXT_MANIFEST_H__ +#define __KERNEL_EXT_MANIFEST_H__ + +#include +#include +#include + +/* In ASCII `XMan` */ +#define EXT_MAN_MAGIC_NUMBER 0x6e614d58 + +/* Build u32 number in format MMmmmppp */ +#define EXT_MAN_BUILD_VERSION(MAJOR, MINOR, PATH) ( \ + ((uint32_t)(MAJOR) << 24) | \ + ((uint32_t)(MINOR) << 12) | \ + (uint32_t)(PATH)) + +/* check extended manifest version consistency */ +#define EXT_MAN_VERSION_INCOMPATIBLE(host_ver, cli_ver) ( \ + ((host_ver) & GENMASK(31, 24)) != \ + ((cli_ver) & GENMASK(31, 24))) + +/* used extended manifest header version */ +#define EXT_MAN_VERSION EXT_MAN_BUILD_VERSION(1, 0, 0) + +/* struct size alignment for ext_man elements */ +#define EXT_MAN_ALIGN 16 + +/* extended manifest header, deleting any field breaks backward compatibility */ +struct ext_man_header { + uint32_t magic; /**< identification number, */ + /**< EXT_MAN_MAGIC_NUMBER */ + uint32_t full_size; /**< [bytes] full size of ext_man, */ + /**< (header + content + padding) */ + uint32_t header_size; /**< [bytes] makes header extensionable, */ + /**< after append new field to ext_man header */ + /**< then backward compatible won't be lost */ + uint32_t header_version; /**< value of EXT_MAN_VERSION */ + /**< not related with following content */ + + /* just after this header should be list of ext_man_elem_* elements */ +} __packed; + +/* Now define extended manifest elements */ + +/* Extended manifest elements identificators */ +enum ext_man_elem_type { + EXT_MAN_ELEM_FW_VERSION = 0, +}; + +/* extended manifest element header */ +struct ext_man_elem_header { + uint32_t type; /**< EXT_MAN_ELEM_* */ + uint32_t elem_size; /**< in bytes, including header size */ + + /* just after this header should be type dependent content */ +} __packed; + +/* FW version */ +struct ext_man_fw_version { + struct ext_man_elem_header hdr; + /* use sof_ipc struct because of code re-use */ + struct sof_ipc_fw_version version; + uint32_t flags; +} __packed; + +#endif /* __KERNEL_EXT_MANIFEST_H__ */ diff --git a/src/init/CMakeLists.txt b/src/init/CMakeLists.txt index 17dab5792dd9..31fc44276210 100644 --- a/src/init/CMakeLists.txt +++ b/src/init/CMakeLists.txt @@ -1,3 +1,12 @@ # SPDX-License-Identifier: BSD-3-Clause add_local_sources(sof init.c) + +add_library(ext_manifest STATIC "") + +add_local_sources(ext_manifest + ext_manifest.c) +sof_append_relative_path_definitions(ext_manifest) + +target_link_libraries(ext_manifest sof_options) +target_link_libraries(sof_static_libraries INTERFACE ext_manifest) diff --git a/src/init/ext_manifest.c b/src/init/ext_manifest.c new file mode 100644 index 000000000000..f91424cc7eed --- /dev/null +++ b/src/init/ext_manifest.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2020 Intel Corporation. All rights reserved. +// +// Author: Karol Trzcinski +// + +#include +#include +#include +#include +#include +#include +#include + +const struct ext_man_fw_version ext_man_fw_ver + __aligned(EXT_MAN_ALIGN) __section(".fw_metadata") = { + .hdr.type = EXT_MAN_ELEM_FW_VERSION, + .hdr.elem_size = ALIGN_UP(sizeof(struct ext_man_fw_version), + EXT_MAN_ALIGN), + .version = { + .hdr.size = sizeof(struct sof_ipc_fw_version), + .micro = SOF_MICRO, + .minor = SOF_MINOR, + .major = SOF_MAJOR, +#if CONFIG_DEBUG + /* only added in debug for reproducibility in releases */ + .build = SOF_BUILD, + .date = __DATE__, + .time = __TIME__, +#endif + .tag = SOF_TAG, + .abi_version = SOF_ABI_VERSION, + }, + .flags = DEBUG_SET_FW_READY_FLAGS, +}; diff --git a/src/platform/apollolake/apollolake.x.in b/src/platform/apollolake/apollolake.x.in index e7ebbd14b613..1e67806ee737 100644 --- a/src/platform/apollolake/apollolake.x.in +++ b/src/platform/apollolake/apollolake.x.in @@ -107,6 +107,9 @@ MEMORY static_log_entries_seg (!ari) : org = LOG_ENTRY_ELF_BASE, len = LOG_ENTRY_ELF_SIZE + fw_metadata_seg (!ari) : + org = EXT_MANIFEST_ELF_BASE, + len = EXT_MANIFEST_ELF_SIZE } PHDRS @@ -142,6 +145,7 @@ PHDRS static_uuid_entries_phdr PT_NOTE; static_log_entries_phdr PT_NOTE; + metadata_entries_phdr PT_NOTE; } /* Default entry point: */ @@ -157,6 +161,9 @@ PROVIDE(_memmap_vecbase_reset = SOF_MEM_VECBASE); _memmap_cacheattr_wbna_trapnull = 0xFF42FFF2; PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wbna_trapnull); +_EXT_MAN_ALIGN_ = 16; +EXTERN(ext_man_fw_ver) + SECTIONS { .MemoryExceptionVector.literal : ALIGN(4) @@ -590,4 +597,10 @@ SECTIONS { *(*.static_log*) } > static_log_entries_seg :static_log_entries_phdr + + .fw_metadata (COPY) : ALIGN(1024) + { + KEEP (*(.fw_metadata)) + . = ALIGN(_EXT_MAN_ALIGN_); + } >fw_metadata_seg :metadata_entries_phdr } diff --git a/src/platform/apollolake/include/platform/lib/memory.h b/src/platform/apollolake/include/platform/lib/memory.h index fb55d9bcb3b3..b82ba41f2c00 100644 --- a/src/platform/apollolake/include/platform/lib/memory.h +++ b/src/platform/apollolake/include/platform/lib/memory.h @@ -122,6 +122,9 @@ #define LOG_ENTRY_ELF_BASE 0x20000000 #define LOG_ENTRY_ELF_SIZE 0x2000000 +#define EXT_MANIFEST_ELF_BASE (LOG_ENTRY_ELF_BASE + LOG_ENTRY_ELF_SIZE) +#define EXT_MANIFEST_ELF_SIZE 0x2000000 + /* * The HP SRAM Region Apollolake is organised like this :- * +--------------------------------------------------------------------------+ diff --git a/src/platform/baytrail/baytrail.x.in b/src/platform/baytrail/baytrail.x.in index 996b739114bd..fd29a93a4b79 100644 --- a/src/platform/baytrail/baytrail.x.in +++ b/src/platform/baytrail/baytrail.x.in @@ -108,6 +108,9 @@ MEMORY static_log_entries_seg (!ari) : org = LOG_ENTRY_ELF_BASE, len = LOG_ENTRY_ELF_SIZE + fw_metadata_seg (!ari) : + org = EXT_MANIFEST_ELF_BASE, + len = EXT_MANIFEST_ELF_SIZE } PHDRS @@ -145,6 +148,7 @@ PHDRS sof_stack_phdr PT_LOAD; static_uuid_entries_phdr PT_NOTE; static_log_entries_phdr PT_NOTE; + metadata_entries_phdr PT_NOTE; } /* Default entry point: */ @@ -172,6 +176,9 @@ _memmap_cacheattr_wt_allvalid = 0x11221222; _memmap_cacheattr_bp_allvalid = 0x22222222; PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wbna_trapnull); +_EXT_MAN_ALIGN_ = 16; +EXTERN(ext_man_fw_ver) + SECTIONS { .ResetVector.text : ALIGN(4) @@ -543,6 +550,12 @@ SECTIONS *(*.static_log*) } > static_log_entries_seg :static_log_entries_phdr + .fw_metadata : ALIGN(1024) + { + KEEP (*(.fw_metadata)) + . = ALIGN(_EXT_MAN_ALIGN_); + } >fw_metadata_seg :metadata_entries_phdr + .fw_ready : ALIGN(4) { KEEP (*(.fw_ready)) diff --git a/src/platform/baytrail/include/platform/lib/memory.h b/src/platform/baytrail/include/platform/lib/memory.h index 1905b2edf553..db890f64b975 100644 --- a/src/platform/baytrail/include/platform/lib/memory.h +++ b/src/platform/baytrail/include/platform/lib/memory.h @@ -98,6 +98,9 @@ static inline void *platform_rfree_prepare(void *ptr) #define LOG_ENTRY_ELF_BASE 0x20000000 #define LOG_ENTRY_ELF_SIZE 0x2000000 +#define EXT_MANIFEST_ELF_BASE 0x22000000 +#define EXT_MANIFEST_ELF_SIZE 0x8000 + /* * The Heap and Stack on Baytrail are organised like this :- * diff --git a/src/platform/cannonlake/cannonlake.x.in b/src/platform/cannonlake/cannonlake.x.in index 54a9e3bc81b7..3359a2575ec7 100644 --- a/src/platform/cannonlake/cannonlake.x.in +++ b/src/platform/cannonlake/cannonlake.x.in @@ -99,6 +99,9 @@ MEMORY static_log_entries_seg (!ari) : org = LOG_ENTRY_ELF_BASE, len = LOG_ENTRY_ELF_SIZE + fw_metadata_seg (!ari) : + org = EXT_MANIFEST_ELF_BASE, + len = EXT_MANIFEST_ELF_SIZE } PHDRS @@ -131,6 +134,7 @@ PHDRS wnd3_phdr PT_LOAD; static_uuid_entries_phdr PT_NOTE; static_log_entries_phdr PT_NOTE; + metadata_entries_phdr PT_NOTE; } /* Default entry point: */ @@ -144,6 +148,9 @@ PROVIDE(_memmap_vecbase_reset = HP_SRAM_VECBASE_RESET); _memmap_cacheattr_wbna_trapnull = 0xFF42FFF2; PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wbna_trapnull); +_EXT_MAN_ALIGN_ = 16; +EXTERN(ext_man_fw_ver) + SECTIONS { .MemoryExceptionVector.text : ALIGN(4) @@ -555,4 +562,10 @@ SECTIONS { *(*.static_log*) } > static_log_entries_seg :static_log_entries_phdr + + .fw_metadata (COPY) : ALIGN(1024) + { + KEEP (*(.fw_metadata)) + . = ALIGN(_EXT_MAN_ALIGN_); + } >fw_metadata_seg :metadata_entries_phdr } diff --git a/src/platform/cannonlake/include/platform/lib/memory.h b/src/platform/cannonlake/include/platform/lib/memory.h index 3400c4fcccb1..9755f72b1d72 100644 --- a/src/platform/cannonlake/include/platform/lib/memory.h +++ b/src/platform/cannonlake/include/platform/lib/memory.h @@ -130,6 +130,9 @@ #define LOG_ENTRY_ELF_BASE 0x20000000 #define LOG_ENTRY_ELF_SIZE 0x2000000 +#define EXT_MANIFEST_ELF_BASE (LOG_ENTRY_ELF_BASE + LOG_ENTRY_ELF_SIZE) +#define EXT_MANIFEST_ELF_SIZE 0x2000000 + /* * The HP SRAM Region on Cannonlake is organised like this :- * +--------------------------------------------------------------------------+ diff --git a/src/platform/haswell/haswell.x.in b/src/platform/haswell/haswell.x.in index 3f9adaea9c95..cca86c0bc1d6 100644 --- a/src/platform/haswell/haswell.x.in +++ b/src/platform/haswell/haswell.x.in @@ -114,6 +114,9 @@ MEMORY static_log_entries_seg (!ari) : org = LOG_ENTRY_ELF_BASE, len = LOG_ENTRY_ELF_SIZE + fw_metadata_seg (!ari) : + org = EXT_MANIFEST_ELF_BASE, + len = EXT_MANIFEST_ELF_SIZE } PHDRS @@ -153,6 +156,7 @@ PHDRS sof_stack_phdr PT_LOAD; static_uuid_entries_phdr PT_NOTE; static_log_entries_phdr PT_NOTE; + metadata_entries_phdr PT_NOTE; } /* Default entry point: */ @@ -180,6 +184,9 @@ _memmap_cacheattr_wt_allvalid = 0x11221222; _memmap_cacheattr_bp_allvalid = 0x22222222; PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wbna_trapnull); +_EXT_MAN_ALIGN_ = 16; +EXTERN(ext_man_fw_ver) + SECTIONS { .ResetVector.text : ALIGN(4) @@ -573,4 +580,10 @@ SECTIONS KEEP (*(.fw_ready)) KEEP (*(.fw_ready_metadata)) } >sof_data :sof_data_phdr + + .fw_metadata (COPY) : ALIGN(1024) + { + KEEP (*(.fw_metadata)) + . = ALIGN(_EXT_MAN_ALIGN_); + } >fw_metadata_seg :metadata_entries_phdr } diff --git a/src/platform/haswell/include/platform/lib/memory.h b/src/platform/haswell/include/platform/lib/memory.h index ec8a02d708e2..8545da99ad12 100644 --- a/src/platform/haswell/include/platform/lib/memory.h +++ b/src/platform/haswell/include/platform/lib/memory.h @@ -91,6 +91,9 @@ static inline void *platform_rfree_prepare(void *ptr) #define LOG_ENTRY_ELF_BASE 0x20000000 #define LOG_ENTRY_ELF_SIZE 0x2000000 +#define EXT_MANIFEST_ELF_BASE (LOG_ENTRY_ELF_BASE + LOG_ENTRY_ELF_SIZE) +#define EXT_MANIFEST_ELF_SIZE 0x2000000 + /* * The Heap and Stack on Haswell/Broadwell are organised like this :- * diff --git a/src/platform/icelake/icelake.x.in b/src/platform/icelake/icelake.x.in index bcf2243ae255..6e7bc494142f 100644 --- a/src/platform/icelake/icelake.x.in +++ b/src/platform/icelake/icelake.x.in @@ -99,11 +99,17 @@ MEMORY static_log_entries_seg (!ari) : org = LOG_ENTRY_ELF_BASE, len = LOG_ENTRY_ELF_SIZE + fw_metadata_seg (!ari) : + org = EXT_MANIFEST_ELF_BASE, + len = EXT_MANIFEST_ELF_SIZE lpsram_mem : org = LP_SRAM_BASE, len = LP_SRAM_SIZE } +_EXT_MAN_ALIGN_ = 16; +EXTERN(ext_man_fw_ver) + PHDRS { vector_memory_lit_phdr PT_LOAD; @@ -134,6 +140,7 @@ PHDRS wnd3_phdr PT_LOAD; static_uuid_entries_phdr PT_NOTE; static_log_entries_phdr PT_NOTE; + metadata_entries_phdr PT_NOTE; lpsram_mem_phdr PT_LOAD; } @@ -559,6 +566,12 @@ SECTIONS *(*.static_log*) } > static_log_entries_seg :static_log_entries_phdr + .fw_metadata (COPY) : ALIGN(1024) + { + KEEP (*(.fw_metadata)) + . = ALIGN(_EXT_MAN_ALIGN_); + } >fw_metadata_seg :metadata_entries_phdr + .lpsram(NOLOAD) : ALIGN(8) { _lpsram_start = ABSOLUTE(.); diff --git a/src/platform/icelake/include/platform/lib/memory.h b/src/platform/icelake/include/platform/lib/memory.h index bce24be9a4c8..d6419a5fa646 100644 --- a/src/platform/icelake/include/platform/lib/memory.h +++ b/src/platform/icelake/include/platform/lib/memory.h @@ -130,6 +130,9 @@ #define LOG_ENTRY_ELF_BASE 0x20000000 #define LOG_ENTRY_ELF_SIZE 0x2000000 +#define EXT_MANIFEST_ELF_BASE (LOG_ENTRY_ELF_BASE + LOG_ENTRY_ELF_SIZE) +#define EXT_MANIFEST_ELF_SIZE 0x2000000 + /* * The HP SRAM Region on Icelake is organised like this :- * +--------------------------------------------------------------------------+ diff --git a/src/platform/imx8/imx8.x.in b/src/platform/imx8/imx8.x.in index b8ae0bd21ec0..609794b02d1f 100644 --- a/src/platform/imx8/imx8.x.in +++ b/src/platform/imx8/imx8.x.in @@ -96,6 +96,9 @@ MEMORY static_log_entries_seg (!ari) : org = LOG_ENTRY_ELF_BASE, len = LOG_ENTRY_ELF_SIZE + fw_metadata_seg (!ari) : + org = EXT_MANIFEST_ELF_BASE, + len = EXT_MANIFEST_ELF_SIZE } PHDRS @@ -127,6 +130,7 @@ PHDRS sof_stack_phdr PT_LOAD; static_uuid_entries_phdr PT_NOTE; static_log_entries_phdr PT_NOTE; + metadata_entries_phdr PT_NOTE; } /* Default entry point: */ @@ -155,6 +159,9 @@ _memmap_cacheattr_bp_allvalid = 0x22222222; _memmap_cacheattr_imx8_wt_allvalid = 0x22212222; PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_imx8_wt_allvalid); +_EXT_MAN_ALIGN_ = 16; +EXTERN(ext_man_fw_ver) + SECTIONS { .ResetVector.text : ALIGN(4) @@ -512,4 +519,10 @@ SECTIONS KEEP (*(.fw_ready)) KEEP (*(.fw_ready_metadata)) } >sof_sdram0 :sof_sdram0_phdr + + .fw_metadata (COPY) : ALIGN(1024) + { + KEEP (*(.fw_metadata)) + . = ALIGN(_EXT_MAN_ALIGN_); + } >fw_metadata_seg :metadata_entries_phdr } diff --git a/src/platform/imx8/include/platform/lib/memory.h b/src/platform/imx8/include/platform/lib/memory.h index 2169130766e9..d5dafe805ca1 100644 --- a/src/platform/imx8/include/platform/lib/memory.h +++ b/src/platform/imx8/include/platform/lib/memory.h @@ -51,6 +51,9 @@ #define LOG_ENTRY_ELF_BASE 0x20000000 #define LOG_ENTRY_ELF_SIZE 0x2000000 +#define EXT_MANIFEST_ELF_BASE (LOG_ENTRY_ELF_BASE + LOG_ENTRY_ELF_SIZE) +#define EXT_MANIFEST_ELF_SIZE 0x2000000 + /* * The Heap and Stack on i.MX8 are organised like this :- * diff --git a/src/platform/imx8m/imx8m.x.in b/src/platform/imx8m/imx8m.x.in index 5652d28bb637..3b5ebf40eb4f 100644 --- a/src/platform/imx8m/imx8m.x.in +++ b/src/platform/imx8m/imx8m.x.in @@ -96,6 +96,9 @@ MEMORY static_log_entries_seg (!ari) : org = LOG_ENTRY_ELF_BASE, len = LOG_ENTRY_ELF_SIZE + fw_metadata_seg (!ari) : + org = EXT_MANIFEST_ELF_BASE, + len = EXT_MANIFEST_ELF_SIZE } PHDRS @@ -127,6 +130,7 @@ PHDRS sof_stack_phdr PT_LOAD; static_uuid_entries_phdr PT_NOTE; static_log_entries_phdr PT_NOTE; + metadata_entries_phdr PT_NOTE; } /* Default entry point: */ @@ -155,6 +159,9 @@ _memmap_cacheattr_bp_allvalid = 0x22222222; _memmap_cacheattr_imx8_wt_allvalid = 0x22212222; PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_imx8_wt_allvalid); +_EXT_MAN_ALIGN_ = 16; +EXTERN(ext_man_fw_ver) + SECTIONS { .ResetVector.text : ALIGN(4) @@ -512,4 +519,10 @@ SECTIONS KEEP (*(.fw_ready)) KEEP (*(.fw_ready_metadata)) } >sof_sdram0 :sof_sdram0_phdr + + .fw_metadata (COPY) : ALIGN(1024) + { + KEEP (*(.fw_metadata)) + . = ALIGN(_EXT_MAN_ALIGN_); + } >fw_metadata_seg :metadata_entries_phdr } diff --git a/src/platform/imx8m/include/platform/lib/memory.h b/src/platform/imx8m/include/platform/lib/memory.h index d216836b0196..d1535b956246 100644 --- a/src/platform/imx8m/include/platform/lib/memory.h +++ b/src/platform/imx8m/include/platform/lib/memory.h @@ -51,6 +51,9 @@ #define LOG_ENTRY_ELF_BASE 0x20000000 #define LOG_ENTRY_ELF_SIZE 0x2000000 +#define EXT_MANIFEST_ELF_BASE (LOG_ENTRY_ELF_BASE + LOG_ENTRY_ELF_SIZE) +#define EXT_MANIFEST_ELF_SIZE 0x2000000 + /* * The Heap and Stack on i.MX8M are organised like this :- * diff --git a/src/platform/suecreek/include/platform/lib/memory.h b/src/platform/suecreek/include/platform/lib/memory.h index eedd76166b44..00e24dcf8da9 100644 --- a/src/platform/suecreek/include/platform/lib/memory.h +++ b/src/platform/suecreek/include/platform/lib/memory.h @@ -154,6 +154,9 @@ #define LOG_ENTRY_ELF_BASE 0x20000000 #define LOG_ENTRY_ELF_SIZE 0x2000000 +#define EXT_MANIFEST_ELF_BASE (LOG_ENTRY_ELF_BASE + LOG_ENTRY_ELF_SIZE) +#define EXT_MANIFEST_ELF_SIZE 0x2000000 + /* * The HP SRAM Region on Sue Creek is organised like this :- * +--------------------------------------------------------------------------+ diff --git a/src/platform/suecreek/suecreek.x.in b/src/platform/suecreek/suecreek.x.in index 4dc70396f48d..24ca2e9722f5 100644 --- a/src/platform/suecreek/suecreek.x.in +++ b/src/platform/suecreek/suecreek.x.in @@ -93,6 +93,9 @@ MEMORY static_log_entries_seg (!ari) : org = LOG_ENTRY_ELF_BASE, len = LOG_ENTRY_ELF_SIZE + fw_metadata_seg (!ari) : + org = EXT_MANIFEST_ELF_BASE, + len = EXT_MANIFEST_ELF_SIZE } PHDRS @@ -123,6 +126,7 @@ PHDRS sof_fw_phdr PT_LOAD; static_uuid_entries_phdr PT_NOTE; static_log_entries_phdr PT_NOTE; + metadata_entries_phdr PT_NOTE; } /* Default entry point: */ @@ -151,6 +155,9 @@ _memmap_cacheattr_bp_allvalid = 0x22222222; _memmap_cacheattr_sue_creek = 0xf2ff4242; PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_sue_creek); +_EXT_MAN_ALIGN_ = 16; +EXTERN(ext_man_fw_ver) + SECTIONS { .ResetVector.text : ALIGN(4) @@ -557,4 +564,10 @@ SECTIONS { *(*.static_log*) } > static_log_entries_seg :static_log_entries_phdr + + .fw_metadata (COPY) : ALIGN(1024) + { + KEEP (*(.fw_metadata)) + . = ALIGN(_EXT_MAN_ALIGN_); + } >fw_metadata_seg :metadata_entries_phdr } diff --git a/src/platform/tigerlake/include/platform/lib/memory.h b/src/platform/tigerlake/include/platform/lib/memory.h index 15234e359aab..dc893d280333 100644 --- a/src/platform/tigerlake/include/platform/lib/memory.h +++ b/src/platform/tigerlake/include/platform/lib/memory.h @@ -130,6 +130,9 @@ #define LOG_ENTRY_ELF_BASE 0x20000000 #define LOG_ENTRY_ELF_SIZE 0x2000000 +#define EXT_MANIFEST_ELF_BASE (LOG_ENTRY_ELF_BASE + LOG_ENTRY_ELF_SIZE) +#define EXT_MANIFEST_ELF_SIZE 0x2000000 + /* * The HP SRAM Region on Tigerlake is organised like this :- * +--------------------------------------------------------------------------+ diff --git a/src/platform/tigerlake/tigerlake.x.in b/src/platform/tigerlake/tigerlake.x.in index 59b1b719786e..449f7004b3e8 100644 --- a/src/platform/tigerlake/tigerlake.x.in +++ b/src/platform/tigerlake/tigerlake.x.in @@ -102,6 +102,9 @@ MEMORY static_log_entries_seg (!ari) : org = LOG_ENTRY_ELF_BASE, len = LOG_ENTRY_ELF_SIZE + fw_metadata_seg (!ari) : + org = EXT_MANIFEST_ELF_BASE, + len = EXT_MANIFEST_ELF_SIZE lpsram_alt_reset_vec_seg : org = LP_SRAM_ALT_RESET_VEC_BASE, len = LP_SRAM_ALT_RESET_VEC_SIZE @@ -147,6 +150,7 @@ PHDRS wnd3_phdr PT_LOAD; static_uuid_entries_phdr PT_NOTE; static_log_entries_phdr PT_NOTE; + metadata_entries_phdr PT_NOTE; lpsram_mem_phdr PT_LOAD; sram_alt_fw_reset_vec_phdr PT_LOAD; sram_alt_fw_reset_vec_int_phdr PT_LOAD; @@ -164,6 +168,8 @@ PROVIDE(_memmap_vecbase_reset = HP_SRAM_VECBASE_RESET); _memmap_cacheattr_wbna_trapnull = 0xFF42FFF2; PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wbna_trapnull); +_EXT_MAN_ALIGN_ = 16; +EXTERN(ext_man_fw_ver) EXTERN(_LpsramHeader) EXTERN(_AltResetVector) @@ -634,6 +640,12 @@ SECTIONS *(*.static_log*) } > static_log_entries_seg :static_log_entries_phdr + .fw_metadata (COPY) : ALIGN(1024) + { + KEEP (*(.fw_metadata)) + . = ALIGN(_EXT_MAN_ALIGN_); + } >fw_metadata_seg :metadata_entries_phdr + .lpsram(NOLOAD) : ALIGN(8) { _lpsram_start = ABSOLUTE(.);