Merge with /home/wd/git/u-boot/custodian/u-boot-fdt
authorWolfgang Denk <wd@denx.de>
Wed, 18 Apr 2007 15:47:39 +0000 (17:47 +0200)
committerWolfgang Denk <wd@denx.de>
Wed, 18 Apr 2007 15:47:39 +0000 (17:47 +0200)
14 files changed:
board/mpc8360emds/mpc8360emds.c
common/Makefile
common/cmd_bootm.c
common/cmd_fdt.c
common/fdt_support.c [new file with mode: 0644]
cpu/mpc83xx/cpu.c
include/fdt.h
include/fdt_support.h [new file with mode: 0644]
include/libfdt.h
include/libfdt_env.h
libfdt/fdt.c
libfdt/fdt_ro.c
libfdt/fdt_rw.c
libfdt/fdt_wip.c

index deadb5ffbe2456ee4f9b0f9cb973ffb772d43eaa..5cabe47084d3be5dd57525b6b7e30b6aa0e10e3f 100644 (file)
@@ -664,19 +664,28 @@ U_BOOT_CMD(ecc, 4, 0, do_ecc,
 
 #if (defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)) \
      && defined(CONFIG_OF_BOARD_SETUP)
+
+/*
+ * Prototypes of functions that we use.
+ */
+void ft_cpu_setup(void *blob, bd_t *bd);
+
+#ifdef CONFIG_PCI
+void ft_pci_setup(void *blob, bd_t *bd);
+#endif
+
 void
 ft_board_setup(void *blob, bd_t *bd)
 {
 #if defined(CONFIG_OF_LIBFDT)
        int nodeoffset;
-       int err;
        int tmp[2];
 
        nodeoffset = fdt_path_offset (fdt, "/memory");
        if (nodeoffset >= 0) {
                tmp[0] = cpu_to_be32(bd->bi_memstart);
                tmp[1] = cpu_to_be32(bd->bi_memsize);
-               err = fdt_setprop(fdt, nodeoffset, "reg", tmp, sizeof(tmp));
+               fdt_setprop(fdt, nodeoffset, "reg", tmp, sizeof(tmp));
        }
 #else
        u32 *p;
@@ -694,4 +703,5 @@ ft_board_setup(void *blob, bd_t *bd)
 #endif
        ft_cpu_setup(blob, bd);
 }
-#endif
+#endif /* CONFIG_OF_x */
+
index 74a6af204e535de7580eeee46227b641f6d1f05e..5dfd3a84a2492339fc810d1714edf4b9a452d052 100644 (file)
@@ -45,7 +45,7 @@ COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o cmd_autoscript.o \
          env_nand.o env_dataflash.o env_flash.o env_eeprom.o \
          env_nvram.o env_nowhere.o \
          exports.o \
-         flash.o fpga.o ft_build.o \
+         fdt_support.o flash.o fpga.o ft_build.o \
          hush.o kgdb.o lcd.o lists.o lynxkdi.o \
          memsize.o miiphybb.o miiphyutil.o \
          s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \
index 2721216bf35eba2418efa60874703c7214eb3e05..32c29e55a37bc829d16226590d94f63adc934ef0 100644 (file)
@@ -37,6 +37,7 @@
 #if defined(CONFIG_OF_LIBFDT)
 #include <fdt.h>
 #include <libfdt.h>
+#include <fdt_support.h>
 #endif
 #if defined(CONFIG_OF_FLAT_TREE)
 #include <ft_build.h>
@@ -748,7 +749,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
                of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16);
                hdr = (image_header_t *)of_flat_tree;
 #if defined(CONFIG_OF_LIBFDT)
