diff options
author | Vic Yang <victoryang@chromium.org> | 2013-05-26 18:46:55 +0800 |
---|---|---|
committer | ChromeBot <chrome-bot@google.com> | 2013-06-03 14:34:10 -0700 |
commit | 80105a95569c36b7a4d372c7e74f086ad27f5492 (patch) | |
tree | 368706c3d44566cb696ebf98018d1dfb7bcd7f80 /chip/host/flash.c | |
parent | 1806f521955623770405778a742d0398cae028a2 (diff) | |
download | chrome-ec-80105a95569c36b7a4d372c7e74f086ad27f5492.tar.gz |
Enable flash unit test on emulator
BUG=chrome-os-partner:19236
TEST=Pass all tests
BRANCH=None
Change-Id: I09276292499b94b2d4810830de51e4c63a9b7342
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/56704
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'chip/host/flash.c')
-rw-r--r-- | chip/host/flash.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/chip/host/flash.c b/chip/host/flash.c new file mode 100644 index 0000000000..24023c5155 --- /dev/null +++ b/chip/host/flash.c @@ -0,0 +1,135 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Flash module for emulator */ + +#include <stdio.h> + +#include "config.h" +#include "flash.h" +#include "persistence.h" +#include "util.h" + +char __host_flash[CONFIG_FLASH_PHYSICAL_SIZE]; +uint8_t __host_flash_protect[PHYSICAL_BANKS]; + +static int flash_check_protect(int offset, int size) +{ + int first_bank = offset / CONFIG_FLASH_BANK_SIZE; + int last_bank = DIV_ROUND_UP(offset + size + 1, + CONFIG_FLASH_BANK_SIZE); + int bank; + + for (bank = first_bank; bank <= last_bank; ++bank) + if (__host_flash_protect[bank]) + return 1; + return 0; +} + +static void flash_set_persistent(void) +{ + FILE *f = get_persistent_storage("flash", "wb"); + int sz; + + ASSERT(f != NULL); + + sz = fwrite(__host_flash, sizeof(__host_flash), 1, f); + ASSERT(sz == 1); + + release_persistent_storage(f); +} + +static void flash_get_persistent(void) +{ + FILE *f = get_persistent_storage("flash", "rb"); + + if (f == NULL) { + fprintf(stderr, + "No flash storage found. Initializing to 0xff.\n"); + memset(__host_flash, 0xff, sizeof(__host_flash)); + return; + } + + fread(__host_flash, sizeof(__host_flash), 1, f); + + release_persistent_storage(f); +} + +int flash_physical_write(int offset, int size, const char *data) +{ + ASSERT((size & (CONFIG_FLASH_WRITE_SIZE - 1)) == 0); + + if (flash_check_protect(offset, size)) + return EC_ERROR_ACCESS_DENIED; + + memcpy(__host_flash + offset, data, size); + flash_set_persistent(); + + return EC_SUCCESS; +} + +int flash_physical_erase(int offset, int size) +{ + ASSERT((size & (CONFIG_FLASH_ERASE_SIZE - 1)) == 0); + + if (flash_check_protect(offset, size)) + return EC_ERROR_ACCESS_DENIED; + + memset(__host_flash + offset, 0xff, size); + flash_set_persistent(); + + return EC_SUCCESS; +} + +int flash_physical_get_protect(int bank) +{ + return __host_flash_protect[bank]; +} + +uint32_t flash_physical_get_protect_flags(void) +{ + int i; + uint32_t flags = EC_FLASH_PROTECT_ALL_NOW; + + for (i = 0; i < PHYSICAL_BANKS; ++i) + if (__host_flash_protect[i] == 0) + flags = 0; + + return flags; +} + +int flash_physical_protect_now(int all) +{ + memset(__host_flash_protect, 1, all ? PHYSICAL_BANKS : RO_BANK_COUNT); + return EC_SUCCESS; +} + +int flash_pre_init(void) +{ + uint32_t prot_flags; + + flash_get_persistent(); + + prot_flags = flash_get_protect(); + + if (prot_flags & EC_FLASH_PROTECT_GPIO_ASSERTED) { + /* + * Write protect is asserted. If we want RO flash protected, + * protect it now. + */ + if ((prot_flags & EC_FLASH_PROTECT_RO_AT_BOOT) && + !(prot_flags & EC_FLASH_PROTECT_RO_NOW)) { + int rv = flash_set_protect(EC_FLASH_PROTECT_RO_NOW, + EC_FLASH_PROTECT_RO_NOW); + if (rv) + return rv; + + /* Re-read flags */ + prot_flags = flash_get_protect(); + } + } + + return EC_SUCCESS; +} |