summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/main.c10
-rw-r--r--common/system.c23
-rw-r--r--core/cortex-m/ec.lds.S15
-rw-r--r--include/config.h6
4 files changed, 54 insertions, 0 deletions
diff --git a/common/main.c b/common/main.c
index 016d4f6279..bafb18c94a 100644
--- a/common/main.c
+++ b/common/main.c
@@ -25,6 +25,7 @@
#include "task.h"
#include "timer.h"
#include "uart.h"
+#include "util.h"
#include "watchdog.h"
/* Console output macros */
@@ -34,6 +35,15 @@
test_mockable __keep int main(void)
{
+#ifdef CONFIG_REPLACE_LOADER_WITH_BSS_SLOW
+ /*
+ * Now that we have started execution, we no longer need the loader.
+ * Instead, variables placed in the .bss.slow section will use this
+ * space. Therefore, clear out this region now.
+ */
+ memset((void *)(CONFIG_PROGRAM_MEMORY_BASE + CONFIG_LOADER_MEM_OFF), 0,
+ CONFIG_LOADER_SIZE);
+#endif /* defined(CONFIG_REPLACE_LOADER_WITH_BSS_SLOW) */
/*
* Pre-initialization (pre-verified boot) stage. Initialization at
* this level should do as little as possible, because verified boot
diff --git a/common/system.c b/common/system.c
index 4e06d7abc2..224ae7d78e 100644
--- a/common/system.c
+++ b/common/system.c
@@ -26,6 +26,7 @@
#include "usb_pd.h"
#include "util.h"
#include "version.h"
+#include "watchdog.h"
/* Console output macros */
#define CPUTS(outstr) cputs(CC_SYSTEM, outstr)
@@ -478,6 +479,12 @@ int system_run_image_copy(enum system_image_copy_t copy)
{
uintptr_t base;
uintptr_t init_addr;
+#ifdef CONFIG_REPLACE_LOADER_WITH_BSS_SLOW
+ uint8_t *buf;
+ uint32_t offset;
+ uint32_t bytes_to_load;
+ int rv;
+#endif /* defined(CONFIG_REPLACE_LOADER_WITH_BSS_SLOW) */
/* If system is already running the requested image, done */
if (system_get_image_copy() == copy)
@@ -506,6 +513,22 @@ int system_run_image_copy(enum system_image_copy_t copy)
return EC_ERROR_INVAL;
#ifdef CONFIG_EXTERNAL_STORAGE
+#ifdef CONFIG_REPLACE_LOADER_WITH_BSS_SLOW
+ /*
+ * We've used the region in which the loader resided as data space for
+ * the .bss.slow section. Therefore, we need to reload the loader from
+ * the external storage back into program memory so that we can load a
+ * different image.
+ */
+ buf = (uint8_t *)(CONFIG_PROGRAM_MEMORY_BASE + CONFIG_LOADER_MEM_OFF);
+ bytes_to_load = CONFIG_LOADER_SIZE;
+ offset = CONFIG_EC_PROTECTED_STORAGE_OFF + CONFIG_LOADER_STORAGE_OFF;
+
+ rv = flash_read(offset, bytes_to_load, buf);
+ if (rv)
+ return rv;
+#endif /* defined(CONFIG_REPLACE_LOADER_WITH_BSS_SLOW) */
+
/* Jump to loader */
init_addr = system_get_lfw_address();
diff --git a/core/cortex-m/ec.lds.S b/core/cortex-m/ec.lds.S
index 3e026331fe..f778ca8f88 100644
--- a/core/cortex-m/ec.lds.S
+++ b/core/cortex-m/ec.lds.S
@@ -36,6 +36,11 @@ MEMORY
IRAM (rw) : ORIGIN = CONFIG_RAM_BASE, LENGTH = CONFIG_RAM_SIZE
#ifdef CONFIG_EXTERNAL_STORAGE
+#ifdef CONFIG_REPLACE_LOADER_WITH_BSS_SLOW
+ LDR_REGION(rw) : \
+ ORIGIN = CONFIG_PROGRAM_MEMORY_BASE + CONFIG_LOADER_MEM_OFF, \
+ LENGTH = CONFIG_LOADER_SIZE
+#endif /* defined(CONFIG_REPLACE_LOADER_WITH_BSS_SLOW) */
CDRAM (rx) : \
ORIGIN = CONFIG_PROGRAM_MEMORY_BASE + FW_MEM_OFF(SECTION), \
LENGTH = FW_SIZE(SECTION)
@@ -221,6 +226,16 @@ SECTIONS
. = ALIGN(4);
__bss_end = .;
} > IRAM
+
+ .bss.slow : {
+ /* Region of RAM reclaimed from the little firmware(LFW). */
+ *(.bss.slow)
+#ifdef CONFIG_REPLACE_LOADER_WITH_BSS_SLOW
+ } > LDR_REGION
+#else
+ } > IRAM
+#endif /* defined(CONFIG_REPLACE_LOADER_WITH_BSS_SLOW) */
+
#ifdef CONFIG_EXTERNAL_STORAGE
.data : AT(LOADADDR(.rodata) + SIZEOF(.rodata)) {
#else
diff --git a/include/config.h b/include/config.h
index 76bae7e9a2..1e017fe028 100644
--- a/include/config.h
+++ b/include/config.h
@@ -793,6 +793,12 @@
#undef CONFIG_FW_PSTATE_SIZE
/*
+ * Reuse the space that was occupied in RAM by the little firmware (LFW) loader
+ * with the section ".bss.slow" instead.
+ */
+#undef CONFIG_REPLACE_LOADER_WITH_BSS_SLOW
+
+/*
* Read-only / read-write image configuration.
* Images may reside on storage (ex. external or internal SPI) at a different
* offset than when copied to program memory. Hence, two sets of offsets,