1 /* $NetBSD: monitor.c,v 1.11 2016/06/11 06:28:49 dholland 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 uint32_t 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 kgets(line, sizeof(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 uint32_t 109 db_atob(char *p) 110 { 111 uint32_t b = 0; 112 int width, tmp, exp, x = 0; 113 114 if (p[1] == 'x') { 115 p += 2; 116 x = 1; 117 } 118 width = strlen(p); 119 while (width--) { 120 exp = 1; 121 for (tmp = 1; tmp <= width; tmp++) 122 exp *= (x ? 16 : 10); 123 if (*p >= '0' && *p <= '9') { 124 tmp = *p - '0'; 125 } else { 126 tmp = *p - 'a' + 10; 127 } 128 b += tmp * exp; 129 p++; 130 } 131 return b; 132 } 133 134 void 135 db_cmd_dump(int argc, char **argv) 136 { 137 char *p, *r, *pp; 138 int mode, size, i; 139 uint32_t add; 140 141 switch (argc) { 142 case 4: 143 r = argv[1]; 144 switch (r[1]) { 145 case 'b': 146 mode = 1; 147 break; 148 case 'h': 149 mode = 2; 150 break; 151 case 'w': 152 mode = 4; 153 break; 154 default: 155 goto out; 156 } 157 p = argv[2]; 158 pp = argv[3]; 159 break; 160 case 3: 161 mode = 4; 162 p = argv[1]; 163 pp = argv[2]; 164 break; 165 default: 166 goto out; 167 } 168 169 add = db_atob(p); 170 size = db_atob(pp); 171 i = 0; 172 for (; size > 0;) { 173 if (!i) 174 printf("\n0x%x:", add); 175 switch (mode) { 176 case 1: 177 printf(" %x", *(uint8_t *)add); 178 add += 1; 179 size -= 1; 180 if (++i == 16) 181 i = 0; 182 break; 183 case 2: 184 printf(" %x", *(uint16_t *)add); 185 add += 2; 186 size -= 2; 187 if (++i == 8) 188 i = 0; 189 break; 190 case 4: 191 printf(" %x", *(uint32_t *)add); 192 add += 4; 193 size -= 4; 194 if (++i == 4) 195 i = 0; 196 break; 197 } 198 } 199 printf("\n"); 200 return; 201 202 out: 203 printf("dump [-b][-h][-w] address size\n"); 204 return; 205 } 206 207 void 208 db_cmd_get(int argc, char **argv) 209 { 210 char *p, *r; 211 uint32_t add; 212 int mode; 213 214 switch (argc) { 215 case 3: 216 r = argv[1]; 217 switch (r[1]) { 218 case 'b': 219 mode = 1; 220 break; 221 case 'h': 222 mode = 2; 223 break; 224 case 'w': 225 mode = 4; 226 break; 227 default: 228 goto out; 229 } 230 p = argv[2]; 231 break; 232 case 2: 233 mode = 4; 234 p = argv[1]; 235 break; 236 default: 237 goto out; 238 } 239 240 add = db_atob(p); 241 printf("0x%x: ", add); 242 switch (mode) { 243 case 1: 244 printf("0x%x", *(uint8_t *)add); 245 break; 246 case 2: 247 printf("0x%x", *(uint16_t *)add); 248 break; 249 case 4: 250 printf("0x%x", *(uint32_t *)add); 251 break; 252 } 253 printf("\n"); 254 return; 255 256 out: 257 printf("get [-b][-h][-w] address\n"); 258 return; 259 } 260 261 void 262 db_cmd_put(int argc, char **argv) 263 { 264 char *p, *r, *pp; 265 uint32_t add, data; 266 int mode; 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 *(uint8_t *)add = data; 302 break; 303 case 2: 304 *(uint16_t *)add = data; 305 break; 306 case 4: 307 *(uint32_t *)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 uint32_t mf ## x(void); \ 322 void mt ## x(uint32_t); \ 323 uint32_t mf ## x() { \ 324 uint32_t tmp; \ 325 __asm volatile (STR(mf ## x %0) : STR(=r)(tmp)); \ 326 return (tmp); \ 327 } \ 328 void mt ## x(uint32_t 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 uint32_t (*mf)(void); 341 void (*mt)(uint32_t); 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)(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("\n"); 400 } 401