summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2013-07-23 06:52:18 +0800
committerChromeBot <chrome-bot@google.com>2013-07-23 16:06:22 -0700
commit74abf3697109b2719d0dbc4e60667740de872fb3 (patch)
treec711bf33700f82793833930c8dc73ec8de0ee272
parent64e38af781a42a346f59ef27c352f4818bfa1516 (diff)
downloadchrome-ec-74abf3697109b2719d0dbc4e60667740de872fb3.tar.gz
Test sysjump tag in kb_8042 test
This checks that keyboard state is preserved across system jump. BUG=chrome-os-partner:19236 TEST=Pass the test BRANCH=None Change-Id: I53c5bb68246fd117b351d89c3907daf028bc4ef3 Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/62908 Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--chip/host/persistence.c12
-rw-r--r--chip/host/persistence.h2
-rw-r--r--chip/host/system.c104
-rw-r--r--common/system_common.c8
-rw-r--r--core/host/main.c5
-rw-r--r--core/host/panic.c5
-rw-r--r--test/kb_8042.c42
7 files changed, 164 insertions, 14 deletions
diff --git a/chip/host/persistence.c b/chip/host/persistence.c
index cd412fa7eb..4be2683bb1 100644
--- a/chip/host/persistence.c
+++ b/chip/host/persistence.c
@@ -42,3 +42,15 @@ void release_persistent_storage(FILE *ps)
{
fclose(ps);
}
+
+void remove_persistent_storage(const char *tag)
+{
+ char buf[BUF_SIZE];
+ char path[BUF_SIZE];
+
+ get_storage_path(buf);
+ if (snprintf(path, BUF_SIZE, "%s_%s", buf, tag) >= BUF_SIZE)
+ path[BUF_SIZE - 1] = '\0';
+
+ unlink(path);
+}
diff --git a/chip/host/persistence.h b/chip/host/persistence.h
index 37dbc5707a..0a80c2e618 100644
--- a/chip/host/persistence.h
+++ b/chip/host/persistence.h
@@ -14,4 +14,6 @@ FILE *get_persistent_storage(const char *tag, const char *mode);
void release_persistent_storage(FILE *ps);
+void remove_persistent_storage(const char *tag);
+
#endif /* _PERSISTENCE_H */
diff --git a/chip/host/system.c b/chip/host/system.c
index dc824f58b7..e1bd2cc898 100644
--- a/chip/host/system.c
+++ b/chip/host/system.c
@@ -7,13 +7,86 @@
#include <stdlib.h>
+#include "common.h"
#include "host_test.h"
#include "system.h"
+#include "panic.h"
#include "persistence.h"
+#include "util.h"
#define SHARED_MEM_SIZE 512 /* bytes */
char __shared_mem_buf[SHARED_MEM_SIZE];
+#define RAM_DATA_SIZE (sizeof(struct panic_data) + 512) /* bytes */
+static char __ram_data[RAM_DATA_SIZE];
+
+static enum system_image_copy_t __running_copy;
+
+static void ramdata_set_persistent(void)
+{
+ FILE *f = get_persistent_storage("ramdata", "wb");
+ int sz;
+
+ ASSERT(f != NULL);
+
+ sz = fwrite(__ram_data, sizeof(__ram_data), 1, f);
+ ASSERT(sz == 1);
+
+ release_persistent_storage(f);
+}
+
+static void ramdata_get_persistent(void)
+{
+ FILE *f = get_persistent_storage("ramdata", "rb");
+
+ if (f == NULL) {
+ fprintf(stderr,
+ "No RAM data found. Initializing to 0x00.\n");
+ memset(__ram_data, 0, sizeof(__ram_data));
+ return;
+ }
+
+ fread(__ram_data, sizeof(__ram_data), 1, f);
+
+ release_persistent_storage(f);
+
+ /*
+ * Assumes RAM data doesn't preserve across reboot except for sysjump.
+ * Clear persistent data once it's read.
+ */
+ remove_persistent_storage("ramdata");
+}
+
+static void set_image_copy(uint32_t copy)
+{
+ FILE *f = get_persistent_storage("image_copy", "wb");
+
+ ASSERT(f != NULL);
+ ASSERT(fwrite(&copy, sizeof(copy), 1, f) == 1);
+
+ release_persistent_storage(f);
+}
+
+static uint32_t get_image_copy(void)
+{
+ FILE *f = get_persistent_storage("image_copy", "rb");
+ uint32_t ret;
+
+ if (f == NULL)
+ return SYSTEM_IMAGE_RO;
+ fread(&ret, sizeof(ret), 1, f);
+ release_persistent_storage(f);
+ remove_persistent_storage("image_copy");
+
+ return ret;
+}
+
+test_mockable struct panic_data *panic_get_data(void)
+{
+ return (struct panic_data *)
+ (__ram_data + RAM_DATA_SIZE - sizeof(struct panic_data));
+}
+
test_mockable void system_reset(int flags)
{
exit(EXIT_CODE_RESET | flags);
@@ -64,6 +137,11 @@ int system_set_vbnvcontext(const uint8_t *block)
return EC_ERROR_UNIMPLEMENTED;
}
+enum system_image_copy_t system_get_image_copy(void)
+{
+ return __running_copy;
+}
+
int system_set_scratchpad(uint32_t value)
{
FILE *f = get_persistent_storage("scratchpad", "w");
@@ -97,7 +175,31 @@ uintptr_t system_usable_ram_end(void)
return (uintptr_t)(__shared_mem_buf + SHARED_MEM_SIZE);
}
+static void __jump_resetvec(void)
+{
+ ramdata_set_persistent();
+ exit(EXIT_CODE_RESET);
+}
+
+static void __ro_jump_resetvec(void)
+{
+ set_image_copy(SYSTEM_IMAGE_RO);
+ __jump_resetvec();
+}
+
+static void __rw_jump_resetvec(void)
+{
+ set_image_copy(SYSTEM_IMAGE_RW);
+ __jump_resetvec();
+}
+
void system_pre_init(void)
{
- /* Nothing */
+ ramdata_get_persistent();
+ __running_copy = get_image_copy();
+
+ *(uintptr_t *)(__host_flash + CONFIG_FW_RO_OFF + 4) =
+ (uintptr_t)__ro_jump_resetvec;
+ *(uintptr_t *)(__host_flash + CONFIG_FW_RW_OFF + 4) =
+ (uintptr_t)__rw_jump_resetvec;
}
diff --git a/common/system_common.c b/common/system_common.c
index 46cbc702cf..c0dd639034 100644
--- a/common/system_common.c
+++ b/common/system_common.c
@@ -213,7 +213,7 @@ void system_disable_jump(void)
disable_jump = 1;
}
-enum system_image_copy_t system_get_image_copy(void)
+test_mockable enum system_image_copy_t system_get_image_copy(void)
{
uintptr_t my_addr = (uintptr_t)system_get_image_copy -
CONFIG_FLASH_BASE;
@@ -345,6 +345,7 @@ static uint32_t get_base(enum system_image_copy_t copy)
/**
* Return the size of the image copy, or 0 if error.
*/
+#ifndef EMU_BUILD
static uint32_t get_size(enum system_image_copy_t copy)
{
switch (copy) {
@@ -356,6 +357,7 @@ static uint32_t get_size(enum system_image_copy_t copy)
return 0;
}
}
+#endif
int system_run_image_copy(enum system_image_copy_t copy)
{
@@ -393,9 +395,11 @@ int system_run_image_copy(enum system_image_copy_t copy)
return EC_ERROR_INVAL;
/* Make sure the reset vector is inside the destination image */
- init_addr = *(uint32_t *)(base + 4);
+ init_addr = *(uintptr_t *)(base + 4);
+#ifndef EMU_BUILD
if (init_addr < base || init_addr >= base + get_size(copy))
return EC_ERROR_UNKNOWN;
+#endif
CPRINTF("[%T Jumping to image %s]\n", image_names[copy]);
diff --git a/core/host/main.c b/core/host/main.c
index 132a5fcaaf..b046f3b584 100644
--- a/core/host/main.c
+++ b/core/host/main.c
@@ -7,6 +7,7 @@
#include "flash.h"
#include "hooks.h"
+#include "system.h"
#include "task.h"
#include "test_util.h"
#include "timer.h"
@@ -17,11 +18,11 @@ int main(void)
register_test_end_hook();
flash_pre_init();
+ system_pre_init();
+ system_common_pre_init();
timer_init();
-
hook_init();
-
uart_init();
task_start();
diff --git a/core/host/panic.c b/core/host/panic.c
index ee815cb678..468d024552 100644
--- a/core/host/panic.c
+++ b/core/host/panic.c
@@ -10,11 +10,6 @@
#include "panic.h"
#include "util.h"
-struct panic_data *panic_get_data(void)
-{
- return NULL;
-}
-
void panic_assert_fail(const char *msg, const char *func, const char *fname,
int linenum)
{
diff --git a/test/kb_8042.c b/test/kb_8042.c
index 8fa3158dd7..a0fbaad4d5 100644
--- a/test/kb_8042.c
+++ b/test/kb_8042.c
@@ -14,6 +14,7 @@
#include "keyboard_protocol.h"
#include "keyboard_scan.h"
#include "lpc.h"
+#include "system.h"
#include "test_util.h"
#include "timer.h"
#include "util.h"
@@ -193,14 +194,47 @@ static int test_scancode_set2(void)
return EC_SUCCESS;
}
+static int test_sysjump(void)
+{
+ set_scancode(2);
+ enable_keystroke(1);
+
+ system_run_image_copy(SYSTEM_IMAGE_RW);
+
+ /* Shouldn't reach here */
+ return EC_ERROR_UNKNOWN;
+}
+
+static int test_sysjump_cont(void)
+{
+ write_cmd_byte(read_cmd_byte() | I8042_XLATE);
+ press_key(1, 1, 1);
+ VERIFY_LPC_CHAR("\x01");
+ press_key(1, 1, 0);
+ VERIFY_LPC_CHAR("\x81");
+
+ write_cmd_byte(read_cmd_byte() & ~I8042_XLATE);
+ press_key(1, 1, 1);
+ VERIFY_LPC_CHAR("\x76");
+ press_key(1, 1, 0);
+ VERIFY_LPC_CHAR("\xf0\x76");
+
+ return EC_SUCCESS;
+}
+
void run_test(void)
{
test_reset();
- RUN_TEST(test_single_key_press);
- RUN_TEST(test_disable_keystroke);
- RUN_TEST(test_typematic);
- RUN_TEST(test_scancode_set2);
+ if (system_get_image_copy() == SYSTEM_IMAGE_RO) {
+ RUN_TEST(test_single_key_press);
+ RUN_TEST(test_disable_keystroke);
+ RUN_TEST(test_typematic);
+ RUN_TEST(test_scancode_set2);
+ RUN_TEST(test_sysjump);
+ } else {
+ RUN_TEST(test_sysjump_cont);
+ }
test_print_result();
}