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