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