xref: /netbsd-src/sys/arch/rs6000/stand/boot/monitor.c (revision 2357cddab4a3fc9c1ab8f4f98d022a9960710ab3)
1*2357cddaSdholland /*	$NetBSD: monitor.c,v 1.4 2016/06/11 06:39:25 dholland Exp $	*/
268fe5b6fSgarbled 
368fe5b6fSgarbled /*-
468fe5b6fSgarbled  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
568fe5b6fSgarbled  * All rights reserved.
668fe5b6fSgarbled  *
768fe5b6fSgarbled  * This code is derived from software contributed to The NetBSD Foundation
868fe5b6fSgarbled  * by Kazuki Sakamoto.
968fe5b6fSgarbled  *
1068fe5b6fSgarbled  * Redistribution and use in source and binary forms, with or without
1168fe5b6fSgarbled  * modification, are permitted provided that the following conditions
1268fe5b6fSgarbled  * are met:
1368fe5b6fSgarbled  * 1. Redistributions of source code must retain the above copyright
1468fe5b6fSgarbled  *    notice, this list of conditions and the following disclaimer.
1568fe5b6fSgarbled  * 2. Redistributions in binary form must reproduce the above copyright
1668fe5b6fSgarbled  *    notice, this list of conditions and the following disclaimer in the
1768fe5b6fSgarbled  *    documentation and/or other materials provided with the distribution.
1868fe5b6fSgarbled  *
1968fe5b6fSgarbled  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2068fe5b6fSgarbled  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2168fe5b6fSgarbled  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2268fe5b6fSgarbled  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2368fe5b6fSgarbled  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2468fe5b6fSgarbled  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2568fe5b6fSgarbled  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2668fe5b6fSgarbled  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2768fe5b6fSgarbled  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2868fe5b6fSgarbled  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2968fe5b6fSgarbled  * POSSIBILITY OF SUCH DAMAGE.
3068fe5b6fSgarbled  */
3168fe5b6fSgarbled 
3268fe5b6fSgarbled #ifdef DBMONITOR
3368fe5b6fSgarbled 
3468fe5b6fSgarbled #include <lib/libsa/stand.h>
3568fe5b6fSgarbled #include <lib/libkern/libkern.h>
3668fe5b6fSgarbled #include "boot.h"
3768fe5b6fSgarbled 
3868fe5b6fSgarbled #define NULL	0
3968fe5b6fSgarbled 
4068fe5b6fSgarbled extern int errno;
4168fe5b6fSgarbled extern char *name;
4268fe5b6fSgarbled 
4368fe5b6fSgarbled void db_cmd_dump(int, char **);
4468fe5b6fSgarbled void db_cmd_get(int, char **);
4568fe5b6fSgarbled void db_cmd_mf(int, char **);
4668fe5b6fSgarbled void db_cmd_mt(int, char **);
4768fe5b6fSgarbled void db_cmd_put(int, char **);
4868fe5b6fSgarbled void db_cmd_help(int, char **);
4968fe5b6fSgarbled 
5092479c29Swiz unsigned int mfmsr(void);
5168fe5b6fSgarbled void mtmsr(unsigned int);
5268fe5b6fSgarbled 
5368fe5b6fSgarbled int db_atob(char *);
5468fe5b6fSgarbled 
5568fe5b6fSgarbled struct {
5668fe5b6fSgarbled 	char *name;
5768fe5b6fSgarbled 	void (*fcn)(int, char **);
5868fe5b6fSgarbled } db_cmd[] = {
5968fe5b6fSgarbled 	{ "dump",	db_cmd_dump },
6068fe5b6fSgarbled 	{ "get",	db_cmd_get },
6168fe5b6fSgarbled 	{ "mf",		db_cmd_mf },
6268fe5b6fSgarbled 	{ "mt",		db_cmd_mt },
6368fe5b6fSgarbled 	{ "put",	db_cmd_put },
6468fe5b6fSgarbled 	{ "help",	db_cmd_help },
6568fe5b6fSgarbled 	{ NULL,		NULL },
6668fe5b6fSgarbled };
6768fe5b6fSgarbled 
6868fe5b6fSgarbled int
db_monitor(void)6968fe5b6fSgarbled db_monitor(void)
7068fe5b6fSgarbled {
7168fe5b6fSgarbled 	int tmp;
7268fe5b6fSgarbled 	int argc, flag;
7368fe5b6fSgarbled 	char *p, *argv[16];
7468fe5b6fSgarbled 	char line[1024];
7568fe5b6fSgarbled 
7668fe5b6fSgarbled 	while(1) {
7768fe5b6fSgarbled 		printf("db> ");
78*2357cddaSdholland 		kgets(line, sizeof(line));
7968fe5b6fSgarbled 
8068fe5b6fSgarbled 		flag = 0;
8168fe5b6fSgarbled 		for(p = line, argc = 0; *p != '\0'; p++) {
8268fe5b6fSgarbled 			if (*p != ' ' && *p != '\t') {
8368fe5b6fSgarbled 				if (!flag) {
8468fe5b6fSgarbled 					flag++;
8568fe5b6fSgarbled 					argv[argc++] = p;
8668fe5b6fSgarbled 				}
8768fe5b6fSgarbled 			} else {
8868fe5b6fSgarbled 				if (flag) {
8968fe5b6fSgarbled 					*p = '\0';
9068fe5b6fSgarbled 					flag = 0;
9168fe5b6fSgarbled 				}
9268fe5b6fSgarbled 			}
9368fe5b6fSgarbled 		}
9468fe5b6fSgarbled 
9568fe5b6fSgarbled 		if (argc == 0)
9668fe5b6fSgarbled 			continue;
9768fe5b6fSgarbled 
9868fe5b6fSgarbled 		tmp = 0;
9968fe5b6fSgarbled 		while (db_cmd[tmp].name != NULL) {
10068fe5b6fSgarbled 			if (!strcmp("continue", argv[0]))
10168fe5b6fSgarbled 				return 0;
10268fe5b6fSgarbled 			if (!strcmp(db_cmd[tmp].name, argv[0])) {
10368fe5b6fSgarbled 				(db_cmd[tmp].fcn)(argc, argv);
10468fe5b6fSgarbled 				break;
10568fe5b6fSgarbled 			}
10668fe5b6fSgarbled 			tmp++;
10768fe5b6fSgarbled 		}
10868fe5b6fSgarbled 		if (db_cmd[tmp].name == NULL)
10968fe5b6fSgarbled 			db_cmd_help(argc, argv);
11068fe5b6fSgarbled 	}
11168fe5b6fSgarbled 	return 0;
11268fe5b6fSgarbled }
11368fe5b6fSgarbled 
11468fe5b6fSgarbled int
db_atob(char * p)11568fe5b6fSgarbled db_atob(char *p)
11668fe5b6fSgarbled {
11768fe5b6fSgarbled 	int b = 0, width, tmp, exp, x = 0;
11868fe5b6fSgarbled 
11968fe5b6fSgarbled 	if (p[1] == 'x') {
12068fe5b6fSgarbled 		p += 2;
12168fe5b6fSgarbled 		x = 1;
12268fe5b6fSgarbled 	}
12368fe5b6fSgarbled 	width = strlen(p);
12468fe5b6fSgarbled 	while(width--) {
12568fe5b6fSgarbled 		exp = 1;
12668fe5b6fSgarbled 		for (tmp = 1; tmp <= width; tmp++)
12768fe5b6fSgarbled 			exp *= (x ? 16 : 10);
12868fe5b6fSgarbled 		if (*p >= '0' && *p <= '9') {
12968fe5b6fSgarbled 			tmp = *p - '0';
13068fe5b6fSgarbled 		} else {
13168fe5b6fSgarbled 			tmp = *p - 'a' + 10;
13268fe5b6fSgarbled 		}
13368fe5b6fSgarbled 		b += tmp * exp;
13468fe5b6fSgarbled 		p++;
13568fe5b6fSgarbled 	}
13668fe5b6fSgarbled 	return b;
13768fe5b6fSgarbled }
13868fe5b6fSgarbled 
13968fe5b6fSgarbled void
db_cmd_dump(int argc,char ** argv)14068fe5b6fSgarbled db_cmd_dump(int argc, char **argv)
14168fe5b6fSgarbled {
14268fe5b6fSgarbled 	char *p, *r, *pp;
14368fe5b6fSgarbled 	int mode, add, size, i;
14468fe5b6fSgarbled 
14568fe5b6fSgarbled 	switch (argc) {
14668fe5b6fSgarbled 	case 4:
14768fe5b6fSgarbled 		r = argv[1];
14868fe5b6fSgarbled 		switch (r[1]) {
14968fe5b6fSgarbled 		case 'b':
15068fe5b6fSgarbled 			mode = 1;
15168fe5b6fSgarbled 			break;
15268fe5b6fSgarbled 		case 'h':
15368fe5b6fSgarbled 			mode = 2;
15468fe5b6fSgarbled 			break;
15568fe5b6fSgarbled 		case 'w':
15668fe5b6fSgarbled 			mode = 4;
15768fe5b6fSgarbled 			break;
15868fe5b6fSgarbled 		default:
15968fe5b6fSgarbled 			goto out;
16068fe5b6fSgarbled 		}
16168fe5b6fSgarbled 		p = argv[2];
16268fe5b6fSgarbled 		pp = argv[3];
16368fe5b6fSgarbled 		break;
16468fe5b6fSgarbled 	case 3:
16568fe5b6fSgarbled 		mode = 4;
16668fe5b6fSgarbled 		p = argv[1];
16768fe5b6fSgarbled 		pp = argv[2];
16868fe5b6fSgarbled 		break;
16968fe5b6fSgarbled 	default:
17068fe5b6fSgarbled 		goto out;
17168fe5b6fSgarbled 	}
17268fe5b6fSgarbled 
17368fe5b6fSgarbled 	add = db_atob(p);
17468fe5b6fSgarbled 	size = db_atob(pp);
17568fe5b6fSgarbled 	i = 0;
17668fe5b6fSgarbled 	for (; size > 0;) {
17768fe5b6fSgarbled 		if (!i)
17868fe5b6fSgarbled 			printf("\n0x%x:", add);
17968fe5b6fSgarbled 		switch (mode) {
18068fe5b6fSgarbled 		case 1:
18168fe5b6fSgarbled 			printf(" %x", *(unsigned char *)add);
18268fe5b6fSgarbled 			add += 1;
18368fe5b6fSgarbled 			size -= 1;
18468fe5b6fSgarbled 			if (++i == 16)
18568fe5b6fSgarbled 				i = 0;
18668fe5b6fSgarbled 			break;
18768fe5b6fSgarbled 		case 2:
18868fe5b6fSgarbled 			printf(" %x", *(unsigned short *)add);
18968fe5b6fSgarbled 			add += 2;
19068fe5b6fSgarbled 			size -= 2;
19168fe5b6fSgarbled 			if (++i == 8)
19268fe5b6fSgarbled 				i = 0;
19368fe5b6fSgarbled 			break;
19468fe5b6fSgarbled 		case 4:
19568fe5b6fSgarbled 			printf(" %x", *(unsigned int *)add);
19668fe5b6fSgarbled 			add += 4;
19768fe5b6fSgarbled 			size -= 4;
19868fe5b6fSgarbled 			if (++i == 4)
19968fe5b6fSgarbled 				i = 0;
20068fe5b6fSgarbled 			break;
20168fe5b6fSgarbled 		}
20268fe5b6fSgarbled 	}
20368fe5b6fSgarbled 	printf("\n");
20468fe5b6fSgarbled 	return;
20568fe5b6fSgarbled 
20668fe5b6fSgarbled out:
20768fe5b6fSgarbled 	printf("dump [-b][-h][-w] address size\n");
20868fe5b6fSgarbled 	return;
20968fe5b6fSgarbled }
21068fe5b6fSgarbled 
21168fe5b6fSgarbled void
db_cmd_get(int argc,char ** argv)21268fe5b6fSgarbled db_cmd_get(int argc, char **argv)
21368fe5b6fSgarbled {
21468fe5b6fSgarbled 	char *p, *r;
21568fe5b6fSgarbled 	int mode, add;
21668fe5b6fSgarbled 
21768fe5b6fSgarbled 	switch (argc) {
21868fe5b6fSgarbled 	case 3:
21968fe5b6fSgarbled 		r = argv[1];
22068fe5b6fSgarbled 		switch (r[1]) {
22168fe5b6fSgarbled 		case 'b':
22268fe5b6fSgarbled 			mode = 1;
22368fe5b6fSgarbled 			break;
22468fe5b6fSgarbled 		case 'h':
22568fe5b6fSgarbled 			mode = 2;
22668fe5b6fSgarbled 			break;
22768fe5b6fSgarbled 		case 'w':
22868fe5b6fSgarbled 			mode = 4;
22968fe5b6fSgarbled 			break;
23068fe5b6fSgarbled 		default:
23168fe5b6fSgarbled 			goto out;
23268fe5b6fSgarbled 		}
23368fe5b6fSgarbled 		p = argv[2];
23468fe5b6fSgarbled 		break;
23568fe5b6fSgarbled 	case 2:
23668fe5b6fSgarbled 		mode = 4;
23768fe5b6fSgarbled 		p = argv[1];
23868fe5b6fSgarbled 		break;
23968fe5b6fSgarbled 	default:
24068fe5b6fSgarbled 		goto out;
24168fe5b6fSgarbled 	}
24268fe5b6fSgarbled 
24368fe5b6fSgarbled 	add = db_atob(p);
24468fe5b6fSgarbled 	printf("0x%x: ", add);
24568fe5b6fSgarbled 	switch (mode) {
24668fe5b6fSgarbled 	case 1:
24768fe5b6fSgarbled 		printf("0x%x", *(char *)add);
24868fe5b6fSgarbled 		break;
24968fe5b6fSgarbled 	case 2:
25068fe5b6fSgarbled 		printf("0x%x", *(short *)add);
25168fe5b6fSgarbled 		break;
25268fe5b6fSgarbled 	case 4:
25368fe5b6fSgarbled 		printf("0x%x", *(int *)add);
25468fe5b6fSgarbled 		break;
25568fe5b6fSgarbled 	}
25668fe5b6fSgarbled 	printf("\n");
25768fe5b6fSgarbled 	return;
25868fe5b6fSgarbled 
25968fe5b6fSgarbled out:
26068fe5b6fSgarbled 	printf("get [-b][-h][-w] address\n");
26168fe5b6fSgarbled 	return;
26268fe5b6fSgarbled }
26368fe5b6fSgarbled 
26468fe5b6fSgarbled void
db_cmd_put(int argc,char ** argv)26568fe5b6fSgarbled db_cmd_put(int argc, char **argv)
26668fe5b6fSgarbled {
26768fe5b6fSgarbled 	char *p, *r, *pp;
26868fe5b6fSgarbled 	int mode, add, data;
26968fe5b6fSgarbled 
27068fe5b6fSgarbled 	switch (argc) {
27168fe5b6fSgarbled 	case 4:
27268fe5b6fSgarbled 		r = argv[1];
27368fe5b6fSgarbled 		switch (r[1]) {
27468fe5b6fSgarbled 		case 'b':
27568fe5b6fSgarbled 			mode = 1;
27668fe5b6fSgarbled 			break;
27768fe5b6fSgarbled 		case 'h':
27868fe5b6fSgarbled 			mode = 2;
27968fe5b6fSgarbled 			break;
28068fe5b6fSgarbled 		case 'w':
28168fe5b6fSgarbled 			mode = 4;
28268fe5b6fSgarbled 			break;
28368fe5b6fSgarbled 		default:
28468fe5b6fSgarbled 			goto out;
28568fe5b6fSgarbled 		}
28668fe5b6fSgarbled 		p = argv[2];
28768fe5b6fSgarbled 		pp = argv[3];
28868fe5b6fSgarbled 		break;
28968fe5b6fSgarbled 	case 3:
29068fe5b6fSgarbled 		mode = 4;
29168fe5b6fSgarbled 		p = argv[1];
29268fe5b6fSgarbled 		pp = argv[2];
29368fe5b6fSgarbled 		break;
29468fe5b6fSgarbled 	default:
29568fe5b6fSgarbled 		goto out;
29668fe5b6fSgarbled 	}
29768fe5b6fSgarbled 
29868fe5b6fSgarbled 	add = db_atob(p);
29968fe5b6fSgarbled 	data = db_atob(pp);
30068fe5b6fSgarbled 	printf("0x%x: 0x%x", add, data);
30168fe5b6fSgarbled 	switch (mode) {
30268fe5b6fSgarbled 	case 1:
30368fe5b6fSgarbled 		*(char *)add = data;
30468fe5b6fSgarbled 		break;
30568fe5b6fSgarbled 	case 2:
30668fe5b6fSgarbled 		*(short *)add = data;
30768fe5b6fSgarbled 		break;
30868fe5b6fSgarbled 	case 4:
30968fe5b6fSgarbled 		*(int *)add = data;
31068fe5b6fSgarbled 		break;
31168fe5b6fSgarbled 	}
31268fe5b6fSgarbled 	printf("\n");
31368fe5b6fSgarbled 	return;
31468fe5b6fSgarbled 
31568fe5b6fSgarbled out:
31668fe5b6fSgarbled 	printf("put [-b][-h][-w] address data\n");
31768fe5b6fSgarbled 	return;
31868fe5b6fSgarbled }
31968fe5b6fSgarbled 
32068fe5b6fSgarbled #define STR(x) #x
32168fe5b6fSgarbled 
32268fe5b6fSgarbled #define	FUNC(x) \
32368fe5b6fSgarbled unsigned int mf ## x() { \
32468fe5b6fSgarbled 	unsigned int tmp; \
32568fe5b6fSgarbled 	__asm volatile (STR(mf ## x %0) : STR(=r)(tmp)); \
32668fe5b6fSgarbled 	return (tmp); \
32768fe5b6fSgarbled } \
32868fe5b6fSgarbled void mt ## x(unsigned int data) \
32968fe5b6fSgarbled { \
33068fe5b6fSgarbled 	__asm volatile (STR(mt ## x %0) :: STR(r)(data)); \
33168fe5b6fSgarbled } \
33268fe5b6fSgarbled 
33368fe5b6fSgarbled #define DEF(x) \
33468fe5b6fSgarbled 	{ #x, mf ## x, mt ## x }
33568fe5b6fSgarbled 
33668fe5b6fSgarbled FUNC(msr);
33768fe5b6fSgarbled 
33868fe5b6fSgarbled struct {
33968fe5b6fSgarbled 	char *op;
34068fe5b6fSgarbled 	unsigned int (*mf)(void);
34168fe5b6fSgarbled 	void (*mt)(unsigned int);
34268fe5b6fSgarbled } mreg [] = {
34368fe5b6fSgarbled 	DEF(msr),
34468fe5b6fSgarbled 	{ NULL, NULL, NULL },
34568fe5b6fSgarbled };
34668fe5b6fSgarbled 
34768fe5b6fSgarbled void
db_cmd_mf(int argc,char ** argv)34868fe5b6fSgarbled db_cmd_mf(int argc, char **argv)
34968fe5b6fSgarbled {
35068fe5b6fSgarbled 	int i = 0;
35168fe5b6fSgarbled 
35268fe5b6fSgarbled 	if (argc != 2) {
35368fe5b6fSgarbled 		printf("mf register\nregister:");
35468fe5b6fSgarbled 		while (mreg[i].op != NULL)
35568fe5b6fSgarbled 			printf(" %s", mreg[i++].op);
35668fe5b6fSgarbled 		printf("\n");
35768fe5b6fSgarbled 		return;
35868fe5b6fSgarbled 	}
35968fe5b6fSgarbled 
36068fe5b6fSgarbled 	while (mreg[i].op != NULL) {
36168fe5b6fSgarbled 		if (!strcmp(mreg[i].op, argv[1])) {
36268fe5b6fSgarbled 			printf(" 0x%x\n", (mreg[i].mf)());
36368fe5b6fSgarbled 			break;
36468fe5b6fSgarbled 		}
36568fe5b6fSgarbled 		i++;
36668fe5b6fSgarbled 	}
36768fe5b6fSgarbled }
36868fe5b6fSgarbled 
36968fe5b6fSgarbled void
db_cmd_mt(int argc,char ** argv)37068fe5b6fSgarbled db_cmd_mt(int argc, char **argv)
37168fe5b6fSgarbled {
37268fe5b6fSgarbled 	int i = 0;
37368fe5b6fSgarbled 
37468fe5b6fSgarbled 	if (argc != 3) {
37568fe5b6fSgarbled 		printf("mt register data\nregister:");
37668fe5b6fSgarbled 		while (mreg[i].op != NULL)
37768fe5b6fSgarbled 			printf(" %s", mreg[i++].op);
37868fe5b6fSgarbled 		printf("\n");
37968fe5b6fSgarbled 		return;
38068fe5b6fSgarbled 	}
38168fe5b6fSgarbled 
38268fe5b6fSgarbled 	while (mreg[i].op != NULL) {
38368fe5b6fSgarbled 		if (!strcmp(mreg[i].op, argv[1])) {
38468fe5b6fSgarbled 			(mreg[i].mt)((unsigned int)db_atob(argv[2]));
38568fe5b6fSgarbled 			printf(" 0x%x\n", db_atob(argv[2]));
38668fe5b6fSgarbled 			break;
38768fe5b6fSgarbled 		}
38868fe5b6fSgarbled 		i++;
38968fe5b6fSgarbled 	}
39068fe5b6fSgarbled }
39168fe5b6fSgarbled 
39268fe5b6fSgarbled void
db_cmd_help(int argc,char ** argv)39368fe5b6fSgarbled db_cmd_help(int argc, char **argv)
39468fe5b6fSgarbled {
39568fe5b6fSgarbled 	int i = 0;
39668fe5b6fSgarbled 
39768fe5b6fSgarbled 	while (db_cmd[i].name != NULL)
39868fe5b6fSgarbled 		printf("%s, ", db_cmd[i++].name);
39968fe5b6fSgarbled 	printf("continue\n");
40068fe5b6fSgarbled }
40168fe5b6fSgarbled 
40268fe5b6fSgarbled #endif /* DBMONITOR */
403