-               if (be32_to_cpu(fdt_magic(of_flat_tree)) == FDT_MAGIC) {
+               if (fdt_check_header(of_flat_tree) == 0) {
 #else
                if (*(ulong *)of_flat_tree == OF_DT_HEADER) {
 #endif
@@ -795,7 +796,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
                                return;
                        }
 #if defined(CONFIG_OF_LIBFDT)
-                       if (be32_to_cpu(fdt_magic(of_flat_tree + sizeof(image_header_t))) != FDT_MAGIC) {
+                       if (fdt_check_header(of_flat_tree + sizeof(image_header_t)) == 0) {
 #else
                        if (*((ulong *)(of_flat_tree + sizeof(image_header_t))) != OF_DT_HEADER) {
 #endif
@@ -836,7 +837,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
                }
 
 #if defined(CONFIG_OF_LIBFDT)
-               if (be32_to_cpu(fdt_magic(of_data)) != FDT_MAGIC) {
+               if (fdt_check_header((void *)of_data) != 0) {
 #else
                if (((struct boot_param_header *)of_data)->magic != OF_DT_HEADER) {
 #endif
@@ -937,23 +938,44 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
        if (of_data) {
                int err;
                ulong of_start, of_len;
+
                of_len = be32_to_cpu(fdt_totalsize(of_data));
-               /* provide extra 8k pad */
+               /* position on a 4K boundary before the initrd/kbd */
                if (initrd_start)
-                       of_start = initrd_start - of_len - 8192;
+                       of_start = initrd_start - of_len;
                else
-                       of_start  = (ulong)kbd - of_len - 8192;
+                       of_start  = (ulong)kbd - of_len;
                of_start &= ~(4096 - 1);        /* align on page */
                debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
                        of_data, of_data + of_len - 1, of_len, of_len);
 
-
+               of_flat_tree = (char *)of_start;
                printf ("   Loading Device Tree to %08lx, end %08lx ... ",
                        of_start, of_start + of_len - 1);
-               err = fdt_open_into(of_start, of_data, of_len);
+               err = fdt_open_into((void *)of_start, (void *)of_data, of_len);
                if (err != 0) {
-                       printf ("libfdt: %s\n", fdt_strerror(err));
+                       printf ("libfdt: %s " __FILE__ " %d\n", fdt_strerror(err), __LINE__);
                }
+               /*
+                * Add the chosen node if it doesn't exist, add the env and bd_t
+                * if the user wants it (the logic is in the subroutines).
+                */
+               if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) {
+                               printf("Failed creating the /chosen node (0x%08X), aborting.\n", of_flat_tree);
+                               return;
+               }
+#ifdef CONFIG_OF_HAS_UBOOT_ENV
+               if (fdt_env(of_flat_tree) < 0) {
+                               printf("Failed creating the /u-boot-env node, aborting.\n");
+                               return;
+               }
+#endif
+#ifdef CONFIG_OF_HAS_BD_T
+               if (fdt_bd_t(of_flat_tree) < 0) {
+                               printf("Failed creating the /bd_t node, aborting.\n");
+                               return;
+               }
+#endif
        }
 #endif
 #if defined(CONFIG_OF_FLAT_TREE)
@@ -1004,6 +1026,24 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
        ft_setup(of_flat_tree, kbd, initrd_start, initrd_end);
        /* ft_dump_blob(of_flat_tree); */
 #endif
+#if defined(CONFIG_OF_LIBFDT)
+       if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) {
+               printf("Failed creating the /chosen node (0x%08X), aborting.\n", of_flat_tree);
+               return;
+       }
+#ifdef CONFIG_OF_HAS_UBOOT_ENV
+       if (fdt_env(of_flat_tree) < 0) {
+               printf("Failed creating the /u-boot-env node, aborting.\n");
+               return;
+       }
+#endif
+#ifdef CONFIG_OF_HAS_BD_T
+       if (fdt_bd_t(of_flat_tree) < 0) {
+               printf("Failed creating the /bd_t node, aborting.\n");
+               return;
+       }
+#endif
+#endif /* if defined(CONFIG_OF_LIBFDT) */
 
        (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);
 #endif
index 968bade626d6be43640e84460fe68acdf4f157b5..08fe3512d4fe6ff8f3a95c328413c4f352d8f4ae 100644 (file)
 #include <linux/types.h>
 
 #ifdef CONFIG_OF_LIBFDT
+
 #include <asm/global_data.h>
 #include <fdt.h>
 #include <libfdt.h>
+#include <fdt_support.h>
 
 #define MAX_LEVEL      32              /* how deeply nested we will go */
 #define SCRATCHPAD     1024    /* bytes of scratchpad memory */
@@ -53,9 +55,6 @@ static char data[SCRATCHPAD];
  */
 static int fdt_valid(void);
 static void print_data(const void *data, int len);
-static int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end);
-static int fdt_env(void *fdt);
-static int fdt_bd_t(void *fdt);
 
 
 /*
@@ -437,7 +436,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
         * Create a chosen node
         ********************************************************************/
        } else if (op == 'c') {
-               fdt_chosen(fdt, 0, 0);
+               fdt_chosen(fdt, 0, 0, 1);
 
        /********************************************************************
         * Create a u-boot-env node
@@ -466,25 +465,36 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 
 static int fdt_valid(void)
 {
+       int  err;
+
        if (fdt == NULL) {
-               printf ("The address of the fdt is invalid.\n");
-               return 0;
-       }
-       if (!fdt || (fdt_magic(fdt) != FDT_MAGIC)) {
-               fdt = NULL;
-               printf ("Unrecognized fdt: bad magic\n");
-               return 0;
-       }
-       if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) {
-               printf ("Unsupported fdt version: $d < %d\n",
-                       FDT_FIRST_SUPPORTED_VERSION, fdt_version(fdt));
-               fdt = NULL;
+               printf ("The address of the fdt is invalid (NULL).\n");
                return 0;
        }
-       if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) {
-               printf ("Unsupported fdt version: $d > %d\n",
-                       fdt_version(fdt), FDT_LAST_SUPPORTED_VERSION);
-               fdt = NULL;
+
+       err = fdt_check_header(fdt);
+       if (err == 0)
+               return 1;       /* valid */
+
+       if (err < 0) {
+               printf("libfdt: %s", fdt_strerror(err));
+               /*
+                * Be more informative on bad version.
+                */
+               if (err == -FDT_ERR_BADVERSION) {
+                       if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) {
+                               printf (" - too old, fdt $d < %d",
+                                       fdt_version(fdt), FDT_FIRST_SUPPORTED_VERSION);
+                               fdt = NULL;
+                       }
+                       if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) {
+                               printf (" - too new, fdt $d > %d",
+                                       fdt_version(fdt), FDT_LAST_SUPPORTED_VERSION);
+                               fdt = NULL;
+                       }
+                       return 0;
+               }
+               printf("\n");
                return 0;
        }
        return 1;
@@ -593,255 +603,6 @@ static void print_data(const void *data, int len)
 
 /********************************************************************/
 
-static int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end)
-{
-       bd_t *bd = gd->bd;
-       int   nodeoffset;
-       int   err;
-       u32   tmp;                      /* used to set 32 bit integer properties */
-       char  *str;                     /* used to set string properties */
-       ulong clock;
-
-       if (initrd_start && initrd_end) {
-               err = fdt_add_reservemap_entry(fdt,
-                       initrd_start, initrd_end - initrd_start + 1);
-               if (err < 0) {
-                       printf("libfdt: %s\n", fdt_strerror(err));
-                       return err;
-               }
-       }
-
-       /*
-        * See if we already have a "chosen" node, create it if not.
-        */
-       nodeoffset = fdt_path_offset (fdt, "/chosen");
-       if (nodeoffset < 0) {
-               /*
-                * Create a new node "/chosen" (offset 0 is root level)
-                */
-               nodeoffset = fdt_add_subnode(fdt, 0, "chosen");
-               if (nodeoffset < 0) {
-                       printf("libfdt: %s\n", fdt_strerror(nodeoffset));
-                       return nodeoffset;
-               }
-       }
-
-       str = getenv("bootargs");
-       if (str != NULL) {
-               err = fdt_setprop(fdt, nodeoffset, "bootargs", str, strlen(str)+1);
-               if (err < 0)
-                       printf("libfdt: %s\n", fdt_strerror(err));
-       }
-       if (initrd_start && initrd_end) {
-               tmp = __cpu_to_be32(initrd_start);
-               err = fdt_setprop(fdt, nodeoffset, "linux,initrd-start", &tmp, sizeof(tmp));
-               if (err < 0)
-                       printf("libfdt: %s\n", fdt_strerror(err));
-               tmp = __cpu_to_be32(initrd_end);
-               err = fdt_setprop(fdt, nodeoffset, "linux,initrd-end", &tmp, sizeof(tmp));
-               if (err < 0)
-                       printf("libfdt: %s\n", fdt_strerror(err));
-       }
-#ifdef OF_STDOUT_PATH
-       err = fdt_setprop(fdt, nodeoffset, "linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1);
-       if (err < 0)
-               printf("libfdt: %s\n", fdt_strerror(err));
-#endif
-
-       nodeoffset = fdt_path_offset (fdt, "/cpus");
-       if (nodeoffset >= 0) {
-               clock = cpu_to_be32(bd->bi_intfreq);
-               err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4);
-               if (err < 0)
-                       printf("libfdt: %s\n", fdt_strerror(err));
-       }
-#ifdef OF_TBCLK
-       nodeoffset = fdt_path_offset (fdt, "/cpus/" OF_CPU "/timebase-frequency");
-       if (nodeoffset >= 0) {
-               clock = cpu_to_be32(OF_TBCLK);
-               err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4);
-               if (err < 0)
-                       printf("libfdt: %s\n", fdt_strerror(err));
-       }
-#endif
-}
-
-/********************************************************************/
-
-#ifdef CONFIG_OF_HAS_BD_T
-
-/* Function that returns a character from the environment */
-extern uchar(*env_get_char) (int);
-
-#define BDM(x) {       .name = #x, .offset = offsetof(bd_t, bi_ ##x ) }
-
-static const struct {
-       const char *name;
-       int offset;
-} bd_map[] = {
-       BDM(memstart),
-       BDM(memsize),
-       BDM(flashstart),
-       BDM(flashsize),
-       BDM(flashoffset),
-       BDM(sramstart),
-       BDM(sramsize),
-#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \
-       || defined(CONFIG_E500)
-       BDM(immr_base),
-#endif
-#if defined(CONFIG_MPC5xxx)
-       BDM(mbar_base),
-#endif
-#if defined(CONFIG_MPC83XX)
-       BDM(immrbar),
-#endif
-#if defined(CONFIG_MPC8220)
-       BDM(mbar_base),
-       BDM(inpfreq),
-       BDM(pcifreq),
-       BDM(pevfreq),
-       BDM(flbfreq),
-       BDM(vcofreq),
-#endif
-       BDM(bootflags),
-       BDM(ip_addr),
-       BDM(intfreq),
-       BDM(busfreq),
-#ifdef CONFIG_CPM2
-       BDM(cpmfreq),
-       BDM(brgfreq),
-       BDM(sccfreq),
-       BDM(vco),
-#endif
-#if defined(CONFIG_MPC5xxx)
-       BDM(ipbfreq),
-       BDM(pcifreq),
-#endif
-       BDM(baudrate),
-};
-
-static int fdt_env(void *fdt)
-{
-       int   nodeoffset;
-       int   err;
-       int   k, nxt;
-       int i;
-       static char tmpenv[256];
-
-       /*
-        * See if we already have a "u-boot-env" node, delete it if so.
-        * Then create a new empty node.
-        */
-       nodeoffset = fdt_path_offset (fdt, "/u-boot-env");
-       if (nodeoffset >= 0) {
-               err = fdt_del_node(fdt, nodeoffset);
-               if (err < 0) {
-                       printf("libfdt: %s\n", fdt_strerror(err));
-                       return err;
-               }
-       }
-       /*
-        * Create a new node "/u-boot-env" (offset 0 is root level)
-        */
-       nodeoffset = fdt_add_subnode(fdt, 0, "u-boot-env");
-       if (nodeoffset < 0) {
-               printf("libfdt: %s\n", fdt_strerror(nodeoffset));
-               return nodeoffset;
-       }
-
-       for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
-               char *s, *lval, *rval;
-
-               /*
-                * Find the end of the name=definition
-                */
-               for (nxt = i; env_get_char(nxt) != '\0'; ++nxt)
-                       ;
-               s = tmpenv;
-               for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k)
-                       *s++ = env_get_char(k);
-               *s++ = '\0';
-               lval = tmpenv;
-               /*
-                * Find the first '=': it separates the name from the value
-                */
-               s = strchr(tmpenv, '=');
-               if (s != NULL) {
-                       *s++ = '\0';
-                       rval = s;
-               } else
-                       continue;
-               err = fdt_setprop(fdt, nodeoffset, lval, rval, strlen(rval)+1);
-               if (err < 0) {
-                       printf("\"%s\" - libfdt: %s\n", lval, fdt_strerror(err));
-                       return err;
-               }
-       }
-       return 0;
-}
-#endif /* CONFIG_OF_HAS_UBOOT_ENV */
-
-/********************************************************************/
-
-#ifdef CONFIG_OF_HAS_BD_T
-static int fdt_bd_t(void *fdt)
-{
-       bd_t *bd = gd->bd;
-       int   nodeoffset;
-       int   err;
-       u32   tmp;                      /* used to set 32 bit integer properties */
-       int i;
-
-       /*
-        * See if we already have a "bd_t" node, delete it if so.
-        * Then create a new empty node.
-        */
-       nodeoffset = fdt_path_offset (fdt, "/bd_t");
-       if (nodeoffset >= 0) {
-               err = fdt_del_node(fdt, nodeoffset);
-               if (err < 0) {
-                       printf("libfdt: %s\n", fdt_strerror(err));
-                       return err;
-               }
-       }
-       /*
-        * Create a new node "/bd_t" (offset 0 is root level)
-        */
-       nodeoffset = fdt_add_subnode(fdt, 0, "bd_t");
-       if (nodeoffset < 0) {
-               printf("libfdt: %s\n", fdt_strerror(nodeoffset));
-               return nodeoffset;
-       }
-       /*
-        * Use the string/pointer structure to create the entries...
-        */
-       for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) {
-               tmp = cpu_to_be32(getenv("bootargs"));
-               err = fdt_setprop(fdt, nodeoffset, bd_map[i].name, &tmp, sizeof(tmp));
-               if (err < 0)
-                       printf("libfdt: %s\n", fdt_strerror(err));
-       }
-       /*
-        * Add a couple of oddball entries...
-        */
-       err = fdt_setprop(fdt, nodeoffset, "enetaddr", &bd->bi_enetaddr, 6);
-       if (err < 0)
-               printf("libfdt: %s\n", fdt_strerror(err));
-       err = fdt_setprop(fdt, nodeoffset, "ethspeed", &bd->bi_ethspeed, 4);
-       if (err < 0)
-               printf("libfdt: %s\n", fdt_strerror(err));
-
-#ifdef CONFIG_OF_BOARD_SETUP
-       ft_board_setup(fdt, bd);
-#endif
-
-       return 0;
-}
-#endif /* CONFIG_OF_HAS_BD_T */
-
-/********************************************************************/
-
 U_BOOT_CMD(
        fdt,    5,      0,      do_fdt,
        "fdt     - flattened device tree utility commands\n",
@@ -871,4 +632,4 @@ U_BOOT_CMD(
        "          fdt set   /cpus \"#address-cells\" \"[00 00 00 01]\"\n"
 );
 
-#endif /* CONFIG_OF_FLAT_TREE */
+#endif /* CONFIG_OF_LIBFDT */
diff --git a/common/fdt_support.c b/common/fdt_support.c
new file mode 100644 (file)
index 0000000..91b729f
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ * (C) Copyright 2007
+ * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <linux/ctype.h>
+#include <linux/types.h>
+
+#ifdef CONFIG_OF_LIBFDT
+
+#include <asm/global_data.h>
+#include <fdt.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+
+/*
+ * Global data (for the gd->bd)
+ */
+DECLARE_GLOBAL_DATA_PTR;
+
+
+/********************************************************************/
+
+int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force)
+{
+       bd_t *bd = gd->bd;
+       int   nodeoffset;
+       int   err;
+       u32   tmp;                      /* used to set 32 bit integer properties */
+       char  *str;                     /* used to set string properties */
+       ulong clock;
+
+       err = fdt_check_header(fdt);
+       if (err < 0) {
+               printf("libfdt: %s\n", fdt_strerror(err));
+               return err;
+       }
+
+       if (initrd_start && initrd_end) {
+               struct fdt_reserve_entry *re;
+               int  used;
+               int  total;
+               int  j;
+
+               err = fdt_num_reservemap(fdt, &used, &total);
+               if (err < 0) {
+                       printf("libfdt: %s\n", fdt_strerror(err));
+                       return err;
+               }
+               if (used >= total) {
+                       printf("fdt_chosen: no room in the reserved map (%d of %d)\n",
+                               used, total);
+                       return -1;
+               }
+               /*
+                * Look for an existing entry and update it.  If we don't find
+                * the entry, we will j be the next available slot.
+                */
+               for (j = 0; j < used; j++) {
+                       err = fdt_get_reservemap(fdt, j, &re);
+                       if (re->address == initrd_start) {
+                               break;
+                       }
+               }
+               err = fdt_replace_reservemap_entry(fdt, j,
+                       initrd_start, initrd_end - initrd_start + 1);
+               if (err < 0) {
+                       printf("libfdt: %s\n", fdt_strerror(err));
+                       return err;
+               }
+       }
+
+       /*
+        * Find the "chosen" node.
+        */
+       nodeoffset = fdt_path_offset (fdt, "/chosen");
+
+       /*
+        * If we have a "chosen" node already the "force the writing"
+        * is not set, our job is done.
+        */
+       if ((nodeoffset >= 0) && !force)
+               return 0;
+
+       /*
+        * No "chosen" node in the blob: create it.
+        */
+       if (nodeoffset < 0) {
+               /*
+                * Create a new node "/chosen" (offset 0 is root level)
+                */
+               nodeoffset = fdt_add_subnode(fdt, 0, "chosen");
+               if (nodeoffset < 0) {
+                       printf("libfdt: %s\n", fdt_strerror(nodeoffset));
+                       return nodeoffset;
+               }
+       }
+
+       /*
+        * Update pre-existing properties, create them if non-existant.
+        */
+       str = getenv("bootargs");
+       if (str != NULL) {
+               err = fdt_setprop(fdt, nodeoffset, "bootargs", str, strlen(str)+1);
+               if (err < 0)
+                       printf("libfdt: %s\n", fdt_strerror(err));
+       }
+       if (initrd_start && initrd_end) {
+               tmp = __cpu_to_be32(initrd_start);
+               err = fdt_setprop(fdt, nodeoffset, "linux,initrd-start", &tmp, sizeof(tmp));
+               if (err < 0)
+                       printf("libfdt: %s\n", fdt_strerror(err));
+               tmp = __cpu_to_be32(initrd_end);
+               err = fdt_setprop(fdt, nodeoffset, "linux,initrd-end", &tmp, sizeof(tmp));
+               if (err < 0)
+                       printf("libfdt: %s\n", fdt_strerror(err));
+       }
+#ifdef OF_STDOUT_PATH
+       err = fdt_setprop(fdt, nodeoffset, "linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1);
+       if (err < 0)
+               printf("libfdt: %s\n", fdt_strerror(err));
+#endif
+
+       nodeoffset = fdt_path_offset (fdt, "/cpus");
+       if (nodeoffset >= 0) {
+               clock = cpu_to_be32(bd->bi_intfreq);
+               err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4);
+               if (err < 0)
+                       printf("libfdt: %s\n", fdt_strerror(err));
+       }
+#ifdef OF_TBCLK
+       nodeoffset = fdt_path_offset (fdt, "/cpus/" OF_CPU "/timebase-frequency");
+       if (nodeoffset >= 0) {
+               clock = cpu_to_be32(OF_TBCLK);
+               err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4);
+               if (err < 0)
+                       printf("libfdt: %s\n", fdt_strerror(err));
+       }
+#endif
+       return err;
+}
+
+/********************************************************************/
+
+#ifdef CONFIG_OF_HAS_UBOOT_ENV
+
+/* Function that returns a character from the environment */
+extern uchar(*env_get_char) (int);
+
+
+int fdt_env(void *fdt)
+{
+       int   nodeoffset;
+       int   err;
+       int   k, nxt;
+       int i;
+       static char tmpenv[256];
+
+       err = fdt_check_header(fdt);
+       if (err < 0) {
+               printf("libfdt: %s\n", fdt_strerror(err));
+               return err;
+       }
+
+       /*
+        * See if we already have a "u-boot-env" node, delete it if so.
+        * Then create a new empty node.
+        */
+       nodeoffset = fdt_path_offset (fdt, "/u-boot-env");
+       if (nodeoffset >= 0) {
+               err = fdt_del_node(fdt, nodeoffset);
+               if (err < 0) {
+                       printf("libfdt: %s\n", fdt_strerror(err));
+                       return err;
+               }
+       }
+       /*
+        * Create a new node "/u-boot-env" (offset 0 is root level)
+        */
+       nodeoffset = fdt_add_subnode(fdt, 0, "u-boot-env");
+       if (nodeoffset < 0) {
+               printf("libfdt: %s\n", fdt_strerror(nodeoffset));
+               return nodeoffset;
+       }
+
+       for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
+               char *s, *lval, *rval;
+
+               /*
+                * Find the end of the name=definition
+                */
+               for (nxt = i; env_get_char(nxt) != '\0'; ++nxt)
+                       ;
+               s = tmpenv;
+               for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k)
+                       *s++ = env_get_char(k);
+               *s++ = '\0';
+               lval = tmpenv;
+               /*
+                * Find the first '=': it separates the name from the value
+                */
+               s = strchr(tmpenv, '=');
+               if (s != NULL) {
+                       *s++ = '\0';
+                       rval = s;
+               } else
+                       continue;
+               err = fdt_setprop(fdt, nodeoffset, lval, rval, strlen(rval)+1);
+               if (err < 0) {
+                       printf("libfdt: %s\n", fdt_strerror(err));
+                       return err;
+               }
+       }
+       return 0;
+}
+#endif /* ifdef CONFIG_OF_HAS_UBOOT_ENV */
+
+/********************************************************************/
+
+#ifdef CONFIG_OF_HAS_BD_T
+
+#define BDM(x) {       .name = #x, .offset = offsetof(bd_t, bi_ ##x ) }
+
+static const struct {
+       const char *name;
+       int offset;
+} bd_map[] = {
+       BDM(memstart),
+       BDM(memsize),
+       BDM(flashstart),
+       BDM(flashsize),
+       BDM(flashoffset),
+       BDM(sramstart),
+       BDM(sramsize),
+#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \
+       || defined(CONFIG_E500)
+       BDM(immr_base),
+#endif
+#if defined(CONFIG_MPC5xxx)
+       BDM(mbar_base),
+#endif
+#if defined(CONFIG_MPC83XX)
+       BDM(immrbar),
+#endif
+#if defined(CONFIG_MPC8220)
+       BDM(mbar_base),
+       BDM(inpfreq),
+       BDM(pcifreq),
+       BDM(pevfreq),
+       BDM(flbfreq),
+       BDM(vcofreq),
+#endif
+       BDM(bootflags),
+       BDM(ip_addr),
+       BDM(intfreq),
+       BDM(busfreq),
+#ifdef CONFIG_CPM2
+       BDM(cpmfreq),
+       BDM(brgfreq),
+       BDM(sccfreq),
+       BDM(vco),
+#endif
+#if defined(CONFIG_MPC5xxx)
+       BDM(ipbfreq),
+       BDM(pcifreq),
+#endif
+       BDM(baudrate),
+};
+
+
+int fdt_bd_t(void *fdt)
+{
+       bd_t *bd = gd->bd;
+       int   nodeoffset;
+       int   err;
+       u32   tmp;                      /* used to set 32 bit integer properties */
+       int i;
+
+       err = fdt_check_header(fdt);
+       if (err < 0) {
+               printf("libfdt: %s\n", fdt_strerror(err));
+               return err;
+       }
+
+       /*
+        * See if we already have a "bd_t" node, delete it if so.
+        * Then create a new empty node.
+        */
+       nodeoffset = fdt_path_offset (fdt, "/bd_t");
+       if (nodeoffset >= 0) {
+               err = fdt_del_node(fdt, nodeoffset);
+               if (err < 0) {
+                       printf("libfdt: %s\n", fdt_strerror(err));
+                       return err;
+               }
+       }
+       /*
+        * Create a new node "/bd_t" (offset 0 is root level)
+        */
+       nodeoffset = fdt_add_subnode(fdt, 0, "bd_t");
+       if (nodeoffset < 0) {
+               printf("libfdt: %s\n", fdt_strerror(nodeoffset));
+               return nodeoffset;
+       }
+       /*
+        * Use the string/pointer structure to create the entries...
+        */
+       for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) {
+               tmp = cpu_to_be32(getenv("bootargs"));
+               err = fdt_setprop(fdt, nodeoffset, bd_map[i].name, &tmp, sizeof(tmp));
+               if (err < 0)
+                       printf("libfdt: %s\n", fdt_strerror(err));
+       }
+       /*
+        * Add a couple of oddball entries...
+        */
+       err = fdt_setprop(fdt, nodeoffset, "enetaddr", &bd->bi_enetaddr, 6);
+       if (err < 0)
+               printf("libfdt: %s\n", fdt_strerror(err));
+       err = fdt_setprop(fdt, nodeoffset, "ethspeed", &bd->bi_ethspeed, 4);
+       if (err < 0)
+               printf("libfdt: %s\n", fdt_strerror(err));
+
+       return 0;
+}
+#endif /* ifdef CONFIG_OF_HAS_BD_T */
+
+#endif /* CONFIG_OF_LIBFDT */
index 21b16463cd7429574795b7893daa0332ef0ce63a..e934ba638fef62e99ff6ce635c8f9cef4611f59e 100644 (file)
@@ -299,93 +299,175 @@ void watchdog_reset (void)
 
 #if defined(CONFIG_OF_LIBFDT)
 
