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