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