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_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 static int dm_test_main(const char *test_name) 114 { 115 struct unit_test *tests = ll_entry_start(struct unit_test, dm_test); 116 const int n_ents = ll_entry_count(struct unit_test, dm_test); 117 struct unit_test_state *uts = &global_dm_test_state; 118 struct unit_test *test; 119 int run_count; 120 121 uts->priv = &_global_priv_dm_test_state; 122 uts->fail_count = 0; 123 124 /* 125 * If we have no device tree, or it only has a root node, then these 126 * tests clearly aren't going to work... 127 */ 128 if (!gd->fdt_blob || fdt_next_node(gd->fdt_blob, 0, NULL) < 0) { 129 puts("Please run with test device tree:\n" 130 " ./u-boot -d arch/sandbox/dts/test.dtb\n"); 131 ut_assert(gd->fdt_blob); 132 } 133 134 if (!test_name) 135 printf("Running %d driver model tests\n", n_ents); 136 137 run_count = 0; 138 #ifdef CONFIG_OF_LIVE 139 uts->of_root = gd->of_root; 140 #endif 141 for (test = tests; test < tests + n_ents; test++) { 142 const char *name = test->name; 143 144 /* All tests have this prefix */ 145 if (!strncmp(name, "dm_test_", 8)) 146 name += 8; 147 if (test_name && strcmp(test_name, name)) 148 continue; 149 ut_assertok(dm_do_test(uts, test, false)); 150 run_count++; 151 } 152 153 if (test_name && !run_count) 154 printf("Test '%s' not found\n", test_name); 155 else 156 printf("Failures: %d\n", uts->fail_count); 157 158 gd->dm_root = NULL; 159 ut_assertok(dm_init(false)); 160 dm_scan_platdata(false); 161 dm_scan_fdt(gd->fdt_blob, false); 162 163 return uts->fail_count ? CMD_RET_FAILURE : 0; 164 } 165 166 int do_ut_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 167 { 168 const char *test_name = NULL; 169 170 if (argc > 1) 171 test_name = argv[1]; 172 173 return dm_test_main(test_name); 174 } 175