diff options
author | Keith Short <keithshort@chromium.org> | 2020-07-19 16:23:23 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-08-13 14:26:53 +0000 |
commit | e0bf946ced052fe5e857b42da666ba252b03da95 (patch) | |
tree | d5218c56b92ecf3e27e62af0a19c8e9d34443134 /core/cortex-m/ec.lds.S | |
parent | 8ce0c16cc2d153b0002fbea64d08c09d98c3835f (diff) | |
download | chrome-ec-e0bf946ced052fe5e857b42da666ba252b03da95.tar.gz |
npcx: add support for rom resident sections
EC images are copied in full from flash to RAM. When the code RAM size
is smaller than 1/2 the flash size, the EC image size is limited to the
code RAM size, leaving unused flash space.
Create a new linker section .init_rom used to store data objects that
are single use in the previously unused flash area. Data objects can be
used at runtime by copying into RAM using the flash_read() function.
This change is tied to the NPCX flash layout, with asserts to ensure
builds fail if the CONFIG_CHIP_INIT_ROM_REGION is not supported by
the chip.
CLs that enable CONFIG_CHIP_INIT_ROM_REGION should not be merged until
the predecessor CL:2325764 is available in CPFE images.
BUG=b:160330682
BRANCH=none
TEST=make buildall
TEST=With debug code, use the _init_rom macro and validate the data can
be read using flash_read().
TEST=Using hex editor, verify .init_rom section located at 192K boundary
and unused bytes are filled with 0xFF.
TEST=compare_build.sh passes when run against waddledoo (npcx, cortex-m)
Signed-off-by: Keith Short <keithshort@chromium.org>
Change-Id: Ia0785798fd1938ad6a1c254a070b219027ee82a3
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2311268
Reviewed-by: caveh jalali <caveh@chromium.org>
Commit-Queue: caveh jalali <caveh@chromium.org>
Diffstat (limited to 'core/cortex-m/ec.lds.S')
-rw-r--r-- | core/cortex-m/ec.lds.S | 117 |
1 files changed, 116 insertions, 1 deletions
diff --git a/core/cortex-m/ec.lds.S b/core/cortex-m/ec.lds.S index c24ee8321b..ed57a29529 100644 --- a/core/cortex-m/ec.lds.S +++ b/core/cortex-m/ec.lds.S @@ -6,6 +6,11 @@ #include "config.h" #include "rwsig.h" +#define CONCAT_STAGE_1(w, x, y, z) w ## x ## y ## z +#define CONCAT2(w, x) CONCAT_STAGE_1(w, x, , ) +#define CONCAT3(w, x, y) CONCAT_STAGE_1(w, x, y, ) +#define CONCAT4(w, x, y, z) CONCAT_STAGE_1(w, x, y, z) + #define STRINGIFY0(name) #name #define STRINGIFY(name) STRINGIFY0(name) @@ -20,6 +25,30 @@ #define FW_SIZE_(section) CONFIG_##section##_SIZE #define FW_SIZE(section) FW_SIZE_(section) +/* + * Define the VMA (virtual memory address) of the ROM_RESIDENT region within + * the EC image. This is full 32-bit address starting from + * CONFIG_PROGRAM_MEMORY_BASE. + */ +#define ROM_RES_OFF(section) FW_OFF(CONCAT2(section, _ROM_RESIDENT)) +#define ROM_RES_SIZE(section) FW_SIZE(CONCAT2(section, _ROM_RESIDENT)) + +/* + * Define the VMA (virtual memory address) of the ROM_RESIDENT region. Instead + * of a full 32-bit address, set the VMA to be an offset within the flash memory + * section. Objects linked into this section can pass the address of the + * object unmodified to the public APIs of the flash and init_rom modules. + */ +#ifdef SECTION_IS_RO +#define ROM_RES_FLASH_OFF(section) \ + FW_MEM_OFF(CONCAT2(section, _ROM_RESIDENT)) + \ + CONFIG_EC_PROTECTED_STORAGE_OFF +#else +#define ROM_RES_FLASH_OFF(section) \ + FW_MEM_OFF(CONCAT2(section, _ROM_RESIDENT)) + \ + CONFIG_EC_WRITABLE_STORAGE_OFF +#endif + /* Indicates where .data LMA should reside. */ #undef DATA_LMA_MEM_REGION @@ -45,6 +74,15 @@ MEMORY #else FLASH (rx) : ORIGIN = FW_OFF(SECTION), LENGTH = FW_SIZE(SECTION) #endif +#ifdef CONFIG_CHIP_INIT_ROM_REGION + ROM_RESIDENT (r) : \ + ORIGIN = ROM_RES_OFF(SECTION), \ + LENGTH = ROM_RES_SIZE(SECTION) + + ROM_RESIDENT_VMA (r) : \ + ORIGIN = ROM_RES_FLASH_OFF(SECTION), \ + LENGTH = ROM_RES_SIZE(SECTION) +#endif /* CONFIG_CHIP_INIT_ROM_REGION */ #ifdef CONFIG_SHAREDLIB SHARED_LIB (rx) : ORIGIN = FW_OFF(SHAREDLIB), \ LENGTH = FW_SIZE(SHAREDLIB) @@ -274,6 +312,18 @@ SECTIONS . = ALIGN(4); *(.rodata*) +#ifndef CONFIG_CHIP_INIT_ROM_REGION + /* + * When a separate ROM resident section isn't enabled, ensure + * the corresponding data objects are linked into the .rodata + * section. + */ + . = ALIGN(4); + __init_rom_start = .; + *(.init.rom) + __init_rom_end = .; +#endif /* CONFIG_CHIP_INIT_ROM_REGION */ + #if defined(SECTION_IS_RO) && defined(CONFIG_FLASH) . = ALIGN(64); KEEP(*(.google)) @@ -418,7 +468,6 @@ SECTIONS * in hash calcuations. */ __flash_used = LOADADDR(.data) + SIZEOF(.data) - ORIGIN(FLASH); - __image_size = __flash_used; #ifdef CONFIG_FLASH /* @@ -446,6 +495,72 @@ SECTIONS ) >= __flash_used, "No room left in the flash") +#ifdef CONFIG_CHIP_INIT_ROM_REGION + /* + * Image layout when ROM_RESIDENT region is used (lower addresses + * at the top). This layout is setup by the LMA assignment. + * + * EC image layout (LMA) VMA + * .header (if RO image) none + * .text code RAM + * .rodata code RAM + .text size + * .data data RAM + * .fill none + * .init_rom flash offset + * + * The loader code copies the .text, .rodata, and .data sections into + * the code RAM of the EC. The .header and .init_rom sections are not + * copied by the loader. + */ + + /* + * The layout assumes the ROM_RESIDENT region follows the FLASH + * region. + */ + ASSERT((ORIGIN(FLASH) + LENGTH(FLASH)) == ORIGIN(ROM_RESIDENT), + ".init_rom section must follow the flash section") + + .init_rom : { + . = ALIGN(4); + __init_rom_start = .; + *(.init.rom) + __init_rom_end = .; + } > ROM_RESIDENT_VMA AT > ROM_RESIDENT + + /* + * The ROM_RESIDENT section is assumed to be in the same physical + * flash as the FLASH section. Fill the space between. + */ + .fill : { + . = LOADADDR(.data) + SIZEOF(.data); + . = ALIGN(4); + __fill_start = .; + FILL(0xFF); + . = ORIGIN(FLASH) + LENGTH(FLASH) - 1; + /* Need at least one byte so section is not omitted */ + BYTE(0xFF); + __fill_end = .; + } > FLASH + + /* + * The end of the .fill region should also be the start of the + * .init_rom region + */ + ASSERT(__fill_end == LOADADDR(.init_rom), + ".fill region end not aligned to start of .init_rom") + + /* + * __image_size is used for hash calculation. When + * CONFIG_CHIP_INIT_ROM_REGION is enabled, this includes the entire + * FLASH region and the bytes used in the .init_rom section. + */ + __image_size = LENGTH(FLASH) + SIZEOF(.init_rom); +#else + /* + * Typical build: __image_size is the same as __flash_used. + */ + __image_size = __flash_used; +#endif /* CONFIG_CHIP_INIT_ROM_REGION */ #ifdef CONFIG_CHIP_MEMORY_REGIONS #define REGION(name, attr, start, size) \ |