summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/g/flash.c5
-rw-r--r--chip/g/flash_info.h2
-rw-r--r--chip/g/upgrade.c19
-rw-r--r--chip/g/upgrade_fw.c17
-rw-r--r--common/ap_ro_integrity_check.c3
5 files changed, 38 insertions, 8 deletions
diff --git a/chip/g/flash.c b/chip/g/flash.c
index 4829c986c8..7812bb52e3 100644
--- a/chip/g/flash.c
+++ b/chip/g/flash.c
@@ -464,6 +464,11 @@ void flash_open_ro_window(uint32_t offset, size_t size_b)
GWRITE_FIELD(GLOBALSEC, FLASH_REGION6_CTRL, WR_EN, 1);
}
+void flash_close_ro_window(void)
+{
+ GWRITE_FIELD(GLOBALSEC, FLASH_REGION6_CTRL, WR_EN, 0);
+}
+
#ifdef CR50_DEV
/*
* The seed is the first 32 bytes of the manufacture state space. That is all
diff --git a/chip/g/flash_info.h b/chip/g/flash_info.h
index 464eb70dbd..4267d8c4ea 100644
--- a/chip/g/flash_info.h
+++ b/chip/g/flash_info.h
@@ -36,6 +36,8 @@ void flash_info_write_disable(void);
int flash_info_physical_write(int byte_offset, int num_bytes, const char *data);
int flash_physical_info_read_word(int byte_offset, uint32_t *dst);
+/* Enable or disable write access to the backup RO section. */
void flash_open_ro_window(uint32_t offset, size_t size_b);
+void flash_close_ro_window(void);
#endif /* ! __EC_CHIP_G_FLASH_INFO_H */
diff --git a/chip/g/upgrade.c b/chip/g/upgrade.c
index 03c6a0450a..ca0fe07a8f 100644
--- a/chip/g/upgrade.c
+++ b/chip/g/upgrade.c
@@ -36,6 +36,8 @@ static int header_restored(uint32_t offset)
{
struct SignedHeader *header;
uint32_t new_size;
+ int rv;
+ bool ro_header;
header = (struct SignedHeader *)(CONFIG_PROGRAM_MEMORY_BASE + offset);
@@ -51,13 +53,20 @@ static int header_restored(uint32_t offset)
if (new_size > CONFIG_RW_SIZE)
return 0;
- if ((offset == CONFIG_RO_MEM_OFF) || (offset == CHIP_RO_B_MEM_OFF))
+ ro_header = (offset == CONFIG_RO_MEM_OFF) ||
+ (offset == CHIP_RO_B_MEM_OFF);
+ if (ro_header)
flash_open_ro_window(offset, sizeof(struct SignedHeader));
- return flash_physical_write(offset + offsetof(struct SignedHeader,
- image_size),
- sizeof(header->image_size),
- (char *)&new_size) == EC_SUCCESS;
+ /* rv is set to TRUE on success. */
+ rv = flash_physical_write(offset + offsetof(struct SignedHeader,
+ image_size),
+ sizeof(header->image_size),
+ (char *)&new_size) == EC_SUCCESS;
+ if (ro_header)
+ flash_close_ro_window();
+
+ return rv;
}
/*
diff --git a/chip/g/upgrade_fw.c b/chip/g/upgrade_fw.c
index f400b4f317..d78afb610d 100644
--- a/chip/g/upgrade_fw.c
+++ b/chip/g/upgrade_fw.c
@@ -114,13 +114,16 @@ static uint8_t check_update_chunk(uint32_t block_offset, size_t body_size)
if (block_offset == valid_sections.ro_base_offset) {
uint32_t base;
uint32_t size;
+ int rv;
base = valid_sections.ro_base_offset;
size = valid_sections.ro_top_offset -
valid_sections.ro_base_offset;
/* backup RO area write access needs to be enabled. */
flash_open_ro_window(base, size);
- if (flash_physical_erase(base, size) != EC_SUCCESS) {
+ rv = flash_physical_erase(base, size);
+ flash_close_ro_window();
+ if (rv != EC_SUCCESS) {
CPRINTF("%s:%d erase failure of 0x%x..+0x%x\n",
__func__, __LINE__, base, size);
return UPGRADE_ERASE_FAILURE;
@@ -399,6 +402,7 @@ void fw_upgrade_command_handler(void *body,
uint8_t *error_code = body; /* Cache the address for code clarity. */
size_t body_size;
uint32_t block_offset;
+ int rv;
*response_size = 1; /* One byte response unless this is a start PDU. */
@@ -506,8 +510,15 @@ void fw_upgrade_command_handler(void *body,
}
CPRINTF("at 0x%x\n", block_offset + CONFIG_PROGRAM_MEMORY_BASE);
- if (flash_physical_write(block_offset, body_size, upgrade_data)
- != EC_SUCCESS) {
+ if (block_offset < valid_sections.ro_top_offset)
+ flash_open_ro_window(valid_sections.ro_base_offset,
+ valid_sections.ro_top_offset -
+ valid_sections.ro_base_offset);
+ rv = flash_physical_write(block_offset, body_size, upgrade_data);
+ if (block_offset < valid_sections.ro_top_offset)
+ flash_close_ro_window();
+
+ if (rv != EC_SUCCESS) {
*error_code = UPGRADE_WRITE_FAILURE;
CPRINTF("%s:%d upgrade write error\n", __func__, __LINE__);
return;
diff --git a/common/ap_ro_integrity_check.c b/common/ap_ro_integrity_check.c
index 43c487cceb..0606415a62 100644
--- a/common/ap_ro_integrity_check.c
+++ b/common/ap_ro_integrity_check.c
@@ -142,6 +142,8 @@ static enum vendor_cmd_rc vc_seed_ap_ro_check(enum vendor_cmd_cc code,
rv = flash_physical_write(h1_flash_offset_ +
sizeof(check_header),
input_size, buf);
+ flash_close_ro_window();
+
if (rv != EC_SUCCESS) {
*response = ARCVE_FLASH_WRITE_FAILED;
return VENDOR_RC_WRITE_FLASH_FAIL;
@@ -258,6 +260,7 @@ static int ap_ro_info_cmd(int argc, char **argv)
*/
flash_open_ro_window(h1_flash_offset_, AP_RO_DATA_SPACE_SIZE);
flash_physical_erase(h1_flash_offset_, AP_RO_DATA_SPACE_SIZE);
+ flash_close_ro_window();
}
#endif
if ((p_chk->header.num_ranges == (uint16_t)~0) &&