Huge patch boils down massive kernel image parsing and boot action
to a modest sequence of code that actually boots the kernel.

Signed-off-by: Andy Green <[EMAIL PROTECTED]>
---

 Makefile             |    5 
 include/image.h      |  572 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/serial.h     |    1 
 include/setup.h      |  269 ++++++++++++++++++++++++
 src/blink_led.c      |    2 
 src/blink_led.h      |    2 
 src/kboot-stage1.lds |   17 +
 src/kboot.h          |    1 
 src/nand_read.c      |   40 +--
 src/serial.c         |   17 +
 src/start_kboot.c    |   10 -
 11 files changed, 890 insertions(+), 46 deletions(-)
 create mode 100644 include/image.h
 create mode 100644 include/setup.h

diff --git a/Makefile b/Makefile
index b279e25..1a73ddb 100644
--- a/Makefile
+++ b/Makefile
@@ -25,8 +25,9 @@ BUILD_VERSION := ${BUILD_BRANCH}_${BUILD_HEAD}
 LDS    = src/kboot-stage1.lds
 INCLUDE        = include
 IMAGE_DIR      = image
-CFLAGS = -Wall -Werror -fno-builtin -ffreestanding -fno-strict-aliasing \
-         -fno-common -ffixed-r8 -I $(INCLUDE) -g -c \
+CFLAGS = -Wall -Werror -I $(INCLUDE) -g -c -O2 -fno-strict-aliasing \
+         -fno-common -ffixed-r8 -msoft-float -fno-builtin -ffreestanding \
+         -march=armv4t -mno-thumb-interwork -Wstrict-prototypes \
          -DBUILD_HOST="${BUILD_HOST}" -DBUILD_VERSION="${BUILD_VERSION}" \
          -DBUILD_DATE="${BUILD_DATE}"
 LDFLAGS = 
