1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2015 Google, Inc
4  */
5 
6 #include <common.h>
7 #include <dm.h>
8 #include <mapmem.h>
9 #include <dm/root.h>
10 #include <dm/util.h>
11 #include <dm/uclass-internal.h>
12 
show_devices(struct udevice * dev,int depth,int last_flag)13 static void show_devices(struct udevice *dev, int depth, int last_flag)
14 {
15 	int i, is_last;
16 	struct udevice *child;
17 	u32 flags = dev_get_flags(dev);
18 
19 	/* print the first 20 characters to not break the tree-format. */
20 	printf(IS_ENABLED(CONFIG_SPL_BUILD) ? " %s  %d  [ %c ]   %s  " :
21 	       " %-10.10s  %3d  [ %c ]   %-20.20s  ", dev->uclass->uc_drv->name,
22 	       dev_get_uclass_index(dev, NULL),
23 	       flags & DM_FLAG_ACTIVATED ? '+' : ' ', dev->driver->name);
24 
25 	for (i = depth; i >= 0; i--) {
26 		is_last = (last_flag >> i) & 1;
27 		if (i) {
28 			if (is_last)
29 				printf("    ");
30 			else
31 				printf("|   ");
32 		} else {
33 			if (is_last)
34 				printf("`-- ");
35 			else
36 				printf("|-- ");
37 		}
38 	}
39 
40 	printf("%s\n", dev->name);
41 
42 	list_for_each_entry(child, &dev->child_head, sibling_node) {
43 		is_last = list_is_last(&child->sibling_node, &dev->child_head);
44 		show_devices(child, depth + 1, (last_flag << 1) | is_last);
45 	}
46 }
47 
dm_dump_all(void)48 void dm_dump_all(void)
49 {
50 	struct udevice *root;
51 
52 	root = dm_root();
53 	if (root) {
54 		printf(" Class     Index  Probed  Driver                Name\n");
55 		printf("-----------------------------------------------------------\n");
56 		show_devices(root, -1, 0);
57 	}
58 }
59 
60 /**
61  * dm_display_line() - Display information about a single device
62  *
63  * Displays a single line of information with an option prefix
64  *
65  * @dev:	Device to display
66  */
dm_display_line(struct udevice * dev,int index)67 static void dm_display_line(struct udevice *dev, int index)
68 {
69 	printf("%-3i %c %s @ %08lx", index,
70 	       dev_get_flags(dev) & DM_FLAG_ACTIVATED ? '*' : ' ',
71 	       dev->name, (ulong)map_to_sysmem(dev));
72 	if (dev->seq_ != -1)
73 		printf(", seq %d", dev_seq(dev));
74 	puts("\n");
75 }
76 
dm_dump_uclass(void)77 void dm_dump_uclass(void)
78 {
79 	struct uclass *uc;
80 	int ret;
81 	int id;
82 
83 	for (id = 0; id < UCLASS_COUNT; id++) {
84 		struct udevice *dev;
85 		int i = 0;
86 
87 		ret = uclass_get(id, &uc);
88 		if (ret)
89 			continue;
90 
91 		printf("uclass %d: %s\n", id, uc->uc_drv->name);
92 		if (list_empty(&uc->dev_head))
93 			continue;
94 		uclass_foreach_dev(dev, uc) {
95 			dm_display_line(dev, i);
96 			i++;
97 		}
98 		puts("\n");
99 	}
100 }
101 
dm_dump_driver_compat(void)102 void dm_dump_driver_compat(void)
103 {
104 	struct driver *d = ll_entry_start(struct driver, driver);
105 	const int n_ents = ll_entry_count(struct driver, driver);
106 	struct driver *entry;
107 	const struct udevice_id *match;
108 
109 	puts("Driver                Compatible\n");
110 	puts("--------------------------------\n");
111 	for (entry = d; entry < d + n_ents; entry++) {
112 		match = entry->of_match;
113 
114 		printf("%-20.20s", entry->name);
115 		if (match) {
116 			printf("  %s", match->compatible);
117 			match++;
118 		}
119 		printf("\n");
120 
121 		for (; match && match->compatible; match++)
122 			printf("%-20.20s  %s\n", "", match->compatible);
123 	}
124 }
125 
dm_dump_drivers(void)126 void dm_dump_drivers(void)
127 {
128 	struct driver *d = ll_entry_start(struct driver, driver);
129 	const int n_ents = ll_entry_count(struct driver, driver);
130 	struct driver *entry;
131 	struct udevice *udev;
132 	struct uclass *uc;
133 	int i;
134 
135 	puts("Driver                    uid uclass               Devices\n");
136 	puts("----------------------------------------------------------\n");
137 
138 	for (entry = d; entry < d + n_ents; entry++) {
139 		uclass_get(entry->id, &uc);
140 
141 		printf("%-25.25s %-3.3d %-20.20s ", entry->name, entry->id,
142 		       uc ? uc->uc_drv->name : "<no uclass>");
143 
144 		if (!uc) {
145 			puts("\n");
146 			continue;
147 		}
148 
149 		i = 0;
150 		uclass_foreach_dev(udev, uc) {
151 			if (udev->driver != entry)
152 				continue;
153 			if (i)
154 				printf("%-51.51s", "");
155 
156 			printf("%-25.25s\n", udev->name);
157 			i++;
158 		}
159 		if (!i)
160 			puts("<none>\n");
161 	}
162 }
163 
dm_dump_static_driver_info(void)164 void dm_dump_static_driver_info(void)
165 {
166 	struct driver_info *drv = ll_entry_start(struct driver_info,
167 						 driver_info);
168 	const int n_ents = ll_entry_count(struct driver_info, driver_info);
169 	struct driver_info *entry;
170 
171 	puts("Driver                    Address\n");
172 	puts("---------------------------------\n");
173 	for (entry = drv; entry != drv + n_ents; entry++) {
174 		printf("%-25.25s @%08lx\n", entry->name,
175 		       (ulong)map_to_sysmem(entry->plat));
176 	}
177 }
178