1 /* $NetBSD: monitor.c,v 1.4 2016/06/11 06:31:49 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 #if defined(DBMONITOR)
33
34 #include <lib/libsa/stand.h>
35 #include <lib/libkern/libkern.h>
36
37 #include "boot.h"
38
39 #ifndef NULL
40 #define NULL (void *)0
41 #endif
42
43 static void db_cmd_dump(int, char **);
44 static void db_cmd_get(int, char **);
45 static void db_cmd_put(int, char **);
46 static void db_cmd_help(int, char **);
47
48 static int db_atob(char *);
49
50 static const struct db_cmd {
51 char *name;
52 void (*fcn)(int, char **);
53 } db_cmd[] = {
54 { "dump", db_cmd_dump },
55 { "get", db_cmd_get },
56 { "put", db_cmd_put },
57 { "help", db_cmd_help },
58 { NULL, NULL },
59 };
60
61 int
db_monitor(void)62 db_monitor(void)
63 {
64 char line[1024];
65 char *p, *argv[16];
66 int argc, flag;
67 int tmp;
68
69 for (;;) {
70 printf("db> ");
71 kgets(line, sizeof(line));
72
73 flag = 0;
74 argc = 0;
75 for (p = line; *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 if (argc == 0)
89 continue;
90
91 tmp = 0;
92 while (db_cmd[tmp].name != NULL) {
93 if (strcmp("continue", argv[0]) == 0)
94 return 0;
95 if (strcmp(db_cmd[tmp].name, argv[0]) == 0) {
96 (db_cmd[tmp].fcn)(argc, argv);
97 break;
98 }
99 tmp++;
100 }
101 if (db_cmd[tmp].name == NULL)
102 db_cmd_help(argc, argv);
103 }
104
105 return 0;
106 }
107
108 static int
db_atob(char * p)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
118 width = strlen(p);
119 while (width--) {
120 exp = 1;
121 for (tmp = 1; tmp <= width; tmp++)
122 exp *= (x ? 16 : 10);
123 if (*p >= '0' && *p <= '9') {
124 tmp = *p - '0';
125 } else {
126 tmp = *p - 'a' + 10;
127 }
128 b += tmp * exp;
129 p++;
130 }
131 return b;
132 }
133
134 static void
db_cmd_dump(int argc,char ** argv)135 db_cmd_dump(int argc, char **argv)
136 {
137 char *p, *r, *pp;
138 int mode, add, size, i;
139
140 switch (argc) {
141 case 4:
142 r = argv[1];
143 switch (r[1]) {
144 case 'b':
145 mode = 1;
146 break;
147 case 'h':
148 mode = 2;
149 break;
150 case 'w':
151 mode = 4;
152 break;
153 default:
154 goto out;
155 }
156 p = argv[2];
157 pp = argv[3];
158 break;
159 case 3:
160 mode = 4;
161 p = argv[1];
162 pp = argv[2];
163 break;
164 default:
165 goto out;
166 }
167
168 add = db_atob(p);
169 size = db_atob(pp);
170 i = 0;
171 for (; size > 0;) {
172 if (i == 0) {
173 printf("\n0x%x:", add);
174 }
175 switch (mode) {
176 case 1:
177 printf(" ");
178 puthex(*(unsigned char *)add, 1);
179 add += 1;
180 size -= 1;
181 if (++i == 16)
182 i = 0;
183 break;
184 case 2:
185 printf(" ");
186 puthex(*(unsigned short *)add, 2);
187 add += 2;
188 size -= 2;
189 if (++i == 8)
190 i = 0;
191 break;
192 case 4:
193 printf(" ");
194 puthex(*(unsigned int *)add, 4);
195 add += 4;
196 size -= 4;
197 if (++i == 4)
198 i = 0;
199 break;
200 }
201 }
202 printf("\n");
203 return;
204
205 out:
206 printf("dump [-b][-h][-w] address size\n");
207 return;
208 }
209
210 static void
db_cmd_get(int argc,char ** argv)211 db_cmd_get(int argc, char **argv)
212 {
213 char *p, *r;
214 int mode, add;
215 int val;
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: 0x", add);
245 switch (mode) {
246 case 1:
247 val = *(char *)add;
248 break;
249 case 2:
250 val = *(short *)add;
251 break;
252 case 4:
253 val = *(int *)add;
254 break;
255 default:
256 val = 0;
257 break;
258 }
259 puthex(val, mode);
260 printf("\n");
261 return;
262
263 out:
264 printf("get [-b][-h][-w] address\n");
265 return;
266 }
267
268 static void
db_cmd_put(int argc,char ** argv)269 db_cmd_put(int argc, char **argv)
270 {
271 char *p, *r, *pp;
272 int mode, add, data;
273
274 switch (argc) {
275 case 4:
276 r = argv[1];
277 switch (r[1]) {
278 case 'b':
279 mode = 1;
280 break;
281 case 'h':
282 mode = 2;
283 break;
284 case 'w':
285 mode = 4;
286 break;
287 default:
288 goto out;
289 }
290 p = argv[2];
291 pp = argv[3];
292 break;
293 case 3:
294 mode = 4;
295 p = argv[1];
296 pp = argv[2];
297 break;
298 default:
299 goto out;
300 }
301
302 add = db_atob(p);
303 data = db_atob(pp);
304 printf("0x%x: 0x", add);
305 puthex(data, mode);
306 switch (mode) {
307 case 1:
308 *(char *)add = data;
309 break;
310 case 2:
311 *(short *)add = data;
312 break;
313 case 4:
314 *(int *)add = data;
315 break;
316 }
317 printf("\n");
318 return;
319
320 out:
321 printf("put [-b][-h][-w] address data\n");
322 return;
323 }
324
325 static void
db_cmd_help(int argc,char ** argv)326 db_cmd_help(int argc, char **argv)
327 {
328 int i = 0;
329
330 while (db_cmd[i].name != NULL)
331 printf("%s, ", db_cmd[i++].name);
332 printf("continue\n");
333 }
334
335 #endif /* DBMONITOR */
336