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