]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - include/image.h
imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
[karo-tx-uboot.git] / include / image.h
index 2f575fd2d76f98f5d3ba977e4fc9d0da6fc7d7d2..beb3a16cd1f18e966aaa01750ae6fdbc8cb56d85 100755 (executable)
@@ -1,4 +1,6 @@
 /*
+ * (C) Copyright 2008 Semihalf
+ *
  * (C) Copyright 2000-2005
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
 #ifndef __IMAGE_H__
 #define __IMAGE_H__
 
+#include "compiler.h"
+
+#ifdef USE_HOSTCC
+
+/* new uImage format support enabled on host */
+#define CONFIG_FIT             1
+#define CONFIG_OF_LIBFDT       1
+#define CONFIG_FIT_VERBOSE     1 /* enable fit_format_{error,warning}() */
+
+#else
+
+#include <lmb.h>
+#include <asm/u-boot.h>
+
+#endif /* USE_HOSTCC */
+
+#include <command.h>
+
+#if defined(CONFIG_FIT)
+#include <fdt.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#define CONFIG_MD5             /* FIT images need MD5 support */
+#endif
+
 /*
  * Operating System Codes
  */
 #define IH_OS_RTEMS            18      /* RTEMS        */
 #define IH_OS_ARTOS            19      /* ARTOS        */
 #define IH_OS_UNITY            20      /* Unity OS     */
+#define IH_OS_INTEGRITY                21      /* INTEGRITY    */
 
 /*
  * CPU Architecture Codes (supported by Linux)
  */
-#define IH_CPU_INVALID         0       /* Invalid CPU  */
-#define IH_CPU_ALPHA           1       /* Alpha        */
-#define IH_CPU_ARM             2       /* ARM          */
-#define IH_CPU_I386            3       /* Intel x86    */
-#define IH_CPU_IA64            4       /* IA64         */
-#define IH_CPU_MIPS            5       /* MIPS         */
-#define IH_CPU_MIPS64          6       /* MIPS  64 Bit */
-#define IH_CPU_PPC             7       /* PowerPC      */
-#define IH_CPU_S390            8       /* IBM S390     */
-#define IH_CPU_SH              9       /* SuperH       */
-#define IH_CPU_SPARC           10      /* Sparc        */
-#define IH_CPU_SPARC64         11      /* Sparc 64 Bit */
-#define IH_CPU_M68K            12      /* M68K         */
-#define IH_CPU_NIOS            13      /* Nios-32      */
-#define IH_CPU_MICROBLAZE      14      /* MicroBlaze   */
-#define IH_CPU_NIOS2           15      /* Nios-II      */
-#define IH_CPU_BLACKFIN                16      /* Blackfin     */
-#define IH_CPU_AVR32           17      /* AVR32        */
+#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
 #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_COMP_LZMA           3       /* lzma  Compression Used       */
 
 #define IH_MAGIC       0x27051956      /* Image Magic Number           */
 #define IH_NMLEN               32      /* Image Name Length            */
 
 /*
- * all data in network byte order (aka natural aka bigendian)
+ * 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    */
@@ -156,5 +186,473 @@ typedef struct image_header {
        uint8_t         ih_name[IH_NMLEN];      /* Image Name           */
 } image_header_t;
 
