monitor.c revision 1.7.78.1 1 /* $NetBSD: monitor.c,v 1.7.78.1 2008/05/16 02:22:06 yamt 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 #include <lib/libsa/stand.h>
33
34 extern int errno;
35 extern char *name;
36
37 void db_cmd_dump(int, char **);
38 void db_cmd_get(int, char **);
39 void db_cmd_mf(int, char **);
40 void db_cmd_mt(int, char **);
41 void db_cmd_put(int, char **);
42 void db_cmd_help(int, char **);
43
44 extern void exec_kernel(char *, void *);
45
46 struct {
47 char *name;
48 void (*fcn)(int, char **);
49 } db_cmd[] = {
50 { "dump", db_cmd_dump },
51 { "get", db_cmd_get },
52 { "mf", db_cmd_mf },
53 { "mt", db_cmd_mt },
54 { "put", db_cmd_put },
55 { "help", db_cmd_help },
56 { NULL, NULL },
57 };
58
59 int
60 db_monitor(void)
61 {
62 int tmp;
63 int argc, flag;
64 char *p, *argv[16];
65 char line[1024];
66
67 while (1) {
68 printf("db> ");
69 gets(line);
70
71 flag = 0;
72 for (p = line, argc = 0; *p != '\0'; p++) {
73 if (*p != ' ' && *p != '\t') {
74 if (!flag) {
75 flag++;
76 argv[argc++] = p;
77 }
78 } else {
79 if (flag) {
80 *p = '\0';
81 flag = 0;
82 }
83 }
84 }
85
86 if (argc == 0)
87 continue;
88
89 tmp = 0;
90 while (db_cmd[tmp].name != NULL) {
91 if (!strcmp("continue", argv[0]))
92 return 0;
93 if (!strcmp(db_cmd[tmp].name, argv[0])) {
94 (db_cmd[tmp].fcn)(argc, argv);
95 break;
96 }
97 tmp++;
98 }
99 if (db_cmd[tmp].name == NULL)
100 db_cmd_help(argc, argv);
101 }
102 return 0;
103 }
104
105 int
106 db_atob(char *p)
107 {
108 int b = 0, width, tmp, exp, x = 0;
109
110 if (p[1] == 'x') {
111 p += 2;
112 x = 1;
113 }
114 width = strlen(p);
115 while (width--) {
116 exp = 1;
117 for (tmp = 1; tmp <= width; tmp++)
118 exp *= (x ? 16 : 10);
119 if (*p >= '0' && *p <= '9') {
120 tmp = *p - '0';
121 } else {
122 tmp = *p - 'a' + 10;
123 }
124 b += tmp * exp;
125 p++;
126 }
127 return b;
128 }
129
130 void
131 db_cmd_dump(int argc, char **argv)
132 {
133 char *p, *r, *pp;
134 int mode, add, size, i;
135
136 switch (argc) {
137 case 4:
138 r = argv[1];
139 switch (r[1]) {
140 case 'b':
141 mode = 1;
142 break;
143 case 'h':
144 mode = 2;
145 break;
146 case 'w':
147 mode = 4;
148 break;
149 default:
150 goto out;
151 }
152 p = argv[2];
153 pp = argv[3];
154 break;
155 case 3:
156 mode = 4;
157 p = argv[1];
158 pp = argv[2];
159 break;
160 default:
161 goto out;
162 }
163
164 add = db_atob(p);
165 size = db_atob(pp);
166 i = 0;
167 for (; size > 0;) {
168 if (!i)
169 printf("\n0x%x:", add);
170 switch (mode) {
171 case 1:
172 printf(" %x", *(unsigned char *)add);
173 add += 1;
174 size -= 1;
175 if (++i == 16)
176 i = 0;
177 break;
178 case 2:
179 printf(" %x", *(unsigned short *)add);
180 add += 2;
181 size -= 2;
182 if (++i == 8)
183 i = 0;
184 break;
185 case 4:
186 printf(" %x", *(unsigned int *)add);
187 add += 4;
188 size -= 4;
189 if (++i == 4)
190 i = 0;
191 break;
192 }
193 }
194 printf("\n");
195 return;
196
197 out:
198 printf("dump [-b][-h][-w] address size\n");
199 return;
200 }
201
202 void
203 db_cmd_get(int argc, char **argv)
204 {
205 char *p, *r;
206 int mode, add;
207
208 switch (argc) {
209 case 3:
210 r = argv[1];
211 switch (r[1]) {
212 case 'b':
213 mode = 1;
214 break;
215 case 'h':
216 mode = 2;
217 break;
218 case 'w':
219 mode = 4;
220 break;
221 default:
222 goto out;
223 }
224 p = argv[2];
225 break;
226 case 2:
227 mode = 4;
228 p = argv[1];
229 break;
230 default:
231 goto out;
232 }
233
234 add = db_atob(p);
235 printf("0x%x: ", add);
236 switch (mode) {
237 case 1:
238 printf("0x%x", *(char *)add);
239 break;
240 case 2:
241 printf("0x%x", *(short *)add);
242 break;
243 case 4:
244 printf("0x%x", *(int *)add);
245 break;
246 }
247 printf("\n");
248 return;
249
250 out:
251 printf("get [-b][-h][-w] address\n");
252 return;
253 }
254
255 void
256 db_cmd_put(int argc, char **argv)
257 {
258 char *p, *r, *pp;
259 int mode, add, data;
260
261 switch (argc) {
262 case 4:
263 r = argv[1];
264 switch (r[1]) {
265 case 'b':
266 mode = 1;
267 break;
268 case 'h':
269 mode = 2;
270 break;
271 case 'w':
272 mode = 4;
273 break;
274 default:
275 goto out;
276 }
277 p = argv[2];
278 pp = argv[3];
279 break;
280 case 3:
281 mode = 4;
282 p = argv[1];
283 pp = argv[2];
284 break;
285 default:
286 goto out;
287 }
288
289 add = db_atob(p);
290 data = db_atob(pp);
291 printf("0x%x: 0x%x", add, data);
292 switch (mode) {
293 case 1:
294 *(char *)add = data;
295 break;
296 case 2:
297 *(short *)add = data;
298 break;
299 case 4:
300 *(int *)add = data;
301 break;
302 }
303 printf("\n");
304 return;
305
306 out:
307 printf("put [-b][-h][-w] address data\n");
308 return;
309 }
310
311 #define STR(x) #x
312
313 #define FUNC(x) \
314 unsigned int mf ## x() { \
315 unsigned int tmp; \
316 __asm volatile (STR(mf ## x %0) : STR(=r)(tmp)); \
317 return (tmp); \
318 } \
319 void mt ## x(data) \
320 unsigned int data; \
321 { \
322 __asm volatile (STR(mt ## x %0) :: STR(r)(data)); \
323 } \
324
325 #define DEF(x) \
326 { #x, mf ## x, mt ## x }
327
328 FUNC(msr);
329
330 struct {
331 char *op;
332 unsigned int (*mf)(void);
333 void (*mt)(unsigned int);
334 } mreg [] = {
335 DEF(msr),
336 { NULL, NULL, NULL },
337 };
338
339 void
340 db_cmd_mf(int argc, char **argv)
341 {
342 int i = 0;
343
344 if (argc != 2) {
345 printf("mf register\nregister:");
346 while (mreg[i].op != NULL)
347 printf(" %s", mreg[i++].op);
348 printf("\n");
349 return;
350 }
351
352 while (mreg[i].op != NULL) {
353 if (!strcmp(mreg[i].op, argv[1])) {
354 printf(" 0x%x\n", (mreg[i].mf)());
355 break;
356 }
357 i++;
358 }
359 }
360
361 void
362 db_cmd_mt(int argc, char **argv)
363 {
364 int i = 0;
365
366 if (argc != 3) {
367 printf("mt register data\nregister:");
368 while (mreg[i].op != NULL)
369 printf(" %s", mreg[i++].op);
370 printf("\n");
371 return;
372 }
373
374 while (mreg[i].op != NULL) {
375 if (!strcmp(mreg[i].op, argv[1])) {
376 (mreg[i].mt)((unsigned int)db_atob(argv[2]));
377 printf(" 0x%x\n", db_atob(argv[2]));
378 break;
379 }
380 i++;
381 }
382 }
383
384 void
385 db_cmd_help(int argc, char **argv)
386 {
387 int i = 0;
388
389 while (db_cmd[i].name != NULL)
390 printf("%s, ", db_cmd[i++].name);
391 printf("\n");
392 }
393