diff options
author | Vic Yang <victoryang@chromium.org> | 2013-04-14 20:01:55 +0800 |
---|---|---|
committer | ChromeBot <chrome-bot@google.com> | 2013-04-15 20:40:02 -0700 |
commit | 216bb93128c2477d2c4053110e0b0df4ddd0b40f (patch) | |
tree | 4378ec4f8c12cf3f572851049518dc8c46608189 | |
parent | 108235225d2536f75a3100cd535f44f732b486c3 (diff) | |
download | chrome-ec-216bb93128c2477d2c4053110e0b0df4ddd0b40f.tar.gz |
Fix flash tests
This merges flash_overwrite and flash_rw_erase to a single test binary.
BUG=chrome-os-partner:18598
TEST=Run on Spring
BRANCH=None
Change-Id: I1da7577cb5dc196178930dda3a07bb942d959866
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/48090
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | chip/lm4/mock_flash.c | 73 | ||||
-rw-r--r-- | common/flash_common.c | 4 | ||||
-rw-r--r-- | common/host_command.c | 2 | ||||
-rw-r--r-- | test/build.mk | 13 | ||||
-rw-r--r-- | test/flash.c | 207 | ||||
-rw-r--r-- | test/flash.tasklist (renamed from test/flash_overwrite.tasklist) | 0 | ||||
-rw-r--r-- | test/flash_overwrite.py | 46 | ||||
-rw-r--r-- | test/flash_rw_erase.py | 29 | ||||
-rw-r--r-- | test/flash_rw_erase.tasklist | 17 | ||||
-rw-r--r-- | test/flash_test_util.py | 94 |
10 files changed, 205 insertions, 280 deletions
diff --git a/chip/lm4/mock_flash.c b/chip/lm4/mock_flash.c deleted file mode 100644 index 8200b66c91..0000000000 --- a/chip/lm4/mock_flash.c +++ /dev/null @@ -1,73 +0,0 @@ -/* 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. - */ - -/* Mock flash memory module for Chrome EC. - * Due to RAM size limit, we cannot mock entire flash memory. Instead, we only - * mock the last bank in order to make pstate works. */ - -#include "flash.h" -#include "uart.h" -#include "util.h" - -#define FLASH_FSIZE 0x7f -#define PHYSICAL_SIZE ((FLASH_FSIZE + 1) * CONFIG_FLASH_BANK_SIZE) -#define FLASH_MOCK_BEGIN (FLASH_FSIZE * CONFIG_FLASH_BANK_SIZE) - -char mock_protect[FLASH_FSIZE + 1]; -char pstate_space[CONFIG_FLASH_BANK_SIZE]; - -int flash_physical_size(void) -{ - return PHYSICAL_SIZE; -} - - -int flash_physical_write(int offset, int size, const char* data) -{ - int i; - int xorsum = 0; - if (offset >= FLASH_MOCK_BEGIN) - memcpy(pstate_space + offset - FLASH_MOCK_BEGIN, data, size); - else { - xorsum = 0; - for (i = 0; i < size; ++i) - xorsum ^= data[i]; - uart_printf("Flash write at %x size %x XOR %x\n", - offset, - size, - xorsum); - } - return EC_SUCCESS; -} - - -int flash_physical_erase(int offset, int size) -{ - uart_printf("Flash erase at %x size %x\n", offset, size); - if (offset + size >= FLASH_MOCK_BEGIN) - memset(pstate_space, 0xff, offset + size - FLASH_MOCK_BEGIN); - return EC_SUCCESS; -} - - -int flash_physical_get_protect(int block) -{ - return mock_protect[block]; -} - -uint32_t flash_get_protect(void) -{ - return 0; -} - -int flash_set_protect(uint32_t mask, uint32_t flags) -{ - return 0; -} - -int flash_pre_init(void) -{ - return EC_SUCCESS; -} diff --git a/common/flash_common.c b/common/flash_common.c index 9407f3336a..47938804cf 100644 --- a/common/flash_common.c +++ b/common/flash_common.c @@ -44,7 +44,7 @@ int flash_is_erased(uint32_t offset, int size) } #endif -int flash_write(int offset, int size, const char *data) +test_mockable int flash_write(int offset, int size, const char *data) { if (flash_dataptr(offset, size, CONFIG_FLASH_WRITE_SIZE, NULL) < 0) return EC_ERROR_INVAL; /* Invalid range */ @@ -56,7 +56,7 @@ int flash_write(int offset, int size, const char *data) return flash_physical_write(offset, size, data); } -int flash_erase(int offset, int size) +test_mockable int flash_erase(int offset, int size) { if (flash_dataptr(offset, size, CONFIG_FLASH_ERASE_SIZE, NULL) < 0) return EC_ERROR_INVAL; /* Invalid range */ diff --git a/common/host_command.c b/common/host_command.c index 264c3dca8e..72669e0429 100644 --- a/common/host_command.c +++ b/common/host_command.c @@ -50,7 +50,7 @@ uint8_t *host_get_memmap(int offset) #endif } -void host_send_response(struct host_cmd_handler_args *args) +test_mockable void host_send_response(struct host_cmd_handler_args *args) { #ifdef CONFIG_HOST_COMMAND_STATUS /* diff --git a/test/build.mk b/test/build.mk index 2fcdd3414d..6478577268 100644 --- a/test/build.mk +++ b/test/build.mk @@ -7,12 +7,10 @@ # test-list=hello pingpong timer_calib timer_dos timer_jump mutex thermal -test-list+=power_button kb_scan scancode typematic charging -test-list+=flash_overwrite flash_rw_erase utils +test-list+=power_button kb_scan scancode typematic charging flash #disable: powerdemo -flash_overwrite-y=flash.o -flash_rw_erase-y=flash.o +flash-y=flash.o kb_scan-y=kb_scan.o mutex-y=mutex.o pingpong-y=pingpong.o @@ -46,10 +44,3 @@ 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 - -# Mock modules for 'flash_rw_erase' -chip-mock-flash_rw_erase-flash.o=mock_flash.o diff --git a/test/flash.c b/test/flash.c index 1cc40382fd..23623ad59a 100644 --- a/test/flash.c +++ b/test/flash.c @@ -9,15 +9,208 @@ #include "console.h" #include "ec_commands.h" #include "host_command.h" -#include "uart.h" +#include "system.h" +#include "timer.h" #include "util.h" -static int ro_image_size(int argc, char **argv) +static int error_count; + +static int last_write_offset; +static int last_write_size; +static char last_write_data[64]; + +static int last_erase_offset; +static int last_erase_size; + +/*****************************************************************************/ +/* Mock functions */ +void host_send_response(struct host_cmd_handler_args *args) +{ + /* Do nothing */ +} + +int flash_write(int offset, int size, const char *data) +{ + last_write_offset = offset; + last_write_size = size; + memcpy(last_write_data, data, size); + return EC_SUCCESS; +} + +int flash_erase(int offset, int size) +{ + last_erase_offset = offset; + last_erase_size = size; + return EC_SUCCESS; +} + +/*****************************************************************************/ +/* Test utilities */ +#define RUN_TEST(n) \ + do { \ + ccprintf("Running %s...", #n); \ + cflush(); \ + if (n() == EC_SUCCESS) { \ + ccputs("OK\n"); \ + } else { \ + ccputs("Fail\n"); \ + error_count++; \ + } \ + } while (0) + +static void begin_verify(void) +{ + last_write_offset = -1; + last_write_size = -1; + last_write_data[0] = '\0'; + last_erase_offset = -1; + last_erase_size = -1; +} + +static int verify_write(int offset, int size, const char *data) { - uart_printf("RO image size = 0x%x\n", CONFIG_SECTION_RO_SIZE); + int i; + + if (offset != last_write_offset || size != last_write_size) + return EC_ERROR_UNKNOWN; + for (i = 0; i < size; ++i) + if (data[i] != last_write_data[i]) + return EC_ERROR_UNKNOWN; + return EC_SUCCESS; } -DECLARE_CONSOLE_COMMAND(rosize, ro_image_size, - NULL, - "Report size of RO image", - NULL); + +#define VERIFY_NO_WRITE(off, sz, d) \ + do { \ + begin_verify(); \ + host_command_write(off, sz, d); \ + if (last_write_offset != -1 || last_write_size != -1) \ + return EC_ERROR_UNKNOWN; \ + } while (0) + +#define VERIFY_NO_ERASE(off, sz) \ + do { \ + begin_verify(); \ + host_command_erase(off, sz); \ + if (last_erase_offset != -1 || last_erase_size != -1) \ + return EC_ERROR_UNKNOWN; \ + } while (0) + +#define VERIFY_WRITE(off, sz, d) \ + do { \ + begin_verify(); \ + host_command_write(off, sz, d); \ + if (verify_write(off, sz, d) != EC_SUCCESS) \ + return EC_ERROR_UNKNOWN; \ + } while (0) + +#define VERIFY_ERASE(off, sz) \ + do { \ + begin_verify(); \ + host_command_erase(off, sz); \ + if (last_erase_offset != off || last_erase_size != sz) \ + return EC_ERROR_UNKNOWN; \ + } while (0) + +int host_command_write(int offset, int size, const char *data) +{ + struct host_cmd_handler_args args; + struct ec_params_flash_write params; + + params.offset = offset; + params.size = size; + memcpy(params.data, data, size); + + args.version = 0; + args.command = EC_CMD_FLASH_WRITE; + args.params = ¶ms; + args.params_size = sizeof(params); + args.response = NULL; + args.response_max = 0; + args.response_size = 0; + + return host_command_process(&args); +} + +int host_command_erase(int offset, int size) +{ + struct host_cmd_handler_args args; + struct ec_params_flash_write params; + + params.offset = offset; + params.size = size; + + args.version = 0; + args.command = EC_CMD_FLASH_ERASE; + args.params = ¶ms; + args.params_size = sizeof(params); + args.response = NULL; + args.response_max = 0; + args.response_size = 0; + + return host_command_process(&args); +} + +/*****************************************************************************/ +/* Tests */ +static int test_overwrite_current(void) +{ + uint32_t offset, size; + const char *d = "TestData0000000"; /* 16 bytes */ + + /* Test that we cannot overwrite current image */ + if (system_get_image_copy() == SYSTEM_IMAGE_RO) { + offset = CONFIG_FW_RO_OFF; + size = CONFIG_FW_RO_SIZE; + } else { + offset = CONFIG_FW_RW_OFF; + size = CONFIG_FW_RW_SIZE; + } + + VERIFY_NO_ERASE(offset, sizeof(d)); + VERIFY_NO_ERASE(offset + size - sizeof(d), sizeof(d)); + VERIFY_NO_WRITE(offset, sizeof(d), d); + VERIFY_NO_WRITE(offset + size - sizeof(d), sizeof(d), d); + + return EC_SUCCESS; +} + +static int test_overwrite_other(void) +{ + uint32_t offset, size; + const char *d = "TestData0000000"; /* 16 bytes */ + + /* Test that we can overwrite the other image */ + if (system_get_image_copy() == SYSTEM_IMAGE_RW) { + offset = CONFIG_FW_RO_OFF; + size = CONFIG_FW_RO_SIZE; + } else { + offset = CONFIG_FW_RW_OFF; + size = CONFIG_FW_RW_SIZE; + } + + VERIFY_ERASE(offset, sizeof(d)); + VERIFY_ERASE(offset + size - sizeof(d), sizeof(d)); + VERIFY_WRITE(offset, sizeof(d), d); + VERIFY_WRITE(offset + size - sizeof(d), sizeof(d), d); + + return EC_SUCCESS; +} + +static int command_run_test(int argc, char **argv) +{ + error_count = 0; + + RUN_TEST(test_overwrite_current); + RUN_TEST(test_overwrite_other); + + if (error_count) { + ccprintf("Failed %d tests!\n", error_count); + return EC_ERROR_UNKNOWN; + } else { + ccprintf("Pass!\n"); + return EC_SUCCESS; + } +} +DECLARE_CONSOLE_COMMAND(runtest, command_run_test, + NULL, NULL, NULL); diff --git a/test/flash_overwrite.tasklist b/test/flash.tasklist index 26cfc53453..26cfc53453 100644 --- a/test/flash_overwrite.tasklist +++ b/test/flash.tasklist diff --git a/test/flash_overwrite.py b/test/flash_overwrite.py deleted file mode 100644 index 93f282ad80..0000000000 --- a/test/flash_overwrite.py +++ /dev/null @@ -1,46 +0,0 @@ -# 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, 0x10, expect_fail=True) - - # Writing to RW should succeed. - test_write(helper, rosize, 0x10) # begin of RW - test_write(helper, (rosize + flashsize) / 2, 0x10) # mid-point of RW - test_write(helper, flashsize - 0x10, 0x10) # 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, 0x10) # begin of RO - test_write(helper, rosize / 2, 0x10) # mid-point of RO - test_write(helper, rosize - 0x10, 0x10) # end of RO - - # Writing to RW-A should fail. - test_write(helper, rosize, 0x10, expect_fail=True) - - return True diff --git a/test/flash_rw_erase.py b/test/flash_rw_erase.py deleted file mode 100644 index 0ee8e774c0..0000000000 --- a/test/flash_rw_erase.py +++ /dev/null @@ -1,29 +0,0 @@ -# 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 read/write/erase test -# - -from flash_test_util import test_erase -from flash_test_util import test_read -from flash_test_util import test_write -import time - -def test(helper): - helper.wait_output("--- UART initialized") - - # 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. Read/write/erase on RO should all succeed. - test_erase(helper, 0, 0x1000) - test_erase(helper, 0x1000, 0x2000) - test_read(helper, 0, 0x40) - test_read(helper, 0x130, 0x40) - test_write(helper, 0, 0x30) - test_write(helper, 0x130, 0x30) - - return True diff --git a/test/flash_rw_erase.tasklist b/test/flash_rw_erase.tasklist deleted file mode 100644 index 26cfc53453..0000000000 --- a/test/flash_rw_erase.tasklist +++ /dev/null @@ -1,17 +0,0 @@ -/* 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. - */ - -/** - * List of enabled tasks in the priority order - * - * The first one has the lowest priority. - * - * For each task, use the macro TASK_TEST(n, r, d, s) 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 - * 's' is the stack size in bytes; must be a multiple of 8 - */ -#define CONFIG_TEST_TASK_LIST /* No test task */ diff --git a/test/flash_test_util.py b/test/flash_test_util.py deleted file mode 100644 index 5942ca7e2f..0000000000 --- a/test/flash_test_util.py +++ /dev/null @@ -1,94 +0,0 @@ -# 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 -import re -import struct - -# Fixed random seed. -random.seed(1234) - -def hex_to_byte(text): - return ''.join(["%c" % chr(int(text[i:i+2], 16)) - for i in range(0, len(text), 2)]) - -def byte_to_hex(byte_arr): - return ''.join(["%02x" % ord(c) for c in byte_arr]) - -def offset_size_pair(offset, size): - return byte_to_hex(struct.pack("II", offset, size)) - -def get_flash_info(helper): - helper.ec_command("hostcmd 0x10 0 00") - resp = helper.wait_output("Response: (?P<r>.{32,32})", use_re=True)["r"] - return struct.unpack("IIII", hex_to_byte(resp)) - -def get_flash_size(helper): - return get_flash_info(helper)[0] - -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_erase(helper, offset, size): - helper.ec_command("hostcmd 0x13 0 %s" % offset_size_pair(offset, size)) - helper.wait_output("Flash erase at %x size %x" % (offset, size)) - -def _get_read_ref(helper, offset, size): - ret = [] - retsub = [] - assert size % 4 == 0 - while size > 0: - helper.ec_command("rw %d" % offset) - h = helper.wait_output("read.*=\s+0x(?P<h>[0-9a-f]+)", use_re=True)["h"] - # Change endianess here - retsub.append(re.sub('(..)(..)(..)(..)', r'\4\3\2\1', h)) - if len(retsub) == 8: - ret.append(''.join(retsub)) - retsub = [] - size = size - 4 - offset = offset + 4 - if retsub: - ret.append(''.join(retsub)) - return ret - -def test_read(helper, offset, size): - ref = _get_read_ref(helper, offset, size) - helper.ec_command("hostcmd 0x11 0 %s" % offset_size_pair(offset, size)) - for line in ref: - helper.wait_output(line) - -def _gen_data(size, seed, mult, add): - data = [] - for i in xrange(size): - data.append("%02x" % (seed & 255)) - seed = (seed * mult + add) & 4294967295; - return ''.join(data) - -def test_write(helper, offset, size, expect_fail=False): - assert size <= 16 - seed = random.randint(2, 10000) - mult = random.randint(2, 10000) - add = random.randint(2, 10000) - data = _gen_data(size, seed, mult, add) - payload = byte_to_hex(struct.pack("II", offset, size)) - helper.ec_command("hostcmd 0x12 0 %s%s" % - (offset_size_pair(offset, size), data)) - if expect_fail: - helper.wait_output("Command returned \d+", use_re=True) - else: - expected_sum = xor_sum(size, seed, mult, add) - helper.wait_output("Flash write at %x size %x XOR %x" % - (offset, size, expected_sum)) |