summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Honscheid <honscheid@google.com>2022-11-23 10:03:44 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-11-30 23:11:03 +0000
commit9446042f202f9e03e8cd97807493b9eba3188ff1 (patch)
tree0a7d4d110aa047a7205a16770c50c9f9ce995dea
parent91893ee143fed8e99da15f8b3b522e7750b5a1dd (diff)
downloadchrome-ec-9446042f202f9e03e8cd97807493b9eba3188ff1.tar.gz
zephyr: test: Test get_panic_data_write()
Test the get_panic_data_write() implementation used in device builds Also remove an unreachable `else` statement from the function (The jump data version cannot be anything other than 1, 2, or 3 since we check that a few lines above) BRANCH=None BUG=None TEST=./twister Signed-off-by: Tristan Honscheid <honscheid@google.com> Change-Id: Ie83cf3c655662498ef6a487d51d39c65d790de2d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4052122 Commit-Queue: Tristan Honscheid <honscheid@google.com> Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com> Tested-by: Tristan Honscheid <honscheid@google.com> Reviewed-by: Tomasz Michalec <tmichalec@google.com>
-rw-r--r--common/panic_output.c9
-rw-r--r--zephyr/test/drivers/panic_output/CMakeLists.txt1
-rw-r--r--zephyr/test/drivers/panic_output/src/panic_output_get_panic_data_write.c209
3 files changed, 215 insertions, 4 deletions
diff --git a/common/panic_output.c b/common/panic_output.c
index 066eb05d6f..87b83043f3 100644
--- a/common/panic_output.c
+++ b/common/panic_output.c
@@ -256,16 +256,13 @@ test_mockable struct panic_data *get_panic_data_write(void)
return pdata_ptr;
}
+ move_size = 0;
if (jdata_ptr->version == 1)
move_size = JUMP_DATA_SIZE_V1;
else if (jdata_ptr->version == 2)
move_size = JUMP_DATA_SIZE_V2 + jdata_ptr->jump_tag_total;
else if (jdata_ptr->version == 3)
move_size = jdata_ptr->struct_size + jdata_ptr->jump_tag_total;
- else {
- /* Unknown jump data version - set move size to 0 */
- move_size = 0;
- }
/* Check if there's enough space for jump tags after move */
if (data_begin - move_size < JUMP_DATA_MIN_ADDRESS) {
@@ -273,8 +270,12 @@ test_mockable struct panic_data *get_panic_data_write(void)
* TODO(b/251190975): This failure should be reported
* in the panic data structure for more visibility.
*/
+ /* LCOV_EXCL_START - JUMP_DATA_MIN_ADDRESS is 0 in test builds
+ * and we cannot go negative by subtracting unsigned ints.
+ */
move_size -= jdata_ptr->jump_tag_total;
jdata_ptr->jump_tag_total = 0;
+ /* LCOV_EXCL_STOP */
}
data_begin -= move_size;
diff --git a/zephyr/test/drivers/panic_output/CMakeLists.txt b/zephyr/test/drivers/panic_output/CMakeLists.txt
index 79cf21fc5f..c9b50b0365 100644
--- a/zephyr/test/drivers/panic_output/CMakeLists.txt
+++ b/zephyr/test/drivers/panic_output/CMakeLists.txt
@@ -5,4 +5,5 @@
# Add source files
target_sources(app PRIVATE
src/panic_output_crash_cmd.c
+ src/panic_output_get_panic_data_write.c
)
diff --git a/zephyr/test/drivers/panic_output/src/panic_output_get_panic_data_write.c b/zephyr/test/drivers/panic_output/src/panic_output_get_panic_data_write.c
new file mode 100644
index 0000000000..e1f4cda84c
--- /dev/null
+++ b/zephyr/test/drivers/panic_output/src/panic_output_get_panic_data_write.c
@@ -0,0 +1,209 @@
+/* Copyright 2022 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <zephyr/ztest.h>
+#include <zephyr/ztest_assert.h>
+
+#include "panic.h"
+#include "sysjump.h"
+#include "test/drivers/test_state.h"
+
+/**
+ * @brief Returns a pointer to an object (such as a struct jump_data) of type
+ * TYPE at the end of the mock_jump_data memory region, plus an optional,
+ * additional offset of OFFSET bytes. OFFSET can be used to help get the
+ * pointer after jump data has been moved by get_panic_data_write(), or
+ * left as zero to get the pre-move location.
+ */
+#define GET_JUMP_DATA_PTR(TYPE, OFFSET) \
+ ((TYPE *)(mock_jump_data + sizeof(mock_jump_data) - sizeof(TYPE) + \
+ (OFFSET)))
+
+ZTEST(panic_output_get_panic_data_write, test_existing_panic_data)
+{
+ struct panic_data *pdata_actual = test_get_panic_data_pointer();
+
+ /* Pretend panic data exists by setting the magic header and setting its
+ * size.
+ */
+ pdata_actual->magic = PANIC_DATA_MAGIC;
+ pdata_actual->struct_size = CONFIG_PANIC_DATA_SIZE;
+
+ /* Verify that pdata_ptr is returned */
+ zassert_equal(pdata_actual, get_panic_data_write());
+}
+
+ZTEST(panic_output_get_panic_data_write, test_no_panic_data__no_jump_data)
+{
+ struct panic_data *pdata_actual = test_get_panic_data_pointer();
+ struct panic_data pdata_expected = {
+ .magic = PANIC_DATA_MAGIC,
+ .struct_size = CONFIG_PANIC_DATA_SIZE,
+ };
+
+ /* Don't fill in any panic data, but add some fake data so we can ensure
+ * it gets reset to zero.
+ */
+ pdata_actual->flags = 0xFF;
+
+ /* Verify that pdata_ptr is returned */
+ zassert_equal(pdata_actual, get_panic_data_write());
+
+ /* Verify the pdata struct has correct fields filled out. */
+ zassert_mem_equal(&pdata_expected, pdata_actual,
+ sizeof(struct panic_data));
+}
+
+/**
+ * @brief Implements the fields of a version 1 jump_data header.
+ *
+ */
+struct jump_data_v1 {
+ /** V1 Jump data header, always goes at end. See sysjump.h for info */
+
+ uint32_t reset_flags;
+ int version;
+ int magic;
+};
+
+/* Test that V1 jump data is moved correctly. */
+ZTEST(panic_output_get_panic_data_write, test_no_panic_data__jump_data_v1)
+{
+ struct panic_data *pdata_actual = test_get_panic_data_pointer();
+ struct jump_data_v1 jdata_expected = {
+ .magic = JUMP_DATA_MAGIC,
+ .version = 1,
+ .reset_flags = 0xAABBCCDD,
+ };
+
+ /* Set up some jump data. Version 1 does not have any jump tags, only
+ * the magic, version number, and reset_flags so it is constant size.
+ */
+ *GET_JUMP_DATA_PTR(struct jump_data_v1, 0) = jdata_expected;
+
+ /* Verify that pdata_ptr is returned */
+ zassert_equal(pdata_actual, get_panic_data_write());
+
+ /* Verify that jump data has been moved to its new location */
+ ssize_t expected_move_delta = -1 * sizeof(struct panic_data);
+ struct jump_data_v1 *jdata_moved =
+ GET_JUMP_DATA_PTR(struct jump_data_v1, expected_move_delta);
+
+ zassert_mem_equal(&jdata_expected, jdata_moved,
+ sizeof(struct jump_data_v1));
+}
+
+/**
+ * @brief Implements a V2 jump_data header plus some extra bytes in front that
+ * represent jump tag data. This reflects how they are stored in the EC's
+ * memory. The jump_tag_total field in jdata stored how many bytes of
+ * preceding jump tag data exists.
+ */
+struct jump_data_v2_plus_tags {
+ /** Arbitrary amount of jump tag data. */
+ uint8_t tag_data[8];
+ /** V2 Jump data header, always goes at end. See sysjump.h for info */
+ struct {
+ int jump_tag_total;
+ uint32_t reset_flags;
+ int version;
+ int magic;
+ } jdata;
+};
+
+/* Test that V2 jump data is moved correctly. */
+ZTEST(panic_output_get_panic_data_write, test_no_panic_data__jump_data_v2)
+{
+ struct panic_data *pdata_actual = test_get_panic_data_pointer();
+ struct jump_data_v2_plus_tags jdata_expected = {
+ /* Arbitrary jump tag data */
+ .tag_data = {1, 2, 3, 4, 5, 6, 7, 8},
+ .jdata = {
+ .magic = JUMP_DATA_MAGIC,
+ .version = 2,
+ .reset_flags = 0xAABBCCDD,
+ .jump_tag_total = sizeof(jdata_expected.tag_data),
+ },
+ };
+
+ /* Set up some jump data and preceding tags */
+ *GET_JUMP_DATA_PTR(struct jump_data_v2_plus_tags, 0) = jdata_expected;
+
+ /* Verify that pdata_ptr is returned */
+ zassert_equal(pdata_actual, get_panic_data_write());
+
+ /* Verify that jump data and tags moved to their new location */
+ ssize_t expected_move_delta = -1 * sizeof(struct panic_data);
+ struct jump_data_v2_plus_tags *jdata_moved = GET_JUMP_DATA_PTR(
+ struct jump_data_v2_plus_tags, expected_move_delta);
+
+ zassert_mem_equal(&jdata_expected, jdata_moved,
+ sizeof(struct jump_data_v2_plus_tags));
+}
+
+/**
+ * @brief Implements a V3 jump_data header with space in front for jump tag data
+ */
+struct jump_data_v3_plus_tags {
+ /** Arbitrary amount of jump tag data. */
+ uint8_t tag_data[8];
+ /** V3 Jump data header, always goes at end. See sysjump.h for info */
+ struct {
+ uint8_t reserved0;
+ int struct_size;
+ int jump_tag_total;
+ uint32_t reset_flags;
+ int version;
+ int magic;
+ } jdata;
+};
+
+/* Test that V3 jump data is moved correctly. */
+ZTEST(panic_output_get_panic_data_write, test_no_panic_data__jump_data_v3)
+{
+ struct panic_data *pdata_actual = test_get_panic_data_pointer();
+ struct jump_data_v3_plus_tags jdata_expected = {
+ /* Arbitrary jump tag data */
+ .tag_data = {1, 2, 3, 4, 5, 6, 7, 8},
+ .jdata = {
+ .magic = JUMP_DATA_MAGIC,
+ .version = 3,
+ .reset_flags = 0xAABBCCDD,
+ .jump_tag_total = sizeof(jdata_expected.tag_data),
+ .struct_size = sizeof(jdata_expected.jdata),
+ .reserved0 = 0xFF,
+ },
+ };
+
+ /* Set up some jump data and preceding tags */
+ *GET_JUMP_DATA_PTR(struct jump_data_v3_plus_tags, 0) = jdata_expected;
+
+ /* Verify that pdata_ptr is returned */
+ zassert_equal(pdata_actual, get_panic_data_write());
+
+ /* Verify that jump data and tags moved to their new location */
+ ssize_t expected_move_delta = -1 * sizeof(struct panic_data);
+ struct jump_data_v3_plus_tags *jdata_moved = GET_JUMP_DATA_PTR(
+ struct jump_data_v3_plus_tags, expected_move_delta);
+
+ zassert_mem_equal(&jdata_expected, jdata_moved,
+ sizeof(struct jump_data_v3_plus_tags));
+}
+
+static void reset(void *data)
+{
+ ARG_UNUSED(data);
+
+ struct panic_data *pdata = test_get_panic_data_pointer();
+
+ memset(pdata, 0, sizeof(struct panic_data));
+ memset(mock_jump_data, 0, sizeof(mock_jump_data));
+}
+
+ZTEST_SUITE(panic_output_get_panic_data_write, drivers_predicate_post_main,
+ NULL, reset, reset, NULL);