summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2016-09-14 15:42:56 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-09-16 21:59:08 -0700
commitfd418235953ed853bbb2093d307679604e539902 (patch)
treeaa2a50afcffb789c5e87c1ef5e163e17470b3da2
parent258bc48bacf948e7f95b98bfc847c3cc0d5f515d (diff)
downloadchrome-ec-fd418235953ed853bbb2093d307679604e539902.tar.gz
flash: Call lock function prior to mapped external read
Mapped read access to external flash may conflict with direct access through SPI commands, so call a chip-level function to lock access prior to doing such reads. BUG=chrome-os-partner:55781 BRANCH=Gru TEST=Verify 'ver' still works fine on kevin, and vboot hashing completes successfully. Change-Id: I009d6d5ee61c83260fb49ad4ee137fa3f4cd625a Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/385165 Tested-by: Mulin Chao <mlchao@nuvoton.com> Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Mulin Chao <mlchao@nuvoton.com> (cherry picked from commit a7f3e3fa376731709f4823a0c1d464b4d1deae14) Reviewed-on: https://chromium-review.googlesource.com/386446 Commit-Ready: Shawn N <shawnn@chromium.org> Tested-by: Shawn N <shawnn@chromium.org> Reviewed-by: Shawn N <shawnn@chromium.org>
-rw-r--r--chip/npcx/flash.c7
-rw-r--r--common/flash.c9
-rw-r--r--common/system.c22
-rw-r--r--common/vboot_hash.c2
-rw-r--r--include/flash.h10
5 files changed, 37 insertions, 13 deletions
diff --git a/chip/npcx/flash.c b/chip/npcx/flash.c
index 95b4796bb3..ac1a06078d 100644
--- a/chip/npcx/flash.c
+++ b/chip/npcx/flash.c
@@ -777,6 +777,13 @@ int flash_pre_init(void)
return EC_SUCCESS;
}
+void flash_lock_mapped_storage(int lock)
+{
+ /*
+ * TODO(crosbug.com/p/55781): Add mutex to ensure no conflict between
+ * mapped read and regular flash ops.
+ */
+}
/*****************************************************************************/
/* Console commands */
diff --git a/common/flash.c b/common/flash.c
index cdd4219394..05489b7b57 100644
--- a/common/flash.c
+++ b/common/flash.c
@@ -370,9 +370,14 @@ int flash_is_erased(uint32_t offset, int size)
(const char **)&ptr) < 0)
return 0;
+ flash_lock_mapped_storage(1);
for (size /= sizeof(uint32_t); size > 0; size--, ptr++)
- if (*ptr != CONFIG_FLASH_ERASED_VALUE32)
+ if (*ptr != CONFIG_FLASH_ERASED_VALUE32) {
+ flash_lock_mapped_storage(0);
return 0;
+ }
+
+ flash_lock_mapped_storage(0);
#else
/* Read flash a chunk at a time */
uint32_t buf[8];
@@ -406,7 +411,9 @@ int flash_read(int offset, int size, char *data)
if (flash_dataptr(offset, size, 1, &src) < 0)
return EC_ERROR_INVAL;
+ flash_lock_mapped_storage(1);
memcpy(data, src, size);
+ flash_lock_mapped_storage(0);
return EC_SUCCESS;
#else
return flash_physical_read(offset, size, data);
diff --git a/common/system.c b/common/system.c
index 9c1d53b60b..4488f45e66 100644
--- a/common/system.c
+++ b/common/system.c
@@ -407,8 +407,10 @@ int system_get_image_used(enum system_image_copy_t copy)
} while (*image != 0xea);
#else
image = (const uint8_t *)(image_offset + CONFIG_MAPPED_STORAGE_BASE);
+ flash_lock_mapped_storage(1);
for (size--; size > 0 && image[size] != 0xea; size--)
;
+ flash_lock_mapped_storage(0);
#endif
return size ? size + 1 : 0; /* 0xea byte IS part of the image */
@@ -613,12 +615,9 @@ int system_run_image_copy(enum system_image_copy_t copy)
__attribute__((weak)) /* Weird chips may need their own implementations */
const char *system_get_version(enum system_image_copy_t copy)
{
-#ifndef CONFIG_MAPPED_STORAGE
- static struct version_struct vdata;
-#endif
+ static struct version_struct v;
uintptr_t addr;
- const struct version_struct *v;
enum system_image_copy_t active_copy = system_get_image_copy();
/* Handle version of current image */
@@ -645,21 +644,20 @@ const char *system_get_version(enum system_image_copy_t copy)
#ifdef CONFIG_MAPPED_STORAGE
addr += CONFIG_MAPPED_STORAGE_BASE;
- v = (const struct version_struct *)addr;
+ flash_lock_mapped_storage(1);
+ memcpy(&v, (const void *)addr, sizeof(v));
+ flash_lock_mapped_storage(0);
#else
-
/* Read the version struct from flash into a buffer. */
- if (flash_read(addr, sizeof(vdata), (char *)&vdata))
+ if (flash_read(addr, sizeof(v), (char *)&v))
return "";
-
- v = &vdata;
#endif
/* Make sure the version struct cookies match before returning the
* version string. */
- if (v->cookie1 == version_data.cookie1 &&
- v->cookie2 == version_data.cookie2)
- return v->version;
+ if (v.cookie1 == version_data.cookie1 &&
+ v.cookie2 == version_data.cookie2)
+ return v.version;
return "";
}
diff --git a/common/vboot_hash.c b/common/vboot_hash.c
index 8de7d8931e..136efe942a 100644
--- a/common/vboot_hash.c
+++ b/common/vboot_hash.c
@@ -117,8 +117,10 @@ static void vboot_hash_next_chunk(void)
size = MIN(CHUNK_SIZE, data_size - curr_pos);
#ifdef CONFIG_MAPPED_STORAGE
+ flash_lock_mapped_storage(1);
SHA256_update(&ctx, (const uint8_t *)(CONFIG_MAPPED_STORAGE_BASE +
data_offset + curr_pos), size);
+ flash_lock_mapped_storage(0);
#else
if (read_and_hash_chunk(data_offset + curr_pos, size) != EC_SUCCESS)
return;
diff --git a/include/flash.h b/include/flash.h
index 03a6e89c25..e0873028f5 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -261,4 +261,14 @@ const char *flash_read_serial(void);
*/
int flash_write_serial(const char *serialno);
+/**
+ * Lock or unlock HW necessary for mapped storage read.
+ *
+ * @param lock 1 to lock, 0 to unlock.
+ */
+#ifdef CONFIG_EXTERNAL_STORAGE
+void flash_lock_mapped_storage(int lock);
+#else
+static inline void flash_lock_mapped_storage(int lock) { };
+#endif /* CONFIG_EXTERNAL_STORAGE */
#endif /* __CROS_EC_FLASH_H */