Annotation of elwix/tools/uboot_mkimage/common/image.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * (C) Copyright 2008 Semihalf
        !             3:  *
        !             4:  * (C) Copyright 2000-2006
        !             5:  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
        !             6:  *
        !             7:  * See file CREDITS for list of people who contributed to this
        !             8:  * project.
        !             9:  *
        !            10:  * This program is free software; you can redistribute it and/or
        !            11:  * modify it under the terms of the GNU General Public License as
        !            12:  * published by the Free Software Foundation; either version 2 of
        !            13:  * the License, or (at your option) any later version.
        !            14:  *
        !            15:  * This program is distributed in the hope that it will be useful,
        !            16:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            17:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            18:  * GNU General Public License for more details.
        !            19:  *
        !            20:  * You should have received a copy of the GNU General Public License
        !            21:  * along with this program; if not, write to the Free Software
        !            22:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
        !            23:  * MA 02111-1307 USA
        !            24:  */
        !            25: 
        !            26: #ifndef USE_HOSTCC
        !            27: #include <common.h>
        !            28: #include <watchdog.h>
        !            29: 
        !            30: #ifdef CONFIG_SHOW_BOOT_PROGRESS
        !            31: #include <status_led.h>
        !            32: #endif
        !            33: 
        !            34: #ifdef CONFIG_HAS_DATAFLASH
        !            35: #include <dataflash.h>
        !            36: #endif
        !            37: 
        !            38: #ifdef CONFIG_LOGBUFFER
        !            39: #include <logbuff.h>
        !            40: #endif
        !            41: 
        !            42: #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE)
        !            43: #include <rtc.h>
        !            44: #endif
        !            45: 
        !            46: #include <image.h>
        !            47: 
        !            48: #if defined(CONFIG_FIT) || defined (CONFIG_OF_LIBFDT)
        !            49: #include <fdt.h>
        !            50: #include <libfdt.h>
        !            51: #include <fdt_support.h>
        !            52: #endif
        !            53: 
        !            54: #if defined(CONFIG_FIT)
        !            55: #include <u-boot/md5.h>
        !            56: #include <sha1.h>
        !            57: 
        !            58: static int fit_check_ramdisk (const void *fit, int os_noffset,
        !            59:                uint8_t arch, int verify);
        !            60: #endif
        !            61: 
        !            62: #ifdef CONFIG_CMD_BDI
        !            63: extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
        !            64: #endif
        !            65: 
        !            66: DECLARE_GLOBAL_DATA_PTR;
        !            67: 
        !            68: static const image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
        !            69:                                                int verify);
        !            70: #else
        !            71: #include "mkimage.h"
        !            72: #include <u-boot/md5.h>
        !            73: #include <time.h>
        !            74: #include <image.h>
        !            75: #endif /* !USE_HOSTCC*/
        !            76: 
        !            77: static table_entry_t uimage_arch[] = {
        !            78:        {       IH_ARCH_INVALID,        NULL,           "Invalid ARCH", },
        !            79:        {       IH_ARCH_ALPHA,          "alpha",        "Alpha",        },
        !            80:        {       IH_ARCH_ARM,            "arm",          "ARM",          },
        !            81:        {       IH_ARCH_I386,           "x86",          "Intel x86",    },
        !            82:        {       IH_ARCH_IA64,           "ia64",         "IA64",         },
        !            83:        {       IH_ARCH_M68K,           "m68k",         "M68K",         },
        !            84:        {       IH_ARCH_MICROBLAZE,     "microblaze",   "MicroBlaze",   },
        !            85:        {       IH_ARCH_MIPS,           "mips",         "MIPS",         },
        !            86:        {       IH_ARCH_MIPS64,         "mips64",       "MIPS 64 Bit",  },
        !            87:        {       IH_ARCH_NIOS2,          "nios2",        "NIOS II",      },
        !            88:        {       IH_ARCH_PPC,            "powerpc",      "PowerPC",      },
        !            89:        {       IH_ARCH_PPC,            "ppc",          "PowerPC",      },
        !            90:        {       IH_ARCH_S390,           "s390",         "IBM S390",     },
        !            91:        {       IH_ARCH_SH,             "sh",           "SuperH",       },
        !            92:        {       IH_ARCH_SPARC,          "sparc",        "SPARC",        },
        !            93:        {       IH_ARCH_SPARC64,        "sparc64",      "SPARC 64 Bit", },
        !            94:        {       IH_ARCH_BLACKFIN,       "blackfin",     "Blackfin",     },
        !            95:        {       IH_ARCH_AVR32,          "avr32",        "AVR32",        },
        !            96:        {       -1,                     "",             "",             },
        !            97: };
        !            98: 
        !            99: static table_entry_t uimage_os[] = {
        !           100:        {       IH_OS_INVALID,  NULL,           "Invalid OS",           },
        !           101:        {       IH_OS_LINUX,    "linux",        "Linux",                },
        !           102: #if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC)
        !           103:        {       IH_OS_LYNXOS,   "lynxos",       "LynxOS",               },
        !           104: #endif
        !           105:        {       IH_OS_NETBSD,   "netbsd",       "NetBSD",               },
        !           106:        {       IH_OS_OSE,      "ose",          "Enea OSE",             },
        !           107:        {       IH_OS_RTEMS,    "rtems",        "RTEMS",                },
        !           108:        {       IH_OS_U_BOOT,   "u-boot",       "U-Boot",               },
        !           109: #if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)
        !           110:        {       IH_OS_QNX,      "qnx",          "QNX",                  },
        !           111:        {       IH_OS_VXWORKS,  "vxworks",      "VxWorks",              },
        !           112: #endif
        !           113: #if defined(CONFIG_INTEGRITY) || defined(USE_HOSTCC)
        !           114:        {       IH_OS_INTEGRITY,"integrity",    "INTEGRITY",            },
        !           115: #endif
        !           116: #ifdef USE_HOSTCC
        !           117:        {       IH_OS_4_4BSD,   "4_4bsd",       "4_4BSD",               },
        !           118:        {       IH_OS_DELL,     "dell",         "Dell",                 },
        !           119:        {       IH_OS_ESIX,     "esix",         "Esix",                 },
        !           120:        {       IH_OS_FREEBSD,  "freebsd",      "FreeBSD",              },
        !           121:        {       IH_OS_IRIX,     "irix",         "Irix",                 },
        !           122:        {       IH_OS_NCR,      "ncr",          "NCR",                  },
        !           123:        {       IH_OS_OPENBSD,  "openbsd",      "OpenBSD",              },
        !           124:        {       IH_OS_PSOS,     "psos",         "pSOS",                 },
        !           125:        {       IH_OS_SCO,      "sco",          "SCO",                  },
        !           126:        {       IH_OS_SOLARIS,  "solaris",      "Solaris",              },
        !           127:        {       IH_OS_SVR4,     "svr4",         "SVR4",                 },
        !           128: #endif
        !           129:        {       -1,             "",             "",                     },
        !           130: };
        !           131: 
        !           132: static table_entry_t uimage_type[] = {
        !           133:        {       IH_TYPE_INVALID,    NULL,         "Invalid Image",      },
        !           134:        {       IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image",   },
        !           135:        {       IH_TYPE_FIRMWARE,   "firmware",   "Firmware",           },
        !           136:        {       IH_TYPE_KERNEL,     "kernel",     "Kernel Image",       },
        !           137:        {       IH_TYPE_MULTI,      "multi",      "Multi-File Image",   },
        !           138:        {       IH_TYPE_RAMDISK,    "ramdisk",    "RAMDisk Image",      },
        !           139:        {       IH_TYPE_SCRIPT,     "script",     "Script",             },
        !           140:        {       IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
        !           141:        {       IH_TYPE_FLATDT,     "flat_dt",    "Flat Device Tree",   },
        !           142:        {       IH_TYPE_KWBIMAGE,   "kwbimage",   "Kirkwood Boot Image",},
        !           143:        {       IH_TYPE_IMXIMAGE,   "imximage",   "Freescale i.MX Boot Image",},
        !           144:        {       -1,                 "",           "",                   },
        !           145: };
        !           146: 
        !           147: static table_entry_t uimage_comp[] = {
        !           148:        {       IH_COMP_NONE,   "none",         "uncompressed",         },
        !           149:        {       IH_COMP_BZIP2,  "bzip2",        "bzip2 compressed",     },
        !           150:        {       IH_COMP_GZIP,   "gzip",         "gzip compressed",      },
        !           151:        {       IH_COMP_LZMA,   "lzma",         "lzma compressed",      },
        !           152:        {       IH_COMP_LZO,    "lzo",          "lzo compressed",       },
        !           153:        {       -1,             "",             "",                     },
        !           154: };
        !           155: 
        !           156: uint32_t crc32 (uint32_t, const unsigned char *, uint);
        !           157: uint32_t crc32_wd (uint32_t, const unsigned char *, uint, uint);
        !           158: #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
        !           159: static void genimg_print_time (time_t timestamp);
        !           160: #endif
        !           161: 
        !           162: /*****************************************************************************/
        !           163: /* Legacy format routines */
        !           164: /*****************************************************************************/
        !           165: int image_check_hcrc (const image_header_t *hdr)
        !           166: {
        !           167:        ulong hcrc;
        !           168:        ulong len = image_get_header_size ();
        !           169:        image_header_t header;
        !           170: 
        !           171:        /* Copy header so we can blank CRC field for re-calculation */
        !           172:        memmove (&header, (char *)hdr, image_get_header_size ());
        !           173:        image_set_hcrc (&header, 0);
        !           174: 
        !           175:        hcrc = crc32 (0, (unsigned char *)&header, len);
        !           176: 
        !           177:        return (hcrc == image_get_hcrc (hdr));
        !           178: }
        !           179: 
        !           180: int image_check_dcrc (const image_header_t *hdr)
        !           181: {
        !           182:        ulong data = image_get_data (hdr);
        !           183:        ulong len = image_get_data_size (hdr);
        !           184:        ulong dcrc = crc32_wd (0, (unsigned char *)data, len, CHUNKSZ_CRC32);
        !           185: 
        !           186:        return (dcrc == image_get_dcrc (hdr));
        !           187: }
        !           188: 
        !           189: /**
        !           190:  * image_multi_count - get component (sub-image) count
        !           191:  * @hdr: pointer to the header of the multi component image
        !           192:  *
        !           193:  * image_multi_count() returns number of components in a multi
        !           194:  * component image.
        !           195:  *
        !           196:  * Note: no checking of the image type is done, caller must pass
        !           197:  * a valid multi component image.
        !           198:  *
        !           199:  * returns:
        !           200:  *     number of components
        !           201:  */
        !           202: ulong image_multi_count (const image_header_t *hdr)
        !           203: {
        !           204:        ulong i, count = 0;
        !           205:        uint32_t *size;
        !           206: 
        !           207:        /* get start of the image payload, which in case of multi
        !           208:         * component images that points to a table of component sizes */
        !           209:        size = (uint32_t *)image_get_data (hdr);
        !           210: 
        !           211:        /* count non empty slots */
        !           212:        for (i = 0; size[i]; ++i)
        !           213:                count++;
        !           214: 
        !           215:        return count;
        !           216: }
        !           217: 
        !           218: /**
        !           219:  * image_multi_getimg - get component data address and size
        !           220:  * @hdr: pointer to the header of the multi component image
        !           221:  * @idx: index of the requested component
        !           222:  * @data: pointer to a ulong variable, will hold component data address
        !           223:  * @len: pointer to a ulong variable, will hold component size
        !           224:  *
        !           225:  * image_multi_getimg() returns size and data address for the requested
        !           226:  * component in a multi component image.
        !           227:  *
        !           228:  * Note: no checking of the image type is done, caller must pass
        !           229:  * a valid multi component image.
        !           230:  *
        !           231:  * returns:
        !           232:  *     data address and size of the component, if idx is valid
        !           233:  *     0 in data and len, if idx is out of range
        !           234:  */
        !           235: void image_multi_getimg (const image_header_t *hdr, ulong idx,
        !           236:                        ulong *data, ulong *len)
        !           237: {
        !           238:        int i;
        !           239:        uint32_t *size;
        !           240:        ulong offset, count, img_data;
        !           241: 
        !           242:        /* get number of component */
        !           243:        count = image_multi_count (hdr);
        !           244: 
        !           245:        /* get start of the image payload, which in case of multi
        !           246:         * component images that points to a table of component sizes */
        !           247:        size = (uint32_t *)image_get_data (hdr);
        !           248: 
        !           249:        /* get address of the proper component data start, which means
        !           250:         * skipping sizes table (add 1 for last, null entry) */
        !           251:        img_data = image_get_data (hdr) + (count + 1) * sizeof (uint32_t);
        !           252: 
        !           253:        if (idx < count) {
        !           254:                *len = uimage_to_cpu (size[idx]);
        !           255:                offset = 0;
        !           256: 
        !           257:                /* go over all indices preceding requested component idx */
        !           258:                for (i = 0; i < idx; i++) {
        !           259:                        /* add up i-th component size, rounding up to 4 bytes */
        !           260:                        offset += (uimage_to_cpu (size[i]) + 3) & ~3 ;
        !           261:                }
        !           262: 
        !           263:                /* calculate idx-th component data address */
        !           264:                *data = img_data + offset;
        !           265:        } else {
        !           266:                *len = 0;
        !           267:                *data = 0;
        !           268:        }
        !           269: }
        !           270: 
        !           271: static void image_print_type (const image_header_t *hdr)
        !           272: {
        !           273:        const char *os, *arch, *type, *comp;
        !           274: 
        !           275:        os = genimg_get_os_name (image_get_os (hdr));
        !           276:        arch = genimg_get_arch_name (image_get_arch (hdr));
        !           277:        type = genimg_get_type_name (image_get_type (hdr));
        !           278:        comp = genimg_get_comp_name (image_get_comp (hdr));
        !           279: 
        !           280:        printf ("%s %s %s (%s)\n", arch, os, type, comp);
        !           281: }
        !           282: 
        !           283: /**
        !           284:  * image_print_contents - prints out the contents of the legacy format image
        !           285:  * @ptr: pointer to the legacy format image header
        !           286:  * @p: pointer to prefix string
        !           287:  *
        !           288:  * image_print_contents() formats a multi line legacy image contents description.
        !           289:  * The routine prints out all header fields followed by the size/offset data
        !           290:  * for MULTI/SCRIPT images.
        !           291:  *
        !           292:  * returns:
        !           293:  *     no returned results
        !           294:  */
        !           295: void image_print_contents (const void *ptr)
        !           296: {
        !           297:        const image_header_t *hdr = (const image_header_t *)ptr;
        !           298:        const char *p;
        !           299: 
        !           300: #ifdef USE_HOSTCC
        !           301:        p = "";
        !           302: #else
        !           303:        p = "   ";
        !           304: #endif
        !           305: 
        !           306:        printf ("%sImage Name:   %.*s\n", p, IH_NMLEN, image_get_name (hdr));
        !           307: #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
        !           308:        printf ("%sCreated:      ", p);
        !           309:        genimg_print_time ((time_t)image_get_time (hdr));
        !           310: #endif
        !           311:        printf ("%sImage Type:   ", p);
        !           312:        image_print_type (hdr);
        !           313:        printf ("%sData Size:    ", p);
        !           314:        genimg_print_size (image_get_data_size (hdr));
        !           315:        printf ("%sLoad Address: %08x\n", p, image_get_load (hdr));
        !           316:        printf ("%sEntry Point:  %08x\n", p, image_get_ep (hdr));
        !           317: 
        !           318:        if (image_check_type (hdr, IH_TYPE_MULTI) ||
        !           319:                        image_check_type (hdr, IH_TYPE_SCRIPT)) {
        !           320:                int i;
        !           321:                ulong data, len;
        !           322:                ulong count = image_multi_count (hdr);
        !           323: 
        !           324:                printf ("%sContents:\n", p);
        !           325:                for (i = 0; i < count; i++) {
        !           326:                        image_multi_getimg (hdr, i, &data, &len);
        !           327: 
        !           328:                        printf ("%s   Image %d: ", p, i);
        !           329:                        genimg_print_size (len);
        !           330: 
        !           331:                        if (image_check_type (hdr, IH_TYPE_SCRIPT) && i > 0) {
        !           332:                                /*
        !           333:                                 * the user may need to know offsets
        !           334:                                 * if planning to do something with
        !           335:                                 * multiple files
        !           336:                                 */
        !           337:                                printf ("%s    Offset = 0x%08lx\n", p, data);
        !           338:                        }
        !           339:                }
        !           340:        }
        !           341: }
        !           342: 
        !           343: 
        !           344: #ifndef USE_HOSTCC
        !           345: /**
        !           346:  * image_get_ramdisk - get and verify ramdisk image
        !           347:  * @rd_addr: ramdisk image start address
        !           348:  * @arch: expected ramdisk architecture
        !           349:  * @verify: checksum verification flag
        !           350:  *
        !           351:  * image_get_ramdisk() returns a pointer to the verified ramdisk image
        !           352:  * header. Routine receives image start address and expected architecture
        !           353:  * flag. Verification done covers data and header integrity and os/type/arch
        !           354:  * fields checking.
        !           355:  *
        !           356:  * If dataflash support is enabled routine checks for dataflash addresses
        !           357:  * and handles required dataflash reads.
        !           358:  *
        !           359:  * returns:
        !           360:  *     pointer to a ramdisk image header, if image was found and valid
        !           361:  *     otherwise, return NULL
        !           362:  */
        !           363: static const image_header_t *image_get_ramdisk (ulong rd_addr, uint8_t arch,
        !           364:                                                int verify)
        !           365: {
        !           366:        const image_header_t *rd_hdr = (const image_header_t *)rd_addr;
        !           367: 
        !           368:        if (!image_check_magic (rd_hdr)) {
        !           369:                puts ("Bad Magic Number\n");
        !           370:                show_boot_progress (-10);
        !           371:                return NULL;
        !           372:        }
        !           373: 
        !           374:        if (!image_check_hcrc (rd_hdr)) {
        !           375:                puts ("Bad Header Checksum\n");
        !           376:                show_boot_progress (-11);
        !           377:                return NULL;
        !           378:        }
        !           379: 
        !           380:        show_boot_progress (10);
        !           381:        image_print_contents (rd_hdr);
        !           382: 
        !           383:        if (verify) {
        !           384:                puts("   Verifying Checksum ... ");
        !           385:                if (!image_check_dcrc (rd_hdr)) {
        !           386:                        puts ("Bad Data CRC\n");
        !           387:                        show_boot_progress (-12);
        !           388:                        return NULL;
        !           389:                }
        !           390:                puts("OK\n");
        !           391:        }
        !           392: 
        !           393:        show_boot_progress (11);
        !           394: 
        !           395:        if (!image_check_os (rd_hdr, IH_OS_LINUX) ||
        !           396:            !image_check_arch (rd_hdr, arch) ||
        !           397:            !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {
        !           398:                printf ("No Linux %s Ramdisk Image\n",
        !           399:                                genimg_get_arch_name(arch));
        !           400:                show_boot_progress (-13);
        !           401:                return NULL;
        !           402:        }
        !           403: 
        !           404:        return rd_hdr;
        !           405: }
        !           406: #endif /* !USE_HOSTCC */
        !           407: 
        !           408: /*****************************************************************************/
        !           409: /* Shared dual-format routines */
        !           410: /*****************************************************************************/
        !           411: #ifndef USE_HOSTCC
        !           412: int getenv_yesno (char *var)
        !           413: {
        !           414:        char *s = getenv (var);
        !           415:        return (s && (*s == 'n')) ? 0 : 1;
        !           416: }
        !           417: 
        !           418: ulong getenv_bootm_low(void)
        !           419: {
        !           420:        char *s = getenv ("bootm_low");
        !           421:        if (s) {
        !           422:                ulong tmp = simple_strtoul (s, NULL, 16);
        !           423:                return tmp;
        !           424:        }
        !           425: 
        !           426: #if defined(CONFIG_SYS_SDRAM_BASE)
        !           427:        return CONFIG_SYS_SDRAM_BASE;
        !           428: #elif defined(CONFIG_ARM)
        !           429:        return gd->bd->bi_dram[0].start;
        !           430: #else
        !           431:        return 0;
        !           432: #endif
        !           433: }
        !           434: 
        !           435: phys_size_t getenv_bootm_size(void)
        !           436: {
        !           437:        phys_size_t tmp;
        !           438:        char *s = getenv ("bootm_size");
        !           439:        if (s) {
        !           440:                tmp = (phys_size_t)simple_strtoull (s, NULL, 16);
        !           441:                return tmp;
        !           442:        }
        !           443:        s = getenv("bootm_low");
        !           444:        if (s)
        !           445:                tmp = (phys_size_t)simple_strtoull (s, NULL, 16);
        !           446:        else
        !           447:                tmp = 0;
        !           448: 
        !           449: 
        !           450: #if defined(CONFIG_ARM)
        !           451:        return gd->bd->bi_dram[0].size - tmp;
        !           452: #else
        !           453:        return gd->bd->bi_memsize - tmp;
        !           454: #endif
        !           455: }
        !           456: 
        !           457: void memmove_wd (void *to, void *from, size_t len, ulong chunksz)
        !           458: {
        !           459:        if (to == from)
        !           460:                return;
        !           461: 
        !           462: #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
        !           463:        while (len > 0) {
        !           464:                size_t tail = (len > chunksz) ? chunksz : len;
        !           465:                WATCHDOG_RESET ();
        !           466:                memmove (to, from, tail);
        !           467:                to += tail;
        !           468:                from += tail;
        !           469:                len -= tail;
        !           470:        }
        !           471: #else  /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
        !           472:        memmove (to, from, len);
        !           473: #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
        !           474: }
        !           475: #endif /* !USE_HOSTCC */
        !           476: 
        !           477: void genimg_print_size (uint32_t size)
        !           478: {
        !           479: #ifndef USE_HOSTCC
        !           480:        printf ("%d Bytes = ", size);
        !           481:        print_size (size, "\n");
        !           482: #else
        !           483:        printf ("%d Bytes = %.2f kB = %.2f MB\n",
        !           484:                        size, (double)size / 1.024e3,
        !           485:                        (double)size / 1.048576e6);
        !           486: #endif
        !           487: }
        !           488: 
        !           489: #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
        !           490: static void genimg_print_time (time_t timestamp)
        !           491: {
        !           492: #ifndef USE_HOSTCC
        !           493:        struct rtc_time tm;
        !           494: 
        !           495:        to_tm (timestamp, &tm);
        !           496:        printf ("%4d-%02d-%02d  %2d:%02d:%02d UTC\n",
        !           497:                        tm.tm_year, tm.tm_mon, tm.tm_mday,
        !           498:                        tm.tm_hour, tm.tm_min, tm.tm_sec);
        !           499: #else
        !           500:        printf ("%s", ctime(&timestamp));
        !           501: #endif
        !           502: }
        !           503: #endif /* CONFIG_TIMESTAMP || CONFIG_CMD_DATE || USE_HOSTCC */
        !           504: 
        !           505: /**
        !           506:  * get_table_entry_name - translate entry id to long name
        !           507:  * @table: pointer to a translation table for entries of a specific type
        !           508:  * @msg: message to be returned when translation fails
        !           509:  * @id: entry id to be translated
        !           510:  *
        !           511:  * get_table_entry_name() will go over translation table trying to find
        !           512:  * entry that matches given id. If matching entry is found, its long
        !           513:  * name is returned to the caller.
        !           514:  *
        !           515:  * returns:
        !           516:  *     long entry name if translation succeeds
        !           517:  *     msg otherwise
        !           518:  */
        !           519: char *get_table_entry_name (table_entry_t *table, char *msg, int id)
        !           520: {
        !           521:        for (; table->id >= 0; ++table) {
        !           522:                if (table->id == id)
        !           523: #if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
        !           524:                        return table->lname;
        !           525: #else
        !           526:                        return table->lname + gd->reloc_off;
        !           527: #endif
        !           528:        }
        !           529:        return (msg);
        !           530: }
        !           531: 
        !           532: const char *genimg_get_os_name (uint8_t os)
        !           533: {
        !           534:        return (get_table_entry_name (uimage_os, "Unknown OS", os));
        !           535: }
        !           536: 
        !           537: const char *genimg_get_arch_name (uint8_t arch)
        !           538: {
        !           539:        return (get_table_entry_name (uimage_arch, "Unknown Architecture", arch));
        !           540: }
        !           541: 
        !           542: const char *genimg_get_type_name (uint8_t type)
        !           543: {
        !           544:        return (get_table_entry_name (uimage_type, "Unknown Image", type));
        !           545: }
        !           546: 
        !           547: const char *genimg_get_comp_name (uint8_t comp)
        !           548: {
        !           549:        return (get_table_entry_name (uimage_comp, "Unknown Compression", comp));
        !           550: }
        !           551: 
        !           552: /**
        !           553:  * get_table_entry_id - translate short entry name to id
        !           554:  * @table: pointer to a translation table for entries of a specific type
        !           555:  * @table_name: to be used in case of error
        !           556:  * @name: entry short name to be translated
        !           557:  *
        !           558:  * get_table_entry_id() will go over translation table trying to find
        !           559:  * entry that matches given short name. If matching entry is found,
        !           560:  * its id returned to the caller.
        !           561:  *
        !           562:  * returns:
        !           563:  *     entry id if translation succeeds
        !           564:  *     -1 otherwise
        !           565:  */
        !           566: int get_table_entry_id (table_entry_t *table,
        !           567:                const char *table_name, const char *name)
        !           568: {
        !           569:        table_entry_t *t;
        !           570: #ifdef USE_HOSTCC
        !           571:        int first = 1;
        !           572: 
        !           573:        for (t = table; t->id >= 0; ++t) {
        !           574:                if (t->sname && strcasecmp(t->sname, name) == 0)
        !           575:                        return (t->id);
        !           576:        }
        !           577: 
        !           578:        fprintf (stderr, "\nInvalid %s Type - valid names are", table_name);
        !           579:        for (t = table; t->id >= 0; ++t) {
        !           580:                if (t->sname == NULL)
        !           581:                        continue;
        !           582:                fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname);
        !           583:                first = 0;
        !           584:        }
        !           585:        fprintf (stderr, "\n");
        !           586: #else
        !           587:        for (t = table; t->id >= 0; ++t) {
        !           588: #ifdef CONFIG_NEEDS_MANUAL_RELOC
        !           589:                if (t->sname && strcmp(t->sname + gd->reloc_off, name) == 0)
        !           590: #else
        !           591:                if (t->sname && strcmp(t->sname, name) == 0)
        !           592: #endif
        !           593:                        return (t->id);
        !           594:        }
        !           595:        debug ("Invalid %s Type: %s\n", table_name, name);
        !           596: #endif /* USE_HOSTCC */
        !           597:        return (-1);
        !           598: }
        !           599: 
        !           600: int genimg_get_os_id (const char *name)
        !           601: {
        !           602:        return (get_table_entry_id (uimage_os, "OS", name));
        !           603: }
        !           604: 
        !           605: int genimg_get_arch_id (const char *name)
        !           606: {
        !           607:        return (get_table_entry_id (uimage_arch, "CPU", name));
        !           608: }
        !           609: 
        !           610: int genimg_get_type_id (const char *name)
        !           611: {
        !           612:        return (get_table_entry_id (uimage_type, "Image", name));
        !           613: }
        !           614: 
        !           615: int genimg_get_comp_id (const char *name)
        !           616: {
        !           617:        return (get_table_entry_id (uimage_comp, "Compression", name));
        !           618: }
        !           619: 
        !           620: #ifndef USE_HOSTCC
        !           621: /**
        !           622:  * genimg_get_format - get image format type
        !           623:  * @img_addr: image start address
        !           624:  *
        !           625:  * genimg_get_format() checks whether provided address points to a valid
        !           626:  * legacy or FIT image.
        !           627:  *
        !           628:  * New uImage format and FDT blob are based on a libfdt. FDT blob
        !           629:  * may be passed directly or embedded in a FIT image. In both situations
        !           630:  * genimg_get_format() must be able to dectect libfdt header.
        !           631:  *
        !           632:  * returns:
        !           633:  *     image format type or IMAGE_FORMAT_INVALID if no image is present
        !           634:  */
        !           635: int genimg_get_format (void *img_addr)
        !           636: {
        !           637:        ulong format = IMAGE_FORMAT_INVALID;
        !           638:        const image_header_t *hdr;
        !           639: #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
        !           640:        char *fit_hdr;
        !           641: #endif
        !           642: 
        !           643:        hdr = (const image_header_t *)img_addr;
        !           644:        if (image_check_magic(hdr))
        !           645:                format = IMAGE_FORMAT_LEGACY;
        !           646: #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
        !           647:        else {
        !           648:                fit_hdr = (char *)img_addr;
        !           649:                if (fdt_check_header (fit_hdr) == 0)
        !           650:                        format = IMAGE_FORMAT_FIT;
        !           651:        }
        !           652: #endif
        !           653: 
        !           654:        return format;
        !           655: }
        !           656: 
        !           657: /**
        !           658:  * genimg_get_image - get image from special storage (if necessary)
        !           659:  * @img_addr: image start address
        !           660:  *
        !           661:  * genimg_get_image() checks if provided image start adddress is located
        !           662:  * in a dataflash storage. If so, image is moved to a system RAM memory.
        !           663:  *
        !           664:  * returns:
        !           665:  *     image start address after possible relocation from special storage
        !           666:  */
        !           667: ulong genimg_get_image (ulong img_addr)
        !           668: {
        !           669:        ulong ram_addr = img_addr;
        !           670: 
        !           671: #ifdef CONFIG_HAS_DATAFLASH
        !           672:        ulong h_size, d_size;
        !           673: 
        !           674:        if (addr_dataflash (img_addr)){
        !           675:                /* ger RAM address */
        !           676:                ram_addr = CONFIG_SYS_LOAD_ADDR;
        !           677: 
        !           678:                /* get header size */
        !           679:                h_size = image_get_header_size ();
        !           680: #if defined(CONFIG_FIT)
        !           681:                if (sizeof(struct fdt_header) > h_size)
        !           682:                        h_size = sizeof(struct fdt_header);
        !           683: #endif
        !           684: 
        !           685:                /* read in header */
        !           686:                debug ("   Reading image header from dataflash address "
        !           687:                        "%08lx to RAM address %08lx\n", img_addr, ram_addr);
        !           688: 
        !           689:                read_dataflash (img_addr, h_size, (char *)ram_addr);
        !           690: 
        !           691:                /* get data size */
        !           692:                switch (genimg_get_format ((void *)ram_addr)) {
        !           693:                case IMAGE_FORMAT_LEGACY:
        !           694:                        d_size = image_get_data_size ((const image_header_t *)ram_addr);
        !           695:                        debug ("   Legacy format image found at 0x%08lx, size 0x%08lx\n",
        !           696:                                        ram_addr, d_size);
        !           697:                        break;
        !           698: #if defined(CONFIG_FIT)
        !           699:                case IMAGE_FORMAT_FIT:
        !           700:                        d_size = fit_get_size ((const void *)ram_addr) - h_size;
        !           701:                        debug ("   FIT/FDT format image found at 0x%08lx, size 0x%08lx\n",
        !           702:                                        ram_addr, d_size);
        !           703:                        break;
        !           704: #endif
        !           705:                default:
        !           706:                        printf ("   No valid image found at 0x%08lx\n", img_addr);
        !           707:                        return ram_addr;
        !           708:                }
        !           709: 
        !           710:                /* read in image data */
        !           711:                debug ("   Reading image remaining data from dataflash address "
        !           712:                        "%08lx to RAM address %08lx\n", img_addr + h_size,
        !           713:                        ram_addr + h_size);
        !           714: 
        !           715:                read_dataflash (img_addr + h_size, d_size,
        !           716:                                (char *)(ram_addr + h_size));
        !           717: 
        !           718:        }
        !           719: #endif /* CONFIG_HAS_DATAFLASH */
        !           720: 
        !           721:        return ram_addr;
        !           722: }
        !           723: 
        !           724: /**
        !           725:  * fit_has_config - check if there is a valid FIT configuration
        !           726:  * @images: pointer to the bootm command headers structure
        !           727:  *
        !           728:  * fit_has_config() checks if there is a FIT configuration in use
        !           729:  * (if FTI support is present).
        !           730:  *
        !           731:  * returns:
        !           732:  *     0, no FIT support or no configuration found
        !           733:  *     1, configuration found
        !           734:  */
        !           735: int genimg_has_config (bootm_headers_t *images)
        !           736: {
        !           737: #if defined(CONFIG_FIT)
        !           738:        if (images->fit_uname_cfg)
        !           739:                return 1;
        !           740: #endif
        !           741:        return 0;
        !           742: }
        !           743: 
        !           744: /**
        !           745:  * boot_get_ramdisk - main ramdisk handling routine
        !           746:  * @argc: command argument count
        !           747:  * @argv: command argument list
        !           748:  * @images: pointer to the bootm images structure
        !           749:  * @arch: expected ramdisk architecture
        !           750:  * @rd_start: pointer to a ulong variable, will hold ramdisk start address
        !           751:  * @rd_end: pointer to a ulong variable, will hold ramdisk end
        !           752:  *
        !           753:  * boot_get_ramdisk() is responsible for finding a valid ramdisk image.
        !           754:  * Curently supported are the following ramdisk sources:
        !           755:  *      - multicomponent kernel/ramdisk image,
        !           756:  *      - commandline provided address of decicated ramdisk image.
        !           757:  *
        !           758:  * returns:
        !           759:  *     0, if ramdisk image was found and valid, or skiped
        !           760:  *     rd_start and rd_end are set to ramdisk start/end addresses if
        !           761:  *     ramdisk image is found and valid
        !           762:  *
        !           763:  *     1, if ramdisk image is found but corrupted, or invalid
        !           764:  *     rd_start and rd_end are set to 0 if no ramdisk exists
        !           765:  */
        !           766: int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images,
        !           767:                uint8_t arch, ulong *rd_start, ulong *rd_end)
        !           768: {
        !           769:        ulong rd_addr, rd_load;
        !           770:        ulong rd_data, rd_len;
        !           771:        const image_header_t *rd_hdr;
        !           772: #if defined(CONFIG_FIT)
        !           773:        void            *fit_hdr;
        !           774:        const char      *fit_uname_config = NULL;
        !           775:        const char      *fit_uname_ramdisk = NULL;
        !           776:        ulong           default_addr;
        !           777:        int             rd_noffset;
        !           778:        int             cfg_noffset;
        !           779:        const void      *data;
        !           780:        size_t          size;
        !           781: #endif
        !           782: 
        !           783:        *rd_start = 0;
        !           784:        *rd_end = 0;
        !           785: 
        !           786:        /*
        !           787:         * Look for a '-' which indicates to ignore the
        !           788:         * ramdisk argument
        !           789:         */
        !           790:        if ((argc >= 3) && (strcmp(argv[2], "-") ==  0)) {
        !           791:                debug ("## Skipping init Ramdisk\n");
        !           792:                rd_len = rd_data = 0;
        !           793:        } else if (argc >= 3 || genimg_has_config (images)) {
        !           794: #if defined(CONFIG_FIT)
        !           795:                if (argc >= 3) {
        !           796:                        /*
        !           797:                         * If the init ramdisk comes from the FIT image and
        !           798:                         * the FIT image address is omitted in the command
        !           799:                         * line argument, try to use os FIT image address or
        !           800:                         * default load address.
        !           801:                         */
        !           802:                        if (images->fit_uname_os)
        !           803:                                default_addr = (ulong)images->fit_hdr_os;
        !           804:                        else
        !           805:                                default_addr = load_addr;
        !           806: 
        !           807:                        if (fit_parse_conf (argv[2], default_addr,
        !           808:                                                &rd_addr, &fit_uname_config)) {
        !           809:                                debug ("*  ramdisk: config '%s' from image at 0x%08lx\n",
        !           810:                                                fit_uname_config, rd_addr);
        !           811:                        } else if (fit_parse_subimage (argv[2], default_addr,
        !           812:                                                &rd_addr, &fit_uname_ramdisk)) {
        !           813:                                debug ("*  ramdisk: subimage '%s' from image at 0x%08lx\n",
        !           814:                                                fit_uname_ramdisk, rd_addr);
        !           815:                        } else
        !           816: #endif
        !           817:                        {
        !           818:                                rd_addr = simple_strtoul(argv[2], NULL, 16);
        !           819:                                debug ("*  ramdisk: cmdline image address = 0x%08lx\n",
        !           820:                                                rd_addr);
        !           821:                        }
        !           822: #if defined(CONFIG_FIT)
        !           823:                } else {
        !           824:                        /* use FIT configuration provided in first bootm
        !           825:                         * command argument
        !           826:                         */
        !           827:                        rd_addr = (ulong)images->fit_hdr_os;
        !           828:                        fit_uname_config = images->fit_uname_cfg;
        !           829:                        debug ("*  ramdisk: using config '%s' from image at 0x%08lx\n",
        !           830:                                        fit_uname_config, rd_addr);
        !           831: 
        !           832:                        /*
        !           833:                         * Check whether configuration has ramdisk defined,
        !           834:                         * if not, don't try to use it, quit silently.
        !           835:                         */
        !           836:                        fit_hdr = (void *)rd_addr;
        !           837:                        cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
        !           838:                        if (cfg_noffset < 0) {
        !           839:                                debug ("*  ramdisk: no such config\n");
        !           840:                                return 1;
        !           841:                        }
        !           842: 
        !           843:                        rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset);
        !           844:                        if (rd_noffset < 0) {
        !           845:                                debug ("*  ramdisk: no ramdisk in config\n");
        !           846:                                return 0;
        !           847:                        }
        !           848:                }
        !           849: #endif
        !           850: 
        !           851:                /* copy from dataflash if needed */
        !           852:                rd_addr = genimg_get_image (rd_addr);
        !           853: 
        !           854:                /*
        !           855:                 * Check if there is an initrd image at the
        !           856:                 * address provided in the second bootm argument
        !           857:                 * check image type, for FIT images get FIT node.
        !           858:                 */
        !           859:                switch (genimg_get_format ((void *)rd_addr)) {
        !           860:                case IMAGE_FORMAT_LEGACY:
        !           861:                        printf ("## Loading init Ramdisk from Legacy "
        !           862:                                        "Image at %08lx ...\n", rd_addr);
        !           863: 
        !           864:                        show_boot_progress (9);
        !           865:                        rd_hdr = image_get_ramdisk (rd_addr, arch,
        !           866:                                                        images->verify);
        !           867: 
        !           868:                        if (rd_hdr == NULL)
        !           869:                                return 1;
        !           870: 
        !           871:                        rd_data = image_get_data (rd_hdr);
        !           872:                        rd_len = image_get_data_size (rd_hdr);
        !           873:                        rd_load = image_get_load (rd_hdr);
        !           874:                        break;
        !           875: #if defined(CONFIG_FIT)
        !           876:                case IMAGE_FORMAT_FIT:
        !           877:                        fit_hdr = (void *)rd_addr;
        !           878:                        printf ("## Loading init Ramdisk from FIT "
        !           879:                                        "Image at %08lx ...\n", rd_addr);
        !           880: 
        !           881:                        show_boot_progress (120);
        !           882:                        if (!fit_check_format (fit_hdr)) {
        !           883:                                puts ("Bad FIT ramdisk image format!\n");
        !           884:                                show_boot_progress (-120);
        !           885:                                return 1;
        !           886:                        }
        !           887:                        show_boot_progress (121);
        !           888: 
        !           889:                        if (!fit_uname_ramdisk) {
        !           890:                                /*
        !           891:                                 * no ramdisk image node unit name, try to get config
        !           892:                                 * node first. If config unit node name is NULL
        !           893:                                 * fit_conf_get_node() will try to find default config node
        !           894:                                 */
        !           895:                                show_boot_progress (122);
        !           896:                                cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
        !           897:                                if (cfg_noffset < 0) {
        !           898:                                        puts ("Could not find configuration node\n");
        !           899:                                        show_boot_progress (-122);
        !           900:                                        return 1;
        !           901:                                }
        !           902:                                fit_uname_config = fdt_get_name (fit_hdr, cfg_noffset, NULL);
        !           903:                                printf ("   Using '%s' configuration\n", fit_uname_config);
        !           904: 
        !           905:                                rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset);
        !           906:                                fit_uname_ramdisk = fit_get_name (fit_hdr, rd_noffset, NULL);
        !           907:                        } else {
        !           908:                                /* get ramdisk component image node offset */
        !           909:                                show_boot_progress (123);
        !           910:                                rd_noffset = fit_image_get_node (fit_hdr, fit_uname_ramdisk);
        !           911:                        }
        !           912:                        if (rd_noffset < 0) {
        !           913:                                puts ("Could not find subimage node\n");
        !           914:                                show_boot_progress (-124);
        !           915:                                return 1;
        !           916:                        }
        !           917: 
        !           918:                        printf ("   Trying '%s' ramdisk subimage\n", fit_uname_ramdisk);
        !           919: 
        !           920:                        show_boot_progress (125);
        !           921:                        if (!fit_check_ramdisk (fit_hdr, rd_noffset, arch, images->verify))
        !           922:                                return 1;
        !           923: 
        !           924:                        /* get ramdisk image data address and length */
        !           925:                        if (fit_image_get_data (fit_hdr, rd_noffset, &data, &size)) {
        !           926:                                puts ("Could not find ramdisk subimage data!\n");
        !           927:                                show_boot_progress (-127);
        !           928:                                return 1;
        !           929:                        }
        !           930:                        show_boot_progress (128);
        !           931: 
        !           932:                        rd_data = (ulong)data;
        !           933:                        rd_len = size;
        !           934: 
        !           935:                        if (fit_image_get_load (fit_hdr, rd_noffset, &rd_load)) {
        !           936:                                puts ("Can't get ramdisk subimage load address!\n");
        !           937:                                show_boot_progress (-129);
        !           938:                                return 1;
        !           939:                        }
        !           940:                        show_boot_progress (129);
        !           941: 
        !           942:                        images->fit_hdr_rd = fit_hdr;
        !           943:                        images->fit_uname_rd = fit_uname_ramdisk;
        !           944:                        images->fit_noffset_rd = rd_noffset;
        !           945:                        break;
        !           946: #endif
        !           947:                default:
        !           948:                        puts ("Wrong Ramdisk Image Format\n");
        !           949:                        rd_data = rd_len = rd_load = 0;
        !           950:                        return 1;
        !           951:                }
        !           952: 
        !           953: #if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO)
        !           954:                /*
        !           955:                 * We need to copy the ramdisk to SRAM to let Linux boot
        !           956:                 */
        !           957:                if (rd_data) {
        !           958:                        memmove ((void *)rd_load, (uchar *)rd_data, rd_len);
        !           959:                        rd_data = rd_load;
        !           960:                }
        !           961: #endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */
        !           962: 
        !           963:        } else if (images->legacy_hdr_valid &&
        !           964:                        image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
        !           965:                /*
        !           966:                 * Now check if we have a legacy mult-component image,
        !           967:                 * get second entry data start address and len.
        !           968:                 */
        !           969:                show_boot_progress (13);
        !           970:                printf ("## Loading init Ramdisk from multi component "
        !           971:                                "Legacy Image at %08lx ...\n",
        !           972:                                (ulong)images->legacy_hdr_os);
        !           973: 
        !           974:                image_multi_getimg (images->legacy_hdr_os, 1, &rd_data, &rd_len);
        !           975:        } else {
        !           976:                /*
        !           977:                 * no initrd image
        !           978:                 */
        !           979:                show_boot_progress (14);
        !           980:                rd_len = rd_data = 0;
        !           981:        }
        !           982: 
        !           983:        if (!rd_data) {
        !           984:                debug ("## No init Ramdisk\n");
        !           985:        } else {
        !           986:                *rd_start = rd_data;
        !           987:                *rd_end = rd_data + rd_len;
        !           988:        }
        !           989:        debug ("   ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n",
        !           990:                        *rd_start, *rd_end);
        !           991: 
        !           992:        return 0;
        !           993: }
        !           994: 
        !           995: #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
        !           996: /**
        !           997:  * boot_ramdisk_high - relocate init ramdisk
        !           998:  * @lmb: pointer to lmb handle, will be used for memory mgmt
        !           999:  * @rd_data: ramdisk data start address
        !          1000:  * @rd_len: ramdisk data length
        !          1001:  * @initrd_start: pointer to a ulong variable, will hold final init ramdisk
        !          1002:  *      start address (after possible relocation)
        !          1003:  * @initrd_end: pointer to a ulong variable, will hold final init ramdisk
        !          1004:  *      end address (after possible relocation)
        !          1005:  *
        !          1006:  * boot_ramdisk_high() takes a relocation hint from "initrd_high" environement
        !          1007:  * variable and if requested ramdisk data is moved to a specified location.
        !          1008:  *
        !          1009:  * Initrd_start and initrd_end are set to final (after relocation) ramdisk
        !          1010:  * start/end addresses if ramdisk image start and len were provided,
        !          1011:  * otherwise set initrd_start and initrd_end set to zeros.
        !          1012:  *
        !          1013:  * returns:
        !          1014:  *      0 - success
        !          1015:  *     -1 - failure
        !          1016:  */
        !          1017: int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
        !          1018:                  ulong *initrd_start, ulong *initrd_end)
        !          1019: {
        !          1020:        char    *s;
        !          1021:        ulong   initrd_high;
        !          1022:        int     initrd_copy_to_ram = 1;
        !          1023: 
        !          1024:        if ((s = getenv ("initrd_high")) != NULL) {
        !          1025:                /* a value of "no" or a similar string will act like 0,
        !          1026:                 * turning the "load high" feature off. This is intentional.
        !          1027:                 */
        !          1028:                initrd_high = simple_strtoul (s, NULL, 16);
        !          1029:                if (initrd_high == ~0)
        !          1030:                        initrd_copy_to_ram = 0;
        !          1031:        } else {
        !          1032:                /* not set, no restrictions to load high */
        !          1033:                initrd_high = ~0;
        !          1034:        }
        !          1035: 
        !          1036: 
        !          1037: #ifdef CONFIG_LOGBUFFER
        !          1038:        /* Prevent initrd from overwriting logbuffer */
        !          1039:        lmb_reserve(lmb, logbuffer_base() - LOGBUFF_OVERHEAD, LOGBUFF_RESERVE);
        !          1040: #endif
        !          1041: 
        !          1042:        debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
        !          1043:                        initrd_high, initrd_copy_to_ram);
        !          1044: 
        !          1045:        if (rd_data) {
        !          1046:                if (!initrd_copy_to_ram) {      /* zero-copy ramdisk support */
        !          1047:                        debug ("   in-place initrd\n");
        !          1048:                        *initrd_start = rd_data;
        !          1049:                        *initrd_end = rd_data + rd_len;
        !          1050:                        lmb_reserve(lmb, rd_data, rd_len);
        !          1051:                } else {
        !          1052:                        if (initrd_high)
        !          1053:                                *initrd_start = (ulong)lmb_alloc_base (lmb, rd_len, 0x1000, initrd_high);
        !          1054:                        else
        !          1055:                                *initrd_start = (ulong)lmb_alloc (lmb, rd_len, 0x1000);
        !          1056: 
        !          1057:                        if (*initrd_start == 0) {
        !          1058:                                puts ("ramdisk - allocation error\n");
        !          1059:                                goto error;
        !          1060:                        }
        !          1061:                        show_boot_progress (12);
        !          1062: 
        !          1063:                        *initrd_end = *initrd_start + rd_len;
        !          1064:                        printf ("   Loading Ramdisk to %08lx, end %08lx ... ",
        !          1065:                                        *initrd_start, *initrd_end);
        !          1066: 
        !          1067:                        memmove_wd ((void *)*initrd_start,
        !          1068:                                        (void *)rd_data, rd_len, CHUNKSZ);
        !          1069: 
        !          1070:                        puts ("OK\n");
        !          1071:                }
        !          1072:        } else {
        !          1073:                *initrd_start = 0;
        !          1074:                *initrd_end = 0;
        !          1075:        }
        !          1076:        debug ("   ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
        !          1077:                        *initrd_start, *initrd_end);
        !          1078: 
        !          1079:        return 0;
        !          1080: 
        !          1081: error:
        !          1082:        return -1;
        !          1083: }
        !          1084: #endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */
        !          1085: 
        !          1086: #ifdef CONFIG_OF_LIBFDT
        !          1087: static void fdt_error (const char *msg)
        !          1088: {
        !          1089:        puts ("ERROR: ");
        !          1090:        puts (msg);
        !          1091:        puts (" - must RESET the board to recover.\n");
        !          1092: }
        !          1093: 
        !          1094: static const image_header_t *image_get_fdt (ulong fdt_addr)
        !          1095: {
        !          1096:        const image_header_t *fdt_hdr = (const image_header_t *)fdt_addr;
        !          1097: 
        !          1098:        image_print_contents (fdt_hdr);
        !          1099: 
        !          1100:        puts ("   Verifying Checksum ... ");
        !          1101:        if (!image_check_hcrc (fdt_hdr)) {
        !          1102:                fdt_error ("fdt header checksum invalid");
        !          1103:                return NULL;
        !          1104:        }
        !          1105: 
        !          1106:        if (!image_check_dcrc (fdt_hdr)) {
        !          1107:                fdt_error ("fdt checksum invalid");
        !          1108:                return NULL;
        !          1109:        }
        !          1110:        puts ("OK\n");
        !          1111: 
        !          1112:        if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) {
        !          1113:                fdt_error ("uImage is not a fdt");
        !          1114:                return NULL;
        !          1115:        }
        !          1116:        if (image_get_comp (fdt_hdr) != IH_COMP_NONE) {
        !          1117:                fdt_error ("uImage is compressed");
        !          1118:                return NULL;
        !          1119:        }
        !          1120:        if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) {
        !          1121:                fdt_error ("uImage data is not a fdt");
        !          1122:                return NULL;
        !          1123:        }
        !          1124:        return fdt_hdr;
        !          1125: }
        !          1126: 
        !          1127: /**
        !          1128:  * fit_check_fdt - verify FIT format FDT subimage
        !          1129:  * @fit_hdr: pointer to the FIT  header
        !          1130:  * fdt_noffset: FDT subimage node offset within FIT image
        !          1131:  * @verify: data CRC verification flag
        !          1132:  *
        !          1133:  * fit_check_fdt() verifies integrity of the FDT subimage and from
        !          1134:  * specified FIT image.
        !          1135:  *
        !          1136:  * returns:
        !          1137:  *     1, on success
        !          1138:  *     0, on failure
        !          1139:  */
        !          1140: #if defined(CONFIG_FIT)
        !          1141: static int fit_check_fdt (const void *fit, int fdt_noffset, int verify)
        !          1142: {
        !          1143:        fit_image_print (fit, fdt_noffset, "   ");
        !          1144: 
        !          1145:        if (verify) {
        !          1146:                puts ("   Verifying Hash Integrity ... ");
        !          1147:                if (!fit_image_check_hashes (fit, fdt_noffset)) {
        !          1148:                        fdt_error ("Bad Data Hash");
        !          1149:                        return 0;
        !          1150:                }
        !          1151:                puts ("OK\n");
        !          1152:        }
        !          1153: 
        !          1154:        if (!fit_image_check_type (fit, fdt_noffset, IH_TYPE_FLATDT)) {
        !          1155:                fdt_error ("Not a FDT image");
        !          1156:                return 0;
        !          1157:        }
        !          1158: 
        !          1159:        if (!fit_image_check_comp (fit, fdt_noffset, IH_COMP_NONE)) {
        !          1160:                fdt_error ("FDT image is compressed");
        !          1161:                return 0;
        !          1162:        }
        !          1163: 
        !          1164:        return 1;
        !          1165: }
        !          1166: #endif /* CONFIG_FIT */
        !          1167: 
        !          1168: #ifndef CONFIG_SYS_FDT_PAD
        !          1169: #define CONFIG_SYS_FDT_PAD 0x3000
        !          1170: #endif
        !          1171: 
        !          1172: /**
        !          1173:  * boot_relocate_fdt - relocate flat device tree
        !          1174:  * @lmb: pointer to lmb handle, will be used for memory mgmt
        !          1175:  * @bootmap_base: base address of the bootmap region
        !          1176:  * @of_flat_tree: pointer to a char* variable, will hold fdt start address
        !          1177:  * @of_size: pointer to a ulong variable, will hold fdt length
        !          1178:  *
        !          1179:  * boot_relocate_fdt() allocates a region of memory within the bootmap and
        !          1180:  * relocates the of_flat_tree into that region, even if the fdt is already in
        !          1181:  * the bootmap.  It also expands the size of the fdt by CONFIG_SYS_FDT_PAD
        !          1182:  * bytes.
        !          1183:  *
        !          1184:  * of_flat_tree and of_size are set to final (after relocation) values
        !          1185:  *
        !          1186:  * returns:
        !          1187:  *      0 - success
        !          1188:  *      1 - failure
        !          1189:  */
        !          1190: #if defined(CONFIG_SYS_BOOTMAPSZ)
        !          1191: int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
        !          1192:                char **of_flat_tree, ulong *of_size)
        !          1193: {
        !          1194:        void    *fdt_blob = *of_flat_tree;
        !          1195:        void    *of_start = 0;
        !          1196:        ulong   of_len = 0;
        !          1197:        int     err;
        !          1198: 
        !          1199:        /* nothing to do */
        !          1200:        if (*of_size == 0)
        !          1201:                return 0;
        !          1202: 
        !          1203:        if (fdt_check_header (fdt_blob) != 0) {
        !          1204:                fdt_error ("image is not a fdt");
        !          1205:                goto error;
        !          1206:        }
        !          1207: 
        !          1208:        /* position on a 4K boundary before the alloc_current */
        !          1209:        /* Pad the FDT by a specified amount */
        !          1210:        of_len = *of_size + CONFIG_SYS_FDT_PAD;
        !          1211:        of_start = (void *)(unsigned long)lmb_alloc_base(lmb, of_len, 0x1000,
        !          1212:                        (CONFIG_SYS_BOOTMAPSZ + bootmap_base));
        !          1213: 
        !          1214:        if (of_start == 0) {
        !          1215:                puts("device tree - allocation error\n");
        !          1216:                goto error;
        !          1217:        }
        !          1218: 
        !          1219:        debug ("## device tree at %p ... %p (len=%ld [0x%lX])\n",
        !          1220:                fdt_blob, fdt_blob + *of_size - 1, of_len, of_len);
        !          1221: 
        !          1222:        printf ("   Loading Device Tree to %p, end %p ... ",
        !          1223:                of_start, of_start + of_len - 1);
        !          1224: 
        !          1225:        err = fdt_open_into (fdt_blob, of_start, of_len);
        !          1226:        if (err != 0) {
        !          1227:                fdt_error ("fdt move failed");
        !          1228:                goto error;
        !          1229:        }
        !          1230:        puts ("OK\n");
        !          1231: 
        !          1232:        *of_flat_tree = of_start;
        !          1233:        *of_size = of_len;
        !          1234: 
        !          1235:        set_working_fdt_addr(*of_flat_tree);
        !          1236:        return 0;
        !          1237: 
        !          1238: error:
        !          1239:        return 1;
        !          1240: }
        !          1241: #endif /* CONFIG_SYS_BOOTMAPSZ */
        !          1242: 
        !          1243: /**
        !          1244:  * boot_get_fdt - main fdt handling routine
        !          1245:  * @argc: command argument count
        !          1246:  * @argv: command argument list
        !          1247:  * @images: pointer to the bootm images structure
        !          1248:  * @of_flat_tree: pointer to a char* variable, will hold fdt start address
        !          1249:  * @of_size: pointer to a ulong variable, will hold fdt length
        !          1250:  *
        !          1251:  * boot_get_fdt() is responsible for finding a valid flat device tree image.
        !          1252:  * Curently supported are the following ramdisk sources:
        !          1253:  *      - multicomponent kernel/ramdisk image,
        !          1254:  *      - commandline provided address of decicated ramdisk image.
        !          1255:  *
        !          1256:  * returns:
        !          1257:  *     0, if fdt image was found and valid, or skipped
        !          1258:  *     of_flat_tree and of_size are set to fdt start address and length if
        !          1259:  *     fdt image is found and valid
        !          1260:  *
        !          1261:  *     1, if fdt image is found but corrupted
        !          1262:  *     of_flat_tree and of_size are set to 0 if no fdt exists
        !          1263:  */
        !          1264: int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *images,
        !          1265:                char **of_flat_tree, ulong *of_size)
        !          1266: {
        !          1267:        const image_header_t *fdt_hdr;
        !          1268:        ulong           fdt_addr;
        !          1269:        char            *fdt_blob = NULL;
        !          1270:        ulong           image_start, image_end;
        !          1271:        ulong           load_start, load_end;
        !          1272: #if defined(CONFIG_FIT)
        !          1273:        void            *fit_hdr;
        !          1274:        const char      *fit_uname_config = NULL;
        !          1275:        const char      *fit_uname_fdt = NULL;
        !          1276:        ulong           default_addr;
        !          1277:        int             cfg_noffset;
        !          1278:        int             fdt_noffset;
        !          1279:        const void      *data;
        !          1280:        size_t          size;
        !          1281: #endif
        !          1282: 
        !          1283:        *of_flat_tree = NULL;
        !          1284:        *of_size = 0;
        !          1285: 
        !          1286:        if (argc > 3 || genimg_has_config (images)) {
        !          1287: #if defined(CONFIG_FIT)
        !          1288:                if (argc > 3) {
        !          1289:                        /*
        !          1290:                         * If the FDT blob comes from the FIT image and the
        !          1291:                         * FIT image address is omitted in the command line
        !          1292:                         * argument, try to use ramdisk or os FIT image
        !          1293:                         * address or default load address.
        !          1294:                         */
        !          1295:                        if (images->fit_uname_rd)
        !          1296:                                default_addr = (ulong)images->fit_hdr_rd;
        !          1297:                        else if (images->fit_uname_os)
        !          1298:                                default_addr = (ulong)images->fit_hdr_os;
        !          1299:                        else
        !          1300:                                default_addr = load_addr;
        !          1301: 
        !          1302:                        if (fit_parse_conf (argv[3], default_addr,
        !          1303:                                                &fdt_addr, &fit_uname_config)) {
        !          1304:                                debug ("*  fdt: config '%s' from image at 0x%08lx\n",
        !          1305:                                                fit_uname_config, fdt_addr);
        !          1306:                        } else if (fit_parse_subimage (argv[3], default_addr,
        !          1307:                                                &fdt_addr, &fit_uname_fdt)) {
        !          1308:                                debug ("*  fdt: subimage '%s' from image at 0x%08lx\n",
        !          1309:                                                fit_uname_fdt, fdt_addr);
        !          1310:                        } else
        !          1311: #endif
        !          1312:                        {
        !          1313:                                fdt_addr = simple_strtoul(argv[3], NULL, 16);
        !          1314:                                debug ("*  fdt: cmdline image address = 0x%08lx\n",
        !          1315:                                                fdt_addr);
        !          1316:                        }
        !          1317: #if defined(CONFIG_FIT)
        !          1318:                } else {
        !          1319:                        /* use FIT configuration provided in first bootm
        !          1320:                         * command argument
        !          1321:                         */
        !          1322:                        fdt_addr = (ulong)images->fit_hdr_os;
        !          1323:                        fit_uname_config = images->fit_uname_cfg;
        !          1324:                        debug ("*  fdt: using config '%s' from image at 0x%08lx\n",
        !          1325:                                        fit_uname_config, fdt_addr);
        !          1326: 
        !          1327:                        /*
        !          1328:                         * Check whether configuration has FDT blob defined,
        !          1329:                         * if not quit silently.
        !          1330:                         */
        !          1331:                        fit_hdr = (void *)fdt_addr;
        !          1332:                        cfg_noffset = fit_conf_get_node (fit_hdr,
        !          1333:                                        fit_uname_config);
        !          1334:                        if (cfg_noffset < 0) {
        !          1335:                                debug ("*  fdt: no such config\n");
        !          1336:                                return 0;
        !          1337:                        }
        !          1338: 
        !          1339:                        fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
        !          1340:                                        cfg_noffset);
        !          1341:                        if (fdt_noffset < 0) {
        !          1342:                                debug ("*  fdt: no fdt in config\n");
        !          1343:                                return 0;
        !          1344:                        }
        !          1345:                }
        !          1346: #endif
        !          1347: 
        !          1348:                debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n",
        !          1349:                                fdt_addr);
        !          1350: 
        !          1351:                /* copy from dataflash if needed */
        !          1352:                fdt_addr = genimg_get_image (fdt_addr);
        !          1353: 
        !          1354:                /*
        !          1355:                 * Check if there is an FDT image at the
        !          1356:                 * address provided in the second bootm argument
        !          1357:                 * check image type, for FIT images get a FIT node.
        !          1358:                 */
        !          1359:                switch (genimg_get_format ((void *)fdt_addr)) {
        !          1360:                case IMAGE_FORMAT_LEGACY:
        !          1361:                        /* verify fdt_addr points to a valid image header */
        !          1362:                        printf ("## Flattened Device Tree from Legacy Image at %08lx\n",
        !          1363:                                        fdt_addr);
        !          1364:                        fdt_hdr = image_get_fdt (fdt_addr);
        !          1365:                        if (!fdt_hdr)
        !          1366:                                goto error;
        !          1367: 
        !          1368:                        /*
        !          1369:                         * move image data to the load address,
        !          1370:                         * make sure we don't overwrite initial image
        !          1371:                         */
        !          1372:                        image_start = (ulong)fdt_hdr;
        !          1373:                        image_end = image_get_image_end (fdt_hdr);
        !          1374: 
        !          1375:                        load_start = image_get_load (fdt_hdr);
        !          1376:                        load_end = load_start + image_get_data_size (fdt_hdr);
        !          1377: 
        !          1378:                        if ((load_start < image_end) && (load_end > image_start)) {
        !          1379:                                fdt_error ("fdt overwritten");
        !          1380:                                goto error;
        !          1381:                        }
        !          1382: 
        !          1383:                        debug ("   Loading FDT from 0x%08lx to 0x%08lx\n",
        !          1384:                                        image_get_data (fdt_hdr), load_start);
        !          1385: 
        !          1386:                        memmove ((void *)load_start,
        !          1387:                                        (void *)image_get_data (fdt_hdr),
        !          1388:                                        image_get_data_size (fdt_hdr));
        !          1389: 
        !          1390:                        fdt_blob = (char *)load_start;
        !          1391:                        break;
        !          1392:                case IMAGE_FORMAT_FIT:
        !          1393:                        /*
        !          1394:                         * This case will catch both: new uImage format
        !          1395:                         * (libfdt based) and raw FDT blob (also libfdt
        !          1396:                         * based).
        !          1397:                         */
        !          1398: #if defined(CONFIG_FIT)
        !          1399:                        /* check FDT blob vs FIT blob */
        !          1400:                        if (fit_check_format ((const void *)fdt_addr)) {
        !          1401:                                /*
        !          1402:                                 * FIT image
        !          1403:                                 */
        !          1404:                                fit_hdr = (void *)fdt_addr;
        !          1405:                                printf ("## Flattened Device Tree from FIT Image at %08lx\n",
        !          1406:                                                fdt_addr);
        !          1407: 
        !          1408:                                if (!fit_uname_fdt) {
        !          1409:                                        /*
        !          1410:                                         * no FDT blob image node unit name,
        !          1411:                                         * try to get config node first. If
        !          1412:                                         * config unit node name is NULL
        !          1413:                                         * fit_conf_get_node() will try to
        !          1414:                                         * find default config node
        !          1415:                                         */
        !          1416:                                        cfg_noffset = fit_conf_get_node (fit_hdr,
        !          1417:                                                        fit_uname_config);
        !          1418: 
        !          1419:                                        if (cfg_noffset < 0) {
        !          1420:                                                fdt_error ("Could not find configuration node\n");
        !          1421:                                                goto error;
        !          1422:                                        }
        !          1423: 
        !          1424:                                        fit_uname_config = fdt_get_name (fit_hdr,
        !          1425:                                                        cfg_noffset, NULL);
        !          1426:                                        printf ("   Using '%s' configuration\n",
        !          1427:                                                        fit_uname_config);
        !          1428: 
        !          1429:                                        fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
        !          1430:                                                        cfg_noffset);
        !          1431:                                        fit_uname_fdt = fit_get_name (fit_hdr,
        !          1432:                                                        fdt_noffset, NULL);
        !          1433:                                } else {
        !          1434:                                        /* get FDT component image node offset */
        !          1435:                                        fdt_noffset = fit_image_get_node (fit_hdr,
        !          1436:                                                        fit_uname_fdt);
        !          1437:                                }
        !          1438:                                if (fdt_noffset < 0) {
        !          1439:                                        fdt_error ("Could not find subimage node\n");
        !          1440:                                        goto error;
        !          1441:                                }
        !          1442: 
        !          1443:                                printf ("   Trying '%s' FDT blob subimage\n",
        !          1444:                                                fit_uname_fdt);
        !          1445: 
        !          1446:                                if (!fit_check_fdt (fit_hdr, fdt_noffset,
        !          1447:                                                        images->verify))
        !          1448:                                        goto error;
        !          1449: 
        !          1450:                                /* get ramdisk image data address and length */
        !          1451:                                if (fit_image_get_data (fit_hdr, fdt_noffset,
        !          1452:                                                        &data, &size)) {
        !          1453:                                        fdt_error ("Could not find FDT subimage data");
        !          1454:                                        goto error;
        !          1455:                                }
        !          1456: 
        !          1457:                                /* verift that image data is a proper FDT blob */
        !          1458:                                if (fdt_check_header ((char *)data) != 0) {
        !          1459:                                        fdt_error ("Subimage data is not a FTD");
        !          1460:                                        goto error;
        !          1461:                                }
        !          1462: 
        !          1463:                                /*
        !          1464:                                 * move image data to the load address,
        !          1465:                                 * make sure we don't overwrite initial image
        !          1466:                                 */
        !          1467:                                image_start = (ulong)fit_hdr;
        !          1468:                                image_end = fit_get_end (fit_hdr);
        !          1469: 
        !          1470:                                if (fit_image_get_load (fit_hdr, fdt_noffset,
        !          1471:                                                        &load_start) == 0) {
        !          1472:                                        load_end = load_start + size;
        !          1473: 
        !          1474:                                        if ((load_start < image_end) &&
        !          1475:                                                        (load_end > image_start)) {
        !          1476:                                                fdt_error ("FDT overwritten");
        !          1477:                                                goto error;
        !          1478:                                        }
        !          1479: 
        !          1480:                                        printf ("   Loading FDT from 0x%08lx to 0x%08lx\n",
        !          1481:                                                        (ulong)data, load_start);
        !          1482: 
        !          1483:                                        memmove ((void *)load_start,
        !          1484:                                                        (void *)data, size);
        !          1485: 
        !          1486:                                        fdt_blob = (char *)load_start;
        !          1487:                                } else {
        !          1488:                                        fdt_blob = (char *)data;
        !          1489:                                }
        !          1490: 
        !          1491:                                images->fit_hdr_fdt = fit_hdr;
        !          1492:                                images->fit_uname_fdt = fit_uname_fdt;
        !          1493:                                images->fit_noffset_fdt = fdt_noffset;
        !          1494:                                break;
        !          1495:                        } else
        !          1496: #endif
        !          1497:                        {
        !          1498:                                /*
        !          1499:                                 * FDT blob
        !          1500:                                 */
        !          1501:                                fdt_blob = (char *)fdt_addr;
        !          1502:                                debug ("*  fdt: raw FDT blob\n");
        !          1503:                                printf ("## Flattened Device Tree blob at %08lx\n", (long)fdt_blob);
        !          1504:                        }
        !          1505:                        break;
        !          1506:                default:
        !          1507:                        puts ("ERROR: Did not find a cmdline Flattened Device Tree\n");
        !          1508:                        goto error;
        !          1509:                }
        !          1510: 
        !          1511:                printf ("   Booting using the fdt blob at 0x%x\n", (int)fdt_blob);
        !          1512: 
        !          1513:        } else if (images->legacy_hdr_valid &&
        !          1514:                        image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
        !          1515: 
        !          1516:                ulong fdt_data, fdt_len;
        !          1517: 
        !          1518:                /*
        !          1519:                 * Now check if we have a legacy multi-component image,
        !          1520:                 * get second entry data start address and len.
        !          1521:                 */
        !          1522:                printf ("## Flattened Device Tree from multi "
        !          1523:                        "component Image at %08lX\n",
        !          1524:                        (ulong)images->legacy_hdr_os);
        !          1525: 
        !          1526:                image_multi_getimg (images->legacy_hdr_os, 2, &fdt_data, &fdt_len);
        !          1527:                if (fdt_len) {
        !          1528: 
        !          1529:                        fdt_blob = (char *)fdt_data;
        !          1530:                        printf ("   Booting using the fdt at 0x%x\n", (int)fdt_blob);
        !          1531: 
        !          1532:                        if (fdt_check_header (fdt_blob) != 0) {
        !          1533:                                fdt_error ("image is not a fdt");
        !          1534:                                goto error;
        !          1535:                        }
        !          1536: 
        !          1537:                        if (fdt_totalsize(fdt_blob) != fdt_len) {
        !          1538:                                fdt_error ("fdt size != image size");
        !          1539:                                goto error;
        !          1540:                        }
        !          1541:                } else {
        !          1542:                        debug ("## No Flattened Device Tree\n");
        !          1543:                        return 0;
        !          1544:                }
        !          1545:        } else {
        !          1546:                debug ("## No Flattened Device Tree\n");
        !          1547:                return 0;
        !          1548:        }
        !          1549: 
        !          1550:        *of_flat_tree = fdt_blob;
        !          1551:        *of_size = fdt_totalsize(fdt_blob);
        !          1552:        debug ("   of_flat_tree at 0x%08lx size 0x%08lx\n",
        !          1553:                        (ulong)*of_flat_tree, *of_size);
        !          1554: 
        !          1555:        return 0;
        !          1556: 
        !          1557: error:
        !          1558:        *of_flat_tree = 0;
        !          1559:        *of_size = 0;
        !          1560:        return 1;
        !          1561: }
        !          1562: #endif /* CONFIG_OF_LIBFDT */
        !          1563: 
        !          1564: #ifdef CONFIG_SYS_BOOT_GET_CMDLINE
        !          1565: /**
        !          1566:  * boot_get_cmdline - allocate and initialize kernel cmdline
        !          1567:  * @lmb: pointer to lmb handle, will be used for memory mgmt
        !          1568:  * @cmd_start: pointer to a ulong variable, will hold cmdline start
        !          1569:  * @cmd_end: pointer to a ulong variable, will hold cmdline end
        !          1570:  * @bootmap_base: ulong variable, holds offset in physical memory to
        !          1571:  * base of bootmap
        !          1572:  *
        !          1573:  * boot_get_cmdline() allocates space for kernel command line below
        !          1574:  * BOOTMAPSZ + bootmap_base address. If "bootargs" U-boot environemnt
        !          1575:  * variable is present its contents is copied to allocated kernel
        !          1576:  * command line.
        !          1577:  *
        !          1578:  * returns:
        !          1579:  *      0 - success
        !          1580:  *     -1 - failure
        !          1581:  */
        !          1582: int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
        !          1583:                        ulong bootmap_base)
        !          1584: {
        !          1585:        char *cmdline;
        !          1586:        char *s;
        !          1587: 
        !          1588:        cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf,
        !          1589:                                         CONFIG_SYS_BOOTMAPSZ + bootmap_base);
        !          1590: 
        !          1591:        if (cmdline == NULL)
        !          1592:                return -1;
        !          1593: 
        !          1594:        if ((s = getenv("bootargs")) == NULL)
        !          1595:                s = "";
        !          1596: 
        !          1597:        strcpy(cmdline, s);
        !          1598: 
        !          1599:        *cmd_start = (ulong) & cmdline[0];
        !          1600:        *cmd_end = *cmd_start + strlen(cmdline);
        !          1601: 
        !          1602:        debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);
        !          1603: 
        !          1604:        return 0;
        !          1605: }
        !          1606: #endif /* CONFIG_SYS_BOOT_GET_CMDLINE */
        !          1607: 
        !          1608: #ifdef CONFIG_SYS_BOOT_GET_KBD
        !          1609: /**
        !          1610:  * boot_get_kbd - allocate and initialize kernel copy of board info
        !          1611:  * @lmb: pointer to lmb handle, will be used for memory mgmt
        !          1612:  * @kbd: double pointer to board info data
        !          1613:  * @bootmap_base: ulong variable, holds offset in physical memory to
        !          1614:  * base of bootmap
        !          1615:  *
        !          1616:  * boot_get_kbd() allocates space for kernel copy of board info data below
        !          1617:  * BOOTMAPSZ + bootmap_base address and kernel board info is initialized with
        !          1618:  * the current u-boot board info data.
        !          1619:  *
        !          1620:  * returns:
        !          1621:  *      0 - success
        !          1622:  *     -1 - failure
        !          1623:  */
        !          1624: int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base)
        !          1625: {
        !          1626:        *kbd = (bd_t *)(ulong)lmb_alloc_base(lmb, sizeof(bd_t), 0xf,
        !          1627:                                      CONFIG_SYS_BOOTMAPSZ + bootmap_base);
        !          1628:        if (*kbd == NULL)
        !          1629:                return -1;
        !          1630: 
        !          1631:        **kbd = *(gd->bd);
        !          1632: 
        !          1633:        debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd);
        !          1634: 
        !          1635: #if defined(DEBUG) && defined(CONFIG_CMD_BDI)
        !          1636:        do_bdinfo(NULL, 0, 0, NULL);
        !          1637: #endif
        !          1638: 
        !          1639:        return 0;
        !          1640: }
        !          1641: #endif /* CONFIG_SYS_BOOT_GET_KBD */
        !          1642: #endif /* !USE_HOSTCC */
        !          1643: 
        !          1644: #if defined(CONFIG_FIT)
        !          1645: /*****************************************************************************/
        !          1646: /* New uImage format routines */
        !          1647: /*****************************************************************************/
        !          1648: #ifndef USE_HOSTCC
        !          1649: static int fit_parse_spec (const char *spec, char sepc, ulong addr_curr,
        !          1650:                ulong *addr, const char **name)
        !          1651: {
        !          1652:        const char *sep;
        !          1653: 
        !          1654:        *addr = addr_curr;
        !          1655:        *name = NULL;
        !          1656: 
        !          1657:        sep = strchr (spec, sepc);
        !          1658:        if (sep) {
        !          1659:                if (sep - spec > 0)
        !          1660:                        *addr = simple_strtoul (spec, NULL, 16);
        !          1661: 
        !          1662:                *name = sep + 1;
        !          1663:                return 1;
        !          1664:        }
        !          1665: 
        !          1666:        return 0;
        !          1667: }
        !          1668: 
        !          1669: /**
        !          1670:  * fit_parse_conf - parse FIT configuration spec
        !          1671:  * @spec: input string, containing configuration spec
        !          1672:  * @add_curr: current image address (to be used as a possible default)
        !          1673:  * @addr: pointer to a ulong variable, will hold FIT image address of a given
        !          1674:  * configuration
        !          1675:  * @conf_name double pointer to a char, will hold pointer to a configuration
        !          1676:  * unit name
        !          1677:  *
        !          1678:  * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>,
        !          1679:  * where <addr> is a FIT image address that contains configuration
        !          1680:  * with a <conf> unit name.
        !          1681:  *
        !          1682:  * Address part is optional, and if omitted default add_curr will
        !          1683:  * be used instead.
        !          1684:  *
        !          1685:  * returns:
        !          1686:  *     1 if spec is a valid configuration string,
        !          1687:  *     addr and conf_name are set accordingly
        !          1688:  *     0 otherwise
        !          1689:  */
        !          1690: inline int fit_parse_conf (const char *spec, ulong addr_curr,
        !          1691:                ulong *addr, const char **conf_name)
        !          1692: {
        !          1693:        return fit_parse_spec (spec, '#', addr_curr, addr, conf_name);
        !          1694: }
        !          1695: 
        !          1696: /**
        !          1697:  * fit_parse_subimage - parse FIT subimage spec
        !          1698:  * @spec: input string, containing subimage spec
        !          1699:  * @add_curr: current image address (to be used as a possible default)
        !          1700:  * @addr: pointer to a ulong variable, will hold FIT image address of a given
        !          1701:  * subimage
        !          1702:  * @image_name: double pointer to a char, will hold pointer to a subimage name
        !          1703:  *
        !          1704:  * fit_parse_subimage() expects subimage spec in the for of
        !          1705:  * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
        !          1706:  * subimage with a <subimg> unit name.
        !          1707:  *
        !          1708:  * Address part is optional, and if omitted default add_curr will
        !          1709:  * be used instead.
        !          1710:  *
        !          1711:  * returns:
        !          1712:  *     1 if spec is a valid subimage string,
        !          1713:  *     addr and image_name are set accordingly
        !          1714:  *     0 otherwise
        !          1715:  */
        !          1716: inline int fit_parse_subimage (const char *spec, ulong addr_curr,
        !          1717:                ulong *addr, const char **image_name)
        !          1718: {
        !          1719:        return fit_parse_spec (spec, ':', addr_curr, addr, image_name);
        !          1720: }
        !          1721: #endif /* !USE_HOSTCC */
        !          1722: 
        !          1723: static void fit_get_debug (const void *fit, int noffset,
        !          1724:                char *prop_name, int err)
        !          1725: {
        !          1726:        debug ("Can't get '%s' property from FIT 0x%08lx, "
        !          1727:                "node: offset %d, name %s (%s)\n",
        !          1728:                prop_name, (ulong)fit, noffset,
        !          1729:                fit_get_name (fit, noffset, NULL),
        !          1730:                fdt_strerror (err));
        !          1731: }
        !          1732: 
        !          1733: /**
        !          1734:  * fit_print_contents - prints out the contents of the FIT format image
        !          1735:  * @fit: pointer to the FIT format image header
        !          1736:  * @p: pointer to prefix string
        !          1737:  *
        !          1738:  * fit_print_contents() formats a multi line FIT image contents description.
        !          1739:  * The routine prints out FIT image properties (root node level) follwed by
        !          1740:  * the details of each component image.
        !          1741:  *
        !          1742:  * returns:
        !          1743:  *     no returned results
        !          1744:  */
        !          1745: void fit_print_contents (const void *fit)
        !          1746: {
        !          1747:        char *desc;
        !          1748:        char *uname;
        !          1749:        int images_noffset;
        !          1750:        int confs_noffset;
        !          1751:        int noffset;
        !          1752:        int ndepth;
        !          1753:        int count = 0;
        !          1754:        int ret;
        !          1755:        const char *p;
        !          1756: #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
        !          1757:        time_t timestamp;
        !          1758: #endif
        !          1759: 
        !          1760: #ifdef USE_HOSTCC
        !          1761:        p = "";
        !          1762: #else
        !          1763:        p = "   ";
        !          1764: #endif
        !          1765: 
        !          1766:        /* Root node properties */
        !          1767:        ret = fit_get_desc (fit, 0, &desc);
        !          1768:        printf ("%sFIT description: ", p);
        !          1769:        if (ret)
        !          1770:                printf ("unavailable\n");
        !          1771:        else
        !          1772:                printf ("%s\n", desc);
        !          1773: 
        !          1774: #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
        !          1775:        ret = fit_get_timestamp (fit, 0, &timestamp);
        !          1776:        printf ("%sCreated:         ", p);
        !          1777:        if (ret)
        !          1778:                printf ("unavailable\n");
        !          1779:        else
        !          1780:                genimg_print_time (timestamp);
        !          1781: #endif
        !          1782: 
        !          1783:        /* Find images parent node offset */
        !          1784:        images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
        !          1785:        if (images_noffset < 0) {
        !          1786:                printf ("Can't find images parent node '%s' (%s)\n",
        !          1787:                        FIT_IMAGES_PATH, fdt_strerror (images_noffset));
        !          1788:                return;
        !          1789:        }
        !          1790: 
        !          1791:        /* Process its subnodes, print out component images details */
        !          1792:        for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth);
        !          1793:             (noffset >= 0) && (ndepth > 0);
        !          1794:             noffset = fdt_next_node (fit, noffset, &ndepth)) {
        !          1795:                if (ndepth == 1) {
        !          1796:                        /*
        !          1797:                         * Direct child node of the images parent node,
        !          1798:                         * i.e. component image node.
        !          1799:                         */
        !          1800:                        printf ("%s Image %u (%s)\n", p, count++,
        !          1801:                                        fit_get_name(fit, noffset, NULL));
        !          1802: 
        !          1803:                        fit_image_print (fit, noffset, p);
        !          1804:                }
        !          1805:        }
        !          1806: 
        !          1807:        /* Find configurations parent node offset */
        !          1808:        confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH);
        !          1809:        if (confs_noffset < 0) {
        !          1810:                debug ("Can't get configurations parent node '%s' (%s)\n",
        !          1811:                        FIT_CONFS_PATH, fdt_strerror (confs_noffset));
        !          1812:                return;
        !          1813:        }
        !          1814: 
        !          1815:        /* get default configuration unit name from default property */
        !          1816:        uname = (char *)fdt_getprop (fit, noffset, FIT_DEFAULT_PROP, NULL);
        !          1817:        if (uname)
        !          1818:                printf ("%s Default Configuration: '%s'\n", p, uname);
        !          1819: 
        !          1820:        /* Process its subnodes, print out configurations details */
        !          1821:        for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, confs_noffset, &ndepth);
        !          1822:             (noffset >= 0) && (ndepth > 0);
        !          1823:             noffset = fdt_next_node (fit, noffset, &ndepth)) {
        !          1824:                if (ndepth == 1) {
        !          1825:                        /*
        !          1826:                         * Direct child node of the configurations parent node,
        !          1827:                         * i.e. configuration node.
        !          1828:                         */
        !          1829:                        printf ("%s Configuration %u (%s)\n", p, count++,
        !          1830:                                        fit_get_name(fit, noffset, NULL));
        !          1831: 
        !          1832:                        fit_conf_print (fit, noffset, p);
        !          1833:                }
        !          1834:        }
        !          1835: }
        !          1836: 
        !          1837: /**
        !          1838:  * fit_image_print - prints out the FIT component image details
        !          1839:  * @fit: pointer to the FIT format image header
        !          1840:  * @image_noffset: offset of the component image node
        !          1841:  * @p: pointer to prefix string
        !          1842:  *
        !          1843:  * fit_image_print() lists all mandatory properies for the processed component
        !          1844:  * image. If present, hash nodes are printed out as well. Load
        !          1845:  * address for images of type firmware is also printed out. Since the load
        !          1846:  * address is not mandatory for firmware images, it will be output as
        !          1847:  * "unavailable" when not present.
        !          1848:  *
        !          1849:  * returns:
        !          1850:  *     no returned results
        !          1851:  */
        !          1852: void fit_image_print (const void *fit, int image_noffset, const char *p)
        !          1853: {
        !          1854:        char *desc;
        !          1855:        uint8_t type, arch, os, comp;
        !          1856:        size_t size;
        !          1857:        ulong load, entry;
        !          1858:        const void *data;
        !          1859:        int noffset;
        !          1860:        int ndepth;
        !          1861:        int ret;
        !          1862: 
        !          1863:        /* Mandatory properties */
        !          1864:        ret = fit_get_desc (fit, image_noffset, &desc);
        !          1865:        printf ("%s  Description:  ", p);
        !          1866:        if (ret)
        !          1867:                printf ("unavailable\n");
        !          1868:        else
        !          1869:                printf ("%s\n", desc);
        !          1870: 
        !          1871:        fit_image_get_type (fit, image_noffset, &type);
        !          1872:        printf ("%s  Type:         %s\n", p, genimg_get_type_name (type));
        !          1873: 
        !          1874:        fit_image_get_comp (fit, image_noffset, &comp);
        !          1875:        printf ("%s  Compression:  %s\n", p, genimg_get_comp_name (comp));
        !          1876: 
        !          1877:        ret = fit_image_get_data (fit, image_noffset, &data, &size);
        !          1878: 
        !          1879: #ifndef USE_HOSTCC
        !          1880:        printf ("%s  Data Start:   ", p);
        !          1881:        if (ret)
        !          1882:                printf ("unavailable\n");
        !          1883:        else
        !          1884:                printf ("0x%08lx\n", (ulong)data);
        !          1885: #endif
        !          1886: 
        !          1887:        printf ("%s  Data Size:    ", p);
        !          1888:        if (ret)
        !          1889:                printf ("unavailable\n");
        !          1890:        else
        !          1891:                genimg_print_size (size);
        !          1892: 
        !          1893:        /* Remaining, type dependent properties */
        !          1894:        if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
        !          1895:            (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
        !          1896:            (type == IH_TYPE_FLATDT)) {
        !          1897:                fit_image_get_arch (fit, image_noffset, &arch);
        !          1898:                printf ("%s  Architecture: %s\n", p, genimg_get_arch_name (arch));
        !          1899:        }
        !          1900: 
        !          1901:        if (type == IH_TYPE_KERNEL) {
        !          1902:                fit_image_get_os (fit, image_noffset, &os);
        !          1903:                printf ("%s  OS:           %s\n", p, genimg_get_os_name (os));
        !          1904:        }
        !          1905: 
        !          1906:        if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
        !          1907:                (type == IH_TYPE_FIRMWARE)) {
        !          1908:                ret = fit_image_get_load (fit, image_noffset, &load);
        !          1909:                printf ("%s  Load Address: ", p);
        !          1910:                if (ret)
        !          1911:                        printf ("unavailable\n");
        !          1912:                else
        !          1913:                        printf ("0x%08lx\n", load);
        !          1914:        }
        !          1915: 
        !          1916:        if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE)) {
        !          1917:                fit_image_get_entry (fit, image_noffset, &entry);
        !          1918:                printf ("%s  Entry Point:  ", p);
        !          1919:                if (ret)
        !          1920:                        printf ("unavailable\n");
        !          1921:                else
        !          1922:                        printf ("0x%08lx\n", entry);
        !          1923:        }
        !          1924: 
        !          1925:        /* Process all hash subnodes of the component image node */
        !          1926:        for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
        !          1927:             (noffset >= 0) && (ndepth > 0);
        !          1928:             noffset = fdt_next_node (fit, noffset, &ndepth)) {
        !          1929:                if (ndepth == 1) {
        !          1930:                        /* Direct child node of the component image node */
        !          1931:                        fit_image_print_hash (fit, noffset, p);
        !          1932:                }
        !          1933:        }
        !          1934: }
        !          1935: 
        !          1936: /**
        !          1937:  * fit_image_print_hash - prints out the hash node details
        !          1938:  * @fit: pointer to the FIT format image header
        !          1939:  * @noffset: offset of the hash node
        !          1940:  * @p: pointer to prefix string
        !          1941:  *
        !          1942:  * fit_image_print_hash() lists properies for the processed hash node
        !          1943:  *
        !          1944:  * returns:
        !          1945:  *     no returned results
        !          1946:  */
        !          1947: void fit_image_print_hash (const void *fit, int noffset, const char *p)
        !          1948: {
        !          1949:        char *algo;
        !          1950:        uint8_t *value;
        !          1951:        int value_len;
        !          1952:        int i, ret;
        !          1953: 
        !          1954:        /*
        !          1955:         * Check subnode name, must be equal to "hash".
        !          1956:         * Multiple hash nodes require unique unit node
        !          1957:         * names, e.g. hash@1, hash@2, etc.
        !          1958:         */
        !          1959:        if (strncmp (fit_get_name(fit, noffset, NULL),
        !          1960:                        FIT_HASH_NODENAME,
        !          1961:                        strlen(FIT_HASH_NODENAME)) != 0)
        !          1962:                return;
        !          1963: 
        !          1964:        debug ("%s  Hash node:    '%s'\n", p,
        !          1965:                        fit_get_name (fit, noffset, NULL));
        !          1966: 
        !          1967:        printf ("%s  Hash algo:    ", p);
        !          1968:        if (fit_image_hash_get_algo (fit, noffset, &algo)) {
        !          1969:                printf ("invalid/unsupported\n");
        !          1970:                return;
        !          1971:        }
        !          1972:        printf ("%s\n", algo);
        !          1973: 
        !          1974:        ret = fit_image_hash_get_value (fit, noffset, &value,
        !          1975:                                        &value_len);
        !          1976:        printf ("%s  Hash value:   ", p);
        !          1977:        if (ret) {
        !          1978:                printf ("unavailable\n");
        !          1979:        } else {
        !          1980:                for (i = 0; i < value_len; i++)
        !          1981:                        printf ("%02x", value[i]);
        !          1982:                printf ("\n");
        !          1983:        }
        !          1984: 
        !          1985:        debug  ("%s  Hash len:     %d\n", p, value_len);
        !          1986: }
        !          1987: 
        !          1988: /**
        !          1989:  * fit_get_desc - get node description property
        !          1990:  * @fit: pointer to the FIT format image header
        !          1991:  * @noffset: node offset
        !          1992:  * @desc: double pointer to the char, will hold pointer to the descrption
        !          1993:  *
        !          1994:  * fit_get_desc() reads description property from a given node, if
        !          1995:  * description is found pointer to it is returened in third call argument.
        !          1996:  *
        !          1997:  * returns:
        !          1998:  *     0, on success
        !          1999:  *     -1, on failure
        !          2000:  */
        !          2001: int fit_get_desc (const void *fit, int noffset, char **desc)
        !          2002: {
        !          2003:        int len;
        !          2004: 
        !          2005:        *desc = (char *)fdt_getprop (fit, noffset, FIT_DESC_PROP, &len);
        !          2006:        if (*desc == NULL) {
        !          2007:                fit_get_debug (fit, noffset, FIT_DESC_PROP, len);
        !          2008:                return -1;
        !          2009:        }
        !          2010: 
        !          2011:        return 0;
        !          2012: }
        !          2013: 
        !          2014: /**
        !          2015:  * fit_get_timestamp - get node timestamp property
        !          2016:  * @fit: pointer to the FIT format image header
        !          2017:  * @noffset: node offset
        !          2018:  * @timestamp: pointer to the time_t, will hold read timestamp
        !          2019:  *
        !          2020:  * fit_get_timestamp() reads timestamp poperty from given node, if timestamp
        !          2021:  * is found and has a correct size its value is retured in third call
        !          2022:  * argument.
        !          2023:  *
        !          2024:  * returns:
        !          2025:  *     0, on success
        !          2026:  *     -1, on property read failure
        !          2027:  *     -2, on wrong timestamp size
        !          2028:  */
        !          2029: int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp)
        !          2030: {
        !          2031:        int len;
        !          2032:        const void *data;
        !          2033: 
        !          2034:        data = fdt_getprop (fit, noffset, FIT_TIMESTAMP_PROP, &len);
        !          2035:        if (data == NULL) {
        !          2036:                fit_get_debug (fit, noffset, FIT_TIMESTAMP_PROP, len);
        !          2037:                return -1;
        !          2038:        }
        !          2039:        if (len != sizeof (uint32_t)) {
        !          2040:                debug ("FIT timestamp with incorrect size of (%u)\n", len);
        !          2041:                return -2;
        !          2042:        }
        !          2043: 
        !          2044:        *timestamp = uimage_to_cpu (*((uint32_t *)data));
        !          2045:        return 0;
        !          2046: }
        !          2047: 
        !          2048: /**
        !          2049:  * fit_image_get_node - get node offset for component image of a given unit name
        !          2050:  * @fit: pointer to the FIT format image header
        !          2051:  * @image_uname: component image node unit name
        !          2052:  *
        !          2053:  * fit_image_get_node() finds a component image (withing the '/images'
        !          2054:  * node) of a provided unit name. If image is found its node offset is
        !          2055:  * returned to the caller.
        !          2056:  *
        !          2057:  * returns:
        !          2058:  *     image node offset when found (>=0)
        !          2059:  *     negative number on failure (FDT_ERR_* code)
        !          2060:  */
        !          2061: int fit_image_get_node (const void *fit, const char *image_uname)
        !          2062: {
        !          2063:        int noffset, images_noffset;
        !          2064: 
        !          2065:        images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
        !          2066:        if (images_noffset < 0) {
        !          2067:                debug ("Can't find images parent node '%s' (%s)\n",
        !          2068:                        FIT_IMAGES_PATH, fdt_strerror (images_noffset));
        !          2069:                return images_noffset;
        !          2070:        }
        !          2071: 
        !          2072:        noffset = fdt_subnode_offset (fit, images_noffset, image_uname);
        !          2073:        if (noffset < 0) {
        !          2074:                debug ("Can't get node offset for image unit name: '%s' (%s)\n",
        !          2075:                        image_uname, fdt_strerror (noffset));
        !          2076:        }
        !          2077: 
        !          2078:        return noffset;
        !          2079: }
        !          2080: 
        !          2081: /**
        !          2082:  * fit_image_get_os - get os id for a given component image node
        !          2083:  * @fit: pointer to the FIT format image header
        !          2084:  * @noffset: component image node offset
        !          2085:  * @os: pointer to the uint8_t, will hold os numeric id
        !          2086:  *
        !          2087:  * fit_image_get_os() finds os property in a given component image node.
        !          2088:  * If the property is found, its (string) value is translated to the numeric
        !          2089:  * id which is returned to the caller.
        !          2090:  *
        !          2091:  * returns:
        !          2092:  *     0, on success
        !          2093:  *     -1, on failure
        !          2094:  */
        !          2095: int fit_image_get_os (const void *fit, int noffset, uint8_t *os)
        !          2096: {
        !          2097:        int len;
        !          2098:        const void *data;
        !          2099: 
        !          2100:        /* Get OS name from property data */
        !          2101:        data = fdt_getprop (fit, noffset, FIT_OS_PROP, &len);
        !          2102:        if (data == NULL) {
        !          2103:                fit_get_debug (fit, noffset, FIT_OS_PROP, len);
        !          2104:                *os = -1;
        !          2105:                return -1;
        !          2106:        }
        !          2107: 
        !          2108:        /* Translate OS name to id */
        !          2109:        *os = genimg_get_os_id (data);
        !          2110:        return 0;
        !          2111: }
        !          2112: 
        !          2113: /**
        !          2114:  * fit_image_get_arch - get arch id for a given component image node
        !          2115:  * @fit: pointer to the FIT format image header
        !          2116:  * @noffset: component image node offset
        !          2117:  * @arch: pointer to the uint8_t, will hold arch numeric id
        !          2118:  *
        !          2119:  * fit_image_get_arch() finds arch property in a given component image node.
        !          2120:  * If the property is found, its (string) value is translated to the numeric
        !          2121:  * id which is returned to the caller.
        !          2122:  *
        !          2123:  * returns:
        !          2124:  *     0, on success
        !          2125:  *     -1, on failure
        !          2126:  */
        !          2127: int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch)
        !          2128: {
        !          2129:        int len;
        !          2130:        const void *data;
        !          2131: 
        !          2132:        /* Get architecture name from property data */
        !          2133:        data = fdt_getprop (fit, noffset, FIT_ARCH_PROP, &len);
        !          2134:        if (data == NULL) {
        !          2135:                fit_get_debug (fit, noffset, FIT_ARCH_PROP, len);
        !          2136:                *arch = -1;
        !          2137:                return -1;
        !          2138:        }
        !          2139: 
        !          2140:        /* Translate architecture name to id */
        !          2141:        *arch = genimg_get_arch_id (data);
        !          2142:        return 0;
        !          2143: }
        !          2144: 
        !          2145: /**
        !          2146:  * fit_image_get_type - get type id for a given component image node
        !          2147:  * @fit: pointer to the FIT format image header
        !          2148:  * @noffset: component image node offset
        !          2149:  * @type: pointer to the uint8_t, will hold type numeric id
        !          2150:  *
        !          2151:  * fit_image_get_type() finds type property in a given component image node.
        !          2152:  * If the property is found, its (string) value is translated to the numeric
        !          2153:  * id which is returned to the caller.
        !          2154:  *
        !          2155:  * returns:
        !          2156:  *     0, on success
        !          2157:  *     -1, on failure
        !          2158:  */
        !          2159: int fit_image_get_type (const void *fit, int noffset, uint8_t *type)
        !          2160: {
        !          2161:        int len;
        !          2162:        const void *data;
        !          2163: 
        !          2164:        /* Get image type name from property data */
        !          2165:        data = fdt_getprop (fit, noffset, FIT_TYPE_PROP, &len);
        !          2166:        if (data == NULL) {
        !          2167:                fit_get_debug (fit, noffset, FIT_TYPE_PROP, len);
        !          2168:                *type = -1;
        !          2169:                return -1;
        !          2170:        }
        !          2171: 
        !          2172:        /* Translate image type name to id */
        !          2173:        *type = genimg_get_type_id (data);
        !          2174:        return 0;
        !          2175: }
        !          2176: 
        !          2177: /**
        !          2178:  * fit_image_get_comp - get comp id for a given component image node
        !          2179:  * @fit: pointer to the FIT format image header
        !          2180:  * @noffset: component image node offset
        !          2181:  * @comp: pointer to the uint8_t, will hold comp numeric id
        !          2182:  *
        !          2183:  * fit_image_get_comp() finds comp property in a given component image node.
        !          2184:  * If the property is found, its (string) value is translated to the numeric
        !          2185:  * id which is returned to the caller.
        !          2186:  *
        !          2187:  * returns:
        !          2188:  *     0, on success
        !          2189:  *     -1, on failure
        !          2190:  */
        !          2191: int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp)
        !          2192: {
        !          2193:        int len;
        !          2194:        const void *data;
        !          2195: 
        !          2196:        /* Get compression name from property data */
        !          2197:        data = fdt_getprop (fit, noffset, FIT_COMP_PROP, &len);
        !          2198:        if (data == NULL) {
        !          2199:                fit_get_debug (fit, noffset, FIT_COMP_PROP, len);
        !          2200:                *comp = -1;
        !          2201:                return -1;
        !          2202:        }
        !          2203: 
        !          2204:        /* Translate compression name to id */
        !          2205:        *comp = genimg_get_comp_id (data);
        !          2206:        return 0;
        !          2207: }
        !          2208: 
        !          2209: /**
        !          2210:  * fit_image_get_load - get load address property for a given component image node
        !          2211:  * @fit: pointer to the FIT format image header
        !          2212:  * @noffset: component image node offset
        !          2213:  * @load: pointer to the uint32_t, will hold load address
        !          2214:  *
        !          2215:  * fit_image_get_load() finds load address property in a given component image node.
        !          2216:  * If the property is found, its value is returned to the caller.
        !          2217:  *
        !          2218:  * returns:
        !          2219:  *     0, on success
        !          2220:  *     -1, on failure
        !          2221:  */
        !          2222: int fit_image_get_load (const void *fit, int noffset, ulong *load)
        !          2223: {
        !          2224:        int len;
        !          2225:        const uint32_t *data;
        !          2226: 
        !          2227:        data = fdt_getprop (fit, noffset, FIT_LOAD_PROP, &len);
        !          2228:        if (data == NULL) {
        !          2229:                fit_get_debug (fit, noffset, FIT_LOAD_PROP, len);
        !          2230:                return -1;
        !          2231:        }
        !          2232: 
        !          2233:        *load = uimage_to_cpu (*data);
        !          2234:        return 0;
        !          2235: }
        !          2236: 
        !          2237: /**
        !          2238:  * fit_image_get_entry - get entry point address property for a given component image node
        !          2239:  * @fit: pointer to the FIT format image header
        !          2240:  * @noffset: component image node offset
        !          2241:  * @entry: pointer to the uint32_t, will hold entry point address
        !          2242:  *
        !          2243:  * fit_image_get_entry() finds entry point address property in a given component image node.
        !          2244:  * If the property is found, its value is returned to the caller.
        !          2245:  *
        !          2246:  * returns:
        !          2247:  *     0, on success
        !          2248:  *     -1, on failure
        !          2249:  */
        !          2250: int fit_image_get_entry (const void *fit, int noffset, ulong *entry)
        !          2251: {
        !          2252:        int len;
        !          2253:        const uint32_t *data;
        !          2254: 
        !          2255:        data = fdt_getprop (fit, noffset, FIT_ENTRY_PROP, &len);
        !          2256:        if (data == NULL) {
        !          2257:                fit_get_debug (fit, noffset, FIT_ENTRY_PROP, len);
        !          2258:                return -1;
        !          2259:        }
        !          2260: 
        !          2261:        *entry = uimage_to_cpu (*data);
        !          2262:        return 0;
        !          2263: }
        !          2264: 
        !          2265: /**
        !          2266:  * fit_image_get_data - get data property and its size for a given component image node
        !          2267:  * @fit: pointer to the FIT format image header
        !          2268:  * @noffset: component image node offset
        !          2269:  * @data: double pointer to void, will hold data property's data address
        !          2270:  * @size: pointer to size_t, will hold data property's data size
        !          2271:  *
        !          2272:  * fit_image_get_data() finds data property in a given component image node.
        !          2273:  * If the property is found its data start address and size are returned to
        !          2274:  * the caller.
        !          2275:  *
        !          2276:  * returns:
        !          2277:  *     0, on success
        !          2278:  *     -1, on failure
        !          2279:  */
        !          2280: int fit_image_get_data (const void *fit, int noffset,
        !          2281:                const void **data, size_t *size)
        !          2282: {
        !          2283:        int len;
        !          2284: 
        !          2285:        *data = fdt_getprop (fit, noffset, FIT_DATA_PROP, &len);
        !          2286:        if (*data == NULL) {
        !          2287:                fit_get_debug (fit, noffset, FIT_DATA_PROP, len);
        !          2288:                *size = 0;
        !          2289:                return -1;
        !          2290:        }
        !          2291: 
        !          2292:        *size = len;
        !          2293:        return 0;
        !          2294: }
        !          2295: 
        !          2296: /**
        !          2297:  * fit_image_hash_get_algo - get hash algorithm name
        !          2298:  * @fit: pointer to the FIT format image header
        !          2299:  * @noffset: hash node offset
        !          2300:  * @algo: double pointer to char, will hold pointer to the algorithm name
        !          2301:  *
        !          2302:  * fit_image_hash_get_algo() finds hash algorithm property in a given hash node.
        !          2303:  * If the property is found its data start address is returned to the caller.
        !          2304:  *
        !          2305:  * returns:
        !          2306:  *     0, on success
        !          2307:  *     -1, on failure
        !          2308:  */
        !          2309: int fit_image_hash_get_algo (const void *fit, int noffset, char **algo)
        !          2310: {
        !          2311:        int len;
        !          2312: 
        !          2313:        *algo = (char *)fdt_getprop (fit, noffset, FIT_ALGO_PROP, &len);
        !          2314:        if (*algo == NULL) {
        !          2315:                fit_get_debug (fit, noffset, FIT_ALGO_PROP, len);
        !          2316:                return -1;
        !          2317:        }
        !          2318: 
        !          2319:        return 0;
        !          2320: }
        !          2321: 
        !          2322: /**
        !          2323:  * fit_image_hash_get_value - get hash value and length
        !          2324:  * @fit: pointer to the FIT format image header
        !          2325:  * @noffset: hash node offset
        !          2326:  * @value: double pointer to uint8_t, will hold address of a hash value data
        !          2327:  * @value_len: pointer to an int, will hold hash data length
        !          2328:  *
        !          2329:  * fit_image_hash_get_value() finds hash value property in a given hash node.
        !          2330:  * If the property is found its data start address and size are returned to
        !          2331:  * the caller.
        !          2332:  *
        !          2333:  * returns:
        !          2334:  *     0, on success
        !          2335:  *     -1, on failure
        !          2336:  */
        !          2337: int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value,
        !          2338:                                int *value_len)
        !          2339: {
        !          2340:        int len;
        !          2341: 
        !          2342:        *value = (uint8_t *)fdt_getprop (fit, noffset, FIT_VALUE_PROP, &len);
        !          2343:        if (*value == NULL) {
        !          2344:                fit_get_debug (fit, noffset, FIT_VALUE_PROP, len);
        !          2345:                *value_len = 0;
        !          2346:                return -1;
        !          2347:        }
        !          2348: 
        !          2349:        *value_len = len;
        !          2350:        return 0;
        !          2351: }
        !          2352: 
        !          2353: /**
        !          2354:  * fit_set_timestamp - set node timestamp property
        !          2355:  * @fit: pointer to the FIT format image header
        !          2356:  * @noffset: node offset
        !          2357:  * @timestamp: timestamp value to be set
        !          2358:  *
        !          2359:  * fit_set_timestamp() attempts to set timestamp property in the requested
        !          2360:  * node and returns operation status to the caller.
        !          2361:  *
        !          2362:  * returns:
        !          2363:  *     0, on success
        !          2364:  *     -1, on property read failure
        !          2365:  */
        !          2366: int fit_set_timestamp (void *fit, int noffset, time_t timestamp)
        !          2367: {
        !          2368:        uint32_t t;
        !          2369:        int ret;
        !          2370: 
        !          2371:        t = cpu_to_uimage (timestamp);
        !          2372:        ret = fdt_setprop (fit, noffset, FIT_TIMESTAMP_PROP, &t,
        !          2373:                                sizeof (uint32_t));
        !          2374:        if (ret) {
        !          2375:                printf ("Can't set '%s' property for '%s' node (%s)\n",
        !          2376:                        FIT_TIMESTAMP_PROP, fit_get_name (fit, noffset, NULL),
        !          2377:                        fdt_strerror (ret));
        !          2378:                return -1;
        !          2379:        }
        !          2380: 
        !          2381:        return 0;
        !          2382: }
        !          2383: 
        !          2384: /**
        !          2385:  * calculate_hash - calculate and return hash for provided input data
        !          2386:  * @data: pointer to the input data
        !          2387:  * @data_len: data length
        !          2388:  * @algo: requested hash algorithm
        !          2389:  * @value: pointer to the char, will hold hash value data (caller must
        !          2390:  * allocate enough free space)
        !          2391:  * value_len: length of the calculated hash
        !          2392:  *
        !          2393:  * calculate_hash() computes input data hash according to the requested algorithm.
        !          2394:  * Resulting hash value is placed in caller provided 'value' buffer, length
        !          2395:  * of the calculated hash is returned via value_len pointer argument.
        !          2396:  *
        !          2397:  * returns:
        !          2398:  *     0, on success
        !          2399:  *    -1, when algo is unsupported
        !          2400:  */
        !          2401: static int calculate_hash (const void *data, int data_len, const char *algo,
        !          2402:                        uint8_t *value, int *value_len)
        !          2403: {
        !          2404:        if (strcmp (algo, "crc32") == 0 ) {
        !          2405:                *((uint32_t *)value) = crc32_wd (0, data, data_len,
        !          2406:                                                        CHUNKSZ_CRC32);
        !          2407:                *((uint32_t *)value) = cpu_to_uimage (*((uint32_t *)value));
        !          2408:                *value_len = 4;
        !          2409:        } else if (strcmp (algo, "sha1") == 0 ) {
        !          2410:                sha1_csum_wd ((unsigned char *) data, data_len,
        !          2411:                                (unsigned char *) value, CHUNKSZ_SHA1);
        !          2412:                *value_len = 20;
        !          2413:        } else if (strcmp (algo, "md5") == 0 ) {
        !          2414:                md5_wd ((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
        !          2415:                *value_len = 16;
        !          2416:        } else {
        !          2417:                debug ("Unsupported hash alogrithm\n");
        !          2418:                return -1;
        !          2419:        }
        !          2420:        return 0;
        !          2421: }
        !          2422: 
        !          2423: #ifdef USE_HOSTCC
        !          2424: /**
        !          2425:  * fit_set_hashes - process FIT component image nodes and calculate hashes
        !          2426:  * @fit: pointer to the FIT format image header
        !          2427:  *
        !          2428:  * fit_set_hashes() adds hash values for all component images in the FIT blob.
        !          2429:  * Hashes are calculated for all component images which have hash subnodes
        !          2430:  * with algorithm property set to one of the supported hash algorithms.
        !          2431:  *
        !          2432:  * returns
        !          2433:  *     0, on success
        !          2434:  *     libfdt error code, on failure
        !          2435:  */
        !          2436: int fit_set_hashes (void *fit)
        !          2437: {
        !          2438:        int images_noffset;
        !          2439:        int noffset;
        !          2440:        int ndepth;
        !          2441:        int ret;
        !          2442: 
        !          2443:        /* Find images parent node offset */
        !          2444:        images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
        !          2445:        if (images_noffset < 0) {
        !          2446:                printf ("Can't find images parent node '%s' (%s)\n",
        !          2447:                        FIT_IMAGES_PATH, fdt_strerror (images_noffset));
        !          2448:                return images_noffset;
        !          2449:        }
        !          2450: 
        !          2451:        /* Process its subnodes, print out component images details */
        !          2452:        for (ndepth = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth);
        !          2453:             (noffset >= 0) && (ndepth > 0);
        !          2454:             noffset = fdt_next_node (fit, noffset, &ndepth)) {
        !          2455:                if (ndepth == 1) {
        !          2456:                        /*
        !          2457:                         * Direct child node of the images parent node,
        !          2458:                         * i.e. component image node.
        !          2459:                         */
        !          2460:                        ret = fit_image_set_hashes (fit, noffset);
        !          2461:                        if (ret)
        !          2462:                                return ret;
        !          2463:                }
        !          2464:        }
        !          2465: 
        !          2466:        return 0;
        !          2467: }
        !          2468: 
        !          2469: /**
        !          2470:  * fit_image_set_hashes - calculate/set hashes for given component image node
        !          2471:  * @fit: pointer to the FIT format image header
        !          2472:  * @image_noffset: requested component image node
        !          2473:  *
        !          2474:  * fit_image_set_hashes() adds hash values for an component image node. All
        !          2475:  * existing hash subnodes are checked, if algorithm property is set to one of
        !          2476:  * the supported hash algorithms, hash value is computed and corresponding
        !          2477:  * hash node property is set, for example:
        !          2478:  *
        !          2479:  * Input component image node structure:
        !          2480:  *
        !          2481:  * o image@1 (at image_noffset)
        !          2482:  *   | - data = [binary data]
        !          2483:  *   o hash@1
        !          2484:  *     |- algo = "sha1"
        !          2485:  *
        !          2486:  * Output component image node structure:
        !          2487:  *
        !          2488:  * o image@1 (at image_noffset)
        !          2489:  *   | - data = [binary data]
        !          2490:  *   o hash@1
        !          2491:  *     |- algo = "sha1"
        !          2492:  *     |- value = sha1(data)
        !          2493:  *
        !          2494:  * returns:
        !          2495:  *     0 on sucess
        !          2496:  *    <0 on failure
        !          2497:  */
        !          2498: int fit_image_set_hashes (void *fit, int image_noffset)
        !          2499: {
        !          2500:        const void *data;
        !          2501:        size_t size;
        !          2502:        char *algo;
        !          2503:        uint8_t value[FIT_MAX_HASH_LEN];
        !          2504:        int value_len;
        !          2505:        int noffset;
        !          2506:        int ndepth;
        !          2507: 
        !          2508:        /* Get image data and data length */
        !          2509:        if (fit_image_get_data (fit, image_noffset, &data, &size)) {
        !          2510:                printf ("Can't get image data/size\n");
        !          2511:                return -1;
        !          2512:        }
        !          2513: 
        !          2514:        /* Process all hash subnodes of the component image node */
        !          2515:        for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
        !          2516:             (noffset >= 0) && (ndepth > 0);
        !          2517:             noffset = fdt_next_node (fit, noffset, &ndepth)) {
        !          2518:                if (ndepth == 1) {
        !          2519:                        /* Direct child node of the component image node */
        !          2520: 
        !          2521:                        /*
        !          2522:                         * Check subnode name, must be equal to "hash".
        !          2523:                         * Multiple hash nodes require unique unit node
        !          2524:                         * names, e.g. hash@1, hash@2, etc.
        !          2525:                         */
        !          2526:                        if (strncmp (fit_get_name(fit, noffset, NULL),
        !          2527:                                                FIT_HASH_NODENAME,
        !          2528:                                                strlen(FIT_HASH_NODENAME)) != 0) {
        !          2529:                                /* Not a hash subnode, skip it */
        !          2530:                                continue;
        !          2531:                        }
        !          2532: 
        !          2533:                        if (fit_image_hash_get_algo (fit, noffset, &algo)) {
        !          2534:                                printf ("Can't get hash algo property for "
        !          2535:                                        "'%s' hash node in '%s' image node\n",
        !          2536:                                        fit_get_name (fit, noffset, NULL),
        !          2537:                                        fit_get_name (fit, image_noffset, NULL));
        !          2538:                                return -1;
        !          2539:                        }
        !          2540: 
        !          2541:                        if (calculate_hash (data, size, algo, value, &value_len)) {
        !          2542:                                printf ("Unsupported hash algorithm (%s) for "
        !          2543:                                        "'%s' hash node in '%s' image node\n",
        !          2544:                                        algo, fit_get_name (fit, noffset, NULL),
        !          2545:                                        fit_get_name (fit, image_noffset, NULL));
        !          2546:                                return -1;
        !          2547:                        }
        !          2548: 
        !          2549:                        if (fit_image_hash_set_value (fit, noffset, value,
        !          2550:                                                        value_len)) {
        !          2551:                                printf ("Can't set hash value for "
        !          2552:                                        "'%s' hash node in '%s' image node\n",
        !          2553:                                        fit_get_name (fit, noffset, NULL),
        !          2554:                                        fit_get_name (fit, image_noffset, NULL));
        !          2555:                                return -1;
        !          2556:                        }
        !          2557:                }
        !          2558:        }
        !          2559: 
        !          2560:        return 0;
        !          2561: }
        !          2562: 
        !          2563: /**
        !          2564:  * fit_image_hash_set_value - set hash value in requested has node
        !          2565:  * @fit: pointer to the FIT format image header
        !          2566:  * @noffset: hash node offset
        !          2567:  * @value: hash value to be set
        !          2568:  * @value_len: hash value length
        !          2569:  *
        !          2570:  * fit_image_hash_set_value() attempts to set hash value in a node at offset
        !          2571:  * given and returns operation status to the caller.
        !          2572:  *
        !          2573:  * returns
        !          2574:  *     0, on success
        !          2575:  *     -1, on failure
        !          2576:  */
        !          2577: int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value,
        !          2578:                                int value_len)
        !          2579: {
        !          2580:        int ret;
        !          2581: 
        !          2582:        ret = fdt_setprop (fit, noffset, FIT_VALUE_PROP, value, value_len);
        !          2583:        if (ret) {
        !          2584:                printf ("Can't set hash '%s' property for '%s' node (%s)\n",
        !          2585:                        FIT_VALUE_PROP, fit_get_name (fit, noffset, NULL),
        !          2586:                        fdt_strerror (ret));
        !          2587:                return -1;
        !          2588:        }
        !          2589: 
        !          2590:        return 0;
        !          2591: }
        !          2592: #endif /* USE_HOSTCC */
        !          2593: 
        !          2594: /**
        !          2595:  * fit_image_check_hashes - verify data intergity
        !          2596:  * @fit: pointer to the FIT format image header
        !          2597:  * @image_noffset: component image node offset
        !          2598:  *
        !          2599:  * fit_image_check_hashes() goes over component image hash nodes,
        !          2600:  * re-calculates each data hash and compares with the value stored in hash
        !          2601:  * node.
        !          2602:  *
        !          2603:  * returns:
        !          2604:  *     1, if all hashes are valid
        !          2605:  *     0, otherwise (or on error)
        !          2606:  */
        !          2607: int fit_image_check_hashes (const void *fit, int image_noffset)
        !          2608: {
        !          2609:        const void      *data;
        !          2610:        size_t          size;
        !          2611:        char            *algo;
        !          2612:        uint8_t         *fit_value;
        !          2613:        int             fit_value_len;
        !          2614:        uint8_t         value[FIT_MAX_HASH_LEN];
        !          2615:        int             value_len;
        !          2616:        int             noffset;
        !          2617:        int             ndepth;
        !          2618:        char            *err_msg = "";
        !          2619: 
        !          2620:        /* Get image data and data length */
        !          2621:        if (fit_image_get_data (fit, image_noffset, &data, &size)) {
        !          2622:                printf ("Can't get image data/size\n");
        !          2623:                return 0;
        !          2624:        }
        !          2625: 
        !          2626:        /* Process all hash subnodes of the component image node */
        !          2627:        for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
        !          2628:             (noffset >= 0) && (ndepth > 0);
        !          2629:             noffset = fdt_next_node (fit, noffset, &ndepth)) {
        !          2630:                if (ndepth == 1) {
        !          2631:                        /* Direct child node of the component image node */
        !          2632: 
        !          2633:                        /*
        !          2634:                         * Check subnode name, must be equal to "hash".
        !          2635:                         * Multiple hash nodes require unique unit node
        !          2636:                         * names, e.g. hash@1, hash@2, etc.
        !          2637:                         */
        !          2638:                        if (strncmp (fit_get_name(fit, noffset, NULL),
        !          2639:                                        FIT_HASH_NODENAME,
        !          2640:                                        strlen(FIT_HASH_NODENAME)) != 0)
        !          2641:                                continue;
        !          2642: 
        !          2643:                        if (fit_image_hash_get_algo (fit, noffset, &algo)) {
        !          2644:                                err_msg = " error!\nCan't get hash algo "
        !          2645:                                                "property";
        !          2646:                                goto error;
        !          2647:                        }
        !          2648:                        printf ("%s", algo);
        !          2649: 
        !          2650:                        if (fit_image_hash_get_value (fit, noffset, &fit_value,
        !          2651:                                                        &fit_value_len)) {
        !          2652:                                err_msg = " error!\nCan't get hash value "
        !          2653:                                                "property";
        !          2654:                                goto error;
        !          2655:                        }
        !          2656: 
        !          2657:                        if (calculate_hash (data, size, algo, value, &value_len)) {
        !          2658:                                err_msg = " error!\nUnsupported hash algorithm";
        !          2659:                                goto error;
        !          2660:                        }
        !          2661: 
        !          2662:                        if (value_len != fit_value_len) {
        !          2663:                                err_msg = " error !\nBad hash value len";
        !          2664:                                goto error;
        !          2665:                        } else if (memcmp (value, fit_value, value_len) != 0) {
        !          2666:                                err_msg = " error!\nBad hash value";
        !          2667:                                goto error;
        !          2668:                        }
        !          2669:                        printf ("+ ");
        !          2670:                }
        !          2671:        }
        !          2672: 
        !          2673:        return 1;
        !          2674: 
        !          2675: error:
        !          2676:        printf ("%s for '%s' hash node in '%s' image node\n",
        !          2677:                        err_msg, fit_get_name (fit, noffset, NULL),
        !          2678:                        fit_get_name (fit, image_noffset, NULL));
        !          2679:        return 0;
        !          2680: }
        !          2681: 
        !          2682: /**
        !          2683:  * fit_all_image_check_hashes - verify data intergity for all images
        !          2684:  * @fit: pointer to the FIT format image header
        !          2685:  *
        !          2686:  * fit_all_image_check_hashes() goes over all images in the FIT and
        !          2687:  * for every images checks if all it's hashes are valid.
        !          2688:  *
        !          2689:  * returns:
        !          2690:  *     1, if all hashes of all images are valid
        !          2691:  *     0, otherwise (or on error)
        !          2692:  */
        !          2693: int fit_all_image_check_hashes (const void *fit)
        !          2694: {
        !          2695:        int images_noffset;
        !          2696:        int noffset;
        !          2697:        int ndepth;
        !          2698:        int count;
        !          2699: 
        !          2700:        /* Find images parent node offset */
        !          2701:        images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
        !          2702:        if (images_noffset < 0) {
        !          2703:                printf ("Can't find images parent node '%s' (%s)\n",
        !          2704:                        FIT_IMAGES_PATH, fdt_strerror (images_noffset));
        !          2705:                return 0;
        !          2706:        }
        !          2707: 
        !          2708:        /* Process all image subnodes, check hashes for each */
        !          2709:        printf ("## Checking hash(es) for FIT Image at %08lx ...\n",
        !          2710:                (ulong)fit);
        !          2711:        for (ndepth = 0, count = 0,
        !          2712:                noffset = fdt_next_node (fit, images_noffset, &ndepth);
        !          2713:                (noffset >= 0) && (ndepth > 0);
        !          2714:                noffset = fdt_next_node (fit, noffset, &ndepth)) {
        !          2715:                if (ndepth == 1) {
        !          2716:                        /*
        !          2717:                         * Direct child node of the images parent node,
        !          2718:                         * i.e. component image node.
        !          2719:                         */
        !          2720:                        printf ("   Hash(es) for Image %u (%s): ", count++,
        !          2721:                                        fit_get_name (fit, noffset, NULL));
        !          2722: 
        !          2723:                        if (!fit_image_check_hashes (fit, noffset))
        !          2724:                                return 0;
        !          2725:                        printf ("\n");
        !          2726:                }
        !          2727:        }
        !          2728:        return 1;
        !          2729: }
        !          2730: 
        !          2731: /**
        !          2732:  * fit_image_check_os - check whether image node is of a given os type
        !          2733:  * @fit: pointer to the FIT format image header
        !          2734:  * @noffset: component image node offset
        !          2735:  * @os: requested image os
        !          2736:  *
        !          2737:  * fit_image_check_os() reads image os property and compares its numeric
        !          2738:  * id with the requested os. Comparison result is returned to the caller.
        !          2739:  *
        !          2740:  * returns:
        !          2741:  *     1 if image is of given os type
        !          2742:  *     0 otherwise (or on error)
        !          2743:  */
        !          2744: int fit_image_check_os (const void *fit, int noffset, uint8_t os)
        !          2745: {
        !          2746:        uint8_t image_os;
        !          2747: 
        !          2748:        if (fit_image_get_os (fit, noffset, &image_os))
        !          2749:                return 0;
        !          2750:        return (os == image_os);
        !          2751: }
        !          2752: 
        !          2753: /**
        !          2754:  * fit_image_check_arch - check whether image node is of a given arch
        !          2755:  * @fit: pointer to the FIT format image header
        !          2756:  * @noffset: component image node offset
        !          2757:  * @arch: requested imagearch
        !          2758:  *
        !          2759:  * fit_image_check_arch() reads image arch property and compares its numeric
        !          2760:  * id with the requested arch. Comparison result is returned to the caller.
        !          2761:  *
        !          2762:  * returns:
        !          2763:  *     1 if image is of given arch
        !          2764:  *     0 otherwise (or on error)
        !          2765:  */
        !          2766: int fit_image_check_arch (const void *fit, int noffset, uint8_t arch)
        !          2767: {
        !          2768:        uint8_t image_arch;
        !          2769: 
        !          2770:        if (fit_image_get_arch (fit, noffset, &image_arch))
        !          2771:                return 0;
        !          2772:        return (arch == image_arch);
        !          2773: }
        !          2774: 
        !          2775: /**
        !          2776:  * fit_image_check_type - check whether image node is of a given type
        !          2777:  * @fit: pointer to the FIT format image header
        !          2778:  * @noffset: component image node offset
        !          2779:  * @type: requested image type
        !          2780:  *
        !          2781:  * fit_image_check_type() reads image type property and compares its numeric
        !          2782:  * id with the requested type. Comparison result is returned to the caller.
        !          2783:  *
        !          2784:  * returns:
        !          2785:  *     1 if image is of given type
        !          2786:  *     0 otherwise (or on error)
        !          2787:  */
        !          2788: int fit_image_check_type (const void *fit, int noffset, uint8_t type)
        !          2789: {
        !          2790:        uint8_t image_type;
        !          2791: 
        !          2792:        if (fit_image_get_type (fit, noffset, &image_type))
        !          2793:                return 0;
        !          2794:        return (type == image_type);
        !          2795: }
        !          2796: 
        !          2797: /**
        !          2798:  * fit_image_check_comp - check whether image node uses given compression
        !          2799:  * @fit: pointer to the FIT format image header
        !          2800:  * @noffset: component image node offset
        !          2801:  * @comp: requested image compression type
        !          2802:  *
        !          2803:  * fit_image_check_comp() reads image compression property and compares its
        !          2804:  * numeric id with the requested compression type. Comparison result is
        !          2805:  * returned to the caller.
        !          2806:  *
        !          2807:  * returns:
        !          2808:  *     1 if image uses requested compression
        !          2809:  *     0 otherwise (or on error)
        !          2810:  */
        !          2811: int fit_image_check_comp (const void *fit, int noffset, uint8_t comp)
        !          2812: {
        !          2813:        uint8_t image_comp;
        !          2814: 
        !          2815:        if (fit_image_get_comp (fit, noffset, &image_comp))
        !          2816:                return 0;
        !          2817:        return (comp == image_comp);
        !          2818: }
        !          2819: 
        !          2820: /**
        !          2821:  * fit_check_format - sanity check FIT image format
        !          2822:  * @fit: pointer to the FIT format image header
        !          2823:  *
        !          2824:  * fit_check_format() runs a basic sanity FIT image verification.
        !          2825:  * Routine checks for mandatory properties, nodes, etc.
        !          2826:  *
        !          2827:  * returns:
        !          2828:  *     1, on success
        !          2829:  *     0, on failure
        !          2830:  */
        !          2831: int fit_check_format (const void *fit)
        !          2832: {
        !          2833:        /* mandatory / node 'description' property */
        !          2834:        if (fdt_getprop (fit, 0, FIT_DESC_PROP, NULL) == NULL) {
        !          2835:                debug ("Wrong FIT format: no description\n");
        !          2836:                return 0;
        !          2837:        }
        !          2838: 
        !          2839: #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
        !          2840:        /* mandatory / node 'timestamp' property */
        !          2841:        if (fdt_getprop (fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) {
        !          2842:                debug ("Wrong FIT format: no timestamp\n");
        !          2843:                return 0;
        !          2844:        }
        !          2845: #endif
        !          2846: 
        !          2847:        /* mandatory subimages parent '/images' node */
        !          2848:        if (fdt_path_offset (fit, FIT_IMAGES_PATH) < 0) {
        !          2849:                debug ("Wrong FIT format: no images parent node\n");
        !          2850:                return 0;
        !          2851:        }
        !          2852: 
        !          2853:        return 1;
        !          2854: }
        !          2855: 
        !          2856: /**
        !          2857:  * fit_conf_get_node - get node offset for configuration of a given unit name
        !          2858:  * @fit: pointer to the FIT format image header
        !          2859:  * @conf_uname: configuration node unit name
        !          2860:  *
        !          2861:  * fit_conf_get_node() finds a configuration (withing the '/configurations'
        !          2862:  * parant node) of a provided unit name. If configuration is found its node offset
        !          2863:  * is returned to the caller.
        !          2864:  *
        !          2865:  * When NULL is provided in second argument fit_conf_get_node() will search
        !          2866:  * for a default configuration node instead. Default configuration node unit name
        !          2867:  * is retrived from FIT_DEFAULT_PROP property of the '/configurations' node.
        !          2868:  *
        !          2869:  * returns:
        !          2870:  *     configuration node offset when found (>=0)
        !          2871:  *     negative number on failure (FDT_ERR_* code)
        !          2872:  */
        !          2873: int fit_conf_get_node (const void *fit, const char *conf_uname)
        !          2874: {
        !          2875:        int noffset, confs_noffset;
        !          2876:        int len;
        !          2877: 
        !          2878:        confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH);
        !          2879:        if (confs_noffset < 0) {
        !          2880:                debug ("Can't find configurations parent node '%s' (%s)\n",
        !          2881:                        FIT_CONFS_PATH, fdt_strerror (confs_noffset));
        !          2882:                return confs_noffset;
        !          2883:        }
        !          2884: 
        !          2885:        if (conf_uname == NULL) {
        !          2886:                /* get configuration unit name from the default property */
        !          2887:                debug ("No configuration specified, trying default...\n");
        !          2888:                conf_uname = (char *)fdt_getprop (fit, confs_noffset, FIT_DEFAULT_PROP, &len);
        !          2889:                if (conf_uname == NULL) {
        !          2890:                        fit_get_debug (fit, confs_noffset, FIT_DEFAULT_PROP, len);
        !          2891:                        return len;
        !          2892:                }
        !          2893:                debug ("Found default configuration: '%s'\n", conf_uname);
        !          2894:        }
        !          2895: 
        !          2896:        noffset = fdt_subnode_offset (fit, confs_noffset, conf_uname);
        !          2897:        if (noffset < 0) {
        !          2898:                debug ("Can't get node offset for configuration unit name: '%s' (%s)\n",
        !          2899:                        conf_uname, fdt_strerror (noffset));
        !          2900:        }
        !          2901: 
        !          2902:        return noffset;
        !          2903: }
        !          2904: 
        !          2905: static int __fit_conf_get_prop_node (const void *fit, int noffset,
        !          2906:                const char *prop_name)
        !          2907: {
        !          2908:        char *uname;
        !          2909:        int len;
        !          2910: 
        !          2911:        /* get kernel image unit name from configuration kernel property */
        !          2912:        uname = (char *)fdt_getprop (fit, noffset, prop_name, &len);
        !          2913:        if (uname == NULL)
        !          2914:                return len;
        !          2915: 
        !          2916:        return fit_image_get_node (fit, uname);
        !          2917: }
        !          2918: 
        !          2919: /**
        !          2920:  * fit_conf_get_kernel_node - get kernel image node offset that corresponds to
        !          2921:  * a given configuration
        !          2922:  * @fit: pointer to the FIT format image header
        !          2923:  * @noffset: configuration node offset
        !          2924:  *
        !          2925:  * fit_conf_get_kernel_node() retrives kernel image node unit name from
        !          2926:  * configuration FIT_KERNEL_PROP property and translates it to the node
        !          2927:  * offset.
        !          2928:  *
        !          2929:  * returns:
        !          2930:  *     image node offset when found (>=0)
        !          2931:  *     negative number on failure (FDT_ERR_* code)
        !          2932:  */
        !          2933: int fit_conf_get_kernel_node (const void *fit, int noffset)
        !          2934: {
        !          2935:        return __fit_conf_get_prop_node (fit, noffset, FIT_KERNEL_PROP);
        !          2936: }
        !          2937: 
        !          2938: /**
        !          2939:  * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to
        !          2940:  * a given configuration
        !          2941:  * @fit: pointer to the FIT format image header
        !          2942:  * @noffset: configuration node offset
        !          2943:  *
        !          2944:  * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from
        !          2945:  * configuration FIT_KERNEL_PROP property and translates it to the node
        !          2946:  * offset.
        !          2947:  *
        !          2948:  * returns:
        !          2949:  *     image node offset when found (>=0)
        !          2950:  *     negative number on failure (FDT_ERR_* code)
        !          2951:  */
        !          2952: int fit_conf_get_ramdisk_node (const void *fit, int noffset)
        !          2953: {
        !          2954:        return __fit_conf_get_prop_node (fit, noffset, FIT_RAMDISK_PROP);
        !          2955: }
        !          2956: 
        !          2957: /**
        !          2958:  * fit_conf_get_fdt_node - get fdt image node offset that corresponds to
        !          2959:  * a given configuration
        !          2960:  * @fit: pointer to the FIT format image header
        !          2961:  * @noffset: configuration node offset
        !          2962:  *
        !          2963:  * fit_conf_get_fdt_node() retrives fdt image node unit name from
        !          2964:  * configuration FIT_KERNEL_PROP property and translates it to the node
        !          2965:  * offset.
        !          2966:  *
        !          2967:  * returns:
        !          2968:  *     image node offset when found (>=0)
        !          2969:  *     negative number on failure (FDT_ERR_* code)
        !          2970:  */
        !          2971: int fit_conf_get_fdt_node (const void *fit, int noffset)
        !          2972: {
        !          2973:        return __fit_conf_get_prop_node (fit, noffset, FIT_FDT_PROP);
        !          2974: }
        !          2975: 
        !          2976: /**
        !          2977:  * fit_conf_print - prints out the FIT configuration details
        !          2978:  * @fit: pointer to the FIT format image header
        !          2979:  * @noffset: offset of the configuration node
        !          2980:  * @p: pointer to prefix string
        !          2981:  *
        !          2982:  * fit_conf_print() lists all mandatory properies for the processed
        !          2983:  * configuration node.
        !          2984:  *
        !          2985:  * returns:
        !          2986:  *     no returned results
        !          2987:  */
        !          2988: void fit_conf_print (const void *fit, int noffset, const char *p)
        !          2989: {
        !          2990:        char *desc;
        !          2991:        char *uname;
        !          2992:        int ret;
        !          2993: 
        !          2994:        /* Mandatory properties */
        !          2995:        ret = fit_get_desc (fit, noffset, &desc);
        !          2996:        printf ("%s  Description:  ", p);
        !          2997:        if (ret)
        !          2998:                printf ("unavailable\n");
        !          2999:        else
        !          3000:                printf ("%s\n", desc);
        !          3001: 
        !          3002:        uname = (char *)fdt_getprop (fit, noffset, FIT_KERNEL_PROP, NULL);
        !          3003:        printf ("%s  Kernel:       ", p);
        !          3004:        if (uname == NULL)
        !          3005:                printf ("unavailable\n");
        !          3006:        else
        !          3007:                printf ("%s\n", uname);
        !          3008: 
        !          3009:        /* Optional properties */
        !          3010:        uname = (char *)fdt_getprop (fit, noffset, FIT_RAMDISK_PROP, NULL);
        !          3011:        if (uname)
        !          3012:                printf ("%s  Init Ramdisk: %s\n", p, uname);
        !          3013: 
        !          3014:        uname = (char *)fdt_getprop (fit, noffset, FIT_FDT_PROP, NULL);
        !          3015:        if (uname)
        !          3016:                printf ("%s  FDT:          %s\n", p, uname);
        !          3017: }
        !          3018: 
        !          3019: /**
        !          3020:  * fit_check_ramdisk - verify FIT format ramdisk subimage
        !          3021:  * @fit_hdr: pointer to the FIT ramdisk header
        !          3022:  * @rd_noffset: ramdisk subimage node offset within FIT image
        !          3023:  * @arch: requested ramdisk image architecture type
        !          3024:  * @verify: data CRC verification flag
        !          3025:  *
        !          3026:  * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from
        !          3027:  * specified FIT image.
        !          3028:  *
        !          3029:  * returns:
        !          3030:  *     1, on success
        !          3031:  *     0, on failure
        !          3032:  */
        !          3033: #ifndef USE_HOSTCC
        !          3034: static int fit_check_ramdisk (const void *fit, int rd_noffset, uint8_t arch, int verify)
        !          3035: {
        !          3036:        fit_image_print (fit, rd_noffset, "   ");
        !          3037: 
        !          3038:        if (verify) {
        !          3039:                puts ("   Verifying Hash Integrity ... ");
        !          3040:                if (!fit_image_check_hashes (fit, rd_noffset)) {
        !          3041:                        puts ("Bad Data Hash\n");
        !          3042:                        show_boot_progress (-125);
        !          3043:                        return 0;
        !          3044:                }
        !          3045:                puts ("OK\n");
        !          3046:        }
        !          3047: 
        !          3048:        show_boot_progress (126);
        !          3049:        if (!fit_image_check_os (fit, rd_noffset, IH_OS_LINUX) ||
        !          3050:            !fit_image_check_arch (fit, rd_noffset, arch) ||
        !          3051:            !fit_image_check_type (fit, rd_noffset, IH_TYPE_RAMDISK)) {
        !          3052:                printf ("No Linux %s Ramdisk Image\n",
        !          3053:                                genimg_get_arch_name(arch));
        !          3054:                show_boot_progress (-126);
        !          3055:                return 0;
        !          3056:        }
        !          3057: 
        !          3058:        show_boot_progress (127);
        !          3059:        return 1;
        !          3060: }
        !          3061: #endif /* USE_HOSTCC */
        !          3062: #endif /* CONFIG_FIT */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>