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