1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 2013 Google, Inc 4 */ 5 6 #include <common.h> 7 #include <command.h> 8 #include <console.h> 9 #include <dm.h> 10 #include <errno.h> 11 #include <malloc.h> 12 #include <asm/state.h> 13 #include <dm/test.h> 14 #include <dm/root.h> 15 #include <dm/uclass-internal.h> 16 #include <test/ut.h> 17 18 DECLARE_GLOBAL_DATA_PTR; 19 20 struct unit_test_state global_dm_test_state; 21 static struct dm_test_state _global_priv_dm_test_state; 22 23 /* Get ready for testing */ 24 static int dm_test_init(struct unit_test_state *uts, bool of_live) 25 { 26 struct dm_test_state *dms = uts->priv; 27 28 memset(dms, '\0', sizeof(*dms)); 29 gd->dm_root = NULL; 30 memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); 31 state_reset_for_test(state_get_current()); 32 33 #ifdef CONFIG_OF_LIVE 34 /* Determine whether to make the live tree available */ 35 gd->of_root = of_live ? uts->of_root : NULL; 36 #endif 37 ut_assertok(dm_init(of_live)); 38 dms->root = dm_root(); 39 40 return 0; 41 } 42 43 /* Ensure all the test devices are probed */ 44 static int do_autoprobe(struct unit_test_state *uts) 45 { 46 struct udevice *dev; 47 int ret; 48 49 /* Scanning the uclass is enough to probe all the devices */ 50 for (ret = uclass_first_device(UCLASS_TEST, &dev); 51 dev; 52 ret = uclass_next_device(&dev)) 53 ; 54 55 return ret; 56 } 57 58 static int dm_test_destroy(struct unit_test_state *uts) 59 { 60 int id; 61 62 for (id = 0; id < UCLASS_COUNT; id++) { 63 struct uclass *uc; 64 65 /* 66 * If the uclass doesn't exist we don't want to create it. So 67 * check that here before we call uclass_find_device()/ 68 */ 69 uc = uclass_find(id); 70 if (!uc) 71 continue; 72 ut_assertok(uclass_destroy(uc)); 73 } 74 75 return 0; 76 } 77 78 static int dm_do_test(struct unit_test_state *uts, struct unit_test *test, 79 bool of_live) 80 { 81 struct sandbox_state *state = state_get_current(); 82 const char *fname = strrchr(test->file, '/') + 1; 83 84 printf("Test: %s: %s%s\n", test->name, fname, 85 !of_live ? " (flat tree)" : ""); 86 ut_assertok(dm_test_init(uts, of_live)); 87 88 uts->start = mallinfo(); 89 if (test->flags & DM_TESTF_SCAN_PDATA) 90 ut_assertok(dm_scan_platdata(false)); 91 if (test->flags & DM_TESTF_PROBE_TEST) 92 ut_assertok(do_autoprobe(uts)); 93 if (test->flags & DM_TESTF_SCAN_FDT) 94 ut_assertok(dm_extended_scan_fdt(gd->fdt_blob, false)); 95 96 /* 97 * Silence the console and rely on console recording to get 98 * our output. 99 */ 100 console_record_reset(); 101 if (!state->show_test_output) 102 gd->flags |= GD_FLG_SILENT; 103 test->func(uts); 104 gd->flags &= ~GD_FLG_SILENT; 105 state_set_skip_delays(false); 106 107 ut_assertok(dm_test_destroy(uts)); 108 109 return 0; 110 } 111 112 /** 113 * dm_test_run_on_flattree() - Check if we should run a test with flat DT 114 * 115 * This skips long/slow tests where there is not much value in running a flat 116 * DT test in addition to a live DT test. 117 * 118 * @return true to run the given test on the flat device tree 119 */ 120 static bool dm_test_run_on_flattree(struct unit_test *test) 121 { 122 const char *fname = strrchr(test->file, '/') + 1; 123 124 return !strstr(fname, "video") || strstr(test->name, "video_base"); 125 } 126 127 static int dm_test_main(const char *test_name) 128 { 129 struct unit_test *tests = ll_entry_start(struct unit_test, dm_test); 130 const int n_ents = ll_entry_count(struct unit_test, dm_test); 131 struct unit_test_state *uts = &global_dm_test_state; 132 struct unit_test *test; 133 int run_count; 134 135 uts->priv = &_global_priv_dm_test_state; 136 uts->fail_count = 0; 137 138 /* 139 * If we have no device tree, or it only has a root node, then these 140 * tests clearly aren't going to work... 141 */ 142 if (!gd->fdt_blob || fdt_next_node(gd->fdt_blob, 0, NULL) < 0) { 143 puts("Please run with test device tree:\n" 144 " ./u-boot -d arch/sandbox/dts/test.dtb\n"); 145 ut_assert(gd->fdt_blob); 146 } 147 148 if (!test_name) 149 printf("Running %d driver model tests\n", n_ents); 150 151 run_count = 0; 152 #ifdef CONFIG_OF_LIVE 153 uts->of_root = gd->of_root; 154 #endif 155 for (test = tests; test < tests + n_ents; test++) { 156 const char *name = test->name; 157 int runs; 158 159 /* All tests have this prefix */ 160 if (!strncmp(name, "dm_test_", 8)) 161 name += 8; 162 if (test_name && strcmp(test_name, name)) 163 continue; 164 165 /* Run with the live tree if possible */ 166 runs = 0; 167 if (IS_ENABLED(CONFIG_OF_LIVE)) { 168 if (!(test->flags & DM_TESTF_FLAT_TREE)) { 169 ut_assertok(dm_do_test(uts, test, true)); 170 runs++; 171 } 172 } 173 174 /* 175 * Run with the flat tree if we couldn't run it with live tree, 176 * or it is a core test. 177 */ 178 if (!(test->flags & DM_TESTF_LIVE_TREE) && 179 (!runs || dm_test_run_on_flattree(test))) { 180 ut_assertok(dm_do_test(uts, test, false)); 181 runs++; 182 } 183 run_count += runs; 184 } 185 186 if (test_name && !run_count) 187 printf("Test '%s' not found\n", test_name); 188 else 189 printf("Failures: %d\n", uts->fail_count); 190 191 gd->dm_root = NULL; 192 ut_assertok(dm_init(false)); 193 dm_scan_platdata(false); 194 dm_scan_fdt(gd->fdt_blob, false); 195 196 return uts->fail_count ? CMD_RET_FAILURE : 0; 197 } 198 199 int do_ut_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 200 { 201 const char *test_name = NULL; 202 203 if (argc > 1) 204 test_name = argv[1]; 205 206 return dm_test_main(test_name); 207 } 208