Home | History | Annotate | Line # | Download | only in boot
monitor.c revision 1.1
      1 /*	$NetBSD: monitor.c,v 1.1 2007/12/17 19:09:52 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(int, char **);
     51 void db_cmd_get(int, char **);
     52 void db_cmd_mf(int, char **);
     53 void db_cmd_mt(int, char **);
     54 void db_cmd_put(int, char **);
     55 void db_cmd_help(int, char **);
     56 
     57 unsigned int mfmsr((void);
     58 void mtmsr(unsigned int);
     59 
     60 int db_atob(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(void)
     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(char *p)
    123 {
    124 	int b = 0, width, tmp, exp, x = 0;
    125 
    126 	if (p[1] == 'x') {
    127 		p += 2;
    128 		x = 1;
    129 	}
    130 	width = strlen(p);
    131 	while(width--) {
    132 		exp = 1;
    133 		for (tmp = 1; tmp <= width; tmp++)
    134 			exp *= (x ? 16 : 10);
    135 		if (*p >= '0' && *p <= '9') {
    136 			tmp = *p - '0';
    137 		} else {
    138 			tmp = *p - 'a' + 10;
    139 		}
    140 		b += tmp * exp;
    141 		p++;
    142 	}
    143 	return b;
    144 }
    145 
    146 void
    147 db_cmd_dump(int argc, char **argv)
    148 {
    149 	char *p, *r, *pp;
    150 	int mode, add, size, i;
    151 
    152 	switch (argc) {
    153 	case 4:
    154 		r = argv[1];
    155 		switch (r[1]) {
    156 		case 'b':
    157 			mode = 1;
    158 			break;
    159 		case 'h':
    160 			mode = 2;
    161 			break;
    162 		case 'w':
    163 			mode = 4;
    164 			break;
    165 		default:
    166 			goto out;
    167 		}
    168 		p = argv[2];
    169 		pp = argv[3];
    170 		break;
    171 	case 3:
    172 		mode = 4;
    173 		p = argv[1];
    174 		pp = argv[2];
    175 		break;
    176 	default:
    177 		goto out;
    178 	}
    179 
    180 	add = db_atob(p);
    181 	size = db_atob(pp);
    182 	i = 0;
    183 	for (; size > 0;) {
    184 		if (!i)
    185 			printf("\n0x%x:", add);
    186 		switch (mode) {
    187 		case 1:
    188 			printf(" %x", *(unsigned char *)add);
    189 			add += 1;
    190 			size -= 1;
    191 			if (++i == 16)
    192 				i = 0;
    193 			break;
    194 		case 2:
    195 			printf(" %x", *(unsigned short *)add);
    196 			add += 2;
    197 			size -= 2;
    198 			if (++i == 8)
    199 				i = 0;
    200 			break;
    201 		case 4:
    202 			printf(" %x", *(unsigned int *)add);
    203 			add += 4;
    204 			size -= 4;
    205 			if (++i == 4)
    206 				i = 0;
    207 			break;
    208 		}
    209 	}
    210 	printf("\n");
    211 	return;
    212 
    213 out:
    214 	printf("dump [-b][-h][-w] address size\n");
    215 	return;
    216 }
    217 
    218 void
    219 db_cmd_get(int argc, char **argv)
    220 {
    221 	char *p, *r;
    222 	int mode, add;
    223 
    224 	switch (argc) {
    225 	case 3:
    226 		r = argv[1];
    227 		switch (r[1]) {
    228 		case 'b':
    229 			mode = 1;
    230 			break;
    231 		case 'h':
    232 			mode = 2;
    233 			break;
    234 		case 'w':
    235 			mode = 4;
    236 			break;
    237 		default:
    238 			goto out;
    239 		}
    240 		p = argv[2];
    241 		break;
    242 	case 2:
    243 		mode = 4;
    244 		p = argv[1];
    245 		break;
    246 	default:
    247 		goto out;
    248 	}
    249 
    250 	add = db_atob(p);
    251 	printf("0x%x: ", add);
    252 	switch (mode) {
    253 	case 1:
    254 		printf("0x%x", *(char *)add);
    255 		break;
    256 	case 2:
    257 		printf("0x%x", *(short *)add);
    258 		break;
    259 	case 4:
    260 		printf("0x%x", *(int *)add);
    261 		break;
    262 	}
    263 	printf("\n");
    264 	return;
    265 
    266 out:
    267 	printf("get [-b][-h][-w] address\n");
    268 	return;
    269 }
    270 
    271 void
    272 db_cmd_put(int argc, char **argv)
    273 {
    274 	char *p, *r, *pp;
    275 	int mode, add, data;
    276 
    277 	switch (argc) {
    278 	case 4:
    279 		r = argv[1];
    280 		switch (r[1]) {
    281 		case 'b':
    282 			mode = 1;
    283 			break;
    284 		case 'h':
    285 			mode = 2;
    286 			break;
    287 		case 'w':
    288 			mode = 4;
    289 			break;
    290 		default:
    291 			goto out;
    292 		}
    293 		p = argv[2];
    294 		pp = argv[3];
    295 		break;
    296 	case 3:
    297 		mode = 4;
    298 		p = argv[1];
    299 		pp = argv[2];
    300 		break;
    301 	default:
    302 		goto out;
    303 	}
    304 
    305 	add = db_atob(p);
    306 	data = db_atob(pp);
    307 	printf("0x%x: 0x%x", add, data);
    308 	switch (mode) {
    309 	case 1:
    310 		*(char *)add = data;
    311 		break;
    312 	case 2:
    313 		*(short *)add = data;
    314 		break;
    315 	case 4:
    316 		*(int *)add = data;
    317 		break;
    318 	}
    319 	printf("\n");
    320 	return;
    321 
    322 out:
    323 	printf("put [-b][-h][-w] address data\n");
    324 	return;
    325 }
    326 
    327 #define STR(x) #x
    328 
    329 #define	FUNC(x) \
    330 unsigned int mf ## x() { \
    331 	unsigned int tmp; \
    332 	__asm volatile (STR(mf ## x %0) : STR(=r)(tmp)); \
    333 	return (tmp); \
    334 } \
    335 void mt ## x(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(int argc, char **argv)
    356 {
    357 	int i = 0;
    358 
    359 	if (argc != 2) {
    360 		printf("mf register\nregister:");
    361 		while (mreg[i].op != NULL)
    362 			printf(" %s", mreg[i++].op);
    363 		printf("\n");
    364 		return;
    365 	}
    366 
    367 	while (mreg[i].op != NULL) {
    368 		if (!strcmp(mreg[i].op, argv[1])) {
    369 			printf(" 0x%x\n", (mreg[i].mf)());
    370 			break;
    371 		}
    372 		i++;
    373 	}
    374 }
    375 
    376 void
    377 db_cmd_mt(int argc, char **argv)
    378 {
    379 	int i = 0;
    380 
    381 	if (argc != 3) {
    382 		printf("mt register data\nregister:");
    383 		while (mreg[i].op != NULL)
    384 			printf(" %s", mreg[i++].op);
    385 		printf("\n");
    386 		return;
    387 	}
    388 
    389 	while (mreg[i].op != NULL) {
    390 		if (!strcmp(mreg[i].op, argv[1])) {
    391 			(mreg[i].mt)((unsigned int)db_atob(argv[2]));
    392 			printf(" 0x%x\n", db_atob(argv[2]));
    393 			break;
    394 		}
    395 		i++;
    396 	}
    397 }
    398 
    399 void
    400 db_cmd_help(int argc, char **argv)
    401 {
    402 	int i = 0;
    403 
    404 	while (db_cmd[i].name != NULL)
    405 		printf("%s, ", db_cmd[i++].name);
    406 	printf("continue\n");
    407 }
    408 
    409 #endif /* DBMONITOR */
    410