1
2
3
4
5
6
7
8
9
10
11
12#ifdef USE_HOSTCC
13#include "mkimage.h"
14#include <time.h>
15#else
16#include <linux/compiler.h>
17#include <linux/kconfig.h>
18#include <common.h>
19#include <errno.h>
20#include <mapmem.h>
21#include <asm/io.h>
22#include <malloc.h>
23DECLARE_GLOBAL_DATA_PTR;
24#endif
25
26#include <image.h>
27#include <bootstage.h>
28#include <u-boot/crc.h>
29#include <u-boot/md5.h>
30#include <u-boot/sha1.h>
31#include <u-boot/sha256.h>
32
33
34
35
36#ifndef USE_HOSTCC
37static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr,
38 ulong *addr, const char **name)
39{
40 const char *sep;
41
42 *addr = addr_curr;
43 *name = NULL;
44
45 sep = strchr(spec, sepc);
46 if (sep) {
47 if (sep - spec > 0)
48 *addr = simple_strtoul(spec, NULL, 16);
49
50 *name = sep + 1;
51 return 1;
52 }
53
54 return 0;
55}
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78int fit_parse_conf(const char *spec, ulong addr_curr,
79 ulong *addr, const char **conf_name)
80{
81 return fit_parse_spec(spec, '#', addr_curr, addr, conf_name);
82}
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104int fit_parse_subimage(const char *spec, ulong addr_curr,
105 ulong *addr, const char **image_name)
106{
107 return fit_parse_spec(spec, ':', addr_curr, addr, image_name);
108}
109#endif
110
111static void fit_get_debug(const void *fit, int noffset,
112 char *prop_name, int err)
113{
114 debug("Can't get '%s' property from FIT 0x%08lx, node: offset %d, name %s (%s)\n",
115 prop_name, (ulong)fit, noffset, fit_get_name(fit, noffset, NULL),
116 fdt_strerror(err));
117}
118
119
120
121
122
123
124
125
126
127int fit_get_subimage_count(const void *fit, int images_noffset)
128{
129 int noffset;
130 int ndepth;
131 int count = 0;
132
133
134 for (ndepth = 0, count = 0,
135 noffset = fdt_next_node(fit, images_noffset, &ndepth);
136 (noffset >= 0) && (ndepth > 0);
137 noffset = fdt_next_node(fit, noffset, &ndepth)) {
138 if (ndepth == 1) {
139 count++;
140 }
141 }
142
143 return count;
144}
145
146#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT)
147
148
149
150
151
152
153
154
155
156
157
158
159void fit_print_contents(const void *fit)
160{
161 char *desc;
162 char *uname;
163 int images_noffset;
164 int confs_noffset;
165 int noffset;
166 int ndepth;
167 int count = 0;
168 int ret;
169 const char *p;
170 time_t timestamp;
171
172
173 p = IMAGE_INDENT_STRING;
174
175
176 ret = fit_get_desc(fit, 0, &desc);
177 printf("%sFIT description: ", p);
178 if (ret)
179 printf("unavailable\n");
180 else
181 printf("%s\n", desc);
182
183 if (IMAGE_ENABLE_TIMESTAMP) {
184 ret = fit_get_timestamp(fit, 0, ×tamp);
185 printf("%sCreated: ", p);
186 if (ret)
187 printf("unavailable\n");
188 else
189 genimg_print_time(timestamp);
190 }
191
192
193 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
194 if (images_noffset < 0) {
195 printf("Can't find images parent node '%s' (%s)\n",
196 FIT_IMAGES_PATH, fdt_strerror(images_noffset));
197 return;
198 }
199
200
201 for (ndepth = 0, count = 0,
202 noffset = fdt_next_node(fit, images_noffset, &ndepth);
203 (noffset >= 0) && (ndepth > 0);
204 noffset = fdt_next_node(fit, noffset, &ndepth)) {
205 if (ndepth == 1) {
206
207
208
209
210 printf("%s Image %u (%s)\n", p, count++,
211 fit_get_name(fit, noffset, NULL));
212
213 fit_image_print(fit, noffset, p);
214 }
215 }
216
217
218 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
219 if (confs_noffset < 0) {
220 debug("Can't get configurations parent node '%s' (%s)\n",
221 FIT_CONFS_PATH, fdt_strerror(confs_noffset));
222 return;
223 }
224
225
226 uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL);
227 if (uname)
228 printf("%s Default Configuration: '%s'\n", p, uname);
229
230
231 for (ndepth = 0, count = 0,
232 noffset = fdt_next_node(fit, confs_noffset, &ndepth);
233 (noffset >= 0) && (ndepth > 0);
234 noffset = fdt_next_node(fit, noffset, &ndepth)) {
235 if (ndepth == 1) {
236
237
238
239
240 printf("%s Configuration %u (%s)\n", p, count++,
241 fit_get_name(fit, noffset, NULL));
242
243 fit_conf_print(fit, noffset, p);
244 }
245 }
246}
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263static void fit_image_print_data(const void *fit, int noffset, const char *p,
264 const char *type)
265{
266 const char *keyname;
267 uint8_t *value;
268 int value_len;
269 char *algo;
270 int required;
271 int ret, i;
272
273 debug("%s %s node: '%s'\n", p, type,
274 fit_get_name(fit, noffset, NULL));
275 printf("%s %s algo: ", p, type);
276 if (fit_image_hash_get_algo(fit, noffset, &algo)) {
277 printf("invalid/unsupported\n");
278 return;
279 }
280 printf("%s", algo);
281 keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
282 required = fdt_getprop(fit, noffset, "required", NULL) != NULL;
283 if (keyname)
284 printf(":%s", keyname);
285 if (required)
286 printf(" (required)");
287 printf("\n");
288
289 ret = fit_image_hash_get_value(fit, noffset, &value,
290 &value_len);
291 printf("%s %s value: ", p, type);
292 if (ret) {
293 printf("unavailable\n");
294 } else {
295 for (i = 0; i < value_len; i++)
296 printf("%02x", value[i]);
297 printf("\n");
298 }
299
300 debug("%s %s len: %d\n", p, type, value_len);
301
302
303 if (IMAGE_ENABLE_TIMESTAMP && keyname) {
304 time_t timestamp;
305
306 printf("%s Timestamp: ", p);
307 if (fit_get_timestamp(fit, noffset, ×tamp))
308 printf("unavailable\n");
309 else
310 genimg_print_time(timestamp);
311 }
312}
313
314
315
316
317
318
319
320
321
322
323
324
325static void fit_image_print_verification_data(const void *fit, int noffset,
326 const char *p)
327{
328 const char *name;
329
330
331
332
333
334
335 name = fit_get_name(fit, noffset, NULL);
336 if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) {
337 fit_image_print_data(fit, noffset, p, "Hash");
338 } else if (!strncmp(name, FIT_SIG_NODENAME,
339 strlen(FIT_SIG_NODENAME))) {
340 fit_image_print_data(fit, noffset, p, "Sign");
341 }
342}
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359void fit_image_print(const void *fit, int image_noffset, const char *p)
360{
361 char *desc;
362 uint8_t type, arch, os, comp;
363 size_t size;
364 ulong load, entry;
365 const void *data;
366 int noffset;
367 int ndepth;
368 int ret;
369
370
371 ret = fit_get_desc(fit, image_noffset, &desc);
372 printf("%s Description: ", p);
373 if (ret)
374 printf("unavailable\n");
375 else
376 printf("%s\n", desc);
377
378 if (IMAGE_ENABLE_TIMESTAMP) {
379 time_t timestamp;
380
381 ret = fit_get_timestamp(fit, 0, ×tamp);
382 printf("%s Created: ", p);
383 if (ret)
384 printf("unavailable\n");
385 else
386 genimg_print_time(timestamp);
387 }
388
389 fit_image_get_type(fit, image_noffset, &type);
390 printf("%s Type: %s\n", p, genimg_get_type_name(type));
391
392 fit_image_get_comp(fit, image_noffset, &comp);
393 printf("%s Compression: %s\n", p, genimg_get_comp_name(comp));
394
395 ret = fit_image_get_data(fit, image_noffset, &data, &size);
396
397#ifndef USE_HOSTCC
398 printf("%s Data Start: ", p);
399 if (ret) {
400 printf("unavailable\n");
401 } else {
402 void *vdata = (void *)data;
403
404 printf("0x%08lx\n", (ulong)map_to_sysmem(vdata));
405 }
406#endif
407
408 printf("%s Data Size: ", p);
409 if (ret)
410 printf("unavailable\n");
411 else
412 genimg_print_size(size);
413
414
415 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
416 (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
417 (type == IH_TYPE_FLATDT)) {
418 fit_image_get_arch(fit, image_noffset, &arch);
419 printf("%s Architecture: %s\n", p, genimg_get_arch_name(arch));
420 }
421
422 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK)) {
423 fit_image_get_os(fit, image_noffset, &os);
424 printf("%s OS: %s\n", p, genimg_get_os_name(os));
425 }
426
427 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
428 (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK) ||
429 (type == IH_TYPE_FPGA)) {
430 ret = fit_image_get_load(fit, image_noffset, &load);
431 printf("%s Load Address: ", p);
432 if (ret)
433 printf("unavailable\n");
434 else
435 printf("0x%08lx\n", load);
436 }
437
438
439 if (type == IH_TYPE_FLATDT && !fit_image_get_load(fit, image_noffset, &load))
440 printf("%s Load Address: 0x%08lx\n", p, load);
441
442 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
443 (type == IH_TYPE_RAMDISK)) {
444 ret = fit_image_get_entry(fit, image_noffset, &entry);
445 printf("%s Entry Point: ", p);
446 if (ret)
447 printf("unavailable\n");
448 else
449 printf("0x%08lx\n", entry);
450 }
451
452
453 for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth);
454 (noffset >= 0) && (ndepth > 0);
455 noffset = fdt_next_node(fit, noffset, &ndepth)) {
456 if (ndepth == 1) {
457
458 fit_image_print_verification_data(fit, noffset, p);
459 }
460 }
461}
462
463#endif
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478int fit_get_desc(const void *fit, int noffset, char **desc)
479{
480 int len;
481
482 *desc = (char *)fdt_getprop(fit, noffset, FIT_DESC_PROP, &len);
483 if (*desc == NULL) {
484 fit_get_debug(fit, noffset, FIT_DESC_PROP, len);
485 return -1;
486 }
487
488 return 0;
489}
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506int fit_get_timestamp(const void *fit, int noffset, time_t *timestamp)
507{
508 int len;
509 const void *data;
510
511 data = fdt_getprop(fit, noffset, FIT_TIMESTAMP_PROP, &len);
512 if (data == NULL) {
513 fit_get_debug(fit, noffset, FIT_TIMESTAMP_PROP, len);
514 return -1;
515 }
516 if (len != sizeof(uint32_t)) {
517 debug("FIT timestamp with incorrect size of (%u)\n", len);
518 return -2;
519 }
520
521 *timestamp = uimage_to_cpu(*((uint32_t *)data));
522 return 0;
523}
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538int fit_image_get_node(const void *fit, const char *image_uname)
539{
540 int noffset, images_noffset;
541
542 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
543 if (images_noffset < 0) {
544 debug("Can't find images parent node '%s' (%s)\n",
545 FIT_IMAGES_PATH, fdt_strerror(images_noffset));
546 return images_noffset;
547 }
548
549 noffset = fdt_subnode_offset(fit, images_noffset, image_uname);
550 if (noffset < 0) {
551 debug("Can't get node offset for image unit name: '%s' (%s)\n",
552 image_uname, fdt_strerror(noffset));
553 }
554
555 return noffset;
556}
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572int fit_image_get_os(const void *fit, int noffset, uint8_t *os)
573{
574 int len;
575 const void *data;
576
577
578 data = fdt_getprop(fit, noffset, FIT_OS_PROP, &len);
579 if (data == NULL) {
580 fit_get_debug(fit, noffset, FIT_OS_PROP, len);
581 *os = -1;
582 return -1;
583 }
584
585
586 *os = genimg_get_os_id(data);
587 return 0;
588}
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604int fit_image_get_arch(const void *fit, int noffset, uint8_t *arch)
605{
606 int len;
607 const void *data;
608
609
610 data = fdt_getprop(fit, noffset, FIT_ARCH_PROP, &len);
611 if (data == NULL) {
612 fit_get_debug(fit, noffset, FIT_ARCH_PROP, len);
613 *arch = -1;
614 return -1;
615 }
616
617
618 *arch = genimg_get_arch_id(data);
619 return 0;
620}
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636int fit_image_get_type(const void *fit, int noffset, uint8_t *type)
637{
638 int len;
639 const void *data;
640
641
642 data = fdt_getprop(fit, noffset, FIT_TYPE_PROP, &len);
643 if (data == NULL) {
644 fit_get_debug(fit, noffset, FIT_TYPE_PROP, len);
645 *type = -1;
646 return -1;
647 }
648
649
650 *type = genimg_get_type_id(data);
651 return 0;
652}
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp)
669{
670 int len;
671 const void *data;
672
673
674 data = fdt_getprop(fit, noffset, FIT_COMP_PROP, &len);
675 if (data == NULL) {
676 fit_get_debug(fit, noffset, FIT_COMP_PROP, len);
677 *comp = -1;
678 return -1;
679 }
680
681
682 *comp = genimg_get_comp_id(data);
683 return 0;
684}
685
686static int fit_image_get_address(const void *fit, int noffset, char *name,
687 ulong *load)
688{
689 int len, cell_len;
690 const fdt32_t *cell;
691 uint64_t load64 = 0;
692
693 cell = fdt_getprop(fit, noffset, name, &len);
694 if (cell == NULL) {
695 fit_get_debug(fit, noffset, name, len);
696 return -1;
697 }
698
699 if (len > sizeof(ulong)) {
700 printf("Unsupported %s address size\n", name);
701 return -1;
702 }
703
704 cell_len = len >> 2;
705
706 while (cell_len--) {
707 load64 = (load64 << 32) | uimage_to_cpu(*cell);
708 cell++;
709 }
710 *load = (ulong)load64;
711
712 return 0;
713}
714
715
716
717
718
719
720
721
722
723
724
725
726
727int fit_image_get_load(const void *fit, int noffset, ulong *load)
728{
729 return fit_image_get_address(fit, noffset, FIT_LOAD_PROP, load);
730}
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749int fit_image_get_entry(const void *fit, int noffset, ulong *entry)
750{
751 return fit_image_get_address(fit, noffset, FIT_ENTRY_PROP, entry);
752}
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769int fit_image_get_data(const void *fit, int noffset,
770 const void **data, size_t *size)
771{
772 int len;
773
774 *data = fdt_getprop(fit, noffset, FIT_DATA_PROP, &len);
775 if (*data == NULL) {
776 fit_get_debug(fit, noffset, FIT_DATA_PROP, len);
777 *size = 0;
778 return -1;
779 }
780
781 *size = len;
782 return 0;
783}
784
785
786
787
788
789
790
791
792
793
794
795
796int fit_image_get_data_offset(const void *fit, int noffset, int *data_offset)
797{
798 const fdt32_t *val;
799
800 val = fdt_getprop(fit, noffset, FIT_DATA_OFFSET_PROP, NULL);
801 if (!val)
802 return -ENOENT;
803
804 *data_offset = fdt32_to_cpu(*val);
805
806 return 0;
807}
808
809
810
811
812
813
814
815
816
817
818
819
820int fit_image_get_data_position(const void *fit, int noffset,
821 int *data_position)
822{
823 const fdt32_t *val;
824
825 val = fdt_getprop(fit, noffset, FIT_DATA_POSITION_PROP, NULL);
826 if (!val)
827 return -ENOENT;
828
829 *data_position = fdt32_to_cpu(*val);
830
831 return 0;
832}
833
834
835
836
837
838
839
840
841
842
843
844
845int fit_image_get_data_size(const void *fit, int noffset, int *data_size)
846{
847 const fdt32_t *val;
848
849 val = fdt_getprop(fit, noffset, FIT_DATA_SIZE_PROP, NULL);
850 if (!val)
851 return -ENOENT;
852
853 *data_size = fdt32_to_cpu(*val);
854
855 return 0;
856}
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871int fit_image_hash_get_algo(const void *fit, int noffset, char **algo)
872{
873 int len;
874
875 *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
876 if (*algo == NULL) {
877 fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
878 return -1;
879 }
880
881 return 0;
882}
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value,
900 int *value_len)
901{
902 int len;
903
904 *value = (uint8_t *)fdt_getprop(fit, noffset, FIT_VALUE_PROP, &len);
905 if (*value == NULL) {
906 fit_get_debug(fit, noffset, FIT_VALUE_PROP, len);
907 *value_len = 0;
908 return -1;
909 }
910
911 *value_len = len;
912 return 0;
913}
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929static int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore)
930{
931 int len;
932 int *value;
933
934 value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len);
935 if (value == NULL || len != sizeof(int))
936 *ignore = 0;
937 else
938 *ignore = *value;
939
940 return 0;
941}
942
943ulong fit_get_end(const void *fit)
944{
945 return map_to_sysmem((void *)(fit + fdt_totalsize(fit)));
946}
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961int fit_set_timestamp(void *fit, int noffset, time_t timestamp)
962{
963 uint32_t t;
964 int ret;
965
966 t = cpu_to_uimage(timestamp);
967 ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t,
968 sizeof(uint32_t));
969 if (ret) {
970 debug("Can't set '%s' property for '%s' node (%s)\n",
971 FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL),
972 fdt_strerror(ret));
973 return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -1;
974 }
975
976 return 0;
977}
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997int calculate_hash(const void *data, int data_len, const char *algo,
998 uint8_t *value, int *value_len)
999{
1000 if (IMAGE_ENABLE_CRC32 && strcmp(algo, "crc32") == 0) {
1001 *((uint32_t *)value) = crc32_wd(0, data, data_len,
1002 CHUNKSZ_CRC32);
1003 *((uint32_t *)value) = cpu_to_uimage(*((uint32_t *)value));
1004 *value_len = 4;
1005 } else if (IMAGE_ENABLE_SHA1 && strcmp(algo, "sha1") == 0) {
1006 sha1_csum_wd((unsigned char *)data, data_len,
1007 (unsigned char *)value, CHUNKSZ_SHA1);
1008 *value_len = 20;
1009 } else if (IMAGE_ENABLE_SHA256 && strcmp(algo, "sha256") == 0) {
1010 sha256_csum_wd((unsigned char *)data, data_len,
1011 (unsigned char *)value, CHUNKSZ_SHA256);
1012 *value_len = SHA256_SUM_LEN;
1013 } else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) {
1014 md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
1015 *value_len = 16;
1016 } else {
1017 debug("Unsupported hash alogrithm\n");
1018 return -1;
1019 }
1020 return 0;
1021}
1022
1023static int fit_image_check_hash(const void *fit, int noffset, const void *data,
1024 size_t size, char **err_msgp)
1025{
1026 uint8_t value[FIT_MAX_HASH_LEN];
1027 int value_len;
1028 char *algo;
1029 uint8_t *fit_value;
1030 int fit_value_len;
1031 int ignore;
1032
1033 *err_msgp = NULL;
1034
1035 if (fit_image_hash_get_algo(fit, noffset, &algo)) {
1036 *err_msgp = "Can't get hash algo property";
1037 return -1;
1038 }
1039 printf("%s", algo);
1040
1041 if (IMAGE_ENABLE_IGNORE) {
1042 fit_image_hash_get_ignore(fit, noffset, &ignore);
1043 if (ignore) {
1044 printf("-skipped ");
1045 return 0;
1046 }
1047 }
1048
1049 if (fit_image_hash_get_value(fit, noffset, &fit_value,
1050 &fit_value_len)) {
1051 *err_msgp = "Can't get hash value property";
1052 return -1;
1053 }
1054
1055 if (calculate_hash(data, size, algo, value, &value_len)) {
1056 *err_msgp = "Unsupported hash algorithm";
1057 return -1;
1058 }
1059
1060 if (value_len != fit_value_len) {
1061 *err_msgp = "Bad hash value len";
1062 return -1;
1063 } else if (memcmp(value, fit_value, value_len) != 0) {
1064 *err_msgp = "Bad hash value";
1065 return -1;
1066 }
1067
1068 return 0;
1069}
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084int fit_image_verify(const void *fit, int image_noffset)
1085{
1086 const void *data;
1087 size_t size;
1088 int noffset = 0;
1089 char *err_msg = "";
1090 int verify_all = 1;
1091 int ret;
1092
1093
1094 if (fit_image_get_data(fit, image_noffset, &data, &size)) {
1095 err_msg = "Can't get image data/size";
1096 goto error;
1097 }
1098
1099
1100 if (IMAGE_ENABLE_VERIFY &&
1101 fit_image_verify_required_sigs(fit, image_noffset, data, size,
1102 gd_fdt_blob(), &verify_all)) {
1103 err_msg = "Unable to verify required signature";
1104 goto error;
1105 }
1106
1107
1108 fdt_for_each_subnode(noffset, fit, image_noffset) {
1109 const char *name = fit_get_name(fit, noffset, NULL);
1110
1111
1112
1113
1114
1115
1116 if (!strncmp(name, FIT_HASH_NODENAME,
1117 strlen(FIT_HASH_NODENAME))) {
1118 if (fit_image_check_hash(fit, noffset, data, size,
1119 &err_msg))
1120 goto error;
1121 puts("+ ");
1122 } else if (IMAGE_ENABLE_VERIFY && verify_all &&
1123 !strncmp(name, FIT_SIG_NODENAME,
1124 strlen(FIT_SIG_NODENAME))) {
1125 ret = fit_image_check_sig(fit, noffset, data,
1126 size, -1, &err_msg);
1127
1128
1129
1130
1131
1132
1133
1134 if (ret)
1135 puts("- ");
1136 else
1137 puts("+ ");
1138 }
1139 }
1140
1141 if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
1142 err_msg = "Corrupted or truncated tree";
1143 goto error;
1144 }
1145
1146 return 1;
1147
1148error:
1149 printf(" error!\n%s for '%s' hash node in '%s' image node\n",
1150 err_msg, fit_get_name(fit, noffset, NULL),
1151 fit_get_name(fit, image_noffset, NULL));
1152 return 0;
1153}
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166int fit_all_image_verify(const void *fit)
1167{
1168 int images_noffset;
1169 int noffset;
1170 int ndepth;
1171 int count;
1172
1173
1174 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1175 if (images_noffset < 0) {
1176 printf("Can't find images parent node '%s' (%s)\n",
1177 FIT_IMAGES_PATH, fdt_strerror(images_noffset));
1178 return 0;
1179 }
1180
1181
1182 printf("## Checking hash(es) for FIT Image at %08lx ...\n",
1183 (ulong)fit);
1184 for (ndepth = 0, count = 0,
1185 noffset = fdt_next_node(fit, images_noffset, &ndepth);
1186 (noffset >= 0) && (ndepth > 0);
1187 noffset = fdt_next_node(fit, noffset, &ndepth)) {
1188 if (ndepth == 1) {
1189
1190
1191
1192
1193 printf(" Hash(es) for Image %u (%s): ", count,
1194 fit_get_name(fit, noffset, NULL));
1195 count++;
1196
1197 if (!fit_image_verify(fit, noffset))
1198 return 0;
1199 printf("\n");
1200 }
1201 }
1202 return 1;
1203}
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218int fit_image_check_os(const void *fit, int noffset, uint8_t os)
1219{
1220 uint8_t image_os;
1221
1222 if (fit_image_get_os(fit, noffset, &image_os))
1223 return 0;
1224 return (os == image_os);
1225}
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)
1241{
1242 uint8_t image_arch;
1243 int aarch32_support = 0;
1244
1245#ifdef CONFIG_ARM64_SUPPORT_AARCH32
1246 aarch32_support = 1;
1247#endif
1248
1249 if (fit_image_get_arch(fit, noffset, &image_arch))
1250 return 0;
1251 return (arch == image_arch) ||
1252 (arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
1253 (arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&
1254 aarch32_support);
1255}
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270int fit_image_check_type(const void *fit, int noffset, uint8_t type)
1271{
1272 uint8_t image_type;
1273
1274 if (fit_image_get_type(fit, noffset, &image_type))
1275 return 0;
1276 return (type == image_type);
1277}
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293int fit_image_check_comp(const void *fit, int noffset, uint8_t comp)
1294{
1295 uint8_t image_comp;
1296
1297 if (fit_image_get_comp(fit, noffset, &image_comp))
1298 return 0;
1299 return (comp == image_comp);
1300}
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313int fit_check_format(const void *fit)
1314{
1315
1316 if (fdt_getprop(fit, 0, FIT_DESC_PROP, NULL) == NULL) {
1317 debug("Wrong FIT format: no description\n");
1318 return 0;
1319 }
1320
1321 if (IMAGE_ENABLE_TIMESTAMP) {
1322
1323 if (fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) {
1324 debug("Wrong FIT format: no timestamp\n");
1325 return 0;
1326 }
1327 }
1328
1329
1330 if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) {
1331 debug("Wrong FIT format: no images parent node\n");
1332 return 0;
1333 }
1334
1335 return 1;
1336}
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378int fit_conf_find_compat(const void *fit, const void *fdt)
1379{
1380 int ndepth = 0;
1381 int noffset, confs_noffset, images_noffset;
1382 const void *fdt_compat;
1383 int fdt_compat_len;
1384 int best_match_offset = 0;
1385 int best_match_pos = 0;
1386
1387 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1388 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1389 if (confs_noffset < 0 || images_noffset < 0) {
1390 debug("Can't find configurations or images nodes.\n");
1391 return -1;
1392 }
1393
1394 fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
1395 if (!fdt_compat) {
1396 debug("Fdt for comparison has no \"compatible\" property.\n");
1397 return -1;
1398 }
1399
1400
1401
1402
1403 for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
1404 (noffset >= 0) && (ndepth > 0);
1405 noffset = fdt_next_node(fit, noffset, &ndepth)) {
1406 const void *kfdt;
1407 const char *kfdt_name;
1408 int kfdt_noffset;
1409 const char *cur_fdt_compat;
1410 int len;
1411 size_t size;
1412 int i;
1413
1414 if (ndepth > 1)
1415 continue;
1416
1417 kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
1418 if (!kfdt_name) {
1419 debug("No fdt property found.\n");
1420 continue;
1421 }
1422 kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
1423 kfdt_name);
1424 if (kfdt_noffset < 0) {
1425 debug("No image node named \"%s\" found.\n",
1426 kfdt_name);
1427 continue;
1428 }
1429
1430
1431
1432 if (fit_image_get_data(fit, kfdt_noffset, &kfdt, &size)) {
1433 debug("Failed to get fdt \"%s\".\n", kfdt_name);
1434 continue;
1435 }
1436
1437 len = fdt_compat_len;
1438 cur_fdt_compat = fdt_compat;
1439
1440
1441
1442
1443 for (i = 0; len > 0 &&
1444 (!best_match_offset || best_match_pos > i); i++) {
1445 int cur_len = strlen(cur_fdt_compat) + 1;
1446
1447 if (!fdt_node_check_compatible(kfdt, 0,
1448 cur_fdt_compat)) {
1449 best_match_offset = noffset;
1450 best_match_pos = i;
1451 break;
1452 }
1453 len -= cur_len;
1454 cur_fdt_compat += cur_len;
1455 }
1456 }
1457 if (!best_match_offset) {
1458 debug("No match found.\n");
1459 return -1;
1460 }
1461
1462 return best_match_offset;
1463}
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483int fit_conf_get_node(const void *fit, const char *conf_uname)
1484{
1485 int noffset, confs_noffset;
1486 int len;
1487 const char *s;
1488 char *conf_uname_copy = NULL;
1489
1490 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1491 if (confs_noffset < 0) {
1492 debug("Can't find configurations parent node '%s' (%s)\n",
1493 FIT_CONFS_PATH, fdt_strerror(confs_noffset));
1494 return confs_noffset;
1495 }
1496
1497 if (conf_uname == NULL) {
1498
1499 debug("No configuration specified, trying default...\n");
1500 conf_uname = (char *)fdt_getprop(fit, confs_noffset,
1501 FIT_DEFAULT_PROP, &len);
1502 if (conf_uname == NULL) {
1503 fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP,
1504 len);
1505 return len;
1506 }
1507 debug("Found default configuration: '%s'\n", conf_uname);
1508 }
1509
1510 s = strchr(conf_uname, '#');
1511 if (s) {
1512 len = s - conf_uname;
1513 conf_uname_copy = malloc(len + 1);
1514 if (!conf_uname_copy) {
1515 debug("Can't allocate uname copy: '%s'\n",
1516 conf_uname);
1517 return -ENOMEM;
1518 }
1519 memcpy(conf_uname_copy, conf_uname, len);
1520 conf_uname_copy[len] = '\0';
1521 conf_uname = conf_uname_copy;
1522 }
1523
1524 noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname);
1525 if (noffset < 0) {
1526 debug("Can't get node offset for configuration unit name: '%s' (%s)\n",
1527 conf_uname, fdt_strerror(noffset));
1528 }
1529
1530 if (conf_uname_copy)
1531 free(conf_uname_copy);
1532
1533 return noffset;
1534}
1535
1536int fit_conf_get_prop_node_count(const void *fit, int noffset,
1537 const char *prop_name)
1538{
1539 return fdt_stringlist_count(fit, noffset, prop_name);
1540}
1541
1542int fit_conf_get_prop_node_index(const void *fit, int noffset,
1543 const char *prop_name, int index)
1544{
1545 const char *uname;
1546 int len;
1547
1548
1549 uname = fdt_stringlist_get(fit, noffset, prop_name, index, &len);
1550 if (uname == NULL)
1551 return len;
1552
1553 return fit_image_get_node(fit, uname);
1554}
1555
1556int fit_conf_get_prop_node(const void *fit, int noffset,
1557 const char *prop_name)
1558{
1559 return fit_conf_get_prop_node_index(fit, noffset, prop_name, 0);
1560}
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574void fit_conf_print(const void *fit, int noffset, const char *p)
1575{
1576 char *desc;
1577 const char *uname;
1578 int ret;
1579 int fdt_index, loadables_index;
1580
1581
1582 ret = fit_get_desc(fit, noffset, &desc);
1583 printf("%s Description: ", p);
1584 if (ret)
1585 printf("unavailable\n");
1586 else
1587 printf("%s\n", desc);
1588
1589 uname = fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL);
1590 printf("%s Kernel: ", p);
1591 if (uname == NULL)
1592 printf("unavailable\n");
1593 else
1594 printf("%s\n", uname);
1595
1596
1597 uname = fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL);
1598 if (uname)
1599 printf("%s Init Ramdisk: %s\n", p, uname);
1600
1601 for (fdt_index = 0;
1602 uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP,
1603 fdt_index, NULL), uname;
1604 fdt_index++) {
1605
1606 if (fdt_index == 0)
1607 printf("%s FDT: ", p);
1608 else
1609 printf("%s ", p);
1610 printf("%s\n", uname);
1611 }
1612
1613 uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL);
1614 if (uname)
1615 printf("%s FPGA: %s\n", p, uname);
1616
1617
1618 for (loadables_index = 0;
1619 uname = fdt_stringlist_get(fit, noffset, FIT_LOADABLE_PROP,
1620 loadables_index, NULL), uname;
1621 loadables_index++) {
1622 if (loadables_index == 0) {
1623 printf("%s Loadables: ", p);
1624 } else {
1625 printf("%s ", p);
1626 }
1627 printf("%s\n", uname);
1628 }
1629}
1630
1631static int fit_image_select(const void *fit, int rd_noffset, int verify)
1632{
1633 fit_image_print(fit, rd_noffset, " ");
1634
1635 if (verify) {
1636 puts(" Verifying Hash Integrity ... ");
1637 if (!fit_image_verify(fit, rd_noffset)) {
1638 puts("Bad Data Hash\n");
1639 return -EACCES;
1640 }
1641 puts("OK\n");
1642 }
1643
1644 return 0;
1645}
1646
1647int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
1648 ulong addr)
1649{
1650 int cfg_noffset;
1651 void *fit_hdr;
1652 int noffset;
1653
1654 debug("* %s: using config '%s' from image at 0x%08lx\n",
1655 prop_name, images->fit_uname_cfg, addr);
1656
1657
1658 fit_hdr = map_sysmem(addr, 0);
1659 cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg);
1660 if (cfg_noffset < 0) {
1661 debug("* %s: no such config\n", prop_name);
1662 return -EINVAL;
1663 }
1664
1665 noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name);
1666 if (noffset < 0) {
1667 debug("* %s: no '%s' in config\n", prop_name, prop_name);
1668 return -ENOENT;
1669 }
1670
1671 return noffset;
1672}
1673
1674
1675
1676
1677
1678
1679
1680static const char *fit_get_image_type_property(int type)
1681{
1682
1683
1684
1685
1686
1687 switch (type) {
1688 case IH_TYPE_FLATDT:
1689 return FIT_FDT_PROP;
1690 case IH_TYPE_KERNEL:
1691 return FIT_KERNEL_PROP;
1692 case IH_TYPE_RAMDISK:
1693 return FIT_RAMDISK_PROP;
1694 case IH_TYPE_X86_SETUP:
1695 return FIT_SETUP_PROP;
1696 case IH_TYPE_LOADABLE:
1697 return FIT_LOADABLE_PROP;
1698 case IH_TYPE_FPGA:
1699 return FIT_FPGA_PROP;
1700 }
1701
1702 return "unknown";
1703}
1704
1705int fit_image_load(bootm_headers_t *images, ulong addr,
1706 const char **fit_unamep, const char **fit_uname_configp,
1707 int arch, int image_type, int bootstage_id,
1708 enum fit_load_op load_op, ulong *datap, ulong *lenp)
1709{
1710 int cfg_noffset, noffset;
1711 const char *fit_uname;
1712 const char *fit_uname_config;
1713 const char *fit_base_uname_config;
1714 const void *fit;
1715 const void *buf;
1716 size_t size;
1717 int type_ok, os_ok;
1718 ulong load, data, len;
1719 uint8_t os;
1720#ifndef USE_HOSTCC
1721 uint8_t os_arch;
1722#endif
1723 const char *prop_name;
1724 int ret;
1725
1726 fit = map_sysmem(addr, 0);
1727 fit_uname = fit_unamep ? *fit_unamep : NULL;
1728 fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL;
1729 fit_base_uname_config = NULL;
1730 prop_name = fit_get_image_type_property(image_type);
1731 printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);
1732
1733 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
1734 if (!fit_check_format(fit)) {
1735 printf("Bad FIT %s image format!\n", prop_name);
1736 bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
1737 return -ENOEXEC;
1738 }
1739 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
1740 if (fit_uname) {
1741
1742 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME);
1743 noffset = fit_image_get_node(fit, fit_uname);
1744 } else {
1745
1746
1747
1748
1749
1750 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
1751 if (IMAGE_ENABLE_BEST_MATCH && !fit_uname_config) {
1752 cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
1753 } else {
1754 cfg_noffset = fit_conf_get_node(fit,
1755 fit_uname_config);
1756 }
1757 if (cfg_noffset < 0) {
1758 puts("Could not find configuration node\n");
1759 bootstage_error(bootstage_id +
1760 BOOTSTAGE_SUB_NO_UNIT_NAME);
1761 return -ENOENT;
1762 }
1763 fit_base_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
1764 printf(" Using '%s' configuration\n", fit_base_uname_config);
1765 if (image_type == IH_TYPE_KERNEL) {
1766
1767 images->fit_uname_cfg = fit_base_uname_config;
1768 if (IMAGE_ENABLE_VERIFY && images->verify) {
1769 puts(" Verifying Hash Integrity ... ");
1770 if (fit_config_verify(fit, cfg_noffset)) {
1771 puts("Bad Data Hash\n");
1772 bootstage_error(bootstage_id +
1773 BOOTSTAGE_SUB_HASH);
1774 return -EACCES;
1775 }
1776 puts("OK\n");
1777 }
1778 bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
1779 }
1780
1781 noffset = fit_conf_get_prop_node(fit, cfg_noffset,
1782 prop_name);
1783 fit_uname = fit_get_name(fit, noffset, NULL);
1784 }
1785 if (noffset < 0) {
1786 puts("Could not find subimage node\n");
1787 bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
1788 return -ENOENT;
1789 }
1790
1791 printf(" Trying '%s' %s subimage\n", fit_uname, prop_name);
1792
1793 ret = fit_image_select(fit, noffset, images->verify);
1794 if (ret) {
1795 bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH);
1796 return ret;
1797 }
1798
1799 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
1800#if !defined(USE_HOSTCC) && !defined(CONFIG_SANDBOX)
1801 if (!fit_image_check_target_arch(fit, noffset)) {
1802 puts("Unsupported Architecture\n");
1803 bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
1804 return -ENOEXEC;
1805 }
1806#endif
1807
1808#ifndef USE_HOSTCC
1809 fit_image_get_arch(fit, noffset, &os_arch);
1810 images->os.arch = os_arch;
1811#endif
1812
1813 if (image_type == IH_TYPE_FLATDT &&
1814 !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) {
1815 puts("FDT image is compressed");
1816 return -EPROTONOSUPPORT;
1817 }
1818
1819 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
1820 type_ok = fit_image_check_type(fit, noffset, image_type) ||
1821 fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE) ||
1822 (image_type == IH_TYPE_KERNEL &&
1823 fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD));
1824
1825 os_ok = image_type == IH_TYPE_FLATDT ||
1826 image_type == IH_TYPE_FPGA ||
1827 fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
1828 fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
1829 fit_image_check_os(fit, noffset, IH_OS_OPENRTOS);
1830
1831
1832
1833
1834
1835
1836 if ((!type_ok || !os_ok) && image_type != IH_TYPE_LOADABLE) {
1837 fit_image_get_os(fit, noffset, &os);
1838 printf("No %s %s %s Image\n",
1839 genimg_get_os_name(os),
1840 genimg_get_arch_name(arch),
1841 genimg_get_type_name(image_type));
1842 bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
1843 return -EIO;
1844 }
1845
1846 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
1847
1848
1849 if (fit_image_get_data(fit, noffset, &buf, &size)) {
1850 printf("Could not find %s subimage data!\n", prop_name);
1851 bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
1852 return -ENOENT;
1853 }
1854
1855#if !defined(USE_HOSTCC) && defined(CONFIG_FIT_IMAGE_POST_PROCESS)
1856
1857 board_fit_image_post_process((void **)&buf, &size);
1858#endif
1859
1860 len = (ulong)size;
1861
1862
1863 if (image_type == IH_TYPE_FLATDT && fdt_check_header(buf)) {
1864 puts("Subimage data is not a FDT");
1865 return -ENOEXEC;
1866 }
1867
1868 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);
1869
1870
1871
1872
1873
1874
1875 {
1876 void *vbuf = (void *)buf;
1877
1878 data = map_to_sysmem(vbuf);
1879 }
1880
1881 if (load_op == FIT_LOAD_IGNORED) {
1882
1883 } else if (fit_image_get_load(fit, noffset, &load)) {
1884 if (load_op == FIT_LOAD_REQUIRED) {
1885 printf("Can't get %s subimage load address!\n",
1886 prop_name);
1887 bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD);
1888 return -EBADF;
1889 }
1890 } else if (load_op != FIT_LOAD_OPTIONAL_NON_ZERO || load) {
1891 ulong image_start, image_end;
1892 ulong load_end;
1893 void *dst;
1894
1895
1896
1897
1898
1899 image_start = addr;
1900 image_end = addr + fit_get_size(fit);
1901
1902 load_end = load + len;
1903 if (image_type != IH_TYPE_KERNEL &&
1904 load < image_end && load_end > image_start) {
1905 printf("Error: %s overwritten\n", prop_name);
1906 return -EXDEV;
1907 }
1908
1909 printf(" Loading %s from 0x%08lx to 0x%08lx\n",
1910 prop_name, data, load);
1911
1912 dst = map_sysmem(load, len);
1913 memmove(dst, buf, len);
1914 data = load;
1915 }
1916 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
1917
1918 *datap = data;
1919 *lenp = len;
1920 if (fit_unamep)
1921 *fit_unamep = (char *)fit_uname;
1922 if (fit_uname_configp)
1923 *fit_uname_configp = (char *)(fit_uname_config ? :
1924 fit_base_uname_config);
1925
1926 return noffset;
1927}
1928
1929int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
1930 ulong *setup_start, ulong *setup_len)
1931{
1932 int noffset;
1933 ulong addr;
1934 ulong len;
1935 int ret;
1936
1937 addr = map_to_sysmem(images->fit_hdr_os);
1938 noffset = fit_get_node_from_config(images, FIT_SETUP_PROP, addr);
1939 if (noffset < 0)
1940 return noffset;
1941
1942 ret = fit_image_load(images, addr, NULL, NULL, arch,
1943 IH_TYPE_X86_SETUP, BOOTSTAGE_ID_FIT_SETUP_START,
1944 FIT_LOAD_REQUIRED, setup_start, &len);
1945
1946 return ret;
1947}
1948
1949#ifndef USE_HOSTCC
1950int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
1951 const char **fit_unamep, const char **fit_uname_configp,
1952 int arch, ulong *datap, ulong *lenp)
1953{
1954 int fdt_noffset, cfg_noffset, count;
1955 const void *fit;
1956 const char *fit_uname = NULL;
1957 const char *fit_uname_config = NULL;
1958 char *fit_uname_config_copy = NULL;
1959 char *next_config = NULL;
1960 ulong load, len;
1961#ifdef CONFIG_OF_LIBFDT_OVERLAY
1962 ulong image_start, image_end;
1963 ulong ovload, ovlen;
1964 const char *uconfig;
1965 const char *uname;
1966 void *base, *ov;
1967 int i, err, noffset, ov_noffset;
1968#endif
1969
1970 fit_uname = fit_unamep ? *fit_unamep : NULL;
1971
1972 if (fit_uname_configp && *fit_uname_configp) {
1973 fit_uname_config_copy = strdup(*fit_uname_configp);
1974 if (!fit_uname_config_copy)
1975 return -ENOMEM;
1976
1977 next_config = strchr(fit_uname_config_copy, '#');
1978 if (next_config)
1979 *next_config++ = '\0';
1980 if (next_config - 1 > fit_uname_config_copy)
1981 fit_uname_config = fit_uname_config_copy;
1982 }
1983
1984 fdt_noffset = fit_image_load(images,
1985 addr, &fit_uname, &fit_uname_config,
1986 arch, IH_TYPE_FLATDT,
1987 BOOTSTAGE_ID_FIT_FDT_START,
1988 FIT_LOAD_OPTIONAL, &load, &len);
1989
1990 if (fdt_noffset < 0)
1991 goto out;
1992
1993 debug("fit_uname=%s, fit_uname_config=%s\n",
1994 fit_uname ? fit_uname : "<NULL>",
1995 fit_uname_config ? fit_uname_config : "<NULL>");
1996
1997 fit = map_sysmem(addr, 0);
1998
1999 cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
2000
2001
2002 count = fit_conf_get_prop_node_count(fit, cfg_noffset, FIT_FDT_PROP);
2003 if (count <= 1 && !next_config)
2004 goto out;
2005
2006
2007
2008#ifdef CONFIG_OF_LIBFDT_OVERLAY
2009 image_start = addr;
2010 image_end = addr + fit_get_size(fit);
2011
2012 if (load >= image_start && load < image_end) {
2013
2014 printf("Overlayed FDT requires relocation\n");
2015 fdt_noffset = -EBADF;
2016 goto out;
2017 }
2018
2019 base = map_sysmem(load, len);
2020
2021
2022 for (i = 1; ; i++) {
2023 if (i < count) {
2024 noffset = fit_conf_get_prop_node_index(fit, cfg_noffset,
2025 FIT_FDT_PROP, i);
2026 uname = fit_get_name(fit, noffset, NULL);
2027 uconfig = NULL;
2028 } else {
2029 if (!next_config)
2030 break;
2031 uconfig = next_config;
2032 next_config = strchr(next_config, '#');
2033 if (next_config)
2034 *next_config++ = '\0';
2035 uname = NULL;
2036 }
2037
2038 debug("%d: using uname=%s uconfig=%s\n", i, uname, uconfig);
2039
2040 ov_noffset = fit_image_load(images,
2041 addr, &uname, &uconfig,
2042 arch, IH_TYPE_FLATDT,
2043 BOOTSTAGE_ID_FIT_FDT_START,
2044 FIT_LOAD_REQUIRED, &ovload, &ovlen);
2045 if (ov_noffset < 0) {
2046 printf("load of %s failed\n", uname);
2047 continue;
2048 }
2049 debug("%s loaded at 0x%08lx len=0x%08lx\n",
2050 uname, ovload, ovlen);
2051 ov = map_sysmem(ovload, ovlen);
2052
2053 base = map_sysmem(load, len + ovlen);
2054 err = fdt_open_into(base, base, len + ovlen);
2055 if (err < 0) {
2056 printf("failed on fdt_open_into\n");
2057 fdt_noffset = err;
2058 goto out;
2059 }
2060
2061 err = fdt_overlay_apply_verbose(base, ov);
2062 if (err < 0) {
2063 fdt_noffset = err;
2064 goto out;
2065 }
2066 fdt_pack(base);
2067 len = fdt_totalsize(base);
2068 }
2069#else
2070 printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
2071 fdt_noffset = -EBADF;
2072#endif
2073
2074out:
2075 if (datap)
2076 *datap = load;
2077 if (lenp)
2078 *lenp = len;
2079 if (fit_unamep)
2080 *fit_unamep = fit_uname;
2081 if (fit_uname_configp)
2082 *fit_uname_configp = fit_uname_config;
2083
2084 if (fit_uname_config_copy)
2085 free(fit_uname_config_copy);
2086 return fdt_noffset;
2087}
2088#endif
2089