1 /* $NetBSD: monitor.c,v 1.3 2010/02/03 13:48:17 wiz 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 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 gets(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 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 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 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 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 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 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 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