183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
22e192b24SSimon Glass /*
32e192b24SSimon Glass * Copyright (c) 2014 Google, Inc
42e192b24SSimon Glass */
52e192b24SSimon Glass
62e192b24SSimon Glass #include <common.h>
72e192b24SSimon Glass #include <command.h>
82e192b24SSimon Glass #include <iotrace.h>
92e192b24SSimon Glass
do_print_stats(void)102e192b24SSimon Glass static void do_print_stats(void)
112e192b24SSimon Glass {
12*e0212dfaSRamon Fried ulong start, size, needed_size, offset, count;
132e192b24SSimon Glass
142e192b24SSimon Glass printf("iotrace is %sabled\n", iotrace_get_enabled() ? "en" : "dis");
15*e0212dfaSRamon Fried iotrace_get_buffer(&start, &size, &needed_size, &offset, &count);
162e192b24SSimon Glass printf("Start: %08lx\n", start);
17*e0212dfaSRamon Fried printf("Actual Size: %08lx\n", size);
18*e0212dfaSRamon Fried printf("Needed Size: %08lx\n", needed_size);
19b559c4afSRamon Fried iotrace_get_region(&start, &size);
20b559c4afSRamon Fried printf("Region: %08lx\n", start);
21b559c4afSRamon Fried printf("Size: %08lx\n", size);
222e192b24SSimon Glass printf("Offset: %08lx\n", offset);
232e192b24SSimon Glass printf("Output: %08lx\n", start + offset);
242e192b24SSimon Glass printf("Count: %08lx\n", count);
252e192b24SSimon Glass printf("CRC32: %08lx\n", (ulong)iotrace_get_checksum());
262e192b24SSimon Glass }
272e192b24SSimon Glass
do_print_trace(void)28501c89d3SRamon Fried static void do_print_trace(void)
29501c89d3SRamon Fried {
30*e0212dfaSRamon Fried ulong start, size, needed_size, offset, count;
31501c89d3SRamon Fried
32501c89d3SRamon Fried struct iotrace_record *cur_record;
33501c89d3SRamon Fried
34*e0212dfaSRamon Fried iotrace_get_buffer(&start, &size, &needed_size, &offset, &count);
35501c89d3SRamon Fried
36501c89d3SRamon Fried if (!start || !size || !count)
37501c89d3SRamon Fried return;
38501c89d3SRamon Fried
39501c89d3SRamon Fried printf("Timestamp Value Address\n");
40501c89d3SRamon Fried
41501c89d3SRamon Fried cur_record = (struct iotrace_record *)start;
42501c89d3SRamon Fried for (int i = 0; i < count; i++) {
43501c89d3SRamon Fried if (cur_record->flags & IOT_WRITE)
44501c89d3SRamon Fried printf("%08llu: 0x%08lx --> 0x%08llx\n",
45501c89d3SRamon Fried cur_record->timestamp,
46501c89d3SRamon Fried cur_record->value,
47501c89d3SRamon Fried (unsigned long long)cur_record->addr);
48501c89d3SRamon Fried else
49501c89d3SRamon Fried printf("%08llu: 0x%08lx <-- 0x%08llx\n",
50501c89d3SRamon Fried cur_record->timestamp,
51501c89d3SRamon Fried cur_record->value,
52501c89d3SRamon Fried (unsigned long long)cur_record->addr);
53501c89d3SRamon Fried
54501c89d3SRamon Fried cur_record++;
55501c89d3SRamon Fried }
56501c89d3SRamon Fried }
57501c89d3SRamon Fried
do_set_buffer(int argc,char * const argv[])582e192b24SSimon Glass static int do_set_buffer(int argc, char * const argv[])
592e192b24SSimon Glass {
602e192b24SSimon Glass ulong addr = 0, size = 0;
612e192b24SSimon Glass
622e192b24SSimon Glass if (argc == 2) {
632e192b24SSimon Glass addr = simple_strtoul(*argv++, NULL, 16);
642e192b24SSimon Glass size = simple_strtoul(*argv++, NULL, 16);
652e192b24SSimon Glass } else if (argc != 0) {
662e192b24SSimon Glass return CMD_RET_USAGE;
672e192b24SSimon Glass }
682e192b24SSimon Glass
692e192b24SSimon Glass iotrace_set_buffer(addr, size);
702e192b24SSimon Glass
712e192b24SSimon Glass return 0;
722e192b24SSimon Glass }
732e192b24SSimon Glass
do_set_region(int argc,char * const argv[])74b559c4afSRamon Fried static int do_set_region(int argc, char * const argv[])
75b559c4afSRamon Fried {
76b559c4afSRamon Fried ulong addr = 0, size = 0;
77b559c4afSRamon Fried
78b559c4afSRamon Fried if (argc == 2) {
79b559c4afSRamon Fried addr = simple_strtoul(*argv++, NULL, 16);
80b559c4afSRamon Fried size = simple_strtoul(*argv++, NULL, 16);
81b559c4afSRamon Fried } else if (argc != 0) {
82b559c4afSRamon Fried return CMD_RET_USAGE;
83b559c4afSRamon Fried }
84b559c4afSRamon Fried
85b559c4afSRamon Fried iotrace_set_region(addr, size);
86b559c4afSRamon Fried
87b559c4afSRamon Fried return 0;
88b559c4afSRamon Fried }
89b559c4afSRamon Fried
do_iotrace(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])902e192b24SSimon Glass int do_iotrace(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
912e192b24SSimon Glass {
922e192b24SSimon Glass const char *cmd = argc < 2 ? NULL : argv[1];
932e192b24SSimon Glass
942e192b24SSimon Glass if (!cmd)
952e192b24SSimon Glass return cmd_usage(cmdtp);
962e192b24SSimon Glass switch (*cmd) {
972e192b24SSimon Glass case 'b':
982e192b24SSimon Glass return do_set_buffer(argc - 2, argv + 2);
99b559c4afSRamon Fried case 'l':
100b559c4afSRamon Fried return do_set_region(argc - 2, argv + 2);
1012e192b24SSimon Glass case 'p':
1022e192b24SSimon Glass iotrace_set_enabled(0);
1032e192b24SSimon Glass break;
1042e192b24SSimon Glass case 'r':
1052e192b24SSimon Glass iotrace_set_enabled(1);
1062e192b24SSimon Glass break;
1072e192b24SSimon Glass case 's':
1082e192b24SSimon Glass do_print_stats();
1092e192b24SSimon Glass break;
110501c89d3SRamon Fried case 'd':
111501c89d3SRamon Fried do_print_trace();
112501c89d3SRamon Fried break;
1132e192b24SSimon Glass default:
1142e192b24SSimon Glass return CMD_RET_USAGE;
1152e192b24SSimon Glass }
1162e192b24SSimon Glass
1172e192b24SSimon Glass return 0;
1182e192b24SSimon Glass }
1192e192b24SSimon Glass
1202e192b24SSimon Glass U_BOOT_CMD(
1212e192b24SSimon Glass iotrace, 4, 1, do_iotrace,
1222e192b24SSimon Glass "iotrace utility commands",
1232e192b24SSimon Glass "stats - display iotrace stats\n"
1242e192b24SSimon Glass "iotrace buffer <address> <size> - set iotrace buffer\n"
125b559c4afSRamon Fried "iotrace limit <address> <size> - set iotrace region limit\n"
1262e192b24SSimon Glass "iotrace pause - pause tracing\n"
127501c89d3SRamon Fried "iotrace resume - resume tracing\n"
128501c89d3SRamon Fried "iotrace dump - dump iotrace buffer"
1292e192b24SSimon Glass );
130