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