main.c revision 182732
1176348Smarcel/*-
2176348Smarcel * Copyright (c) 2000 Benno Rice <benno@jeamland.net>
3176348Smarcel * Copyright (c) 2000 Stephane Potvin <sepotvin@videotron.ca>
4182732Sraj * Copyright (c) 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
5176348Smarcel * All rights reserved.
6176348Smarcel *
7176348Smarcel * Redistribution and use in source and binary forms, with or without
8176348Smarcel * modification, are permitted provided that the following conditions
9176348Smarcel * are met:
10176348Smarcel * 1. Redistributions of source code must retain the above copyright
11176348Smarcel *    notice, this list of conditions and the following disclaimer.
12176348Smarcel * 2. Redistributions in binary form must reproduce the above copyright
13176348Smarcel *    notice, this list of conditions and the following disclaimer in the
14176348Smarcel *    documentation and/or other materials provided with the distribution.
15176348Smarcel *
16176348Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17176348Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18176348Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19176348Smarcel * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20176348Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21176348Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22176348Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23176348Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24176348Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25176348Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26176348Smarcel * SUCH DAMAGE.
27176348Smarcel */
28176348Smarcel
29176348Smarcel#include <sys/cdefs.h>
30176348Smarcel__FBSDID("$FreeBSD: head/sys/boot/uboot/common/main.c 182732 2008-09-03 17:48:41Z raj $");
31176348Smarcel
32176348Smarcel#include <stand.h>
33176482Smarcel
34176482Smarcel#include "api_public.h"
35176348Smarcel#include "bootstrap.h"
36176482Smarcel#include "glue.h"
37176348Smarcel#include "libuboot.h"
38176348Smarcel
39182732Srajstruct uboot_devdesc currdev;
40182732Srajstruct arch_switch archsw;		/* MI/MD interface boundary */
41182732Srajint devs_no;
42176348Smarcel
43176348Smarcelextern char end[];
44176348Smarcelextern char bootprog_name[];
45176348Smarcelextern char bootprog_rev[];
46176348Smarcelextern char bootprog_date[];
47176348Smarcelextern char bootprog_maker[];
48176348Smarcel
49176348Smarcelextern unsigned char _etext[];
50176348Smarcelextern unsigned char _edata[];
51176348Smarcelextern unsigned char __bss_start[];
52176348Smarcelextern unsigned char __sbss_start[];
53176348Smarcelextern unsigned char __sbss_end[];
54176348Smarcelextern unsigned char _end[];
55176348Smarcel
56182732Srajstatic void
57182732Srajdump_sig(struct api_signature *sig)
58176348Smarcel{
59176348Smarcel#ifdef DEBUG
60176348Smarcel	printf("signature:\n");
61176348Smarcel	printf("  version\t= %d\n", sig->version);
62176348Smarcel	printf("  checksum\t= 0x%08x\n", sig->checksum);
63176348Smarcel	printf("  sc entry\t= 0x%08x\n", sig->syscall);
64176348Smarcel#endif
65176348Smarcel}
66182732Sraj
67176348Smarcelstatic void
68176348Smarceldump_addr_info(void)
69176348Smarcel{
70176348Smarcel#ifdef DEBUG
71176348Smarcel	printf("\naddresses info:\n");
72182732Sraj	printf(" _etext (sdata) = 0x%08x\n", (uint32_t)_etext);
73182732Sraj	printf(" _edata         = 0x%08x\n", (uint32_t)_edata);
74182732Sraj	printf(" __sbss_start   = 0x%08x\n", (uint32_t)__sbss_start);
75182732Sraj	printf(" __sbss_end     = 0x%08x\n", (uint32_t)__sbss_end);
76182732Sraj	printf(" __sbss_start   = 0x%08x\n", (uint32_t)__bss_start);
77182732Sraj	printf(" _end           = 0x%08x\n", (uint32_t)_end);
78182732Sraj	printf(" syscall entry  = 0x%08x\n", (uint32_t)syscall_ptr);
79176348Smarcel#endif
80176348Smarcel}
81176348Smarcel
82176348Smarcelstatic uint64_t
83182732Srajmemsize(struct sys_info *si, int flags)
84176348Smarcel{
85182732Sraj	uint64_t size;
86182732Sraj	int i;
87176348Smarcel
88176482Smarcel	size = 0;
89176348Smarcel	for (i = 0; i < si->mr_no; i++)
90176348Smarcel		if (si->mr[i].flags == flags && si->mr[i].size)
91176482Smarcel			size += (si->mr[i].size);
92176348Smarcel
93176482Smarcel	return (size);
94176348Smarcel}
95176348Smarcel
96182732Srajstatic void
97182732Srajmeminfo(void)
98182732Sraj{
99182732Sraj	uint64_t size;
100182732Sraj	struct sys_info *si;
101182732Sraj	int t[3] = { MR_ATTR_DRAM, MR_ATTR_FLASH, MR_ATTR_SRAM };
102182732Sraj	int i;
103182732Sraj
104182732Sraj	if ((si = ub_get_sys_info()) == NULL)
105182732Sraj		panic("could not retrieve system info");
106182732Sraj
107182732Sraj	for (i = 0; i < 3; i++) {
108182732Sraj		size = memsize(si, t[i]);
109182732Sraj		if (size > 0)
110182732Sraj			printf("%s:\t %lldMB\n", ub_mem_type(t[i]),
111182732Sraj			    size / 1024 / 1024);
112182732Sraj	}
113182732Sraj}
114182732Sraj
115176348Smarcelint
116176348Smarcelmain(void)
117176348Smarcel{
118176348Smarcel	struct api_signature *sig = NULL;
119182723Sraj	int i;
120176348Smarcel
121176348Smarcel	if (!api_search_sig(&sig))
122182732Sraj		return (-1);
123176348Smarcel
124176348Smarcel	syscall_ptr = sig->syscall;
125176348Smarcel	if (syscall_ptr == NULL)
126182732Sraj		return (-2);
127176348Smarcel
128176348Smarcel	if (sig->version > API_SIG_VERSION)
129182732Sraj		return (-3);
130176348Smarcel
131176348Smarcel        /* Clear BSS sections */
132176348Smarcel	bzero(__sbss_start, __sbss_end - __sbss_start);
133176348Smarcel	bzero(__bss_start, _end - __bss_start);
134176348Smarcel
135176348Smarcel	/*
136176348Smarcel         * Set up console.
137176348Smarcel         */
138176348Smarcel	cons_probe();
139176348Smarcel
140182723Sraj	printf("Compatible API signature found @%x\n", (uint32_t)sig);
141176348Smarcel
142176348Smarcel	dump_sig(sig);
143176348Smarcel	dump_addr_info();
144176348Smarcel
145176348Smarcel	/*
146176348Smarcel	 * Initialise the heap as early as possible.  Once this is done,
147176348Smarcel	 * alloc() is usable. The stack is buried inside us, so this is
148176348Smarcel	 * safe.
149176348Smarcel	 */
150176348Smarcel	setheap((void *)end, (void *)(end + 512 * 1024));
151176348Smarcel
152176348Smarcel	/*
153176348Smarcel	 * Enumerate U-Boot devices
154176348Smarcel	 */
155176348Smarcel	if ((devs_no = ub_dev_enum()) == 0)
156182732Sraj		panic("no U-Boot devices found");
157182732Sraj	printf("Number of U-Boot devices: %d\n", devs_no);
158176348Smarcel
159176348Smarcel	/*
160176348Smarcel	 * March through the device switch probing for things.
161176348Smarcel	 */
162176348Smarcel	for (i = 0; devsw[i] != NULL; i++)
163176348Smarcel		if (devsw[i]->dv_init != NULL)
164176348Smarcel			(devsw[i]->dv_init)();
165176348Smarcel
166176348Smarcel	printf("\n");
167176348Smarcel	printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
168176348Smarcel	printf("(%s, %s)\n", bootprog_maker, bootprog_date);
169182732Sraj	meminfo();
170176348Smarcel
171176348Smarcel	/* XXX only support netbooting for now */
172176348Smarcel	for (i = 0; devsw[i] != NULL; i++)
173177152Sobrien		if (strncmp(devsw[i]->dv_name, "net",
174177152Sobrien		    strlen(devsw[i]->dv_name)) == 0)
175176348Smarcel			break;
176176348Smarcel
177176348Smarcel	if (devsw[i] == NULL)
178176348Smarcel		panic("no network devices?!");
179176348Smarcel
180176348Smarcel	currdev.d_dev = devsw[i];
181176348Smarcel	currdev.d_type = currdev.d_dev->dv_type;
182176348Smarcel	currdev.d_unit = 0;
183176348Smarcel
184176348Smarcel	env_setenv("currdev", EV_VOLATILE, uboot_fmtdev(&currdev),
185177152Sobrien	    uboot_setcurrdev, env_nounset);
186176348Smarcel	env_setenv("loaddev", EV_VOLATILE, uboot_fmtdev(&currdev),
187177152Sobrien	    env_noset, env_nounset);
188176348Smarcel
189176348Smarcel	setenv("LINES", "24", 1);		/* optional */
190176348Smarcel	setenv("prompt", "loader>", 1);
191176348Smarcel
192176348Smarcel	archsw.arch_getdev = uboot_getdev;
193176348Smarcel	archsw.arch_copyin = uboot_copyin;
194176348Smarcel	archsw.arch_copyout = uboot_copyout;
195176348Smarcel	archsw.arch_readin = uboot_readin;
196176348Smarcel	archsw.arch_autoload = uboot_autoload;
197176348Smarcel
198176348Smarcel	interact();				/* doesn't return */
199176348Smarcel
200182732Sraj	return (0);
201176348Smarcel}
202176348Smarcel
203176348Smarcel
204176348SmarcelCOMMAND_SET(heap, "heap", "show heap usage", command_heap);
205176348Smarcelstatic int
206176348Smarcelcommand_heap(int argc, char *argv[])
207176348Smarcel{
208182723Sraj
209182723Sraj	printf("heap base at %p, top at %p, used %d\n", end, sbrk(0),
210177152Sobrien	    sbrk(0) - end);
211176348Smarcel
212182732Sraj	return (CMD_OK);
213176348Smarcel}
214176348Smarcel
215176348SmarcelCOMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
216176348Smarcelstatic int
217176348Smarcelcommand_reboot(int argc, char *argv[])
218176348Smarcel{
219176348Smarcel	printf("Resetting...\n");
220176348Smarcel	ub_reset();
221176348Smarcel
222176348Smarcel	printf("Reset failed!\n");
223176348Smarcel	while(1);
224176348Smarcel}
225182732Sraj
226182732SrajCOMMAND_SET(devinfo, "devinfo", "show U-Boot devices", command_devinfo);
227182732Srajstatic int
228182732Srajcommand_devinfo(int argc, char *argv[])
229182732Sraj{
230182732Sraj	int i;
231182732Sraj
232182732Sraj	if ((devs_no = ub_dev_enum()) == 0) {
233182732Sraj		command_errmsg = "no U-Boot devices found!?";
234182732Sraj		return (CMD_ERROR);
235182732Sraj	}
236182732Sraj
237182732Sraj	printf("U-Boot devices:\n");
238182732Sraj	for (i = 0; i < devs_no; i++) {
239182732Sraj		ub_dump_di(i);
240182732Sraj		printf("\n");
241182732Sraj	}
242182732Sraj	return (CMD_OK);
243182732Sraj}
244182732Sraj
245182732SrajCOMMAND_SET(sysinfo, "sysinfo", "show U-Boot system info", command_sysinfo);
246182732Srajstatic int
247182732Srajcommand_sysinfo(int argc, char *argv[])
248182732Sraj{
249182732Sraj	struct sys_info *si;
250182732Sraj
251182732Sraj	if ((si = ub_get_sys_info()) == NULL) {
252182732Sraj		command_errmsg = "could not retrieve U-Boot sys info!?";
253182732Sraj		return (CMD_ERROR);
254182732Sraj	}
255182732Sraj
256182732Sraj	printf("U-Boot system info:\n");
257182732Sraj	ub_dump_si(si);
258182732Sraj	return (CMD_OK);
259182732Sraj}
260