diff --git a/chip/stm32/flash-stm32f100.c b/chip/stm32/flash-stm32f100.c index 50f1a5b0f3..e5f11d9394 100644 --- a/chip/stm32/flash-stm32f100.c +++ b/chip/stm32/flash-stm32f100.c @@ -8,6 +8,7 @@ #include "console.h" #include "flash.h" #include "registers.h" +#include "power_button.h" #include "task.h" #include "timer.h" #include "util.h" @@ -39,6 +40,10 @@ #define PRG_LOCK 0 #define OPT_LOCK (1<<9) +/* Fake write protect switch for flash write protect development. + * TODO: Remove this when we have real write protect pin. */ +static int fake_write_protect; + static void write_optb(int byte, uint8_t value); int flash_physical_size(void) @@ -123,7 +128,7 @@ static void preserve_optb(int byte) uint8_t optb[8]; /* The byte has been reset, no need to run preserve. */ - if (*(uint8_t *)(STM32_OPTB_BASE + byte) == 0xff) + if (*(uint16_t *)(STM32_OPTB_BASE + byte) == 0xffff) return; for (i = 0; i < ARRAY_SIZE(optb); ++i) @@ -295,15 +300,61 @@ int flash_physical_get_protect(int block) void flash_physical_set_protect(int start_bank, int bank_count) { int block; + int i; + int original_val[8], val[8]; + + for (i = 0; i < 8; ++i) + original_val[i] = val[i] = read_optb(i * 2); for (block = start_bank; block < start_bank + bank_count; block++) { - int byte_off = STM32_OPTB_WRP_OFF(block/8); - uint8_t val = read_optb(byte_off) | (1 << (block % 8)); - write_optb(byte_off, val); + int byte_off = STM32_OPTB_WRP_OFF(block/8) / 2; + val[byte_off] = val[byte_off] & (~(1 << (block % 8))); } + + for (i = 0; i < 8; ++i) + if (original_val[i] != val[i]) + write_optb(i * 2, val[i]); +} + +static void unprotect_all_blocks(void) +{ + int i; + for (i = 4; i < 8; ++i) + write_optb(i * 2, 0xff); } int flash_physical_pre_init(void) { + /* Drop write protect status here. If a block should be protected, + * write protect for it will be set by pstate. */ + unprotect_all_blocks(); + return EC_SUCCESS; } + +int write_protect_asserted(void) +{ + return fake_write_protect; +} + +static int command_set_fake_wp(int argc, char **argv) +{ + int val; + char *e; + + if (argc < 2) + return EC_ERROR_PARAM_COUNT; + + val = strtoi(argv[1], &e, 0); + if (*e) + return EC_ERROR_PARAM1; + + fake_write_protect = val; + ccprintf("Fake write protect = %d\n", val); + + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(fakewp, command_set_fake_wp, + "<0 | 1>", + "Set fake write protect pin", + NULL); diff --git a/common/flash_common.c b/common/flash_common.c index c914d52672..bfd50edac5 100644 --- a/common/flash_common.c +++ b/common/flash_common.c @@ -20,13 +20,12 @@ #define PHYSICAL_BANKS (CONFIG_FLASH_PHYSICAL_SIZE / CONFIG_FLASH_BANK_SIZE) /* Persistent protection state flash offset / size / bank */ -#define PSTATE_OFFSET (CONFIG_SECTION_FLASH_PSTATE_OFF - CONFIG_FLASH_BASE) +#define PSTATE_OFFSET CONFIG_SECTION_FLASH_PSTATE_OFF #define PSTATE_SIZE CONFIG_SECTION_FLASH_PSTATE_SIZE #define PSTATE_BANK (PSTATE_OFFSET / CONFIG_FLASH_BANK_SIZE) /* Read-only firmware offset and size in units of flash banks */ -#define RO_BANK_OFFSET ((CONFIG_SECTION_RO_OFF - CONFIG_FLASH_BASE) \ - / CONFIG_FLASH_BANK_SIZE) +#define RO_BANK_OFFSET (CONFIG_SECTION_RO_OFF / CONFIG_FLASH_BANK_SIZE) #define RO_BANK_COUNT (CONFIG_SECTION_RO_SIZE / CONFIG_FLASH_BANK_SIZE) @@ -50,7 +49,10 @@ static int wp_pin_asserted(void) { #ifdef BOARD_link return write_protect_asserted(); -#elif defined(CHIP_stm32) +#elif defined(CHIP_VARIANT_stm32f100) + /* Fake write protect pin */ + return write_protect_asserted(); +#elif defined(CHIP_STM32) /* TODO (vpalatin) : write protect scheme for stm32 */ /* * Always enable write protect until we have WP pin. For developer to diff --git a/include/flash.h b/include/flash.h index 617259f0c9..d74ae19c7b 100644 --- a/include/flash.h +++ b/include/flash.h @@ -9,6 +9,7 @@ #define __CROS_EC_FLASH_H #include "common.h" +#include "config.h" #include "ec_commands.h" /* For EC_FLASH_PROTECT_* flags */ /*****************************************************************************/ @@ -41,7 +42,7 @@ int flash_physical_size(void); */ static inline char *flash_physical_dataptr(int offset) { - return (char *)offset; + return (char *)(CONFIG_FLASH_BASE + offset); } /**