/*-
* Copyright (c) 2000 Benno Rice <benno@jeamland.net>
* Copyright (c) 2000 Stephane Potvin <sepotvin@videotron.ca>
* Copyright (c) 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
__FBSDID("$FreeBSD$");
#include <stand.h>
#include "api_public.h"
#include "bootstrap.h"
#include "glue.h"
#include "libuboot.h"
#ifndef nitems
#define nitems(x) (sizeof((x)) / sizeof((x)[0]))
#endif
int devs_no;
struct device_type {
const char *name;
int type;
} device_types[] = {
{ "disk", DEV_TYP_STOR },
{ "net", DEV_TYP_NET }
};
extern char end[];
extern char bootprog_name[];
extern char bootprog_rev[];
extern char bootprog_date[];
extern char bootprog_maker[];
extern unsigned char _etext[];
extern unsigned char _edata[];
extern unsigned char __bss_start[];
extern unsigned char __sbss_start[];
extern unsigned char __sbss_end[];
extern unsigned char _end[];
#ifdef LOADER_FDT_SUPPORT
#endif
static void
{
#ifdef DEBUG
printf("signature:\n");
#endif
}
static void
dump_addr_info(void)
{
#ifdef DEBUG
printf("\naddresses info:\n");
#endif
}
static uint64_t
{
int i;
size = 0;
return (size);
}
static void
meminfo(void)
{
int i;
panic("could not retrieve system info");
for (i = 0; i < 3; i++) {
if (size > 0)
}
}
static const char *
{
int i;
int namelen;
if (devstr) {
for (i = 0; i < nitems(device_types); i++) {
dt = &device_types[i];
}
}
}
*devtype = -1;
return (NULL);
}
static const char *
{
int i;
for (i = 0; i < nitems(device_types); i++)
return (device_types[i].name);
return ("<unknown>");
}
/*
* Parse a device string into type, unit, slice and partition numbers. A
* returned value of -1 for type indicates a search should be done for the
* first loadable device, otherwise a returned value of -1 for unit
* indicates a search should be done for the first loadable device of the
* given type.
*
* The returned values for slice and partition are interpreted by
* disk_open().
*
* Valid device strings: For device types:
*
* <type_name> DEV_TYP_STOR, DEV_TYP_NET
* <type_name><unit> DEV_TYP_STOR, DEV_TYP_NET
* <type_name><unit>: DEV_TYP_STOR, DEV_TYP_NET
* <type_name><unit>:<slice> DEV_TYP_STOR
* <type_name><unit>:<slice>. DEV_TYP_STOR
* <type_name><unit>:<slice>.<partition> DEV_TYP_STOR
*
* For valid type names, see the device_types array, above.
*
* Slice numbers are 1-based. 0 is a wildcard.
*/
static void
{
char *devstr;
const char *p;
char *endp;
*type = -1;
*unit = -1;
*slice = 0;
*partition = -1;
printf("U-Boot env: loaderdev not set, will probe all devices.\n");
return;
}
/* Ignore optional spaces after the device name. */
while (*p == ' ')
p++;
/* Unknown device name, or a known name without unit number. */
return;
}
/* Malformed unit number. */
if (!isdigit(*p)) {
*type = -1;
return;
}
/* Guaranteed to extract a number from the string, as *p is a digit. */
p = endp;
/* Known device name with unit number and nothing else. */
if (*p == '\0') {
return;
}
/* Device string is malformed beyond unit number. */
if (*p != ':') {
*type = -1;
*unit = -1;
return;
}
p++;
/* No slice and partition specification. */
if ('\0' == *p )
return;
/* Only DEV_TYP_STOR devices can have a slice specification. */
if (!(*type & DEV_TYP_STOR)) {
*type = -1;
*unit = -1;
return;
}
/* Malformed slice number. */
if (p == endp) {
*type = -1;
*unit = -1;
*slice = 0;
return;
}
p = endp;
/* No partition specification. */
if (*p == '\0')
return;
/* Device string is malformed beyond slice number. */
if (*p != '.') {
*type = -1;
*unit = -1;
*slice = 0;
return;
}
p++;
/* No partition specification. */
if (*p == '\0')
return;
p = endp;
/* Full, valid device string. */
if (*endp == '\0')
return;
/* Junk beyond partition number. */
*type = -1;
*unit = -1;
*slice = 0;
*partition = -1;
}
static void
{
else
else
printf(" Checking unit=%d slice=%s partition=%s...",
}
static int
int load_partition)
{
struct open_file f;
open_result = -1;
if (load_type == -1) {
printf(" Probing all disk devices...\n");
/* Try each disk in succession until one works. */
if (open_result == 0) {
printf(" good.\n");
return (0);
}
printf("\n");
}
return (-1);
}
if (load_unit == -1) {
/* Try each disk of given type in succession until one works. */
break;
if (open_result == 0) {
printf(" good.\n");
return (0);
}
printf("\n");
}
return (-1);
}
if (open_result == 0) {
printf(" good.\n");
return (0);
}
printf("\n");
}
return (-1);
}
int
main(void)
{
int i;
const char *ldev;
/*
* If we can't find the magic signature and related info, exit with a
* unique error code that U-Boot reports as "## Application terminated,
* rc = 0xnnbadab1". Hopefully 'badab1' looks enough like "bad api" to
* provide a clue. It's better than 0xffffffff anyway.
*/
if (!api_search_sig(&sig))
return (0x01badab1);
if (syscall_ptr == NULL)
return (0x02badab1);
return (0x03badab1);
/* Clear BSS sections */
/*
* Initialise the heap as early as possible. Once this is done,
* alloc() is usable. The stack is buried inside us, so this is safe.
*/
/*
* Set up console.
*/
cons_probe();
printf("\n");
printf("\n");
meminfo();
/*
* Enumerate U-Boot devices
*/
if ((devs_no = ub_dev_enum()) == 0)
panic("no U-Boot devices found");
/*
* March through the device switch probing for things.
*/
continue;
continue;
load_partition) == 0)
break;
}
break;
}
/*
* If we couldn't find a boot device, return an error to u-boot.
* U-boot may be running a boot script that can try something different
* so returning an error is better than forcing a reboot.
*/
printf("No boot device found!\n");
return (0xbadef1ce);
}
return (0);
}
static int
{
return (CMD_OK);
}
static int
{
printf("Resetting...\n");
ub_reset();
printf("Reset failed!\n");
while(1);
}
static int
{
int i;
if ((devs_no = ub_dev_enum()) == 0) {
command_errmsg = "no U-Boot devices found!?";
return (CMD_ERROR);
}
printf("U-Boot devices:\n");
for (i = 0; i < devs_no; i++) {
ub_dump_di(i);
printf("\n");
}
return (CMD_OK);
}
static int
{
command_errmsg = "could not retrieve U-Boot sys info!?";
return (CMD_ERROR);
}
printf("U-Boot system info:\n");
ub_dump_si(si);
return (CMD_OK);
}
enum ubenv_action {
};
static void
{
const char *val;
char *wrk;
int len;
/*
* On an import with the variable name formatted as ldname=ubname,
* import the uboot variable ubname into the loader variable ldname,
* otherwise the historical behavior is to import to uboot.ubname.
*/
if (action == UBENV_IMPORT) {
if (len == 0) {
return;
}
} else {
}
}
/*
* If the user prepended "uboot." (which is how they usually see these
* names) strip it off as a convenience.
*/
}
/* If there is no variable name left, punt. */
if (var[0] == 0) {
printf("empty variable name\n");
return;
}
if (action == UBENV_SHOW) {
else
} else if (action == UBENV_IMPORT) {
}
}
}
static int
{
const char *var;
int i;
if (argc > 1) {
action = UBENV_SHOW;
}
if (action == UBENV_UNKNOWN) {
command_errmsg = "usage: 'ubenv <import|show> [var ...]";
return (CMD_ERROR);
}
if (argc > 2) {
for (i = 2; i < argc; i++)
} else {
for (;;) {
break;
}
}
return (CMD_OK);
}
#ifdef LOADER_FDT_SUPPORT
/*
* Since proper fdt command handling function is defined in fdt_loader_cmd.c,
* and declaring it as extern is in contradiction with COMMAND_SET() macro
* (which uses static pointer), we're defining wrapper function, which
* calls the proper fdt handling routine.
*/
static int
{
}
#endif