diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2015-01-02 15:03:42 -0800 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-01-05 19:10:27 +0000 |
commit | 9ce66a98b28df3e832b822bdec24e32e69d57e08 (patch) | |
tree | 8896694e47fedb83bd482a4c7da7df341e661bf2 /board/zinger | |
parent | 05b0b9774a1c255e6332dc11f644b5e176f4f365 (diff) | |
download | chrome-ec-9ce66a98b28df3e832b822bdec24e32e69d57e08.tar.gz |
zinger: enable RO partition write-protection
Check the flash protection at startup, if the RDP is still at level 0
(no read protection) or if the RO partition is not write protected :
- set the write protection on the first 16KB of flash (4 LSB of WRP0)
- push the RDP to level 1, so SWD/serial monitor needs to fully erase
the part before re-writing the code or the write-protection.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=samus
BUG=chrome-os-partner:34935
TEST=dump the content of the option bytes.
Change-Id: I11af64365a6fbc34327b2e463eb8e2d369ffacd2
Reviewed-on: https://chromium-review.googlesource.com/238262
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
Trybot-Ready: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'board/zinger')
-rw-r--r-- | board/zinger/board.c | 4 | ||||
-rw-r--r-- | board/zinger/board.h | 2 | ||||
-rw-r--r-- | board/zinger/hardware.c | 79 |
3 files changed, 85 insertions, 0 deletions
diff --git a/board/zinger/board.c b/board/zinger/board.c index 3ea9850015..e06da587da 100644 --- a/board/zinger/board.c +++ b/board/zinger/board.c @@ -83,6 +83,10 @@ int main(void) debug_printf("Power supply started ... %s\n", is_ro_mode() ? "RO" : "RW"); + /* the RO partition protection is not enabled : do it */ + if (!flash_physical_is_permanently_protected()) + flash_physical_permanent_protect(); + /* Verify RW firmware and use it if valid */ if (is_ro_mode() && check_rw_valid()) jump_to_rw(); diff --git a/board/zinger/board.h b/board/zinger/board.h index 79d60514eb..e307c6ff27 100644 --- a/board/zinger/board.h +++ b/board/zinger/board.h @@ -97,6 +97,8 @@ extern volatile uint32_t last_event; /* RW section flashing */ int flash_erase_rw(void); int flash_write_rw(int offset, int size, const char *data); +void flash_physical_permanent_protect(void); +int flash_physical_is_permanently_protected(void); uint8_t *flash_hash_rw(void); int is_ro_mode(void); diff --git a/board/zinger/hardware.c b/board/zinger/hardware.c index 1713ca342e..31f57da6a3 100644 --- a/board/zinger/hardware.c +++ b/board/zinger/hardware.c @@ -296,8 +296,11 @@ int adc_disable_watchdog(void) /* Lock bits for FLASH_CR register */ #define PG (1<<0) #define PER (1<<1) +#define OPTPG (1<<4) +#define OPTER (1<<5) #define STRT (1<<6) #define CR_LOCK (1<<7) +#define OPTWRE (1<<9) int flash_physical_write(int offset, int size, const char *data) { @@ -399,3 +402,79 @@ exit_er: return res; } + +static void unlock_erase_optb(void) +{ + int i; + + /* Clear previous error status */ + STM32_FLASH_SR = 0x34; + + /* wait to be ready */ + for (i = 0; (STM32_FLASH_SR & 1) && (i < FLASH_TIMEOUT_LOOP); i++) + ; + + /* Unlock the option bytes access */ + if (STM32_FLASH_CR & CR_LOCK) { + STM32_FLASH_KEYR = KEY1; + STM32_FLASH_KEYR = KEY2; + } + if (!(STM32_FLASH_CR & OPTWRE)) { + STM32_FLASH_OPTKEYR = KEY1; + STM32_FLASH_OPTKEYR = KEY2; + } + /* Must be set in 2 separate lines. */ + STM32_FLASH_CR |= OPTER; + STM32_FLASH_CR |= STRT; + + /* wait to be ready */ + for (i = 0; (STM32_FLASH_SR & 1) && (i < FLASH_TIMEOUT_LOOP); i++) + ; + /* reset erasing bits */ + STM32_FLASH_CR = OPTWRE; +} + + +static void write_optb(int byte, uint8_t value) +{ + volatile int16_t *hword = (uint16_t *)(STM32_OPTB_BASE + byte); + int i; + + /* Clear previous error status */ + STM32_FLASH_SR = 0x34; + + /* set OPTPG bit */ + STM32_FLASH_CR |= OPTPG; + + *hword = ((~value) << STM32_OPTB_COMPL_SHIFT) | value; + + /* reset OPTPG bit */ + STM32_FLASH_CR = OPTWRE; + + /* wait to be ready */ + for (i = 0; (STM32_FLASH_SR & 1) && (i < FLASH_TIMEOUT_LOOP); i++) + ; +} + +void flash_physical_permanent_protect(void) +{ + unlock_erase_optb(); + /* protect the 16KB RO partition against write/erase in WRP0 */ + write_optb(8, 0xF0); + /* Set RDP to level 1 to prevent disabling the protection */ + write_optb(0, 0x11); + /* Reset by using OBL_LAUNCH to take changes into account */ + asm volatile("cpsid i"); + STM32_FLASH_CR |= STM32_FLASH_CR_OBL_LAUNCH; + /* Spin and wait for reboot; should never return */ + while (1) + ; +} + +int flash_physical_is_permanently_protected(void) +{ + /* if RDP is still at level 0, the flash protection is not in place */ + return (STM32_FLASH_OBR & STM32_FLASH_OBR_RDP_MASK) && + /* the low 16KB (RO partition) are write-protected */ + !(STM32_FLASH_WRPR & 0xF); +} |