/* * Copyright Meta Platforms, Inc. and its affiliates. * * SPDX-License-Identifier: Apache-2.0 */ #include #include /* 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 #ifdef CONFIG_COVERAGE_DUMP #include #endif 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) }; void k_sys_fatal_error_handler(unsigned int reason, const struct arch_esf *pEsf) { ARG_UNUSED(pEsf); printk("%s as expected; reason = %u; halting ...\n", __func__, reason); #ifdef CONFIG_COVERAGE_DUMP gcov_coverage_dump(); /* LCOV_EXCL_LINE */ #endif k_fatal_halt(reason); } 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 *const coredump_dev = DEVICE_DT_GET(DT_NODELABEL(coredump_device0)); const struct device *const 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(); }