Home | History | Annotate | Line # | Download | only in boot
      1 /*	$NetBSD: monitor.c,v 1.4 2016/06/11 06:31: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 #if defined(DBMONITOR)
     33 
     34 #include <lib/libsa/stand.h>
     35 #include <lib/libkern/libkern.h>
     36 
     37 #include "boot.h"
     38 
     39 #ifndef	NULL
     40 #define NULL	(void *)0
     41 #endif
     42 
     43 static void db_cmd_dump(int, char **);
     44 static void db_cmd_get(int, char **);
     45 static void db_cmd_put(int, char **);
     46 static void db_cmd_help(int, char **);
     47 
     48 static int db_atob(char *);
     49 
     50 static const struct db_cmd {
     51 	char *name;
     52 	void (*fcn)(int, char **);
     53 } db_cmd[] = {
     54 	{ "dump",	db_cmd_dump },
     55 	{ "get",	db_cmd_get },
     56 	{ "put",	db_cmd_put },
     57 	{ "help",	db_cmd_help },
     58 	{ NULL,		NULL },
     59 };
     60 
     61 int
     62 db_monitor(void)
     63 {
     64 	char line[1024];
     65 	char *p, *argv[16];
     66 	int argc, flag;
     67 	int tmp;
     68 
     69 	for (;;) {
     70 		printf("db> ");
     71 		kgets(line, sizeof(line));
     72 
     73 		flag = 0;
     74 		argc = 0;
     75 		for (p = line; *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 		if (argc == 0)
     89 			continue;
     90 
     91 		tmp = 0;
     92 		while (db_cmd[tmp].name != NULL) {
     93 			if (strcmp("continue", argv[0]) == 0)
     94 				return 0;
     95 			if (strcmp(db_cmd[tmp].name, argv[0]) == 0) {
     96 				(db_cmd[tmp].fcn)(argc, argv);
     97 				break;
     98 			}
     99 			tmp++;
    100 		}
    101 		if (db_cmd[tmp].name == NULL)
    102 			db_cmd_help(argc, argv);
    103 	}
    104 
    105 	return 0;
    106 }
    107 
    108 static int
    109 db_atob(char *p)
    110 {
    111 	int b = 0, width, tmp, exp, x = 0;
    112 
    113 	if (p[1] == 'x') {
    114 		p += 2;
    115 		x = 1;
    116 	}
    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 static void
    135 db_cmd_dump(int argc, char **argv)
    136 {
    137 	char *p, *r, *pp;
    138 	int mode, add, size, i;
    139 
    140 	switch (argc) {
    141 	case 4:
    142 		r = argv[1];
    143 		switch (r[1]) {
    144 		case 'b':
    145 			mode = 1;
    146 			break;
    147 		case 'h':
    148 			mode = 2;
    149 			break;
    150 		case 'w':
    151 			mode = 4;
    152 			break;
    153 		default:
    154 			goto out;
    155 		}
    156 		p = argv[2];
    157 		pp = argv[3];
    158 		break;
    159 	case 3:
    160 		mode = 4;
    161 		p = argv[1];
    162 		pp = argv[2];
    163 		break;
    164 	default:
    165 		goto out;
    166 	}
    167 
    168 	add = db_atob(p);
    169 	size = db_atob(pp);
    170 	i = 0;
    171 	for (; size > 0;) {
    172 		if (i == 0) {
    173 			printf("\n0x%x:", add);
    174 		}
    175 		switch (mode) {
    176 		case 1:
    177 			printf(" ");
    178 			puthex(*(unsigned char *)add, 1);
    179 			add += 1;
    180 			size -= 1;
    181 			if (++i == 16)
    182 				i = 0;
    183 			break;
    184 		case 2:
    185 			printf(" ");
    186 			puthex(*(unsigned short *)add, 2);
    187 			add += 2;
    188 			size -= 2;
    189 			if (++i == 8)
    190 				i = 0;
    191 			break;
    192 		case 4:
    193 			printf(" ");
    194 			puthex(*(unsigned int *)add, 4);
    195 			add += 4;
    196 			size -= 4;
    197 			if (++i == 4)
    198 				i = 0;
    199 			break;
    200 		}
    201 	}
    202 	printf("\n");
    203 	return;
    204 
    205 out:
    206 	printf("dump [-b][-h][-w] address size\n");
    207 	return;
    208 }
    209 
    210 static void
    211 db_cmd_get(int argc, char **argv)
    212 {
    213 	char *p, *r;
    214 	int mode, add;
    215 	int val;
    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: 0x", add);
    245 	switch (mode) {
    246 	case 1:
    247 		val = *(char *)add;
    248 		break;
    249 	case 2:
    250 		val = *(short *)add;
    251 		break;
    252 	case 4:
    253 		val = *(int *)add;
    254 		break;
    255 	default:
    256 		val = 0;
    257 		break;
    258 	}
    259 	puthex(val, mode);
    260 	printf("\n");
    261 	return;
    262 
    263 out:
    264 	printf("get [-b][-h][-w] address\n");
    265 	return;
    266 }
    267 
    268 static void
    269 db_cmd_put(int argc, char **argv)
    270 {
    271 	char *p, *r, *pp;
    272 	int mode, add, data;
    273 
    274 	switch (argc) {
    275 	case 4:
    276 		r = argv[1];
    277 		switch (r[1]) {
    278 		case 'b':
    279 			mode = 1;
    280 			break;
    281 		case 'h':
    282 			mode = 2;
    283 			break;
    284 		case 'w':
    285 			mode = 4;
    286 			break;
    287 		default:
    288 			goto out;
    289 		}
    290 		p = argv[2];
    291 		pp = argv[3];
    292 		break;
    293 	case 3:
    294 		mode = 4;
    295 		p = argv[1];
    296 		pp = argv[2];
    297 		break;
    298 	default:
    299 		goto out;
    300 	}
    301 
    302 	add = db_atob(p);
    303 	data = db_atob(pp);
    304 	printf("0x%x: 0x", add);
    305 	puthex(data, mode);
    306 	switch (mode) {
    307 	case 1:
    308 		*(char *)add = data;
    309 		break;
    310 	case 2:
    311 		*(short *)add = data;
    312 		break;
    313 	case 4:
    314 		*(int *)add = data;
    315 		break;
    316 	}
    317 	printf("\n");
    318 	return;
    319 
    320 out:
    321 	printf("put [-b][-h][-w] address data\n");
    322 	return;
    323 }
    324 
    325 static void
    326 db_cmd_help(int argc, char **argv)
    327 {
    328 	int i = 0;
    329 
    330 	while (db_cmd[i].name != NULL)
    331 		printf("%s, ", db_cmd[i++].name);
    332 	printf("continue\n");
    333 }
    334 
    335 #endif	/* DBMONITOR */
    336