Home | History | Annotate | Line # | Download | only in standtest
test.c revision 1.1
      1 /* $NetBSD: test.c,v 1.1 1999/04/11 03:38:51 cgd Exp $ */
      2 
      3 /*
      4  * Copyright (c) 1999 Christopher G. Demetriou.  All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. All advertising materials mentioning features or use of this software
     15  *    must display the following acknowledgement:
     16  *      This product includes software developed by Christopher G. Demetriou
     17  *	for the NetBSD Project.
     18  * 4. The name of the author may not be used to endorse or promote products
     19  *    derived from this software without specific prior written permission
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 #include <lib/libsa/stand.h>
     34 #include <lib/libkern/libkern.h>
     35 #include <machine/autoconf.h>
     36 #include <machine/rpb.h>
     37 
     38 #include "../common/common.h"
     39 
     40 struct cmdtab {
     41 	const char *cmd;
     42 	void (*fn)(const char *buf);
     43 };
     44 
     45 int		done;
     46 unsigned long	arg_pfn, arg_ptb, arg_bim, arg_bip, arg_biv;
     47 
     48 const char *advance_past_space(const char *buf);
     49 int	dispatch_cmd(const char *buf, const struct cmdtab *cmds);
     50 #define		DISPATCH_CMD_NOCMD	0
     51 #define		DISPATCH_CMD_MATCHED	1
     52 #define		DISPATCH_CMD_NOMATCH	2
     53 #define		DISPATCH_CMD_AMBIGUOUS	3
     54 void	print_cmds(const struct cmdtab *cmds, const char *match,
     55 	    size_t matchlen);
     56 void	print_stringarray(const char *s, size_t maxlen);
     57 
     58 void	toplevel_db(const char *buf);
     59 void	toplevel_dl(const char *buf);
     60 void	toplevel_dq(const char *buf);
     61 void	toplevel_dw(const char *buf);
     62 void	toplevel_halt(const char *buf);
     63 void	toplevel_help(const char *buf);
     64 void	toplevel_show(const char *buf);
     65 
     66 void	show_args(const char *buf);
     67 void	show_bootinfo(const char *buf);
     68 void	show_pt(const char *buf);
     69 void	show_rpb(const char *buf);
     70 
     71 void
     72 main(pfn, ptb, bim, bip, biv)
     73 	unsigned long pfn;	/* first free PFN number */
     74 	unsigned long ptb;	/* PFN of current level 1 page table */
     75 	unsigned long bim;	/* bootinfo magic */
     76 	unsigned long bip;	/* bootinfo pointer */
     77 	unsigned long biv;	/* bootinfo version */
     78 {
     79 	char input_buf[512];
     80 	const struct cmdtab toplevel_cmds[] = {
     81 	    {	"?",		toplevel_help,	},
     82 #if 0 /* XXX notyet */
     83 	    {	"db",		toplevel_db,	},
     84 	    {	"dl",		toplevel_dl,	},
     85 	    {	"dq",		toplevel_dq,	},
     86 	    {	"dw",		toplevel_dw,	},
     87 #endif
     88 	    {	"quit",		toplevel_halt,	},
     89 	    {	"show",		toplevel_show,	},
     90 	    {	NULL,				},
     91 	};
     92 
     93 	printf("\n");
     94 	printf("NetBSD/alpha " NETBSD_VERS
     95 	    " Standalone Test Program, Revision %s\n", bootprog_rev);
     96 	printf("(%s, %s)\n", bootprog_maker, bootprog_date);
     97 	printf("\n");
     98 
     99 	arg_pfn = pfn;
    100 	arg_ptb = ptb;
    101 	arg_bim = bim;
    102 	arg_bip = bip;
    103 	arg_biv = biv;
    104 
    105 	printf("Enter '?' for help.\n");
    106 	printf("\n");
    107 
    108 	do {
    109 		printf("test> ");
    110 		gets(input_buf);
    111 
    112 		dispatch_cmd(input_buf, toplevel_cmds);
    113 	} while (!done);
    114 
    115 	printf("\n");
    116 	printf("halting...\n");
    117 	halt();
    118 }
    119 
    120 const char *
    121 advance_past_space(const char *buf)
    122 {
    123 
    124 	/* advance past white space. */
    125 	while (isspace(*buf))
    126 		buf++;
    127 
    128 	if (*buf == '\0')
    129 		return NULL;
    130 	return buf;
    131 }
    132 
    133 int
    134 dispatch_cmd(const char *buf, const struct cmdtab *cmds)
    135 {
    136 	const struct cmdtab *try, *winner;
    137 	size_t nonwhitespace, i;
    138 	unsigned int nmatches;
    139 	const char *pre, *post;
    140 	int rv;
    141 
    142 	/* advance past white space. */
    143 	buf = advance_past_space(buf);
    144 	if (buf == NULL)
    145 		return (DISPATCH_CMD_NOCMD);
    146 
    147 	/* find how much non-white space there is. */
    148 	nonwhitespace = 0;
    149 	while ((buf[nonwhitespace] != '\0') && !isspace(buf[nonwhitespace]))
    150 		nonwhitespace++;
    151 
    152 	/* at this point, nonwhitespace should always be non-zero */
    153 	if (nonwhitespace == 0) {
    154 		printf("assertion failed: dispatch_cmd: nonwhitespace == 0\n");
    155 		halt();
    156 	}
    157 
    158 	/* see how many matches there were. */
    159 	for (nmatches = 0, try = cmds;
    160 	    try != NULL && try->cmd != NULL;
    161 	    try++) {
    162 		if (strncmp(buf, try->cmd, nonwhitespace) == 0) {
    163 			winner = try;
    164 			nmatches++;
    165 		}
    166 	}
    167 
    168 	if (nmatches == 1) {
    169 		(*winner->fn)(buf + nonwhitespace);
    170 		return (DISPATCH_CMD_MATCHED);
    171 	} else if (nmatches == 0) {
    172 		pre = "invalid command word";
    173 		post = "allowed words";
    174 		rv = DISPATCH_CMD_NOMATCH;
    175 	} else {
    176 		pre = "ambiguous command word";
    177 		post = "matches";
    178 		rv = DISPATCH_CMD_AMBIGUOUS;
    179 	}
    180 
    181 	printf("%s \"", pre);
    182 	print_stringarray(buf, nonwhitespace);
    183 	printf("\", %s:\n", post);
    184 
    185 	/* print commands.  if no match, print all commands. */
    186 	print_cmds(cmds, buf, rv == DISPATCH_CMD_NOMATCH ? 0 : nonwhitespace);
    187 	return (rv);
    188 }
    189 
    190 void
    191 print_cmds(const struct cmdtab *cmds, const char *match, size_t matchlen)
    192 {
    193 	const struct cmdtab *try;
    194 
    195 	printf("    ");
    196 	for (try = cmds; try != NULL && try->cmd != NULL; try++) {
    197 		if (strncmp(match, try->cmd, matchlen) == 0)
    198 			printf("%s%s", try != cmds ? ", " : "", try->cmd);
    199 	}
    200 	printf("\n");
    201 }
    202 
    203 void
    204 print_stringarray(const char *s, size_t maxlen)
    205 {
    206 	size_t i;
    207 
    208 	for (i = 0; (i < maxlen) && (*s != '\0'); i++, s++)
    209 		putchar(*s);
    210 }
    211 
    212 void
    213 warn_ignored_args(const char *buf, const char *cmd)
    214 {
    215 
    216 	if (advance_past_space(buf) != NULL)
    217 		printf("WARNING: extra arguments to \"%s\" command ignored\n",
    218 		    cmd);
    219 }
    220 
    221 /*
    222  * Top-level Commands
    223  */
    224 
    225 void
    226 toplevel_db(const char *buf)
    227 {
    228 
    229 	printf("\"db\" not yet implemented\n");
    230 }
    231 
    232 void
    233 toplevel_dl(const char *buf)
    234 {
    235 
    236 	printf("\"dl\" not yet implemented\n");
    237 }
    238 
    239 void
    240 toplevel_dq(const char *buf)
    241 {
    242 
    243 	printf("\"dq\" not yet implemented\n");
    244 }
    245 
    246 void
    247 toplevel_dw(const char *buf)
    248 {
    249 
    250 	printf("\"dw\" not yet implemented\n");
    251 }
    252 
    253 void
    254 toplevel_halt(const char *buf)
    255 {
    256 
    257 	warn_ignored_args(buf, "halt");
    258 
    259 	done = 1;
    260 }
    261 
    262 void
    263 toplevel_help(const char *buf)
    264 {
    265 
    266 	warn_ignored_args(buf, "?");
    267 
    268 	printf("Standalone Test Program Commands:\n");
    269 	printf("    ?                       print help\n");
    270 	printf("    quit                    return to console\n");
    271 #if 0 /* XXX notyet */
    272 	printf("    db startaddr [count]    display memory (8-bit units)\n");
    273 	printf("    dw startaddr [count]    display memory (16-bit units)\n");
    274 	printf("    dl startaddr [count]    display memory (32-bit units)\n");
    275 	printf("    dq startaddr [count]    display memory (64-bit units)\n");
    276 #endif
    277 	printf("    show args               show test program arguments\n");
    278 	printf("    show bootinfo           show bootstrap bootinfo\n");
    279 #if 0 /* XXX notyet */
    280 	printf("    show pt [startaddr [endaddr]]\n");
    281 	printf("                            show page tables\n");
    282 	printf("    show rpb                show the HWRPB\n");
    283 	printf("\n");
    284 	printf("If optional \"count\" argument is omitted, 1 is used.\n");
    285 	printf("If optional \"startaddr\" argument is omitted, "
    286 	    "0x0 is used.\n");
    287 	printf("If optional \"endaddr\" argument is omitted, "
    288 	    "0xffffffffffffffff is used.\n");
    289 #endif
    290 }
    291 
    292 void
    293 toplevel_show(const char *buf)
    294 {
    295 	const struct cmdtab show_cmds[] = {
    296 	    {	"args",		show_args,	},
    297 	    {	"bootinfo",	show_bootinfo,	},
    298 #if 0 /* XXX notyet */
    299 	    {	"pt",		show_pt,	},
    300 	    {	"rpb",		show_rpb,	},
    301 #endif
    302 	    {	NULL,				},
    303 	};
    304 
    305 	if (dispatch_cmd(buf, show_cmds) == DISPATCH_CMD_NOCMD) {
    306 		printf("no subcommand given.  allowed subcommands:\n");
    307 		print_cmds(show_cmds, NULL, 0);
    308 	}
    309 }
    310 
    311 
    312 /*
    313  * Show Commands
    314  */
    315 
    316 void
    317 show_args(const char *buf)
    318 {
    319 
    320 	warn_ignored_args(buf, "show args");
    321 
    322 	printf("first free page frame number:       0x%lx\n", arg_pfn);
    323 	printf("page table base page frame number:  0x%lx\n", arg_ptb);
    324 	printf("bootinfo magic number:              0x%lx\n", arg_bim);
    325 	printf("bootinfo pointer:                   0x%lx\n", arg_bip);
    326 	printf("bootinfo version:                   0x%lx\n", arg_biv);
    327 }
    328 
    329 void
    330 show_bootinfo(const char *buf)
    331 {
    332 	u_long biv, bip;
    333 
    334 	warn_ignored_args(buf, "show bootinfo");
    335 
    336 	if (arg_bim != BOOTINFO_MAGIC) {
    337 		printf("bootinfo magic number not present; no bootinfo\n");
    338 		return;
    339 	}
    340 
    341 	bip = arg_bip;
    342 	biv = arg_biv;
    343 	if (biv == 0) {
    344 		biv = *(u_long *)bip;
    345 		bip += 8;
    346 	}
    347 
    348 	printf("bootinfo version: %d\n", biv);
    349 	printf("bootinfo pointer: %p\n", (void *)bip);
    350 	printf("bootinfo data:\n");
    351 
    352 	switch (biv) {
    353 	case 1: {
    354 		const struct bootinfo_v1 *v1p;
    355 		int i;
    356 
    357 		v1p = (const struct bootinfo_v1 *)bip;
    358 		printf("    ssym:          0x%lx\n", v1p->ssym);
    359 		printf("    esym:          0x%lx\n", v1p->esym);
    360 		printf("    boot flags:    \"");
    361 		print_stringarray(v1p->boot_flags, sizeof v1p->boot_flags);
    362 		printf("\"\n");
    363 		printf("    booted kernel: \"", v1p->esym);
    364 		print_stringarray(v1p->booted_kernel,
    365 		    sizeof v1p->booted_kernel);
    366 		printf("\"\n");
    367 		printf("    hwrpb:         %p\n", v1p->hwrpb);
    368 		printf("    hwrpbsize:     0x%lx\n", v1p->hwrpbsize);
    369 		printf("    cngetc:        %p\n", v1p->cngetc);
    370 		printf("    cnputc:        %p\n", v1p->cnputc);
    371 		printf("    cnpollc:       %p\n", v1p->cnpollc);
    372 		for (i = 0; i < (sizeof v1p->pad / sizeof v1p->pad[0]); i++) {
    373 			printf("    pad[%d]:        0x%lx\n", i, v1p->pad[i]);
    374 		}
    375 		break;
    376 	}
    377 	default:
    378 		printf("    unknown bootinfo version, cannot print data\n");
    379 		break;
    380 	}
    381 }
    382 
    383 void
    384 show_pt(const char *buf)
    385 {
    386 
    387 	/* has additional args! */
    388 	printf("\"show pt\" not yet implemented\n");
    389 }
    390 
    391 void
    392 show_rpb(const char *buf)
    393 {
    394 
    395 	warn_ignored_args(buf, "show pt");
    396 
    397 	printf("\"show rpb\" not yet implemented\n");
    398 }
    399