| // SPDX-License-Identifier: GPL-2.0 | |
| /* | |
| * KUnit tests for OF APIs | |
| */ | |
| #include <linux/ioport.h> | |
| #include <linux/module.h> | |
| #include <linux/of.h> | |
| #include <kunit/test.h> | |
| #include "of_private.h" | |
| /* | |
| * Test that the root node "/" can be found by path. | |
| */ | |
| static void of_dtb_root_node_found_by_path(struct kunit *test) | |
| { | |
| struct device_node *np; | |
| np = of_find_node_by_path("/"); | |
| KUNIT_EXPECT_NOT_ERR_OR_NULL(test, np); | |
| of_node_put(np); | |
| } | |
| /* | |
| * Test that the 'of_root' global variable is always populated when DT code is | |
| * enabled. Remove this test once of_root is removed from global access. | |
| */ | |
| static void of_dtb_root_node_populates_of_root(struct kunit *test) | |
| { | |
| KUNIT_EXPECT_NOT_ERR_OR_NULL(test, of_root); | |
| } | |
| static struct kunit_case of_dtb_test_cases[] = { | |
| KUNIT_CASE(of_dtb_root_node_found_by_path), | |
| KUNIT_CASE(of_dtb_root_node_populates_of_root), | |
| {} | |
| }; | |
| static int of_dtb_test_init(struct kunit *test) | |
| { | |
| of_root_kunit_skip(test); | |
| if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE)) | |
| kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE"); | |
| return 0; | |
| } | |
| /* | |
| * Test suite to confirm a DTB is loaded. | |
| */ | |
| static struct kunit_suite of_dtb_suite = { | |
| .name = "of_dtb", | |
| .test_cases = of_dtb_test_cases, | |
| .init = of_dtb_test_init, | |
| }; | |
| struct of_address_resource_bounds_case { | |
| u64 start; | |
| u64 size; | |
| int ret; | |
| u64 res_start; | |
| u64 res_end; | |
| }; | |
| static void of_address_resource_bounds_case_desc(const struct of_address_resource_bounds_case *p, | |
| char *name) | |
| { | |
| snprintf(name, KUNIT_PARAM_DESC_SIZE, "start=0x%016llx,size=0x%016llx", p->start, p->size); | |
| } | |
| static const struct of_address_resource_bounds_case of_address_resource_bounds_cases[] = { | |
| { | |
| .start = 0, | |
| .size = 0, | |
| .ret = 0, | |
| .res_start = 0, | |
| .res_end = -1, | |
| }, | |
| { | |
| .start = 0, | |
| .size = 0x1000, | |
| .ret = 0, | |
| .res_start = 0, | |
| .res_end = 0xfff, | |
| }, | |
| { | |
| .start = 0x1000, | |
| .size = 0, | |
| .ret = 0, | |
| .res_start = 0x1000, | |
| .res_end = 0xfff, | |
| }, | |
| { | |
| .start = 0x1000, | |
| .size = 0x1000, | |
| .ret = 0, | |
| .res_start = 0x1000, | |
| .res_end = 0x1fff, | |
| }, | |
| { | |
| .start = 1, | |
| .size = RESOURCE_SIZE_MAX, | |
| .ret = 0, | |
| .res_start = 1, | |
| .res_end = RESOURCE_SIZE_MAX, | |
| }, | |
| { | |
| .start = RESOURCE_SIZE_MAX, | |
| .size = 1, | |
| .ret = 0, | |
| .res_start = RESOURCE_SIZE_MAX, | |
| .res_end = RESOURCE_SIZE_MAX, | |
| }, | |
| { | |
| .start = 2, | |
| .size = RESOURCE_SIZE_MAX, | |
| .ret = -EOVERFLOW, | |
| }, | |
| { | |
| .start = RESOURCE_SIZE_MAX, | |
| .size = 2, | |
| .ret = -EOVERFLOW, | |
| }, | |
| { | |
| .start = ULL(0x100000000), | |
| .size = 1, | |
| .ret = sizeof(resource_size_t) > sizeof(u32) ? 0 : -EOVERFLOW, | |
| .res_start = ULL(0x100000000), | |
| .res_end = ULL(0x100000000), | |
| }, | |
| { | |
| .start = 0x1000, | |
| .size = 0xffffffff, | |
| .ret = sizeof(resource_size_t) > sizeof(u32) ? 0 : -EOVERFLOW, | |
| .res_start = 0x1000, | |
| .res_end = ULL(0x100000ffe), | |
| }, | |
| }; | |
| KUNIT_ARRAY_PARAM(of_address_resource_bounds, | |
| of_address_resource_bounds_cases, of_address_resource_bounds_case_desc); | |
| static void of_address_resource_bounds(struct kunit *test) | |
| { | |
| const struct of_address_resource_bounds_case *param = test->param_value; | |
| struct resource r; /* Intentionally uninitialized */ | |
| int ret; | |
| if (!IS_ENABLED(CONFIG_OF_ADDRESS)) | |
| kunit_skip(test, "CONFIG_OF_ADDRESS not enabled\n"); | |
| ret = __of_address_resource_bounds(&r, param->start, param->size); | |
| KUNIT_EXPECT_EQ(test, param->ret, ret); | |
| if (ret == 0) { | |
| KUNIT_EXPECT_EQ(test, (resource_size_t)param->res_start, r.start); | |
| KUNIT_EXPECT_EQ(test, (resource_size_t)param->res_end, r.end); | |
| KUNIT_EXPECT_EQ(test, param->size, resource_size(&r)); | |
| } | |
| } | |
| static struct kunit_case of_address_test_cases[] = { | |
| KUNIT_CASE_PARAM(of_address_resource_bounds, of_address_resource_bounds_gen_params), | |
| {} | |
| }; | |
| static struct kunit_suite of_address_suite = { | |
| .name = "of_address", | |
| .test_cases = of_address_test_cases, | |
| }; | |
| kunit_test_suites( | |
| &of_dtb_suite, &of_address_suite, | |
| ); | |
| MODULE_DESCRIPTION("KUnit tests for OF APIs"); | |
| MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); | |
| MODULE_LICENSE("GPL"); |