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