]> Git Repo - J-u-boot.git/blame - common/image-fit.c
image: Remove remaining #ifdefs in image-fit.c
[J-u-boot.git] / common / image-fit.c
CommitLineData
53fbb7e8
SG
1/*
2 * Copyright (c) 2013, Google Inc.
3 *
4 * (C) Copyright 2008 Semihalf
5 *
6 * (C) Copyright 2000-2006
7 * Wolfgang Denk, DENX Software Engineering, [email protected].
8 *
9 * See file CREDITS for list of people who contributed to this
10 * project.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 * MA 02111-1307 USA
26 */
27
28#ifdef USE_HOSTCC
29#include "mkimage.h"
30#include <image.h>
31#include <time.h>
32#else
33#include <common.h>
34#endif /* !USE_HOSTCC*/
35
36#include <bootstage.h>
37#include <sha1.h>
38#include <u-boot/crc.h>
39#include <u-boot/md5.h>
40
41/*****************************************************************************/
42/* New uImage format routines */
43/*****************************************************************************/
44#ifndef USE_HOSTCC
45static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr,
46 ulong *addr, const char **name)
47{
48 const char *sep;
49
50 *addr = addr_curr;
51 *name = NULL;
52
53 sep = strchr(spec, sepc);
54 if (sep) {
55 if (sep - spec > 0)
56 *addr = simple_strtoul(spec, NULL, 16);
57
58 *name = sep + 1;
59 return 1;
60 }
61
62 return 0;
63}
64
65/**
66 * fit_parse_conf - parse FIT configuration spec
67 * @spec: input string, containing configuration spec
68 * @add_curr: current image address (to be used as a possible default)
69 * @addr: pointer to a ulong variable, will hold FIT image address of a given
70 * configuration
71 * @conf_name double pointer to a char, will hold pointer to a configuration
72 * unit name
73 *
74 * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>,
75 * where <addr> is a FIT image address that contains configuration
76 * with a <conf> unit name.
77 *
78 * Address part is optional, and if omitted default add_curr will
79 * be used instead.
80 *
81 * returns:
82 * 1 if spec is a valid configuration string,
83 * addr and conf_name are set accordingly
84 * 0 otherwise
85 */
86int fit_parse_conf(const char *spec, ulong addr_curr,
87 ulong *addr, const char **conf_name)
88{
89 return fit_parse_spec(spec, '#', addr_curr, addr, conf_name);
90}
91
92/**
93 * fit_parse_subimage - parse FIT subimage spec
94 * @spec: input string, containing subimage spec
95 * @add_curr: current image address (to be used as a possible default)
96 * @addr: pointer to a ulong variable, will hold FIT image address of a given
97 * subimage
98 * @image_name: double pointer to a char, will hold pointer to a subimage name
99 *
100 * fit_parse_subimage() expects subimage spec in the for of
101 * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
102 * subimage with a <subimg> unit name.
103 *
104 * Address part is optional, and if omitted default add_curr will
105 * be used instead.
106 *
107 * returns:
108 * 1 if spec is a valid subimage string,
109 * addr and image_name are set accordingly
110 * 0 otherwise
111 */
112int fit_parse_subimage(const char *spec, ulong addr_curr,
113 ulong *addr, const char **image_name)
114{
115 return fit_parse_spec(spec, ':', addr_curr, addr, image_name);
116}
117#endif /* !USE_HOSTCC */
118
119static void fit_get_debug(const void *fit, int noffset,
120 char *prop_name, int err)
121{
122 debug("Can't get '%s' property from FIT 0x%08lx, node: offset %d, name %s (%s)\n",
123 prop_name, (ulong)fit, noffset, fit_get_name(fit, noffset, NULL),
124 fdt_strerror(err));
125}
126
127/**
128 * fit_print_contents - prints out the contents of the FIT format image
129 * @fit: pointer to the FIT format image header
130 * @p: pointer to prefix string
131 *
132 * fit_print_contents() formats a multi line FIT image contents description.
133 * The routine prints out FIT image properties (root node level) follwed by
134 * the details of each component image.
135 *
136 * returns:
137 * no returned results
138 */
139void fit_print_contents(const void *fit)
140{
141 char *desc;
142 char *uname;
143 int images_noffset;
144 int confs_noffset;
145 int noffset;
146 int ndepth;
147 int count = 0;
148 int ret;
149 const char *p;
150 time_t timestamp;
151
1fe7d938
SG
152 /* Indent string is defined in header image.h */
153 p = IMAGE_INDENT_STRING;
53fbb7e8
SG
154
155 /* Root node properties */
156 ret = fit_get_desc(fit, 0, &desc);
157 printf("%sFIT description: ", p);
158 if (ret)
159 printf("unavailable\n");
160 else
161 printf("%s\n", desc);
162
163 if (IMAGE_ENABLE_TIMESTAMP) {
164 ret = fit_get_timestamp(fit, 0, &timestamp);
165 printf("%sCreated: ", p);
166 if (ret)
167 printf("unavailable\n");
168 else
169 genimg_print_time(timestamp);
170 }
171
172 /* Find images parent node offset */
173 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
174 if (images_noffset < 0) {
175 printf("Can't find images parent node '%s' (%s)\n",
176 FIT_IMAGES_PATH, fdt_strerror(images_noffset));
177 return;
178 }
179
180 /* Process its subnodes, print out component images details */
181 for (ndepth = 0, count = 0,
182 noffset = fdt_next_node(fit, images_noffset, &ndepth);
183 (noffset >= 0) && (ndepth > 0);
184 noffset = fdt_next_node(fit, noffset, &ndepth)) {
185 if (ndepth == 1) {
186 /*
187 * Direct child node of the images parent node,
188 * i.e. component image node.
189 */
190 printf("%s Image %u (%s)\n", p, count++,
191 fit_get_name(fit, noffset, NULL));
192
193 fit_image_print(fit, noffset, p);
194 }
195 }
196
197 /* Find configurations parent node offset */
198 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
199 if (confs_noffset < 0) {
200 debug("Can't get configurations parent node '%s' (%s)\n",
201 FIT_CONFS_PATH, fdt_strerror(confs_noffset));
202 return;
203 }
204
205 /* get default configuration unit name from default property */
206 uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL);
207 if (uname)
208 printf("%s Default Configuration: '%s'\n", p, uname);
209
210 /* Process its subnodes, print out configurations details */
211 for (ndepth = 0, count = 0,
212 noffset = fdt_next_node(fit, confs_noffset, &ndepth);
213 (noffset >= 0) && (ndepth > 0);
214 noffset = fdt_next_node(fit, noffset, &ndepth)) {
215 if (ndepth == 1) {
216 /*
217 * Direct child node of the configurations parent node,
218 * i.e. configuration node.
219 */
220 printf("%s Configuration %u (%s)\n", p, count++,
221 fit_get_name(fit, noffset, NULL));
222
223 fit_conf_print(fit, noffset, p);
224 }
225 }
226}
227
d8b75360
SG
228/**
229 * fit_image_print_data() - prints out the hash node details
230 * @fit: pointer to the FIT format image header
231 * @noffset: offset of the hash node
232 * @p: pointer to prefix string
233 *
234 * fit_image_print_data() lists properies for the processed hash node
235 *
236 * returns:
237 * no returned results
238 */
239static void fit_image_print_data(const void *fit, int noffset, const char *p)
240{
241 char *algo;
242 uint8_t *value;
243 int value_len;
244 int i, ret;
245
246 /*
247 * Check subnode name, must be equal to "hash".
248 * Multiple hash nodes require unique unit node
249 * names, e.g. hash@1, hash@2, etc.
250 */
251 if (strncmp(fit_get_name(fit, noffset, NULL),
252 FIT_HASH_NODENAME,
253 strlen(FIT_HASH_NODENAME)) != 0)
254 return;
255
256 debug("%s Hash node: '%s'\n", p,
257 fit_get_name(fit, noffset, NULL));
258
259 printf("%s Hash algo: ", p);
260 if (fit_image_hash_get_algo(fit, noffset, &algo)) {
261 printf("invalid/unsupported\n");
262 return;
263 }
264 printf("%s\n", algo);
265
266 ret = fit_image_hash_get_value(fit, noffset, &value,
267 &value_len);
268 printf("%s Hash value: ", p);
269 if (ret) {
270 printf("unavailable\n");
271 } else {
272 for (i = 0; i < value_len; i++)
273 printf("%02x", value[i]);
274 printf("\n");
275 }
276
277 debug("%s Hash len: %d\n", p, value_len);
278}
279
280/**
281 * fit_image_print_verification_data() - prints out the hash/signature details
282 * @fit: pointer to the FIT format image header
283 * @noffset: offset of the hash or signature node
284 * @p: pointer to prefix string
285 *
286 * This lists properies for the processed hash node
287 *
288 * returns:
289 * no returned results
290 */
291static void fit_image_print_verification_data(const void *fit, int noffset,
292 const char *p)
293{
294 const char *name;
295
296 /*
297 * Check subnode name, must be equal to "hash" or "signature".
298 * Multiple hash/signature nodes require unique unit node
299 * names, e.g. hash@1, hash@2, signature@1, signature@2, etc.
300 */
301 name = fit_get_name(fit, noffset, NULL);
302 if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME)))
303 fit_image_print_data(fit, noffset, p);
304}
305
53fbb7e8
SG
306/**
307 * fit_image_print - prints out the FIT component image details
308 * @fit: pointer to the FIT format image header
309 * @image_noffset: offset of the component image node
310 * @p: pointer to prefix string
311 *
312 * fit_image_print() lists all mandatory properies for the processed component
313 * image. If present, hash nodes are printed out as well. Load
314 * address for images of type firmware is also printed out. Since the load
315 * address is not mandatory for firmware images, it will be output as
316 * "unavailable" when not present.
317 *
318 * returns:
319 * no returned results
320 */
321void fit_image_print(const void *fit, int image_noffset, const char *p)
322{
323 char *desc;
324 uint8_t type, arch, os, comp;
325 size_t size;
326 ulong load, entry;
327 const void *data;
328 int noffset;
329 int ndepth;
330 int ret;
331
332 /* Mandatory properties */
333 ret = fit_get_desc(fit, image_noffset, &desc);
334 printf("%s Description: ", p);
335 if (ret)
336 printf("unavailable\n");
337 else
338 printf("%s\n", desc);
339
340 fit_image_get_type(fit, image_noffset, &type);
341 printf("%s Type: %s\n", p, genimg_get_type_name(type));
342
343 fit_image_get_comp(fit, image_noffset, &comp);
344 printf("%s Compression: %s\n", p, genimg_get_comp_name(comp));
345
346 ret = fit_image_get_data(fit, image_noffset, &data, &size);
347
348#ifndef USE_HOSTCC
349 printf("%s Data Start: ", p);
350 if (ret)
351 printf("unavailable\n");
352 else
353 printf("0x%08lx\n", (ulong)data);
354#endif
355
356 printf("%s Data Size: ", p);
357 if (ret)
358 printf("unavailable\n");
359 else
360 genimg_print_size(size);
361
362 /* Remaining, type dependent properties */
363 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
364 (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
365 (type == IH_TYPE_FLATDT)) {
366 fit_image_get_arch(fit, image_noffset, &arch);
367 printf("%s Architecture: %s\n", p, genimg_get_arch_name(arch));
368 }
369
370 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK)) {
371 fit_image_get_os(fit, image_noffset, &os);
372 printf("%s OS: %s\n", p, genimg_get_os_name(os));
373 }
374
375 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
376 (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK)) {
377 ret = fit_image_get_load(fit, image_noffset, &load);
378 printf("%s Load Address: ", p);
379 if (ret)
380 printf("unavailable\n");
381 else
382 printf("0x%08lx\n", load);
383 }
384
385 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
386 (type == IH_TYPE_RAMDISK)) {
387 fit_image_get_entry(fit, image_noffset, &entry);
388 printf("%s Entry Point: ", p);
389 if (ret)
390 printf("unavailable\n");
391 else
392 printf("0x%08lx\n", entry);
393 }
394
395 /* Process all hash subnodes of the component image node */
396 for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth);
397 (noffset >= 0) && (ndepth > 0);
398 noffset = fdt_next_node(fit, noffset, &ndepth)) {
399 if (ndepth == 1) {
400 /* Direct child node of the component image node */
d8b75360 401 fit_image_print_verification_data(fit, noffset, p);
53fbb7e8
SG
402 }
403 }
404}
405
53fbb7e8
SG
406/**
407 * fit_get_desc - get node description property
408 * @fit: pointer to the FIT format image header
409 * @noffset: node offset
410 * @desc: double pointer to the char, will hold pointer to the descrption
411 *
412 * fit_get_desc() reads description property from a given node, if
413 * description is found pointer to it is returened in third call argument.
414 *
415 * returns:
416 * 0, on success
417 * -1, on failure
418 */
419int fit_get_desc(const void *fit, int noffset, char **desc)
420{
421 int len;
422
423 *desc = (char *)fdt_getprop(fit, noffset, FIT_DESC_PROP, &len);
424 if (*desc == NULL) {
425 fit_get_debug(fit, noffset, FIT_DESC_PROP, len);
426 return -1;
427 }
428
429 return 0;
430}
431
432/**
433 * fit_get_timestamp - get node timestamp property
434 * @fit: pointer to the FIT format image header
435 * @noffset: node offset
436 * @timestamp: pointer to the time_t, will hold read timestamp
437 *
438 * fit_get_timestamp() reads timestamp poperty from given node, if timestamp
439 * is found and has a correct size its value is retured in third call
440 * argument.
441 *
442 * returns:
443 * 0, on success
444 * -1, on property read failure
445 * -2, on wrong timestamp size
446 */
447int fit_get_timestamp(const void *fit, int noffset, time_t *timestamp)
448{
449 int len;
450 const void *data;
451
452 data = fdt_getprop(fit, noffset, FIT_TIMESTAMP_PROP, &len);
453 if (data == NULL) {
454 fit_get_debug(fit, noffset, FIT_TIMESTAMP_PROP, len);
455 return -1;
456 }
457 if (len != sizeof(uint32_t)) {
458 debug("FIT timestamp with incorrect size of (%u)\n", len);
459 return -2;
460 }
461
462 *timestamp = uimage_to_cpu(*((uint32_t *)data));
463 return 0;
464}
465
466/**
467 * fit_image_get_node - get node offset for component image of a given unit name
468 * @fit: pointer to the FIT format image header
469 * @image_uname: component image node unit name
470 *
471 * fit_image_get_node() finds a component image (withing the '/images'
472 * node) of a provided unit name. If image is found its node offset is
473 * returned to the caller.
474 *
475 * returns:
476 * image node offset when found (>=0)
477 * negative number on failure (FDT_ERR_* code)
478 */
479int fit_image_get_node(const void *fit, const char *image_uname)
480{
481 int noffset, images_noffset;
482
483 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
484 if (images_noffset < 0) {
485 debug("Can't find images parent node '%s' (%s)\n",
486 FIT_IMAGES_PATH, fdt_strerror(images_noffset));
487 return images_noffset;
488 }
489
490 noffset = fdt_subnode_offset(fit, images_noffset, image_uname);
491 if (noffset < 0) {
492 debug("Can't get node offset for image unit name: '%s' (%s)\n",
493 image_uname, fdt_strerror(noffset));
494 }
495
496 return noffset;
497}
498
499/**
500 * fit_image_get_os - get os id for a given component image node
501 * @fit: pointer to the FIT format image header
502 * @noffset: component image node offset
503 * @os: pointer to the uint8_t, will hold os numeric id
504 *
505 * fit_image_get_os() finds os property in a given component image node.
506 * If the property is found, its (string) value is translated to the numeric
507 * id which is returned to the caller.
508 *
509 * returns:
510 * 0, on success
511 * -1, on failure
512 */
513int fit_image_get_os(const void *fit, int noffset, uint8_t *os)
514{
515 int len;
516 const void *data;
517
518 /* Get OS name from property data */
519 data = fdt_getprop(fit, noffset, FIT_OS_PROP, &len);
520 if (data == NULL) {
521 fit_get_debug(fit, noffset, FIT_OS_PROP, len);
522 *os = -1;
523 return -1;
524 }
525
526 /* Translate OS name to id */
527 *os = genimg_get_os_id(data);
528 return 0;
529}
530
531/**
532 * fit_image_get_arch - get arch id for a given component image node
533 * @fit: pointer to the FIT format image header
534 * @noffset: component image node offset
535 * @arch: pointer to the uint8_t, will hold arch numeric id
536 *
537 * fit_image_get_arch() finds arch property in a given component image node.
538 * If the property is found, its (string) value is translated to the numeric
539 * id which is returned to the caller.
540 *
541 * returns:
542 * 0, on success
543 * -1, on failure
544 */
545int fit_image_get_arch(const void *fit, int noffset, uint8_t *arch)
546{
547 int len;
548 const void *data;
549
550 /* Get architecture name from property data */
551 data = fdt_getprop(fit, noffset, FIT_ARCH_PROP, &len);
552 if (data == NULL) {
553 fit_get_debug(fit, noffset, FIT_ARCH_PROP, len);
554 *arch = -1;
555 return -1;
556 }
557
558 /* Translate architecture name to id */
559 *arch = genimg_get_arch_id(data);
560 return 0;
561}
562
563/**
564 * fit_image_get_type - get type id for a given component image node
565 * @fit: pointer to the FIT format image header
566 * @noffset: component image node offset
567 * @type: pointer to the uint8_t, will hold type numeric id
568 *
569 * fit_image_get_type() finds type property in a given component image node.
570 * If the property is found, its (string) value is translated to the numeric
571 * id which is returned to the caller.
572 *
573 * returns:
574 * 0, on success
575 * -1, on failure
576 */
577int fit_image_get_type(const void *fit, int noffset, uint8_t *type)
578{
579 int len;
580 const void *data;
581
582 /* Get image type name from property data */
583 data = fdt_getprop(fit, noffset, FIT_TYPE_PROP, &len);
584 if (data == NULL) {
585 fit_get_debug(fit, noffset, FIT_TYPE_PROP, len);
586 *type = -1;
587 return -1;
588 }
589
590 /* Translate image type name to id */
591 *type = genimg_get_type_id(data);
592 return 0;
593}
594
595/**
596 * fit_image_get_comp - get comp id for a given component image node
597 * @fit: pointer to the FIT format image header
598 * @noffset: component image node offset
599 * @comp: pointer to the uint8_t, will hold comp numeric id
600 *
601 * fit_image_get_comp() finds comp property in a given component image node.
602 * If the property is found, its (string) value is translated to the numeric
603 * id which is returned to the caller.
604 *
605 * returns:
606 * 0, on success
607 * -1, on failure
608 */
609int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp)
610{
611 int len;
612 const void *data;
613
614 /* Get compression name from property data */
615 data = fdt_getprop(fit, noffset, FIT_COMP_PROP, &len);
616 if (data == NULL) {
617 fit_get_debug(fit, noffset, FIT_COMP_PROP, len);
618 *comp = -1;
619 return -1;
620 }
621
622 /* Translate compression name to id */
623 *comp = genimg_get_comp_id(data);
624 return 0;
625}
626
627/**
628 * fit_image_get_load() - get load addr property for given component image node
629 * @fit: pointer to the FIT format image header
630 * @noffset: component image node offset
631 * @load: pointer to the uint32_t, will hold load address
632 *
633 * fit_image_get_load() finds load address property in a given component
634 * image node. If the property is found, its value is returned to the caller.
635 *
636 * returns:
637 * 0, on success
638 * -1, on failure
639 */
640int fit_image_get_load(const void *fit, int noffset, ulong *load)
641{
642 int len;
643 const uint32_t *data;
644
645 data = fdt_getprop(fit, noffset, FIT_LOAD_PROP, &len);
646 if (data == NULL) {
647 fit_get_debug(fit, noffset, FIT_LOAD_PROP, len);
648 return -1;
649 }
650
651 *load = uimage_to_cpu(*data);
652 return 0;
653}
654
655/**
656 * fit_image_get_entry() - get entry point address property
657 * @fit: pointer to the FIT format image header
658 * @noffset: component image node offset
659 * @entry: pointer to the uint32_t, will hold entry point address
660 *
661 * This gets the entry point address property for a given component image
662 * node.
663 *
664 * fit_image_get_entry() finds entry point address property in a given
665 * component image node. If the property is found, its value is returned
666 * to the caller.
667 *
668 * returns:
669 * 0, on success
670 * -1, on failure
671 */
672int fit_image_get_entry(const void *fit, int noffset, ulong *entry)
673{
674 int len;
675 const uint32_t *data;
676
677 data = fdt_getprop(fit, noffset, FIT_ENTRY_PROP, &len);
678 if (data == NULL) {
679 fit_get_debug(fit, noffset, FIT_ENTRY_PROP, len);
680 return -1;
681 }
682
683 *entry = uimage_to_cpu(*data);
684 return 0;
685}
686
687/**
688 * fit_image_get_data - get data property and its size for a given component image node
689 * @fit: pointer to the FIT format image header
690 * @noffset: component image node offset
691 * @data: double pointer to void, will hold data property's data address
692 * @size: pointer to size_t, will hold data property's data size
693 *
694 * fit_image_get_data() finds data property in a given component image node.
695 * If the property is found its data start address and size are returned to
696 * the caller.
697 *
698 * returns:
699 * 0, on success
700 * -1, on failure
701 */
702int fit_image_get_data(const void *fit, int noffset,
703 const void **data, size_t *size)
704{
705 int len;
706
707 *data = fdt_getprop(fit, noffset, FIT_DATA_PROP, &len);
708 if (*data == NULL) {
709 fit_get_debug(fit, noffset, FIT_DATA_PROP, len);
710 *size = 0;
711 return -1;
712 }
713
714 *size = len;
715 return 0;
716}
717
718/**
719 * fit_image_hash_get_algo - get hash algorithm name
720 * @fit: pointer to the FIT format image header
721 * @noffset: hash node offset
722 * @algo: double pointer to char, will hold pointer to the algorithm name
723 *
724 * fit_image_hash_get_algo() finds hash algorithm property in a given hash node.
725 * If the property is found its data start address is returned to the caller.
726 *
727 * returns:
728 * 0, on success
729 * -1, on failure
730 */
731int fit_image_hash_get_algo(const void *fit, int noffset, char **algo)
732{
733 int len;
734
735 *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
736 if (*algo == NULL) {
737 fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
738 return -1;
739 }
740
741 return 0;
742}
743
744/**
745 * fit_image_hash_get_value - get hash value and length
746 * @fit: pointer to the FIT format image header
747 * @noffset: hash node offset
748 * @value: double pointer to uint8_t, will hold address of a hash value data
749 * @value_len: pointer to an int, will hold hash data length
750 *
751 * fit_image_hash_get_value() finds hash value property in a given hash node.
752 * If the property is found its data start address and size are returned to
753 * the caller.
754 *
755 * returns:
756 * 0, on success
757 * -1, on failure
758 */
759int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value,
760 int *value_len)
761{
762 int len;
763
764 *value = (uint8_t *)fdt_getprop(fit, noffset, FIT_VALUE_PROP, &len);
765 if (*value == NULL) {
766 fit_get_debug(fit, noffset, FIT_VALUE_PROP, len);
767 *value_len = 0;
768 return -1;
769 }
770
771 *value_len = len;
772 return 0;
773}
774
53fbb7e8
SG
775/**
776 * fit_image_hash_get_ignore - get hash ignore flag
777 * @fit: pointer to the FIT format image header
778 * @noffset: hash node offset
779 * @ignore: pointer to an int, will hold hash ignore flag
780 *
781 * fit_image_hash_get_ignore() finds hash ignore property in a given hash node.
782 * If the property is found and non-zero, the hash algorithm is not verified by
783 * u-boot automatically.
784 *
785 * returns:
786 * 0, on ignore not found
787 * value, on ignore found
788 */
ab9efc66 789static int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore)
53fbb7e8
SG
790{
791 int len;
792 int *value;
793
794 value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len);
795 if (value == NULL || len != sizeof(int))
796 *ignore = 0;
797 else
798 *ignore = *value;
799
800 return 0;
801}
53fbb7e8
SG
802
803/**
804 * fit_set_timestamp - set node timestamp property
805 * @fit: pointer to the FIT format image header
806 * @noffset: node offset
807 * @timestamp: timestamp value to be set
808 *
809 * fit_set_timestamp() attempts to set timestamp property in the requested
810 * node and returns operation status to the caller.
811 *
812 * returns:
813 * 0, on success
814 * -1, on property read failure
815 */
816int fit_set_timestamp(void *fit, int noffset, time_t timestamp)
817{
818 uint32_t t;
819 int ret;
820
821 t = cpu_to_uimage(timestamp);
822 ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t,
823 sizeof(uint32_t));
824 if (ret) {
825 printf("Can't set '%s' property for '%s' node (%s)\n",
826 FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL),
827 fdt_strerror(ret));
828 return -1;
829 }
830
831 return 0;
832}
833
834/**
835 * calculate_hash - calculate and return hash for provided input data
836 * @data: pointer to the input data
837 * @data_len: data length
838 * @algo: requested hash algorithm
839 * @value: pointer to the char, will hold hash value data (caller must
840 * allocate enough free space)
841 * value_len: length of the calculated hash
842 *
843 * calculate_hash() computes input data hash according to the requested
844 * algorithm.
845 * Resulting hash value is placed in caller provided 'value' buffer, length
846 * of the calculated hash is returned via value_len pointer argument.
847 *
848 * returns:
849 * 0, on success
850 * -1, when algo is unsupported
851 */
604f23dd 852int calculate_hash(const void *data, int data_len, const char *algo,
53fbb7e8
SG
853 uint8_t *value, int *value_len)
854{
855 if (strcmp(algo, "crc32") == 0) {
856 *((uint32_t *)value) = crc32_wd(0, data, data_len,
857 CHUNKSZ_CRC32);
858 *((uint32_t *)value) = cpu_to_uimage(*((uint32_t *)value));
859 *value_len = 4;
860 } else if (strcmp(algo, "sha1") == 0) {
861 sha1_csum_wd((unsigned char *)data, data_len,
862 (unsigned char *)value, CHUNKSZ_SHA1);
863 *value_len = 20;
864 } else if (strcmp(algo, "md5") == 0) {
865 md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
866 *value_len = 16;
867 } else {
868 debug("Unsupported hash alogrithm\n");
869 return -1;
870 }
871 return 0;
872}
873
ab9efc66
SG
874static int fit_image_check_hash(const void *fit, int noffset, const void *data,
875 size_t size, char **err_msgp)
876{
877 uint8_t value[FIT_MAX_HASH_LEN];
878 int value_len;
879 char *algo;
880 uint8_t *fit_value;
881 int fit_value_len;
882 int ignore;
883
884 *err_msgp = NULL;
885
886 if (fit_image_hash_get_algo(fit, noffset, &algo)) {
e754da2a 887 *err_msgp = "Can't get hash algo property";
ab9efc66
SG
888 return -1;
889 }
890 printf("%s", algo);
891
892 if (IMAGE_ENABLE_IGNORE) {
893 fit_image_hash_get_ignore(fit, noffset, &ignore);
894 if (ignore) {
895 printf("-skipped ");
896 return 0;
897 }
898 }
899
900 if (fit_image_hash_get_value(fit, noffset, &fit_value,
901 &fit_value_len)) {
e754da2a 902 *err_msgp = "Can't get hash value property";
ab9efc66
SG
903 return -1;
904 }
905
906 if (calculate_hash(data, size, algo, value, &value_len)) {
e754da2a 907 *err_msgp = "Unsupported hash algorithm";
ab9efc66
SG
908 return -1;
909 }
910
911 if (value_len != fit_value_len) {
e754da2a 912 *err_msgp = "Bad hash value len";
ab9efc66
SG
913 return -1;
914 } else if (memcmp(value, fit_value, value_len) != 0) {
e754da2a 915 *err_msgp = "Bad hash value";
ab9efc66
SG
916 return -1;
917 }
918
919 return 0;
920}
921
53fbb7e8 922/**
b8da8366 923 * fit_image_verify - verify data intergity
53fbb7e8
SG
924 * @fit: pointer to the FIT format image header
925 * @image_noffset: component image node offset
926 *
b8da8366 927 * fit_image_verify() goes over component image hash nodes,
53fbb7e8
SG
928 * re-calculates each data hash and compares with the value stored in hash
929 * node.
930 *
931 * returns:
932 * 1, if all hashes are valid
933 * 0, otherwise (or on error)
934 */
b8da8366 935int fit_image_verify(const void *fit, int image_noffset)
53fbb7e8
SG
936{
937 const void *data;
938 size_t size;
53fbb7e8 939 int noffset;
53fbb7e8
SG
940 char *err_msg = "";
941
942 /* Get image data and data length */
943 if (fit_image_get_data(fit, image_noffset, &data, &size)) {
e754da2a 944 err_msg = "Can't get image data/size";
53fbb7e8
SG
945 return 0;
946 }
947
948 /* Process all hash subnodes of the component image node */
ab9efc66
SG
949 for (noffset = fdt_first_subnode(fit, image_noffset);
950 noffset >= 0;
951 noffset = fdt_next_subnode(fit, noffset)) {
952 const char *name = fit_get_name(fit, noffset, NULL);
953
954 /*
955 * Check subnode name, must be equal to "hash".
956 * Multiple hash nodes require unique unit node
957 * names, e.g. hash@1, hash@2, etc.
958 */
959 if (!strncmp(name, FIT_HASH_NODENAME,
960 strlen(FIT_HASH_NODENAME))) {
961 if (fit_image_check_hash(fit, noffset, data, size,
962 &err_msg))
53fbb7e8 963 goto error;
ab9efc66 964 puts("+ ");
53fbb7e8
SG
965 }
966 }
967
968 if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
e754da2a 969 err_msg = "Corrupted or truncated tree";
53fbb7e8
SG
970 goto error;
971 }
972
973 return 1;
974
975error:
e754da2a 976 printf(" error!\n%s for '%s' hash node in '%s' image node\n",
53fbb7e8
SG
977 err_msg, fit_get_name(fit, noffset, NULL),
978 fit_get_name(fit, image_noffset, NULL));
979 return 0;
980}
981
982/**
b8da8366 983 * fit_all_image_verify - verify data intergity for all images
53fbb7e8
SG
984 * @fit: pointer to the FIT format image header
985 *
b8da8366 986 * fit_all_image_verify() goes over all images in the FIT and
53fbb7e8
SG
987 * for every images checks if all it's hashes are valid.
988 *
989 * returns:
990 * 1, if all hashes of all images are valid
991 * 0, otherwise (or on error)
992 */
b8da8366 993int fit_all_image_verify(const void *fit)
53fbb7e8
SG
994{
995 int images_noffset;
996 int noffset;
997 int ndepth;
998 int count;
999
1000 /* Find images parent node offset */
1001 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1002 if (images_noffset < 0) {
1003 printf("Can't find images parent node '%s' (%s)\n",
1004 FIT_IMAGES_PATH, fdt_strerror(images_noffset));
1005 return 0;
1006 }
1007
1008 /* Process all image subnodes, check hashes for each */
1009 printf("## Checking hash(es) for FIT Image at %08lx ...\n",
1010 (ulong)fit);
1011 for (ndepth = 0, count = 0,
1012 noffset = fdt_next_node(fit, images_noffset, &ndepth);
1013 (noffset >= 0) && (ndepth > 0);
1014 noffset = fdt_next_node(fit, noffset, &ndepth)) {
1015 if (ndepth == 1) {
1016 /*
1017 * Direct child node of the images parent node,
1018 * i.e. component image node.
1019 */
1020 printf(" Hash(es) for Image %u (%s): ", count++,
1021 fit_get_name(fit, noffset, NULL));
1022
b8da8366 1023 if (!fit_image_verify(fit, noffset))
53fbb7e8
SG
1024 return 0;
1025 printf("\n");
1026 }
1027 }
1028 return 1;
1029}
1030
1031/**
1032 * fit_image_check_os - check whether image node is of a given os type
1033 * @fit: pointer to the FIT format image header
1034 * @noffset: component image node offset
1035 * @os: requested image os
1036 *
1037 * fit_image_check_os() reads image os property and compares its numeric
1038 * id with the requested os. Comparison result is returned to the caller.
1039 *
1040 * returns:
1041 * 1 if image is of given os type
1042 * 0 otherwise (or on error)
1043 */
1044int fit_image_check_os(const void *fit, int noffset, uint8_t os)
1045{
1046 uint8_t image_os;
1047
1048 if (fit_image_get_os(fit, noffset, &image_os))
1049 return 0;
1050 return (os == image_os);
1051}
1052
1053/**
1054 * fit_image_check_arch - check whether image node is of a given arch
1055 * @fit: pointer to the FIT format image header
1056 * @noffset: component image node offset
1057 * @arch: requested imagearch
1058 *
1059 * fit_image_check_arch() reads image arch property and compares its numeric
1060 * id with the requested arch. Comparison result is returned to the caller.
1061 *
1062 * returns:
1063 * 1 if image is of given arch
1064 * 0 otherwise (or on error)
1065 */
1066int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)
1067{
1068 uint8_t image_arch;
1069
1070 if (fit_image_get_arch(fit, noffset, &image_arch))
1071 return 0;
1072 return (arch == image_arch);
1073}
1074
1075/**
1076 * fit_image_check_type - check whether image node is of a given type
1077 * @fit: pointer to the FIT format image header
1078 * @noffset: component image node offset
1079 * @type: requested image type
1080 *
1081 * fit_image_check_type() reads image type property and compares its numeric
1082 * id with the requested type. Comparison result is returned to the caller.
1083 *
1084 * returns:
1085 * 1 if image is of given type
1086 * 0 otherwise (or on error)
1087 */
1088int fit_image_check_type(const void *fit, int noffset, uint8_t type)
1089{
1090 uint8_t image_type;
1091
1092 if (fit_image_get_type(fit, noffset, &image_type))
1093 return 0;
1094 return (type == image_type);
1095}
1096
1097/**
1098 * fit_image_check_comp - check whether image node uses given compression
1099 * @fit: pointer to the FIT format image header
1100 * @noffset: component image node offset
1101 * @comp: requested image compression type
1102 *
1103 * fit_image_check_comp() reads image compression property and compares its
1104 * numeric id with the requested compression type. Comparison result is
1105 * returned to the caller.
1106 *
1107 * returns:
1108 * 1 if image uses requested compression
1109 * 0 otherwise (or on error)
1110 */
1111int fit_image_check_comp(const void *fit, int noffset, uint8_t comp)
1112{
1113 uint8_t image_comp;
1114
1115 if (fit_image_get_comp(fit, noffset, &image_comp))
1116 return 0;
1117 return (comp == image_comp);
1118}
1119
1120/**
1121 * fit_check_format - sanity check FIT image format
1122 * @fit: pointer to the FIT format image header
1123 *
1124 * fit_check_format() runs a basic sanity FIT image verification.
1125 * Routine checks for mandatory properties, nodes, etc.
1126 *
1127 * returns:
1128 * 1, on success
1129 * 0, on failure
1130 */
1131int fit_check_format(const void *fit)
1132{
1133 /* mandatory / node 'description' property */
1134 if (fdt_getprop(fit, 0, FIT_DESC_PROP, NULL) == NULL) {
1135 debug("Wrong FIT format: no description\n");
1136 return 0;
1137 }
1138
1139 if (IMAGE_ENABLE_TIMESTAMP) {
1140 /* mandatory / node 'timestamp' property */
1141 if (fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) {
1142 debug("Wrong FIT format: no timestamp\n");
1143 return 0;
1144 }
1145 }
1146
1147 /* mandatory subimages parent '/images' node */
1148 if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) {
1149 debug("Wrong FIT format: no images parent node\n");
1150 return 0;
1151 }
1152
1153 return 1;
1154}
1155
1156
1157/**
1158 * fit_conf_find_compat
1159 * @fit: pointer to the FIT format image header
1160 * @fdt: pointer to the device tree to compare against
1161 *
1162 * fit_conf_find_compat() attempts to find the configuration whose fdt is the
1163 * most compatible with the passed in device tree.
1164 *
1165 * Example:
1166 *
1167 * / o image-tree
1168 * |-o images
1169 * | |-o fdt@1
1170 * | |-o fdt@2
1171 * |
1172 * |-o configurations
1173 * |-o config@1
1174 * | |-fdt = fdt@1
1175 * |
1176 * |-o config@2
1177 * |-fdt = fdt@2
1178 *
1179 * / o U-Boot fdt
1180 * |-compatible = "foo,bar", "bim,bam"
1181 *
1182 * / o kernel fdt1
1183 * |-compatible = "foo,bar",
1184 *
1185 * / o kernel fdt2
1186 * |-compatible = "bim,bam", "baz,biz"
1187 *
1188 * Configuration 1 would be picked because the first string in U-Boot's
1189 * compatible list, "foo,bar", matches a compatible string in the root of fdt1.
1190 * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1.
1191 *
1192 * returns:
1193 * offset to the configuration to use if one was found
1194 * -1 otherwise
1195 */
1196int fit_conf_find_compat(const void *fit, const void *fdt)
1197{
1198 int ndepth = 0;
1199 int noffset, confs_noffset, images_noffset;
1200 const void *fdt_compat;
1201 int fdt_compat_len;
1202 int best_match_offset = 0;
1203 int best_match_pos = 0;
1204
1205 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1206 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1207 if (confs_noffset < 0 || images_noffset < 0) {
1208 debug("Can't find configurations or images nodes.\n");
1209 return -1;
1210 }
1211
1212 fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
1213 if (!fdt_compat) {
1214 debug("Fdt for comparison has no \"compatible\" property.\n");
1215 return -1;
1216 }
1217
1218 /*
1219 * Loop over the configurations in the FIT image.
1220 */
1221 for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
1222 (noffset >= 0) && (ndepth > 0);
1223 noffset = fdt_next_node(fit, noffset, &ndepth)) {
1224 const void *kfdt;
1225 const char *kfdt_name;
1226 int kfdt_noffset;
1227 const char *cur_fdt_compat;
1228 int len;
1229 size_t size;
1230 int i;
1231
1232 if (ndepth > 1)
1233 continue;
1234
1235 kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
1236 if (!kfdt_name) {
1237 debug("No fdt property found.\n");
1238 continue;
1239 }
1240 kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
1241 kfdt_name);
1242 if (kfdt_noffset < 0) {
1243 debug("No image node named \"%s\" found.\n",
1244 kfdt_name);
1245 continue;
1246 }
1247 /*
1248 * Get a pointer to this configuration's fdt.
1249 */
1250 if (fit_image_get_data(fit, kfdt_noffset, &kfdt, &size)) {
1251 debug("Failed to get fdt \"%s\".\n", kfdt_name);
1252 continue;
1253 }
1254
1255 len = fdt_compat_len;
1256 cur_fdt_compat = fdt_compat;
1257 /*
1258 * Look for a match for each U-Boot compatibility string in
1259 * turn in this configuration's fdt.
1260 */
1261 for (i = 0; len > 0 &&
1262 (!best_match_offset || best_match_pos > i); i++) {
1263 int cur_len = strlen(cur_fdt_compat) + 1;
1264
1265 if (!fdt_node_check_compatible(kfdt, 0,
1266 cur_fdt_compat)) {
1267 best_match_offset = noffset;
1268 best_match_pos = i;
1269 break;
1270 }
1271 len -= cur_len;
1272 cur_fdt_compat += cur_len;
1273 }
1274 }
1275 if (!best_match_offset) {
1276 debug("No match found.\n");
1277 return -1;
1278 }
1279
1280 return best_match_offset;
1281}
1282
1283/**
1284 * fit_conf_get_node - get node offset for configuration of a given unit name
1285 * @fit: pointer to the FIT format image header
1286 * @conf_uname: configuration node unit name
1287 *
1288 * fit_conf_get_node() finds a configuration (withing the '/configurations'
1289 * parant node) of a provided unit name. If configuration is found its node
1290 * offset is returned to the caller.
1291 *
1292 * When NULL is provided in second argument fit_conf_get_node() will search
1293 * for a default configuration node instead. Default configuration node unit
1294 * name is retrived from FIT_DEFAULT_PROP property of the '/configurations'
1295 * node.
1296 *
1297 * returns:
1298 * configuration node offset when found (>=0)
1299 * negative number on failure (FDT_ERR_* code)
1300 */
1301int fit_conf_get_node(const void *fit, const char *conf_uname)
1302{
1303 int noffset, confs_noffset;
1304 int len;
1305
1306 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1307 if (confs_noffset < 0) {
1308 debug("Can't find configurations parent node '%s' (%s)\n",
1309 FIT_CONFS_PATH, fdt_strerror(confs_noffset));
1310 return confs_noffset;
1311 }
1312
1313 if (conf_uname == NULL) {
1314 /* get configuration unit name from the default property */
1315 debug("No configuration specified, trying default...\n");
1316 conf_uname = (char *)fdt_getprop(fit, confs_noffset,
1317 FIT_DEFAULT_PROP, &len);
1318 if (conf_uname == NULL) {
1319 fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP,
1320 len);
1321 return len;
1322 }
1323 debug("Found default configuration: '%s'\n", conf_uname);
1324 }
1325
1326 noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname);
1327 if (noffset < 0) {
1328 debug("Can't get node offset for configuration unit name: '%s' (%s)\n",
1329 conf_uname, fdt_strerror(noffset));
1330 }
1331
1332 return noffset;
1333}
1334
003efd7d 1335int fit_conf_get_prop_node(const void *fit, int noffset,
53fbb7e8
SG
1336 const char *prop_name)
1337{
1338 char *uname;
1339 int len;
1340
1341 /* get kernel image unit name from configuration kernel property */
1342 uname = (char *)fdt_getprop(fit, noffset, prop_name, &len);
1343 if (uname == NULL)
1344 return len;
1345
1346 return fit_image_get_node(fit, uname);
1347}
1348
1349/**
1350 * fit_conf_get_kernel_node - get kernel image node offset that corresponds to
1351 * a given configuration
1352 * @fit: pointer to the FIT format image header
1353 * @noffset: configuration node offset
1354 *
1355 * fit_conf_get_kernel_node() retrives kernel image node unit name from
1356 * configuration FIT_KERNEL_PROP property and translates it to the node
1357 * offset.
1358 *
1359 * returns:
1360 * image node offset when found (>=0)
1361 * negative number on failure (FDT_ERR_* code)
1362 */
1363int fit_conf_get_kernel_node(const void *fit, int noffset)
1364{
003efd7d 1365 return fit_conf_get_prop_node(fit, noffset, FIT_KERNEL_PROP);
53fbb7e8
SG
1366}
1367
1368/**
1369 * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to
1370 * a given configuration
1371 * @fit: pointer to the FIT format image header
1372 * @noffset: configuration node offset
1373 *
1374 * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from
1375 * configuration FIT_KERNEL_PROP property and translates it to the node
1376 * offset.
1377 *
1378 * returns:
1379 * image node offset when found (>=0)
1380 * negative number on failure (FDT_ERR_* code)
1381 */
1382int fit_conf_get_ramdisk_node(const void *fit, int noffset)
1383{
003efd7d 1384 return fit_conf_get_prop_node(fit, noffset, FIT_RAMDISK_PROP);
53fbb7e8
SG
1385}
1386
1387/**
1388 * fit_conf_get_fdt_node - get fdt image node offset that corresponds to
1389 * a given configuration
1390 * @fit: pointer to the FIT format image header
1391 * @noffset: configuration node offset
1392 *
1393 * fit_conf_get_fdt_node() retrives fdt image node unit name from
1394 * configuration FIT_KERNEL_PROP property and translates it to the node
1395 * offset.
1396 *
1397 * returns:
1398 * image node offset when found (>=0)
1399 * negative number on failure (FDT_ERR_* code)
1400 */
1401int fit_conf_get_fdt_node(const void *fit, int noffset)
1402{
003efd7d 1403 return fit_conf_get_prop_node(fit, noffset, FIT_FDT_PROP);
53fbb7e8
SG
1404}
1405
1406/**
1407 * fit_conf_print - prints out the FIT configuration details
1408 * @fit: pointer to the FIT format image header
1409 * @noffset: offset of the configuration node
1410 * @p: pointer to prefix string
1411 *
1412 * fit_conf_print() lists all mandatory properies for the processed
1413 * configuration node.
1414 *
1415 * returns:
1416 * no returned results
1417 */
1418void fit_conf_print(const void *fit, int noffset, const char *p)
1419{
1420 char *desc;
1421 char *uname;
1422 int ret;
1423
1424 /* Mandatory properties */
1425 ret = fit_get_desc(fit, noffset, &desc);
1426 printf("%s Description: ", p);
1427 if (ret)
1428 printf("unavailable\n");
1429 else
1430 printf("%s\n", desc);
1431
1432 uname = (char *)fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL);
1433 printf("%s Kernel: ", p);
1434 if (uname == NULL)
1435 printf("unavailable\n");
1436 else
1437 printf("%s\n", uname);
1438
1439 /* Optional properties */
1440 uname = (char *)fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL);
1441 if (uname)
1442 printf("%s Init Ramdisk: %s\n", p, uname);
1443
1444 uname = (char *)fdt_getprop(fit, noffset, FIT_FDT_PROP, NULL);
1445 if (uname)
1446 printf("%s FDT: %s\n", p, uname);
1447}
1448
1449/**
1450 * fit_check_ramdisk - verify FIT format ramdisk subimage
1451 * @fit_hdr: pointer to the FIT ramdisk header
1452 * @rd_noffset: ramdisk subimage node offset within FIT image
1453 * @arch: requested ramdisk image architecture type
1454 * @verify: data CRC verification flag
1455 *
1456 * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from
1457 * specified FIT image.
1458 *
1459 * returns:
1460 * 1, on success
1461 * 0, on failure
1462 */
53fbb7e8
SG
1463int fit_check_ramdisk(const void *fit, int rd_noffset, uint8_t arch,
1464 int verify)
1465{
1466 fit_image_print(fit, rd_noffset, " ");
1467
1468 if (verify) {
1469 puts(" Verifying Hash Integrity ... ");
b8da8366 1470 if (!fit_image_verify(fit, rd_noffset)) {
53fbb7e8
SG
1471 puts("Bad Data Hash\n");
1472 bootstage_error(BOOTSTAGE_ID_FIT_RD_HASH);
1473 return 0;
1474 }
1475 puts("OK\n");
1476 }
1477
1478 bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK_ALL);
1479 if (!fit_image_check_os(fit, rd_noffset, IH_OS_LINUX) ||
1480 !fit_image_check_arch(fit, rd_noffset, arch) ||
1481 !fit_image_check_type(fit, rd_noffset, IH_TYPE_RAMDISK)) {
1482 printf("No Linux %s Ramdisk Image\n",
1483 genimg_get_arch_name(arch));
1484 bootstage_error(BOOTSTAGE_ID_FIT_RD_CHECK_ALL);
1485 return 0;
1486 }
1487
1488 bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK_ALL_OK);
1489 return 1;
1490}
This page took 0.18585 seconds and 4 git commands to generate.