soc/intel_adsp: Build bootloader with Zephyr

The presence of a separate build for the bootloader code has always
been a wart with this platform.  Sharing of code between the two has
required great care. We've had bugs with mismatched include paths,
macro definitions and compiler flags, etc...  And of course it's not
possible for one to see the other; in theory we'd like the ability to
call back into IMR code after startup, to use the space for temporary
storage, etc...

So let's finally do it.  This really isn't that complicated when you
see it in isolation:

+ Move the module manifest metadata into an "rimage_modules.c", and
  put them in their own NOLOAD section where we can grab them later
  with objcopy.

+ Make a new "imr" memory region in the main linker and just paste the
  bootloader linkage (which is now using its own specific sections) in
  there.

+ After zephyr.elf is built and cache-remapped, we can extract the imr
  sections and the appropriate manifest for the bootloader rimage
  module, and then do the converse by excluding them for the main
  image module.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2021-12-10 15:37:17 -08:00 committed by Maureen Helm
parent 79746d701b
commit 2906d1aa51
4 changed files with 98 additions and 10 deletions

View file

@ -423,8 +423,8 @@ class RimageSigner(Signer):
out_xman = str(b / 'zephyr' / 'zephyr.ri.xman')
out_tmp = str(b / 'zephyr' / 'zephyr.rix')
else:
bootloader = str(b / 'zephyr' / 'bootloader.elf.mod')
kernel = str(b / 'zephyr' / 'zephyr.elf.mod')
bootloader = str(b / 'zephyr' / 'boot.mod')
kernel = str(b / 'zephyr' / 'main.mod')
out_bin = str(b / 'zephyr' / 'zephyr.ri')
out_xman = str(b / 'zephyr' / 'zephyr.ri.xman')
out_tmp = str(b / 'zephyr' / 'zephyr.rix')

View file

@ -15,16 +15,38 @@ zephyr_library_sources(adsp.c)
zephyr_library_sources(soc.c)
zephyr_library_sources(soc_mp.c)
zephyr_library_sources(trace_out.c)
zephyr_library_sources(rimage_modules.c)
zephyr_library_sources(bootloader/boot_loader.c)
zephyr_library_link_libraries(INTEL_ADSP_COMMON)
target_include_directories(INTEL_ADSP_COMMON INTERFACE include)
target_link_libraries(INTEL_ADSP_COMMON INTERFACE intel_adsp_common)
# Common CAVS code
if(CONFIG_SOC_SERIES_INTEL_CAVS_V15 OR
CONFIG_SOC_SERIES_INTEL_CAVS_V18 OR
CONFIG_SOC_SERIES_INTEL_CAVS_V20 OR
CONFIG_SOC_SERIES_INTEL_CAVS_V25)
include(bootloader.cmake)
endif()
set(ELF_FIX ${SOC_DIR}/${ARCH}/${SOC_FAMILY}/common/fix_elf_addrs.py)
set(KERNEL_REMAPPED ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_NAME}-remapped.elf)
# Generate rimage modules from the base kernel ELF file
add_custom_target(
gen_modules ALL
DEPENDS ${ZEPHYR_FINAL_EXECUTABLE}
# Remap uncached section addresses so they appear contiguous
COMMAND ${CMAKE_COMMAND} -E
copy ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_NAME}.elf ${KERNEL_REMAPPED}
COMMAND ${ELF_FIX} ${CMAKE_OBJCOPY} ${KERNEL_REMAPPED}
# Extract modules for rimage
COMMAND ${CMAKE_OBJCOPY}
--only-section .imr*
--only-section .module.boot
--rename-section .module.boot=.module
${KERNEL_REMAPPED} ${CMAKE_BINARY_DIR}/zephyr/boot.mod
COMMAND ${CMAKE_OBJCOPY}
--remove-section .imr*
--remove-section .module.boot
--rename-section .module.main=.module
${KERNEL_REMAPPED} ${CMAKE_BINARY_DIR}/zephyr/main.mod
)

View file