diff --git a/include/image.h b/include/image.h
new file mode 100644
index 0000000..2e3c6ef
--- /dev/null
+++ b/include/image.h
@@ -0,0 +1,572 @@
+/*
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2005
+ * Wolfgang Denk, DENX Software Engineering, [EMAIL PROTECTED]
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ********************************************************************
+ * NOTE: This header file defines an interface to U-Boot. Including
+ * this (unmodified) header file in another file is considered normal
+ * use of U-Boot, and does *not* fall under the heading of "derived
+ * work".
+ ********************************************************************
+ */
+
+#ifndef __IMAGE_H__
+#define __IMAGE_H__
+
+#include <arpa/inet.h>
+
+/*
+ * Operating System Codes
+ */
+#define IH_OS_INVALID          0       /* Invalid OS   */
+#define IH_OS_OPENBSD          1       /* OpenBSD      */
+#define IH_OS_NETBSD           2       /* NetBSD       */
+#define IH_OS_FREEBSD          3       /* FreeBSD      */
+#define IH_OS_4_4BSD           4       /* 4.4BSD       */
+#define IH_OS_LINUX            5       /* Linux        */
+#define IH_OS_SVR4             6       /* SVR4         */
+#define IH_OS_ESIX             7       /* Esix         */
+#define IH_OS_SOLARIS          8       /* Solaris      */
+#define IH_OS_IRIX             9       /* Irix         */
+#define IH_OS_SCO              10      /* SCO          */
+#define IH_OS_DELL             11      /* Dell         */
+#define IH_OS_NCR              12      /* NCR          */
+#define IH_OS_LYNXOS           13      /* LynxOS       */
+#define IH_OS_VXWORKS          14      /* VxWorks      */
+#define IH_OS_PSOS             15      /* pSOS         */
+#define IH_OS_QNX              16      /* QNX          */
+#define IH_OS_U_BOOT           17      /* Firmware     */
+#define IH_OS_RTEMS            18      /* RTEMS        */
+#define IH_OS_ARTOS            19      /* ARTOS        */
+#define IH_OS_UNITY            20      /* Unity OS     */
+
+/*
+ * CPU Architecture Codes (supported by Linux)
+ */
+#define IH_ARCH_INVALID                0       /* Invalid CPU  */
+#define IH_ARCH_ALPHA          1       /* Alpha        */
+#define IH_ARCH_ARM            2       /* ARM          */
+#define IH_ARCH_I386           3       /* Intel x86    */
+#define IH_ARCH_IA64           4       /* IA64         */
+#define IH_ARCH_MIPS           5       /* MIPS         */
+#define IH_ARCH_MIPS64         6       /* MIPS  64 Bit */
+#define IH_ARCH_PPC            7       /* PowerPC      */
+#define IH_ARCH_S390           8       /* IBM S390     */
+#define IH_ARCH_SH             9       /* SuperH       */
+#define IH_ARCH_SPARC          10      /* Sparc        */
+#define IH_ARCH_SPARC64                11      /* Sparc 64 Bit */
+#define IH_ARCH_M68K           12      /* M68K         */
+#define IH_ARCH_NIOS           13      /* Nios-32      */
+#define IH_ARCH_MICROBLAZE     14      /* MicroBlaze   */
+#define IH_ARCH_NIOS2          15      /* Nios-II      */
+#define IH_ARCH_BLACKFIN       16      /* Blackfin     */
+#define IH_ARCH_AVR32          17      /* AVR32        */
+#define IH_ARCH_ST200          18      /* STMicroelectronics ST200  */
+
+/*
+ * Image Types
+ *
+ * "Standalone Programs" are directly runnable in the environment
+ *     provided by U-Boot; it is expected that (if they behave
+ *     well) you can continue to work in U-Boot after return from
+ *     the Standalone Program.
+ * "OS Kernel Images" are usually images of some Embedded OS which
+ *     will take over control completely. Usually these programs
+ *     will install their own set of exception handlers, device
+ *     drivers, set up the MMU, etc. - this means, that you cannot
+ *     expect to re-enter U-Boot except by resetting the CPU.
+ * "RAMDisk Images" are more or less just data blocks, and their
+ *     parameters (address, size) are passed to an OS kernel that is
+ *     being started.
+ * "Multi-File Images" contain several images, typically an OS
+ *     (Linux) kernel image and one or more data images like
+ *     RAMDisks. This construct is useful for instance when you want
+ *     to boot over the network using BOOTP etc., where the boot
+ *     server provides just a single image file, but you want to get
+ *     for instance an OS kernel and a RAMDisk image.
+ *
+ *     "Multi-File Images" start with a list of image sizes, each
+ *     image size (in bytes) specified by an "uint32_t" in network
+ *     byte order. This list is terminated by an "(uint32_t)0".
+ *     Immediately after the terminating 0 follow the images, one by
+ *     one, all aligned on "uint32_t" boundaries (size rounded up to
+ *     a multiple of 4 bytes - except for the last file).
+ *
+ * "Firmware Images" are binary images containing firmware (like
+ *     U-Boot or FPGA images) which usually will be programmed to
+ *     flash memory.
+ *
+ * "Script files" are command sequences that will be executed by
+ *     U-Boot's command interpreter; this feature is especially
+ *     useful when you configure U-Boot to use a real shell (hush)
+ *     as command interpreter (=> Shell Scripts).
+ */
+
+#define IH_TYPE_INVALID                0       /* Invalid Image                
*/
+#define IH_TYPE_STANDALONE     1       /* Standalone Program           */
+#define IH_TYPE_KERNEL         2       /* OS Kernel Image              */
+#define IH_TYPE_RAMDISK                3       /* RAMDisk Image                
*/
+#define IH_TYPE_MULTI          4       /* Multi-File Image             */
+#define IH_TYPE_FIRMWARE       5       /* Firmware Image               */
+#define IH_TYPE_SCRIPT         6       /* Script file                  */
+#define IH_TYPE_FILESYSTEM     7       /* Filesystem Image (any type)  */
+#define IH_TYPE_FLATDT         8       /* Binary Flat Device Tree Blob */
+
+/*
+ * Compression Types
+ */
+#define IH_COMP_NONE           0       /*  No   Compression Used       */
+#define IH_COMP_GZIP           1       /* gzip  Compression Used       */
+#define IH_COMP_BZIP2          2       /* bzip2 Compression Used       */
+
+#define IH_MAGIC       0x27051956      /* Image Magic Number           */
+#define IH_NMLEN               32      /* Image Name Length            */
+
+/*
+ * Legacy format image header,
+ * all data in network byte order (aka natural aka bigendian).
+ */
+typedef struct image_header {
+       uint32_t        ih_magic;       /* Image Header Magic Number    */
+       uint32_t        ih_hcrc;        /* Image Header CRC Checksum    */
+       uint32_t        ih_time;        /* Image Creation Timestamp     */
+       uint32_t        ih_size;        /* Image Data Size              */
+       uint32_t        ih_load;        /* Data  Load  Address          */
+       uint32_t        ih_ep;          /* Entry Point Address          */
+       uint32_t        ih_dcrc;        /* Image Data CRC Checksum      */
+       uint8_t         ih_os;          /* Operating System             */
+       uint8_t         ih_arch;        /* CPU architecture             */
+       uint8_t         ih_type;        /* Image Type                   */
+       uint8_t         ih_comp;        /* Compression Type             */
+       uint8_t         ih_name[IH_NMLEN];      /* Image Name           */
+} image_header_t;
+
+/*
+ * Legacy and FIT format headers used by do_bootm() and do_bootm_<os>()
+ * routines.
+ */
+typedef struct bootm_headers {
+       /*
+        * Legacy os image header, if it is a multi component image
+        * then boot_get_ramdisk() and get_fdt() will attempt to get
+        * data from second and third component accordingly.
+        */
+       image_header_t  *legacy_hdr_os;
+       ulong           legacy_hdr_valid;
+
+#if defined(CONFIG_FIT)
+       const char      *fit_uname_cfg; /* configuration node unit name */
+
+       void            *fit_hdr_os;    /* os FIT image header */
+       const char      *fit_uname_os;  /* os subimage node unit name */
+       int             fit_noffset_os; /* os subimage node offset */
+
+       void            *fit_hdr_rd;    /* init ramdisk FIT image header */
+       const char      *fit_uname_rd;  /* init ramdisk subimage node unit name 
*/
+       int             fit_noffset_rd; /* init ramdisk subimage node offset */
+
+#if defined(CONFIG_PPC)
+       void            *fit_hdr_fdt;   /* FDT blob FIT image header */
+       const char      *fit_uname_fdt; /* FDT blob subimage node unit name */
+       int             fit_noffset_fdt;/* FDT blob subimage node offset */
+#endif
+#endif
+
+       int             verify;         /* getenv("verify")[0] != 'n' */
+       int             autostart;      /* getenv("autostart")[0] != 'n' */
+       struct lmb      *lmb;           /* for memory mgmt */
+} bootm_headers_t;
+
+/*
+ * Some systems (for example LWMON) have very short watchdog periods;
+ * we must make sure to split long operations like memmove() or
+ * crc32() into reasonable chunks.
+ */
+#define CHUNKSZ (64 * 1024)
+
+#define uimage_to_cpu(x)               ntohl(x)
+#define cpu_to_uimage(x)               htonl(x)
+
+const char *genimg_get_os_name (uint8_t os);
+const char *genimg_get_arch_name (uint8_t arch);
+const char *genimg_get_type_name (uint8_t type);
+const char *genimg_get_comp_name (uint8_t comp);
+int genimg_get_os_id (const char *name);
+int genimg_get_arch_id (const char *name);
+int genimg_get_type_id (const char *name);
+int genimg_get_comp_id (const char *name);
+
+#ifndef USE_HOSTCC
+/* Image format types, returned by _get_format() routine */
+#define IMAGE_FORMAT_INVALID   0x00
+#define IMAGE_FORMAT_LEGACY    0x01    /* legacy image_header based format */
+#define IMAGE_FORMAT_FIT       0x02    /* new, libfdt based format */
+
+int genimg_get_format (void *img_addr);
+int genimg_has_config (bootm_headers_t *images);
+ulong genimg_get_image (ulong img_addr);
+
+int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
+               uint8_t arch, ulong *rd_start, ulong *rd_end);
+
+#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
+int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
+                 ulong *initrd_start, ulong *initrd_end);
+
+int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
+                       ulong bootmap_base);
+int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base);
+#endif /* CONFIG_PPC || CONFIG_M68K */
+#endif /* !USE_HOSTCC */
+
+/*******************************************************************/
+/* Legacy format specific code (prefixed with image_) */
+/*******************************************************************/
+static inline uint32_t image_get_header_size (void)
+{
+       return (sizeof (image_header_t));
+}
+
+#define image_get_hdr_l(f) \
+       static inline uint32_t image_get_##f(image_header_t *hdr) \
+       { \
+               return uimage_to_cpu (hdr->ih_##f); \
+       }
+image_get_hdr_l (magic);
+image_get_hdr_l (hcrc);
+image_get_hdr_l (time);
+image_get_hdr_l (size);
+image_get_hdr_l (load);
+image_get_hdr_l (ep);
+image_get_hdr_l (dcrc);
+
+#define image_get_hdr_b(f) \
+       static inline uint8_t image_get_##f(image_header_t *hdr) \
+       { \
+               return hdr->ih_##f; \
+       }
+image_get_hdr_b (os);
+image_get_hdr_b (arch);
+image_get_hdr_b (type);
+image_get_hdr_b (comp);
+
+static inline char *image_get_name (image_header_t *hdr)
+{
+       return (char *)hdr->ih_name;
+}
+
+static inline uint32_t image_get_data_size (image_header_t *hdr)
+{
+       return image_get_size (hdr);
+}
+
+/**
+ * image_get_data - get image payload start address
+ * @hdr: image header
+ *
+ * image_get_data() returns address of the image payload. For single
+ * component images it is image data start. For multi component
+ * images it points to the null terminated table of sub-images sizes.
+ *
+ * returns:
+ *     image payload data start address
+ */
+static inline ulong image_get_data (image_header_t *hdr)
+{
+       return ((ulong)hdr + image_get_header_size ());
+}
+
+static inline uint32_t image_get_image_size (image_header_t *hdr)
+{
+       return (image_get_size (hdr) + image_get_header_size ());
+}
+static inline ulong image_get_image_end (image_header_t *hdr)
+{
+       return ((ulong)hdr + image_get_image_size (hdr));
+}
+
+#define image_set_hdr_l(f) \
+       static inline void image_set_##f(image_header_t *hdr, uint32_t val) \
+       { \
+               hdr->ih_##f = cpu_to_uimage (val); \
+       }
+image_set_hdr_l (magic);
+image_set_hdr_l (hcrc);
+image_set_hdr_l (time);
+image_set_hdr_l (size);
+image_set_hdr_l (load);
+image_set_hdr_l (ep);
+image_set_hdr_l (dcrc);
+
+#define image_set_hdr_b(f) \
+       static inline void image_set_##f(image_header_t *hdr, uint8_t val) \
+       { \
+               hdr->ih_##f = val; \
+       }
+image_set_hdr_b (os);
+image_set_hdr_b (arch);
+image_set_hdr_b (type);
+image_set_hdr_b (comp);
+
+static inline void image_set_name (image_header_t *hdr, const char *name)
+{
+       strncpy (image_get_name (hdr), name, IH_NMLEN);
+}
+
+int image_check_hcrc (image_header_t *hdr);
+int image_check_dcrc (image_header_t *hdr);
+#ifndef USE_HOSTCC
+int image_check_dcrc_wd (image_header_t *hdr, ulong chunksize);
+int getenv_verify (void);
+int getenv_autostart (void);
+ulong getenv_bootm_low(void);
+ulong getenv_bootm_size(void);
+void memmove_wd (void *to, void *from, size_t len, ulong chunksz);
+#endif
+
+static inline int image_check_magic (image_header_t *hdr)
+{
+       return (image_get_magic (hdr) == IH_MAGIC);
+}
+static inline int image_check_type (image_header_t *hdr, uint8_t type)
+{
+       return (image_get_type (hdr) == type);
+}
+static inline int image_check_arch (image_header_t *hdr, uint8_t arch)
+{
+       return (image_get_arch (hdr) == arch);
+}
+static inline int image_check_os (image_header_t *hdr, uint8_t os)
+{
+       return (image_get_os (hdr) == os);
+}
+
+ulong image_multi_count (image_header_t *hdr);
+void image_multi_getimg (image_header_t *hdr, ulong idx,
+                       ulong *data, ulong *len);
+
+inline void image_print_contents (image_header_t *hdr);
+inline void image_print_contents_noindent (image_header_t *hdr);
+
+#ifndef USE_HOSTCC
+static inline int image_check_target_arch (image_header_t *hdr)
+{
+#if defined(__ARM__)
+       if (!image_check_arch (hdr, IH_ARCH_ARM))
+#elif defined(__avr32__)
+       if (!image_check_arch (hdr, IH_ARCH_AVR32))
+#elif defined(__bfin__)
+       if (!image_check_arch (hdr, IH_ARCH_BLACKFIN))
+#elif defined(__I386__)
+       if (!image_check_arch (hdr, IH_ARCH_I386))
+#elif defined(__M68K__)
+       if (!image_check_arch (hdr, IH_ARCH_M68K))
+#elif defined(__microblaze__)
+       if (!image_check_arch (hdr, IH_ARCH_MICROBLAZE))
+#elif defined(__mips__)
+       if (!image_check_arch (hdr, IH_ARCH_MIPS))
+#elif defined(__nios__)
+       if (!image_check_arch (hdr, IH_ARCH_NIOS))
+#elif defined(__nios2__)
+       if (!image_check_arch (hdr, IH_ARCH_NIOS2))
+#elif defined(__PPC__)
+       if (!image_check_arch (hdr, IH_ARCH_PPC))
+#elif defined(__sh__)
+       if (!image_check_arch (hdr, IH_ARCH_SH))
+#else
+# error Unknown CPU type
+#endif
+               return 0;
+
+       return 1;
+}
+#endif /* USE_HOSTCC */
+
+/*******************************************************************/
+/* New uImage format specific code (prefixed with fit_) */
+/*******************************************************************/
+#if defined(CONFIG_FIT)
+
+#define FIT_IMAGES_PATH                "/images"
+#define FIT_CONFS_PATH         "/configurations"
+
+/* hash node */
+#define FIT_HASH_NODENAME      "hash"
+#define FIT_ALGO_PROP          "algo"
+#define FIT_VALUE_PROP         "value"
+
+/* image node */
+#define FIT_DATA_PROP          "data"
+#define FIT_TIMESTAMP_PROP     "timestamp"
+#define FIT_DESC_PROP          "description"
+#define FIT_ARCH_PROP          "arch"
+#define FIT_TYPE_PROP          "type"
+#define FIT_OS_PROP            "os"
+#define FIT_COMP_PROP          "compression"
+#define FIT_ENTRY_PROP         "entry"
+#define FIT_LOAD_PROP          "load"
+
+/* configuration node */
+#define FIT_KERNEL_PROP                "kernel"
+#define FIT_RAMDISK_PROP       "ramdisk"
+#define FIT_FDT_PROP           "fdt"
+#define FIT_DEFAULT_PROP       "default"
+
+#define FIT_MAX_HASH_LEN       20      /* max(crc32_len(4), sha1_len(20)) */
+
+/* cmdline argument format parsing */
+inline int fit_parse_conf (const char *spec, ulong addr_curr,
+               ulong *addr, const char **conf_name);
+inline int fit_parse_subimage (const char *spec, ulong addr_curr,
+               ulong *addr, const char **image_name);
+
+inline void fit_print_contents (const void *fit);
+inline void fit_print_contents_noindent (const void *fit);
+void fit_image_print (const void *fit, int noffset, const char *p);
+void fit_image_print_hash (const void *fit, int noffset, const char *p);
+
+/**
+ * fit_get_end - get FIT image size
+ * @fit: pointer to the FIT format image header
+ *
+ * returns:
+ *     size of the FIT image (blob) in memory
+ */
+static inline ulong fit_get_size (const void *fit)
+{
+       return fdt_totalsize (fit);
+}
+
+/**
+ * fit_get_end - get FIT image end
+ * @fit: pointer to the FIT format image header
+ *
+ * returns:
+ *     end address of the FIT image (blob) in memory
+ */
+static inline ulong fit_get_end (const void *fit)
+{
+       return (ulong)fit + fdt_totalsize (fit);
+}
+
+/**
+ * fit_get_name - get FIT node name
+ * @fit: pointer to the FIT format image header
+ *
+ * returns:
+ *     NULL, on error
+ *     pointer to node name, on success
+ */
+static inline const char *fit_get_name (const void *fit_hdr,
+               int noffset, int *len)
+{
+       return fdt_get_name (fit_hdr, noffset, len);
+}
+
+int fit_get_desc (const void *fit, int noffset, char **desc);
+int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp);
+
+int fit_image_get_node (const void *fit, const char *image_uname);
+int fit_image_get_os (const void *fit, int noffset, uint8_t *os);
+int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch);
+int fit_image_get_type (const void *fit, int noffset, uint8_t *type);
+int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp);
+int fit_image_get_load (const void *fit, int noffset, ulong *load);
+int fit_image_get_entry (const void *fit, int noffset, ulong *entry);
+int fit_image_get_data (const void *fit, int noffset,
+                               const void **data, size_t *size);
+
+int fit_image_hash_get_algo (const void *fit, int noffset, char **algo);
+int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value,
+                               int *value_len);
+
+int fit_set_timestamp (void *fit, int noffset, time_t timestamp);
+int fit_set_hashes (void *fit);
+int fit_image_set_hashes (void *fit, int image_noffset);
+int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value,
+                               int value_len);
+
+int fit_image_check_hashes (const void *fit, int noffset);
+int fit_image_check_os (const void *fit, int noffset, uint8_t os);
+int fit_image_check_arch (const void *fit, int noffset, uint8_t arch);
+int fit_image_check_type (const void *fit, int noffset, uint8_t type);
+int fit_image_check_comp (const void *fit, int noffset, uint8_t comp);
+int fit_check_format (const void *fit);
+
+int fit_conf_get_node (const void *fit, const char *conf_uname);
+int fit_conf_get_kernel_node (const void *fit, int noffset);
+int fit_conf_get_ramdisk_node (const void *fit, int noffset);
+int fit_conf_get_fdt_node (const void *fit, int noffset);
+
+void fit_conf_print (const void *fit, int noffset, const char *p);
+
+#ifndef USE_HOSTCC
+static inline int fit_image_check_target_arch (const void *fdt, int node)
+{
+#if defined(__ARM__)
+       if (!fit_image_check_arch (fdt, node, IH_ARCH_ARM))
+#elif defined(__avr32__)
+       if (!fit_image_check_arch (fdt, node, IH_ARCH_AVR32))
+#elif defined(__bfin__)
+       if (!fit_image_check_arch (fdt, node, IH_ARCH_BLACKFIN))
+#elif defined(__I386__)
+       if (!fit_image_check_arch (fdt, node, IH_ARCH_I386))
+#elif defined(__M68K__)
+       if (!fit_image_check_arch (fdt, node, IH_ARCH_M68K))
+#elif defined(__microblaze__)
+       if (!fit_image_check_arch (fdt, node, IH_ARCH_MICROBLAZE))
+#elif defined(__mips__)
+       if (!fit_image_check_arch (fdt, node, IH_ARCH_MIPS))
+#elif defined(__nios__)
+       if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS))
+#elif defined(__nios2__)
+       if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS2))
+#elif defined(__PPC__)
+       if (!fit_image_check_arch (fdt, node, IH_ARCH_PPC))
+#elif defined(__sh__)
+       if (!fit_image_check_arch (fdt, node, IH_ARCH_SH))
+#else
+# error Unknown CPU type
+#endif
+               return 0;
+
+       return 1;
+}
+#endif /* USE_HOSTCC */
+
+#ifdef CONFIG_FIT_VERBOSE
+#define fit_unsupported(msg)   printf ("! %s:%d " \
+                               "FIT images not supported for '%s'\n", \
+                               __FILE__, __LINE__, (msg))
+
+#define fit_unsupported_reset(msg)     printf ("! %s:%d " \
+                               "FIT images not supported for '%s' " \
+                               "- must reset board to recover!\n", \
+                               __FILE__, __LINE__, (msg))
+#else
+#define fit_unsupported(msg)
+#define fit_unsupported_reset(msg)
+#endif /* CONFIG_FIT_VERBOSE */
+#endif /* CONFIG_FIT */
+
+#endif /* __IMAGE_H__ */
diff --git a/include/serial.h b/include/serial.h
index 12e2ae9..732fe67 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -107,7 +107,6 @@ void port_init(void);
 void serial_init (const int ubrdiv_val,const int uart);
 void serial_putc (const int uart,const char c);
 int printk(const char *fmt, ...);
