Annotation of elwix/tools/uboot_mkimage/common/image.c, revision 1.1.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>