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