-int vsprintf(char *buf, const char *fmt, va_list args);
 int puts(const char *string);
 
 #endif
diff --git a/include/setup.h b/include/setup.h
new file mode 100644
index 0000000..89df4dc
--- /dev/null
+++ b/include/setup.h
@@ -0,0 +1,269 @@
+/*
+ *  linux/include/asm/setup.h
+ *
+ *  Copyright (C) 1997-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Structure passed to kernel to tell it about the
+ *  hardware it's running on.  See linux/Documentation/arm/Setup
+ *  for more info.
+ *
+ * NOTE:
+ *  This file contains two ways to pass information from the boot
+ *  loader to the kernel. The old struct param_struct is deprecated,
+ *  but it will be kept in the kernel for 5 years from now
+ *  (2001). This will allow boot loaders to convert to the new struct
+ *  tag way.
+ */
+#ifndef __ASMARM_SETUP_H
+#define __ASMARM_SETUP_H
+
+/*
+ * Usage:
+ *  - do not go blindly adding fields, add them at the end
+ *  - when adding fields, don't rely on the address until
+ *    a patch from me has been released
+ *  - unused fields should be zero (for future expansion)
+ *  - this structure is relatively short-lived - only
+ *    guaranteed to contain useful data in setup_arch()
+ */
+#define COMMAND_LINE_SIZE 1024
+
+/* This is the old deprecated way to pass parameters to the kernel */
+struct param_struct {
+    union {
+       struct {
+           unsigned long page_size;            /*  0 */
+           unsigned long nr_pages;             /*  4 */
+           unsigned long ramdisk_size;         /*  8 */
+           unsigned long flags;                /* 12 */
+#define FLAG_READONLY  1
+#define FLAG_RDLOAD    4
+#define FLAG_RDPROMPT  8
+           unsigned long rootdev;              /* 16 */
+           unsigned long video_num_cols;       /* 20 */
+           unsigned long video_num_rows;       /* 24 */
+           unsigned long video_x;              /* 28 */
+           unsigned long video_y;              /* 32 */
+           unsigned long memc_control_reg;     /* 36 */
+           unsigned char sounddefault;         /* 40 */
+           unsigned char adfsdrives;           /* 41 */
+           unsigned char bytes_per_char_h;     /* 42 */
+           unsigned char bytes_per_char_v;     /* 43 */
+           unsigned long pages_in_bank[4];     /* 44 */
+           unsigned long pages_in_vram;        /* 60 */
+           unsigned long initrd_start;         /* 64 */
+           unsigned long initrd_size;          /* 68 */
+           unsigned long rd_start;             /* 72 */
+           unsigned long system_rev;           /* 76 */
+           unsigned long system_serial_low;    /* 80 */
+           unsigned long system_serial_high;   /* 84 */
+           unsigned long mem_fclk_21285;       /* 88 */
+       } s;
+       char unused[256];
+    } u1;
+    union {
+       char paths[8][128];
+       struct {
+           unsigned long magic;
+           char n[1024 - sizeof(unsigned long)];
+       } s;
+    } u2;
+    char commandline[COMMAND_LINE_SIZE];
+};
+
+
+/*
+ * The new way of passing information: a list of tagged entries
+ */
+
+/* The list ends with an ATAG_NONE node. */
+#define ATAG_NONE      0x00000000
+
+struct tag_header {
+       u32 size;
+       u32 tag;
+};
+
+/* The list must start with an ATAG_CORE node */
+#define ATAG_CORE      0x54410001
+
+struct tag_core {
+       u32 flags;              /* bit 0 = read-only */
+       u32 pagesize;
+       u32 rootdev;
+};
+
+/* it is allowed to have multiple ATAG_MEM nodes */
+#define ATAG_MEM       0x54410002
+
+struct tag_mem32 {
+       u32     size;
+       u32     start;  /* physical start address */
+};
+
+/* VGA text type displays */
+#define ATAG_VIDEOTEXT 0x54410003
+
+struct tag_videotext {
+       u8              x;
+       u8              y;
+       u16             video_page;
+       u8              video_mode;
+       u8              video_cols;
+       u16             video_ega_bx;
+       u8              video_lines;
+       u8              video_isvga;
+       u16             video_points;
+};
+
+/* describes how the ramdisk will be used in kernel */
+#define ATAG_RAMDISK   0x54410004
+
+struct tag_ramdisk {
+       u32 flags;      /* bit 0 = load, bit 1 = prompt */
+       u32 size;       /* decompressed ramdisk size in _kilo_ bytes */
+       u32 start;      /* starting block of floppy-based RAM disk image */
+};
+
+/* describes where the compressed ramdisk image lives (virtual address) */
+/*
+ * this one accidentally used virtual addresses - as such,
+ * its depreciated.
+ */
+#define ATAG_INITRD    0x54410005
+
+/* describes where the compressed ramdisk image lives (physical address) */
+#define ATAG_INITRD2   0x54420005
+
+struct tag_initrd {
+       u32 start;      /* physical start address */
+       u32 size;       /* size of compressed ramdisk image in bytes */
+};
+
+/* board serial number. "64 bits should be enough for everybody" */
+#define ATAG_SERIAL    0x54410006
+
+struct tag_serialnr {
+       u32 low;
+       u32 high;
+};
+
+/* board revision */
+#define ATAG_REVISION  0x54410007
+
+struct tag_revision {
+       u32 rev;
+};
+
+/* initial values for vesafb-type framebuffers. see struct screen_info
+ * in include/linux/tty.h
+ */
+#define ATAG_VIDEOLFB  0x54410008
+
+struct tag_videolfb {
+       u16             lfb_width;
+       u16             lfb_height;
+       u16             lfb_depth;
+       u16             lfb_linelength;
+       u32             lfb_base;
+       u32             lfb_size;
+       u8              red_size;
+       u8              red_pos;
+       u8              green_size;
+       u8              green_pos;
+       u8              blue_size;
+       u8              blue_pos;
+       u8              rsvd_size;
+       u8              rsvd_pos;
+};
+
+/* command line: \0 terminated string */
+#define ATAG_CMDLINE   0x54410009
+
+struct tag_cmdline {
+       char    cmdline[1];     /* this is the minimum size */
+};
+
+/* acorn RiscPC specific information */
+#define ATAG_ACORN     0x41000101
+
+struct tag_acorn {
+       u32 memc_control_reg;
+       u32 vram_pages;
+       u8 sounddefault;
+       u8 adfsdrives;
+};
+
+/* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */
+#define ATAG_MEMCLK    0x41000402
+
+struct tag_memclk {
+       u32 fmemclk;
+};
+
+struct tag {
+       struct tag_header hdr;
+       union {
+               struct tag_core         core;
+               struct tag_mem32        mem;
+               struct tag_videotext    videotext;
+               struct tag_ramdisk      ramdisk;
+               struct tag_initrd       initrd;
+               struct tag_serialnr     serialnr;
+               struct tag_revision     revision;
+               struct tag_videolfb     videolfb;
+               struct tag_cmdline      cmdline;
+
+               /*
+                * Acorn specific
+                */
+               struct tag_acorn        acorn;
+
+               /*
+                * DC21285 specific
+                */
+               struct tag_memclk       memclk;
+       } u;
+};
+
+struct tagtable {
+       u32 tag;
+       int (*parse)(const struct tag *);
+};
+
+#define __tag __attribute__((unused, __section__(".taglist")))
+#define __tagtable(tag, fn) \
+static struct tagtable __tagtable_##fn __tag = { tag, fn }
+
+#define tag_member_present(tag,member)                         \
+       ((unsigned long)(&((struct tag *)0L)->member + 1)       \
+               <= (tag)->hdr.size * 4)
+
+#define tag_next(t)    ((struct tag *)((u32 *)(t) + (t)->hdr.size))
+#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
+
+#define for_each_tag(t,base)           \
+       for (t = base; t->hdr.size; t = tag_next(t))
+
+/*
+ * Memory map description
+ */
+#define NR_BANKS 8
+
+struct meminfo {
+       int nr_banks;
+       unsigned long end;
+       struct {
+               unsigned long start;
+               unsigned long size;
+               int           node;
+       } bank[NR_BANKS];
+};
+
+extern struct meminfo meminfo;
+
+#endif
diff --git a/src/blink_led.c b/src/blink_led.c
index fa4482e..e1e7a94 100644
--- a/src/blink_led.c
+++ b/src/blink_led.c
@@ -27,7 +27,7 @@ int delay(int time)
   for(i=0;i<time;i++);
   return 0;
 }
