diff options
author | Patryk Duda <pdk@semihalf.com> | 2022-03-22 09:55:12 +0100 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-04-06 15:10:19 +0000 |
commit | 3b9284b13cc4be2f2a8283ff2e63c23b3564a31b (patch) | |
tree | 0028764a2e7d9ab86eafc0d916472816b16379a4 /test | |
parent | ae35143aa53abfb74f1cd285f10e49a331e2f731 (diff) | |
download | chrome-ec-3b9284b13cc4be2f2a8283ff2e63c23b3564a31b.tar.gz |
test: Introduce panic data persistency test
The test is going to check if panic data are correct after crash,
soft reboot and hard reboot. In the last case we expect to have only
16 bits of a panic reason and info associated with reason.
Checking panic data after soft reboot will make sure that RO doesn't
overwrite part of panic data created by RW (eg. when doing sysjump).
Doing the same checks after hard reboot will make sure that RO is able
to restore panic data from backup RAM and RW is restoring any additional
data which RO is not aware of (eg. panic flags) correctly.
BUG=b:221087395
BRANCH=none
TEST=./test/run_device_tests.py -b dartmonkey --test panic_data.*
TEST=./test/run_device_tests.py -b bloonchipper --test panic_data.*
Signed-off-by: Patryk Duda <pdk@semihalf.com>
Change-Id: If84af40fc0045b633effbb32d61061ec20505516
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3555750
Reviewed-by: Andrea Grandi <agrandi@google.com>
Reviewed-by: Bobby Casey <bobbycasey@google.com>
Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Commit-Queue: Patryk Duda <patrykd@google.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/build.mk | 1 | ||||
-rw-r--r-- | test/panic_data.c | 140 | ||||
-rw-r--r-- | test/panic_data.tasklist | 10 | ||||
-rwxr-xr-x | test/run_device_tests.py | 48 |
4 files changed, 198 insertions, 1 deletions
diff --git a/test/build.mk b/test/build.mk index c0c9b3cc9e..87606f8751 100644 --- a/test/build.mk +++ b/test/build.mk @@ -192,6 +192,7 @@ kasa-y=kasa.o mpu-y=mpu.o mutex-y=mutex.o newton_fit-y=newton_fit.o +panic_data-y=panic_data.o pingpong-y=pingpong.o power_button-y=power_button.o powerdemo-y=powerdemo.o diff --git a/test/panic_data.c b/test/panic_data.c new file mode 100644 index 0000000000..9abbcb7745 --- /dev/null +++ b/test/panic_data.c @@ -0,0 +1,140 @@ +/* Copyright 2022 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. + */ + +#include "test_util.h" + +#include "assert.h" +#include "panic.h" +#include "system.h" +#include "task.h" + +static int get_assert_line(void) +{ + /* Returned number should point to ASSERT(0) line below */ + return __LINE__ + 5; +} + +static void crash_system(void) +{ + ASSERT(0); +} + +test_static int test_panic_data(void) +{ + struct panic_data *pdata = panic_get_data(); + + /* Check panic reason. */ + TEST_EQ(pdata->cm.regs[CORTEX_PANIC_REGISTER_R4], PANIC_SW_ASSERT, + "%08x"); + + /* Check panic info. */ + TEST_EQ(pdata->cm.regs[CORTEX_PANIC_REGISTER_R5], get_assert_line(), + "%d"); + + /* + * Check panic exception - it should be always 0 because panic didn't + * happen during interrupt processing. + */ + TEST_EQ(pdata->cm.regs[CORTEX_PANIC_REGISTER_IPSR], 0, "%d"); + + /* Check panic flags. */ + TEST_EQ(pdata->flags, + PANIC_DATA_FLAG_FRAME_VALID | PANIC_DATA_FLAG_OLD_HOSTEVENT, + "%02x"); + + return EC_SUCCESS; +} + +/* + * After hard reboot we expect to have panic flags, panic exception and lower + * 16 bits of panic reason and info (upper 16 bits should be zero). This + * information is saved in backup RAM because hard reboot clears memory. The + * backup RAM only has 16 bits available for this information. Check if lower + * 16 bits of reason and info are present and upper 16 bits are zero. + */ +test_static int test_panic_data_half(void) +{ + struct panic_data *pdata = panic_get_data(); + + /* Check panic reason. */ + TEST_EQ(pdata->cm.regs[CORTEX_PANIC_REGISTER_R4], + (PANIC_SW_ASSERT & 0xffff), "%08x"); + + /* Check panic info. */ + TEST_EQ(pdata->cm.regs[CORTEX_PANIC_REGISTER_R5], + (get_assert_line() & 0xffff), "%d"); + + /* + * Check panic exception - it should be always 0 because panic didn't + * happen during interrupt processing. + */ + TEST_EQ(pdata->cm.regs[CORTEX_PANIC_REGISTER_IPSR], 0, "%d"); + + /* Check panic flags. */ + TEST_EQ(pdata->flags, + PANIC_DATA_FLAG_FRAME_VALID | PANIC_DATA_FLAG_OLD_HOSTEVENT, + "%02x"); + + return EC_SUCCESS; +} + +void test_run_step(uint32_t state) +{ + /* Step 1: Crash system to get panic data. */ + if (state & TEST_STATE_MASK(TEST_STATE_STEP_1)) { + test_set_next_step(TEST_STATE_STEP_2); + /* Crash the system */ + ccprintf("Crash the system!\n"); + cflush(); + crash_system(); + } + /* Step 2: Check panic data after crash and do soft reboot. */ + else if (state & TEST_STATE_MASK(TEST_STATE_STEP_2)) { + RUN_TEST(test_panic_data); + if (!test_get_error_count()) { + test_set_next_step(TEST_STATE_STEP_3); + /* Do a soft system reset */ + ccprintf("Perform soft reboot\n"); + cflush(); + system_reset(0); + } else + test_reboot_to_next_step(TEST_STATE_FAILED); + } + /* Step 3: Check panic data after soft reboot and do hard reboot. */ + else if (state & TEST_STATE_MASK(TEST_STATE_STEP_3)) { + RUN_TEST(test_panic_data); + if (!test_get_error_count()) { + test_set_next_step(TEST_STATE_STEP_4); + /* Do a hard system reset */ + ccprintf("Perform hard reboot\n"); + cflush(); + system_reset(SYSTEM_RESET_HARD); + } else + test_reboot_to_next_step(TEST_STATE_FAILED); + } + /* Step 4: Check panic data after hard reboot */ + else if (state & TEST_STATE_MASK(TEST_STATE_STEP_4)) { + RUN_TEST(test_panic_data_half); + if (!test_get_error_count()) + test_reboot_to_next_step(TEST_STATE_PASSED); + else + test_reboot_to_next_step(TEST_STATE_FAILED); + } +} + +int task_test(void *unused) +{ + if (IS_ENABLED(SECTION_IS_RW)) + test_run_multistep(); + + return EC_SUCCESS; +} + +void run_test(int argc, char **argv) +{ + test_reset(); + msleep(30); /* Wait for TASK_ID_TEST to initialize */ + task_wake(TASK_ID_TEST); +} diff --git a/test/panic_data.tasklist b/test/panic_data.tasklist new file mode 100644 index 0000000000..6a2f1834ca --- /dev/null +++ b/test/panic_data.tasklist @@ -0,0 +1,10 @@ +/* Copyright 2022 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. + */ + +/** + * See CONFIG_TASK_LIST in config.h for details. + */ +#define CONFIG_TEST_TASK_LIST \ + TASK_TEST(TEST, task_test, NULL, TASK_STACK_SIZE) diff --git a/test/run_device_tests.py b/test/run_device_tests.py index 2643634062..e138051d0c 100755 --- a/test/run_device_tests.py +++ b/test/run_device_tests.py @@ -67,6 +67,18 @@ SERVO_MICRO = 'servo_micro' GCC = 'gcc' CLANG = 'clang' +TEST_ASSETS_BUCKET = 'gs://chromiumos-test-assets-public/fpmcu/RO' +DARTMONKEY_IMAGE_PATH = os.path.join( + TEST_ASSETS_BUCKET, 'dartmonkey_v2.0.2887-311310808.bin') +NOCTURNE_FP_IMAGE_PATH = os.path.join( + TEST_ASSETS_BUCKET, 'nocturne_fp_v2.2.64-58cf5974e.bin') +NAMI_FP_IMAGE_PATH = os.path.join( + TEST_ASSETS_BUCKET, 'nami_fp_v2.2.144-7a08e07eb.bin') +BLOONCHIPPER_V4277_IMAGE_PATH = os.path.join( + TEST_ASSETS_BUCKET, 'bloonchipper_v2.0.4277-9f652bb3.bin') +BLOONCHIPPER_V5938_IMAGE_PATH = os.path.join( + TEST_ASSETS_BUCKET, 'bloonchipper_v2.0.5938-197506c1.bin') + class ImageType(Enum): """EC Image type to use for the test.""" @@ -78,13 +90,15 @@ class BoardConfig: """Board-specific configuration.""" def __init__(self, name, servo_uart_name, servo_power_enable, - rollback_region0_regex, rollback_region1_regex, mpu_regex): + rollback_region0_regex, rollback_region1_regex, mpu_regex, + variants): self.name = name self.servo_uart_name = servo_uart_name self.servo_power_enable = servo_power_enable self.rollback_region0_regex = rollback_region0_regex self.rollback_region1_regex = rollback_region1_regex self.mpu_regex = mpu_regex + self.variants = variants class TestConfig: @@ -204,6 +218,15 @@ class AllTests: if board_config.name == BLOONCHIPPER: tests['stm32f_rtc'] = TestConfig(name='stm32f_rtc') + # Run panic data tests for all boards and RO versions. + for variant_name, variant_info in board_config.variants.items(): + tests['panic_data_' + variant_name] = ( + TestConfig(name='panic_data', + fail_regexes=[SINGLE_CHECK_FAILED_REGEX, + ALL_TESTS_FAILED_REGEX], + ro_image=variant_info.get('ro_image_path'), + build_board=variant_info.get('build_board'))) + return tests @@ -214,6 +237,14 @@ BLOONCHIPPER_CONFIG = BoardConfig( rollback_region0_regex=DATA_ACCESS_VIOLATION_8020000_REGEX, rollback_region1_regex=DATA_ACCESS_VIOLATION_8040000_REGEX, mpu_regex=DATA_ACCESS_VIOLATION_20000000_REGEX, + variants={ + 'bloonchipper_v2.0.4277': { + 'ro_image_path': BLOONCHIPPER_V4277_IMAGE_PATH + }, + 'bloonchipper_v2.0.5938': { + 'ro_image_path': BLOONCHIPPER_V5938_IMAGE_PATH + } + } ) DARTMONKEY_CONFIG = BoardConfig( @@ -223,6 +254,21 @@ DARTMONKEY_CONFIG = BoardConfig( rollback_region0_regex=DATA_ACCESS_VIOLATION_80C0000_REGEX, rollback_region1_regex=DATA_ACCESS_VIOLATION_80E0000_REGEX, mpu_regex=DATA_ACCESS_VIOLATION_24000000_REGEX, + # For dartmonkey board, run panic data test also on nocturne_fp and + # nami_fp boards with appropriate RO image. + variants={ + 'dartmonkey_v2.0.2887': { + 'ro_image_path': DARTMONKEY_IMAGE_PATH + }, + 'nocturne_fp_v2.2.64': { + 'ro_image_path': NOCTURNE_FP_IMAGE_PATH, + 'build_board': 'nocturne_fp' + }, + 'nami_fp_v2.2.144': { + 'ro_image_path': NAMI_FP_IMAGE_PATH, + 'build_board': 'nami_fp' + } + } ) BOARD_CONFIGS = { |