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