Home | History | Annotate | Line # | Download | only in boot
monitor.c revision 1.11
      1 /*	$NetBSD: monitor.c,v 1.11 2016/06/11 06:28:49 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 #include <lib/libsa/stand.h>
     33 #include <lib/libkern/libkern.h>
     34 
     35 #include "boot.h"
     36 
     37 extern int errno;
     38 extern char *name;
     39 
     40 void db_cmd_dump(int, char **);
     41 void db_cmd_get(int, char **);
     42 void db_cmd_mf(int, char **);
     43 void db_cmd_mt(int, char **);
     44 void db_cmd_put(int, char **);
     45 void db_cmd_help(int, char **);
     46 
     47 uint32_t db_atob(char *);
     48 
     49 struct {
     50 	char *name;
     51 	void (*fcn)(int, char **);
     52 } db_cmd[] = {
     53 	{ "dump",	db_cmd_dump },
     54 	{ "get",	db_cmd_get },
     55 	{ "mf",		db_cmd_mf },
     56 	{ "mt",		db_cmd_mt },
     57 	{ "put",	db_cmd_put },
     58 	{ "help",	db_cmd_help },
     59 	{ NULL,		NULL },
     60 };
     61 
     62 int
     63 db_monitor(void)
     64 {
     65 	int tmp;
     66 	int argc, flag;
     67 	char *p, *argv[16];
     68 	char line[1024];
     69 
     70 	while (1) {
     71 		printf("db> ");
     72 		kgets(line, sizeof(line));
     73 
     74 		flag = 0;
     75 		for (p = line, argc = 0; *p != '\0'; p++) {
     76 			if (*p != ' ' && *p != '\t') {
     77 				if (!flag) {
     78 					flag++;
     79 					argv[argc++] = p;
     80 				}
     81 			} else {
     82 				if (flag) {
     83 					*p = '\0';
     84 					flag = 0;
     85 				}
     86 			}
     87 		}
     88 
     89 		if (argc == 0)
     90 			continue;
     91 
     92 		tmp = 0;
     93 		while (db_cmd[tmp].name != NULL) {
     94 			if (!strcmp("continue", argv[0]))
     95 				return 0;
     96 			if (!strcmp(db_cmd[tmp].name, argv[0])) {
     97 				(db_cmd[tmp].fcn)(argc, argv);
     98 				break;
     99 			}
    100 			tmp++;
    101 		}
    102 		if (db_cmd[tmp].name == NULL)
    103 			db_cmd_help(argc, argv);
    104 	}
    105 	return 0;
    106 }
    107 
    108 uint32_t
    109 db_atob(char *p)
    110 {
    111 	uint32_t b = 0;
    112 	int width, tmp, exp, x = 0;
    113 
    114 	if (p[1] == 'x') {
    115 		p += 2;
    116 		x = 1;
    117 	}
    118 	width = strlen(p);
    119 	while (width--) {
    120 		exp = 1;
    121 		for (tmp = 1; tmp <= width; tmp++)
    122 			exp *= (x ? 16 : 10);
    123 		if (*p >= '0' && *p <= '9') {
    124 			tmp = *p - '0';
    125 		} else {
    126 			tmp = *p - 'a' + 10;
    127 		}
    128 		b += tmp * exp;
    129 		p++;
    130 	}
    131 	return b;
    132 }
    133 
    134 void
    135 db_cmd_dump(int argc, char **argv)
    136 {
    137 	char *p, *r, *pp;
    138 	int mode, size, i;
    139 	uint32_t add;
    140 
    141 	switch (argc) {
    142 	case 4:
    143 		r = argv[1];
    144 		switch (r[1]) {
    145 		case 'b':
    146 			mode = 1;
    147 			break;
    148 		case 'h':
    149 			mode = 2;
    150 			break;
    151 		case 'w':
    152 			mode = 4;
    153 			break;
    154 		default:
    155 			goto out;
    156 		}
    157 		p = argv[2];
    158 		pp = argv[3];
    159 		break;
    160 	case 3:
    161 		mode = 4;
    162 		p = argv[1];
    163 		pp = argv[2];
    164 		break;
    165 	default:
    166 		goto out;
    167 	}
    168 
    169 	add = db_atob(p);
    170 	size = db_atob(pp);
    171 	i = 0;
    172 	for (; size > 0;) {
    173 		if (!i)
    174 			printf("\n0x%x:", add);
    175 		switch (mode) {
    176 		case 1:
    177 			printf(" %x", *(uint8_t *)add);
    178 			add += 1;
    179 			size -= 1;
    180 			if (++i == 16)
    181 				i = 0;
    182 			break;
    183 		case 2:
    184 			printf(" %x", *(uint16_t *)add);
    185 			add += 2;
    186 			size -= 2;
    187 			if (++i == 8)
    188 				i = 0;
    189 			break;
    190 		case 4:
    191 			printf(" %x", *(uint32_t *)add);
    192 			add += 4;
    193 			size -= 4;
    194 			if (++i == 4)
    195 				i = 0;
    196 			break;
    197 		}
    198 	}
    199 	printf("\n");
    200 	return;
    201 
    202 out:
    203 	printf("dump [-b][-h][-w] address size\n");
    204 	return;
    205 }
    206 
    207 void
    208 db_cmd_get(int argc, char **argv)
    209 {
    210 	char *p, *r;
    211 	uint32_t add;
    212 	int mode;
    213 
    214 	switch (argc) {
    215 	case 3:
    216 		r = argv[1];
    217 		switch (r[1]) {
    218 		case 'b':
    219 			mode = 1;
    220 			break;
    221 		case 'h':
    222 			mode = 2;
    223 			break;
    224 		case 'w':
    225 			mode = 4;
    226 			break;
    227 		default:
    228 			goto out;
    229 		}
    230 		p = argv[2];
    231 		break;
    232 	case 2:
    233 		mode = 4;
    234 		p = argv[1];
    235 		break;
    236 	default:
    237 		goto out;
    238 	}
    239 
    240 	add = db_atob(p);
    241 	printf("0x%x: ", add);
    242 	switch (mode) {
    243 	case 1:
    244 		printf("0x%x", *(uint8_t *)add);
    245 		break;
    246 	case 2:
    247 		printf("0x%x", *(uint16_t *)add);
    248 		break;
    249 	case 4:
    250 		printf("0x%x", *(uint32_t *)add);
    251 		break;
    252 	}
    253 	printf("\n");
    254 	return;
    255 
    256 out:
    257 	printf("get [-b][-h][-w] address\n");
    258 	return;
    259 }
    260 
    261 void
    262 db_cmd_put(int argc, char **argv)
    263 {
    264 	char *p, *r, *pp;
    265 	uint32_t add, data;
    266 	int mode;
    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 		*(uint8_t *)add = data;
    302 		break;
    303 	case 2:
    304 		*(uint16_t *)add = data;
    305 		break;
    306 	case 4:
    307 		*(uint32_t *)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 uint32_t mf ## x(void); \
    322 void mt ## x(uint32_t); \
    323 uint32_t mf ## x() { \
    324 	uint32_t tmp; \
    325 	__asm volatile (STR(mf ## x %0) : STR(=r)(tmp)); \
    326 	return (tmp); \
    327 } \
    328 void mt ## x(uint32_t 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 	uint32_t (*mf)(void);
    341 	void (*mt)(uint32_t);
    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)(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("\n");
    400 }
    401