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