diff options
author | Vic Yang <victoryang@chromium.org> | 2012-07-09 10:56:32 +0800 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-07-10 00:35:58 -0700 |
commit | 37b295fd6e0df1bc24b39948031892021a73c539 (patch) | |
tree | 4dc0a1e6353a88ff0ded8cb2e18b6fa27ecbdbc0 /test | |
parent | 42d027099008ba511260a4b96b8d045847baa173 (diff) | |
download | chrome-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.mk | 8 | ||||
-rw-r--r-- | test/flash.c | 153 | ||||
-rw-r--r-- | test/flash_overwrite.py | 46 | ||||
-rw-r--r-- | test/flash_overwrite.tasklist | 20 | ||||
-rw-r--r-- | test/flash_test_util.py | 40 |
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)) |