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