@ -26,6 +26,11 @@ OUTPUT_ARCH(xtensa)
PROVIDE(__memctl_default = 0x00000000);
PROVIDE(_MemErrorHandler = 0x00000000);
/* Offset of the entry point from the manifest start in IMR. Magic
* number must be synchronized with the module and rimage configuration!
*/
#define ENTRY_POINT_OFF 0x6000
#define LP_SRAM_REGION lpram
/* DSP RAM regions (all of them) are mapped twice on the DSP: once in
@ -57,6 +62,9 @@ PROVIDE(_MemErrorHandler = 0x00000000);
MEMORY
{
modules :
org = 0x10000,
len = 0x10000
vector_memory_lit :
org = XCHAL_MEMERROR_VECTOR_PADDR + MEM_ERROR_LIT_SIZE,
len = MEM_ERROR_LIT_SIZE
@ -120,6 +128,9 @@ MEMORY
vector_double_text :
org = XCHAL_DOUBLEEXC_VECTOR_PADDR_SRAM,
len = MEM_VECT_TEXT_SIZE
imr :
org = CONFIG_IMR_MANIFEST_ADDR + ENTRY_POINT_OFF,
len = 0x100000
ram :
org = RAM_BASE,
len = RAM_SIZE
@ -171,6 +182,7 @@ PHDRS
vector_user_text_phdr PT_LOAD;
vector_double_lit_phdr PT_LOAD;
vector_double_text_phdr PT_LOAD;
imr_phdr PT_LOAD;
ram_phdr PT_LOAD;
#ifdef CONFIG_KERNEL_COHERENCE
ucram_phdr PT_LOAD;
@ -178,6 +190,7 @@ PHDRS
static_uuid_entries_phdr PT_NOTE;
static_log_entries_phdr PT_NOTE;
metadata_entries_phdr PT_NOTE;
module_phdr PT_NOTE;
}
_rom_store_table = 0;
PROVIDE(_memmap_vecbase_reset = XCHAL_VECBASE_RESET_PADDR_SRAM);
@ -229,9 +242,29 @@ EXTERN(ext_man_cavs_config)
SECTIONS
{
#include <linker/rel-sections.ld>
/* Boot loader code in IMR memory */
.imr : {
/* Entry point MUST be here per external configuration */
KEEP (*(.boot_entry.text))
*(.imr .imr.*)
} >imr :imr_phdr
/* Boot loader data. Note that rimage seems to want this
* page-aligned or it will throw an error, not sure why since all
* the ROM cares about is a contiguous region. And it's
* particularly infuriating as it precludes linker .rodata next to
* .text.
*/
.imrdata : ALIGN(4096) {
*(.imrdata .imrdata.*)
} >imr :imr_phdr
/* rimage module manifest headers */
.module.boot : { KEEP(*(.module.boot)) } >modules :module_phdr
.module.main : { KEEP(*(.module.main)) } >modules :module_phdr
.MemoryExceptionVector.literal : ALIGN(4)
{
_MemoryExceptionVector_literal_start = ABSOLUTE(.);

View file

@ -0,0 +1,33 @@
#include "bootloader/manifest.h"
#include <cavs-mem.h>
/* These data structures define "module manifest" headers. They
* aren't runtime data used by Zephyr, but instead act as input
* parameters to rimage and later to the ROM loader on the DSP. As it
* happens most of the data here is ignored by both layers, but it's
* left unchanged for historical purposes.
*/
__attribute__((section(".module.boot")))
struct sof_man_module_manifest boot_manifest =
{ .module = {
.name = "BRNGUP",
.uuid = { 0xcc, 0x48, 0x7b, 0x0d, 0xa9, 0x1e, 0x0a, 0x47,
0xa8, 0xc1, 0x53, 0x34, 0x24, 0x52, 0x8a, 0x17 },
.entry_point = IMR_BOOT_LDR_TEXT_ENTRY_BASE,
.type = { .load_type = SOF_MAN_MOD_TYPE_MODULE,
.domain_ll = 1, },
.affinity_mask = 3,
}};
__attribute__((section(".module.main")))
struct sof_man_module_manifest main_manifest =
{ .module = {
.name = "BASEFW",
.uuid = { 0x2e, 0x9e, 0x86, 0xfc, 0xf8, 0x45, 0x45, 0x40,
0xa4, 0x16, 0x89, 0x88, 0x0a, 0xe3, 0x20, 0xa9 },
.entry_point = RAM_BASE,
.type = { .load_type = SOF_MAN_MOD_TYPE_MODULE,
.domain_ll = 1 },
.affinity_mask = 3,
}};