xref: /haiku/src/tests/add-ons/accelerants/intel_extreme/intel_reg.cpp (revision 13581b3d2a71545960b98fefebc5225b5bf29072)
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", &regs, 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