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