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