1 /*
2 * K3CONF Command Dump
3 *
4 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
5 * Lokesh Vutla <lokeshvutla@ti.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the
17 * distribution.
18 *
19 * Neither the name of Texas Instruments Incorporated nor the names of
20 * its contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
36 #include <stdlib.h>
37 #include <string.h>
38 #include <stdio.h>
39 #include <tisci.h>
40 #include <socinfo.h>
41 #include <help.h>
42 #include <autoadjust_table.h>
43 #include <k3conf.h>
45 int dump_cpu_info(void)
46 {
47 struct ti_sci_processors_info *p = soc_info.sci_info.processors_info;
48 char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN];
49 uint32_t row = 0, found = 0;
50 uint64_t freq;
52 autoadjust_table_init(table);
53 strncpy(table[row][0], "Processor Name", TABLE_MAX_ELT_LEN);
54 strncpy(table[row][1], "Processor State", TABLE_MAX_ELT_LEN);
55 strncpy(table[row][2], "Processor Frequency", TABLE_MAX_ELT_LEN);
57 for (row = 0; row < soc_info.sci_info.num_processors; row++) {
58 if (strncmp(p[row].name, "A", 1))
59 continue;
60 strncpy(table[found + 1][0], p[row].name, TABLE_MAX_ELT_LEN);
61 /* ToDo: Should we get the state from proc ops */
62 snprintf(table[found + 1][1], TABLE_MAX_ELT_LEN, "%s",
63 ti_sci_cmd_get_device_status(p[row].dev_id));
64 ti_sci_cmd_get_clk_freq(p[row].dev_id, p[row].clk_id, &freq);
65 snprintf(table[found + 1][2], TABLE_MAX_ELT_LEN, "%lu", freq);
66 found++;
67 }
69 return autoadjust_table_print(table, found + 1, 3);
70 }
72 int dump_clocks_info(int argc, char *argv[])
73 {
74 struct ti_sci_clocks_info *c = soc_info.sci_info.clocks_info;
75 char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN];
76 uint32_t row = 0, dev_id;
77 int found = 0, ret;
78 uint64_t freq;
80 autoadjust_table_init(table);
81 strncpy(table[row][0], "Device ID", TABLE_MAX_ELT_LEN);
82 strncpy(table[row][1], "Clock ID", TABLE_MAX_ELT_LEN);
83 strncpy(table[row][2], "Clock Name", TABLE_MAX_ELT_LEN);
84 strncpy(table[row][3], "Status", TABLE_MAX_ELT_LEN);
85 strncpy(table[row][4], "Clock Frequency", TABLE_MAX_ELT_LEN);
87 if (argc)
88 goto print_single_device;
90 for (row = 0; row < soc_info.sci_info.num_clocks; row++) {
91 snprintf(table[row + 1][0], TABLE_MAX_ELT_LEN, "%5d",
92 c[row].dev_id);
93 snprintf(table[row + 1][1], TABLE_MAX_ELT_LEN, "%5d",
94 c[row].clk_id);
95 strncpy(table[row + 1][2], c[row].clk_name, TABLE_MAX_ELT_LEN);
96 snprintf(table[row + 1][3], TABLE_MAX_ELT_LEN, "%s",
97 ti_sci_cmd_get_clk_state(c[row].dev_id, c[row].clk_id));
98 ti_sci_cmd_get_clk_freq(c[row].dev_id, c[row].clk_id, &freq);
99 snprintf(table[row + 1][4], TABLE_MAX_ELT_LEN, "%lu", freq);
100 }
102 return autoadjust_table_print(table, row + 1, 5);
104 print_single_device:
105 ret = sscanf(argv[0], "%u", &dev_id);
106 if (ret != 1)
107 return -1;
109 for (row = 0; row < soc_info.sci_info.num_clocks; row++) {
110 if (dev_id == c[row].dev_id) {
111 snprintf(table[found + 1][0], TABLE_MAX_ELT_LEN, "%5d",
112 c[row].dev_id);
113 snprintf(table[found + 1][1], TABLE_MAX_ELT_LEN, "%5d",
114 c[row].clk_id);
115 strncpy(table[found + 1][2], c[row].clk_name,
116 TABLE_MAX_ELT_LEN);
117 strncpy(table[found + 1][3],
118 ti_sci_cmd_get_clk_state(dev_id, c[row].clk_id),
119 TABLE_MAX_ELT_LEN);
120 ti_sci_cmd_get_clk_freq(c[row].dev_id, c[row].clk_id,
121 &freq);
122 snprintf(table[found + 1][4], TABLE_MAX_ELT_LEN, "%lu",
123 freq);
124 found++;
125 }
126 }
128 if (!found)
129 return -1;
131 return autoadjust_table_print(table, found + 1, 5);
132 }
134 int dump_devices_info(int argc, char *argv[])
135 {
136 struct ti_sci_devices_info *p = soc_info.sci_info.devices_info;
137 char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN];
138 uint32_t row = 0, dev_id;
139 int found = 0, ret;
141 autoadjust_table_init(table);
142 strncpy(table[row][0], "Device ID", TABLE_MAX_ELT_LEN);
143 strncpy(table[row][1], "Device Name", TABLE_MAX_ELT_LEN);
144 strncpy(table[row][2], "Device Status", TABLE_MAX_ELT_LEN);
146 if (argc)
147 goto print_single_device;
149 for (row = 0; row < soc_info.sci_info.num_devices; row++) {
150 snprintf(table[row + 1][0], TABLE_MAX_ELT_LEN, "%5d",
151 p[row].dev_id);
152 strncpy(table[row + 1][1], p[row].name, TABLE_MAX_ELT_LEN);
153 snprintf(table[row + 1][2], TABLE_MAX_ELT_LEN, "%s",
154 ti_sci_cmd_get_device_status(p[row].dev_id));
155 }
157 return autoadjust_table_print(table, row + 1, 3);
159 print_single_device:
160 ret = sscanf(argv[0], "%u", &dev_id);
161 if (ret != 1)
162 return -1;
164 for (row = 0; row < soc_info.sci_info.num_devices; row++) {
165 if (dev_id == p[row].dev_id) {
166 snprintf(table[1][0], TABLE_MAX_ELT_LEN, "%5d",
167 p[row].dev_id);
168 strncpy(table[1][1], p[row].name,
169 TABLE_MAX_ELT_LEN);
170 snprintf(table[1][2], TABLE_MAX_ELT_LEN, "%s",
171 ti_sci_cmd_get_device_status(p[row].dev_id));
172 found = 1;
173 break;
174 }
175 }
177 if (!found)
178 return -1;
180 return autoadjust_table_print(table, 2, 3);
181 }
183 static int dump_processors_info(int argc, char *argv[])
184 {
185 struct ti_sci_processors_info *p = soc_info.sci_info.processors_info;
186 char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN];
187 uint32_t row = 0, proc_id;
188 int found = 0, ret;
189 uint64_t freq;
191 autoadjust_table_init(table);
192 strncpy(table[row][0], "Device ID", TABLE_MAX_ELT_LEN);
193 strncpy(table[row][1], "Processor ID", TABLE_MAX_ELT_LEN);
194 strncpy(table[row][2], "Processor Name", TABLE_MAX_ELT_LEN);
195 strncpy(table[row][3], "Processor State", TABLE_MAX_ELT_LEN);
196 strncpy(table[row][4], "Processor Frequency", TABLE_MAX_ELT_LEN);
198 if (argc)
199 goto print_single_processor;
201 for (row = 0; row < soc_info.sci_info.num_processors; row++) {
202 snprintf(table[row + 1][0], TABLE_MAX_ELT_LEN, "%5d",
203 p[row].dev_id);
204 snprintf(table[row + 1][1], TABLE_MAX_ELT_LEN, "%7d",
205 p[row].processor_id);
206 strncpy(table[row + 1][2], p[row].name, TABLE_MAX_ELT_LEN);
207 /* ToDo: Should we get the state from proc ops */
208 snprintf(table[row + 1][3], TABLE_MAX_ELT_LEN, "%s",
209 ti_sci_cmd_get_device_status(p[row].dev_id));
210 ti_sci_cmd_get_clk_freq(p[row].dev_id, p[row].clk_id, &freq);
211 snprintf(table[row + 1][4], TABLE_MAX_ELT_LEN, "%lu", freq);
212 }
214 return autoadjust_table_print(table, row + 1, 5);
216 print_single_processor:
217 ret = sscanf(argv[0], "%u", &proc_id);
218 if (ret != 1)
219 return -1;
221 for (row = 0; row < soc_info.sci_info.num_processors; row++) {
222 if (proc_id != p[row].processor_id)
223 continue;
224 snprintf(table[found + 1][0], TABLE_MAX_ELT_LEN, "%5d",
225 p[row].dev_id);
226 snprintf(table[found + 1][1], TABLE_MAX_ELT_LEN, "%7d",
227 p[row].processor_id);
228 strncpy(table[found + 1][2], p[row].name, TABLE_MAX_ELT_LEN);
229 /* ToDo: Should we get the state from proc ops */
230 snprintf(table[found + 1][3], TABLE_MAX_ELT_LEN, "%s",
231 ti_sci_cmd_get_device_status(p[row].dev_id));
232 ti_sci_cmd_get_clk_freq(p[row].dev_id, p[row].clk_id, &freq);
233 snprintf(table[found + 1][4], TABLE_MAX_ELT_LEN, "%lu", freq);
234 found++;
235 break;
236 }
237 if (!found)
238 return -1;
240 return autoadjust_table_print(table, found + 1, 5);
241 }
243 static int dump_rm_resource(u_int32_t type, u_int32_t subtype,
244 u_int32_t host_id, char *value)
245 {
246 struct ti_sci_rm_desc desc;
247 int ret;
249 ret = ti_sci_cmd_get_range(type, subtype, host_id, &desc);
250 if (ret)
251 return ret;
253 if (desc.num_sec && desc.num) {
255 /* Print Primary + Secondary range */
256 snprintf(value, TABLE_MAX_ELT_LEN, "[%5d +%4d] (%4d +%3d)",
257 desc.start, desc.num,
258 desc.start_sec, desc.num_sec);
260 } else if (desc.num_sec) {
262 /* Print blank + Secondary range */
263 snprintf(value, TABLE_MAX_ELT_LEN, "[ ] (%4d +%3d)",
264 desc.start_sec, desc.num_sec);
265 } else if (desc.num) {
267 /* Print only Primary range */
268 snprintf(value, TABLE_MAX_ELT_LEN,
269 "[%5d +%4d]",
270 desc.start, desc.num);
271 } else {
272 *value = 0;
273 }
275 return 0;
276 }
278 static int dump_rm_info(int argc, char *argv[])
279 {
280 uint32_t filter_host_id = 0, filter_type = 0, filter_subtype = 0xFFF;
281 char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN];
282 struct ti_sci_host_info *h = soc_info.sci_info.host_info;
283 struct ti_sci_rm_info *r = soc_info.sci_info.rm_info;
284 uint32_t type, subtype, host_id, host_valid;
285 char cell[TABLE_MAX_ELT_LEN], *host_name;
286 uint32_t i, j, row, col;
287 int ret;
289 if (argc > 0 && !strcmp(argv[0], "-h")) {
291 if (argc == 1)
292 return -1;
294 sscanf(argv[1], "%u", &filter_host_id);
295 argc -= 2;
296 argv += 2;
297 }
299 if (argc > 0) {
300 sscanf(argv[0], "%u", &filter_type);
301 argc--;
302 argv++;
303 }
305 if (argc > 0) {
306 sscanf(argv[0], "%u", &filter_subtype);
307 argc--;
308 argv++;
309 }
311 autoadjust_table_init(table);
312 snprintf(table[0][0], TABLE_MAX_ELT_LEN,
313 "Resource allocation => [Primary start +count] (Secondary start +count)");
314 snprintf(table[1][0], TABLE_MAX_ELT_LEN,
315 "utype");
316 snprintf(table[1][1], TABLE_MAX_ELT_LEN,
317 "type");
318 snprintf(table[1][2], TABLE_MAX_ELT_LEN,
319 "subtype");
321 row = 2;
322 col = 3;
323 for (i = 0; i < soc_info.sci_info.num_hosts; i++) {
325 host_valid = 0;
326 host_id = h[i].host_id;
327 host_name = h[i].host_name;
328 if (filter_host_id && host_id != filter_host_id)
329 continue;
331 row = 2;
332 for (j = 0; j < soc_info.sci_info.num_res; j++) {
334 type = r[j].utype >> 6;
335 subtype = r[j].utype & 0x3F;
337 if (filter_type && type != filter_type)
338 continue;
339 if (filter_subtype != 0xFFF && subtype != filter_subtype)
340 continue;
342 snprintf(table[row][0], TABLE_MAX_ELT_LEN,
343 "0x%04x", r[j].utype);
344 snprintf(table[row][1], TABLE_MAX_ELT_LEN,
345 "%d", type);
346 snprintf(table[row][2], TABLE_MAX_ELT_LEN,
347 "%d", subtype);
349 ret = dump_rm_resource(type, subtype, host_id, cell);
350 if (ret)
351 return ret;
353 if (!cell[0]) {
354 row++;
355 continue;
356 }
358 host_valid = 1;
359 snprintf(table[row][col], TABLE_MAX_ELT_LEN,
360 "%s", cell);
361 row++;
362 }
364 if (!host_valid)
365 continue;
367 snprintf(table[1][col], TABLE_MAX_ELT_LEN,
368 "%s", host_name);
369 col++;
370 }
372 return autoadjust_table_generic_fprint(stdout, table, row, col,
373 TABLE_HAS_TITLE | TABLE_HAS_SUBTITLE);
374 }
376 int process_dump_command(int argc, char *argv[])
377 {
378 int ret;
380 if (argc < 1) {
381 help(HELP_DUMP);
382 return -1;
383 }
385 if (!strncmp(argv[0], "device", 6)) {
386 argc--;
387 argv++;
388 ret = dump_devices_info(argc, argv);
389 if (ret) {
390 fprintf(stderr, "Invalid device arguments\n");
391 help(HELP_DUMP_DEVICE);
392 }
393 } else if (!strncmp(argv[0], "clock", 5)) {
394 argc--;
395 argv++;
396 ret = dump_clocks_info(argc, argv);
397 if (ret) {
398 fprintf(stderr, "Invalid clock arguments\n");
399 help(HELP_DUMP_CLOCK);
400 }
401 } else if(!strncmp(argv[0], "processor", 9)) {
402 argc--;
403 argv++;
404 ret = dump_processors_info(argc, argv);
405 if (ret)
406 help(HELP_DUMP_PROCESSOR);
407 } else if(!strncmp(argv[0], "rm", 2)) {
408 argc--;
409 argv++;
410 ret = dump_rm_info(argc, argv);
411 if (ret) {
412 fprintf(stderr, "Invalid arguments\n");
413 help(HELP_DUMP_RM);
414 }
415 } else if (!strcmp(argv[0], "--help")) {
416 help(HELP_DUMP);
417 return 0;
418 } else {
419 fprintf(stderr, "Invalid argument %s\n", argv[1]);
420 help(HELP_DUMP);
421 return -1;
422 }
423 return ret;
424 }