main.c revision 177152
1/*-
2 * Copyright (c) 2000 Benno Rice <benno@jeamland.net>
3 * Copyright (c) 2000 Stephane Potvin <sepotvin@videotron.ca>
4 * Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/boot/uboot/common/main.c 177152 2008-03-13 17:54:21Z obrien $");
31
32#include <stand.h>
33
34#include "api_public.h"
35#include "bootstrap.h"
36#include "glue.h"
37#include "libuboot.h"
38
39struct uboot_devdesc	currdev;
40struct arch_switch	archsw;		/* MI/MD interface boundary */
41int			devs_no;
42
43extern char end[];
44extern char bootprog_name[];
45extern char bootprog_rev[];
46extern char bootprog_date[];
47extern char bootprog_maker[];
48
49static char bootargs[128];
50
51extern unsigned char _etext[];
52extern unsigned char _edata[];
53extern unsigned char __bss_start[];
54extern unsigned char __sbss_start[];
55extern unsigned char __sbss_end[];
56extern unsigned char _end[];
57
58void dump_si(struct sys_info *si)
59{
60#ifdef DEBUG
61	printf("sys info:\n");
62	printf("  clkbus\t= 0x%08x\n", si->clk_bus);
63	printf("  clkcpu\t= 0x%08x\n", si->clk_cpu);
64	printf("  bar\t\t= 0x%08x\n", si->bar);
65#endif
66}
67
68static void dump_sig(struct api_signature *sig)
69{
70#ifdef DEBUG
71	printf("signature:\n");
72	printf("  version\t= %d\n", sig->version);
73	printf("  checksum\t= 0x%08x\n", sig->checksum);
74	printf("  sc entry\t= 0x%08x\n", sig->syscall);
75#endif
76}
77static void
78dump_addr_info(void)
79{
80#ifdef DEBUG
81	printf("\naddresses info:\n");
82	printf(" _etext (sdata) = 0x%08x\n", (u_int32_t)_etext);
83	printf(" _edata         = 0x%08x\n", (u_int32_t)_edata);
84	printf(" __sbss_start   = 0x%08x\n", (u_int32_t)__sbss_start);
85	printf(" __sbss_end     = 0x%08x\n", (u_int32_t)__sbss_end);
86	printf(" __sbss_start   = 0x%08x\n", (u_int32_t)__bss_start);
87	printf(" _end           = 0x%08x\n", (u_int32_t)_end);
88	printf(" syscall entry  = 0x%08x\n", (u_int32_t)syscall_ptr);
89#endif
90}
91
92static uint64_t
93memsize(int flags)
94{
95	int		i;
96	struct sys_info	*si;
97	uint64_t	size;
98
99	if ((si = ub_get_sys_info()) == NULL)
100		return 0;
101
102	size = 0;
103	for (i = 0; i < si->mr_no; i++)
104		if (si->mr[i].flags == flags && si->mr[i].size)
105			size += (si->mr[i].size);
106
107	return (size);
108}
109
110int
111main(void)
112{
113	char **bargv;
114	char *ch;
115	int bargc, i;
116	struct api_signature *sig = NULL;
117
118	if (!api_search_sig(&sig))
119		return -1;
120
121	syscall_ptr = sig->syscall;
122	if (syscall_ptr == NULL)
123		return -2;
124
125	if (sig->version > API_SIG_VERSION)
126		return -3;
127
128        /* Clear BSS sections */
129	bzero(__sbss_start, __sbss_end - __sbss_start);
130	bzero(__bss_start, _end - __bss_start);
131
132	/*
133         * Set up console.
134         */
135	cons_probe();
136
137	printf("Compatible API signature found @%x\n", sig);
138
139	dump_sig(sig);
140	dump_addr_info();
141
142	/*
143	 * Initialise the heap as early as possible.  Once this is done,
144	 * alloc() is usable. The stack is buried inside us, so this is
145	 * safe.
146	 */
147	setheap((void *)end, (void *)(end + 512 * 1024));
148
149	/*
150	 * Enumerate U-Boot devices
151	 */
152	if ((devs_no = ub_dev_enum()) == 0)
153		panic("no devices found");
154	printf("Number of U-Boot devices found %d\n", devs_no);
155
156	/* XXX all our dv_init()s currently don't do anything... */
157	/*
158	 * March through the device switch probing for things.
159	 */
160	for (i = 0; devsw[i] != NULL; i++)
161		if (devsw[i]->dv_init != NULL)
162			(devsw[i]->dv_init)();
163
164	printf("\n");
165	printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
166	printf("(%s, %s)\n", bootprog_maker, bootprog_date);
167	printf("Memory: %lldMB\n", memsize(MR_ATTR_DRAM) / 1024 / 1024);
168	printf("FLASH:  %lldMB\n", memsize(MR_ATTR_FLASH) / 1024 / 1024);
169//	printf("SRAM:   %lldMB\n", memsize(MR_ATTR_SRAM) / 1024 / 1024);
170
171	/* XXX only support netbooting for now */
172	for (i = 0; devsw[i] != NULL; i++)
173		if (strncmp(devsw[i]->dv_name, "net",
174		    strlen(devsw[i]->dv_name)) == 0)
175			break;
176
177	if (devsw[i] == NULL)
178		panic("no network devices?!");
179
180	currdev.d_dev = devsw[i];
181	currdev.d_type = currdev.d_dev->dv_type;
182	currdev.d_unit = 0;
183
184	env_setenv("currdev", EV_VOLATILE, uboot_fmtdev(&currdev),
185	    uboot_setcurrdev, env_nounset);
186	env_setenv("loaddev", EV_VOLATILE, uboot_fmtdev(&currdev),
187	    env_noset, env_nounset);
188
189	setenv("LINES", "24", 1);		/* optional */
190	setenv("prompt", "loader>", 1);
191
192	archsw.arch_getdev = uboot_getdev;
193	archsw.arch_copyin = uboot_copyin;
194	archsw.arch_copyout = uboot_copyout;
195	archsw.arch_readin = uboot_readin;
196	archsw.arch_autoload = uboot_autoload;
197
198	interact();				/* doesn't return */
199
200	return 0;
201}
202
203
204COMMAND_SET(heap, "heap", "show heap usage", command_heap);
205static int
206command_heap(int argc, char *argv[])
207{
208	printf("heap base at %p, top at %p, used %ld\n", end, sbrk(0),
209	    sbrk(0) - end);
210
211	return(CMD_OK);
212}
213
214COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
215static int
216command_reboot(int argc, char *argv[])
217{
218	printf("Resetting...\n");
219	ub_reset();
220
221	printf("Reset failed!\n");
222	while(1);
223}
224