1*2357cddaSdholland /* $NetBSD: monitor.c,v 1.9 2016/06/11 06:38:50 dholland Exp $ */
237eb9eebSnonaka
337eb9eebSnonaka /*-
437eb9eebSnonaka * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
537eb9eebSnonaka * All rights reserved.
637eb9eebSnonaka *
737eb9eebSnonaka * This code is derived from software contributed to The NetBSD Foundation
837eb9eebSnonaka * by Kazuki Sakamoto.
937eb9eebSnonaka *
1037eb9eebSnonaka * Redistribution and use in source and binary forms, with or without
1137eb9eebSnonaka * modification, are permitted provided that the following conditions
1237eb9eebSnonaka * are met:
1337eb9eebSnonaka * 1. Redistributions of source code must retain the above copyright
1437eb9eebSnonaka * notice, this list of conditions and the following disclaimer.
1537eb9eebSnonaka * 2. Redistributions in binary form must reproduce the above copyright
1637eb9eebSnonaka * notice, this list of conditions and the following disclaimer in the
1737eb9eebSnonaka * documentation and/or other materials provided with the distribution.
1837eb9eebSnonaka *
1937eb9eebSnonaka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2037eb9eebSnonaka * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2137eb9eebSnonaka * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2237eb9eebSnonaka * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2337eb9eebSnonaka * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2437eb9eebSnonaka * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2537eb9eebSnonaka * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2637eb9eebSnonaka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2737eb9eebSnonaka * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2837eb9eebSnonaka * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2937eb9eebSnonaka * POSSIBILITY OF SUCH DAMAGE.
3037eb9eebSnonaka */
3137eb9eebSnonaka
327c009730Sgarbled #ifdef DBMONITOR
337c009730Sgarbled
3437eb9eebSnonaka #include <lib/libsa/stand.h>
3555759344She #include <lib/libkern/libkern.h>
3637eb9eebSnonaka #include "boot.h"
3737eb9eebSnonaka
3837eb9eebSnonaka #define NULL 0
3937eb9eebSnonaka
4037eb9eebSnonaka extern int errno;
4137eb9eebSnonaka extern char *name;
4237eb9eebSnonaka
4378fba760Sgarbled void db_cmd_dump(int, char **);
4478fba760Sgarbled void db_cmd_get(int, char **);
4578fba760Sgarbled void db_cmd_mf(int, char **);
4678fba760Sgarbled void db_cmd_mt(int, char **);
4778fba760Sgarbled void db_cmd_put(int, char **);
4878fba760Sgarbled void db_cmd_help(int, char **);
4937eb9eebSnonaka
504222db0cSwiz unsigned int mfmsr(void);
5178fba760Sgarbled void mtmsr(unsigned int);
5237eb9eebSnonaka
5378fba760Sgarbled int db_atob(char *);
5437eb9eebSnonaka
5537eb9eebSnonaka struct {
5637eb9eebSnonaka char *name;
5737eb9eebSnonaka void (*fcn)(int, char **);
5837eb9eebSnonaka } db_cmd[] = {
5937eb9eebSnonaka { "dump", db_cmd_dump },
6037eb9eebSnonaka { "get", db_cmd_get },
6137eb9eebSnonaka { "mf", db_cmd_mf },
6237eb9eebSnonaka { "mt", db_cmd_mt },
6337eb9eebSnonaka { "put", db_cmd_put },
6437eb9eebSnonaka { "help", db_cmd_help },
6537eb9eebSnonaka { NULL, NULL },
6637eb9eebSnonaka };
6737eb9eebSnonaka
6837eb9eebSnonaka int
db_monitor(void)6978fba760Sgarbled db_monitor(void)
7037eb9eebSnonaka {
7137eb9eebSnonaka int tmp;
7237eb9eebSnonaka int argc, flag;
7337eb9eebSnonaka char *p, *argv[16];
7437eb9eebSnonaka char line[1024];
7537eb9eebSnonaka
7637eb9eebSnonaka while(1) {
7737eb9eebSnonaka printf("db> ");
78*2357cddaSdholland kgets(line, sizeof(line));
7937eb9eebSnonaka
8037eb9eebSnonaka flag = 0;
8137eb9eebSnonaka for(p = line, argc = 0; *p != '\0'; p++) {
8237eb9eebSnonaka if (*p != ' ' && *p != '\t') {
8337eb9eebSnonaka if (!flag) {
8437eb9eebSnonaka flag++;
8537eb9eebSnonaka argv[argc++] = p;
8637eb9eebSnonaka }
8737eb9eebSnonaka } else {
8837eb9eebSnonaka if (flag) {
8937eb9eebSnonaka *p = '\0';
9037eb9eebSnonaka flag = 0;
9137eb9eebSnonaka }
9237eb9eebSnonaka }
9337eb9eebSnonaka }
9437eb9eebSnonaka
9537eb9eebSnonaka if (argc == 0)
9637eb9eebSnonaka continue;
9737eb9eebSnonaka
9837eb9eebSnonaka tmp = 0;
9937eb9eebSnonaka while (db_cmd[tmp].name != NULL) {
10037eb9eebSnonaka if (!strcmp("continue", argv[0]))
10137eb9eebSnonaka return 0;
10237eb9eebSnonaka if (!strcmp(db_cmd[tmp].name, argv[0])) {
10337eb9eebSnonaka (db_cmd[tmp].fcn)(argc, argv);
10437eb9eebSnonaka break;
10537eb9eebSnonaka }
10637eb9eebSnonaka tmp++;
10737eb9eebSnonaka }
10837eb9eebSnonaka if (db_cmd[tmp].name == NULL)
10937eb9eebSnonaka db_cmd_help(argc, argv);
11037eb9eebSnonaka }
11137eb9eebSnonaka return 0;
11237eb9eebSnonaka }
11337eb9eebSnonaka
11437eb9eebSnonaka int
db_atob(char * p)11578fba760Sgarbled db_atob(char *p)
11637eb9eebSnonaka {
11737eb9eebSnonaka int b = 0, width, tmp, exp, x = 0;
11837eb9eebSnonaka
11937eb9eebSnonaka if (p[1] == 'x') {
12037eb9eebSnonaka p += 2;
12137eb9eebSnonaka x = 1;
12237eb9eebSnonaka }
12337eb9eebSnonaka width = strlen(p);
12437eb9eebSnonaka while(width--) {
12537eb9eebSnonaka exp = 1;
12637eb9eebSnonaka for (tmp = 1; tmp <= width; tmp++)
12737eb9eebSnonaka exp *= (x ? 16 : 10);
12837eb9eebSnonaka if (*p >= '0' && *p <= '9') {
12937eb9eebSnonaka tmp = *p - '0';
13037eb9eebSnonaka } else {
13137eb9eebSnonaka tmp = *p - 'a' + 10;
13237eb9eebSnonaka }
13337eb9eebSnonaka b += tmp * exp;
13437eb9eebSnonaka p++;
13537eb9eebSnonaka }
13637eb9eebSnonaka return b;
13737eb9eebSnonaka }
13837eb9eebSnonaka
13937eb9eebSnonaka void
db_cmd_dump(int argc,char ** argv)14078fba760Sgarbled db_cmd_dump(int argc, char **argv)
14137eb9eebSnonaka {
14237eb9eebSnonaka char *p, *r, *pp;
14337eb9eebSnonaka int mode, add, size, i;
14437eb9eebSnonaka
14537eb9eebSnonaka switch (argc) {
14637eb9eebSnonaka case 4:
14737eb9eebSnonaka r = argv[1];
14837eb9eebSnonaka switch (r[1]) {
14937eb9eebSnonaka case 'b':
15037eb9eebSnonaka mode = 1;
15137eb9eebSnonaka break;
15237eb9eebSnonaka case 'h':
15337eb9eebSnonaka mode = 2;
15437eb9eebSnonaka break;
15537eb9eebSnonaka case 'w':
15637eb9eebSnonaka mode = 4;
15737eb9eebSnonaka break;
15837eb9eebSnonaka default:
15937eb9eebSnonaka goto out;
16037eb9eebSnonaka }
16137eb9eebSnonaka p = argv[2];
16237eb9eebSnonaka pp = argv[3];
16337eb9eebSnonaka break;
16437eb9eebSnonaka case 3:
16537eb9eebSnonaka mode = 4;
16637eb9eebSnonaka p = argv[1];
16737eb9eebSnonaka pp = argv[2];
16837eb9eebSnonaka break;
16937eb9eebSnonaka default:
17037eb9eebSnonaka goto out;
17137eb9eebSnonaka }
17237eb9eebSnonaka
17337eb9eebSnonaka add = db_atob(p);
17437eb9eebSnonaka size = db_atob(pp);
17537eb9eebSnonaka i = 0;
17637eb9eebSnonaka for (; size > 0;) {
17737eb9eebSnonaka if (!i)
17837eb9eebSnonaka printf("\n0x%x:", add);
17937eb9eebSnonaka switch (mode) {
18037eb9eebSnonaka case 1:
18137eb9eebSnonaka printf(" %x", *(unsigned char *)add);
18237eb9eebSnonaka add += 1;
18337eb9eebSnonaka size -= 1;
18437eb9eebSnonaka if (++i == 16)
18537eb9eebSnonaka i = 0;
18637eb9eebSnonaka break;
18737eb9eebSnonaka case 2:
18837eb9eebSnonaka printf(" %x", *(unsigned short *)add);
18937eb9eebSnonaka add += 2;
19037eb9eebSnonaka size -= 2;
19137eb9eebSnonaka if (++i == 8)
19237eb9eebSnonaka i = 0;
19337eb9eebSnonaka break;
19437eb9eebSnonaka case 4:
19537eb9eebSnonaka printf(" %x", *(unsigned int *)add);
19637eb9eebSnonaka add += 4;
19737eb9eebSnonaka size -= 4;
19837eb9eebSnonaka if (++i == 4)
19937eb9eebSnonaka i = 0;
20037eb9eebSnonaka break;
20137eb9eebSnonaka }
20237eb9eebSnonaka }
20337eb9eebSnonaka printf("\n");
20437eb9eebSnonaka return;
20537eb9eebSnonaka
20637eb9eebSnonaka out:
20737eb9eebSnonaka printf("dump [-b][-h][-w] address size\n");
20837eb9eebSnonaka return;
20937eb9eebSnonaka }
21037eb9eebSnonaka
21137eb9eebSnonaka void
db_cmd_get(int argc,char ** argv)21278fba760Sgarbled db_cmd_get(int argc, char **argv)
21337eb9eebSnonaka {
21437eb9eebSnonaka char *p, *r;
21537eb9eebSnonaka int mode, add;
21637eb9eebSnonaka
21737eb9eebSnonaka switch (argc) {
21837eb9eebSnonaka case 3:
21937eb9eebSnonaka r = argv[1];
22037eb9eebSnonaka switch (r[1]) {
22137eb9eebSnonaka case 'b':
22237eb9eebSnonaka mode = 1;
22337eb9eebSnonaka break;
22437eb9eebSnonaka case 'h':
22537eb9eebSnonaka mode = 2;
22637eb9eebSnonaka break;
22737eb9eebSnonaka case 'w':
22837eb9eebSnonaka mode = 4;
22937eb9eebSnonaka break;
23037eb9eebSnonaka default:
23137eb9eebSnonaka goto out;
23237eb9eebSnonaka }
23337eb9eebSnonaka p = argv[2];
23437eb9eebSnonaka break;
23537eb9eebSnonaka case 2:
23637eb9eebSnonaka mode = 4;
23737eb9eebSnonaka p = argv[1];
23837eb9eebSnonaka break;
23937eb9eebSnonaka default:
24037eb9eebSnonaka goto out;
24137eb9eebSnonaka }
24237eb9eebSnonaka
24337eb9eebSnonaka add = db_atob(p);
24437eb9eebSnonaka printf("0x%x: ", add);
24537eb9eebSnonaka switch (mode) {
24637eb9eebSnonaka case 1:
24737eb9eebSnonaka printf("0x%x", *(char *)add);
24837eb9eebSnonaka break;
24937eb9eebSnonaka case 2:
25037eb9eebSnonaka printf("0x%x", *(short *)add);
25137eb9eebSnonaka break;
25237eb9eebSnonaka case 4:
25337eb9eebSnonaka printf("0x%x", *(int *)add);
25437eb9eebSnonaka break;
25537eb9eebSnonaka }
25637eb9eebSnonaka printf("\n");
25737eb9eebSnonaka return;
25837eb9eebSnonaka
25937eb9eebSnonaka out:
26037eb9eebSnonaka printf("get [-b][-h][-w] address\n");
26137eb9eebSnonaka return;
26237eb9eebSnonaka }
26337eb9eebSnonaka
26437eb9eebSnonaka void
db_cmd_put(int argc,char ** argv)26578fba760Sgarbled db_cmd_put(int argc, char **argv)
26637eb9eebSnonaka {
26737eb9eebSnonaka char *p, *r, *pp;
26837eb9eebSnonaka int mode, add, data;
26937eb9eebSnonaka
27037eb9eebSnonaka switch (argc) {
27137eb9eebSnonaka case 4:
27237eb9eebSnonaka r = argv[1];
27337eb9eebSnonaka switch (r[1]) {
27437eb9eebSnonaka case 'b':
27537eb9eebSnonaka mode = 1;
27637eb9eebSnonaka break;
27737eb9eebSnonaka case 'h':
27837eb9eebSnonaka mode = 2;
27937eb9eebSnonaka break;
28037eb9eebSnonaka case 'w':
28137eb9eebSnonaka mode = 4;
28237eb9eebSnonaka break;
28337eb9eebSnonaka default:
28437eb9eebSnonaka goto out;
28537eb9eebSnonaka }
28637eb9eebSnonaka p = argv[2];
28737eb9eebSnonaka pp = argv[3];
28837eb9eebSnonaka break;
28937eb9eebSnonaka case 3:
29037eb9eebSnonaka mode = 4;
29137eb9eebSnonaka p = argv[1];
29237eb9eebSnonaka pp = argv[2];
29337eb9eebSnonaka break;
29437eb9eebSnonaka default:
29537eb9eebSnonaka goto out;
29637eb9eebSnonaka }
29737eb9eebSnonaka
29837eb9eebSnonaka add = db_atob(p);
29937eb9eebSnonaka data = db_atob(pp);
30037eb9eebSnonaka printf("0x%x: 0x%x", add, data);
30137eb9eebSnonaka switch (mode) {
30237eb9eebSnonaka case 1:
30337eb9eebSnonaka *(char *)add = data;
30437eb9eebSnonaka break;
30537eb9eebSnonaka case 2:
30637eb9eebSnonaka *(short *)add = data;
30737eb9eebSnonaka break;
30837eb9eebSnonaka case 4:
30937eb9eebSnonaka *(int *)add = data;
31037eb9eebSnonaka break;
31137eb9eebSnonaka }
31237eb9eebSnonaka printf("\n");
31337eb9eebSnonaka return;
31437eb9eebSnonaka
31537eb9eebSnonaka out:
31637eb9eebSnonaka printf("put [-b][-h][-w] address data\n");
31737eb9eebSnonaka return;
31837eb9eebSnonaka }
31937eb9eebSnonaka
32037eb9eebSnonaka #define STR(x) #x
32137eb9eebSnonaka
32237eb9eebSnonaka #define FUNC(x) \
32337eb9eebSnonaka unsigned int mf ## x() { \
32437eb9eebSnonaka unsigned int tmp; \
3252d65de24Sperry __asm volatile (STR(mf ## x %0) : STR(=r)(tmp)); \
32637eb9eebSnonaka return (tmp); \
32737eb9eebSnonaka } \
32878fba760Sgarbled void mt ## x(unsigned int data) \
32937eb9eebSnonaka { \
3302d65de24Sperry __asm volatile (STR(mt ## x %0) :: STR(r)(data)); \
33137eb9eebSnonaka } \
33237eb9eebSnonaka
33337eb9eebSnonaka #define DEF(x) \
33437eb9eebSnonaka { #x, mf ## x, mt ## x }
33537eb9eebSnonaka
33637eb9eebSnonaka FUNC(msr);
33737eb9eebSnonaka
33837eb9eebSnonaka struct {
33937eb9eebSnonaka char *op;
34037eb9eebSnonaka unsigned int (*mf)(void);
34137eb9eebSnonaka void (*mt)(unsigned int);
34237eb9eebSnonaka } mreg [] = {
34337eb9eebSnonaka DEF(msr),
34437eb9eebSnonaka { NULL, NULL, NULL },
34537eb9eebSnonaka };
34637eb9eebSnonaka
34737eb9eebSnonaka void
db_cmd_mf(int argc,char ** argv)34878fba760Sgarbled db_cmd_mf(int argc, char **argv)
34937eb9eebSnonaka {
35037eb9eebSnonaka int i = 0;
35137eb9eebSnonaka
35237eb9eebSnonaka if (argc != 2) {
35337eb9eebSnonaka printf("mf register\nregister:");
35437eb9eebSnonaka while (mreg[i].op != NULL)
35537eb9eebSnonaka printf(" %s", mreg[i++].op);
35637eb9eebSnonaka printf("\n");
35737eb9eebSnonaka return;
35837eb9eebSnonaka }
35937eb9eebSnonaka
36037eb9eebSnonaka while (mreg[i].op != NULL) {
36137eb9eebSnonaka if (!strcmp(mreg[i].op, argv[1])) {
36237eb9eebSnonaka printf(" 0x%x\n", (mreg[i].mf)());
36337eb9eebSnonaka break;
36437eb9eebSnonaka }
36537eb9eebSnonaka i++;
36637eb9eebSnonaka }
36737eb9eebSnonaka }
36837eb9eebSnonaka
36937eb9eebSnonaka void
db_cmd_mt(int argc,char ** argv)37078fba760Sgarbled db_cmd_mt(int argc, char **argv)
37137eb9eebSnonaka {
37237eb9eebSnonaka int i = 0;
37337eb9eebSnonaka
37437eb9eebSnonaka if (argc != 3) {
37537eb9eebSnonaka printf("mt register data\nregister:");
37637eb9eebSnonaka while (mreg[i].op != NULL)
37737eb9eebSnonaka printf(" %s", mreg[i++].op);
37837eb9eebSnonaka printf("\n");
37937eb9eebSnonaka return;
38037eb9eebSnonaka }
38137eb9eebSnonaka
38237eb9eebSnonaka while (mreg[i].op != NULL) {
38337eb9eebSnonaka if (!strcmp(mreg[i].op, argv[1])) {
38437eb9eebSnonaka (mreg[i].mt)((unsigned int)db_atob(argv[2]));
38537eb9eebSnonaka printf(" 0x%x\n", db_atob(argv[2]));
38637eb9eebSnonaka break;
38737eb9eebSnonaka }
38837eb9eebSnonaka i++;
38937eb9eebSnonaka }
39037eb9eebSnonaka }
39137eb9eebSnonaka
39237eb9eebSnonaka void
db_cmd_help(int argc,char ** argv)39378fba760Sgarbled db_cmd_help(int argc, char **argv)
39437eb9eebSnonaka {
39537eb9eebSnonaka int i = 0;
39637eb9eebSnonaka
39737eb9eebSnonaka while (db_cmd[i].name != NULL)
39837eb9eebSnonaka printf("%s, ", db_cmd[i++].name);
39937eb9eebSnonaka printf("continue\n");
40037eb9eebSnonaka }
4017c009730Sgarbled
4027c009730Sgarbled #endif /* DBMONITOR */
403