1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 2014 Google, Inc 4 */ 5 6 #include <common.h> 7 #include <command.h> 8 #include <iotrace.h> 9 10 static void do_print_stats(void) 11 { 12 ulong start, size, needed_size, offset, count; 13 14 printf("iotrace is %sabled\n", iotrace_get_enabled() ? "en" : "dis"); 15 iotrace_get_buffer(&start, &size, &needed_size, &offset, &count); 16 printf("Start: %08lx\n", start); 17 printf("Actual Size: %08lx\n", size); 18 printf("Needed Size: %08lx\n", needed_size); 19 iotrace_get_region(&start, &size); 20 printf("Region: %08lx\n", start); 21 printf("Size: %08lx\n", size); 22 printf("Offset: %08lx\n", offset); 23 printf("Output: %08lx\n", start + offset); 24 printf("Count: %08lx\n", count); 25 printf("CRC32: %08lx\n", (ulong)iotrace_get_checksum()); 26 } 27 28 static void do_print_trace(void) 29 { 30 ulong start, size, needed_size, offset, count; 31 32 struct iotrace_record *cur_record; 33 34 iotrace_get_buffer(&start, &size, &needed_size, &offset, &count); 35 36 if (!start || !size || !count) 37 return; 38 39 printf("Timestamp Value Address\n"); 40 41 cur_record = (struct iotrace_record *)start; 42 for (int i = 0; i < count; i++) { 43 if (cur_record->flags & IOT_WRITE) 44 printf("%08llu: 0x%08lx --> 0x%08llx\n", 45 cur_record->timestamp, 46 cur_record->value, 47 (unsigned long long)cur_record->addr); 48 else 49 printf("%08llu: 0x%08lx <-- 0x%08llx\n", 50 cur_record->timestamp, 51 cur_record->value, 52 (unsigned long long)cur_record->addr); 53 54 cur_record++; 55 } 56 } 57 58 static int do_set_buffer(int argc, char * const argv[]) 59 { 60 ulong addr = 0, size = 0; 61 62 if (argc == 2) { 63 addr = simple_strtoul(*argv++, NULL, 16); 64 size = simple_strtoul(*argv++, NULL, 16); 65 } else if (argc != 0) { 66 return CMD_RET_USAGE; 67 } 68 69 iotrace_set_buffer(addr, size); 70 71 return 0; 72 } 73 74 static int do_set_region(int argc, char * const argv[]) 75 { 76 ulong addr = 0, size = 0; 77 78 if (argc == 2) { 79 addr = simple_strtoul(*argv++, NULL, 16); 80 size = simple_strtoul(*argv++, NULL, 16); 81 } else if (argc != 0) { 82 return CMD_RET_USAGE; 83 } 84 85 iotrace_set_region(addr, size); 86 87 return 0; 88 } 89 90 int do_iotrace(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 91 { 92 const char *cmd = argc < 2 ? NULL : argv[1]; 93 94 if (!cmd) 95 return cmd_usage(cmdtp); 96 switch (*cmd) { 97 case 'b': 98 return do_set_buffer(argc - 2, argv + 2); 99 case 'l': 100 return do_set_region(argc - 2, argv + 2); 101 case 'p': 102 iotrace_set_enabled(0); 103 break; 104 case 'r': 105 iotrace_set_enabled(1); 106 break; 107 case 's': 108 do_print_stats(); 109 break; 110 case 'd': 111 do_print_trace(); 112 break; 113 default: 114 return CMD_RET_USAGE; 115 } 116 117 return 0; 118 } 119 120 U_BOOT_CMD( 121 iotrace, 4, 1, do_iotrace, 122 "iotrace utility commands", 123 "stats - display iotrace stats\n" 124 "iotrace buffer <address> <size> - set iotrace buffer\n" 125 "iotrace limit <address> <size> - set iotrace region limit\n" 126 "iotrace pause - pause tracing\n" 127 "iotrace resume - resume tracing\n" 128 "iotrace dump - dump iotrace buffer" 129 ); 130