main.c revision 182723
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 182723 2008-09-03 15:39:50Z raj $");
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
49extern unsigned char _etext[];
50extern unsigned char _edata[];
51extern unsigned char __bss_start[];
52extern unsigned char __sbss_start[];
53extern unsigned char __sbss_end[];
54extern unsigned char _end[];
55
56void dump_si(struct sys_info *si)
57{
58#ifdef DEBUG
59	printf("sys info:\n");
60	printf("  clkbus\t= 0x%08x\n", si->clk_bus);
61	printf("  clkcpu\t= 0x%08x\n", si->clk_cpu);
62	printf("  bar\t\t= 0x%08x\n", si->bar);
63#endif
64}
65
66static void dump_sig(struct api_signature *sig)
67{
68#ifdef DEBUG
69	printf("signature:\n");
70	printf("  version\t= %d\n", sig->version);
71	printf("  checksum\t= 0x%08x\n", sig->checksum);
72	printf("  sc entry\t= 0x%08x\n", sig->syscall);
73#endif
74}
75static void
76dump_addr_info(void)
77{
78#ifdef DEBUG
79	printf("\naddresses info:\n");
80	printf(" _etext (sdata) = 0x%08x\n", (u_int32_t)_etext);
81	printf(" _edata         = 0x%08x\n", (u_int32_t)_edata);
82	printf(" __sbss_start   = 0x%08x\n", (u_int32_t)__sbss_start);
83	printf(" __sbss_end     = 0x%08x\n", (u_int32_t)__sbss_end);
84	printf(" __sbss_start   = 0x%08x\n", (u_int32_t)__bss_start);
85	printf(" _end           = 0x%08x\n", (u_int32_t)_end);
86	printf(" syscall entry  = 0x%08x\n", (u_int32_t)syscall_ptr);
87#endif
88}
89
90static uint64_t
91memsize(int flags)
92{
93	int		i;
94	struct sys_info	*si;
95	uint64_t	size;
96
97	if ((si = ub_get_sys_info()) == NULL)
98		return 0;
99
100	size = 0;
101	for (i = 0; i < si->mr_no; i++)
102		if (si->mr[i].flags == flags && si->mr[i].size)
103			size += (si->mr[i].size);
104
105	return (size);
106}
107
108int
109main(void)
110{
111	struct api_signature *sig = NULL;
112	int i;
113
114	if (!api_search_sig(&sig))
115		return -1;
116
117	syscall_ptr = sig->syscall;
118	if (syscall_ptr == NULL)
119		return -2;
120
121	if (sig->version > API_SIG_VERSION)
122		return -3;
123
124        /* Clear BSS sections */
125	bzero(__sbss_start, __sbss_end - __sbss_start);
126	bzero(__bss_start, _end - __bss_start);
127
128	/*
129         * Set up console.
130         */
131	cons_probe();
132
133	printf("Compatible API signature found @%x\n", (uint32_t)sig);
134
135	dump_sig(sig);
136	dump_addr_info();
137
138	/*
139	 * Initialise the heap as early as possible.  Once this is done,
140	 * alloc() is usable. The stack is buried inside us, so this is
141	 * safe.
142	 */
143	setheap((void *)end, (void *)(end + 512 * 1024));
144
145	/*
146	 * Enumerate U-Boot devices
147	 */
148	if ((devs_no = ub_dev_enum()) == 0)
149		panic("no devices found");
150	printf("Number of U-Boot devices found %d\n", devs_no);
151
152	/* XXX all our dv_init()s currently don't do anything... */
153	/*
154	 * March through the device switch probing for things.
155	 */
156	for (i = 0; devsw[i] != NULL; i++)
157		if (devsw[i]->dv_init != NULL)
158			(devsw[i]->dv_init)();
159
160	printf("\n");
161	printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
162	printf("(%s, %s)\n", bootprog_maker, bootprog_date);
163	printf("Memory: %lldMB\n", memsize(MR_ATTR_DRAM) / 1024 / 1024);
164	printf("FLASH:  %lldMB\n", memsize(MR_ATTR_FLASH) / 1024 / 1024);
165//	printf("SRAM:   %lldMB\n", memsize(MR_ATTR_SRAM) / 1024 / 1024);
166
167	/* XXX only support netbooting for now */
168	for (i = 0; devsw[i] != NULL; i++)
169		if (strncmp(devsw[i]->dv_name, "net",
170		    strlen(devsw[i]->dv_name)) == 0)
171			break;
172
173	if (devsw[i] == NULL)
174		panic("no network devices?!");
175
176	currdev.d_dev = devsw[i];
177	currdev.d_type = currdev.d_dev->dv_type;
178	currdev.d_unit = 0;
179
180	env_setenv("currdev", EV_VOLATILE, uboot_fmtdev(&currdev),
181	    uboot_setcurrdev, env_nounset);
182	env_setenv("loaddev", EV_VOLATILE, uboot_fmtdev(&currdev),
183	    env_noset, env_nounset);
184
185	setenv("LINES", "24", 1);		/* optional */
186	setenv("prompt", "loader>", 1);
187
188	archsw.arch_getdev = uboot_getdev;
189	archsw.arch_copyin = uboot_copyin;
190	archsw.arch_copyout = uboot_copyout;
191	archsw.arch_readin = uboot_readin;
192	archsw.arch_autoload = uboot_autoload;
193
194	interact();				/* doesn't return */
195
196	return 0;
197}
198
199
200COMMAND_SET(heap, "heap", "show heap usage", command_heap);
201static int
202command_heap(int argc, char *argv[])
203{
204
205	printf("heap base at %p, top at %p, used %d\n", end, sbrk(0),
206	    sbrk(0) - end);
207
208	return(CMD_OK);
209}
210
211COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
212static int
213command_reboot(int argc, char *argv[])
214{
215	printf("Resetting...\n");
216	ub_reset();
217
218	printf("Reset failed!\n");
219	while(1);
220}
221