+/*
+ * "Setter" functions used to add/modify FDT entries.
+ */
+static int fdt_set_eth0(void *fdt, int nodeoffset, const char *name, bd_t *bd)
+{
+       /*
+        * Fix it up if it exists, don't create it if it doesn't exist.
+        */
+       if (fdt_get_property(fdt, nodeoffset, name, 0)) {
+               return fdt_setprop(fdt, nodeoffset, name, bd->bi_enetaddr, 6);
+       }
+       return -FDT_ERR_NOTFOUND;
+}
+#ifdef CONFIG_HAS_ETH1
+/* second onboard ethernet port */
+static int fdt_set_eth1(void *fdt, int nodeoffset, const char *name, bd_t *bd)
+{
+       /*
+        * Fix it up if it exists, don't create it if it doesn't exist.
+        */
+       if (fdt_get_property(fdt, nodeoffset, name, 0)) {
+               return fdt_setprop(fdt, nodeoffset, name, bd->bi_enet1addr, 6);
+       }
+       return -FDT_ERR_NOTFOUND;
+}
+#endif
+#ifdef CONFIG_HAS_ETH2
+/* third onboard ethernet port */
+static int fdt_set_eth2(void *fdt, int nodeoffset, const char *name, bd_t *bd)
+{
+       /*
+        * Fix it up if it exists, don't create it if it doesn't exist.
+        */
+       if (fdt_get_property(fdt, nodeoffset, name, 0)) {
+               return fdt_setprop(fdt, nodeoffset, name, bd->bi_enet2addr, 6);
+       }
+       return -FDT_ERR_NOTFOUND;
+}
+#endif
+#ifdef CONFIG_HAS_ETH3
+/* fourth onboard ethernet port */
+static int fdt_set_eth3(void *fdt, int nodeoffset, const char *name, bd_t *bd)
+{
+       /*
+        * Fix it up if it exists, don't create it if it doesn't exist.
+        */
+       if (fdt_get_property(fdt, nodeoffset, name, 0)) {
+               return fdt_setprop(fdt, nodeoffset, name, bd->bi_enet3addr, 6);
+       }
+       return -FDT_ERR_NOTFOUND;
+}
+#endif
+
+static int fdt_set_busfreq(void *fdt, int nodeoffset, const char *name, bd_t *bd)
+{
+       u32  tmp;
+       /*
+        * Create or update the property.
+        */
+       tmp = cpu_to_be32(bd->bi_busfreq);
+       return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
+}
+
 /*
  * Fixups to the fdt.  If "create" is TRUE, the node is created
  * unconditionally.  If "create" is FALSE, the node is updated
  * only if it already exists.
  */
