summaryrefslogtreecommitdiff
path: root/common/vboot_hash.c
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2015-02-04 10:44:02 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-02-05 21:03:01 +0000
commitf8af89c40d974e79b3e69698f6d8aa98e0e40fc9 (patch)
tree9d469c96dd9240af3bff374aa93dc92a041c45bc /common/vboot_hash.c
parentc0be4409522bc53447940ac88aff455a6844427c (diff)
downloadchrome-ec-f8af89c40d974e79b3e69698f6d8aa98e0e40fc9.tar.gz
Support vboot hash and system version if flash isn't memory-mapped
Some EC chips (mec1322) use external SPI flash which is not mapped into the EC CPU's address space. These must explicitly read data from flash when calculating the vboot hash or reading the version string of the image which isn't currently loaded into code RAM. To test this bug, I used a board with known working mapped flash, and temporarily patched it to act like it didn't have mapped flash. Also add a flashread console command, useful for manually testing. BUG=chrome-os-partner:35308 BRANCH=glower,strago TEST=manual 1. Apply this patch to samus 2. Check result for 'vboot hash RW' 3. Check result for 'version' 4a. In board/samus/board.h, #undef CONFIG_FLASH_MAPPED and #define CONFIG_CMD_FLASH 4b. In chip/lm4/flash.c, add the following: int flash_physical_read(int offset, int size, char *data) { const char *src; if (offset > CONFIG_FLASH_SIZE || offset + size > CONFIG_FLASH_SIZE) return EC_ERROR_INVAL; src = (const char *)((uintptr_t)CONFIG_FLASH_BASE + offset); memcpy(data, src, size); return EC_SUCCESS; } Steps 4a,4b will make the LM4 chip act like it doesn't have memory-mapped flash. 5. From the dev system, util/flash_ec --board=samus --ro 6. Check result for 'vboot hash RW'. Should be same as 2. 7. Check result for 'version' for RW version. Should be same as in 3. 8. From the dev system, util/flash_ec --board=samus 9. sysjump rw 10. Check result for 'version' for RO version. Should be same as in 3. 11. Compare 'flashread 0x100 0x100' with 'md 0x100 0x40'. The results should be the same (but endian-swapped, since flashread is byte ordered and md is 32-bit ordered). 12. Revert changes from steps 4a-4b. Change-Id: I951d6f5603a84e326740936e4e84dfe6296a0f59 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/246200 Reviewed-by: Shawn N <shawnn@chromium.org>
Diffstat (limited to 'common/vboot_hash.c')
-rw-r--r--common/vboot_hash.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/common/vboot_hash.c b/common/vboot_hash.c
index e7717e96db..f2fa839c67 100644
--- a/common/vboot_hash.c
+++ b/common/vboot_hash.c
@@ -7,9 +7,11 @@
#include "common.h"
#include "console.h"
+#include "flash.h"
#include "hooks.h"
#include "host_command.h"
#include "sha256.h"
+#include "shared_mem.h"
#include "system.h"
#include "task.h"
#include "timer.h"
@@ -56,6 +58,37 @@ static void vboot_hash_abort(void)
}
}
+#ifndef CONFIG_FLASH_MAPPED
+
+static void vboot_hash_next_chunk(void);
+
+static int read_and_hash_chunk(int offset, int size)
+{
+ char *buf;
+ int rv;
+
+ rv = shared_mem_acquire(size, &buf);
+ if (rv == EC_ERROR_BUSY) {
+ /* Couldn't update hash right now; try again later */
+ hook_call_deferred(vboot_hash_next_chunk, WORK_INTERVAL_US);
+ return rv;
+ } else if (rv != EC_SUCCESS) {
+ vboot_hash_abort();
+ return rv;
+ }
+
+ rv = flash_read(offset, size, buf);
+ if (rv == EC_SUCCESS)
+ SHA256_update(&ctx, (const uint8_t *)buf, size);
+ else
+ vboot_hash_abort();
+
+ shared_mem_release(buf);
+ return rv;
+}
+
+#endif
+
/**
* Do next chunk of hashing work, if any.
*/
@@ -72,8 +105,14 @@ static void vboot_hash_next_chunk(void)
/* Compute the next chunk of hash */
size = MIN(CHUNK_SIZE, data_size - curr_pos);
+
+#ifdef CONFIG_FLASH_MAPPED
SHA256_update(&ctx, (const uint8_t *)(CONFIG_FLASH_BASE +
data_offset + curr_pos), size);
+#else
+ if (read_and_hash_chunk(data_offset + curr_pos, size) != EC_SUCCESS)
+ return;
+#endif
curr_pos += size;
if (curr_pos >= data_size) {