summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2013-05-26 18:46:55 +0800
committerChromeBot <chrome-bot@google.com>2013-06-03 14:34:10 -0700
commit80105a95569c36b7a4d372c7e74f086ad27f5492 (patch)
tree368706c3d44566cb696ebf98018d1dfb7bcd7f80
parent1806f521955623770405778a742d0398cae028a2 (diff)
downloadchrome-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>
-rw-r--r--board/host/board.c1
-rw-r--r--board/host/board.h3
-rw-r--r--chip/host/build.mk2
-rw-r--r--chip/host/config.h11
-rw-r--r--chip/host/flash.c135
-rw-r--r--chip/host/registers.h11
-rw-r--r--chip/lm4/config.h1
-rw-r--r--chip/stm32/config.h1
-rw-r--r--common/build.mk3
-rw-r--r--common/system_common.c2
-rw-r--r--common/test_util.c5
-rw-r--r--core/host/main.c3
-rw-r--r--include/test_util.h2
-rw-r--r--test/build.mk2
-rw-r--r--test/flash.c52
15 files changed, 211 insertions, 23 deletions
diff --git a/board/host/board.c b/board/host/board.c
index 10d8d1d3c4..0eda62b0ee 100644
--- a/board/host/board.c
+++ b/board/host/board.c
@@ -12,6 +12,7 @@ const struct gpio_info gpio_list[GPIO_COUNT] = {
{"EC_INT", 0, 0, 0, 0},
{"LID_OPEN", 0, 0, 0, 0},
{"POWER_BUTTON_L", 0, 0, 0, 0},
+ {"WP", 0, 0, 0, 0},
};
static int dummy_temp_get_val(int idx, int *temp_ptr)
diff --git a/board/host/board.h b/board/host/board.h
index 553f55c76c..632596b64d 100644
--- a/board/host/board.h
+++ b/board/host/board.h
@@ -20,10 +20,13 @@
#define CONFIG_POWER_BUTTON
#define CONFIG_TEMP_SENSOR
+#define CONFIG_WP_ACTIVE_HIGH
+
enum gpio_signal {
GPIO_EC_INT,
GPIO_LID_OPEN,
GPIO_POWER_BUTTON_L,
+ GPIO_WP,
GPIO_COUNT
};
diff --git a/chip/host/build.mk b/chip/host/build.mk
index 110daefb8b..866c84da20 100644
--- a/chip/host/build.mk
+++ b/chip/host/build.mk
@@ -8,5 +8,5 @@
CORE:=host
-chip-y=system.o gpio.o uart.o persistence.o
+chip-y=system.o gpio.o uart.o persistence.o flash.o
chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o
diff --git a/chip/host/config.h b/chip/host/config.h
index c296e1b7cc..9825f086e9 100644
--- a/chip/host/config.h
+++ b/chip/host/config.h
@@ -9,14 +9,16 @@
#define __CONFIG_H
/* Memory mapping */
-#define CONFIG_FLASH_BASE 0x08000000
#define CONFIG_FLASH_PHYSICAL_SIZE 0x00020000
#define CONFIG_FLASH_SIZE CONFIG_FLASH_PHYSICAL_SIZE
+extern char __host_flash[CONFIG_FLASH_PHYSICAL_SIZE];
+
+#define CONFIG_FLASH_BASE ((uintptr_t)__host_flash)
#define CONFIG_FLASH_BANK_SIZE 0x1000
#define CONFIG_FLASH_ERASE_SIZE 0x0400 /* erase bank size */
#define CONFIG_FLASH_WRITE_SIZE 0x0002 /* minimum write size */
-#define CONFIG_RAM_BASE 0x20000000
-#define CONFIG_RAM_SIZE 0x00002000
+#define CONFIG_RAM_BASE 0x0 /* Not supported */
+#define CONFIG_RAM_SIZE 0x0 /* Not supported */
/* Size of one firmware image in flash */
#define CONFIG_FW_IMAGE_SIZE (64 * 1024)
@@ -28,6 +30,9 @@
#define CONFIG_FW_WP_RO_OFF CONFIG_FW_RO_OFF
#define CONFIG_FW_WP_RO_SIZE CONFIG_FW_IMAGE_SIZE
+/* Features */
+#define CONFIG_FLASH
+
/*
* Put this after RO to give RW more space and make RO write protect region
* contiguous.
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;
+}
diff --git a/chip/host/registers.h b/chip/host/registers.h
new file mode 100644
index 0000000000..0ee68b8e23
--- /dev/null
+++ b/chip/host/registers.h
@@ -0,0 +1,11 @@
+/* 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.
+ */
+
+/* Empty registers header for emulator */
+
+/*
+ * There is no register for emulator, but this file exists to prevent
+ * compilation failure if any file includes registers.h
+ */
diff --git a/chip/lm4/config.h b/chip/lm4/config.h
index 609a88ae90..6be1085c02 100644
--- a/chip/lm4/config.h
+++ b/chip/lm4/config.h
@@ -101,6 +101,7 @@
/* Optional features present on this chip */
#define CONFIG_ADC
#define CONFIG_FLASH
+#define CONFIG_FMAP
#define CONFIG_FPU
#define CONFIG_I2C
#define CONFIG_WATCHDOG
diff --git a/chip/stm32/config.h b/chip/stm32/config.h
index d4107b1d36..6eb8a48b51 100644
--- a/chip/stm32/config.h
+++ b/chip/stm32/config.h
@@ -39,6 +39,7 @@
/* support programming on-chip flash */
#define CONFIG_FLASH
+#define CONFIG_FMAP
/* build with assertions and debug messages */
#define CONFIG_DEBUG
diff --git a/common/build.mk b/common/build.mk
index 5df925b7d0..912097ce46 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -22,7 +22,8 @@ common-$(CONFIG_EOPTION)+=eoption.o
common-$(CONFIG_EXTPOWER_GPIO)+=extpower_gpio.o
common-$(CONFIG_EXTPOWER_SNOW)+=extpower_snow.o
common-$(CONFIG_EXTPOWER_USB)+=extpower_usb.o
-common-$(CONFIG_FLASH)+=flash_common.o fmap.o
+common-$(CONFIG_FLASH)+=flash_common.o
+common-$(CONFIG_FMAP)+=fmap.o
common-$(CONFIG_I2C)+=i2c_common.o
common-$(CONFIG_I2C_ARBITRATION)+=i2c_arbitration.o
common-$(CONFIG_IR357x)+=ir357x.o
diff --git a/common/system_common.c b/common/system_common.c
index ac85c8051b..03febba603 100644
--- a/common/system_common.c
+++ b/common/system_common.c
@@ -256,7 +256,7 @@ int system_get_image_used(enum system_image_copy_t copy)
return size ? size + 1 : 0; /* 0xea byte IS part of the image */
}
-int system_unsafe_to_overwrite(uint32_t offset, uint32_t size)
+test_mockable int system_unsafe_to_overwrite(uint32_t offset, uint32_t size)
{
uint32_t r_offset;
uint32_t r_size;
diff --git a/common/test_util.c b/common/test_util.c
index 8594f3468e..7cd9850645 100644
--- a/common/test_util.c
+++ b/common/test_util.c
@@ -27,6 +27,11 @@ void test_print_result(void)
ccprintf("Pass!\n");
}
+int test_get_error_count(void)
+{
+ return __test_error_count;
+}
+
static int command_run_test(int argc, char **argv)
{
run_test();
diff --git a/core/host/main.c b/core/host/main.c
index e96dc40faa..ba8ec95dcf 100644
--- a/core/host/main.c
+++ b/core/host/main.c
@@ -5,12 +5,15 @@
/* Entry point of unit test executable */
+#include "flash.h"
#include "hooks.h"
#include "task.h"
#include "timer.h"
int main(void)
{
+ flash_pre_init();
+
timer_init();
hook_init();
diff --git a/include/test_util.h b/include/test_util.h
index e940beda1c..8b99c560d2 100644
--- a/include/test_util.h
+++ b/include/test_util.h
@@ -56,6 +56,8 @@ void test_reset(void);
void test_print_result(void);
+int test_get_error_count(void);
+
extern int __test_error_count;
#endif /* __CROS_EC_TEST_UTIL_H */
diff --git a/test/build.mk b/test/build.mk
index 17cb6c9853..90f775de0a 100644
--- a/test/build.mk
+++ b/test/build.mk
@@ -28,7 +28,7 @@ test-list-$(BOARD_peppy)=
# Emulator tests
test-list-host=mutex pingpong utils kb_scan kb_mkbp lid_sw power_button hooks
-test-list-host+=thermal
+test-list-host+=thermal flash
flash-y=flash.o
hooks-y=hooks.o
diff --git a/test/flash.c b/test/flash.c
index cf6ee659fd..33f47543bd 100644
--- a/test/flash.c
+++ b/test/flash.c
@@ -17,8 +17,6 @@
#include "timer.h"
#include "util.h"
-static int error_count;
-
static int last_write_offset;
static int last_write_size;
static char last_write_data[64];
@@ -33,9 +31,21 @@ static int mock_wp = -1;
#define TEST_STATE_STEP_3 (1 << 2)
#define TEST_STATE_BOOT_WP_ON (1 << 3)
#define TEST_STATE_PASSED (1 << 4)
+#define TEST_STATE_FAILED (1 << 5)
#define CLEAN_UP_FLAG_PASSED TEST_STATE_PASSED
-#define CLEAN_UP_FLAG_FAILED 0
+#define CLEAN_UP_FLAG_FAILED TEST_STATE_FAILED
+
+/*****************************************************************************/
+/* Emulator-only mock functions */
+#ifdef EMU_BUILD
+static int mock_is_running_img;
+
+int system_unsafe_to_overwrite(uint32_t offset, uint32_t size)
+{
+ return mock_is_running_img;
+}
+#endif
/*****************************************************************************/
/* Mock functions */
@@ -240,6 +250,10 @@ static int test_overwrite_current(void)
size = CONFIG_FW_RW_SIZE;
}
+#ifdef EMU_BUILD
+ mock_is_running_img = 1;
+#endif
+
VERIFY_NO_ERASE(offset, sizeof(d));
VERIFY_NO_ERASE(offset + size - sizeof(d), sizeof(d));
VERIFY_NO_WRITE(offset, sizeof(d), d);
@@ -262,6 +276,10 @@ static int test_overwrite_other(void)
size = CONFIG_FW_RW_SIZE;
}
+#ifdef EMU_BUILD
+ mock_is_running_img = 0;
+#endif
+
VERIFY_ERASE(offset, sizeof(d));
VERIFY_ERASE(offset + size - sizeof(d), sizeof(d));
VERIFY_WRITE(offset, sizeof(d), d);
@@ -344,43 +362,37 @@ static void reboot_to_next_step(uint32_t step)
static void run_test_step1(void)
{
- error_count = 0;
+ test_reset();
mock_wp = 0;
RUN_TEST(test_overwrite_current);
RUN_TEST(test_overwrite_other);
RUN_TEST(test_write_protect);
- if (error_count) {
- ccprintf("Failed %d tests!\n", error_count);
+ if (test_get_error_count())
reboot_to_clean_up(CLEAN_UP_FLAG_FAILED);
- } else {
+ else
reboot_to_next_step(TEST_STATE_STEP_2 | TEST_STATE_BOOT_WP_ON);
- }
}
static void run_test_step2(void)
{
RUN_TEST(test_boot_write_protect);
- if (error_count) {
- ccprintf("Failed %d tests!\n", error_count);
+ if (test_get_error_count())
reboot_to_clean_up(CLEAN_UP_FLAG_FAILED);
- } else {
+ else
reboot_to_next_step(TEST_STATE_STEP_3);
- }
}
static void run_test_step3(void)
{
RUN_TEST(test_boot_no_write_protect);
- if (error_count) {
- ccprintf("Failed %d tests!\n", error_count);
+ if (test_get_error_count())
reboot_to_clean_up(CLEAN_UP_FLAG_FAILED);
- } else {
+ else
reboot_to_clean_up(CLEAN_UP_FLAG_PASSED);
- }
}
int TaskTest(void *data)
@@ -389,6 +401,8 @@ int TaskTest(void *data)
if (state & TEST_STATE_PASSED)
ccprintf("Pass!\n");
+ else if (state & TEST_STATE_FAILED)
+ ccprintf("Fail!\n");
if (state & TEST_STATE_STEP_2)
run_test_step2();
@@ -396,11 +410,17 @@ int TaskTest(void *data)
run_test_step3();
else if (state & TEST_STATE_CLEAN_UP)
clean_up();
+#ifdef EMU_BUILD
+ else
+ run_test_step1();
+#endif
return EC_SUCCESS;
}
+#ifndef EMU_BUILD
void run_test(void)
{
run_test_step1();
}
+#endif