-#define        FT_UPDATE       0x00000000              /* update existing property only */
-#define        FT_CREATE       0x00000001              /* create property if it doesn't exist */
-#define        FT_BUSFREQ      0x00000002              /* source is bd->bi_busfreq */
-#define        FT_ENETADDR     0x00000004              /* source is bd->bi_enetaddr */
 static const struct {
-       int  createflags;
        char *node;
        char *prop;
+       int (*set_fn)(void *fdt, int nodeoffset, const char *name, bd_t *bd);
 } fixup_props[] = {
-       {       FT_CREATE | FT_BUSFREQ,
-               "/cpus/" OF_CPU,
+       {       "/cpus/" OF_CPU,
                 "bus-frequency",
+               fdt_set_busfreq
        },
-       {       FT_CREATE | FT_BUSFREQ,
-               "/cpus/" OF_SOC,
-               "bus-frequency"
+       {       "/cpus/" OF_SOC,
+               "bus-frequency",
+               fdt_set_busfreq
        },
-       {       FT_CREATE | FT_BUSFREQ,
-               "/" OF_SOC "/serial@4500/",
-               "clock-frequency"
+       {       "/" OF_SOC "/serial@4500/",
+               "clock-frequency",
+               fdt_set_busfreq
        },
-       {       FT_CREATE | FT_BUSFREQ,
-               "/" OF_SOC "/serial@4600/",
-               "clock-frequency"
+       {       "/" OF_SOC "/serial@4600/",
+               "clock-frequency",
+               fdt_set_busfreq
        },
 #ifdef CONFIG_MPC83XX_TSEC1
-       {       FT_UPDATE | FT_ENETADDR,
-               "/" OF_SOC "/ethernet@24000,
+       {       "/" OF_SOC "/ethernet@24000,
                "mac-address",
+               fdt_set_eth0
        },
-       {       FT_UPDATE | FT_ENETADDR,
-               "/" OF_SOC "/ethernet@24000,
+       {       "/" OF_SOC "/ethernet@24000,
                "local-mac-address",
+               fdt_set_eth0
        },
 #endif
 #ifdef CONFIG_MPC83XX_TSEC2
-       {       FT_UPDATE | FT_ENETADDR,
-               "/" OF_SOC "/ethernet@25000,
+       {       "/" OF_SOC "/ethernet@25000,
+               "mac-address",
+               fdt_set_eth1
+       },
+       {       "/" OF_SOC "/ethernet@25000,
+               "local-mac-address",
+               fdt_set_eth1
+       },
+#endif
+#ifdef CONFIG_UEC_ETH1
+#if CFG_UEC1_UCC_NUM == 0  /* UCC1 */
+       {       "/" OF_QE "/ucc@2000/mac-address",
+               "mac-address",
+               fdt_set_eth0
+       },
+       {       "/" OF_QE "/ucc@2000/mac-address",
+               "local-mac-address",
+               fdt_set_eth0
+       },
+#elif CFG_UEC1_UCC_NUM == 2  /* UCC3 */
+       {       "/" OF_QE "/ucc@2200/mac-address",
+               "mac-address",
+               fdt_set_eth0
+       },
+       {       "/" OF_QE "/ucc@2200/mac-address",
+               "local-mac-address",
+               fdt_set_eth0
+       },
+#endif
+#endif
+#ifdef CONFIG_UEC_ETH2
+#if CFG_UEC2_UCC_NUM == 1  /* UCC2 */
+       {       "/" OF_QE "/ucc@3000/mac-address",
                "mac-address",
+               fdt_set_eth1
        },
-       {       FT_UPDATE | FT_ENETADDR,
-               "/" OF_SOC "/ethernet@25000,
+       {       "/" OF_QE "/ucc@3000/mac-address",
                "local-mac-address",
+               fdt_set_eth1
+       },
+#elif CFG_UEC1_UCC_NUM == 3  /* UCC4 */
+       {       "/" OF_QE "/ucc@3200/mac-address",
+               "mac-address",
+               fdt_set_eth1
        },
+       {       "/" OF_QE "/ucc@3200/mac-address",
+               "local-mac-address",
+               fdt_set_eth1
+       },
+#endif
 #endif
 };
 
 void
 ft_cpu_setup(void *blob, bd_t *bd)
 {
-       int   nodeoffset;
-       int   err;
-       int j;
+       int  nodeoffset;
+       int  err;
+       int  j;
 
        for (j = 0; j < (sizeof(fixup_props) / sizeof(fixup_props[0])); j++) {
-               nodeoffset = fdt_path_offset (fdt, fixup_props[j].node);
+               nodeoffset = fdt_path_offset(fdt, fixup_props[j].node);
                if (nodeoffset >= 0) {
-                       /*
-                        * If unconditional create or the property already exists...
-                        */
-                       if ((fixup_props[j].createflags & FT_CREATE) ||
-                               (fdt_get_property(fdt, nodeoffset, fixup_props[j].prop, 0))) {
-                               if (fixup_props[j].createflags & FT_BUSFREQ) {
-                                       u32   tmp;
-
-                                       tmp = cpu_to_be32(bd->bi_busfreq);
-                                       err = fdt_setprop(fdt, nodeoffset,
-                                                       fixup_props[j].prop, &tmp, sizeof(tmp));
-                               } else if (fixup_props[j].createflags & FT_ENETADDR) {
-                                       err = fdt_setprop(fdt, nodeoffset,
-                                                       fixup_props[j].prop, bd->bi_enetaddr, 6);
-                               } else {
-                                       printf("ft_cpu_setup: %s %s has no flag for the value to set\n",
-                                               fixup_props[j].node,
-                                               fixup_props[j].prop);
-                               }
-                               if (err < 0)
-                                       printf("libfdt: %s %s returned %s\n",
-                                               fixup_props[j].node,
-                                               fixup_props[j].prop,
-                                               fdt_strerror(err));
-                       }
+                       err = (*fixup_props[j].set_fn)(blob, nodeoffset, fixup_props[j].prop, bd);
+                       if (err < 0)
+                               printf("set_fn/libfdt: %s %s returned %s\n",
+                                       fixup_props[j].node,
+                                       fixup_props[j].prop,
+                                       fdt_strerror(err));
                }
        }
 }
index 48ccfd9100002deb3aff35ee4f17bc7d232b25b2..3dd3aca3b6aaa53803b402be79f451313f18604e 100644 (file)
@@ -1,3 +1,22 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
 #ifndef _FDT_H
 #define _FDT_H
 
diff --git a/include/fdt_support.h b/include/fdt_support.h
new file mode 100644 (file)
index 0000000..a276834
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * (C) Copyright 2007
+ * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __FDT_SUPPORT_H
+#define __FDT_SUPPORT_H
+
+#ifdef CONFIG_OF_LIBFDT
+
+#include <fdt.h>
+
+int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force);
+
+#ifdef CONFIG_OF_HAS_UBOOT_ENV
+int fdt_env(void *fdt);
+#endif
+
+#ifdef CONFIG_OF_HAS_BD_T
+int fdt_bd_t(void *fdt);
+#endif
+
+#endif /* ifdef CONFIG_OF_LIBFDT */
+#endif /* ifndef __FDT_SUPPORT_H */
index a0b4d55034155e5e99ff5013c65040bbd7c42b3e..f8bac73a319fabee0c669c46dcd354823de911b7 100644 (file)
@@ -1,5 +1,3 @@
-#ifndef _LIBFDT_H
-#define _LIBFDT_H
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
@@ -19,6 +17,9 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#ifndef _LIBFDT_H
+#define _LIBFDT_H
+
 #include <fdt.h>
 #include <libfdt_env.h>
 
@@ -60,6 +61,8 @@
 #define fdt_set_header(fdt, field, val) \
        ((struct fdt_header *)(fdt))->field = cpu_to_fdt32(val)
 
+int fdt_check_header(const void *fdt);
+
 void *fdt_offset_ptr(const void *fdt, int offset, int checklen);
 
 #define fdt_offset_ptr_typed(fdt, offset, var) \
@@ -83,6 +86,8 @@ void *fdt_getprop(const void *fdt, int nodeoffset,
 
 uint32_t fdt_next_tag(const void *fdt, int offset,
                      int *nextoffset, char **namep);
+int fdt_num_reservemap(void *fdt, int *used, int *total);
+int fdt_get_reservemap(void *fdt, int n, struct fdt_reserve_entry *re);
 
 /* Write-in-place functions */
 int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
@@ -96,6 +101,8 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
 
 int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
 int fdt_nop_node(void *fdt, int nodeoffset);
+int fdt_insert_reservemap_entry(void *fdt, int n, uint64_t addr, uint64_t size);
+
 
 /* Sequential-write functions */
 int fdt_create(void *buf, int bufsize);
@@ -112,6 +119,7 @@ int fdt_property(void *fdt, const char *name, const void *val, int len);
        fdt_property(fdt, name, str, strlen(str)+1)
 int fdt_end_node(void *fdt);
 int fdt_finish(void *fdt);
+int fdt_replace_reservemap_entry(void *fdt, int n, uint64_t addr, uint64_t size);
 
 /* Read-write functions */
 int fdt_open_into(void *fdt, void *buf, int bufsize);
index 6c7785254074ddc063f740ac5fe32b6f416af1a4..e746314b1e7522f0dcc9f8b5a46c9d9ba9e292ba 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * libfdt - Flat Device Tree manipulation (build/run environment adaptation)
+ * Copyright (C) 2007 Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com
+ * Original version written by David Gibson, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
 #ifndef _LIBFDT_ENV_H
 #define _LIBFDT_ENV_H
 
index 4b1c8abf95e90c4ec6fc45a44e81b357e9b80fb5..212b83838c6ebba4289d0610d78ba838a5914e30 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "libfdt_internal.h"
 
-int _fdt_check_header(const void *fdt)
+int fdt_check_header(const void *fdt)
 {
        if (fdt_magic(fdt) == FDT_MAGIC) {
                /* Complete tree */
@@ -72,7 +72,7 @@ const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
 
 int fdt_move(const void *fdt, void *buf, int bufsize)
 {
-       int err = _fdt_check_header(fdt);
+       int err = fdt_check_header(fdt);
 
        if (err)
                return err;
index ce01dc700b60f207693ecba52b81258ce3934600..af3333686960598ec9de3d5b499b3c2abdb7fed0 100644 (file)
@@ -25,7 +25,7 @@
 
 #define CHECK_HEADER(fdt)      { \
        int err; \
-       if ((err = _fdt_check_header(fdt)) != 0) \
+       if ((err = fdt_check_header(fdt)) != 0) \
                return err; \
 }
 
@@ -188,7 +188,7 @@ struct fdt_property *fdt_get_property(const void *fdt,
        int offset, nextoffset;
        int err;
 
-       if ((err = _fdt_check_header(fdt)) != 0)
+       if ((err = fdt_check_header(fdt)) != 0)
                goto fail;
 
        err = -FDT_ERR_BADOFFSET;
@@ -329,3 +329,75 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset, char **namep
 
        return tag;
 }
+
+/*
+ * Return the number of used reserve map entries and total slots available.
+ */
+int fdt_num_reservemap(void *fdt, int *used, int *total)
+{
+       struct fdt_reserve_entry *re;
+       int  start;
+       int  end;
+       int  err = fdt_check_header(fdt);
+
+       if (err != 0)
+               return err;
+
+       start = fdt_off_mem_rsvmap(fdt);
+
+       /*
+        * Convention is that the reserve map is before the dt_struct,
+        * but it does not have to be.
+        */
+       end = fdt_totalsize(fdt);
+       if (end > fdt_off_dt_struct(fdt))
+               end = fdt_off_dt_struct(fdt);
+       if (end > fdt_off_dt_strings(fdt))
+               end = fdt_off_dt_strings(fdt);
+
+       /*
+        * Since the reserved area list is zero terminated, you get one fewer.
+        */
+       if (total)
+               *total = ((end - start) / sizeof(struct fdt_reserve_entry)) - 1;
+
+       if (used) {
+               *used = 0;
+               while (start < end) {
+                       re = (struct fdt_reserve_entry *)(fdt + start);
+                       if (re->size == 0)
+                               return 0;       /* zero size terminates the list */
+
+                       *used += 1;
+                       start += sizeof(struct fdt_reserve_entry);
+               }
+               /*
+                * If we get here, there was no zero size termination.
+                */
+               return -FDT_ERR_BADLAYOUT;
+       }
+       return 0;
+}
+
+/*
+ * Return the nth reserve map entry.
+ */
+int fdt_get_reservemap(void *fdt, int n, struct fdt_reserve_entry *re)
+{
+       int  used;
+       int  total;
+       int  err;
+
+       err = fdt_num_reservemap(fdt, &used, &total);
+       if (err != 0)
+               return err;
+
+       if (n >= total)
+               return -FDT_ERR_NOSPACE;
+       if (re) {
+               *re = *(struct fdt_reserve_entry *)
+                       _fdt_offset_ptr(fdt, n * sizeof(struct fdt_reserve_entry));
+       }
+       return 0;
+}
+
index b33fbf45debd7c1c27bf4903bb6cac61aa8246e0..aaafc53644fb89100db283bcfabf2adef9c535b0 100644 (file)
@@ -27,7 +27,7 @@ static int rw_check_header(void *fdt)
 {
        int err;
 
-       if ((err = _fdt_check_header(fdt)))
+       if ((err = fdt_check_header(fdt)))
                return err;
        if (fdt_version(fdt) < 0x11)
                return -FDT_ERR_BADVERSION;
index 261b9b0dc9379f714fd00ea2a0806d065a269336..cf811830a73bdba81b71239940fcd958f8b6d89a 100644 (file)
@@ -110,3 +110,29 @@ int fdt_nop_node(void *fdt, int nodeoffset)
        nop_region(fdt_offset_ptr(fdt, nodeoffset, 0), endoffset - nodeoffset);
        return 0;
 }
+
+/*
+ * Replace a reserve map entry in the nth slot.
+ */
+int fdt_replace_reservemap_entry(void *fdt, int n, uint64_t addr, uint64_t size)
+{
+       struct fdt_reserve_entry *re;
+       int  used;
+       int  total;
+       int  err;
+
+       err = fdt_num_reservemap(fdt, &used, &total);
+       if (err != 0)
+               return err;
+
+       if (n >= total)
+               return -FDT_ERR_NOSPACE;
+       re = (struct fdt_reserve_entry *)
+               (fdt + fdt_off_mem_rsvmap(fdt) +
+                (n * sizeof(struct fdt_reserve_entry)));
+       re->address = cpu_to_fdt64(addr);
+       re->size    = cpu_to_fdt64(size);
+
+       return 0;
+}
+