1 /* 2 * Copyright 2024, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Jérôme Duval <jerome.duval@gmail.com> 7 */ 8 9 10 #include <errno.h> 11 #include <stdint.h> 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <string.h> 15 16 #include <OS.h> 17 18 19 extern const char *__progname; 20 static const char *kCommandName = __progname; 21 22 23 // usage 24 static const char *kUsage = 25 "Usage: %s [ <options> ] [ command ] [ args ]\n" 26 "\n" 27 "Options:\n" 28 " --count <n> - Read n registers.\n" 29 ; 30 31 32 static void 33 print_usage(bool error) 34 { 35 // print usage 36 fprintf((error ? stderr : stdout), kUsage, kCommandName); 37 } 38 39 40 static void 41 print_usage_and_exit(bool error) 42 { 43 print_usage(error); 44 exit(error ? 1 : 0); 45 } 46 47 48 int 49 main(int argc, const char *const *argv) 50 { 51 const char *const *programArgs = NULL; 52 int32_t programArgCount = 0; 53 uint32_t count = 1; 54 55 // parse arguments 56 for (int argi = 1; argi < argc; argi++) { 57 const char *arg = argv[argi]; 58 if (arg[0] == '-') { 59 if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) { 60 print_usage_and_exit(false); 61 } else if (strcmp(arg, "--count") == 0) { 62 count = strtol(argv[++argi], (char **)NULL, 10); 63 if (count == 0 && errno != 0) 64 print_usage_and_exit(true); 65 } else { 66 print_usage_and_exit(true); 67 } 68 } else { 69 programArgs = argv + argi; 70 programArgCount = argc - argi; 71 break; 72 } 73 } 74 75 bool write = false; 76 uint32 value = 0; 77 if (programArgCount < 2) { 78 print_usage_and_exit(true); 79 } 80 if (strcmp(programArgs[0], "read") == 0) { 81 if (programArgCount >= 4) { 82 const char *arg = programArgs[1]; 83 if (arg[0] == '-') { 84 if (strcmp(arg, "--count") == 0) { 85 count = strtol(programArgs[2], (char **)NULL, 10); 86 if (count == 0 && errno != 0) 87 print_usage_and_exit(true); 88 programArgCount -= 2; 89 programArgs += 2; 90 } else { 91 print_usage_and_exit(true); 92 } 93 } 94 } 95 } else if (strcmp(programArgs[0], "write") == 0) { 96 write = true; 97 } else 98 print_usage_and_exit(true); 99 programArgCount--; 100 programArgs++; 101 102 area_id area = find_area("intel extreme mmio"); 103 if (area < 0) { 104 fprintf(stderr, "couldn't find intel extreme mmio area\n"); 105 exit(1); 106 } 107 108 void* regs; 109 uint32 protection = B_READ_AREA | (write ? B_WRITE_AREA : 0); 110 area_id clone = clone_area("clone regs", ®s, B_ANY_ADDRESS, protection, area); 111 if (clone < B_OK) { 112 fprintf(stderr, "couldn't clone intel extreme mmio area\n"); 113 exit(1); 114 } 115 116 while (programArgCount > 0) { 117 const char* arg = programArgs[0]; 118 programArgCount--; 119 programArgs++; 120 if (write) { 121 if (programArgCount < 1) 122 print_usage_and_exit(true); 123 const char* val = programArgs[0]; 124 if (val[0] == '0' && (val[1] == 'x' || val[1] == 'X')) 125 value = strtol(val + 2, (char **)NULL, 16); 126 else 127 value = strtol(val, (char **)NULL, 10); 128 if (value == 0 && errno != 0) 129 print_usage_and_exit(true); 130 programArgCount--; 131 programArgs++; 132 } 133 uint64_t address; 134 if (arg[0] == '0' && (arg[1] == 'x' || arg[1] == 'X')) { 135 address = strtol(arg + 2, (char **)NULL, 16); 136 } else 137 address = strtol(arg, (char **)NULL, 10); 138 if (address == 0 && errno != 0) 139 print_usage_and_exit(true); 140 141 for (uint32_t i = 0; i < count; i++) { 142 addr_t addr = (addr_t)regs + address + i * sizeof(uint32); 143 if (write) { 144 *(uint32*)addr = value; 145 } else { 146 printf("(0x%08" B_PRIxADDR "): 0x%08" B_PRIx32 "\n", address + i * sizeof(uint32), *(uint32*)addr); 147 } 148 } 149 } 150 151 delete_area(clone); 152 exit(0); 153 } 154