summaryrefslogtreecommitdiff
path: root/core/cortex-m/ec.lds.S
diff options
context:
space:
mode:
authorKeith Short <keithshort@chromium.org>2020-07-19 16:23:23 -0600
committerCommit Bot <commit-bot@chromium.org>2020-08-13 14:26:53 +0000
commite0bf946ced052fe5e857b42da666ba252b03da95 (patch)
treed5218c56b92ecf3e27e62af0a19c8e9d34443134 /core/cortex-m/ec.lds.S
parent8ce0c16cc2d153b0002fbea64d08c09d98c3835f (diff)
downloadchrome-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.S117
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) \