summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2012-07-09 10:56:32 +0800
committerGerrit <chrome-bot@google.com>2012-07-10 00:35:58 -0700
commit37b295fd6e0df1bc24b39948031892021a73c539 (patch)
tree4dc0a1e6353a88ff0ded8cb2e18b6fa27ecbdbc0 /test
parent42d027099008ba511260a4b96b8d045847baa173 (diff)
downloadchrome-ec-37b295fd6e0df1bc24b39948031892021a73c539.tar.gz
Add a test of flash overwrite
This test checks we cannot overwrite current running system image. BUG=chrome-os-partner:10262 TEST=Test passed Change-Id: I72be277c9de2114e72000a102d8b885e842ef15a Reviewed-on: https://gerrit.chromium.org/gerrit/27006 Commit-Ready: Vic Yang <victoryang@chromium.org> Reviewed-by: Vic Yang <victoryang@chromium.org> Tested-by: Vic Yang <victoryang@chromium.org>
Diffstat (limited to 'test')
-rw-r--r--test/build.mk8
-rw-r--r--test/flash.c153
-rw-r--r--test/flash_overwrite.py46
-rw-r--r--test/flash_overwrite.tasklist20
-rw-r--r--test/flash_test_util.py40
5 files changed, 266 insertions, 1 deletions
diff --git a/test/build.mk b/test/build.mk
index c6240e1252..9736ec26f2 100644
--- a/test/build.mk
+++ b/test/build.mk
@@ -8,6 +8,7 @@
test-list=hello pingpong timer_calib timer_dos timer_jump mutex thermal
test-list+=power_button kb_deghost kb_debounce scancode typematic charging
+test-list+=flash_overwrite
#disable: powerdemo
pingpong-y=pingpong.o
@@ -15,6 +16,7 @@ powerdemo-y=powerdemo.o
timer_calib-y=timer_calib.o
timer_dos-y=timer_dos.o
mutex-y=mutex.o
+flash_overwrite-y=flash.o
# Mock modules for 'thermal'
chip-mock-thermal-lpc.o=mock_lpc.o
@@ -44,8 +46,12 @@ common-mock-typematic-i8042.o=mock_i8042.o
chip-mock-kb_debounce-keyboard_scan_stub.o=mock_keyboard_scan_stub.o
common-mock-kb_debounce-i8042.o=mock_i8042.o
-# Mock modules for 'charging;
+# Mock modules for 'charging'
chip-mock-charging-gpio.o=mock_gpio.o
common-mock-charging-x86_power.o=mock_x86_power.o
common-mock-charging-smart_battery_stub.o=mock_smart_battery_stub.o
common-mock-charging-charger_bq24725.o=mock_charger.o
+
+# Mock modules for 'flash_overwrite'
+chip-mock-flash_overwrite-flash.o=mock_flash.o
+chip-mock-flash_overwrite-gpio.o=mock_gpio.o
diff --git a/test/flash.c b/test/flash.c
new file mode 100644
index 0000000000..c7e8d94365
--- /dev/null
+++ b/test/flash.c
@@ -0,0 +1,153 @@
+/* Copyright (c) 2012 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.
+ */
+
+/* Console commands to trigger flash host commands */
+
+#include "board.h"
+#include "console.h"
+#include "ec_commands.h"
+#include "host_command.h"
+#include "uart.h"
+#include "util.h"
+
+static int ro_image_size(int argc, char **argv)
+{
+ uart_printf("RO image size = 0x%x\n", CONFIG_SECTION_RO_SIZE);
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(rosize, ro_image_size,
+ NULL,
+ "Report size of RO image",
+ NULL);
+
+static int hc_flash_info(int argc, char **argv)
+{
+ uint8_t data[EC_PARAM_SIZE];
+ enum ec_status res;
+ int resp_size;
+ struct ec_response_flash_info *r =
+ (struct ec_response_flash_info *)data;
+
+ res = host_command_process(0, EC_CMD_FLASH_INFO, data, &resp_size);
+ if (res != EC_RES_SUCCESS)
+ return EC_ERROR_UNKNOWN;
+ uart_printf("flash_size = %d\n", r->flash_size);
+ uart_printf("write_block_size = %d\n", r->write_block_size);
+ uart_printf("erase_block_size = %d\n", r->erase_block_size);
+ uart_printf("protect_block_size = %d\n", r->protect_block_size);
+
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(hcflashinfo, hc_flash_info,
+ NULL, NULL, NULL);
+
+static int hc_flash_read(int argc, char **argv)
+{
+ uint8_t data[EC_PARAM_SIZE];
+ enum ec_status res;
+ int resp_size;
+ struct ec_params_flash_read *p =
+ (struct ec_params_flash_read *)data;
+ struct ec_response_flash_read *r =
+ (struct ec_response_flash_read *)data;
+ char *e;
+ int i, size;
+
+ if (argc != 3)
+ return EC_ERROR_PARAM_COUNT;
+
+ p->offset = strtoi(argv[1], &e, 0);
+ if (*e)
+ return EC_ERROR_PARAM1;
+ size = strtoi(argv[2], &e, 0);
+ p->size = size;
+ if (*e)
+ return EC_ERROR_PARAM2;
+
+ res = host_command_process(0, EC_CMD_FLASH_READ, data, &resp_size);
+ if (res != EC_RES_SUCCESS)
+ return EC_ERROR_UNKNOWN;
+ for (i = 0; i < size; ++i) {
+ uart_printf("%02x", r->data[i]);
+ if ((i & 31) == 31)
+ uart_puts("\n");
+ }
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(hcflashread, hc_flash_read,
+ NULL, NULL, NULL);
+
+static int hc_flash_write(int argc, char **argv)
+{
+ uint8_t data[EC_PARAM_SIZE];
+ enum ec_status res;
+ int resp_size;
+ struct ec_params_flash_write *p =
+ (struct ec_params_flash_write *)data;
+ char *e;
+ int i, size;
+ int seed, mult, add;
+
+ if (argc != 6)
+ return EC_ERROR_PARAM_COUNT;
+
+ p->offset = strtoi(argv[1], &e, 0);
+ if (*e)
+ return EC_ERROR_PARAM1;
+ size = strtoi(argv[2], &e, 0);
+ p->size = size;
+ if (*e)
+ return EC_ERROR_PARAM2;
+ seed = strtoi(argv[3], &e, 0);
+ if (*e)
+ return EC_ERROR_PARAM3;
+ mult = strtoi(argv[4], &e, 0);
+ if (*e)
+ return EC_ERROR_PARAM4;
+ add = strtoi(argv[5], &e, 0);
+ if (*e)
+ return EC_ERROR_PARAM5;
+
+ for (i = 0; i < size; ++i) {
+ p->data[i] = (uint8_t)(seed & 0xff);
+ seed = seed * mult + add;
+ }
+
+ res = host_command_process(0, EC_CMD_FLASH_WRITE, data, &resp_size);
+ if (res != EC_RES_SUCCESS)
+ return EC_ERROR_UNKNOWN;
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(hcflashwrite, hc_flash_write,
+ NULL, NULL, NULL);
+
+static int hc_flash_erase(int argc, char **argv)
+{
+ uint8_t data[EC_PARAM_SIZE];
+ enum ec_status res;
+ int resp_size;
+ struct ec_params_flash_erase *p =
+ (struct ec_params_flash_erase *)data;
+ char *e;
+ int size;
+
+ if (argc != 3)
+ return EC_ERROR_PARAM_COUNT;
+
+ p->offset = strtoi(argv[1], &e, 0);
+ if (*e)
+ return EC_ERROR_PARAM1;
+ size = strtoi(argv[2], &e, 0);
+ p->size = size;
+ if (*e)
+ return EC_ERROR_PARAM2;
+
+ res = host_command_process(0, EC_CMD_FLASH_ERASE, data, &resp_size);
+ if (res != EC_RES_SUCCESS)
+ return EC_ERROR_UNKNOWN;
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(hcflasherase, hc_flash_erase,
+ NULL, NULL, NULL);
diff --git a/test/flash_overwrite.py b/test/flash_overwrite.py
new file mode 100644
index 0000000000..15b3e4817a
--- /dev/null
+++ b/test/flash_overwrite.py
@@ -0,0 +1,46 @@
+# Copyright (c) 2012 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 overwrite test
+#
+
+from flash_test_util import get_flash_size
+from flash_test_util import get_ro_size
+from flash_test_util import test_write
+import time
+
+def test(helper):
+ helper.wait_output("--- UART initialized")
+
+ # Jump to RO
+ helper.ec_command("sysjump ro")
+ helper.wait_output("idle task started") # jump completed
+ time.sleep(0.5)
+
+ # Get flash info
+ flashsize = get_flash_size(helper)
+ rosize = get_ro_size(helper)
+
+ # We are in RO now. Writing to RO should fail.
+ test_write(helper, rosize / 2, 0x30, expect_fail=True)
+
+ # Writing to RW should succeed.
+ test_write(helper, rosize, 0x30) # begin of RW
+ test_write(helper, (rosize + flashsize) / 2, 0x30) # mid-point of RW
+ test_write(helper, flashsize - 0x30, 0x30) # end of flash
+
+ # Jump to RW-A
+ helper.ec_command("sysjump a")
+ helper.wait_output("idle task started") # jump completed
+ time.sleep(0.5)
+
+ # We are in RW now. Writing to RO should succeed.
+ test_write(helper, 0, 0x30) # begin of RO
+ test_write(helper, rosize / 2, 0x30) # mid-point of RO
+ test_write(helper, rosize - 0x30, 0x30) # end of RO
+
+ # Writing to RW-A should fail.
+ test_write(helper, rosize, 0x30, expect_fail=True)
+
+ return True
diff --git a/test/flash_overwrite.tasklist b/test/flash_overwrite.tasklist
new file mode 100644
index 0000000000..65a15ac498
--- /dev/null
+++ b/test/flash_overwrite.tasklist
@@ -0,0 +1,20 @@
+/* Copyright (c) 2012 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.
+ */
+
+/**
+ * List of enabled tasks in the priority order
+ *
+ * The first one has the lowest priority.
+ *
+ * For each task, use the macro TASK(n, r, d) where :
+ * 'n' in the name of the task
+ * 'r' in the main routine of the task
+ * 'd' in an opaque parameter passed to the routine at startup
+ */
+#define CONFIG_TASK_LIST \
+ TASK(WATCHDOG, watchdog_task, NULL) \
+ TASK(VBOOTHASH, vboot_hash_task, NULL) \
+ TASK(HOSTCMD, host_command_task, NULL) \
+ TASK(CONSOLE, console_task, NULL)
diff --git a/test/flash_test_util.py b/test/flash_test_util.py
new file mode 100644
index 0000000000..c0194a3a6e
--- /dev/null
+++ b/test/flash_test_util.py
@@ -0,0 +1,40 @@
+# Copyright (c) 2012 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.
+#
+# Utility functions for flash related test
+#
+
+import random
+
+# Fixed random seed.
+random.seed(1234)
+
+def get_flash_size(helper):
+ helper.ec_command("hcflashinfo")
+ return int(helper.wait_output("flash_size = (?P<f>\d+)", use_re=True)["f"])
+
+def get_ro_size(helper):
+ helper.ec_command("rosize")
+ return int(helper.wait_output(
+ "RO image size = (?P<ro>0x[0-9a-f]+)", use_re=True)["ro"], 16)
+
+def xor_sum(size, seed, mult, add):
+ ret = 0
+ for i in xrange(size):
+ ret ^= (seed & 0xff)
+ seed = seed * mult + add
+ return ret
+
+def test_write(helper, offset, size, expect_fail=False):
+ seed = random.randint(2, 10000)
+ mult = random.randint(2, 10000)
+ add = random.randint(2, 10000)
+ helper.ec_command("hcflashwrite %d %d %d %d %d" %
+ (offset, size, seed, mult, add))
+ if expect_fail:
+ helper.wait_output("Command returned error")
+ else:
+ expected_sum = xor_sum(size, seed, mult, add)
+ helper.wait_output("Flash write at %x size %x XOR %x" %
+ (offset, size, expected_sum))