Home | History | Annotate | Line # | Download | only in boot
monitor.c revision 1.4
      1 /*	$NetBSD: monitor.c,v 1.4 2016/06/11 06:39:25 dholland 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  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #ifdef DBMONITOR
     33 
     34 #include <lib/libsa/stand.h>
     35 #include <lib/libkern/libkern.h>
     36 #include "boot.h"
     37 
     38 #define NULL	0
     39 
     40 extern int errno;
     41 extern char *name;
     42 
     43 void db_cmd_dump(int, char **);
     44 void db_cmd_get(int, char **);
     45 void db_cmd_mf(int, char **);
     46 void db_cmd_mt(int, char **);
     47 void db_cmd_put(int, char **);
     48 void db_cmd_help(int, char **);
     49 
     50 unsigned int mfmsr(void);
     51 void mtmsr(unsigned int);
     52 
     53 int db_atob(char *);
     54 
     55 struct {
     56 	char *name;
     57 	void (*fcn)(int, char **);
     58 } db_cmd[] = {
     59 	{ "dump",	db_cmd_dump },
     60 	{ "get",	db_cmd_get },
     61 	{ "mf",		db_cmd_mf },
     62 	{ "mt",		db_cmd_mt },
     63 	{ "put",	db_cmd_put },
     64 	{ "help",	db_cmd_help },
     65 	{ NULL,		NULL },
     66 };
     67 
     68 int
     69 db_monitor(void)
     70 {
     71 	int tmp;
     72 	int argc, flag;
     73 	char *p, *argv[16];
     74 	char line[1024];
     75 
     76 	while(1) {
     77 		printf("db> ");
     78 		kgets(line, sizeof(line));
     79 
     80 		flag = 0;
     81 		for(p = line, argc = 0; *p != '\0'; p++) {
     82 			if (*p != ' ' && *p != '\t') {
     83 				if (!flag) {
     84 					flag++;
     85 					argv[argc++] = p;
     86 				}
     87 			} else {
     88 				if (flag) {
     89 					*p = '\0';
     90 					flag = 0;
     91 				}
     92 			}
     93 		}
     94 
     95 		if (argc == 0)
     96 			continue;
     97 
     98 		tmp = 0;
     99 		while (db_cmd[tmp].name != NULL) {
    100 			if (!strcmp("continue", argv[0]))
    101 				return 0;
    102 			if (!strcmp(db_cmd[tmp].name, argv[0])) {
    103 				(db_cmd[tmp].fcn)(argc, argv);
    104 				break;
    105 			}
    106 			tmp++;
    107 		}
    108 		if (db_cmd[tmp].name == NULL)
    109 			db_cmd_help(argc, argv);
    110 	}
    111 	return 0;
    112 }
    113 
    114 int
    115 db_atob(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(int argc, char **argv)
    141 {
    142 	char *p, *r, *pp;
    143 	int mode, add, size, i;
    144 
    145 	switch (argc) {
    146 	case 4:
    147 		r = argv[1];
    148 		switch (r[1]) {
    149 		case 'b':
    150 			mode = 1;
    151 			break;
    152 		case 'h':
    153 			mode = 2;
    154 			break;
    155 		case 'w':
    156 			mode = 4;
    157 			break;
    158 		default:
    159 			goto out;
    160 		}
    161 		p = argv[2];
    162 		pp = argv[3];
    163 		break;
    164 	case 3:
    165 		mode = 4;
    166 		p = argv[1];
    167 		pp = argv[2];
    168 		break;
    169 	default:
    170 		goto out;
    171 	}
    172 
    173 	add = db_atob(p);
    174 	size = db_atob(pp);
    175 	i = 0;
    176 	for (; size > 0;) {
    177 		if (!i)
    178 			printf("\n0x%x:", add);
    179 		switch (mode) {
    180 		case 1:
    181 			printf(" %x", *(unsigned char *)add);
    182 			add += 1;
    183 			size -= 1;
    184 			if (++i == 16)
    185 				i = 0;
    186 			break;
    187 		case 2:
    188 			printf(" %x", *(unsigned short *)add);
    189 			add += 2;
    190 			size -= 2;
    191 			if (++i == 8)
    192 				i = 0;
    193 			break;
    194 		case 4:
    195 			printf(" %x", *(unsigned int *)add);
    196 			add += 4;
    197 			size -= 4;
    198 			if (++i == 4)
    199 				i = 0;
    200 			break;
    201 		}
    202 	}
    203 	printf("\n");
    204 	return;
    205 
    206 out:
    207 	printf("dump [-b][-h][-w] address size\n");
    208 	return;
    209 }
    210 
    211 void
    212 db_cmd_get(int argc, char **argv)
    213 {
    214 	char *p, *r;
    215 	int mode, add;
    216 
    217 	switch (argc) {
    218 	case 3:
    219 		r = argv[1];
    220 		switch (r[1]) {
    221 		case 'b':
    222 			mode = 1;
    223 			break;
    224 		case 'h':
    225 			mode = 2;
    226 			break;
    227 		case 'w':
    228 			mode = 4;
    229 			break;
    230 		default:
    231 			goto out;
    232 		}
    233 		p = argv[2];
    234 		break;
    235 	case 2:
    236 		mode = 4;
    237 		p = argv[1];
    238 		break;
    239 	default:
    240 		goto out;
    241 	}
    242 
    243 	add = db_atob(p);
    244 	printf("0x%x: ", add);
    245 	switch (mode) {
    246 	case 1:
    247 		printf("0x%x", *(char *)add);
    248 		break;
    249 	case 2:
    250 		printf("0x%x", *(short *)add);
    251 		break;
    252 	case 4:
    253 		printf("0x%x", *(int *)add);
    254 		break;
    255 	}
    256 	printf("\n");
    257 	return;
    258 
    259 out:
    260 	printf("get [-b][-h][-w] address\n");
    261 	return;
    262 }
    263 
    264 void
    265 db_cmd_put(int argc, char **argv)
    266 {
    267 	char *p, *r, *pp;
    268 	int mode, add, data;
    269 
    270 	switch (argc) {
    271 	case 4:
    272 		r = argv[1];
    273 		switch (r[1]) {
    274 		case 'b':
    275 			mode = 1;
    276 			break;
    277 		case 'h':
    278 			mode = 2;
    279 			break;
    280 		case 'w':
    281 			mode = 4;
    282 			break;
    283 		default:
    284 			goto out;
    285 		}
    286 		p = argv[2];
    287 		pp = argv[3];
    288 		break;
    289 	case 3:
    290 		mode = 4;
    291 		p = argv[1];
    292 		pp = argv[2];
    293 		break;
    294 	default:
    295 		goto out;
    296 	}
    297 
    298 	add = db_atob(p);
    299 	data = db_atob(pp);
    300 	printf("0x%x: 0x%x", add, data);
    301 	switch (mode) {
    302 	case 1:
    303 		*(char *)add = data;
    304 		break;
    305 	case 2:
    306 		*(short *)add = data;
    307 		break;
    308 	case 4:
    309 		*(int *)add = data;
    310 		break;
    311 	}
    312 	printf("\n");
    313 	return;
    314 
    315 out:
    316 	printf("put [-b][-h][-w] address data\n");
    317 	return;
    318 }
    319 
    320 #define STR(x) #x
    321 
    322 #define	FUNC(x) \
    323 unsigned int mf ## x() { \
    324 	unsigned int tmp; \
    325 	__asm volatile (STR(mf ## x %0) : STR(=r)(tmp)); \
    326 	return (tmp); \
    327 } \
    328 void mt ## x(unsigned int data) \
    329 { \
    330 	__asm volatile (STR(mt ## x %0) :: STR(r)(data)); \
    331 } \
    332 
    333 #define DEF(x) \
    334 	{ #x, mf ## x, mt ## x }
    335 
    336 FUNC(msr);
    337 
    338 struct {
    339 	char *op;
    340 	unsigned int (*mf)(void);
    341 	void (*mt)(unsigned int);
    342 } mreg [] = {
    343 	DEF(msr),
    344 	{ NULL, NULL, NULL },
    345 };
    346 
    347 void
    348 db_cmd_mf(int argc, char **argv)
    349 {
    350 	int i = 0;
    351 
    352 	if (argc != 2) {
    353 		printf("mf register\nregister:");
    354 		while (mreg[i].op != NULL)
    355 			printf(" %s", mreg[i++].op);
    356 		printf("\n");
    357 		return;
    358 	}
    359 
    360 	while (mreg[i].op != NULL) {
    361 		if (!strcmp(mreg[i].op, argv[1])) {
    362 			printf(" 0x%x\n", (mreg[i].mf)());
    363 			break;
    364 		}
    365 		i++;
    366 	}
    367 }
    368 
    369 void
    370 db_cmd_mt(int argc, char **argv)
    371 {
    372 	int i = 0;
    373 
    374 	if (argc != 3) {
    375 		printf("mt register data\nregister:");
    376 		while (mreg[i].op != NULL)
    377 			printf(" %s", mreg[i++].op);
    378 		printf("\n");
    379 		return;
    380 	}
    381 
    382 	while (mreg[i].op != NULL) {
    383 		if (!strcmp(mreg[i].op, argv[1])) {
    384 			(mreg[i].mt)((unsigned int)db_atob(argv[2]));
    385 			printf(" 0x%x\n", db_atob(argv[2]));
    386 			break;
    387 		}
    388 		i++;
    389 	}
    390 }
    391 
    392 void
    393 db_cmd_help(int argc, char **argv)
    394 {
    395 	int i = 0;
    396 
    397 	while (db_cmd[i].name != NULL)
    398 		printf("%s, ", db_cmd[i++].name);
    399 	printf("continue\n");
    400 }
    401 
    402 #endif /* DBMONITOR */
    403