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) 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 33 ut_assertok(dm_init()); 34 dms->root = dm_root(); 35 36 return 0; 37 } 38 39 /* Ensure all the test devices are probed */ 40 static int do_autoprobe(struct unit_test_state *uts) 41 { 42 struct udevice *dev; 43 int ret; 44 45 /* Scanning the uclass is enough to probe all the devices */ 46 for (ret = uclass_first_device(UCLASS_TEST, &dev); 47 dev; 48 ret = uclass_next_device(&dev)) 49 ; 50 51 return ret; 52 } 53 54 static int dm_test_destroy(struct unit_test_state *uts) 55 { 56 int id; 57 58 for (id = 0; id < UCLASS_COUNT; id++) { 59 struct uclass *uc; 60 61 /* 62 * If the uclass doesn't exist we don't want to create it. So 63 * check that here before we call uclass_find_device()/ 64 */ 65 uc = uclass_find(id); 66 if (!uc) 67 continue; 68 ut_assertok(uclass_destroy(uc)); 69 } 70 71 return 0; 72 } 73 74 static int dm_test_main(const char *test_name) 75 { 76 struct unit_test *tests = ll_entry_start(struct unit_test, dm_test); 77 const int n_ents = ll_entry_count(struct unit_test, dm_test); 78 struct unit_test_state *uts = &global_dm_test_state; 79 struct sandbox_state *state = state_get_current(); 80 uts->priv = &_global_priv_dm_test_state; 81 struct unit_test *test; 82 int run_count; 83 84 uts->fail_count = 0; 85 86 /* 87 * If we have no device tree, or it only has a root node, then these 88 * tests clearly aren't going to work... 89 */ 90 if (!gd->fdt_blob || fdt_next_node(gd->fdt_blob, 0, NULL) < 0) { 91 puts("Please run with test device tree:\n" 92 " ./u-boot -d arch/sandbox/dts/test.dtb\n"); 93 ut_assert(gd->fdt_blob); 94 } 95 96 if (!test_name) 97 printf("Running %d driver model tests\n", n_ents); 98 99 run_count = 0; 100 for (test = tests; test < tests + n_ents; test++) { 101 const char *name = test->name; 102 103 /* All tests have this prefix */ 104 if (!strncmp(name, "dm_test_", 8)) 105 name += 8; 106 if (test_name && strcmp(test_name, name)) 107 continue; 108 printf("Test: %s\n", test->name); 109 run_count++; 110 ut_assertok(dm_test_init(uts)); 111 112 uts->start = mallinfo(); 113 if (test->flags & DM_TESTF_SCAN_PDATA) 114 ut_assertok(dm_scan_platdata(false)); 115 if (test->flags & DM_TESTF_PROBE_TEST) 116 ut_assertok(do_autoprobe(uts)); 117 if (test->flags & DM_TESTF_SCAN_FDT) 118 ut_assertok(dm_scan_fdt(gd->fdt_blob, false)); 119 120 /* 121 * Silence the console and rely on console reocrding to get 122 * our output. 123 */ 124 console_record_reset(); 125 if (!state->show_test_output) 126 gd->flags |= GD_FLG_SILENT; 127 test->func(uts); 128 gd->flags &= ~GD_FLG_SILENT; 129 state_set_skip_delays(false); 130 131 ut_assertok(dm_test_destroy(uts)); 132 } 133 134 if (test_name && !run_count) 135 printf("Test '%s' not found\n", test_name); 136 else 137 printf("Failures: %d\n", uts->fail_count); 138 139 gd->dm_root = NULL; 140 ut_assertok(dm_init()); 141 dm_scan_platdata(false); 142 dm_scan_fdt(gd->fdt_blob, false); 143 144 return uts->fail_count ? CMD_RET_FAILURE : 0; 145 } 146 147 int do_ut_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 148 { 149 const char *test_name = NULL; 150 151 if (argc > 1) 152 test_name = argv[1]; 153 154 return dm_test_main(test_name); 155 } 156