Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | // SPDX-License-Identifier: GPL-2.0+ /* * Tests for fdt command * * Copyright 2022 Google LLCmap_to_sysmem(fdt)); */ #include <common.h> #include <console.h> #include <fdt_support.h> #include <mapmem.h> #include <asm/global_data.h> #include <linux/libfdt.h> #include <test/suites.h> #include <test/ut.h> DECLARE_GLOBAL_DATA_PTR; /* Declare a new fdt test */ #define FDT_TEST(_name, _flags) UNIT_TEST(_name, _flags, fdt_test) /** * make_test_fdt() - Create an FDT with just a root node * * The size is set to the minimum needed * * @uts: Test state * @fdt: Place to write FDT * @size: Maximum size of space for fdt */ static int make_test_fdt(struct unit_test_state *uts, void *fdt, int size) { ut_assertok(fdt_create(fdt, size)); ut_assertok(fdt_finish_reservemap(fdt)); ut_assert(fdt_begin_node(fdt, "") >= 0); ut_assertok(fdt_end_node(fdt)); ut_assertok(fdt_finish(fdt)); return 0; } /* Test 'fdt addr' getting/setting address */ static int fdt_test_addr(struct unit_test_state *uts) { const void *fdt_blob, *new_fdt; char fdt[256]; ulong addr; int ret; ut_assertok(console_record_reset_enable()); ut_assertok(run_command("fdt addr -c", 0)); ut_assert_nextline("Control fdt: %08lx", (ulong)map_to_sysmem(gd->fdt_blob)); ut_assertok(ut_check_console_end(uts)); /* The working fdt is not set, so this should fail */ set_working_fdt_addr(0); ut_asserteq(CMD_RET_FAILURE, run_command("fdt addr", 0)); ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC"); ut_assertok(ut_check_console_end(uts)); /* Set up a working FDT and try again */ ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt))); addr = map_to_sysmem(fdt); set_working_fdt_addr(addr); ut_assertok(run_command("fdt addr", 0)); ut_assert_nextline("Working fdt: %08lx", (ulong)map_to_sysmem(fdt)); ut_assertok(ut_check_console_end(uts)); /* Set the working FDT */ set_working_fdt_addr(0); ut_assertok(run_commandf("fdt addr %08x", addr)); ut_asserteq(addr, map_to_sysmem(working_fdt)); ut_assertok(ut_check_console_end(uts)); set_working_fdt_addr(0); /* Set the working FDT */ fdt_blob = gd->fdt_blob; gd->fdt_blob = NULL; ret = run_commandf("fdt addr -c %08x", addr); new_fdt = gd->fdt_blob; gd->fdt_blob = fdt_blob; ut_assertok(ret); ut_asserteq(addr, map_to_sysmem(new_fdt)); ut_assertok(ut_check_console_end(uts)); /* Test setting an invalid FDT */ fdt[0] = 123; ut_asserteq(1, run_commandf("fdt addr %08x", addr)); ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC"); ut_assertok(ut_check_console_end(uts)); /* Test detecting an invalid FDT */ fdt[0] = 123; set_working_fdt_addr(addr); ut_asserteq(1, run_commandf("fdt addr")); ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC"); ut_assertok(ut_check_console_end(uts)); return 0; } FDT_TEST(fdt_test_addr, UT_TESTF_CONSOLE_REC); /* Test 'fdt addr' resizing an fdt */ static int fdt_test_resize(struct unit_test_state *uts) { char fdt[256]; const int newsize = sizeof(fdt) / 2; ulong addr; ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt))); addr = map_to_sysmem(fdt); set_working_fdt_addr(addr); /* Test setting and resizing the working FDT to a larger size */ ut_assertok(console_record_reset_enable()); ut_assertok(run_commandf("fdt addr %08x %x", addr, newsize)); ut_assertok(ut_check_console_end(uts)); /* Try shrinking it */ ut_assertok(run_commandf("fdt addr %08x %x", addr, sizeof(fdt) / 4)); ut_assert_nextline("New length %d < existing length %d, ignoring", (int)sizeof(fdt) / 4, newsize); ut_assertok(ut_check_console_end(uts)); /* ...quietly */ ut_assertok(run_commandf("fdt addr -q %08x %x", addr, sizeof(fdt) / 4)); ut_assertok(ut_check_console_end(uts)); /* We cannot easily provoke errors in fdt_open_into(), so ignore that */ return 0; } FDT_TEST(fdt_test_resize, UT_TESTF_CONSOLE_REC); int do_ut_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { struct unit_test *tests = UNIT_TEST_SUITE_START(fdt_test); const int n_ents = UNIT_TEST_SUITE_COUNT(fdt_test); return cmd_ut_category("fdt", "fdt_test_", tests, n_ents, argc, argv); } |