diff options
author | Nadim Taha <ntaha@google.com> | 2016-01-26 19:25:35 -0800 |
---|---|---|
committer | Nadim Taha <ntaha@chromium.org> | 2016-01-28 20:58:32 +0000 |
commit | 8f39d1d51933d21fd243d54ac0f6daa87063ca0a (patch) | |
tree | c947861338c75061bb0c4f38e6673d2ee93b3d7a /chip/g/loader | |
parent | f8f0618ca4baf7bee03bebefe083c3911a77e52b (diff) | |
download | chrome-ec-8f39d1d51933d21fd243d54ac0f6daa87063ca0a.tar.gz |
Modified the bootloader to check PMU_PWRDN_SCRATCH30 and load the newer
of the two RW images if set.
Imported the Haven "signed_header.h" file into chip/g and fixed prior
references to the util/ copy.
BUG=none
BRANCH=none
TEST=Went through a full update. Simulated a botched update.
Change-Id: I1e4c006ef391270a7e350fea6f43cc1a1b057d0e
Signed-off-by: Nadim Taha <ntaha@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/324109
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Diffstat (limited to 'chip/g/loader')
-rw-r--r-- | chip/g/loader/launch.c | 7 | ||||
-rw-r--r-- | chip/g/loader/main.c | 54 |
2 files changed, 54 insertions, 7 deletions
diff --git a/chip/g/loader/launch.c b/chip/g/loader/launch.c index 3e41756ae9..56314bb46b 100644 --- a/chip/g/loader/launch.c +++ b/chip/g/loader/launch.c @@ -9,11 +9,10 @@ #include "registers.h" #include "rom_flash.h" #include "setup.h" +#include "signed_header.h" #include "uart.h" #include "verify.h" -#include "util/signer/common/signed_header.h" - static int unlockedForExecution(void) { return GREAD_FIELD(GLOBALSEC, SB_COMP_STATUS, SB_BL_SIG_MATCH); @@ -44,7 +43,7 @@ void tryLaunch(uint32_t adr, size_t max_size) int i; uint32_t major; const uint32_t FAKE_rom_hash[8] = {1, 2, 3, 4, 5, 6, 7, 8}; - const SignedHeader *hdr = (const SignedHeader *)(adr); + const struct SignedHeader *hdr = (const struct SignedHeader *)(adr); memset(&hashes, 0, sizeof(hashes)); @@ -77,7 +76,7 @@ void tryLaunch(uint32_t adr, size_t max_size) GWRITE_FIELD(GLOBALSEC, CPU0_I_STAGING_REGION1_CTRL, EN, 1); GWRITE_FIELD(GLOBALSEC, CPU0_I_STAGING_REGION1_CTRL, RD_EN, 1); DCRYPTO_SHA256_hash((uint8_t *) &hdr->tag, - hdr->image_size - offsetof(SignedHeader, tag), + hdr->image_size - offsetof(struct SignedHeader, tag), (uint8_t *) hashes.img_hash); VERBOSE("img_hash : %.32h\n", hashes.img_hash); diff --git a/chip/g/loader/main.c b/chip/g/loader/main.c index afa4d0067a..d3b60dd91c 100644 --- a/chip/g/loader/main.c +++ b/chip/g/loader/main.c @@ -8,6 +8,7 @@ #include "printf.h" #include "registers.h" #include "setup.h" +#include "signed_header.h" #include "system.h" #include "trng.h" #include "uart.h" @@ -59,8 +60,27 @@ void panic_printf(const char *format, ...) va_end(args); } +/* Returns 1 if version a is newer, 0 otherwise. */ +int is_newer_than(const struct SignedHeader *a, const struct SignedHeader *b) +{ + if (a->epoch_ > b->epoch_) + return 1; + if (a->epoch_ < b->epoch_) + return 0; + if (a->major_ > b->major_) + return 1; + if (a->major_ < b->major_) + return 0; + if (a->minor_ > b->minor_) + return 1; + if (a->minor_ < b->minor_) + return 0; + return 0; +} + int main(void) { + const struct SignedHeader *a, *b, *first, *second; init_trng(); uart_init(); debug_printf("\n\n%s bootloader, %8u_%u@%u, %sUSB, %s crypto\n", @@ -72,10 +92,38 @@ int main(void) GC_CONST_SWDP_FPGA_CONFIG_NOUSB_CRYPTO) ? "full" : "8x8"); unlockFlashForRW(); - /* Trying RW A only for now */ - tryLaunch(CONFIG_PROGRAM_MEMORY_BASE + CONFIG_RW_MEM_OFF, - CONFIG_FLASH_SIZE/2 - CONFIG_RW_MEM_OFF); + a = (const struct SignedHeader *)(CONFIG_PROGRAM_MEMORY_BASE + + CONFIG_RW_MEM_OFF); + b = (const struct SignedHeader *)(CONFIG_PROGRAM_MEMORY_BASE + + CONFIG_RW_B_MEM_OFF); + /* Default to loading the older version first. + * Run from bank a if the versions are equal. + */ + if (is_newer_than(a, b)) { + first = b; + second = a; + } else { + first = a; + second = b; + } + if (GREG32(PMU, PWRDN_SCRATCH30) == 0xcafebabe) { + /* Launch from the alternate bank first. + * This knob will be used to attempt to load the newer version + * after an update and to run from bank b in the face of flash + * integrity issues. + */ + debug_printf("PWRDN_SCRATCH30 set to magic value\n"); + GREG32(PMU, PWRDN_SCRATCH30) = 0x0; + a = first; + first = second; + second = a; + } + tryLaunch((uint32_t)first, CONFIG_FLASH_SIZE/2 - CONFIG_RW_MEM_OFF); + debug_printf("Failed to launch.\n"); + debug_printf("Attempting to load the alternate image.\n"); + tryLaunch((uint32_t)second, CONFIG_FLASH_SIZE/2 - CONFIG_RW_MEM_OFF); debug_printf("No valid image found, not sure what to do...\n"); + /* TODO: Some applications might want to reboot instead. */ halt(); return 1; } |