* Implement new mechanism to export U-Boot's functions to standalone
applications: instead of using (PPC-specific) system calls we now
use a jump table; please see doc/README.standalone for details
* Patch by Dave Westwood, 24 Jul 2003:
added support for Unity OS (a proprietary OS)
diff --git a/common/Makefile b/common/Makefile
index 3aa9b65..d144bef 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -42,7 +42,7 @@
cmd_reginfo.o cmd_scsi.o cmd_spi.o cmd_usb.o cmd_vfd.o \
command.o console.o devices.o dlmalloc.o docecc.o \
environment.o env_common.o \
- env_flash.o env_eeprom.o env_nvram.o env_nowhere.o \
+ env_flash.o env_eeprom.o env_nvram.o env_nowhere.o exports.o \
flash.o fpga.o \
hush.o kgdb.o lists.o miiphybb.o miiphyutil.o \
s_record.o soft_i2c.o soft_spi.o spartan2.o \
diff --git a/common/cmd_boot.c b/common/cmd_boot.c
index fe8025d..b2f0331 100644
--- a/common/cmd_boot.c
+++ b/common/cmd_boot.c
@@ -27,13 +27,15 @@
#include <common.h>
#include <command.h>
#include <net.h>
-#include <syscall.h>
/* -------------------------------------------------------------------- */
int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
+#if defined(CONFIG_I386)
+ DECLARE_GLOBAL_DATA_PTR;
+#endif
ulong addr, rc;
int rcode = 0;
@@ -50,6 +52,13 @@
* pass address parameter as argv[0] (aka command name),
* and all remaining args
*/
+#if defined(CONFIG_I386)
+ /*
+ * x86 does not use a dedicated register to pass the pointer
+ * to the global_data
+ */
+ argv[0] = (char *)gd;
+#endif
rc = ((ulong (*)(int, char *[]))addr) (--argc, &argv[1]);
if (rc != 0) rcode = 1;
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index d1d03e3..1343659 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -80,6 +80,13 @@
#if (CONFIG_COMMANDS & CFG_CMD_IMI)
static int image_info (unsigned long addr);
#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_IMLS)
+#include <flash.h>
+extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+#endif
+
static void print_type (image_header_t *hdr);
#ifdef __I386__
@@ -961,6 +968,56 @@
#endif /* CFG_CMD_IMI */
+#if (CONFIG_COMMANDS & CFG_CMD_IMLS)
+/*-----------------------------------------------------------------------
+ * List all images found in flash.
+ */
+int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ flash_info_t *info;
+ int i, j;
+ image_header_t *hdr;
+ ulong checksum;
+
+ for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info) {
+ if (info->flash_id == FLASH_UNKNOWN)
+ goto next_bank;
+ for (j=0; j<CFG_MAX_FLASH_SECT; ++j) {
+
+ if (!(hdr=(image_header_t *)info->start[j]) ||
+ (ntohl(hdr->ih_magic) != IH_MAGIC))
+ goto next_sector;
+
+ /* Copy header so we can blank CRC field for re-calculation */
+ memmove (&header, (char *)hdr, sizeof(image_header_t));
+
+ checksum = ntohl(header.ih_hcrc);
+ header.ih_hcrc = 0;
+
+ if (crc32 (0, (char *)&header, sizeof(image_header_t))
+ != checksum)
+ goto next_sector;
+
+ printf ("Image at %08lX:\n", (ulong)hdr);
+ print_image_hdr( hdr );
+ putc ('\n');
+ next_sector:
+ }
+ next_bank:
+ }
+
+ return (0);
+}
+
+U_BOOT_CMD(
+ imls, 1, 1, do_imls,
+ "imls - list all images found in flash\n",
+ "\n"
+ " - Prints information about all images found at sector\n"
+ " boundaries in flash.\n"
+);
+#endif /* CFG_CMD_IMLS */
+
void
print_image_hdr (image_header_t *hdr)
{
diff --git a/common/cmd_load.c b/common/cmd_load.c
index 0ea8c4b..5622452 100644
--- a/common/cmd_load.c
+++ b/common/cmd_load.c
@@ -28,7 +28,7 @@
#include <command.h>
#include <s_record.h>
#include <net.h>
-#include <syscall.h>
+#include <exports.h>
#if (CONFIG_COMMANDS & CFG_CMD_LOADS)
@@ -213,6 +213,7 @@
static int
read_record (char *buf, ulong len)
{
+ DECLARE_GLOBAL_DATA_PTR;
char *p;
char c;
@@ -236,13 +237,11 @@
}
/* Check for the console hangup (if any different from serial) */
-#ifdef CONFIG_PPC /* we don't have syscall_tbl anywhere else */
- if (syscall_tbl[SYSCALL_GETC] != serial_getc) {
+ if (gd->jt[XF_getc] != serial_getc) {
if (ctrlc()) {
return (-1);
}
}
-#endif
}
/* line too long - truncate */
@@ -479,7 +478,7 @@
printf ("## Ready for binary (kermit) download "
"to 0x%08lX at %d bps...\n",
offset,
- current_baudrate);
+ load_baudrate);
addr = load_serial_bin (offset);
if (addr == ~0) {
diff --git a/common/cmd_log.c b/common/cmd_log.c
index 8780da5..57ef484 100644
--- a/common/cmd_log.c
+++ b/common/cmd_log.c
@@ -86,8 +86,7 @@
post_word = post_word_load();
#ifdef CONFIG_POST
/* The post routines have setup the word so we can simply test it */
- if (((post_word & 0xffff) == POST_POWERON) ||
- ((post_word & 0xffff) == POST_SLOWTEST)) {
+ if (post_word_load () & POST_COLDBOOT) {
logged_chars = log_size = log_start = 0;
*ext_tag = LOGBUFF_MAGIC;
}
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index 7e6c19e..3e22598 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -53,6 +53,8 @@
return 2;
case 'l':
return 4;
+ default:
+ return -1;
}
}
return default_size;
@@ -86,9 +88,10 @@
#define DISP_LINE_LEN 16
int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- ulong addr, size, length;
+ ulong addr, length;
ulong i, nbytes, linebytes;
u_char *cp;
+ int size;
int rc = 0;
/* We use the last specified parameters, unless new ones are
@@ -107,7 +110,8 @@
/* New command specified. Check for a size specification.
* Defaults to long if no or incorrect specification.
*/
- size = cmd_get_data_size(argv[0], 4);
+ if ((size = cmd_get_data_size(argv[0], 4)) < 0)
+ return 1;
/* Address is specified since argc > 1
*/
@@ -199,7 +203,8 @@
int do_mem_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- ulong addr, size, writeval, count;
+ ulong addr, writeval, count;
+ int size;
if ((argc < 3) || (argc > 4)) {
printf ("Usage:\n%s\n", cmdtp->usage);
@@ -208,7 +213,8 @@
/* Check for size specification.
*/
- size = cmd_get_data_size(argv[0], 4);
+ if ((size = cmd_get_data_size(argv[0], 4)) < 1)
+ return 1;
/* Address is specified since argc > 1
*/
@@ -240,7 +246,8 @@
int do_mem_cmp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- ulong size, addr1, addr2, count, ngood;
+ ulong addr1, addr2, count, ngood;
+ int size;
int rcode = 0;
if (argc != 4) {
@@ -250,7 +257,8 @@
/* Check for size specification.
*/
- size = cmd_get_data_size(argv[0], 4);
+ if ((size = cmd_get_data_size(argv[0], 4)) < 0)
+ return 1;
addr1 = simple_strtoul(argv[1], NULL, 16);
addr1 += base_address;
@@ -316,7 +324,8 @@
int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- ulong addr, size, dest, count;
+ ulong addr, dest, count;
+ int size;
if (argc != 4) {
printf ("Usage:\n%s\n", cmdtp->usage);
@@ -325,7 +334,8 @@
/* Check for size specification.
*/
- size = cmd_get_data_size(argv[0], 4);
+ if ((size = cmd_get_data_size(argv[0], 4)) < 0)
+ return 1;
addr = simple_strtoul(argv[1], NULL, 16);
addr += base_address;
@@ -458,7 +468,8 @@
int do_mem_loop (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- ulong addr, size, length, i, junk;
+ ulong addr, length, i, junk;
+ int size;
volatile uint *longp;
volatile ushort *shortp;
volatile u_char *cp;
@@ -471,7 +482,8 @@
/* Check for a size spefication.
* Defaults to long if no or incorrect specification.
*/
- size = cmd_get_data_size(argv[0], 4);
+ if ((size = cmd_get_data_size(argv[0], 4)) < 0)
+ return 1;
/* Address is always specified.
*/
@@ -839,8 +851,8 @@
static int
mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[])
{
- ulong addr, size, i;
- int nbytes;
+ ulong addr, i;
+ int nbytes, size;
extern char console_buffer[];
if (argc != 2) {
@@ -861,7 +873,8 @@
/* New command specified. Check for a size specification.
* Defaults to long if no or incorrect specification.
*/
- size = cmd_get_data_size(argv[0], 4);
+ if ((size = cmd_get_data_size(argv[0], 4)) < 0)
+ return 1;
/* Address is specified since argc > 1
*/
diff --git a/common/console.c b/common/console.c
index 8c94aa7..148c599 100644
--- a/common/console.c
+++ b/common/console.c
@@ -25,9 +25,7 @@
#include <stdarg.h>
#include <malloc.h>
#include <console.h>
-#include <syscall.h>
-
-void **syscall_tbl;
+#include <exports.h>
#ifdef CONFIG_AMIGAONEG3SE
int console_changed = 0;
@@ -52,6 +50,7 @@
static int console_setfile (int file, device_t * dev)
{
+ DECLARE_GLOBAL_DATA_PTR;
int error = 0;
if (dev == NULL)
@@ -78,13 +77,13 @@
*/
switch (file) {
case stdin:
- syscall_tbl[SYSCALL_GETC] = dev->getc;
- syscall_tbl[SYSCALL_TSTC] = dev->tstc;
+ gd->jt[XF_getc] = dev->getc;
+ gd->jt[XF_tstc] = dev->tstc;
break;
case stdout:
- syscall_tbl[SYSCALL_PUTC] = dev->putc;
- syscall_tbl[SYSCALL_PUTS] = dev->puts;
- syscall_tbl[SYSCALL_PRINTF] = printf;
+ gd->jt[XF_putc] = dev->putc;
+ gd->jt[XF_puts] = dev->puts;
+ gd->jt[XF_printf] = printf;
break;
}
break;
@@ -394,15 +393,16 @@
/* Called after the relocation - use desired console functions */
int console_init_r (void)
{
+ DECLARE_GLOBAL_DATA_PTR;
char *stdinname, *stdoutname, *stderrname;
device_t *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
/* set default handlers at first */
- syscall_tbl[SYSCALL_GETC] = serial_getc;
- syscall_tbl[SYSCALL_TSTC] = serial_tstc;
- syscall_tbl[SYSCALL_PUTC] = serial_putc;
- syscall_tbl[SYSCALL_PUTS] = serial_puts;
- syscall_tbl[SYSCALL_PRINTF] = serial_printf;
+ gd->jt[XF_getc] = serial_getc;
+ gd->jt[XF_tstc] = serial_tstc;
+ gd->jt[XF_putc] = serial_putc;
+ gd->jt[XF_puts] = serial_puts;
+ gd->jt[XF_printf] = serial_printf;
/* stdin stdout and stderr are in environment */
/* scan for it */
diff --git a/common/exports.c b/common/exports.c
new file mode 100644
index 0000000..22002cc
--- /dev/null
+++ b/common/exports.c
@@ -0,0 +1,31 @@
+#include <common.h>
+#include <exports.h>
+
+static void dummy(void)
+{
+}
+
+unsigned long get_version(void)
+{
+ return XF_VERSION;
+}
+
+void jumptable_init (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ int i;
+
+ gd->jt = (void **) malloc (XF_MAX * sizeof (void *));
+ for (i = 0; i < XF_MAX; i++)
+ gd->jt[i] = (void *) dummy;
+
+ gd->jt[XF_get_version] = (void *) get_version;
+ gd->jt[XF_malloc] = (void *) malloc;
+ gd->jt[XF_free] = (void *) free;
+ gd->jt[XF_get_timer] = (void *)get_timer;
+ gd->jt[XF_udelay] = (void *)udelay;
+#if defined(CONFIG_I386) || defined(CONFIG_PPC)
+ gd->jt[XF_install_hdlr] = (void *) irq_install_handler;
+ gd->jt[XF_free_hdlr] = (void *) irq_free_handler;
+#endif
+}