xref: /netbsd/sys/arch/rs6000/stand/boot/monitor.c (revision a7a9685f)
1 /*	$NetBSD: monitor.c,v 1.4 2016/06/11 06:39:25 dholland Exp $	*/
2 
3 /*-
4  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Kazuki Sakamoto.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifdef DBMONITOR
33 
34 #include <lib/libsa/stand.h>
35 #include <lib/libkern/libkern.h>
36 #include "boot.h"
37 
38 #define NULL	0
39 
40 extern int errno;
41 extern char *name;
42 
43 void db_cmd_dump(int, char **);
44 void db_cmd_get(int, char **);
45 void db_cmd_mf(int, char **);
46 void db_cmd_mt(int, char **);
47 void db_cmd_put(int, char **);
48 void db_cmd_help(int, char **);
49 
50 unsigned int mfmsr(void);
51 void mtmsr(unsigned int);
52 
53 int db_atob(char *);
54 
55 struct {
56 	char *name;
57 	void (*fcn)(int, char **);
58 } db_cmd[] = {
59 	{ "dump",	db_cmd_dump },
60 	{ "get",	db_cmd_get },
61 	{ "mf",		db_cmd_mf },
62 	{ "mt",		db_cmd_mt },
63 	{ "put",	db_cmd_put },
64 	{ "help",	db_cmd_help },
65 	{ NULL,		NULL },
66 };
67 
68 int
db_monitor(void)69 db_monitor(void)
70 {
71 	int tmp;
72 	int argc, flag;
73 	char *p, *argv[16];
74 	char line[1024];
75 
76 	while(1) {
77 		printf("db> ");
78 		kgets(line, sizeof(line));
79 
80 		flag = 0;
81 		for(p = line, argc = 0; *p != '\0'; p++) {
82 			if (*p != ' ' && *p != '\t') {
83 				if (!flag) {
84 					flag++;
85 					argv[argc++] = p;
86 				}
87 			} else {
88 				if (flag) {
89 					*p = '\0';
90 					flag = 0;
91 				}
92 			}
93 		}
94 
95 		if (argc == 0)
96 			continue;
97 
98 		tmp = 0;
99 		while (db_cmd[tmp].name != NULL) {
100 			if (!strcmp("continue", argv[0]))
101 				return 0;
102 			if (!strcmp(db_cmd[tmp].name, argv[0])) {
103 				(db_cmd[tmp].fcn)(argc, argv);
104 				break;
105 			}
106 			tmp++;
107 		}
108 		if (db_cmd[tmp].name == NULL)
109 			db_cmd_help(argc, argv);
110 	}
111 	return 0;
112 }
113 
114 int
db_atob(char * p)115 db_atob(char *p)
116 {
117 	int b = 0, width, tmp, exp, x = 0;
118 
119 	if (p[1] == 'x') {
120 		p += 2;
121 		x = 1;
122 	}
123 	width = strlen(p);
124 	while(width--) {
125 		exp = 1;
126 		for (tmp = 1; tmp <= width; tmp++)
127 			exp *= (x ? 16 : 10);
128 		if (*p >= '0' && *p <= '9') {
129 			tmp = *p - '0';
130 		} else {
131 			tmp = *p - 'a' + 10;
132 		}
133 		b += tmp * exp;
134 		p++;
135 	}
136 	return b;
137 }
138 
139 void
db_cmd_dump(int argc,char ** argv)140 db_cmd_dump(int argc, char **argv)
141 {
142 	char *p, *r, *pp;
143 	int mode, add, size, i;
144 
145 	switch (argc) {
146 	case 4:
147 		r = argv[1];
148 		switch (r[1]) {
149 		case 'b':
150 			mode = 1;
151 			break;
152 		case 'h':
153 			mode = 2;
154 			break;
155 		case 'w':
156 			mode = 4;
157 			break;
158 		default:
159 			goto out;
160 		}
161 		p = argv[2];
162 		pp = argv[3];
163 		break;
164 	case 3:
165 		mode = 4;
166 		p = argv[1];
167 		pp = argv[2];
168 		break;
169 	default:
170 		goto out;
171 	}
172 
173 	add = db_atob(p);
174 	size = db_atob(pp);
175 	i = 0;
176 	for (; size > 0;) {
177 		if (!i)
178 			printf("\n0x%x:", add);
179 		switch (mode) {
180 		case 1:
181 			printf(" %x", *(unsigned char *)add);
182 			add += 1;
183 			size -= 1;
184 			if (++i == 16)
185 				i = 0;
186 			break;
187 		case 2:
188 			printf(" %x", *(unsigned short *)add);
189 			add += 2;
190 			size -= 2;
191 			if (++i == 8)
192 				i = 0;
193 			break;
194 		case 4:
195 			printf(" %x", *(unsigned int *)add);
196 			add += 4;
197 			size -= 4;
198 			if (++i == 4)
199 				i = 0;
200 			break;
201 		}
202 	}
203 	printf("\n");
204 	return;
205 
206 out:
207 	printf("dump [-b][-h][-w] address size\n");
208 	return;
209 }
210 
211 void
db_cmd_get(int argc,char ** argv)212 db_cmd_get(int argc, char **argv)
213 {
214 	char *p, *r;
215 	int mode, add;
216 
217 	switch (argc) {
218 	case 3:
219 		r = argv[1];
220 		switch (r[1]) {
221 		case 'b':
222 			mode = 1;
223 			break;
224 		case 'h':
225 			mode = 2;
226 			break;
227 		case 'w':
228 			mode = 4;
229 			break;
230 		default:
231 			goto out;
232 		}
233 		p = argv[2];
234 		break;
235 	case 2:
236 		mode = 4;
237 		p = argv[1];
238 		break;
239 	default:
240 		goto out;
241 	}
242 
243 	add = db_atob(p);
244 	printf("0x%x: ", add);
245 	switch (mode) {
246 	case 1:
247 		printf("0x%x", *(char *)add);
248 		break;
249 	case 2:
250 		printf("0x%x", *(short *)add);
251 		break;
252 	case 4:
253 		printf("0x%x", *(int *)add);
254 		break;
255 	}
256 	printf("\n");
257 	return;
258 
259 out:
260 	printf("get [-b][-h][-w] address\n");
261 	return;
262 }
263 
264 void
db_cmd_put(int argc,char ** argv)265 db_cmd_put(int argc, char **argv)
266 {
267 	char *p, *r, *pp;
268 	int mode, add, data;
269 
270 	switch (argc) {
271 	case 4:
272 		r = argv[1];
273 		switch (r[1]) {
274 		case 'b':
275 			mode = 1;
276 			break;
277 		case 'h':
278 			mode = 2;
279 			break;
280 		case 'w':
281 			mode = 4;
282 			break;
283 		default:
284 			goto out;
285 		}
286 		p = argv[2];
287 		pp = argv[3];
288 		break;
289 	case 3:
290 		mode = 4;
291 		p = argv[1];
292 		pp = argv[2];
293 		break;
294 	default:
295 		goto out;
296 	}
297 
298 	add = db_atob(p);
299 	data = db_atob(pp);
300 	printf("0x%x: 0x%x", add, data);
301 	switch (mode) {
302 	case 1:
303 		*(char *)add = data;
304 		break;
305 	case 2:
306 		*(short *)add = data;
307 		break;
308 	case 4:
309 		*(int *)add = data;
310 		break;
311 	}
312 	printf("\n");
313 	return;
314 
315 out:
316 	printf("put [-b][-h][-w] address data\n");
317 	return;
318 }
319 
320 #define STR(x) #x
321 
322 #define	FUNC(x) \
323 unsigned int mf ## x() { \
324 	unsigned int tmp; \
325 	__asm volatile (STR(mf ## x %0) : STR(=r)(tmp)); \
326 	return (tmp); \
327 } \
328 void mt ## x(unsigned int data) \
329 { \
330 	__asm volatile (STR(mt ## x %0) :: STR(r)(data)); \
331 } \
332 
333 #define DEF(x) \
334 	{ #x, mf ## x, mt ## x }
335 
336 FUNC(msr);
337 
338 struct {
339 	char *op;
340 	unsigned int (*mf)(void);
341 	void (*mt)(unsigned int);
342 } mreg [] = {
343 	DEF(msr),
344 	{ NULL, NULL, NULL },
345 };
346 
347 void
db_cmd_mf(int argc,char ** argv)348 db_cmd_mf(int argc, char **argv)
349 {
350 	int i = 0;
351 
352 	if (argc != 2) {
353 		printf("mf register\nregister:");
354 		while (mreg[i].op != NULL)
355 			printf(" %s", mreg[i++].op);
356 		printf("\n");
357 		return;
358 	}
359 
360 	while (mreg[i].op != NULL) {
361 		if (!strcmp(mreg[i].op, argv[1])) {
362 			printf(" 0x%x\n", (mreg[i].mf)());
363 			break;
364 		}
365 		i++;
366 	}
367 }
368 
369 void
db_cmd_mt(int argc,char ** argv)370 db_cmd_mt(int argc, char **argv)
371 {
372 	int i = 0;
373 
374 	if (argc != 3) {
375 		printf("mt register data\nregister:");
376 		while (mreg[i].op != NULL)
377 			printf(" %s", mreg[i++].op);
378 		printf("\n");
379 		return;
380 	}
381 
382 	while (mreg[i].op != NULL) {
383 		if (!strcmp(mreg[i].op, argv[1])) {
384 			(mreg[i].mt)((unsigned int)db_atob(argv[2]));
385 			printf(" 0x%x\n", db_atob(argv[2]));
386 			break;
387 		}
388 		i++;
389 	}
390 }
391 
392 void
db_cmd_help(int argc,char ** argv)393 db_cmd_help(int argc, char **argv)
394 {
395 	int i = 0;
396 
397 	while (db_cmd[i].name != NULL)
398 		printf("%s, ", db_cmd[i++].name);
399 	printf("continue\n");
400 }
401 
402 #endif /* DBMONITOR */
403