summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2020-05-14 18:06:37 -0700
committerCommit Bot <commit-bot@chromium.org>2020-05-29 04:42:27 +0000
commit160f0f9f632e5a64527753d8c17399ab1ae0ff2b (patch)
tree05bb50c897eb93e6e609bae19187c7210fceb83f
parentb3b080f7e9a9f329e08d838ccaabdf7c81926609 (diff)
downloadchrome-ec-160f0f9f632e5a64527753d8c17399ab1ae0ff2b.tar.gz
close RO window after use
The code opening the RO windows to make it possible to update or enable the RO images, leaves the window open, allowing subsequent writes into the RO space. It has been acceptable until now, because RO updates are usually followed up by reboots. With introduction of the AP RO hash, there is a need to close the window (specifically, disable write access) when not in use. This patch adds a function for that and uses the new function everywhere where flash_open_ro_window() is called. BUG=b:153764696 TEST=verified successful Cr50 RO and AP RO hash updates. Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Change-Id: Ia595e5c7ce0beb1a67ef3513117984d18655a60c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2204973 Reviewed-by: Mary Ruthven <mruthven@chromium.org>
-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) &&