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