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