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