]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/cmd_fdt.c
Modified the DDR SDRAM clock control register to delay MCK/MCK_B 3/4 clock
[karo-tx-uboot.git] / common / cmd_fdt.c
index b665bd6c6addcdf647dbf75a74c9bdaf4a50a430..a52284e2fee798d2c71d6bf78199fd5a76cc4b4c 100644 (file)
@@ -44,7 +44,7 @@ DECLARE_GLOBAL_DATA_PTR;
 static int fdt_valid(void);
 static int fdt_parse_prop(char *pathp, char *prop, char *newval,
        char *data, int *len);
-static int fdt_print(char *pathp, char *prop, int depth);
+static int fdt_print(const char *pathp, char *prop, int depth);
 
 /*
  * Flattened Device Tree command, see the help for parameter definitions.
@@ -75,7 +75,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                        /*
                         * Optional new length
                         */
-                       len =  simple_strtoul(argv[3], NULL, 16);
+                       len = simple_strtoul(argv[3], NULL, 16);
                        if (len < fdt_totalsize(fdt)) {
                                printf ("New length %d < existing length %d, "
                                        "ignoring.\n",
@@ -162,12 +162,12 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                pathp = argv[2];
                nodep = argv[3];
 
-               nodeoffset = fdt_find_node_by_path (fdt, pathp);
+               nodeoffset = fdt_path_offset (fdt, pathp);
                if (nodeoffset < 0) {
                        /*
                         * Not found or something else bad happened.
                         */
-                       printf ("libfdt fdt_find_node_by_path() returned %s\n",
+                       printf ("libfdt fdt_path_offset() returned %s\n",
                                fdt_strerror(nodeoffset));
                        return 1;
                }
@@ -184,36 +184,38 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
        } else if (argv[1][0] == 's') {
                char *pathp;            /* path */
                char *prop;             /* property */
-               char *newval;           /* value from the user (as a string) */
                int  nodeoffset;        /* node offset from libfdt */
                static char data[SCRATCHPAD];   /* storage for the property */
                int  len;               /* new length of the property */
                int  ret;               /* return value */
 
                /*
-                * Parameters: Node path, property, value.
+                * Parameters: Node path, property, optional value.
                 */
-               if (argc < 5) {
+               if (argc < 4) {
                        printf ("Usage:\n%s\n", cmdtp->usage);
                        return 1;
                }
 
                pathp  = argv[2];
                prop   = argv[3];
-               newval = argv[4];
+               if (argc == 4) {
+                       len = 0;
+               } else {
+                       ret = fdt_parse_prop(pathp, prop, argv[4], data, &len);
+                       if (ret != 0)
+                               return ret;
+               }
 
-               nodeoffset = fdt_find_node_by_path (fdt, pathp);
+               nodeoffset = fdt_path_offset (fdt, pathp);
                if (nodeoffset < 0) {
                        /*
                         * Not found or something else bad happened.
                         */
-                       printf ("libfdt fdt_find_node_by_path() returned %s\n",
+                       printf ("libfdt fdt_path_offset() returned %s\n",
                                fdt_strerror(nodeoffset));
                        return 1;
                }
-               ret = fdt_parse_prop(pathp, prop, newval, data, &len);
-               if (ret != 0)
-                       return ret;
 
                ret = fdt_setprop(fdt, nodeoffset, prop, data, len);
                if (ret < 0) {
@@ -258,7 +260,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
        /********************************************************************
         * Remove a property/node
         ********************************************************************/
-       } else if (argv[1][0] == 'r') {
+       } else if ((argv[1][0] == 'r') && (argv[1][1] == 'm')) {
                int  nodeoffset;        /* node offset from libfdt */
                int  err;
 
@@ -266,12 +268,12 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                 * Get the path.  The root node is an oddball, the offset
                 * is zero and has no name.
                 */
-               nodeoffset = fdt_find_node_by_path (fdt, argv[2]);
+               nodeoffset = fdt_path_offset (fdt, argv[2]);
                if (nodeoffset < 0) {
                        /*
                         * Not found or something else bad happened.
                         */
-                       printf ("libfdt fdt_find_node_by_path() returned %s\n",
+                       printf ("libfdt fdt_path_offset() returned %s\n",
                                fdt_strerror(nodeoffset));
                        return 1;
                }
@@ -294,6 +296,111 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                                return err;
                        }
                }
+
+       /********************************************************************
+        * Display header info
+        ********************************************************************/
+       } else if (argv[1][0] == 'h') {
+               u32 version = fdt_version(fdt);
+               printf("magic:\t\t\t0x%x\n", fdt_magic(fdt));
+               printf("totalsize:\t\t0x%x (%d)\n", fdt_totalsize(fdt), fdt_totalsize(fdt));
+               printf("off_dt_struct:\t\t0x%x\n", fdt_off_dt_struct(fdt));
+               printf("off_dt_strings:\t\t0x%x\n", fdt_off_dt_strings(fdt));
+               printf("off_mem_rsvmap:\t\t0x%x\n", fdt_off_mem_rsvmap(fdt));
+               printf("version:\t\t%d\n", version);
+               printf("last_comp_version:\t%d\n", fdt_last_comp_version(fdt));
+               if (version >= 2)
+                       printf("boot_cpuid_phys:\t0x%x\n",
+                               fdt_boot_cpuid_phys(fdt));
+               if (version >= 3)
+                       printf("size_dt_strings:\t0x%x\n",
+                               fdt_size_dt_strings(fdt));
+               if (version >= 17)
+                       printf("size_dt_struct:\t\t0x%x\n",
+                               fdt_size_dt_struct(fdt));
+               printf("number mem_rsv:\t\t0x%x\n", fdt_num_mem_rsv(fdt));
+               printf("\n");
+
+       /********************************************************************
+        * Set boot cpu id
+        ********************************************************************/
+       } else if ((argv[1][0] == 'b') && (argv[1][1] == 'o') &&
+                  (argv[1][2] == 'o')) {
+               unsigned long tmp = simple_strtoul(argv[2], NULL, 16);
+               fdt_set_boot_cpuid_phys(fdt, tmp);
+
+       /********************************************************************
+        * memory command
+        ********************************************************************/
+       } else if ((argv[1][0] == 'm') && (argv[1][1] == 'e')) {
+               uint64_t addr, size;
+               int err;
+#ifdef CFG_64BIT_STRTOUL
+                       addr = simple_strtoull(argv[2], NULL, 16);
+                       size = simple_strtoull(argv[3], NULL, 16);
+#else
+                       addr = simple_strtoul(argv[2], NULL, 16);
+                       size = simple_strtoul(argv[3], NULL, 16);
+#endif
+               err = fdt_fixup_memory(fdt, addr, size);
+               if (err < 0)
+                       return err;
+
+       /********************************************************************
+        * mem reserve commands
+        ********************************************************************/
+       } else if ((argv[1][0] == 'r') && (argv[1][1] == 's')) {
+               if (argv[2][0] == 'p') {
+                       uint64_t addr, size;
+                       int total = fdt_num_mem_rsv(fdt);
+                       int j, err;
+                       printf("index\t\t   start\t\t    size\n");
+                       printf("-------------------------------"
+                               "-----------------\n");
+                       for (j = 0; j < total; j++) {
+                               err = fdt_get_mem_rsv(fdt, j, &addr, &size);
+                               if (err < 0) {
+                                       printf("libfdt fdt_get_mem_rsv():  %s\n",
+                                                       fdt_strerror(err));
+                                       return err;
+                               }
+                               printf("    %x\t%08x%08x\t%08x%08x\n", j,
+                                       (u32)(addr >> 32),
+                                       (u32)(addr & 0xffffffff),
+                                       (u32)(size >> 32),
+                                       (u32)(size & 0xffffffff));
+                       }
+               } else if (argv[2][0] == 'a') {
+                       uint64_t addr, size;
+                       int err;
+#ifdef CFG_64BIT_STRTOUL
+                       addr = simple_strtoull(argv[3], NULL, 16);
+                       size = simple_strtoull(argv[4], NULL, 16);
+#else
+                       addr = simple_strtoul(argv[3], NULL, 16);
+                       size = simple_strtoul(argv[4], NULL, 16);
+#endif
+                       err = fdt_add_mem_rsv(fdt, addr, size);
+
+                       if (err < 0) {
+                               printf("libfdt fdt_add_mem_rsv():  %s\n",
+                                       fdt_strerror(err));
+                               return err;
+                       }
+               } else if (argv[2][0] == 'd') {
+                       unsigned long idx = simple_strtoul(argv[3], NULL, 16);
+                       int err = fdt_del_mem_rsv(fdt, idx);
+
+                       if (err < 0) {
+                               printf("libfdt fdt_del_mem_rsv():  %s\n",
+                                       fdt_strerror(err));
+                               return err;
+                       }
+               } else {
+                       /* Unrecognized command */
+                       printf ("Usage:\n%s\n", cmdtp->usage);
+                       return 1;
+               }
        }
 #ifdef CONFIG_OF_BOARD_SETUP
        /* Call the board-specific fixup routine */
@@ -303,17 +410,6 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
        /* Create a chosen node */
        else if (argv[1][0] == 'c')
                fdt_chosen(fdt, 0, 0, 1);
-
-#ifdef CONFIG_OF_HAS_UBOOT_ENV
-       /* Create a u-boot-env node */
-       else if (argv[1][0] == 'e')
-               fdt_env(fdt);
-#endif
-#ifdef CONFIG_OF_HAS_BD_T
-       /* Create a bd_t node */
-       else if (argv[1][0] == 'b')
-               fdt_bd_t(fdt);
-#endif
        else {
                /* Unrecognized command */
                printf ("Usage:\n%s\n", cmdtp->usage);
@@ -522,21 +618,21 @@ static void print_data(const void *data, int len)
 
        switch (len) {
        case 1:  /* byte */
-               printf("<%02x>", (*(u8 *) data) & 0xff);
+               printf("<0x%02x>", (*(u8 *) data) & 0xff);
                break;
        case 2:  /* half-word */
-               printf("<%04x>", be16_to_cpu(*(u16 *) data) & 0xffff);
+               printf("<0x%04x>", be16_to_cpu(*(u16 *) data) & 0xffff);
                break;
        case 4:  /* word */
-               printf("<%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
+               printf("<0x%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
                break;
        case 8:  /* double-word */
 #if __WORDSIZE == 64
-               printf("<%016llx>", be64_to_cpu(*(uint64_t *) data));
+               printf("<0x%016llx>", be64_to_cpu(*(uint64_t *) data));
 #else
-               printf("<%08x ", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
+               printf("<0x%08x ", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
                data += 4;
-               printf("%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
+               printf("0x%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
 #endif
                break;
        default:                /* anything else... hexdump */
@@ -555,25 +651,25 @@ static void print_data(const void *data, int len)
  * Recursively print (a portion of) the fdt.  The depth parameter
  * determines how deeply nested the fdt is printed.
  */
-static int fdt_print(char *pathp, char *prop, int depth)
+static int fdt_print(const char *pathp, char *prop, int depth)
 {
-       static int offstack[MAX_LEVEL];
        static char tabs[MAX_LEVEL+1] =
                "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"
                "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
-       void *nodep;            /* property node pointer */
+       const void *nodep;      /* property node pointer */
        int  nodeoffset;        /* node offset from libfdt */
        int  nextoffset;        /* next node offset from libfdt */
        uint32_t tag;           /* tag */
        int  len;               /* length of the property */
        int  level = 0;         /* keep track of nesting level */
+       const struct fdt_property *fdt_prop;
 
-       nodeoffset = fdt_find_node_by_path (fdt, pathp);
+       nodeoffset = fdt_path_offset (fdt, pathp);
        if (nodeoffset < 0) {
                /*
                 * Not found or something else bad happened.
                 */
-               printf ("libfdt fdt_find_node_by_path() returned %s\n",
+               printf ("libfdt fdt_path_offset() returned %s\n",
                        fdt_strerror(nodeoffset));
                return 1;
        }
@@ -588,7 +684,7 @@ static int fdt_print(char *pathp, char *prop, int depth)
                        printf("%s %s\n", pathp, prop);
                        return 0;
                } else if (len > 0) {
-                       printf("%s=", prop);
+                       printf("%s = ", prop);
                        print_data (nodep, len);
                        printf("\n");
                        return 0;
@@ -603,46 +699,53 @@ static int fdt_print(char *pathp, char *prop, int depth)
         * The user passed in a node path and no property,
         * print the node and all subnodes.
         */
-       offstack[0] = nodeoffset;
-
        while(level >= 0) {
-               tag = fdt_next_tag(fdt, nodeoffset, &nextoffset, &pathp);
+               tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
                switch(tag) {
                case FDT_BEGIN_NODE:
-                       if(level <= depth)
+                       pathp = fdt_get_name(fdt, nodeoffset, NULL);
+                       if (level <= depth) {
+                               if (pathp == NULL)
+                                       pathp = "/* NULL pointer error */";
+                               if (*pathp == '\0')
+                                       pathp = "/";    /* root is nameless */
                                printf("%s%s {\n",
                                        &tabs[MAX_LEVEL - level], pathp);
+                       }
                        level++;
-                       offstack[level] = nodeoffset;
                        if (level >= MAX_LEVEL) {
-                               printf("Aaaiii <splat> nested too deep. "
-                                       "Aborting.\n");
+                               printf("Nested too deep, aborting.\n");
                                return 1;
                        }
                        break;
                case FDT_END_NODE:
                        level--;
-                       if(level <= depth)
+                       if (level <= depth)
                                printf("%s};\n", &tabs[MAX_LEVEL - level]);
                        if (level == 0) {
                                level = -1;             /* exit the loop */
                        }
                        break;
                case FDT_PROP:
-                       nodep = fdt_getprop (fdt, offstack[level], pathp, &len);
+                       fdt_prop = fdt_offset_ptr(fdt, nodeoffset,
+                                       sizeof(*fdt_prop));
+                       pathp    = fdt_string(fdt,
+                                       fdt32_to_cpu(fdt_prop->nameoff));
+                       len      = fdt32_to_cpu(fdt_prop->len);
+                       nodep    = fdt_prop->data;
                        if (len < 0) {
                                printf ("libfdt fdt_getprop(): %s\n",
                                        fdt_strerror(len));
                                return 1;
                        } else if (len == 0) {
                                /* the property has no value */
-                               if(level <= depth)
+                               if (level <= depth)
                                        printf("%s%s;\n",
                                                &tabs[MAX_LEVEL - level],
                                                pathp);
                        } else {
-                               if(level <= depth) {
-                                       printf("%s%s=",
+                               if (level <= depth) {
+                                       printf("%s%s = ",
                                                &tabs[MAX_LEVEL - level],
                                                pathp);
                                        print_data (nodep, len);
@@ -651,11 +754,12 @@ static int fdt_print(char *pathp, char *prop, int depth)
                        }
                        break;
                case FDT_NOP:
+                       printf("/* NOP */\n", &tabs[MAX_LEVEL - level]);
                        break;
                case FDT_END:
                        return 1;
                default:
-                       if(level <= depth)
+                       if (level <= depth)
                                printf("Unknown tag 0x%08X\n", tag);
                        return 1;
                }
@@ -673,23 +777,19 @@ U_BOOT_CMD(
 #ifdef CONFIG_OF_BOARD_SETUP
        "fdt boardsetup                      - Do board-specific set up\n"
 #endif
-       "fdt move   <fdt> <newaddr> <length> - Copy the fdt to <addr>\n"
+       "fdt move   <fdt> <newaddr> <length> - Copy the fdt to <addr> and make it active\n"
        "fdt print  <path> [<prop>]          - Recursive print starting at <path>\n"
        "fdt list   <path> [<prop>]          - Print one level starting at <path>\n"
        "fdt set    <path> <prop> [<val>]    - Set <property> [to <val>]\n"
        "fdt mknode <path> <node>            - Create a new node after <path>\n"
        "fdt rm     <path> [<prop>]          - Delete the node or <property>\n"
+       "fdt header                          - Display header info\n"
+       "fdt bootcpu <id>                    - Set boot cpuid\n"
+       "fdt memory <addr> <size>            - Add/Update memory node\n"
+       "fdt rsvmem print                    - Show current mem reserves\n"
+       "fdt rsvmem add <addr> <size>        - Add a mem reserve\n"
+       "fdt rsvmem delete <index>           - Delete a mem reserves\n"
        "fdt chosen - Add/update the /chosen branch in the tree\n"
-#ifdef CONFIG_OF_HAS_UBOOT_ENV
-       "fdt env    - Add/replace the /u-boot-env branch in the tree\n"
-#endif
-#ifdef CONFIG_OF_HAS_BD_T
-       "fdt bd_t   - Add/replace the /bd_t branch in the tree\n"
-#endif
-       "Hints:\n"
-       " If the property you are setting/printing has a '#' character or spaces,\n"
-       "     you MUST escape it with a \\ character or quote it with \".\n"
-       "Examples: fdt print /               # print the whole tree\n"
-       "          fdt print /cpus \"#address-cells\"\n"
-       "          fdt set   /cpus \"#address-cells\" \"[00 00 00 01]\"\n"
+       "NOTE: If the path or property you are setting/printing has a '#' character\n"
+       "     or spaces, you MUST escape it with a \\ character or quote it with \".\n"
 );