summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2017-06-29 16:03:04 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-07-13 19:45:57 -0700
commit34fed775b65063fb519d11deb11eb1feac7a8ecc (patch)
treec5a505368025900931fa35eb0adeb95eef182a2d
parent1106dea40d3b18fbab2f42a2510d0a7899650db9 (diff)
downloadchrome-ec-34fed775b65063fb519d11deb11eb1feac7a8ecc.tar.gz
npcx: Build RW_B and support sysjump to it
This patch allows a board to include another RW image in ec.bin. The size of each copy is a quarter of the flash size on Fizz. BUG=b:38462249 BRANCH=none CQ-DEPEND=CL:568297 TEST=Run sysjump RW/A/B. Verify there is no size change by running make savesizes/newsizes. Run objdump -h build/fizz/ec.obj: Idx Name Size VMA LMA File off Algn 0 .image.RO 0001700c 10088000 10088000 00008000 2**0 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .image.RO.key 00000340 1009f00c 100a7c40 0001f00c 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .image.RW 00016ddc 1009f34c 100c8000 0001f34c 2**0 CONTENTS, ALLOC, LOAD, READONLY, CODE 3 .image.RW.sign 000001b8 100b6128 100e7c00 00036128 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .image.RW_B 00016ddc 100b62e0 100e8000 000362e0 2**0 CONTENTS, ALLOC, LOAD, READONLY, CODE 5 .image.RW_B.sign 000001b8 100cd0bc 10107c00 0004d0bc 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .padding 00000001 100cd274 10107fff 0004d274 2**0 CONTENTS, ALLOC, LOAD, DATA 7 .ARM.attributes 00000014 00000000 00000000 0004d275 2**0 CONTENTS, READONLY Change-Id: Iaa687c1d7d704fec4cccfa127376c8db102267fa Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/557305 Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
-rw-r--r--board/fizz/board.h23
-rw-r--r--chip/npcx/registers.h1
-rw-r--r--chip/npcx/system.c66
-rw-r--r--common/firmware_image.S7
-rw-r--r--common/firmware_image.lds.S13
-rw-r--r--include/rwsig.h21
6 files changed, 112 insertions, 19 deletions
diff --git a/board/fizz/board.h b/board/fizz/board.h
index 49644f0137..991b906b08 100644
--- a/board/fizz/board.h
+++ b/board/fizz/board.h
@@ -139,6 +139,29 @@
#define CONFIG_VBOOT_HASH
#define CONFIG_VSTORE
#define CONFIG_VSTORE_SLOT_COUNT 1
+
+/*
+ * Flash layout. Since config_flash_layout.h is included before board.h,
+ * we can only overwrite (=undef/define) these parameters here.
+ *
+ * Flash stores 3 images: RO, RW_A, RW_B. We divide the flash by 4.
+ * A public key is stored at the end of RO. Signatures are stored at the
+ * end of RW_A and RW_B, respectively.
+ */
+#define CONFIG_RW_B
+#define CONFIG_RW_B_MEM_OFF CONFIG_RO_MEM_OFF
+#undef CONFIG_RO_SIZE
+#define CONFIG_RO_SIZE (CONFIG_FLASH_SIZE / 4)
+#undef CONFIG_RW_SIZE
+#define CONFIG_RW_SIZE CONFIG_RO_SIZE
+#define CONFIG_RW_A_STORAGE_OFF CONFIG_RW_STORAGE_OFF
+#define CONFIG_RW_B_STORAGE_OFF (CONFIG_RW_A_STORAGE_OFF + \
+ CONFIG_RW_SIZE)
+#define CONFIG_RW_A_SIGN_STORAGE_OFF (CONFIG_RW_A_STORAGE_OFF + \
+ CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE)
+#define CONFIG_RW_B_SIGN_STORAGE_OFF (CONFIG_RW_B_STORAGE_OFF + \
+ CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE)
+
#define CONFIG_RWSIG
#define CONFIG_RWSIG_TYPE_RWSIG
#define CONFIG_RSA
diff --git a/chip/npcx/registers.h b/chip/npcx/registers.h
index edcaf5587f..c201576d68 100644
--- a/chip/npcx/registers.h
+++ b/chip/npcx/registers.h
@@ -252,6 +252,7 @@
/* MDC register fields */
#define NPCX_FWCTRL_RO_REGION 0
+#define NPCX_FWCTRL_FW_SLOT 1
/******************************************************************************/
/* High Frequency Clock Generator (HFCG) registers */
diff --git a/chip/npcx/system.c b/chip/npcx/system.c
index d863c7b30c..d3b6474459 100644
--- a/chip/npcx/system.c
+++ b/chip/npcx/system.c
@@ -948,14 +948,25 @@ void system_jump_to_booter(void)
* Get memory offset and size for RO/RW regions.
* Both of them need 16-bytes alignment since GDMA burst mode.
*/
- if (IS_BIT_SET(NPCX_FWCTRL, NPCX_FWCTRL_RO_REGION)) {
- flash_offset = CONFIG_EC_PROTECTED_STORAGE_OFF +
- CONFIG_RO_STORAGE_OFF;
- flash_used = CONFIG_RO_SIZE;
- } else {
+ switch (system_get_shrspi_image_copy()) {
+ case SYSTEM_IMAGE_RW:
flash_offset = CONFIG_EC_WRITABLE_STORAGE_OFF +
CONFIG_RW_STORAGE_OFF;
flash_used = CONFIG_RW_SIZE;
+ break;
+#ifdef CONFIG_RW_B
+ case SYSTEM_IMAGE_RW_B:
+ flash_offset = CONFIG_EC_WRITABLE_STORAGE_OFF +
+ CONFIG_RW_B_STORAGE_OFF;
+ flash_used = CONFIG_RW_SIZE;
+ break;
+#endif
+ case SYSTEM_IMAGE_RO:
+ default: /* Jump to RO by default */
+ flash_offset = CONFIG_EC_PROTECTED_STORAGE_OFF +
+ CONFIG_RO_STORAGE_OFF;
+ flash_used = CONFIG_RO_SIZE;
+ break;
}
/* Make sure the reset vector is inside the destination image */
@@ -998,21 +1009,54 @@ uint32_t system_get_lfw_address()
return jump_addr;
}
+/*
+ * Set and clear image copy flags in MDC register.
+ *
+ * NPCX_FWCTRL_RO_REGION: 1 - RO, 0 - RW
+ * NPCX_FWCTRL_FW_SLOT: 1 - SLOT_A, 0 - SLOT_B
+ */
void system_set_image_copy(enum system_image_copy_t copy)
{
- /* Jump to RW region -- clear flag */
- if (copy == SYSTEM_IMAGE_RW)
+ switch (copy) {
+ case SYSTEM_IMAGE_RW:
+ CLEAR_BIT(NPCX_FWCTRL, NPCX_FWCTRL_RO_REGION);
+ SET_BIT(NPCX_FWCTRL, NPCX_FWCTRL_FW_SLOT);
+ break;
+#ifdef CONFIG_RW_B
+ case SYSTEM_IMAGE_RW_B:
CLEAR_BIT(NPCX_FWCTRL, NPCX_FWCTRL_RO_REGION);
- else /* Jump to RO region -- set flag */
+ CLEAR_BIT(NPCX_FWCTRL, NPCX_FWCTRL_FW_SLOT);
+ break;
+#endif
+ default:
+ CPRINTS("Invalid copy (%d) is requested as a jump destination. "
+ "Change it to %d.", copy, SYSTEM_IMAGE_RO);
+ /* Fall through to SYSTEM_IMAGE_RO */
+ case SYSTEM_IMAGE_RO:
SET_BIT(NPCX_FWCTRL, NPCX_FWCTRL_RO_REGION);
+ SET_BIT(NPCX_FWCTRL, NPCX_FWCTRL_FW_SLOT);
+ break;
+ }
}
enum system_image_copy_t system_get_shrspi_image_copy(void)
{
- /* RO region FW */
- if (IS_BIT_SET(NPCX_FWCTRL, NPCX_FWCTRL_RO_REGION))
+ if (IS_BIT_SET(NPCX_FWCTRL, NPCX_FWCTRL_RO_REGION)) {
+ /* RO image */
+#ifdef CHIP_HAS_RO_B
+ if (!IS_BIT_SET(NPCX_FWCTRL, NPCX_FWCTRL_FW_SLOT))
+ return SYSTEM_IMAGE_RO_B;
+#endif
return SYSTEM_IMAGE_RO;
- else/* RW region FW */
+ } else {
+#ifdef CONFIG_RW_B
+ /* RW image */
+ if (!IS_BIT_SET(NPCX_FWCTRL, NPCX_FWCTRL_FW_SLOT))
+ /* Slot A */
+ return SYSTEM_IMAGE_RW_B;
+#endif
return SYSTEM_IMAGE_RW;
+ }
}
+
#endif
diff --git a/common/firmware_image.S b/common/firmware_image.S
index 79661c2866..a19968994f 100644
--- a/common/firmware_image.S
+++ b/common/firmware_image.S
@@ -57,6 +57,13 @@
#endif
#ifdef CONFIG_RW_B
+#ifdef CONFIG_RWSIG_TYPE_RWSIG
+.section .image.RW_B, "ax"
+.incbin FW_IMAGE(RW,)
+.section .image.RW_B.sign, "a"
+.incbin FW_IMAGE_SIGN(RW,)
+#else
.section .image.RW_B, "ax"
.incbin FW_IMAGE(RW,_B)
#endif
+#endif
diff --git a/common/firmware_image.lds.S b/common/firmware_image.lds.S
index a956683aa6..8e82dcf1de 100644
--- a/common/firmware_image.lds.S
+++ b/common/firmware_image.lds.S
@@ -15,6 +15,9 @@
#define IMAGE_RW_AT (CONFIG_PROGRAM_MEMORY_BASE + \
CONFIG_EC_WRITABLE_STORAGE_OFF + \
CONFIG_RW_STORAGE_OFF)
+#define IMAGE_RW_B_AT (CONFIG_PROGRAM_MEMORY_BASE + \
+ CONFIG_EC_WRITABLE_STORAGE_OFF + \
+ CONFIG_RW_B_STORAGE_OFF)
#elif (CONFIG_RO_MEM_OFF == CONFIG_RW_MEM_OFF)
#define IMAGE_RO_AT (CONFIG_PROGRAM_MEMORY_BASE + CONFIG_RO_MEM_OFF)
@@ -23,10 +26,13 @@ mapped to the same location but we still have to generate an ec.bin with RO
and RW images at different Flash offset */
#define IMAGE_RW_AT (CONFIG_PROGRAM_MEMORY_BASE + \
CONFIG_RO_MEM_OFF + CONFIG_RO_SIZE)
+#define IMAGE_RW_B_AT (CONFIG_PROGRAM_MEMORY_BASE + \
+ CONFIG_RO_MEM_OFF + CONFIG_RO_SIZE + CONFIG_RW_SIZE)
#else
#define IMAGE_RO_AT (CONFIG_PROGRAM_MEMORY_BASE + CONFIG_RO_MEM_OFF)
#define IMAGE_RW_AT (CONFIG_PROGRAM_MEMORY_BASE + CONFIG_RW_MEM_OFF)
+#define IMAGE_RW_B_AT (CONFIG_PROGRAM_MEMORY_BASE + CONFIG_RW_B_MEM_OFF)
#endif
OUTPUT_FORMAT(BFD_FORMAT, BFD_FORMAT, BFD_FORMAT)
@@ -69,9 +75,14 @@ SECTIONS
} > FLASH =0xff
#endif
#ifdef CONFIG_RW_B_MEM_OFF
- .image.RW_B : AT(CONFIG_PROGRAM_MEMORY_BASE + CONFIG_RW_B_MEM_OFF) {
+ .image.RW_B : AT(IMAGE_RW_B_AT) {
*(.image.RW_B)
} > FLASH =0xff
+#ifdef CONFIG_RWSIG_TYPE_RWSIG
+ .image.RW_B.sign : AT(CONFIG_RW_B_SIG_ADDR) {
+ *(.image.RW_B.sign)
+ } > FLASH =0xff
+#endif
#endif
.padding : AT(CONFIG_PROGRAM_MEMORY_BASE + CONFIG_FLASH_SIZE - 1) {
BYTE(0xff);
diff --git a/include/rwsig.h b/include/rwsig.h
index 765ac09ec5..0cb98c83f0 100644
--- a/include/rwsig.h
+++ b/include/rwsig.h
@@ -105,13 +105,20 @@ void rwsig_jump_now(void);
#define CONFIG_RW_SIG_SIZE RSANUMBYTES
#endif
#endif /* ! CONFIG_RW_SIG_SIZE */
+/* The signature resides at the end of each RW copy */
+#define RW_SIG_OFFSET (CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE)
+#define RW_A_ADDR (CONFIG_PROGRAM_MEMORY_BASE + \
+ CONFIG_EC_WRITABLE_STORAGE_OFF + \
+ CONFIG_RW_STORAGE_OFF)
+/* Assume the layout is same as RW_A and it sits right after RW_A */
+#define RW_B_ADDR (CONFIG_PROGRAM_MEMORY_BASE + \
+ CONFIG_EC_WRITABLE_STORAGE_OFF + \
+ CONFIG_RW_B_STORAGE_OFF)
#ifndef CONFIG_RW_SIG_ADDR
-/* The signature resides at the end of the RW image */
-#define CONFIG_RW_SIG_ADDR (CONFIG_PROGRAM_MEMORY_BASE \
- + CONFIG_EC_WRITABLE_STORAGE_OFF \
- + CONFIG_RW_STORAGE_OFF \
- + CONFIG_RW_SIZE \
- - CONFIG_RW_SIG_SIZE)
-#endif /* !CONFIG_RW_SIG_ADDR */
+#define CONFIG_RW_SIG_ADDR (RW_A_ADDR + RW_SIG_OFFSET)
+#endif
+#ifndef CONFIG_RW_B_SIG_ADDR
+#define CONFIG_RW_B_SIG_ADDR (RW_B_ADDR + RW_SIG_OFFSET)
+#endif
#endif /* __CROS_EC_RWSIG_H */