1 /*
2 * Copyright Meta Platforms, Inc. and its affiliates.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/drivers/coredump.h>
8 #include <zephyr/ztest.h>
9
10 /* Test will verify that these values are present in the core dump */
11 #define TEST_MEMORY_VALUE_0 0xabababab
12 #define TEST_MEMORY_VALUE_1 0xcdcdcdcd
13 #define TEST_MEMORY_VALUE_2 0xefefefef
14
15 #if defined(CONFIG_BOARD_QEMU_RISCV32)
16 #define TEST_MEMORY_VALUE_3 0x12121212
17 #define TEST_MEMORY_VALUE_4 0x34343434
18 #define TEST_MEMORY_VALUE_5 0x56565656
19 #define TEST_MEMORY_VALUE_6 0x78787878
20 #define TEST_MEMORY_VALUE_7 0x90909090
21 #endif
22
23 #define TEST_MEMORY_VALUE_8 0xbabababa
24
25 static uint32_t values_to_dump[3];
26 static struct coredump_mem_region_node dump_region0 = {
27 .start = (uintptr_t)&values_to_dump,
28 .size = sizeof(values_to_dump)
29 };
30
test_coredump_callback(uintptr_t dump_area,size_t dump_area_size)31 static void test_coredump_callback(uintptr_t dump_area, size_t dump_area_size)
32 {
33 uint32_t expected_size = DT_PROP_BY_IDX(DT_NODELABEL(coredump_devicecb), memory_regions, 1);
34
35 zassert_equal(dump_area_size, expected_size, "Size in callback doesn't match device tree");
36 zassert_not_null((void *)dump_area, "dump_area is NULL");
37
38 uint32_t *mem = (uint32_t *)dump_area;
39 *mem = TEST_MEMORY_VALUE_8;
40 }
41
coredump_tests_suite_setup(void)42 static void *coredump_tests_suite_setup(void)
43 {
44 #if defined(CONFIG_BOARD_QEMU_RISCV32)
45 /* Get addresses of memory regions specified in device tree to fill with test data */
46 uint32_t *mem0 =
47 (uint32_t *)DT_PROP_BY_IDX(DT_NODELABEL(coredump_device0), memory_regions, 0);
48 uint32_t *mem1 =
49 (uint32_t *)DT_PROP_BY_IDX(DT_NODELABEL(coredump_device0), memory_regions, 2);
50 uint32_t *mem2 =
51 (uint32_t *)DT_PROP_BY_IDX(DT_NODELABEL(coredump_device1), memory_regions, 0);
52
53 *mem0 = TEST_MEMORY_VALUE_3;
54 *mem1 = TEST_MEMORY_VALUE_4;
55 mem2[0] = TEST_MEMORY_VALUE_5;
56 mem2[1] = TEST_MEMORY_VALUE_6;
57 mem2[2] = TEST_MEMORY_VALUE_7;
58 #endif
59
60 return NULL;
61 }
62
63 ZTEST_SUITE(coredump_tests, NULL, coredump_tests_suite_setup, NULL, NULL, NULL);
64
ZTEST(coredump_tests,test_register_memory)65 ZTEST(coredump_tests, test_register_memory)
66 {
67 const struct device *const coredump_dev = DEVICE_DT_GET(DT_NODELABEL(coredump_device0));
68 const struct device *const coredump_cb_dev = DEVICE_DT_GET(DT_NODELABEL(coredump_devicecb));
69
70 zassert_not_null(coredump_dev, "Cannot get coredump device");
71
72 /* Verify register callback fails for COREDUMP_TYPE_MEMCPY type device */
73 zassert_false(coredump_device_register_callback(coredump_dev, test_coredump_callback),
74 "register callback unexpected succeeded");
75
76 /* Verify unregister fails for memory that was never registered */
77 zassert_false(coredump_device_unregister_memory(coredump_dev, &dump_region0),
78 "unregister unexpected succeeded");
79
80 /* Verify unregister succeeds after registration */
81 zassert_true(coredump_device_register_memory(coredump_dev, &dump_region0),
82 "register failed");
83 zassert_true(coredump_device_unregister_memory(coredump_dev, &dump_region0),
84 "unregister failed");
85
86 /* Register dump_region0 to be collected in core dump and set test values */
87 zassert_true(coredump_device_register_memory(coredump_dev, &dump_region0),
88 "register failed");
89 values_to_dump[0] = TEST_MEMORY_VALUE_0;
90 values_to_dump[1] = TEST_MEMORY_VALUE_1;
91 values_to_dump[2] = TEST_MEMORY_VALUE_2;
92
93 /* Verify register memory region fails for COREDUMP_TYPE_CALLBACK type device */
94 zassert_false(coredump_device_register_memory(coredump_cb_dev, &dump_region0),
95 "register memory unexpected succeeded");
96
97 /* Register callback to be invoked for the COREDUMP_TYPE_CALLBACK type device */
98 zassert_true(coredump_device_register_callback(coredump_cb_dev, test_coredump_callback),
99 "register failed");
100
101 /* Force a crash */
102 k_panic();
103 }
104