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