test.c revision 1.7
1/* $NetBSD: test.c,v 1.7 2016/06/11 06:26:50 dholland 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 40struct cmdtab { 41 const char *cmd; 42 void (*fn)(const char *buf); 43}; 44 45int done; 46unsigned long arg_pfn, arg_ptb, arg_bim, arg_bip, arg_biv; 47 48const char *advance_past_space(const char *buf); 49const char *cvt_number(const char *buf, u_int64_t *nump); 50int dispatch_cmd(const char *buf, const struct cmdtab *cmds); 51#define DISPATCH_CMD_NOCMD 0 52#define DISPATCH_CMD_MATCHED 1 53#define DISPATCH_CMD_NOMATCH 2 54#define DISPATCH_CMD_AMBIGUOUS 3 55void print_cmds(const struct cmdtab *cmds, const char *match, 56 size_t matchlen); 57void print_stringarray(const char *s, size_t maxlen); 58 59void toplevel_dpb(const char *buf); 60void toplevel_dpl(const char *buf); 61void toplevel_dpq(const char *buf); 62void toplevel_dpw(const char *buf); 63void toplevel_dvb(const char *buf); 64void toplevel_dvl(const char *buf); 65void toplevel_dvq(const char *buf); 66void toplevel_dvw(const char *buf); 67void toplevel_halt(const char *buf); 68void toplevel_help(const char *buf); 69void toplevel_show(const char *buf); 70 71void show_args(const char *buf); 72void show_bootinfo(const char *buf); 73void show_pt(const char *buf); 74void show_rpb(const char *buf); 75 76void 77main(unsigned long pfn, unsigned long ptb, unsigned long bim, unsigned long bip, unsigned long biv) 78 /* pfn: first free PFN number */ 79 /* ptb: PFN of current level 1 page table */ 80 /* bim: bootinfo magic */ 81 /* bip: bootinfo pointer */ 82 /* biv: bootinfo version */ 83{ 84 char input_buf[512]; 85 static const struct cmdtab toplevel_cmds[] = { 86 { "?", toplevel_help, }, 87#if 0 /* XXX notyet */ 88 { "dpb", toplevel_dpb, }, 89 { "dpl", toplevel_dpl, }, 90 { "dpq", toplevel_dpq, }, 91 { "dpw", toplevel_dpw, }, 92 { "dvb", toplevel_dvb, }, 93 { "dvl", toplevel_dvl, }, 94 { "dvq", toplevel_dvq, }, 95 { "dvw", toplevel_dvw, }, 96#endif 97 { "quit", toplevel_halt, }, 98 { "show", toplevel_show, }, 99 { NULL, }, 100 }; 101 102 printf("\n"); 103 printf("NetBSD/alpha " NETBSD_VERS 104 " Standalone Test Program, Revision %s\n", bootprog_rev); 105 printf("\n"); 106 107 arg_pfn = pfn; 108 arg_ptb = ptb; 109 arg_bim = bim; 110 arg_bip = bip; 111 arg_biv = biv; 112 113 printf("Enter '?' for help.\n"); 114 printf("\n"); 115 116 do { 117 printf("test> "); 118 kgets(input_buf, sizeof(input_buf)); 119 120 dispatch_cmd(input_buf, toplevel_cmds); 121 } while (!done); 122 123 printf("\n"); 124 printf("halting...\n"); 125 halt(); 126} 127 128const char * 129advance_past_space(const char *buf) 130{ 131 132 /* advance past white space. */ 133 while (isspace(*buf)) 134 buf++; 135 136 if (*buf == '\0') 137 return NULL; 138 return buf; 139} 140 141const char * 142cvt_number(const char *buf, u_int64_t *nump) 143{ 144 int base; 145 unsigned char c; 146 147 base = 10; 148 *nump = 0; 149 150 c = *buf; 151 if (c == '0') { 152 c = *(++buf); 153 154 if (c == 'x' || c == 'X') { 155 base = 16; 156 buf++; 157 } else { 158 base = 8; 159 } 160 } 161 162 for (c = *buf; c != '\0' && !isspace(c); c = *(++buf)) { 163 switch (base) { 164 case 10: 165 if (c < '0' || c > '9') 166 goto done; 167 } 168 } 169done: 170 171} 172 173int 174dispatch_cmd(const char *buf, const struct cmdtab *cmds) 175{ 176 const struct cmdtab *try, *winner; 177 size_t nonwhitespace, i; 178 unsigned int nmatches; 179 const char *pre, *post; 180 int rv; 181 182 /* advance past white space. */ 183 buf = advance_past_space(buf); 184 if (buf == NULL) 185 return (DISPATCH_CMD_NOCMD); 186 187 /* find how much non-white space there is. */ 188 nonwhitespace = 0; 189 while ((buf[nonwhitespace] != '\0') && !isspace(buf[nonwhitespace])) 190 nonwhitespace++; 191 192 /* at this point, nonwhitespace should always be non-zero */ 193 if (nonwhitespace == 0) { 194 printf("assertion failed: dispatch_cmd: nonwhitespace == 0\n"); 195 halt(); 196 } 197 198 /* see how many matches there were. */ 199 for (nmatches = 0, try = cmds; 200 try != NULL && try->cmd != NULL; 201 try++) { 202 if (strncmp(buf, try->cmd, nonwhitespace) == 0) { 203 winner = try; 204 nmatches++; 205 } 206 } 207 208 if (nmatches == 1) { 209 (*winner->fn)(buf + nonwhitespace); 210 return (DISPATCH_CMD_MATCHED); 211 } else if (nmatches == 0) { 212 pre = "invalid command word"; 213 post = "allowed words"; 214 rv = DISPATCH_CMD_NOMATCH; 215 } else { 216 pre = "ambiguous command word"; 217 post = "matches"; 218 rv = DISPATCH_CMD_AMBIGUOUS; 219 } 220 221 printf("%s \"", pre); 222 print_stringarray(buf, nonwhitespace); 223 printf("\", %s:\n", post); 224 225 /* print commands. if no match, print all commands. */ 226 print_cmds(cmds, buf, rv == DISPATCH_CMD_NOMATCH ? 0 : nonwhitespace); 227 return (rv); 228} 229 230void 231print_cmds(const struct cmdtab *cmds, const char *match, size_t matchlen) 232{ 233 const struct cmdtab *try; 234 235 printf(" "); 236 for (try = cmds; try != NULL && try->cmd != NULL; try++) { 237 if (strncmp(match, try->cmd, matchlen) == 0) 238 printf("%s%s", try != cmds ? ", " : "", try->cmd); 239 } 240 printf("\n"); 241} 242 243void 244print_stringarray(const char *s, size_t maxlen) 245{ 246 size_t i; 247 248 for (i = 0; (i < maxlen) && (*s != '\0'); i++, s++) 249 putchar(*s); 250} 251 252void 253warn_ignored_args(const char *buf, const char *cmd) 254{ 255 256 if (advance_past_space(buf) != NULL) 257 printf("WARNING: extra arguments to \"%s\" command ignored\n", 258 cmd); 259} 260 261 262/* 263 * Top-level Commands 264 */ 265 266void 267toplevel_dpb(const char *buf) 268{ 269 u_int64_t startaddr, count = 1; 270 271 buf = advance_past_space(buf); 272 if (buf == NULL) { 273 printf("\"dpb\" must be given starting address\n"); 274 return; 275 } 276 buf = cvt_number(buf, &startaddr); 277 if (*buf != '\0' && !isspace(*buf)) { 278 printf("bad character '%c' in starting address\n", *buf); 279 return; 280 } 281 282 buf = advance_past_space(buf); 283 if (buf != NULL) { 284 buf = cvt_number(buf, &count); 285 if (*buf != '\0' && !isspace(*buf)) { 286 printf("bad character '%c' in count\n", *buf); 287 return; 288 } 289 buf = advance_past_space(buf); 290 if (buf != NULL) { 291 printf("extra args at end of \"dpb\" command\n"); 292 return; 293 } 294 } 295 296 printf("startaddr = 0x%lx, count = 0x%lx\n", startaddr, count); 297 printf("\"dpb\" not yet implemented\n"); 298} 299 300void 301toplevel_dpl(const char *buf) 302{ 303 304 printf("\"dpl\" not yet implemented\n"); 305} 306 307void 308toplevel_dpq(const char *buf) 309{ 310 311 printf("\"dpq\" not yet implemented\n"); 312} 313 314void 315toplevel_dpw(const char *buf) 316{ 317 318 printf("\"dpw\" not yet implemented\n"); 319} 320 321void 322toplevel_dvb(const char *buf) 323{ 324 325 printf("\"dvb\" not yet implemented\n"); 326} 327 328void 329toplevel_dvl(const char *buf) 330{ 331 332 printf("\"dvl\" not yet implemented\n"); 333} 334 335void 336toplevel_dvq(const char *buf) 337{ 338 339 printf("\"dvq\" not yet implemented\n"); 340} 341 342void 343toplevel_dvw(const char *buf) 344{ 345 346 printf("\"dvw\" not yet implemented\n"); 347} 348 349void 350toplevel_halt(const char *buf) 351{ 352 353 warn_ignored_args(buf, "halt"); 354 355 done = 1; 356} 357 358void 359toplevel_help(const char *buf) 360{ 361 362 warn_ignored_args(buf, "?"); 363 364 printf("Standalone Test Program Commands:\n"); 365 printf(" ? print help\n"); 366 printf(" quit return to console\n"); 367#if 0 /* XXX notyet */ 368 printf(" dpb startaddr [count] display physical memory " 369 "(8-bit units)\n"); 370 printf(" dpw startaddr [count] display physical memory " 371 "(16-bit units)\n"); 372 printf(" dpl startaddr [count] display physical memory " 373 "(32-bit units)\n"); 374 printf(" dpq startaddr [count] display physical memory " 375 "(64-bit units)\n"); 376 printf(" dvb startaddr [count] display virtual memory " 377 "(8-bit units)\n"); 378 printf(" dvw startaddr [count] display virtual memory " 379 "(16-bit units)\n"); 380 printf(" dvl startaddr [count] display virtual memory " 381 "(32-bit units)\n"); 382 printf(" dvq startaddr [count] display virtual memory " 383 "(64-bit units)\n"); 384#endif 385 printf(" show args show test program arguments\n"); 386 printf(" show bootinfo show bootstrap bootinfo\n"); 387#if 0 /* XXX notyet */ 388 printf(" show pt [startaddr [endaddr]]\n"); 389 printf(" show page tables\n"); 390 printf(" show rpb show the HWRPB\n"); 391 printf("\n"); 392 printf("If optional \"count\" argument is omitted, 1 is used.\n"); 393 printf("If optional \"startaddr\" argument is omitted, " 394 "0x0 is used.\n"); 395 printf("If optional \"endaddr\" argument is omitted, " 396 "0xffffffffffffffff is used.\n"); 397#endif 398} 399 400void 401toplevel_show(const char *buf) 402{ 403 static const struct cmdtab show_cmds[] = { 404 { "args", show_args, }, 405 { "bootinfo", show_bootinfo, }, 406#if 0 /* XXX notyet */ 407 { "pt", show_pt, }, 408 { "rpb", show_rpb, }, 409#endif 410 { NULL, }, 411 }; 412 413 if (dispatch_cmd(buf, show_cmds) == DISPATCH_CMD_NOCMD) { 414 printf("no subcommand given. allowed subcommands:\n"); 415 print_cmds(show_cmds, NULL, 0); 416 } 417} 418 419 420/* 421 * Show Commands 422 */ 423 424void 425show_args(const char *buf) 426{ 427 428 warn_ignored_args(buf, "show args"); 429 430 printf("first free page frame number: 0x%lx\n", arg_pfn); 431 printf("page table base page frame number: 0x%lx\n", arg_ptb); 432 printf("bootinfo magic number: 0x%lx\n", arg_bim); 433 printf("bootinfo pointer: 0x%lx\n", arg_bip); 434 printf("bootinfo version: 0x%lx\n", arg_biv); 435} 436 437void 438show_bootinfo(const char *buf) 439{ 440 u_long biv, bip; 441 442 warn_ignored_args(buf, "show bootinfo"); 443 444 if (arg_bim != BOOTINFO_MAGIC) { 445 printf("bootinfo magic number not present; no bootinfo\n"); 446 return; 447 } 448 449 bip = arg_bip; 450 biv = arg_biv; 451 if (biv == 0) { 452 biv = *(u_long *)bip; 453 bip += 8; 454 } 455 456 printf("bootinfo version: %d\n", biv); 457 printf("bootinfo pointer: %p\n", (void *)bip); 458 printf("bootinfo data:\n"); 459 460 switch (biv) { 461 case 1: { 462 const struct bootinfo_v1 *v1p; 463 int i; 464 465 v1p = (const struct bootinfo_v1 *)bip; 466 printf(" ssym: 0x%lx\n", v1p->ssym); 467 printf(" esym: 0x%lx\n", v1p->esym); 468 printf(" boot flags: \""); 469 print_stringarray(v1p->boot_flags, sizeof v1p->boot_flags); 470 printf("\"\n"); 471 printf(" booted kernel: \"", v1p->esym); 472 print_stringarray(v1p->booted_kernel, 473 sizeof v1p->booted_kernel); 474 printf("\"\n"); 475 printf(" hwrpb: %p\n", v1p->hwrpb); 476 printf(" hwrpbsize: 0x%lx\n", v1p->hwrpbsize); 477 printf(" cngetc: %p\n", v1p->cngetc); 478 printf(" cnputc: %p\n", v1p->cnputc); 479 printf(" cnpollc: %p\n", v1p->cnpollc); 480 for (i = 0; i < (sizeof v1p->pad / sizeof v1p->pad[0]); i++) { 481 printf(" pad[%d]: 0x%lx\n", i, v1p->pad[i]); 482 } 483 break; 484 } 485 default: 486 printf(" unknown bootinfo version, cannot print data\n"); 487 break; 488 } 489} 490 491void 492show_pt(const char *buf) 493{ 494 495 /* has additional args! */ 496 printf("\"show pt\" not yet implemented\n"); 497} 498 499void 500show_rpb(const char *buf) 501{ 502 503 warn_ignored_args(buf, "show pt"); 504 505 printf("\"show rpb\" not yet implemented\n"); 506} 507