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