Commit 64dbbd40c58349b64f43fd33dbb5ca0adb67d642
1 parent
6679f92995
Exists in
master
and in
54 other branches
Moved fdt command support code to fdt_support.c
...in preparation for improving the bootm command's handling of fdt blobs. Also cleaned up some coding sloppiness.
Showing 7 changed files with 412 additions and 275 deletions Side-by-side Diff
board/mpc8360emds/mpc8360emds.c
... | ... | @@ -664,19 +664,28 @@ |
664 | 664 | |
665 | 665 | #if (defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)) \ |
666 | 666 | && defined(CONFIG_OF_BOARD_SETUP) |
667 | + | |
668 | +/* | |
669 | + * Prototypes of functions that we use. | |
670 | + */ | |
671 | +void ft_cpu_setup(void *blob, bd_t *bd); | |
672 | + | |
673 | +#ifdef CONFIG_PCI | |
674 | +void ft_pci_setup(void *blob, bd_t *bd); | |
675 | +#endif | |
676 | + | |
667 | 677 | void |
668 | 678 | ft_board_setup(void *blob, bd_t *bd) |
669 | 679 | { |
670 | 680 | #if defined(CONFIG_OF_LIBFDT) |
671 | 681 | int nodeoffset; |
672 | - int err; | |
673 | 682 | int tmp[2]; |
674 | 683 | |
675 | 684 | nodeoffset = fdt_path_offset (fdt, "/memory"); |
676 | 685 | if (nodeoffset >= 0) { |
677 | 686 | tmp[0] = cpu_to_be32(bd->bi_memstart); |
678 | 687 | tmp[1] = cpu_to_be32(bd->bi_memsize); |
679 | - err = fdt_setprop(fdt, nodeoffset, "reg", tmp, sizeof(tmp)); | |
688 | + fdt_setprop(fdt, nodeoffset, "reg", tmp, sizeof(tmp)); | |
680 | 689 | } |
681 | 690 | #else |
682 | 691 | u32 *p; |
... | ... | @@ -694,5 +703,5 @@ |
694 | 703 | #endif |
695 | 704 | ft_cpu_setup(blob, bd); |
696 | 705 | } |
697 | -#endif | |
706 | +#endif /* CONFIG_OF_x */ |
common/Makefile
... | ... | @@ -45,7 +45,7 @@ |
45 | 45 | env_nand.o env_dataflash.o env_flash.o env_eeprom.o \ |
46 | 46 | env_nvram.o env_nowhere.o \ |
47 | 47 | exports.o \ |
48 | - flash.o fpga.o ft_build.o \ | |
48 | + fdt_support.o flash.o fpga.o ft_build.o \ | |
49 | 49 | hush.o kgdb.o lcd.o lists.o lynxkdi.o \ |
50 | 50 | memsize.o miiphybb.o miiphyutil.o \ |
51 | 51 | s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \ |
common/cmd_bootm.c
... | ... | @@ -950,7 +950,7 @@ |
950 | 950 | |
951 | 951 | printf (" Loading Device Tree to %08lx, end %08lx ... ", |
952 | 952 | of_start, of_start + of_len - 1); |
953 | - err = fdt_open_into(of_start, of_data, of_len); | |
953 | + err = fdt_open_into((void *)of_start, (void *)of_data, of_len); | |
954 | 954 | if (err != 0) { |
955 | 955 | printf ("libfdt: %s\n", fdt_strerror(err)); |
956 | 956 | } |
common/cmd_fdt.c
... | ... | @@ -30,9 +30,11 @@ |
30 | 30 | #include <linux/types.h> |
31 | 31 | |
32 | 32 | #ifdef CONFIG_OF_LIBFDT |
33 | + | |
33 | 34 | #include <asm/global_data.h> |
34 | 35 | #include <fdt.h> |
35 | 36 | #include <libfdt.h> |
37 | +#include <fdt_support.h> | |
36 | 38 | |
37 | 39 | #define MAX_LEVEL 32 /* how deeply nested we will go */ |
38 | 40 | #define SCRATCHPAD 1024 /* bytes of scratchpad memory */ |
... | ... | @@ -53,9 +55,6 @@ |
53 | 55 | */ |
54 | 56 | static int fdt_valid(void); |
55 | 57 | static void print_data(const void *data, int len); |
56 | -static int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end); | |
57 | -static int fdt_env(void *fdt); | |
58 | -static int fdt_bd_t(void *fdt); | |
59 | 58 | |
60 | 59 | |
61 | 60 | /* |
... | ... | @@ -437,7 +436,7 @@ |
437 | 436 | * Create a chosen node |
438 | 437 | ********************************************************************/ |
439 | 438 | } else if (op == 'c') { |
440 | - fdt_chosen(fdt, 0, 0); | |
439 | + fdt_chosen(fdt, 0, 0, 1); | |
441 | 440 | |
442 | 441 | /******************************************************************** |
443 | 442 | * Create a u-boot-env node |
444 | 443 | |
445 | 444 | |
446 | 445 | |
... | ... | @@ -466,27 +465,38 @@ |
466 | 465 | |
467 | 466 | static int fdt_valid(void) |
468 | 467 | { |
468 | + int err; | |
469 | + | |
469 | 470 | if (fdt == NULL) { |
470 | - printf ("The address of the fdt is invalid.\n"); | |
471 | + printf ("The address of the fdt is invalid (NULL).\n"); | |
471 | 472 | return 0; |
472 | 473 | } |
473 | - if (!fdt || (fdt_magic(fdt) != FDT_MAGIC)) { | |
474 | - fdt = NULL; | |
475 | - printf ("Unrecognized fdt: bad magic\n"); | |
474 | + | |
475 | + err = fdt_check_header(fdt); | |
476 | + if (err == 0) | |
477 | + return 1; /* valid */ | |
478 | + | |
479 | + if (err < 0) { | |
480 | + printf("libfdt: %s", fdt_strerror(err)); | |
481 | + /* | |
482 | + * Be more informative on bad version. | |
483 | + */ | |
484 | + if (err == -FDT_ERR_BADVERSION) { | |
485 | + if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) { | |
486 | + printf (" - too old, fdt $d < %d", | |
487 | + fdt_version(fdt), FDT_FIRST_SUPPORTED_VERSION); | |
488 | + fdt = NULL; | |
489 | + } | |
490 | + if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) { | |
491 | + printf (" - too new, fdt $d > %d", | |
492 | + fdt_version(fdt), FDT_LAST_SUPPORTED_VERSION); | |
493 | + fdt = NULL; | |
494 | + } | |
495 | + return 0; | |
496 | + } | |
497 | + printf("\n"); | |
476 | 498 | return 0; |
477 | 499 | } |
478 | - if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) { | |
479 | - printf ("Unsupported fdt version: $d < %d\n", | |
480 | - FDT_FIRST_SUPPORTED_VERSION, fdt_version(fdt)); | |
481 | - fdt = NULL; | |
482 | - return 0; | |
483 | - } | |
484 | - if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) { | |
485 | - printf ("Unsupported fdt version: $d > %d\n", | |
486 | - fdt_version(fdt), FDT_LAST_SUPPORTED_VERSION); | |
487 | - fdt = NULL; | |
488 | - return 0; | |
489 | - } | |
490 | 500 | return 1; |
491 | 501 | } |
492 | 502 | |
... | ... | @@ -593,255 +603,6 @@ |
593 | 603 | |
594 | 604 | /********************************************************************/ |
595 | 605 | |
596 | -static int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end) | |
597 | -{ | |
598 | - bd_t *bd = gd->bd; | |
599 | - int nodeoffset; | |
600 | - int err; | |
601 | - u32 tmp; /* used to set 32 bit integer properties */ | |
602 | - char *str; /* used to set string properties */ | |
603 | - ulong clock; | |
604 | - | |
605 | - if (initrd_start && initrd_end) { | |
606 | - err = fdt_add_reservemap_entry(fdt, | |
607 | - initrd_start, initrd_end - initrd_start + 1); | |
608 | - if (err < 0) { | |
609 | - printf("libfdt: %s\n", fdt_strerror(err)); | |
610 | - return err; | |
611 | - } | |
612 | - } | |
613 | - | |
614 | - /* | |
615 | - * See if we already have a "chosen" node, create it if not. | |
616 | - */ | |
617 | - nodeoffset = fdt_path_offset (fdt, "/chosen"); | |
618 | - if (nodeoffset < 0) { | |
619 | - /* | |
620 | - * Create a new node "/chosen" (offset 0 is root level) | |
621 | - */ | |
622 | - nodeoffset = fdt_add_subnode(fdt, 0, "chosen"); | |
623 | - if (nodeoffset < 0) { | |
624 | - printf("libfdt: %s\n", fdt_strerror(nodeoffset)); | |
625 | - return nodeoffset; | |
626 | - } | |
627 | - } | |
628 | - | |
629 | - str = getenv("bootargs"); | |
630 | - if (str != NULL) { | |
631 | - err = fdt_setprop(fdt, nodeoffset, "bootargs", str, strlen(str)+1); | |
632 | - if (err < 0) | |
633 | - printf("libfdt: %s\n", fdt_strerror(err)); | |
634 | - } | |
635 | - if (initrd_start && initrd_end) { | |
636 | - tmp = __cpu_to_be32(initrd_start); | |
637 | - err = fdt_setprop(fdt, nodeoffset, "linux,initrd-start", &tmp, sizeof(tmp)); | |
638 | - if (err < 0) | |
639 | - printf("libfdt: %s\n", fdt_strerror(err)); | |
640 | - tmp = __cpu_to_be32(initrd_end); | |
641 | - err = fdt_setprop(fdt, nodeoffset, "linux,initrd-end", &tmp, sizeof(tmp)); | |
642 | - if (err < 0) | |
643 | - printf("libfdt: %s\n", fdt_strerror(err)); | |
644 | - } | |
645 | -#ifdef OF_STDOUT_PATH | |
646 | - err = fdt_setprop(fdt, nodeoffset, "linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1); | |
647 | - if (err < 0) | |
648 | - printf("libfdt: %s\n", fdt_strerror(err)); | |
649 | -#endif | |
650 | - | |
651 | - nodeoffset = fdt_path_offset (fdt, "/cpus"); | |
652 | - if (nodeoffset >= 0) { | |
653 | - clock = cpu_to_be32(bd->bi_intfreq); | |
654 | - err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4); | |
655 | - if (err < 0) | |
656 | - printf("libfdt: %s\n", fdt_strerror(err)); | |
657 | - } | |
658 | -#ifdef OF_TBCLK | |
659 | - nodeoffset = fdt_path_offset (fdt, "/cpus/" OF_CPU "/timebase-frequency"); | |
660 | - if (nodeoffset >= 0) { | |
661 | - clock = cpu_to_be32(OF_TBCLK); | |
662 | - err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4); | |
663 | - if (err < 0) | |
664 | - printf("libfdt: %s\n", fdt_strerror(err)); | |
665 | - } | |
666 | -#endif | |
667 | -} | |
668 | - | |
669 | -/********************************************************************/ | |
670 | - | |
671 | -#ifdef CONFIG_OF_HAS_BD_T | |
672 | - | |
673 | -/* Function that returns a character from the environment */ | |
674 | -extern uchar(*env_get_char) (int); | |
675 | - | |
676 | -#define BDM(x) { .name = #x, .offset = offsetof(bd_t, bi_ ##x ) } | |
677 | - | |
678 | -static const struct { | |
679 | - const char *name; | |
680 | - int offset; | |
681 | -} bd_map[] = { | |
682 | - BDM(memstart), | |
683 | - BDM(memsize), | |
684 | - BDM(flashstart), | |
685 | - BDM(flashsize), | |
686 | - BDM(flashoffset), | |
687 | - BDM(sramstart), | |
688 | - BDM(sramsize), | |
689 | -#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \ | |
690 | - || defined(CONFIG_E500) | |
691 | - BDM(immr_base), | |
692 | -#endif | |
693 | -#if defined(CONFIG_MPC5xxx) | |
694 | - BDM(mbar_base), | |
695 | -#endif | |
696 | -#if defined(CONFIG_MPC83XX) | |
697 | - BDM(immrbar), | |
698 | -#endif | |
699 | -#if defined(CONFIG_MPC8220) | |
700 | - BDM(mbar_base), | |
701 | - BDM(inpfreq), | |
702 | - BDM(pcifreq), | |
703 | - BDM(pevfreq), | |
704 | - BDM(flbfreq), | |
705 | - BDM(vcofreq), | |
706 | -#endif | |
707 | - BDM(bootflags), | |
708 | - BDM(ip_addr), | |
709 | - BDM(intfreq), | |
710 | - BDM(busfreq), | |
711 | -#ifdef CONFIG_CPM2 | |
712 | - BDM(cpmfreq), | |
713 | - BDM(brgfreq), | |
714 | - BDM(sccfreq), | |
715 | - BDM(vco), | |
716 | -#endif | |
717 | -#if defined(CONFIG_MPC5xxx) | |
718 | - BDM(ipbfreq), | |
719 | - BDM(pcifreq), | |
720 | -#endif | |
721 | - BDM(baudrate), | |
722 | -}; | |
723 | - | |
724 | -static int fdt_env(void *fdt) | |
725 | -{ | |
726 | - int nodeoffset; | |
727 | - int err; | |
728 | - int k, nxt; | |
729 | - int i; | |
730 | - static char tmpenv[256]; | |
731 | - | |
732 | - /* | |
733 | - * See if we already have a "u-boot-env" node, delete it if so. | |
734 | - * Then create a new empty node. | |
735 | - */ | |
736 | - nodeoffset = fdt_path_offset (fdt, "/u-boot-env"); | |
737 | - if (nodeoffset >= 0) { | |
738 | - err = fdt_del_node(fdt, nodeoffset); | |
739 | - if (err < 0) { | |
740 | - printf("libfdt: %s\n", fdt_strerror(err)); | |
741 | - return err; | |
742 | - } | |
743 | - } | |
744 | - /* | |
745 | - * Create a new node "/u-boot-env" (offset 0 is root level) | |
746 | - */ | |
747 | - nodeoffset = fdt_add_subnode(fdt, 0, "u-boot-env"); | |
748 | - if (nodeoffset < 0) { | |
749 | - printf("libfdt: %s\n", fdt_strerror(nodeoffset)); | |
750 | - return nodeoffset; | |
751 | - } | |
752 | - | |
753 | - for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { | |
754 | - char *s, *lval, *rval; | |
755 | - | |
756 | - /* | |
757 | - * Find the end of the name=definition | |
758 | - */ | |
759 | - for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) | |
760 | - ; | |
761 | - s = tmpenv; | |
762 | - for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k) | |
763 | - *s++ = env_get_char(k); | |
764 | - *s++ = '\0'; | |
765 | - lval = tmpenv; | |
766 | - /* | |
767 | - * Find the first '=': it separates the name from the value | |
768 | - */ | |
769 | - s = strchr(tmpenv, '='); | |
770 | - if (s != NULL) { | |
771 | - *s++ = '\0'; | |
772 | - rval = s; | |
773 | - } else | |
774 | - continue; | |
775 | - err = fdt_setprop(fdt, nodeoffset, lval, rval, strlen(rval)+1); | |
776 | - if (err < 0) { | |
777 | - printf("\"%s\" - libfdt: %s\n", lval, fdt_strerror(err)); | |
778 | - return err; | |
779 | - } | |
780 | - } | |
781 | - return 0; | |
782 | -} | |
783 | -#endif /* CONFIG_OF_HAS_UBOOT_ENV */ | |
784 | - | |
785 | -/********************************************************************/ | |
786 | - | |
787 | -#ifdef CONFIG_OF_HAS_BD_T | |
788 | -static int fdt_bd_t(void *fdt) | |
789 | -{ | |
790 | - bd_t *bd = gd->bd; | |
791 | - int nodeoffset; | |
792 | - int err; | |
793 | - u32 tmp; /* used to set 32 bit integer properties */ | |
794 | - int i; | |
795 | - | |
796 | - /* | |
797 | - * See if we already have a "bd_t" node, delete it if so. | |
798 | - * Then create a new empty node. | |
799 | - */ | |
800 | - nodeoffset = fdt_path_offset (fdt, "/bd_t"); | |
801 | - if (nodeoffset >= 0) { | |
802 | - err = fdt_del_node(fdt, nodeoffset); | |
803 | - if (err < 0) { | |
804 | - printf("libfdt: %s\n", fdt_strerror(err)); | |
805 | - return err; | |
806 | - } | |
807 | - } | |
808 | - /* | |
809 | - * Create a new node "/bd_t" (offset 0 is root level) | |
810 | - */ | |
811 | - nodeoffset = fdt_add_subnode(fdt, 0, "bd_t"); | |
812 | - if (nodeoffset < 0) { | |
813 | - printf("libfdt: %s\n", fdt_strerror(nodeoffset)); | |
814 | - return nodeoffset; | |
815 | - } | |
816 | - /* | |
817 | - * Use the string/pointer structure to create the entries... | |
818 | - */ | |
819 | - for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) { | |
820 | - tmp = cpu_to_be32(getenv("bootargs")); | |
821 | - err = fdt_setprop(fdt, nodeoffset, bd_map[i].name, &tmp, sizeof(tmp)); | |
822 | - if (err < 0) | |
823 | - printf("libfdt: %s\n", fdt_strerror(err)); | |
824 | - } | |
825 | - /* | |
826 | - * Add a couple of oddball entries... | |
827 | - */ | |
828 | - err = fdt_setprop(fdt, nodeoffset, "enetaddr", &bd->bi_enetaddr, 6); | |
829 | - if (err < 0) | |
830 | - printf("libfdt: %s\n", fdt_strerror(err)); | |
831 | - err = fdt_setprop(fdt, nodeoffset, "ethspeed", &bd->bi_ethspeed, 4); | |
832 | - if (err < 0) | |
833 | - printf("libfdt: %s\n", fdt_strerror(err)); | |
834 | - | |
835 | -#ifdef CONFIG_OF_BOARD_SETUP | |
836 | - ft_board_setup(fdt, bd); | |
837 | -#endif | |
838 | - | |
839 | - return 0; | |
840 | -} | |
841 | -#endif /* CONFIG_OF_HAS_BD_T */ | |
842 | - | |
843 | -/********************************************************************/ | |
844 | - | |
845 | 606 | U_BOOT_CMD( |
846 | 607 | fdt, 5, 0, do_fdt, |
847 | 608 | "fdt - flattened device tree utility commands\n", |
... | ... | @@ -871,5 +632,5 @@ |
871 | 632 | " fdt set /cpus \"#address-cells\" \"[00 00 00 01]\"\n" |
872 | 633 | ); |
873 | 634 | |
874 | -#endif /* CONFIG_OF_FLAT_TREE */ | |
635 | +#endif /* CONFIG_OF_LIBFDT */ |
common/fdt_support.c
1 | +/* | |
2 | + * (C) Copyright 2007 | |
3 | + * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com | |
4 | + * | |
5 | + * See file CREDITS for list of people who contributed to this | |
6 | + * project. | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or | |
9 | + * modify it under the terms of the GNU General Public License as | |
10 | + * published by the Free Software Foundation; either version 2 of | |
11 | + * the License, or (at your option) any later version. | |
12 | + * | |
13 | + * This program is distributed in the hope that it will be useful, | |
14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | + * GNU General Public License for more details. | |
17 | + * | |
18 | + * You should have received a copy of the GNU General Public License | |
19 | + * along with this program; if not, write to the Free Software | |
20 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | + * MA 02111-1307 USA | |
22 | + */ | |
23 | + | |
24 | +#include <common.h> | |
25 | +#include <linux/ctype.h> | |
26 | +#include <linux/types.h> | |
27 | + | |
28 | +#ifdef CONFIG_OF_LIBFDT | |
29 | + | |
30 | +#include <asm/global_data.h> | |
31 | +#include <fdt.h> | |
32 | +#include <libfdt.h> | |
33 | +#include <fdt_support.h> | |
34 | + | |
35 | +/* | |
36 | + * Global data (for the gd->bd) | |
37 | + */ | |
38 | +DECLARE_GLOBAL_DATA_PTR; | |
39 | + | |
40 | + | |
41 | +/********************************************************************/ | |
42 | + | |
43 | +int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force) | |
44 | +{ | |
45 | + bd_t *bd = gd->bd; | |
46 | + int nodeoffset; | |
47 | + int err; | |
48 | + u32 tmp; /* used to set 32 bit integer properties */ | |
49 | + char *str; /* used to set string properties */ | |
50 | + ulong clock; | |
51 | + | |
52 | + err = fdt_check_header(fdt); | |
53 | + if (err < 0) { | |
54 | + printf("libfdt: %s\n", fdt_strerror(err)); | |
55 | + return err; | |
56 | + } | |
57 | + | |
58 | +#warning "Don't double-add the reserved map" | |
59 | + if (initrd_start && initrd_end) { | |
60 | + err = fdt_add_reservemap_entry(fdt, | |
61 | + initrd_start, initrd_end - initrd_start + 1); | |
62 | + if (err < 0) { | |
63 | + printf("libfdt: %s\n", fdt_strerror(err)); | |
64 | + return err; | |
65 | + } | |
66 | + } | |
67 | + | |
68 | + /* | |
69 | + * Find the "chosen" node. | |
70 | + */ | |
71 | + nodeoffset = fdt_path_offset (fdt, "/chosen"); | |
72 | + | |
73 | + /* | |
74 | + * If we have a "chosen" node already the "force the writing" | |
75 | + * is not set, our job is done. | |
76 | + */ | |
77 | + if ((nodeoffset >= 0) && !force) | |
78 | + return 0; | |
79 | + | |
80 | + /* | |
81 | + * No "chosen" node in the blob: create it. | |
82 | + */ | |
83 | + if (nodeoffset < 0) { | |
84 | + /* | |
85 | + * Create a new node "/chosen" (offset 0 is root level) | |
86 | + */ | |
87 | + nodeoffset = fdt_add_subnode(fdt, 0, "chosen"); | |
88 | + if (nodeoffset < 0) { | |
89 | + printf("libfdt: %s\n", fdt_strerror(nodeoffset)); | |
90 | + return nodeoffset; | |
91 | + } | |
92 | + } | |
93 | + | |
94 | + /* | |
95 | + * Update pre-existing properties, create them if non-existant. | |
96 | + */ | |
97 | + str = getenv("bootargs"); | |
98 | + if (str != NULL) { | |
99 | + err = fdt_setprop(fdt, nodeoffset, "bootargs", str, strlen(str)+1); | |
100 | + if (err < 0) | |
101 | + printf("libfdt: %s\n", fdt_strerror(err)); | |
102 | + } | |
103 | + if (initrd_start && initrd_end) { | |
104 | + tmp = __cpu_to_be32(initrd_start); | |
105 | + err = fdt_setprop(fdt, nodeoffset, "linux,initrd-start", &tmp, sizeof(tmp)); | |
106 | + if (err < 0) | |
107 | + printf("libfdt: %s\n", fdt_strerror(err)); | |
108 | + tmp = __cpu_to_be32(initrd_end); | |
109 | + err = fdt_setprop(fdt, nodeoffset, "linux,initrd-end", &tmp, sizeof(tmp)); | |
110 | + if (err < 0) | |
111 | + printf("libfdt: %s\n", fdt_strerror(err)); | |
112 | + } | |
113 | +#ifdef OF_STDOUT_PATH | |
114 | + err = fdt_setprop(fdt, nodeoffset, "linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1); | |
115 | + if (err < 0) | |
116 | + printf("libfdt: %s\n", fdt_strerror(err)); | |
117 | +#endif | |
118 | + | |
119 | + nodeoffset = fdt_path_offset (fdt, "/cpus"); | |
120 | + if (nodeoffset >= 0) { | |
121 | + clock = cpu_to_be32(bd->bi_intfreq); | |
122 | + err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4); | |
123 | + if (err < 0) | |
124 | + printf("libfdt: %s\n", fdt_strerror(err)); | |
125 | + } | |
126 | +#ifdef OF_TBCLK | |
127 | + nodeoffset = fdt_path_offset (fdt, "/cpus/" OF_CPU "/timebase-frequency"); | |
128 | + if (nodeoffset >= 0) { | |
129 | + clock = cpu_to_be32(OF_TBCLK); | |
130 | + err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4); | |
131 | + if (err < 0) | |
132 | + printf("libfdt: %s\n", fdt_strerror(err)); | |
133 | + } | |
134 | +#endif | |
135 | + return err; | |
136 | +} | |
137 | + | |
138 | +/********************************************************************/ | |
139 | + | |
140 | +#ifdef CONFIG_OF_HAS_UBOOT_ENV | |
141 | + | |
142 | +/* Function that returns a character from the environment */ | |
143 | +extern uchar(*env_get_char) (int); | |
144 | + | |
145 | + | |
146 | +int fdt_env(void *fdt) | |
147 | +{ | |
148 | + int nodeoffset; | |
149 | + int err; | |
150 | + int k, nxt; | |
151 | + int i; | |
152 | + static char tmpenv[256]; | |
153 | + | |
154 | + err = fdt_check_header(fdt); | |
155 | + if (err < 0) { | |
156 | + printf("libfdt: %s\n", fdt_strerror(err)); | |
157 | + return err; | |
158 | + } | |
159 | + | |
160 | + /* | |
161 | + * See if we already have a "u-boot-env" node, delete it if so. | |
162 | + * Then create a new empty node. | |
163 | + */ | |
164 | + nodeoffset = fdt_path_offset (fdt, "/u-boot-env"); | |
165 | + if (nodeoffset >= 0) { | |
166 | + err = fdt_del_node(fdt, nodeoffset); | |
167 | + if (err < 0) { | |
168 | + printf("libfdt: %s\n", fdt_strerror(err)); | |
169 | + return err; | |
170 | + } | |
171 | + } | |
172 | + /* | |
173 | + * Create a new node "/u-boot-env" (offset 0 is root level) | |
174 | + */ | |
175 | + nodeoffset = fdt_add_subnode(fdt, 0, "u-boot-env"); | |
176 | + if (nodeoffset < 0) { | |
177 | + printf("libfdt: %s\n", fdt_strerror(nodeoffset)); | |
178 | + return nodeoffset; | |
179 | + } | |
180 | + | |
181 | + for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { | |
182 | + char *s, *lval, *rval; | |
183 | + | |
184 | + /* | |
185 | + * Find the end of the name=definition | |
186 | + */ | |
187 | + for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) | |
188 | + ; | |
189 | + s = tmpenv; | |
190 | + for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k) | |
191 | + *s++ = env_get_char(k); | |
192 | + *s++ = '\0'; | |
193 | + lval = tmpenv; | |
194 | + /* | |
195 | + * Find the first '=': it separates the name from the value | |
196 | + */ | |
197 | + s = strchr(tmpenv, '='); | |
198 | + if (s != NULL) { | |
199 | + *s++ = '\0'; | |
200 | + rval = s; | |
201 | + } else | |
202 | + continue; | |
203 | + err = fdt_setprop(fdt, nodeoffset, lval, rval, strlen(rval)+1); | |
204 | + if (err < 0) { | |
205 | + printf("libfdt: %s\n", lval, fdt_strerror(err)); | |
206 | + return err; | |
207 | + } | |
208 | + } | |
209 | + return 0; | |
210 | +} | |
211 | +#endif /* CONFIG_OF_HAS_UBOOT_ENV */ | |
212 | + | |
213 | +/********************************************************************/ | |
214 | + | |
215 | +#ifdef CONFIG_OF_HAS_BD_T | |
216 | + | |
217 | +#define BDM(x) { .name = #x, .offset = offsetof(bd_t, bi_ ##x ) } | |
218 | + | |
219 | +static const struct { | |
220 | + const char *name; | |
221 | + int offset; | |
222 | +} bd_map[] = { | |
223 | + BDM(memstart), | |
224 | + BDM(memsize), | |
225 | + BDM(flashstart), | |
226 | + BDM(flashsize), | |
227 | + BDM(flashoffset), | |
228 | + BDM(sramstart), | |
229 | + BDM(sramsize), | |
230 | +#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \ | |
231 | + || defined(CONFIG_E500) | |
232 | + BDM(immr_base), | |
233 | +#endif | |
234 | +#if defined(CONFIG_MPC5xxx) | |
235 | + BDM(mbar_base), | |
236 | +#endif | |
237 | +#if defined(CONFIG_MPC83XX) | |
238 | + BDM(immrbar), | |
239 | +#endif | |
240 | +#if defined(CONFIG_MPC8220) | |
241 | + BDM(mbar_base), | |
242 | + BDM(inpfreq), | |
243 | + BDM(pcifreq), | |
244 | + BDM(pevfreq), | |
245 | + BDM(flbfreq), | |
246 | + BDM(vcofreq), | |
247 | +#endif | |
248 | + BDM(bootflags), | |
249 | + BDM(ip_addr), | |
250 | + BDM(intfreq), | |
251 | + BDM(busfreq), | |
252 | +#ifdef CONFIG_CPM2 | |
253 | + BDM(cpmfreq), | |
254 | + BDM(brgfreq), | |
255 | + BDM(sccfreq), | |
256 | + BDM(vco), | |
257 | +#endif | |
258 | +#if defined(CONFIG_MPC5xxx) | |
259 | + BDM(ipbfreq), | |
260 | + BDM(pcifreq), | |
261 | +#endif | |
262 | + BDM(baudrate), | |
263 | +}; | |
264 | + | |
265 | + | |
266 | +int fdt_bd_t(void *fdt) | |
267 | +{ | |
268 | + bd_t *bd = gd->bd; | |
269 | + int nodeoffset; | |
270 | + int err; | |
271 | + u32 tmp; /* used to set 32 bit integer properties */ | |
272 | + int i; | |
273 | + | |
274 | + err = fdt_check_header(fdt); | |
275 | + if (err < 0) { | |
276 | + printf("libfdt: %s\n", fdt_strerror(err)); | |
277 | + return err; | |
278 | + } | |
279 | + | |
280 | + /* | |
281 | + * See if we already have a "bd_t" node, delete it if so. | |
282 | + * Then create a new empty node. | |
283 | + */ | |
284 | + nodeoffset = fdt_path_offset (fdt, "/bd_t"); | |
285 | + if (nodeoffset >= 0) { | |
286 | + err = fdt_del_node(fdt, nodeoffset); | |
287 | + if (err < 0) { | |
288 | + printf("libfdt: %s\n", fdt_strerror(err)); | |
289 | + return err; | |
290 | + } | |
291 | + } | |
292 | + /* | |
293 | + * Create a new node "/bd_t" (offset 0 is root level) | |
294 | + */ | |
295 | + nodeoffset = fdt_add_subnode(fdt, 0, "bd_t"); | |
296 | + if (nodeoffset < 0) { | |
297 | + printf("libfdt: %s\n", fdt_strerror(nodeoffset)); | |
298 | + return nodeoffset; | |
299 | + } | |
300 | + /* | |
301 | + * Use the string/pointer structure to create the entries... | |
302 | + */ | |
303 | + for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) { | |
304 | + tmp = cpu_to_be32(getenv("bootargs")); | |
305 | + err = fdt_setprop(fdt, nodeoffset, bd_map[i].name, &tmp, sizeof(tmp)); | |
306 | + if (err < 0) | |
307 | + printf("libfdt: %s\n", fdt_strerror(err)); | |
308 | + } | |
309 | + /* | |
310 | + * Add a couple of oddball entries... | |
311 | + */ | |
312 | + err = fdt_setprop(fdt, nodeoffset, "enetaddr", &bd->bi_enetaddr, 6); | |
313 | + if (err < 0) | |
314 | + printf("libfdt: %s\n", fdt_strerror(err)); | |
315 | + err = fdt_setprop(fdt, nodeoffset, "ethspeed", &bd->bi_ethspeed, 4); | |
316 | + if (err < 0) | |
317 | + printf("libfdt: %s\n", fdt_strerror(err)); | |
318 | + | |
319 | + return 0; | |
320 | +} | |
321 | +#endif /* CONFIG_OF_HAS_BD_T */ | |
322 | + | |
323 | +#endif /* CONFIG_OF_LIBFDT */ |
cpu/mpc83xx/cpu.c
... | ... | @@ -364,6 +364,7 @@ |
364 | 364 | /* |
365 | 365 | * If unconditional create or the property already exists... |
366 | 366 | */ |
367 | + err = 0; | |
367 | 368 | if ((fixup_props[j].createflags & FT_CREATE) || |
368 | 369 | (fdt_get_property(fdt, nodeoffset, fixup_props[j].prop, 0))) { |
369 | 370 | if (fixup_props[j].createflags & FT_BUSFREQ) { |
include/fdt_support.h
1 | +/* | |
2 | + * (C) Copyright 2007 | |
3 | + * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com | |
4 | + * | |
5 | + * See file CREDITS for list of people who contributed to this | |
6 | + * project. | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or | |
9 | + * modify it under the terms of the GNU General Public License as | |
10 | + * published by the Free Software Foundation; either version 2 of | |
11 | + * the License, or (at your option) any later version. | |
12 | + * | |
13 | + * This program is distributed in the hope that it will be useful, | |
14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | + * GNU General Public License for more details. | |
17 | + * | |
18 | + * You should have received a copy of the GNU General Public License | |
19 | + * along with this program; if not, write to the Free Software | |
20 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | + * MA 02111-1307 USA | |
22 | + */ | |
23 | + | |
24 | +#ifndef __FDT_SUPPORT_H | |
25 | +#define __FDT_SUPPORT_H | |
26 | + | |
27 | +#ifdef CONFIG_OF_LIBFDT | |
28 | + | |
29 | +#include <fdt.h> | |
30 | + | |
31 | +int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force); | |
32 | + | |
33 | +#ifdef CONFIG_OF_HAS_UBOOT_ENV | |
34 | +int fdt_env(void *fdt); | |
35 | +#endif | |
36 | + | |
37 | +#ifdef CONFIG_OF_HAS_BD_T | |
38 | +int fdt_bd_t(void *fdt); | |
39 | +#endif | |
40 | + | |
41 | +#endif /* ifdef CONFIG_OF_LIBFDT */ | |
42 | +#endif /* ifndef __FDT_SUPPORT_H */ |