-int set_GPB()
+int set_GPB(void)
 {
   GPBCON = 0x5;
   GPBDW = 0xffff;
diff --git a/src/blink_led.h b/src/blink_led.h
index c0b05b5..8485404 100644
--- a/src/blink_led.h
+++ b/src/blink_led.h
@@ -36,6 +36,6 @@
 
 int orange_on(int times);
 int blue_on(int times);
-int blink_led();
+int blink_led(void);
 
 #endif /* __BLINK_LED_H */
diff --git a/src/kboot-stage1.lds b/src/kboot-stage1.lds
index 4b93b52..7987801 100644
--- a/src/kboot-stage1.lds
+++ b/src/kboot-stage1.lds
@@ -32,17 +32,16 @@ SECTIONS
        . = ALIGN(4);
        .text      :
        {
-         src/start.o   (.text)
-         src/lowlevel_init.o(.text)
-         src/start_kboot.o     (.text .rodata)
-         *(.text .rodata)
+         src/start.o   (.text .rodata* .data)
+         src/lowlevel_init.o(.text .rodata* .data)
+         src/start_kboot.o     (.text .rodata* .data)
+         src/serial.o  (.text .rodata* .data)
+         src/blink_led.o       (.text .rodata* .data)
+         * (.rodata* .data)
        }
 
        . = ALIGN(4);
-       .data : 
-    { 
-        *(.data) 
-    }
+       .everything_else : { *(.text) }
 
        . = ALIGN(4);
        .got : 
@@ -50,7 +49,7 @@ SECTIONS
         *(.got) 
     }
 
