xref: /netbsd-src/sys/arch/hpcmips/stand/lcboot/main.c (revision 85e3fbd2ebdea4c043943e3fc74aae69c997bc76)
1*85e3fbd2Sdholland /* $NetBSD: main.c,v 1.7 2016/06/11 06:29:24 dholland Exp $ */
2f8bc0014Sigy 
3f8bc0014Sigy /*
48f53455cSigy  * Copyright (c) 2003 Naoto Shimazaki.
5f8bc0014Sigy  * All rights reserved.
6f8bc0014Sigy  *
7f8bc0014Sigy  * Redistribution and use in source and binary forms, with or without
8f8bc0014Sigy  * modification, are permitted provided that the following conditions
9f8bc0014Sigy  * are met:
10f8bc0014Sigy  * 1. Redistributions of source code must retain the above copyright
11f8bc0014Sigy  *    notice, this list of conditions and the following disclaimer.
12f8bc0014Sigy  * 2. Redistributions in binary form must reproduce the above copyright
13f8bc0014Sigy  *    notice, this list of conditions and the following disclaimer in the
14f8bc0014Sigy  *    documentation and/or other materials provided with the distribution.
15f8bc0014Sigy  *
168f53455cSigy  * THIS SOFTWARE IS PROVIDED BY NAOTO SHIMAZAKI AND CONTRIBUTORS ``AS IS''
178f53455cSigy  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
188f53455cSigy  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
198f53455cSigy  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE NAOTO OR CONTRIBUTORS BE
208f53455cSigy  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21f8bc0014Sigy  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22f8bc0014Sigy  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23f8bc0014Sigy  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24f8bc0014Sigy  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
258f53455cSigy  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
268f53455cSigy  * THE POSSIBILITY OF SUCH DAMAGE.
27f8bc0014Sigy  */
28f8bc0014Sigy 
29f8bc0014Sigy /*
30f8bc0014Sigy  * Boot loader for L-Card+
31f8bc0014Sigy  *
32f8bc0014Sigy  * ROM Map
33f8bc0014Sigy  * -------
34f8bc0014Sigy  * ROM1
35f8bc0014Sigy  * BFFF FFFF	------------------------------
36f8bc0014Sigy  *
37f8bc0014Sigy  *		reserved
38f8bc0014Sigy  *
39f8bc0014Sigy  * BF80 0000	------------------------------
40f8bc0014Sigy  *
41f8bc0014Sigy  * ROM0
42f8bc0014Sigy  * BFFF FFFF	------------------------------
43f8bc0014Sigy  *
44f8bc0014Sigy  *		user storage (max 2Mbytes)
45f8bc0014Sigy  *
46f8bc0014Sigy  * BFE0 0000	------------------------------
47f8bc0014Sigy  *
48f8bc0014Sigy  *		reserved
49f8bc0014Sigy  *
50f8bc0014Sigy  * BFD4 0000	------------------------------
51f8bc0014Sigy  *
52f8bc0014Sigy  *		boot params
53f8bc0014Sigy  *
54f8bc0014Sigy  * BFD2 0000	------------------------------
55f8bc0014Sigy  *
56f8bc0014Sigy  *		second boot loader (mirror image)
57f8bc0014Sigy  *		or Linux Kernel
58f8bc0014Sigy  *
59f8bc0014Sigy  * BFD0 0000	------------------------------
60f8bc0014Sigy  *
61f8bc0014Sigy  *		first boot loader (L-Card+ original loader)
62f8bc0014Sigy  *
63f8bc0014Sigy  *		reset vector
64f8bc0014Sigy  * BFC0 0000	------------------------------
65f8bc0014Sigy  *
66f8bc0014Sigy  *		gziped kernel image (max 4Mbytes)
67f8bc0014Sigy  *
68f8bc0014Sigy  * BF80 0000	------------------------------
69f8bc0014Sigy  *
70f8bc0014Sigy  *
71f8bc0014Sigy  *
72f8bc0014Sigy  * RAM Map
73f8bc0014Sigy  * -------
74f8bc0014Sigy  *
75f8bc0014Sigy  * 80FF FFFF	------------------------------
76f8bc0014Sigy  *		ROM ICE work
77f8bc0014Sigy  * 80FF FE00	------------------------------
78f8bc0014Sigy  *		ROM ICE stack
79f8bc0014Sigy  * 80FF FDA8	------------------------------
80f8bc0014Sigy  *
81f8bc0014Sigy  *
82f8bc0014Sigy  *
83f8bc0014Sigy  *		kernel
84f8bc0014Sigy  * 8004 0000	------------------------------
85f8bc0014Sigy  *		kernel stack (growing to lower)
86f8bc0014Sigy  *
87f8bc0014Sigy  *
88f8bc0014Sigy  *		boot loader heap (growing to upper)
89f8bc0014Sigy  *		boot loader text & data (at exec time)
90f8bc0014Sigy  * 8000 1000	------------------------------
91f8bc0014Sigy  *		vector table
92f8bc0014Sigy  * 8000 0000	------------------------------
93f8bc0014Sigy  *
94f8bc0014Sigy  *		virtual memory space
95f8bc0014Sigy  *
96f8bc0014Sigy  * 0000 0000	------------------------------
97f8bc0014Sigy  *
98f8bc0014Sigy  *
99f8bc0014Sigy  *
100f8bc0014Sigy  * ROMCS0 <-> ROMCS3 mapping
101f8bc0014Sigy  *
102f8bc0014Sigy  *  ROMCS0        ROMCS3
103f8bc0014Sigy  * BE7F FFFF <-> BFFF FFFF
104f8bc0014Sigy  * BE40 0000 <-> BFC0 0000	reset vector
105f8bc0014Sigy  * BE00 0000 <-> BF80 0000
106f8bc0014Sigy  *
107f8bc0014Sigy  *
108f8bc0014Sigy  */
1098f53455cSigy #include <sys/cdefs.h>
110*85e3fbd2Sdholland __KERNEL_RCSID(0, "$NetBSD: main.c,v 1.7 2016/06/11 06:29:24 dholland Exp $");
111f8bc0014Sigy 
112f8bc0014Sigy #include <lib/libsa/stand.h>
1138f53455cSigy 
114f8bc0014Sigy #include <lib/libsa/loadfile.h>
115f8bc0014Sigy #include <lib/libkern/libkern.h>
116f8bc0014Sigy 
117f8bc0014Sigy #include <hpcmips/vr/vripreg.h>
118f8bc0014Sigy #include <hpcmips/vr/cmureg.h>
119f8bc0014Sigy #include <hpcmips/vr/vr4181giureg.h>
120f8bc0014Sigy 
121f8bc0014Sigy #include "extern.h"
122f8bc0014Sigy #include "i28f128reg.h"
123f8bc0014Sigy 
124f8bc0014Sigy /* XXX */
125f8bc0014Sigy #define ISABRGCTL	0x00
126f8bc0014Sigy #define ISABRGSTS	0x02
127f8bc0014Sigy #define XISACTL		0x04
128f8bc0014Sigy 
129f8bc0014Sigy #define BOOTTIMEOUT	9	/* must less than 10 */
130f8bc0014Sigy #define LINEBUFLEN	80
131f8bc0014Sigy 
132f8bc0014Sigy extern const char bootprog_rev[];
133f8bc0014Sigy extern const char bootprog_name[];
134f8bc0014Sigy 
135f8bc0014Sigy static void command_help(char *opt);
136f8bc0014Sigy static void command_dump(char *opt);
137f8bc0014Sigy static void command_boot(char *opt);
138f8bc0014Sigy static void command_load(char *opt);
139f8bc0014Sigy static void command_fill(char *opt);
140f8bc0014Sigy static void command_write(char *opt);
1418f53455cSigy static void command_option(char *subcmd);
1428f53455cSigy static void opt_subcmd_print(char *opt);
1438f53455cSigy static void opt_subcmd_read(char *opt);
1448f53455cSigy static void opt_subcmd_write(char *opt);
1458f53455cSigy static void opt_subcmd_path(char *opt);
1468f53455cSigy static void opt_subcmd_bootp(char *opt);
1478f53455cSigy static void opt_subcmd_ip(char *opt);
1488f53455cSigy 
1498f53455cSigy 
1508f53455cSigy struct boot_option	bootopts;
151f8bc0014Sigy 
152f8bc0014Sigy static struct bootmenu_command commands[] = {
153f8bc0014Sigy 	{ "?",		command_help },
154f8bc0014Sigy 	{ "h",		command_help },
155f8bc0014Sigy 	{ "d",		command_dump },
156f8bc0014Sigy 	{ "b",		command_boot },
157f8bc0014Sigy 	{ "l",		command_load },
158f8bc0014Sigy 	{ "f",		command_fill },
159f8bc0014Sigy 	{ "w",		command_write },
1608f53455cSigy 	{ "o",		command_option },
1618f53455cSigy 	{ NULL,		NULL },
1628f53455cSigy };
1638f53455cSigy 
1648f53455cSigy static struct bootmenu_command opt_subcommands[] = {
1658f53455cSigy 	{ "p",		opt_subcmd_print },
1668f53455cSigy 	{ "r",		opt_subcmd_read },
1678f53455cSigy 	{ "w",		opt_subcmd_write },
1688f53455cSigy 	{ "path",	opt_subcmd_path },
1698f53455cSigy 	{ "bootp",	opt_subcmd_bootp },
1708f53455cSigy 	{ "ip",		opt_subcmd_ip },
171f8bc0014Sigy 	{ NULL,		NULL },
172f8bc0014Sigy };
173f8bc0014Sigy 
174f8bc0014Sigy static void
print_banner(void)175f8bc0014Sigy print_banner(void)
176f8bc0014Sigy {
177f8bc0014Sigy 	printf("\n");
178f8bc0014Sigy 	printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);
179f8bc0014Sigy #if 0
180f8bc0014Sigy 	printf(">> Memory: %d/%d k\n", getbasemem(), getextmem());
181f8bc0014Sigy #endif
182f8bc0014Sigy }
183f8bc0014Sigy 
184f8bc0014Sigy static void
init_devices(void)185f8bc0014Sigy init_devices(void)
186f8bc0014Sigy {
187f8bc0014Sigy 	/* Init RTC */
188f8bc0014Sigy 	REGWRITE_2(VRETIMEH, 0, 0);
189f8bc0014Sigy 	REGWRITE_2(VRETIMEM, 0, 0);
190f8bc0014Sigy 	REGWRITE_2(VRETIMEL, 0, 0);
191f8bc0014Sigy 
192f8bc0014Sigy 
193f8bc0014Sigy 	/*
194f8bc0014Sigy 	 * CLKSPEEDREG	0x6012
195f8bc0014Sigy 	 *	DIV	DIV2 mode
196f8bc0014Sigy 	 *	CLKSP	18 (0x12)
197f8bc0014Sigy 	 *	PClock (CPU clock)		65.536MHz
198f8bc0014Sigy 	 *		PClock = (18.432MHz / CLKSP) x 64
199f8bc0014Sigy 	 *		       = (18.432MHz / 18) x 64
200f8bc0014Sigy 	 *		       = 65.536MHz
201f8bc0014Sigy 	 *	TClock (peripheral clock)	32.768MHz
202f8bc0014Sigy 	 *		TClock = PClock / DIV
203f8bc0014Sigy 	 *		       = 65.536MHz / 2
204f8bc0014Sigy 	 *		       = 32.768MHz
205f8bc0014Sigy 	 */
206f8bc0014Sigy 
207f8bc0014Sigy 	/*
208f8bc0014Sigy 	 * setup ISA BUS clock freqency
209f8bc0014Sigy 	 *
210f8bc0014Sigy 	 * set PCLK (internal peripheral clock) to 32.768MHz (TClock / 1)
211f8bc0014Sigy 	 * set External ISA bus clock to 10.922MHz (TClock / 3)
212f8bc0014Sigy 	 */
213f8bc0014Sigy 	REGWRITE_2(VR4181_ISABRG_ADDR, ISABRGCTL, 0x0003);
214f8bc0014Sigy 	REGWRITE_2(VR4181_ISABRG_ADDR, XISACTL, 0x0401);
215f8bc0014Sigy 
216f8bc0014Sigy 	/*
217f8bc0014Sigy 	 * setup peripheral's clock supply
218f8bc0014Sigy 	 *
219f8bc0014Sigy 	 * CSU: disable
220f8bc0014Sigy 	 * AIU: enable (AIU, ADU, ADU18M)
221f8bc0014Sigy 	 * PIU: disable
222f8bc0014Sigy 	 * SIU: enable (SIU18M)
223f8bc0014Sigy 	 */
224f8bc0014Sigy 	REGWRITE_2(VR4181_CMU_ADDR, 0, CMUMASK_SIU | CMUMASK_AIU);
225f8bc0014Sigy 
226f8bc0014Sigy 	/*
227f8bc0014Sigy 	 * setup GPIO
228f8bc0014Sigy 	 */
229f8bc0014Sigy #if 0
230f8bc0014Sigy 	/* L-Card+ generic setup */
231f8bc0014Sigy 	/*
232f8bc0014Sigy 	 * pin   mode	comment
233f8bc0014Sigy 	 * GP0 : GPI	not used
234f8bc0014Sigy 	 * GP1 : GPI	not used
235f8bc0014Sigy 	 * GP2 : GPO	LED6 (0: on  1: off)
236f8bc0014Sigy 	 * GP3 : PCS0	chip select for CS8900A Lan controller
237f8bc0014Sigy 	 * GP4 : GPI	IRQ input from CS8900A
238f8bc0014Sigy 	 * GP5 : GPI	not used
239f8bc0014Sigy 	 * GP6 : GPI	not used
240f8bc0014Sigy 	 * GP7 : GPI	reserved by TANBAC TB0193
241f8bc0014Sigy 	 */
242f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_PIOD_L_REG_W, 0xffff);
243f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_MODE0_REG_W,
244f8bc0014Sigy 		   GP3_PCS0 | GP2_GPO);
245f8bc0014Sigy 	/*
246f8bc0014Sigy 	 * pin   mode	comment
247f8bc0014Sigy 	 * GP8 : GPO	LED5 (0: on  1: off)
248f8bc0014Sigy 	 * GP9 : GPI	CD2
249f8bc0014Sigy 	 * GP10: GPI	CD1
250f8bc0014Sigy 	 * GP11: GPI	not used
251f8bc0014Sigy 	 * GP12: GPI	not used
252f8bc0014Sigy 	 * GP13: GPI	not used
253f8bc0014Sigy 	 * GP14: GPI	not used
254f8bc0014Sigy 	 * GP15: GPI	not used
255f8bc0014Sigy 	 */
256f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_MODE1_REG_W, GP8_GPO);
257f8bc0014Sigy 	/*
258f8bc0014Sigy 	 * pin   mode	comment
259f8bc0014Sigy 	 * GP16: IORD	ISA bus
260f8bc0014Sigy 	 * GP17: IOWR	ISA bus
261f8bc0014Sigy 	 * GP18: IORDY	ISA bus
262f8bc0014Sigy 	 * GP19: GPI	not used
263f8bc0014Sigy 	 * GP20: GPI	not used
264f8bc0014Sigy 	 * GP21: RESET	resets CS8900A
265f8bc0014Sigy 	 * GP22: ROMCS0	ROM chip select
266f8bc0014Sigy 	 * GP23: ROMCS1	ROM chip select
267f8bc0014Sigy 	 */
268f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_MODE2_REG_W,
269f8bc0014Sigy 		   GP23_ROMCS1 | GP22_ROMCS0 | GP21_RESET
270f8bc0014Sigy 		   | GP18_IORDY | GP17_IOWR | GP16_IORD);
271f8bc0014Sigy 	/*
272f8bc0014Sigy 	 * GP24: ROMCS2	ROM chip select
273f8bc0014Sigy 	 * GP25: RxD1	SIU1
274f8bc0014Sigy 	 * GP26: TxD1	SIU1
275f8bc0014Sigy 	 * GP27: RTS1	SIU1
276f8bc0014Sigy 	 * GP28: CTS1	SIU1
277f8bc0014Sigy 	 * GP29: GPI	LED3
278f8bc0014Sigy 	 * GP30: GPI	reserved by TANBAC TB0193
279f8bc0014Sigy 	 * GP31: GPI	LED4
280f8bc0014Sigy 	 */
281f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_MODE3_REG_W,
282f8bc0014Sigy 		   GP30_GPI
283f8bc0014Sigy 		   | GP28_CTS1 | GP27_RTS1 | GP26_TxD1 | GP25_RxD1
284f8bc0014Sigy 		   | GP24_ROMCS2);
285f8bc0014Sigy #else
286f8bc0014Sigy 	/* e-care node specific setup */
287f8bc0014Sigy 	/*
288f8bc0014Sigy 	 * pin   mode	comment
289f8bc0014Sigy 	 * GP0 : GPO	ECNRTC_RST
290f8bc0014Sigy 	 * GP1 : GPO	ECNRTC_CLK
291f8bc0014Sigy 	 * GP2 : GPO	LED6 (0: on  1: off)
292f8bc0014Sigy 	 * GP3 : PCS0	chip select for CS8900A Lan controller
293f8bc0014Sigy 	 * GP4 : GPI	IRQ input from CS8900A
294f8bc0014Sigy 	 * GP5 : GPO	ECNRTC_DIR
295f8bc0014Sigy 	 * GP6 : GPO	ECNRTC_OUT
296f8bc0014Sigy 	 * GP7 : GPI	reserved by TANBAC TB0193
297f8bc0014Sigy 	 */
298f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_PIOD_L_REG_W, 0xffff);
299f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_MODE0_REG_W,
300f8bc0014Sigy 		   GP6_GPO | GP5_GPO | GP3_PCS0
301f8bc0014Sigy 		   | GP2_GPO | GP1_GPO | GP0_GPO);
302f8bc0014Sigy 
303f8bc0014Sigy 	/*
304f8bc0014Sigy 	 * pin   mode	comment
305f8bc0014Sigy 	 * GP8 : GPO	LED5 (0: on  1: off)
306f8bc0014Sigy 	 * GP9 : GPI	CD2
307f8bc0014Sigy 	 * GP10: GPI	CD1
308f8bc0014Sigy 	 * GP11: GPI	not used
309f8bc0014Sigy 	 * GP12: GPI	ECNRTC_IN
310f8bc0014Sigy 	 * GP13: GPI	not used
311f8bc0014Sigy 	 * GP14: GPI	not used
312f8bc0014Sigy 	 * GP15: GPI	not used
313f8bc0014Sigy 	 */
314f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_MODE1_REG_W,
315f8bc0014Sigy 		   GP12_GPI | GP8_GPO);
316f8bc0014Sigy 
317f8bc0014Sigy 	/*
318f8bc0014Sigy 	 * pin   mode	comment
319f8bc0014Sigy 	 * GP16: IORD	ISA bus
320f8bc0014Sigy 	 * GP17: IOWR	ISA bus
321f8bc0014Sigy 	 * GP18: IORDY	ISA bus
322f8bc0014Sigy 	 * GP19: GPI	not used
323f8bc0014Sigy 	 * GP20: GPI	not used
324f8bc0014Sigy 	 * GP21: RESET	resets CS8900A
325f8bc0014Sigy 	 * GP22: ROMCS0	ROM chip select
326f8bc0014Sigy 	 * GP23: ROMCS1	ROM chip select
327f8bc0014Sigy 	 */
328f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_MODE2_REG_W,
329f8bc0014Sigy 		   GP23_ROMCS1 | GP22_ROMCS0 | GP21_RESET
330f8bc0014Sigy 		   | GP18_IORDY | GP17_IOWR | GP16_IORD);
331f8bc0014Sigy 	/*
332f8bc0014Sigy 	 * GP24: ROMCS2	ROM chip select
333f8bc0014Sigy 	 * GP25: RxD1	SIU1
334f8bc0014Sigy 	 * GP26: TxD1	SIU1
335f8bc0014Sigy 	 * GP27: RTS1	SIU1
336f8bc0014Sigy 	 * GP28: CTS1	SIU1
337f8bc0014Sigy 	 * GP29: GPI	LED3
338f8bc0014Sigy 	 * GP30: GPI	reserved by TANBAC TB0193
339f8bc0014Sigy 	 * GP31: GPI	LED4
340f8bc0014Sigy 	 */
341f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_MODE3_REG_W,
342f8bc0014Sigy 		   GP30_GPI
343f8bc0014Sigy 		   | GP28_CTS1 | GP27_RTS1 | GP26_TxD1 | GP25_RxD1
344f8bc0014Sigy 		   | GP24_ROMCS2);
345f8bc0014Sigy #endif
346f8bc0014Sigy 
347f8bc0014Sigy #if 0
348f8bc0014Sigy 	/*
349f8bc0014Sigy 	 * setup interrupt
350f8bc0014Sigy 	 *
351f8bc0014Sigy 	 * I4TYP:  falling edge trigger
352f8bc0014Sigy 	 * GIMSK4: unmask
353f8bc0014Sigy 	 * GIEN4:  enable
354f8bc0014Sigy 	 * other:  unused, mask, disable
355f8bc0014Sigy 	 */
356f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_INTTYP_L_REG_W,
357f8bc0014Sigy 		   I4TYP_HIGH_LEVEL);
358f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_INTMASK_REG_W,
359f8bc0014Sigy 		   0xffffU & ~GIMSK4);
360f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_INTEN_REG_W, GIEN4);
361f8bc0014Sigy #endif
362f8bc0014Sigy 
363f8bc0014Sigy 	/*
364f8bc0014Sigy 	 * programmable chip select
365f8bc0014Sigy 	 *
366f8bc0014Sigy 	 * PCS0 is used to select CS8900A Ethernet controller
367f8bc0014Sigy 	 * on TB0193
368f8bc0014Sigy 	 *
369f8bc0014Sigy 	 * PCS0:
370f8bc0014Sigy 	 *	0x14010000 - 0x14010fff
371f8bc0014Sigy 	 *	I/O access, 16bit cycle, both of read/write
372f8bc0014Sigy 	 * PCS1: unused
373f8bc0014Sigy 	 */
374f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_PCS0STRA_REG_W, 0x0000);
375f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_PCS0STPA_REG_W, 0x0fff);
376f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_PCS0HIA_REG_W, 0x1401);
377f8bc0014Sigy 	REGWRITE_2(VR4181_GIU81_ADDR, VR4181GIU_PCSMODE_REG_W,
378f8bc0014Sigy 		   PCS0MIOB_IO | PCS0DSIZE_16BIT | PCS0MD_READWRITE);
379f8bc0014Sigy }
380f8bc0014Sigy 
381f8bc0014Sigy /*
382f8bc0014Sigy  * chops the head from the arguments and returns the arguments if any,
383f8bc0014Sigy  * or possibly an empty string.
384f8bc0014Sigy  */
385f8bc0014Sigy static char *
get_next_arg(char * arg)386f8bc0014Sigy get_next_arg(char *arg)
387f8bc0014Sigy {
388f8bc0014Sigy 	char *opt;
389f8bc0014Sigy 
390f8bc0014Sigy 	if ((opt = strchr(arg, ' ')) == NULL) {
391f8bc0014Sigy 		opt = "";
392f8bc0014Sigy 	} else {
393f8bc0014Sigy 		*opt++ = '\0';
394f8bc0014Sigy 	}
395f8bc0014Sigy 
396f8bc0014Sigy         /* trim leading blanks */
397f8bc0014Sigy 	while (*opt == ' ')
398f8bc0014Sigy 		opt++;
399f8bc0014Sigy 
400f8bc0014Sigy 	return opt;
401f8bc0014Sigy }
402f8bc0014Sigy 
403f8bc0014Sigy static void
command_help(char * opt)404f8bc0014Sigy command_help(char *opt)
405f8bc0014Sigy {
406f8bc0014Sigy 	printf("commands are:\n"
4078f53455cSigy 	       "boot:\tb\n"
4088f53455cSigy 	       "dump:\td addr [addr]\n"
4098f53455cSigy 	       "fill:\tf addr addr char\n"
4108f53455cSigy 	       "load:\tl [offset] (with following S-Record)\n"
4118f53455cSigy 	       "write:\tw dst src len\n"
4128f53455cSigy 	       "option:\to subcommand [params]\n"
4138f53455cSigy 	       "help:\th|?\n"
4148f53455cSigy 	       "\n"
4158f53455cSigy 	       "option subcommands are:\n"
4168f53455cSigy 	       "print:\to p\n"
4178f53455cSigy 	       "read:\to r\n"
4188f53455cSigy 	       "write:\to w\n"
4198f53455cSigy 	       "path:\to path pathname\n"
4208f53455cSigy 	       "bootp:\to bootp yes|no\n"
4218f53455cSigy 	       "ip:\to ip remote local netmask gateway\n"
4228f53455cSigy 		);
423f8bc0014Sigy }
424f8bc0014Sigy 
425f8bc0014Sigy static void
bad_param(void)426f8bc0014Sigy bad_param(void)
427f8bc0014Sigy {
428f8bc0014Sigy 	printf("bad param\n");
429f8bc0014Sigy 	command_help(NULL);
430f8bc0014Sigy }
431f8bc0014Sigy 
432f8bc0014Sigy static const u_int8_t print_cnv[] = {
433f8bc0014Sigy 	'0', '1', '2', '3', '4', '5', '6', '7',
434f8bc0014Sigy 	'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
435f8bc0014Sigy 
436f8bc0014Sigy static void
printhexul(u_int32_t n)437f8bc0014Sigy printhexul(u_int32_t n)
438f8bc0014Sigy {
439f8bc0014Sigy 	int	i;
440f8bc0014Sigy 
441f8bc0014Sigy 	for (i = 28; i >= 0; i -= 4)
442f8bc0014Sigy 		putchar(print_cnv[(n >> i) & 0x0f]);
443f8bc0014Sigy }
444f8bc0014Sigy 
445f8bc0014Sigy static void
printhexuc(u_int8_t n)446f8bc0014Sigy printhexuc(u_int8_t n)
447f8bc0014Sigy {
448f8bc0014Sigy 	int	i;
449f8bc0014Sigy 
450f8bc0014Sigy 	for (i = 4; i >= 0; i -= 4)
451f8bc0014Sigy 		putchar(print_cnv[(n >> i) & 0x0f]);
452f8bc0014Sigy }
453f8bc0014Sigy 
454f8bc0014Sigy static void
command_dump(char * opt)455f8bc0014Sigy command_dump(char *opt)
456f8bc0014Sigy {
457f8bc0014Sigy 	char		*endptr;
458f8bc0014Sigy 	const char	*p;
459f8bc0014Sigy 	const char	*line_fence;
460f8bc0014Sigy 	const char	*limit;
461f8bc0014Sigy 
462f8bc0014Sigy 	p = (const char *) strtoul(opt, &endptr, 16);
463f8bc0014Sigy 	if (opt == endptr) {
464f8bc0014Sigy 		bad_param();
465f8bc0014Sigy 		return;
466f8bc0014Sigy 	}
467f8bc0014Sigy 
468f8bc0014Sigy 	opt = get_next_arg(opt);
469f8bc0014Sigy 	limit = (const char *) strtoul(opt, &endptr, 16);
470f8bc0014Sigy 	if (opt == endptr) {
471f8bc0014Sigy 		limit = p + 256;
472f8bc0014Sigy 	}
473f8bc0014Sigy 
474f8bc0014Sigy 	for (;;) {
475f8bc0014Sigy 		printhexul((u_int32_t) p);
476f8bc0014Sigy 		putchar(' ');
477f8bc0014Sigy 		line_fence = p + 16;
478f8bc0014Sigy 		while (p < line_fence) {
479f8bc0014Sigy 			printhexuc(*p++);
480f8bc0014Sigy 			putchar(' ');
481f8bc0014Sigy 			if (p >= limit) {
482f8bc0014Sigy 				putchar('\n');
483f8bc0014Sigy 				return;
484f8bc0014Sigy 			}
485f8bc0014Sigy 		}
486f8bc0014Sigy 		putchar('\n');
487f8bc0014Sigy 		if (ISKEY) {
488f8bc0014Sigy 			if (getchar() == '\x03')
489f8bc0014Sigy 				break;
490f8bc0014Sigy 		}
491f8bc0014Sigy 	}
492f8bc0014Sigy }
493f8bc0014Sigy 
494f8bc0014Sigy static void
command_boot(char * opt)495f8bc0014Sigy command_boot(char *opt)
496f8bc0014Sigy {
497f8bc0014Sigy 	u_long	marks[MARK_MAX];
498f8bc0014Sigy 
499f8bc0014Sigy 	marks[MARK_START] = 0;
5008f53455cSigy 	if (loadfile(bootopts.b_pathname, marks, LOAD_KERNEL)) {
5018f53455cSigy 		printf("loadfile failed\n");
5028f53455cSigy 		return;
5038f53455cSigy 	}
504f8bc0014Sigy 	start_netbsd();
505f8bc0014Sigy 	/* no return */
506f8bc0014Sigy }
507f8bc0014Sigy 
508f8bc0014Sigy /*
509f8bc0014Sigy  * loading S-Record
510f8bc0014Sigy  */
511f8bc0014Sigy static int
load_srec(char * offset)512f8bc0014Sigy load_srec(char *offset)
513f8bc0014Sigy {
514f8bc0014Sigy 	char		s2lbuf[9];
515f8bc0014Sigy 	char		c;
516f8bc0014Sigy 	char		rectype;
517f8bc0014Sigy 	u_int32_t	reclen;
518f8bc0014Sigy 	u_int32_t	reclen_bk;
519f8bc0014Sigy 	u_int32_t	recaddr;
520f8bc0014Sigy 	char		*endptr;
521f8bc0014Sigy 	char		*p;
522f8bc0014Sigy 	u_int32_t	sum;
523f8bc0014Sigy 	int		err = 0;
524f8bc0014Sigy 
525f8bc0014Sigy 	for (;;) {
526f8bc0014Sigy 		/*
527f8bc0014Sigy 		 * the first step is to read a S-Record.
528f8bc0014Sigy 		 */
529f8bc0014Sigy 		if ((c = getchar()) != 'S')
530f8bc0014Sigy 			goto out;
531f8bc0014Sigy 
532f8bc0014Sigy 		rectype = getchar();
533f8bc0014Sigy 
534f8bc0014Sigy 		s2lbuf[0] = getchar();
535f8bc0014Sigy 		s2lbuf[1] = getchar();
536f8bc0014Sigy 		s2lbuf[2] = '\0';
537f8bc0014Sigy 		reclen_bk = reclen = strtoul(s2lbuf, &endptr, 16);
538f8bc0014Sigy 		if (endptr != &s2lbuf[2])
539f8bc0014Sigy 			goto out;
540f8bc0014Sigy 		sum = reclen;
541f8bc0014Sigy 
542f8bc0014Sigy 		p = s2lbuf;
543f8bc0014Sigy 
544f8bc0014Sigy 		switch (rectype) {
545f8bc0014Sigy 		case '0':
546f8bc0014Sigy 			/* just ignore */
547f8bc0014Sigy 			do {
548f8bc0014Sigy 				c = getchar();
549f8bc0014Sigy 			} while (c != '\r' && c != '\n');
550f8bc0014Sigy 			continue;
551f8bc0014Sigy 
552f8bc0014Sigy 		case '3':
553f8bc0014Sigy 			*p++ = getchar();
554f8bc0014Sigy 			*p++ = getchar();
555f8bc0014Sigy 			reclen--;
556f8bc0014Sigy 			/* FALLTHRU */
557f8bc0014Sigy 		case '2':
558f8bc0014Sigy 			*p++ = getchar();
559f8bc0014Sigy 			*p++ = getchar();
560f8bc0014Sigy 			reclen--;
561f8bc0014Sigy 			/* FALLTHRU */
562f8bc0014Sigy 		case '1':
563f8bc0014Sigy 			*p++ = getchar();
564f8bc0014Sigy 			*p++ = getchar();
565f8bc0014Sigy 			*p++ = getchar();
566f8bc0014Sigy 			*p++ = getchar();
567f8bc0014Sigy 			*p = '\0';
568f8bc0014Sigy 			reclen -= 2;
569f8bc0014Sigy 
570f8bc0014Sigy 			recaddr = strtoul(s2lbuf, &endptr, 16);
571f8bc0014Sigy 			if (endptr != p)
572f8bc0014Sigy 				goto out;
573f8bc0014Sigy 			sum += (recaddr >> 24) & 0xff;
574f8bc0014Sigy 			sum += (recaddr >> 16) & 0xff;
575f8bc0014Sigy 			sum += (recaddr >> 8) & 0xff;
576f8bc0014Sigy 			sum += recaddr & 0xff;
577f8bc0014Sigy 
578f8bc0014Sigy 			p = offset + recaddr;
579f8bc0014Sigy 			/*
580f8bc0014Sigy 			 * XXX
581f8bc0014Sigy 			 * address range is must be chaked here!
582f8bc0014Sigy 			 */
583f8bc0014Sigy 			reclen--;
584f8bc0014Sigy 			s2lbuf[2] = '\0';
585f8bc0014Sigy 			while (reclen > 0) {
586f8bc0014Sigy 				s2lbuf[0] = getchar();
587f8bc0014Sigy 				s2lbuf[1] = getchar();
588f8bc0014Sigy 				*p = (u_int8_t) strtoul(s2lbuf, &endptr, 16);
589f8bc0014Sigy 				if (endptr != &s2lbuf[2])
590f8bc0014Sigy 					goto out;
591f8bc0014Sigy 				sum += *p++;
592f8bc0014Sigy 				reclen--;
593f8bc0014Sigy 			}
594f8bc0014Sigy 			break;
595f8bc0014Sigy 
596f8bc0014Sigy 		case '7':
597f8bc0014Sigy 		case '8':
598f8bc0014Sigy 		case '9':
599f8bc0014Sigy 			goto out2;
600f8bc0014Sigy 
601f8bc0014Sigy 		default:
602f8bc0014Sigy 			goto out;
603f8bc0014Sigy 		}
604f8bc0014Sigy 
605f8bc0014Sigy 		s2lbuf[0] = getchar();
606f8bc0014Sigy 		s2lbuf[1] = getchar();
607f8bc0014Sigy 		s2lbuf[2] = '\0';
608f8bc0014Sigy 		sum += (strtoul(s2lbuf, &endptr, 16) & 0xff);
609f8bc0014Sigy 		sum &= 0xff;
610f8bc0014Sigy 		if (sum != 0xff) {
611f8bc0014Sigy 			printf("checksum error\n");
612f8bc0014Sigy 			err = 1;
613f8bc0014Sigy 			goto out2;
614f8bc0014Sigy 		}
615f8bc0014Sigy 
616f8bc0014Sigy 		c = getchar();
617f8bc0014Sigy 		if (c != '\r' && c != '\n')
618f8bc0014Sigy 			goto out;
619f8bc0014Sigy 	}
620f8bc0014Sigy 	/* never reach */
621f8bc0014Sigy 	return 1;
622f8bc0014Sigy 
623f8bc0014Sigy out:
624f8bc0014Sigy 	printf("invalid S-Record\n");
625f8bc0014Sigy 	err = 1;
626f8bc0014Sigy 
627f8bc0014Sigy out2:
628f8bc0014Sigy 	do {
629f8bc0014Sigy 		c = getchar();
630f8bc0014Sigy 	} while (c != '\r' && c != '\n');
631f8bc0014Sigy 
632f8bc0014Sigy 	return err;
633f8bc0014Sigy }
634f8bc0014Sigy 
635f8bc0014Sigy static void
command_load(char * opt)636f8bc0014Sigy command_load(char *opt)
637f8bc0014Sigy {
638f8bc0014Sigy 	char	*endptr;
639f8bc0014Sigy 	char	*offset;
640f8bc0014Sigy 
641f8bc0014Sigy 	offset = (char *) strtoul(opt, &endptr, 16);
642f8bc0014Sigy 	if (opt == endptr)
643f8bc0014Sigy 		offset = 0;
644f8bc0014Sigy 	load_srec(offset);
645f8bc0014Sigy }
646f8bc0014Sigy 
647f8bc0014Sigy static void
command_fill(char * opt)648f8bc0014Sigy command_fill(char *opt)
649f8bc0014Sigy {
650f8bc0014Sigy 	char	*endptr;
651f8bc0014Sigy 	char	*p;
652f8bc0014Sigy 	char	*limit;
653f8bc0014Sigy 	int	c;
654f8bc0014Sigy 
655f8bc0014Sigy 	p = (char *) strtoul(opt, &endptr, 16);
656f8bc0014Sigy 	if (opt == endptr) {
657f8bc0014Sigy 		bad_param();
658f8bc0014Sigy 		return;
659f8bc0014Sigy 	}
660f8bc0014Sigy 
661f8bc0014Sigy 	opt = get_next_arg(opt);
662f8bc0014Sigy 	limit = (char *) strtoul(opt, &endptr, 16);
663f8bc0014Sigy 	if (opt == endptr) {
664f8bc0014Sigy 		bad_param();
665f8bc0014Sigy 		return;
666f8bc0014Sigy 	}
667f8bc0014Sigy 
668f8bc0014Sigy 	opt = get_next_arg(opt);
669f8bc0014Sigy 	c = strtoul(opt, &endptr, 16);
670f8bc0014Sigy 	if (opt == endptr)
671f8bc0014Sigy 		c = '\0';
672f8bc0014Sigy 
673f8bc0014Sigy 	memset(p, c, limit - p);
674f8bc0014Sigy }
675f8bc0014Sigy 
676f8bc0014Sigy static void
check_write_verify_flash(u_int32_t src,u_int32_t dst,size_t len)6778f53455cSigy check_write_verify_flash(u_int32_t src, u_int32_t dst, size_t len)
678f8bc0014Sigy {
679f8bc0014Sigy 	int		status;
680f8bc0014Sigy 
681f8bc0014Sigy 	if ((dst & I28F128_BLOCK_MASK) != 0) {
682f8bc0014Sigy 		printf("dst addr must be aligned to block boundary (0x%x)\n",
683f8bc0014Sigy 		       I28F128_BLOCK_SIZE);
684f8bc0014Sigy 		return;
685f8bc0014Sigy 	}
686f8bc0014Sigy 
687f8bc0014Sigy 	if (i28f128_probe((void *) dst)) {
688f8bc0014Sigy 		printf("dst addr is not a intel 28F128\n");
689f8bc0014Sigy 	} else {
690f8bc0014Sigy 		printf("intel 28F128 detected\n");
691f8bc0014Sigy 	}
692f8bc0014Sigy 
693f8bc0014Sigy 	if ((status = i28f128_region_write((void *) dst, (void *) src, len))
694f8bc0014Sigy 	    != 0) {
695f8bc0014Sigy 		printf("write mem to flash failed status = %x\n", status);
696f8bc0014Sigy 		return;
697f8bc0014Sigy 	}
698f8bc0014Sigy 
699c0f40774Sigy 	printf("verifying...");
700c0f40774Sigy 	if (memcmp((void *) dst, (void *) src, len)) {
701c0f40774Sigy 		printf("verify error\n");
702c0f40774Sigy 		return;
703c0f40774Sigy 	}
704c0f40774Sigy 	printf("ok\n");
705c0f40774Sigy 
706c0f40774Sigy 	printf("writing memory to flash succeeded\n");
7078f53455cSigy }
7088f53455cSigy 
7098f53455cSigy static void
command_write(char * opt)7108f53455cSigy command_write(char *opt)
7118f53455cSigy {
7128f53455cSigy 	char		*endptr;
7138f53455cSigy 	u_int32_t	src;
7148f53455cSigy 	u_int32_t	dst;
7158f53455cSigy 	size_t		len;
7168f53455cSigy 
7178f53455cSigy 	dst = strtoul(opt, &endptr, 16);
7188f53455cSigy 	if (opt == endptr)
7198f53455cSigy 		goto out;
7208f53455cSigy 
7218f53455cSigy 	opt = get_next_arg(opt);
7228f53455cSigy 	src = strtoul(opt, &endptr, 16);
7238f53455cSigy 	if (opt == endptr)
7248f53455cSigy 		goto out;
7258f53455cSigy 
7268f53455cSigy 	opt = get_next_arg(opt);
7278f53455cSigy 	len = strtoul(opt, &endptr, 16);
7288f53455cSigy 	if (opt == endptr)
7298f53455cSigy 		goto out;
7308f53455cSigy 
7318f53455cSigy 	check_write_verify_flash(src, dst, len);
732f8bc0014Sigy 	return;
733f8bc0014Sigy 
734f8bc0014Sigy out:
735f8bc0014Sigy 	bad_param();
736f8bc0014Sigy 	return;
737f8bc0014Sigy }
738f8bc0014Sigy 
739f8bc0014Sigy static void
command_option(char * subcmd)7408f53455cSigy command_option(char *subcmd)
7418f53455cSigy {
7428f53455cSigy 	char	*opt;
7438f53455cSigy 	int	i;
7448f53455cSigy 
7458f53455cSigy 	opt = get_next_arg(subcmd);
7468f53455cSigy 
7478f53455cSigy 	/* dispatch subcommand */
7488f53455cSigy 	for (i = 0; opt_subcommands[i].c_name != NULL; i++) {
7498f53455cSigy 		if (strcmp(subcmd, opt_subcommands[i].c_name) == 0) {
7508f53455cSigy 			opt_subcommands[i].c_fn(opt);
7518f53455cSigy 			break;
7528f53455cSigy 		}
7538f53455cSigy 	}
7548f53455cSigy 	if (opt_subcommands[i].c_name == NULL) {
7558f53455cSigy 		printf("unknown option subcommand\n");
7568f53455cSigy 		command_help(NULL);
7578f53455cSigy 	}
7588f53455cSigy }
7598f53455cSigy 
7608f53455cSigy static void
opt_subcmd_print(char * opt)7618f53455cSigy opt_subcmd_print(char *opt)
7628f53455cSigy {
7638f53455cSigy 	printf("boot options:\n"
7648f53455cSigy 	       "magic:\t\t%s\n"
7658f53455cSigy 	       "pathname:\t`%s'\n"
7668f53455cSigy 	       "bootp:\t\t%s\n",
7678f53455cSigy 	       bootopts.b_magic == BOOTOPT_MAGIC ? "ok" : "bad",
7688f53455cSigy 	       bootopts.b_pathname,
7698f53455cSigy 	       bootopts.b_flags & B_F_USE_BOOTP ? "yes" : "no");
7708f53455cSigy 	printf("remote IP:\t%s\n", inet_ntoa(bootopts.b_remote_ip));
7718f53455cSigy 	printf("local IP:\t%s\n", inet_ntoa(bootopts.b_local_ip));
7728f53455cSigy 	printf("netmask:\t%s\n", intoa(bootopts.b_netmask));
7738f53455cSigy 	printf("gateway IP:\t%s\n", inet_ntoa(bootopts.b_gate_ip));
7748f53455cSigy }
7758f53455cSigy 
7768f53455cSigy static void
opt_subcmd_read(char * opt)7778f53455cSigy opt_subcmd_read(char *opt)
7788f53455cSigy {
7798f53455cSigy 	bootopts = *((struct boot_option *) BOOTOPTS_BASE);
7808f53455cSigy 	if (bootopts.b_magic != BOOTOPT_MAGIC)
7818f53455cSigy 		bootopts.b_pathname[0] = '\0';
7828f53455cSigy }
7838f53455cSigy 
7848f53455cSigy static void
opt_subcmd_write(char * opt)7858f53455cSigy opt_subcmd_write(char *opt)
7868f53455cSigy {
7878f53455cSigy 	bootopts.b_magic = BOOTOPT_MAGIC;
7888f53455cSigy 
7898f53455cSigy 	check_write_verify_flash((u_int32_t) &bootopts, BOOTOPTS_BASE,
7908f53455cSigy 				 sizeof bootopts);
7918f53455cSigy }
7928f53455cSigy 
7938f53455cSigy static void
opt_subcmd_path(char * opt)7948f53455cSigy opt_subcmd_path(char *opt)
7958f53455cSigy {
7968f53455cSigy 	strlcpy(bootopts.b_pathname, opt, sizeof bootopts.b_pathname);
7978f53455cSigy }
7988f53455cSigy 
7998f53455cSigy static void
opt_subcmd_bootp(char * opt)8008f53455cSigy opt_subcmd_bootp(char *opt)
8018f53455cSigy {
8028f53455cSigy 	if (strcmp(opt, "yes") == 0) {
8038f53455cSigy 		bootopts.b_flags |= B_F_USE_BOOTP;
8048f53455cSigy 	} else if (strcmp(opt, "no") == 0) {
8058f53455cSigy 		bootopts.b_flags &= ~B_F_USE_BOOTP;
8068f53455cSigy 	} else {
8078f53455cSigy 		bad_param();
8088f53455cSigy 	}
8098f53455cSigy }
8108f53455cSigy 
8118f53455cSigy static void
opt_subcmd_ip(char * opt)8128f53455cSigy opt_subcmd_ip(char *opt)
8138f53455cSigy {
8148f53455cSigy 	bootopts.b_remote_ip.s_addr = inet_addr(opt);
8158f53455cSigy 	opt = get_next_arg(opt);
8168f53455cSigy 	bootopts.b_local_ip.s_addr = inet_addr(opt);
8178f53455cSigy 	opt = get_next_arg(opt);
8188f53455cSigy 	bootopts.b_netmask = inet_addr(opt);
8198f53455cSigy 	opt = get_next_arg(opt);
8208f53455cSigy 	bootopts.b_gate_ip.s_addr = inet_addr(opt);
8218f53455cSigy }
8228f53455cSigy 
8238f53455cSigy static void
bootmenu(void)824f8bc0014Sigy bootmenu(void)
825f8bc0014Sigy {
826f8bc0014Sigy 	char	input[LINEBUFLEN];
827f8bc0014Sigy 	char	*cmd;
828f8bc0014Sigy 	char	*opt;
829f8bc0014Sigy 	int	i;
830f8bc0014Sigy 
831f8bc0014Sigy 	for (;;) {
832f8bc0014Sigy 
833f8bc0014Sigy 		/* input a line */
834f8bc0014Sigy 		input[0] = '\0';
835f8bc0014Sigy 		printf("> ");
836*85e3fbd2Sdholland 		kgets(input, sizeof(input));
837f8bc0014Sigy 		cmd = input;
838f8bc0014Sigy 
839f8bc0014Sigy 		/* skip leading whitespace. */
840f8bc0014Sigy 		while(*cmd == ' ')
841f8bc0014Sigy 			cmd++;
842f8bc0014Sigy 
843f8bc0014Sigy 		if(*cmd) {
844f8bc0014Sigy 			/* here, some command entered */
845f8bc0014Sigy 
846f8bc0014Sigy 			opt = get_next_arg(cmd);
847f8bc0014Sigy 
848f8bc0014Sigy 			/* dispatch command */
849f8bc0014Sigy 			for (i = 0; commands[i].c_name != NULL; i++) {
850f8bc0014Sigy 				if (strcmp(cmd, commands[i].c_name) == 0) {
851f8bc0014Sigy 					commands[i].c_fn(opt);
852f8bc0014Sigy 					break;
853f8bc0014Sigy 				}
854f8bc0014Sigy 			}
855f8bc0014Sigy 			if (commands[i].c_name == NULL) {
856f8bc0014Sigy 				printf("unknown command\n");
857f8bc0014Sigy 				command_help(NULL);
858f8bc0014Sigy 			}
859f8bc0014Sigy 		}
860f8bc0014Sigy 
861f8bc0014Sigy 	}
862f8bc0014Sigy }
863f8bc0014Sigy 
864f8bc0014Sigy static char
awaitkey(void)865f8bc0014Sigy awaitkey(void)
866f8bc0014Sigy {
867f8bc0014Sigy 	int	i;
868f8bc0014Sigy 	int	j;
869f8bc0014Sigy 	char	c = 0;
870f8bc0014Sigy 
871f8bc0014Sigy 	while (ISKEY)
872f8bc0014Sigy 		getchar();
873f8bc0014Sigy 
874f8bc0014Sigy 	for (i = BOOTTIMEOUT; i > 0; i--) {
875f8bc0014Sigy 		printf("%d\b", i);
876f8bc0014Sigy 		for (j = 0; j < 1000000; j++) {
877f8bc0014Sigy 			if (ISKEY) {
878f8bc0014Sigy 				while (ISKEY)
879f8bc0014Sigy 					c = getchar();
880f8bc0014Sigy 				goto out;
881f8bc0014Sigy 			}
882f8bc0014Sigy 		}
883f8bc0014Sigy 	}
884f8bc0014Sigy 
885f8bc0014Sigy out:
886f8bc0014Sigy 	printf("0\n");
887f8bc0014Sigy 	return(c);
888f8bc0014Sigy }
889f8bc0014Sigy 
8901625aa91Sigy __dead void
_rtt(void)8911625aa91Sigy _rtt(void)
8921625aa91Sigy {
8931625aa91Sigy 	for (;;)
8941625aa91Sigy 		;
8951625aa91Sigy }
8961625aa91Sigy 
897f8bc0014Sigy int
main(void)898f8bc0014Sigy main(void)
899f8bc0014Sigy {
900f8bc0014Sigy 	char	c;
901f8bc0014Sigy 
902f8bc0014Sigy 	init_devices();
903f8bc0014Sigy 
904f8bc0014Sigy 	comcninit();
905f8bc0014Sigy 
9068f53455cSigy 	opt_subcmd_read(NULL);
9078f53455cSigy 
908f8bc0014Sigy 	print_banner();
909f8bc0014Sigy 
910f8bc0014Sigy 	c = awaitkey();
911f8bc0014Sigy 	if (c != '\r' && c != '\n' && c != '\0') {
912f8bc0014Sigy 		printf("type \"?\" or \"h\" for help.\n");
913f8bc0014Sigy 		bootmenu(); /* does not return */
914f8bc0014Sigy 	}
915f8bc0014Sigy 
916f8bc0014Sigy 	command_boot(NULL);
9178f53455cSigy 	/*
9188f53455cSigy 	 * command_boot() returns only if it failed to boot.
9198f53455cSigy 	 * we enter to boot menu in this case.
9208f53455cSigy 	 */
9218f53455cSigy 	bootmenu();
9228f53455cSigy 
923f8bc0014Sigy 	return 0;
924f8bc0014Sigy }
925