xref: /netbsd-src/sys/arch/bebox/stand/boot/monitor.c (revision 85e3fbd2ebdea4c043943e3fc74aae69c997bc76)
1*85e3fbd2Sdholland /*	$NetBSD: monitor.c,v 1.11 2016/06/11 06:28:49 dholland Exp $	*/
2b1bde3fcSsakamoto 
3b1bde3fcSsakamoto /*-
4b1bde3fcSsakamoto  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
5b1bde3fcSsakamoto  * All rights reserved.
6b1bde3fcSsakamoto  *
7b1bde3fcSsakamoto  * This code is derived from software contributed to The NetBSD Foundation
8b1bde3fcSsakamoto  * by Kazuki Sakamoto.
9b1bde3fcSsakamoto  *
10b1bde3fcSsakamoto  * Redistribution and use in source and binary forms, with or without
11b1bde3fcSsakamoto  * modification, are permitted provided that the following conditions
12b1bde3fcSsakamoto  * are met:
13b1bde3fcSsakamoto  * 1. Redistributions of source code must retain the above copyright
14b1bde3fcSsakamoto  *    notice, this list of conditions and the following disclaimer.
15b1bde3fcSsakamoto  * 2. Redistributions in binary form must reproduce the above copyright
16b1bde3fcSsakamoto  *    notice, this list of conditions and the following disclaimer in the
17b1bde3fcSsakamoto  *    documentation and/or other materials provided with the distribution.
18b1bde3fcSsakamoto  *
19b1bde3fcSsakamoto  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20b1bde3fcSsakamoto  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21b1bde3fcSsakamoto  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22b1bde3fcSsakamoto  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23b1bde3fcSsakamoto  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24b1bde3fcSsakamoto  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25b1bde3fcSsakamoto  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26b1bde3fcSsakamoto  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27b1bde3fcSsakamoto  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28b1bde3fcSsakamoto  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29b1bde3fcSsakamoto  * POSSIBILITY OF SUCH DAMAGE.
30b1bde3fcSsakamoto  */
31b1bde3fcSsakamoto 
32e63501d2Sjunyoung #include <lib/libsa/stand.h>
3333aaae50Skiyohara #include <lib/libkern/libkern.h>
3433aaae50Skiyohara 
3533aaae50Skiyohara #include "boot.h"
36b1bde3fcSsakamoto 
37b1bde3fcSsakamoto extern int errno;
38b1bde3fcSsakamoto extern char *name;
39b1bde3fcSsakamoto 
4088ebacb4Sjunyoung void db_cmd_dump(int, char **);
4188ebacb4Sjunyoung void db_cmd_get(int, char **);
4288ebacb4Sjunyoung void db_cmd_mf(int, char **);
4388ebacb4Sjunyoung void db_cmd_mt(int, char **);
4488ebacb4Sjunyoung void db_cmd_put(int, char **);
4588ebacb4Sjunyoung void db_cmd_help(int, char **);
46d32f2272Ssakamoto 
4766c8502fSphx uint32_t db_atob(char *);
48b1bde3fcSsakamoto 
49b1bde3fcSsakamoto struct {
50b1bde3fcSsakamoto 	char *name;
51b1bde3fcSsakamoto 	void (*fcn)(int, char **);
52b1bde3fcSsakamoto } db_cmd[] = {
53b1bde3fcSsakamoto 	{ "dump",	db_cmd_dump },
54b1bde3fcSsakamoto 	{ "get",	db_cmd_get },
55b1bde3fcSsakamoto 	{ "mf",		db_cmd_mf },
56b1bde3fcSsakamoto 	{ "mt",		db_cmd_mt },
57b1bde3fcSsakamoto 	{ "put",	db_cmd_put },
58b1bde3fcSsakamoto 	{ "help",	db_cmd_help },
59b1bde3fcSsakamoto 	{ NULL,		NULL },
60b1bde3fcSsakamoto };
61b1bde3fcSsakamoto 
62b1bde3fcSsakamoto int
db_monitor(void)6388ebacb4Sjunyoung db_monitor(void)
64b1bde3fcSsakamoto {
65b1bde3fcSsakamoto 	int tmp;
66b1bde3fcSsakamoto 	int argc, flag;
67b1bde3fcSsakamoto 	char *p, *argv[16];
68b1bde3fcSsakamoto 	char line[1024];
69b1bde3fcSsakamoto 
70b1bde3fcSsakamoto 	while (1) {
71b1bde3fcSsakamoto 		printf("db> ");
72*85e3fbd2Sdholland 		kgets(line, sizeof(line));
73b1bde3fcSsakamoto 
74b1bde3fcSsakamoto 		flag = 0;
75b1bde3fcSsakamoto 		for (p = line, argc = 0; *p != '\0'; p++) {
76b1bde3fcSsakamoto 			if (*p != ' ' && *p != '\t') {
77b1bde3fcSsakamoto 				if (!flag) {
78b1bde3fcSsakamoto 					flag++;
79b1bde3fcSsakamoto 					argv[argc++] = p;
80b1bde3fcSsakamoto 				}
81b1bde3fcSsakamoto 			} else {
82b1bde3fcSsakamoto 				if (flag) {
83b1bde3fcSsakamoto 					*p = '\0';
84b1bde3fcSsakamoto 					flag = 0;
85b1bde3fcSsakamoto 				}
86b1bde3fcSsakamoto 			}
87b1bde3fcSsakamoto 		}
88b1bde3fcSsakamoto 
89b1bde3fcSsakamoto 		if (argc == 0)
90b1bde3fcSsakamoto 			continue;
91b1bde3fcSsakamoto 
92b1bde3fcSsakamoto 		tmp = 0;
93b1bde3fcSsakamoto 		while (db_cmd[tmp].name != NULL) {
94b1bde3fcSsakamoto 			if (!strcmp("continue", argv[0]))
95b1bde3fcSsakamoto 				return 0;
96b1bde3fcSsakamoto 			if (!strcmp(db_cmd[tmp].name, argv[0])) {
97b1bde3fcSsakamoto 				(db_cmd[tmp].fcn)(argc, argv);
98b1bde3fcSsakamoto 				break;
99b1bde3fcSsakamoto 			}
100b1bde3fcSsakamoto 			tmp++;
101b1bde3fcSsakamoto 		}
102b1bde3fcSsakamoto 		if (db_cmd[tmp].name == NULL)
103b1bde3fcSsakamoto 			db_cmd_help(argc, argv);
104b1bde3fcSsakamoto 	}
105b1bde3fcSsakamoto 	return 0;
106b1bde3fcSsakamoto }
107b1bde3fcSsakamoto 
10866c8502fSphx uint32_t
db_atob(char * p)10988ebacb4Sjunyoung db_atob(char *p)
110b1bde3fcSsakamoto {
11166c8502fSphx 	uint32_t b = 0;
11266c8502fSphx 	int width, tmp, exp, x = 0;
113b1bde3fcSsakamoto 
114b1bde3fcSsakamoto 	if (p[1] == 'x') {
115b1bde3fcSsakamoto 		p += 2;
116b1bde3fcSsakamoto 		x = 1;
117b1bde3fcSsakamoto 	}
118b1bde3fcSsakamoto 	width = strlen(p);
119b1bde3fcSsakamoto 	while (width--) {
120b1bde3fcSsakamoto 		exp = 1;
121b1bde3fcSsakamoto 		for (tmp = 1; tmp <= width; tmp++)
122b1bde3fcSsakamoto 			exp *= (x ? 16 : 10);
123b1bde3fcSsakamoto 		if (*p >= '0' && *p <= '9') {
124b1bde3fcSsakamoto 			tmp = *p - '0';
125b1bde3fcSsakamoto 		} else {
126b1bde3fcSsakamoto 			tmp = *p - 'a' + 10;
127b1bde3fcSsakamoto 		}
128b1bde3fcSsakamoto 		b += tmp * exp;
129b1bde3fcSsakamoto 		p++;
130b1bde3fcSsakamoto 	}
131b1bde3fcSsakamoto 	return b;
132b1bde3fcSsakamoto }
133b1bde3fcSsakamoto 
134b1bde3fcSsakamoto void
db_cmd_dump(int argc,char ** argv)13588ebacb4Sjunyoung db_cmd_dump(int argc, char **argv)
136b1bde3fcSsakamoto {
137b1bde3fcSsakamoto 	char *p, *r, *pp;
13866c8502fSphx 	int mode, size, i;
13966c8502fSphx 	uint32_t add;
140b1bde3fcSsakamoto 
141b1bde3fcSsakamoto 	switch (argc) {
142b1bde3fcSsakamoto 	case 4:
143b1bde3fcSsakamoto 		r = argv[1];
144b1bde3fcSsakamoto 		switch (r[1]) {
145b1bde3fcSsakamoto 		case 'b':
146b1bde3fcSsakamoto 			mode = 1;
147b1bde3fcSsakamoto 			break;
148b1bde3fcSsakamoto 		case 'h':
149b1bde3fcSsakamoto 			mode = 2;
150b1bde3fcSsakamoto 			break;
151b1bde3fcSsakamoto 		case 'w':
152b1bde3fcSsakamoto 			mode = 4;
153b1bde3fcSsakamoto 			break;
154b1bde3fcSsakamoto 		default:
155b1bde3fcSsakamoto 			goto out;
156b1bde3fcSsakamoto 		}
157b1bde3fcSsakamoto 		p = argv[2];
158b1bde3fcSsakamoto 		pp = argv[3];
159b1bde3fcSsakamoto 		break;
160b1bde3fcSsakamoto 	case 3:
161b1bde3fcSsakamoto 		mode = 4;
162b1bde3fcSsakamoto 		p = argv[1];
163b1bde3fcSsakamoto 		pp = argv[2];
164b1bde3fcSsakamoto 		break;
165b1bde3fcSsakamoto 	default:
166b1bde3fcSsakamoto 		goto out;
167b1bde3fcSsakamoto 	}
168b1bde3fcSsakamoto 
169b1bde3fcSsakamoto 	add = db_atob(p);
170b1bde3fcSsakamoto 	size = db_atob(pp);
171b1bde3fcSsakamoto 	i = 0;
172b1bde3fcSsakamoto 	for (; size > 0;) {
173b1bde3fcSsakamoto 		if (!i)
174b1bde3fcSsakamoto 			printf("\n0x%x:", add);
175b1bde3fcSsakamoto 		switch (mode) {
176b1bde3fcSsakamoto 		case 1:
17766c8502fSphx 			printf(" %x", *(uint8_t *)add);
178b1bde3fcSsakamoto 			add += 1;
179b1bde3fcSsakamoto 			size -= 1;
180b1bde3fcSsakamoto 			if (++i == 16)
181b1bde3fcSsakamoto 				i = 0;
182b1bde3fcSsakamoto 			break;
183b1bde3fcSsakamoto 		case 2:
18466c8502fSphx 			printf(" %x", *(uint16_t *)add);
185b1bde3fcSsakamoto 			add += 2;
186b1bde3fcSsakamoto 			size -= 2;
187b1bde3fcSsakamoto 			if (++i == 8)
188b1bde3fcSsakamoto 				i = 0;
189b1bde3fcSsakamoto 			break;
190b1bde3fcSsakamoto 		case 4:
19166c8502fSphx 			printf(" %x", *(uint32_t *)add);
192b1bde3fcSsakamoto 			add += 4;
193b1bde3fcSsakamoto 			size -= 4;
194b1bde3fcSsakamoto 			if (++i == 4)
195b1bde3fcSsakamoto 				i = 0;
196b1bde3fcSsakamoto 			break;
197b1bde3fcSsakamoto 		}
198b1bde3fcSsakamoto 	}
199b1bde3fcSsakamoto 	printf("\n");
200b1bde3fcSsakamoto 	return;
201b1bde3fcSsakamoto 
202b1bde3fcSsakamoto out:
203b1bde3fcSsakamoto 	printf("dump [-b][-h][-w] address size\n");
204b1bde3fcSsakamoto 	return;
205b1bde3fcSsakamoto }
206b1bde3fcSsakamoto 
207b1bde3fcSsakamoto void
db_cmd_get(int argc,char ** argv)20888ebacb4Sjunyoung db_cmd_get(int argc, char **argv)
209b1bde3fcSsakamoto {
210b1bde3fcSsakamoto 	char *p, *r;
21166c8502fSphx 	uint32_t add;
21266c8502fSphx 	int mode;
213b1bde3fcSsakamoto 
214b1bde3fcSsakamoto 	switch (argc) {
215b1bde3fcSsakamoto 	case 3:
216b1bde3fcSsakamoto 		r = argv[1];
217b1bde3fcSsakamoto 		switch (r[1]) {
218b1bde3fcSsakamoto 		case 'b':
219b1bde3fcSsakamoto 			mode = 1;
220b1bde3fcSsakamoto 			break;
221b1bde3fcSsakamoto 		case 'h':
222b1bde3fcSsakamoto 			mode = 2;
223b1bde3fcSsakamoto 			break;
224b1bde3fcSsakamoto 		case 'w':
225b1bde3fcSsakamoto 			mode = 4;
226b1bde3fcSsakamoto 			break;
227b1bde3fcSsakamoto 		default:
228b1bde3fcSsakamoto 			goto out;
229b1bde3fcSsakamoto 		}
230b1bde3fcSsakamoto 		p = argv[2];
231b1bde3fcSsakamoto 		break;
232b1bde3fcSsakamoto 	case 2:
233b1bde3fcSsakamoto 		mode = 4;
234b1bde3fcSsakamoto 		p = argv[1];
235b1bde3fcSsakamoto 		break;
236b1bde3fcSsakamoto 	default:
237b1bde3fcSsakamoto 		goto out;
238b1bde3fcSsakamoto 	}
239b1bde3fcSsakamoto 
240b1bde3fcSsakamoto 	add = db_atob(p);
241b1bde3fcSsakamoto 	printf("0x%x: ", add);
242b1bde3fcSsakamoto 	switch (mode) {
243b1bde3fcSsakamoto 	case 1:
24466c8502fSphx 		printf("0x%x", *(uint8_t *)add);
245b1bde3fcSsakamoto 		break;
246b1bde3fcSsakamoto 	case 2:
24766c8502fSphx 		printf("0x%x", *(uint16_t *)add);
248b1bde3fcSsakamoto 		break;
249b1bde3fcSsakamoto 	case 4:
25066c8502fSphx 		printf("0x%x", *(uint32_t *)add);
251b1bde3fcSsakamoto 		break;
252b1bde3fcSsakamoto 	}
253b1bde3fcSsakamoto 	printf("\n");
254b1bde3fcSsakamoto 	return;
255b1bde3fcSsakamoto 
256b1bde3fcSsakamoto out:
257b1bde3fcSsakamoto 	printf("get [-b][-h][-w] address\n");
258b1bde3fcSsakamoto 	return;
259b1bde3fcSsakamoto }
260b1bde3fcSsakamoto 
261b1bde3fcSsakamoto void
db_cmd_put(int argc,char ** argv)26288ebacb4Sjunyoung db_cmd_put(int argc, char **argv)
263b1bde3fcSsakamoto {
264b1bde3fcSsakamoto 	char *p, *r, *pp;
26566c8502fSphx 	uint32_t add, data;
26666c8502fSphx 	int mode;
267b1bde3fcSsakamoto 
268b1bde3fcSsakamoto 	switch (argc) {
269b1bde3fcSsakamoto 	case 4:
270b1bde3fcSsakamoto 		r = argv[1];
271b1bde3fcSsakamoto 		switch (r[1]) {
272b1bde3fcSsakamoto 		case 'b':
273b1bde3fcSsakamoto 			mode = 1;
274b1bde3fcSsakamoto 			break;
275b1bde3fcSsakamoto 		case 'h':
276b1bde3fcSsakamoto 			mode = 2;
277b1bde3fcSsakamoto 			break;
278b1bde3fcSsakamoto 		case 'w':
279b1bde3fcSsakamoto 			mode = 4;
280b1bde3fcSsakamoto 			break;
281b1bde3fcSsakamoto 		default:
282b1bde3fcSsakamoto 			goto out;
283b1bde3fcSsakamoto 		}
284b1bde3fcSsakamoto 		p = argv[2];
285b1bde3fcSsakamoto 		pp = argv[3];
286b1bde3fcSsakamoto 		break;
287b1bde3fcSsakamoto 	case 3:
288b1bde3fcSsakamoto 		mode = 4;
289b1bde3fcSsakamoto 		p = argv[1];
290b1bde3fcSsakamoto 		pp = argv[2];
291b1bde3fcSsakamoto 		break;
292b1bde3fcSsakamoto 	default:
293b1bde3fcSsakamoto 		goto out;
294b1bde3fcSsakamoto 	}
295b1bde3fcSsakamoto 
296b1bde3fcSsakamoto 	add = db_atob(p);
297b1bde3fcSsakamoto 	data = db_atob(pp);
298b1bde3fcSsakamoto 	printf("0x%x: 0x%x", add, data);
299b1bde3fcSsakamoto 	switch (mode) {
300b1bde3fcSsakamoto 	case 1:
30166c8502fSphx 		*(uint8_t *)add = data;
302b1bde3fcSsakamoto 		break;
303b1bde3fcSsakamoto 	case 2:
30466c8502fSphx 		*(uint16_t *)add = data;
305b1bde3fcSsakamoto 		break;
306b1bde3fcSsakamoto 	case 4:
30766c8502fSphx 		*(uint32_t *)add = data;
308b1bde3fcSsakamoto 		break;
309b1bde3fcSsakamoto 	}
310b1bde3fcSsakamoto 	printf("\n");
311b1bde3fcSsakamoto 	return;
312b1bde3fcSsakamoto 
313b1bde3fcSsakamoto out:
314b1bde3fcSsakamoto 	printf("put [-b][-h][-w] address data\n");
315b1bde3fcSsakamoto 	return;
316b1bde3fcSsakamoto }
317b1bde3fcSsakamoto 
318b1bde3fcSsakamoto #define STR(x) #x
319b1bde3fcSsakamoto 
320b1bde3fcSsakamoto #define	FUNC(x) \
32166c8502fSphx uint32_t mf ## x(void); \
32266c8502fSphx void mt ## x(uint32_t); \
32366c8502fSphx uint32_t mf ## x() { \
32466c8502fSphx 	uint32_t tmp; \
3252d65de24Sperry 	__asm volatile (STR(mf ## x %0) : STR(=r)(tmp)); \
326b1bde3fcSsakamoto 	return (tmp); \
327b1bde3fcSsakamoto } \
32866c8502fSphx void mt ## x(uint32_t data) \
329b1bde3fcSsakamoto { \
3302d65de24Sperry 	__asm volatile (STR(mt ## x %0) :: STR(r)(data)); \
331b1bde3fcSsakamoto } \
332b1bde3fcSsakamoto 
333b1bde3fcSsakamoto #define DEF(x) \
334b1bde3fcSsakamoto 	{ #x, mf ## x, mt ## x }
335b1bde3fcSsakamoto 
33633aaae50Skiyohara FUNC(msr)
337b1bde3fcSsakamoto 
338b1bde3fcSsakamoto struct {
339b1bde3fcSsakamoto 	char *op;
34066c8502fSphx 	uint32_t (*mf)(void);
34166c8502fSphx 	void (*mt)(uint32_t);
342b1bde3fcSsakamoto } mreg [] = {
343b1bde3fcSsakamoto 	DEF(msr),
344b1bde3fcSsakamoto 	{ NULL, NULL, NULL },
345b1bde3fcSsakamoto };
346b1bde3fcSsakamoto 
347b1bde3fcSsakamoto void
db_cmd_mf(int argc,char ** argv)34888ebacb4Sjunyoung db_cmd_mf(int argc, char **argv)
349b1bde3fcSsakamoto {
350b1bde3fcSsakamoto 	int i = 0;
351b1bde3fcSsakamoto 
352b1bde3fcSsakamoto 	if (argc != 2) {
353b1bde3fcSsakamoto 		printf("mf register\nregister:");
354b1bde3fcSsakamoto 		while (mreg[i].op != NULL)
355b1bde3fcSsakamoto 			printf(" %s", mreg[i++].op);
356b1bde3fcSsakamoto 		printf("\n");
357b1bde3fcSsakamoto 		return;
358b1bde3fcSsakamoto 	}
359b1bde3fcSsakamoto 
360b1bde3fcSsakamoto 	while (mreg[i].op != NULL) {
361b1bde3fcSsakamoto 		if (!strcmp(mreg[i].op, argv[1])) {
362b1bde3fcSsakamoto 			printf(" 0x%x\n", (mreg[i].mf)());
363b1bde3fcSsakamoto 			break;
364b1bde3fcSsakamoto 		}
365b1bde3fcSsakamoto 		i++;
366b1bde3fcSsakamoto 	}
367b1bde3fcSsakamoto }
368b1bde3fcSsakamoto 
369b1bde3fcSsakamoto void
db_cmd_mt(int argc,char ** argv)37088ebacb4Sjunyoung db_cmd_mt(int argc, char **argv)
371b1bde3fcSsakamoto {
372b1bde3fcSsakamoto 	int i = 0;
373b1bde3fcSsakamoto 
374b1bde3fcSsakamoto 	if (argc != 3) {
375b1bde3fcSsakamoto 		printf("mt register data\nregister:");
376b1bde3fcSsakamoto 		while (mreg[i].op != NULL)
377b1bde3fcSsakamoto 			printf(" %s", mreg[i++].op);
378b1bde3fcSsakamoto 		printf("\n");
379b1bde3fcSsakamoto 		return;
380b1bde3fcSsakamoto 	}
381b1bde3fcSsakamoto 
382b1bde3fcSsakamoto 	while (mreg[i].op != NULL) {
383b1bde3fcSsakamoto 		if (!strcmp(mreg[i].op, argv[1])) {
38466c8502fSphx 			(mreg[i].mt)(db_atob(argv[2]));
385b1bde3fcSsakamoto 			printf(" 0x%x\n", db_atob(argv[2]));
386b1bde3fcSsakamoto 			break;
387b1bde3fcSsakamoto 		}
388b1bde3fcSsakamoto 		i++;
389b1bde3fcSsakamoto 	}
390b1bde3fcSsakamoto }
391b1bde3fcSsakamoto 
392b1bde3fcSsakamoto void
db_cmd_help(int argc,char ** argv)39388ebacb4Sjunyoung db_cmd_help(int argc, char **argv)
394b1bde3fcSsakamoto {
395b1bde3fcSsakamoto 	int i = 0;
396b1bde3fcSsakamoto 
397b1bde3fcSsakamoto 	while (db_cmd[i].name != NULL)
398b1bde3fcSsakamoto 		printf("%s, ", db_cmd[i++].name);
399b1bde3fcSsakamoto 	printf("\n");
400b1bde3fcSsakamoto }
401