-       . = ALIGN(4);
+       . = 0x32000000 ;
        __bss_start = .;
        .bss (NOLOAD) : 
     { 
diff --git a/src/kboot.h b/src/kboot.h
index 7143aae..1c70dda 100644
--- a/src/kboot.h
+++ b/src/kboot.h
@@ -11,6 +11,7 @@ int vsprintf(char *buf, const char *fmt, va_list args);
 int puts(const char *string);
 void printhex(unsigned char v);
 void print32(unsigned int u);
+void hexdump(unsigned char *start, int len);
 
 #endif
 
diff --git a/src/nand_read.c b/src/nand_read.c
index 8deadb7..16310bb 100644
--- a/src/nand_read.c
+++ b/src/nand_read.c
@@ -89,6 +89,8 @@ static int nand_read_page_ll(unsigned char *buf, unsigned 
long addr)
 {
        unsigned short *ptr16 = (unsigned short *)buf;
        unsigned int i, page_num;
+       unsigned char ecc[64];
+       unsigned short *p16 = (unsigned short *)ecc;
 
        nand_clear_RnB();
 
@@ -104,9 +106,11 @@ static int nand_read_page_ll(unsigned char *buf, unsigned 
long addr)
        NFCMD = NAND_CMD_READSTART;
        nand_wait();
 
-       for (i = 0; i < NAND_PAGE_SIZE/2; i++) {
-               *ptr16 = NFDATA16;
-               ptr16++;
+       for (i = 0; i < NAND_PAGE_SIZE/2; i++)
+               *ptr16++ = NFDATA16;
+
+       for (i = 0; i < 64 / 2; i++) {
+               *p16++ = NFDATA16;
        }
 
        return NAND_PAGE_SIZE;
@@ -129,26 +133,20 @@ int nand_read_ll(unsigned char *buf, unsigned long 
start_addr, int size)
                ;
 
        for (i = start_addr; i < (start_addr + size);) {
-#ifdef DEBUG
-               serial_putc(2, 'i');
-               serial_putc(2, '0');
-               serial_putc(2, 'x');
-               print32((unsigned int)i);
-               serial_putc(2, ' ');
-#endif
-               if (i % NAND_BLOCK_SIZE == 0) {
+               if ((i & (NAND_BLOCK_SIZE - 1)) == 0) {
                        if (is_bad_block(i) ||
                                        is_bad_block(i + NAND_PAGE_SIZE)) {
-#ifdef DEBUG
-                               serial_putc(2, '?');
-#endif
+                               serial_putc(2, '!');
+                               serial_putc(2, '0');
+                               serial_putc(2, 'x');
+                               print32((unsigned int)i);
+                               serial_putc(2, ' ');
+
                                i += NAND_BLOCK_SIZE;
                                size += NAND_BLOCK_SIZE;
                                if (bad_count++ == 4) {
-#ifdef DEBUG
                                        serial_putc(2, '+');
                                        serial_putc(2, '\n');
-#endif
                                        return -1;
                                }
                                serial_putc(2, '\n');
@@ -157,18 +155,8 @@ int nand_read_ll(unsigned char *buf, unsigned long 
start_addr, int size)
                }
 
                j = nand_read_page_ll(buf, i);
-#ifdef DEBUG
-               serial_putc(2, 'j');
-               serial_putc(2, '0');
-               serial_putc(2, 'x');
-               print32((unsigned int)j);
-               serial_putc(2, ' ');
-#endif
                i += j;
                buf += j;
-#if DEBUG
-               serial_putc(2, '\n');
-#endif
        }
 
        /* chip Disable */
diff --git a/src/serial.c b/src/serial.c
index 8c8c2a5..5fb8b04 100644
--- a/src/serial.c
+++ b/src/serial.c
@@ -109,6 +109,23 @@ void print32(unsigned int u)
        printhex(u);
 }
 
+void hexdump(unsigned char *start, int len)
+{
+       int n;
+
+       while (len > 0) {
+               print32((int)start);
+               serial_putc(DEBUG_CONSOLE_UART, ':');
+               serial_putc(DEBUG_CONSOLE_UART, ' ');
+               for (n = 0; n < 16; n++) {
+                       printhex(*start++);
+                       serial_putc(DEBUG_CONSOLE_UART, ' ');
+               }
+               serial_putc(DEBUG_CONSOLE_UART, '\n');
+               len -= 16;
+       }
+}
+
 int printk(const char *fmt, ...)
 {
        va_list args;
diff --git a/src/start_kboot.c b/src/start_kboot.c
index 10badfa..2e2c605 100644
--- a/src/start_kboot.c
+++ b/src/start_kboot.c
@@ -35,7 +35,8 @@ extern void bootloader_second_phase(void);
 
 void start_kboot(void)
 {
-       void (*phase2)(void) = bootloader_second_phase + TEXT_BASE;
+       void (*phase2)(void) = (void (*)(void))((int)bootloader_second_phase +
+                                                                    TEXT_BASE);
 
        port_init();
        serial_init(0x11, UART2);
@@ -43,18 +44,15 @@ void start_kboot(void)
        puts("Openmoko KBOOT "stringify2(BUILD_HOST)" "
                              stringify2(BUILD_VERSION)" "
                              stringify2(BUILD_DATE)"\n");
-
        /*
-        * pull the whole U-Boot image into SDRAM
+        * pull the whole bootloader image into SDRAM
         */
 
-       if (nand_read_ll((unsigned char *)TEXT_BASE, 0, 256 * 1024) < 0)
+       if (nand_read_ll((unsigned char *)TEXT_BASE, 0, 24 * 1024) < 0)
                while(1)
                        blink_led();
-
        /*
         * jump to bootloader_second_phase() running from DRAM copy
         */
-
        (phase2)();
 }


Reply via email to