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