+typedef struct image_info {
+       ulong           start, end;             /* start/end of blob */
+       ulong           image_start, image_len; /* start of image within blob, len of image */
+       ulong           load;                   /* load addr for the image */
+       uint8_t         comp, type, os;         /* compression, type of image, os type */
+} image_info_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;         /* image header pointer */
+       image_header_t  legacy_hdr_os_copy;     /* header copy */
+       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
+
+#ifndef USE_HOSTCC
+       image_info_t    os;             /* os image info */
+       ulong           ep;             /* entry point of OS */
+
+       ulong           rd_start, rd_end;/* ramdisk start/end */
+
+#ifdef CONFIG_OF_LIBFDT
+       char            *ft_addr;       /* flat dev tree address */
+#endif
+       ulong           ft_len;         /* length of flat device tree */
+
+       ulong           initrd_start;
+       ulong           initrd_end;
+       ulong           cmdline_start;
+       ulong           cmdline_end;
+       bd_t            *kbd;
+#endif
+
+       int             verify;         /* getenv("verify")[0] != 'n' */
+
+#define        BOOTM_STATE_START       (0x00000001)
+#define        BOOTM_STATE_LOADOS      (0x00000002)
+#define        BOOTM_STATE_RAMDISK     (0x00000004)
+#define        BOOTM_STATE_FDT         (0x00000008)
+#define        BOOTM_STATE_OS_CMDLINE  (0x00000010)
+#define        BOOTM_STATE_OS_BD_T     (0x00000020)
+#define        BOOTM_STATE_OS_PREP     (0x00000040)
+#define        BOOTM_STATE_OS_GO       (0x00000080)
+       int             state;
+
+#ifndef USE_HOSTCC
+       struct lmb      lmb;            /* for memory mgmt */
+#endif
+} bootm_headers_t;
+
+/*
+ * Some systems (for example LWMON) have very short watchdog periods;
+ * we must make sure to split long operations like memmove() or
+ * checksum calculations into reasonable chunks.
+ */
+#ifndef CHUNKSZ
+#define CHUNKSZ (64 * 1024)
+#endif
+
+#ifndef CHUNKSZ_CRC32
+#define CHUNKSZ_CRC32 (64 * 1024)
+#endif
+
+#ifndef CHUNKSZ_MD5
+#define CHUNKSZ_MD5 (64 * 1024)
+#endif
+
+#ifndef CHUNKSZ_SHA1
+#define CHUNKSZ_SHA1 (64 * 1024)
+#endif
+
+#define uimage_to_cpu(x)               be32_to_cpu(x)
+#define cpu_to_uimage(x)               cpu_to_be32(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);
+
+
+#ifdef CONFIG_OF_LIBFDT
+int boot_get_fdt (int flag, int argc, char *argv[], bootm_headers_t *images,
+               char **of_flat_tree, ulong *of_size);
+int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
+               char **of_flat_tree, ulong *of_size);
+#endif
+
+#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_magic */
+image_get_hdr_l (hcrc);                /* image_get_hcrc */
+image_get_hdr_l (time);                /* image_get_time */
+image_get_hdr_l (size);                /* image_get_size */
+image_get_hdr_l (load);                /* image_get_load */
+image_get_hdr_l (ep);          /* image_get_ep */
+image_get_hdr_l (dcrc);                /* image_get_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_os */
+image_get_hdr_b (arch);                /* image_get_arch */
+image_get_hdr_b (type);                /* image_get_type */
+image_get_hdr_b (comp);                /* image_get_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_magic */
+image_set_hdr_l (hcrc);                /* image_set_hcrc */
+image_set_hdr_l (time);                /* image_set_time */
+image_set_hdr_l (size);                /* image_set_size */
+image_set_hdr_l (load);                /* image_set_load */
+image_set_hdr_l (ep);          /* image_set_ep */
+image_set_hdr_l (dcrc);                /* image_set_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_os */
+image_set_hdr_b (arch);                /* image_set_arch */
+image_set_hdr_b (type);                /* image_set_type */
+image_set_hdr_b (comp);                /* image_set_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 getenv_yesno (char *var);
+ulong getenv_bootm_low(void);
+phys_size_t 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);
+
+void image_print_contents (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))
+#elif defined(__sparc__)
+       if (!image_check_arch (hdr, IH_ARCH_SPARC))
+#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);
+
+void fit_print_contents (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_all_image_check_hashes (const void *fit);
+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))
+#elif defined(__sparc__)
+       if (!fit_image_check_arch (fdt, node, IH_ARCH_SPARC))
+#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__ */