blob: 256441392ca50d5021e42e903e3a9ec1cfbd4d4d [file] [log] [blame]
/*
* Copyright Meta Platforms, Inc. and its affiliates.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/drivers/coredump.h>
#include <zephyr/ztest.h>
/* Test will verify that these values are present in the core dump */
#define TEST_MEMORY_VALUE_0 0xabababab
#define TEST_MEMORY_VALUE_1 0xcdcdcdcd
#define TEST_MEMORY_VALUE_2 0xefefefef
#if defined(CONFIG_BOARD_QEMU_RISCV32)
#define TEST_MEMORY_VALUE_3 0x12121212
#define TEST_MEMORY_VALUE_4 0x34343434
#define TEST_MEMORY_VALUE_5 0x56565656
#define TEST_MEMORY_VALUE_6 0x78787878
#define TEST_MEMORY_VALUE_7 0x90909090
#endif
#define TEST_MEMORY_VALUE_8 0xbabababa
static uint32_t values_to_dump[3];
static struct coredump_mem_region_node dump_region0 = {
.start = (uintptr_t)&values_to_dump,
.size = sizeof(values_to_dump)
};
static void test_coredump_callback(uintptr_t dump_area, size_t dump_area_size)
{
uint32_t expected_size = DT_PROP_BY_IDX(DT_NODELABEL(coredump_devicecb), memory_regions, 1);
zassert_equal(dump_area_size, expected_size, "Size in callback doesn't match device tree");
zassert_not_null((void *)dump_area, "dump_area is NULL");
uint32_t *mem = (uint32_t *)dump_area;
*mem = TEST_MEMORY_VALUE_8;
}
static void *coredump_tests_suite_setup(void)
{
#if defined(CONFIG_BOARD_QEMU_RISCV32)
/* Get addresses of memory regions specified in device tree to fill with test data */
uint32_t *mem0 =
(uint32_t *)DT_PROP_BY_IDX(DT_NODELABEL(coredump_device0), memory_regions, 0);
uint32_t *mem1 =
(uint32_t *)DT_PROP_BY_IDX(DT_NODELABEL(coredump_device0), memory_regions, 2);
uint32_t *mem2 =
(uint32_t *)DT_PROP_BY_IDX(DT_NODELABEL(coredump_device1), memory_regions, 0);
*mem0 = TEST_MEMORY_VALUE_3;
*mem1 = TEST_MEMORY_VALUE_4;
mem2[0] = TEST_MEMORY_VALUE_5;
mem2[1] = TEST_MEMORY_VALUE_6;
mem2[2] = TEST_MEMORY_VALUE_7;
#endif
return NULL;
}
ZTEST_SUITE(coredump_tests, NULL, coredump_tests_suite_setup, NULL, NULL, NULL);
ZTEST(coredump_tests, test_register_memory)
{
const struct device *coredump_dev = DEVICE_DT_GET(DT_NODELABEL(coredump_device0));
const struct device *coredump_cb_dev = DEVICE_DT_GET(DT_NODELABEL(coredump_devicecb));
zassert_not_null(coredump_dev, "Cannot get coredump device");
/* Verify register callback fails for COREDUMP_TYPE_MEMCPY type device */
zassert_false(coredump_device_register_callback(coredump_dev, test_coredump_callback),
"register callback unexpected succeeded");
/* Verify unregister fails for memory that was never registered */
zassert_false(coredump_device_unregister_memory(coredump_dev, &dump_region0),
"unregister unexpected succeeded");
/* Verify unregister succeeds after registration */
zassert_true(coredump_device_register_memory(coredump_dev, &dump_region0),
"register failed");
zassert_true(coredump_device_unregister_memory(coredump_dev, &dump_region0),
"unregister failed");
/* Register dump_region0 to be collected in core dump and set test values */
zassert_true(coredump_device_register_memory(coredump_dev, &dump_region0),
"register failed");
values_to_dump[0] = TEST_MEMORY_VALUE_0;
values_to_dump[1] = TEST_MEMORY_VALUE_1;
values_to_dump[2] = TEST_MEMORY_VALUE_2;
/* Verify register memory region fails for COREDUMP_TYPE_CALLBACK type device */
zassert_false(coredump_device_register_memory(coredump_cb_dev, &dump_region0),
"register memory unexpected succeeded");
/* Register callback to be invoked for the COREDUMP_TYPE_CALLBACK type device */
zassert_true(coredump_device_register_callback(coredump_cb_dev, test_coredump_callback),
"register failed");
/* Force a crash */
k_panic();
}