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