Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Functions for working with the Flattened Device Tree data format
0004  *
0005  * Copyright 2009 Benjamin Herrenschmidt, IBM Corp
0006  * benh@kernel.crashing.org
0007  */
0008 
0009 #define pr_fmt(fmt) "OF: fdt: " fmt
0010 
0011 #include <linux/crash_dump.h>
0012 #include <linux/crc32.h>
0013 #include <linux/kernel.h>
0014 #include <linux/initrd.h>
0015 #include <linux/memblock.h>
0016 #include <linux/mutex.h>
0017 #include <linux/of.h>
0018 #include <linux/of_fdt.h>
0019 #include <linux/of_reserved_mem.h>
0020 #include <linux/sizes.h>
0021 #include <linux/string.h>
0022 #include <linux/errno.h>
0023 #include <linux/slab.h>
0024 #include <linux/libfdt.h>
0025 #include <linux/debugfs.h>
0026 #include <linux/serial_core.h>
0027 #include <linux/sysfs.h>
0028 #include <linux/random.h>
0029 #include <linux/kmemleak.h>
0030 
0031 #include <asm/setup.h>  /* for COMMAND_LINE_SIZE */
0032 #include <asm/page.h>
0033 
0034 #include "of_private.h"
0035 
0036 /*
0037  * of_fdt_limit_memory - limit the number of regions in the /memory node
0038  * @limit: maximum entries
0039  *
0040  * Adjust the flattened device tree to have at most 'limit' number of
0041  * memory entries in the /memory node. This function may be called
0042  * any time after initial_boot_param is set.
0043  */
0044 void __init of_fdt_limit_memory(int limit)
0045 {
0046     int memory;
0047     int len;
0048     const void *val;
0049     int nr_address_cells = OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
0050     int nr_size_cells = OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
0051     const __be32 *addr_prop;
0052     const __be32 *size_prop;
0053     int root_offset;
0054     int cell_size;
0055 
0056     root_offset = fdt_path_offset(initial_boot_params, "/");
0057     if (root_offset < 0)
0058         return;
0059 
0060     addr_prop = fdt_getprop(initial_boot_params, root_offset,
0061                 "#address-cells", NULL);
0062     if (addr_prop)
0063         nr_address_cells = fdt32_to_cpu(*addr_prop);
0064 
0065     size_prop = fdt_getprop(initial_boot_params, root_offset,
0066                 "#size-cells", NULL);
0067     if (size_prop)
0068         nr_size_cells = fdt32_to_cpu(*size_prop);
0069 
0070     cell_size = sizeof(uint32_t)*(nr_address_cells + nr_size_cells);
0071 
0072     memory = fdt_path_offset(initial_boot_params, "/memory");
0073     if (memory > 0) {
0074         val = fdt_getprop(initial_boot_params, memory, "reg", &len);
0075         if (len > limit*cell_size) {
0076             len = limit*cell_size;
0077             pr_debug("Limiting number of entries to %d\n", limit);
0078             fdt_setprop(initial_boot_params, memory, "reg", val,
0079                     len);
0080         }
0081     }
0082 }
0083 
0084 static bool of_fdt_device_is_available(const void *blob, unsigned long node)
0085 {
0086     const char *status = fdt_getprop(blob, node, "status", NULL);
0087 
0088     if (!status)
0089         return true;
0090 
0091     if (!strcmp(status, "ok") || !strcmp(status, "okay"))
0092         return true;
0093 
0094     return false;
0095 }
0096 
0097 static void *unflatten_dt_alloc(void **mem, unsigned long size,
0098                        unsigned long align)
0099 {
0100     void *res;
0101 
0102     *mem = PTR_ALIGN(*mem, align);
0103     res = *mem;
0104     *mem += size;
0105 
0106     return res;
0107 }
0108 
0109 static void populate_properties(const void *blob,
0110                 int offset,
0111                 void **mem,
0112                 struct device_node *np,
0113                 const char *nodename,
0114                 bool dryrun)
0115 {
0116     struct property *pp, **pprev = NULL;
0117     int cur;
0118     bool has_name = false;
0119 
0120     pprev = &np->properties;
0121     for (cur = fdt_first_property_offset(blob, offset);
0122          cur >= 0;
0123          cur = fdt_next_property_offset(blob, cur)) {
0124         const __be32 *val;
0125         const char *pname;
0126         u32 sz;
0127 
0128         val = fdt_getprop_by_offset(blob, cur, &pname, &sz);
0129         if (!val) {
0130             pr_warn("Cannot locate property at 0x%x\n", cur);
0131             continue;
0132         }
0133 
0134         if (!pname) {
0135             pr_warn("Cannot find property name at 0x%x\n", cur);
0136             continue;
0137         }
0138 
0139         if (!strcmp(pname, "name"))
0140             has_name = true;
0141 
0142         pp = unflatten_dt_alloc(mem, sizeof(struct property),
0143                     __alignof__(struct property));
0144         if (dryrun)
0145             continue;
0146 
0147         /* We accept flattened tree phandles either in
0148          * ePAPR-style "phandle" properties, or the
0149          * legacy "linux,phandle" properties.  If both
0150          * appear and have different values, things
0151          * will get weird. Don't do that.
0152          */
0153         if (!strcmp(pname, "phandle") ||
0154             !strcmp(pname, "linux,phandle")) {
0155             if (!np->phandle)
0156                 np->phandle = be32_to_cpup(val);
0157         }
0158 
0159         /* And we process the "ibm,phandle" property
0160          * used in pSeries dynamic device tree
0161          * stuff
0162          */
0163         if (!strcmp(pname, "ibm,phandle"))
0164             np->phandle = be32_to_cpup(val);
0165 
0166         pp->name   = (char *)pname;
0167         pp->length = sz;
0168         pp->value  = (__be32 *)val;
0169         *pprev     = pp;
0170         pprev      = &pp->next;
0171     }
0172 
0173     /* With version 0x10 we may not have the name property,
0174      * recreate it here from the unit name if absent
0175      */
0176     if (!has_name) {
0177         const char *p = nodename, *ps = p, *pa = NULL;
0178         int len;
0179 
0180         while (*p) {
0181             if ((*p) == '@')
0182                 pa = p;
0183             else if ((*p) == '/')
0184                 ps = p + 1;
0185             p++;
0186         }
0187 
0188         if (pa < ps)
0189             pa = p;
0190         len = (pa - ps) + 1;
0191         pp = unflatten_dt_alloc(mem, sizeof(struct property) + len,
0192                     __alignof__(struct property));
0193         if (!dryrun) {
0194             pp->name   = "name";
0195             pp->length = len;
0196             pp->value  = pp + 1;
0197             *pprev     = pp;
0198             memcpy(pp->value, ps, len - 1);
0199             ((char *)pp->value)[len - 1] = 0;
0200             pr_debug("fixed up name for %s -> %s\n",
0201                  nodename, (char *)pp->value);
0202         }
0203     }
0204 }
0205 
0206 static int populate_node(const void *blob,
0207               int offset,
0208               void **mem,
0209               struct device_node *dad,
0210               struct device_node **pnp,
0211               bool dryrun)
0212 {
0213     struct device_node *np;
0214     const char *pathp;
0215     int len;
0216 
0217     pathp = fdt_get_name(blob, offset, &len);
0218     if (!pathp) {
0219         *pnp = NULL;
0220         return len;
0221     }
0222 
0223     len++;
0224 
0225     np = unflatten_dt_alloc(mem, sizeof(struct device_node) + len,
0226                 __alignof__(struct device_node));
0227     if (!dryrun) {
0228         char *fn;
0229         of_node_init(np);
0230         np->full_name = fn = ((char *)np) + sizeof(*np);
0231 
0232         memcpy(fn, pathp, len);
0233 
0234         if (dad != NULL) {
0235             np->parent = dad;
0236             np->sibling = dad->child;
0237             dad->child = np;
0238         }
0239     }
0240 
0241     populate_properties(blob, offset, mem, np, pathp, dryrun);
0242     if (!dryrun) {
0243         np->name = of_get_property(np, "name", NULL);
0244         if (!np->name)
0245             np->name = "<NULL>";
0246     }
0247 
0248     *pnp = np;
0249     return 0;
0250 }
0251 
0252 static void reverse_nodes(struct device_node *parent)
0253 {
0254     struct device_node *child, *next;
0255 
0256     /* In-depth first */
0257     child = parent->child;
0258     while (child) {
0259         reverse_nodes(child);
0260 
0261         child = child->sibling;
0262     }
0263 
0264     /* Reverse the nodes in the child list */
0265     child = parent->child;
0266     parent->child = NULL;
0267     while (child) {
0268         next = child->sibling;
0269 
0270         child->sibling = parent->child;
0271         parent->child = child;
0272         child = next;
0273     }
0274 }
0275 
0276 /**
0277  * unflatten_dt_nodes - Alloc and populate a device_node from the flat tree
0278  * @blob: The parent device tree blob
0279  * @mem: Memory chunk to use for allocating device nodes and properties
0280  * @dad: Parent struct device_node
0281  * @nodepp: The device_node tree created by the call
0282  *
0283  * Return: The size of unflattened device tree or error code
0284  */
0285 static int unflatten_dt_nodes(const void *blob,
0286                   void *mem,
0287                   struct device_node *dad,
0288                   struct device_node **nodepp)
0289 {
0290     struct device_node *root;
0291     int offset = 0, depth = 0, initial_depth = 0;
0292 #define FDT_MAX_DEPTH   64
0293     struct device_node *nps[FDT_MAX_DEPTH];
0294     void *base = mem;
0295     bool dryrun = !base;
0296     int ret;
0297 
0298     if (nodepp)
0299         *nodepp = NULL;
0300 
0301     /*
0302      * We're unflattening device sub-tree if @dad is valid. There are
0303      * possibly multiple nodes in the first level of depth. We need
0304      * set @depth to 1 to make fdt_next_node() happy as it bails
0305      * immediately when negative @depth is found. Otherwise, the device
0306      * nodes except the first one won't be unflattened successfully.
0307      */
0308     if (dad)
0309         depth = initial_depth = 1;
0310 
0311     root = dad;
0312     nps[depth] = dad;
0313 
0314     for (offset = 0;
0315          offset >= 0 && depth >= initial_depth;
0316          offset = fdt_next_node(blob, offset, &depth)) {
0317         if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH - 1))
0318             continue;
0319 
0320         if (!IS_ENABLED(CONFIG_OF_KOBJ) &&
0321             !of_fdt_device_is_available(blob, offset))
0322             continue;
0323 
0324         ret = populate_node(blob, offset, &mem, nps[depth],
0325                    &nps[depth+1], dryrun);
0326         if (ret < 0)
0327             return ret;
0328 
0329         if (!dryrun && nodepp && !*nodepp)
0330             *nodepp = nps[depth+1];
0331         if (!dryrun && !root)
0332             root = nps[depth+1];
0333     }
0334 
0335     if (offset < 0 && offset != -FDT_ERR_NOTFOUND) {
0336         pr_err("Error %d processing FDT\n", offset);
0337         return -EINVAL;
0338     }
0339 
0340     /*
0341      * Reverse the child list. Some drivers assumes node order matches .dts
0342      * node order
0343      */
0344     if (!dryrun)
0345         reverse_nodes(root);
0346 
0347     return mem - base;
0348 }
0349 
0350 /**
0351  * __unflatten_device_tree - create tree of device_nodes from flat blob
0352  * @blob: The blob to expand
0353  * @dad: Parent device node
0354  * @mynodes: The device_node tree created by the call
0355  * @dt_alloc: An allocator that provides a virtual address to memory
0356  * for the resulting tree
0357  * @detached: if true set OF_DETACHED on @mynodes
0358  *
0359  * unflattens a device-tree, creating the tree of struct device_node. It also
0360  * fills the "name" and "type" pointers of the nodes so the normal device-tree
0361  * walking functions can be used.
0362  *
0363  * Return: NULL on failure or the memory chunk containing the unflattened
0364  * device tree on success.
0365  */
0366 void *__unflatten_device_tree(const void *blob,
0367                   struct device_node *dad,
0368                   struct device_node **mynodes,
0369                   void *(*dt_alloc)(u64 size, u64 align),
0370                   bool detached)
0371 {
0372     int size;
0373     void *mem;
0374     int ret;
0375 
0376     if (mynodes)
0377         *mynodes = NULL;
0378 
0379     pr_debug(" -> unflatten_device_tree()\n");
0380 
0381     if (!blob) {
0382         pr_debug("No device tree pointer\n");
0383         return NULL;
0384     }
0385 
0386     pr_debug("Unflattening device tree:\n");
0387     pr_debug("magic: %08x\n", fdt_magic(blob));
0388     pr_debug("size: %08x\n", fdt_totalsize(blob));
0389     pr_debug("version: %08x\n", fdt_version(blob));
0390 
0391     if (fdt_check_header(blob)) {
0392         pr_err("Invalid device tree blob header\n");
0393         return NULL;
0394     }
0395 
0396     /* First pass, scan for size */
0397     size = unflatten_dt_nodes(blob, NULL, dad, NULL);
0398     if (size <= 0)
0399         return NULL;
0400 
0401     size = ALIGN(size, 4);
0402     pr_debug("  size is %d, allocating...\n", size);
0403 
0404     /* Allocate memory for the expanded device tree */
0405     mem = dt_alloc(size + 4, __alignof__(struct device_node));
0406     if (!mem)
0407         return NULL;
0408 
0409     memset(mem, 0, size);
0410 
0411     *(__be32 *)(mem + size) = cpu_to_be32(0xdeadbeef);
0412 
0413     pr_debug("  unflattening %p...\n", mem);
0414 
0415     /* Second pass, do actual unflattening */
0416     ret = unflatten_dt_nodes(blob, mem, dad, mynodes);
0417 
0418     if (be32_to_cpup(mem + size) != 0xdeadbeef)
0419         pr_warn("End of tree marker overwritten: %08x\n",
0420             be32_to_cpup(mem + size));
0421 
0422     if (ret <= 0)
0423         return NULL;
0424 
0425     if (detached && mynodes && *mynodes) {
0426         of_node_set_flag(*mynodes, OF_DETACHED);
0427         pr_debug("unflattened tree is detached\n");
0428     }
0429 
0430     pr_debug(" <- unflatten_device_tree()\n");
0431     return mem;
0432 }
0433 
0434 static void *kernel_tree_alloc(u64 size, u64 align)
0435 {
0436     return kzalloc(size, GFP_KERNEL);
0437 }
0438 
0439 static DEFINE_MUTEX(of_fdt_unflatten_mutex);
0440 
0441 /**
0442  * of_fdt_unflatten_tree - create tree of device_nodes from flat blob
0443  * @blob: Flat device tree blob
0444  * @dad: Parent device node
0445  * @mynodes: The device tree created by the call
0446  *
0447  * unflattens the device-tree passed by the firmware, creating the
0448  * tree of struct device_node. It also fills the "name" and "type"
0449  * pointers of the nodes so the normal device-tree walking functions
0450  * can be used.
0451  *
0452  * Return: NULL on failure or the memory chunk containing the unflattened
0453  * device tree on success.
0454  */
0455 void *of_fdt_unflatten_tree(const unsigned long *blob,
0456                 struct device_node *dad,
0457                 struct device_node **mynodes)
0458 {
0459     void *mem;
0460 
0461     mutex_lock(&of_fdt_unflatten_mutex);
0462     mem = __unflatten_device_tree(blob, dad, mynodes, &kernel_tree_alloc,
0463                       true);
0464     mutex_unlock(&of_fdt_unflatten_mutex);
0465 
0466     return mem;
0467 }
0468 EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree);
0469 
0470 /* Everything below here references initial_boot_params directly. */
0471 int __initdata dt_root_addr_cells;
0472 int __initdata dt_root_size_cells;
0473 
0474 void *initial_boot_params __ro_after_init;
0475 
0476 #ifdef CONFIG_OF_EARLY_FLATTREE
0477 
0478 static u32 of_fdt_crc32;
0479 
0480 static int __init early_init_dt_reserve_memory(phys_addr_t base,
0481                            phys_addr_t size, bool nomap)
0482 {
0483     if (nomap) {
0484         /*
0485          * If the memory is already reserved (by another region), we
0486          * should not allow it to be marked nomap, but don't worry
0487          * if the region isn't memory as it won't be mapped.
0488          */
0489         if (memblock_overlaps_region(&memblock.memory, base, size) &&
0490             memblock_is_region_reserved(base, size))
0491             return -EBUSY;
0492 
0493         return memblock_mark_nomap(base, size);
0494     }
0495     return memblock_reserve(base, size);
0496 }
0497 
0498 /*
0499  * __reserved_mem_reserve_reg() - reserve all memory described in 'reg' property
0500  */
0501 static int __init __reserved_mem_reserve_reg(unsigned long node,
0502                          const char *uname)
0503 {
0504     int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
0505     phys_addr_t base, size;
0506     int len;
0507     const __be32 *prop;
0508     int first = 1;
0509     bool nomap;
0510 
0511     prop = of_get_flat_dt_prop(node, "reg", &len);
0512     if (!prop)
0513         return -ENOENT;
0514 
0515     if (len && len % t_len != 0) {
0516         pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n",
0517                uname);
0518         return -EINVAL;
0519     }
0520 
0521     nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
0522 
0523     while (len >= t_len) {
0524         base = dt_mem_next_cell(dt_root_addr_cells, &prop);
0525         size = dt_mem_next_cell(dt_root_size_cells, &prop);
0526 
0527         if (size &&
0528             early_init_dt_reserve_memory(base, size, nomap) == 0) {
0529             pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n",
0530                 uname, &base, (unsigned long)(size / SZ_1M));
0531             if (!nomap)
0532                 kmemleak_alloc_phys(base, size, 0);
0533         }
0534         else
0535             pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n",
0536                    uname, &base, (unsigned long)(size / SZ_1M));
0537 
0538         len -= t_len;
0539         if (first) {
0540             fdt_reserved_mem_save_node(node, uname, base, size);
0541             first = 0;
0542         }
0543     }
0544     return 0;
0545 }
0546 
0547 /*
0548  * __reserved_mem_check_root() - check if #size-cells, #address-cells provided
0549  * in /reserved-memory matches the values supported by the current implementation,
0550  * also check if ranges property has been provided
0551  */
0552 static int __init __reserved_mem_check_root(unsigned long node)
0553 {
0554     const __be32 *prop;
0555 
0556     prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
0557     if (!prop || be32_to_cpup(prop) != dt_root_size_cells)
0558         return -EINVAL;
0559 
0560     prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
0561     if (!prop || be32_to_cpup(prop) != dt_root_addr_cells)
0562         return -EINVAL;
0563 
0564     prop = of_get_flat_dt_prop(node, "ranges", NULL);
0565     if (!prop)
0566         return -EINVAL;
0567     return 0;
0568 }
0569 
0570 /*
0571  * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory
0572  */
0573 static int __init fdt_scan_reserved_mem(void)
0574 {
0575     int node, child;
0576     const void *fdt = initial_boot_params;
0577 
0578     node = fdt_path_offset(fdt, "/reserved-memory");
0579     if (node < 0)
0580         return -ENODEV;
0581 
0582     if (__reserved_mem_check_root(node) != 0) {
0583         pr_err("Reserved memory: unsupported node format, ignoring\n");
0584         return -EINVAL;
0585     }
0586 
0587     fdt_for_each_subnode(child, fdt, node) {
0588         const char *uname;
0589         int err;
0590 
0591         if (!of_fdt_device_is_available(fdt, child))
0592             continue;
0593 
0594         uname = fdt_get_name(fdt, child, NULL);
0595 
0596         err = __reserved_mem_reserve_reg(child, uname);
0597         if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL))
0598             fdt_reserved_mem_save_node(child, uname, 0, 0);
0599     }
0600     return 0;
0601 }
0602 
0603 /*
0604  * fdt_reserve_elfcorehdr() - reserves memory for elf core header
0605  *
0606  * This function reserves the memory occupied by an elf core header
0607  * described in the device tree. This region contains all the
0608  * information about primary kernel's core image and is used by a dump
0609  * capture kernel to access the system memory on primary kernel.
0610  */
0611 static void __init fdt_reserve_elfcorehdr(void)
0612 {
0613     if (!IS_ENABLED(CONFIG_CRASH_DUMP) || !elfcorehdr_size)
0614         return;
0615 
0616     if (memblock_is_region_reserved(elfcorehdr_addr, elfcorehdr_size)) {
0617         pr_warn("elfcorehdr is overlapped\n");
0618         return;
0619     }
0620 
0621     memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
0622 
0623     pr_info("Reserving %llu KiB of memory at 0x%llx for elfcorehdr\n",
0624         elfcorehdr_size >> 10, elfcorehdr_addr);
0625 }
0626 
0627 /**
0628  * early_init_fdt_scan_reserved_mem() - create reserved memory regions
0629  *
0630  * This function grabs memory from early allocator for device exclusive use
0631  * defined in device tree structures. It should be called by arch specific code
0632  * once the early allocator (i.e. memblock) has been fully activated.
0633  */
0634 void __init early_init_fdt_scan_reserved_mem(void)
0635 {
0636     int n;
0637     u64 base, size;
0638 
0639     if (!initial_boot_params)
0640         return;
0641 
0642     /* Process header /memreserve/ fields */
0643     for (n = 0; ; n++) {
0644         fdt_get_mem_rsv(initial_boot_params, n, &base, &size);
0645         if (!size)
0646             break;
0647         memblock_reserve(base, size);
0648     }
0649 
0650     fdt_scan_reserved_mem();
0651     fdt_reserve_elfcorehdr();
0652     fdt_init_reserved_mem();
0653 }
0654 
0655 /**
0656  * early_init_fdt_reserve_self() - reserve the memory used by the FDT blob
0657  */
0658 void __init early_init_fdt_reserve_self(void)
0659 {
0660     if (!initial_boot_params)
0661         return;
0662 
0663     /* Reserve the dtb region */
0664     memblock_reserve(__pa(initial_boot_params),
0665              fdt_totalsize(initial_boot_params));
0666 }
0667 
0668 /**
0669  * of_scan_flat_dt - scan flattened tree blob and call callback on each.
0670  * @it: callback function
0671  * @data: context data pointer
0672  *
0673  * This function is used to scan the flattened device-tree, it is
0674  * used to extract the memory information at boot before we can
0675  * unflatten the tree
0676  */
0677 int __init of_scan_flat_dt(int (*it)(unsigned long node,
0678                      const char *uname, int depth,
0679                      void *data),
0680                void *data)
0681 {
0682     const void *blob = initial_boot_params;
0683     const char *pathp;
0684     int offset, rc = 0, depth = -1;
0685 
0686     if (!blob)
0687         return 0;
0688 
0689     for (offset = fdt_next_node(blob, -1, &depth);
0690          offset >= 0 && depth >= 0 && !rc;
0691          offset = fdt_next_node(blob, offset, &depth)) {
0692 
0693         pathp = fdt_get_name(blob, offset, NULL);
0694         rc = it(offset, pathp, depth, data);
0695     }
0696     return rc;
0697 }
0698 
0699 /**
0700  * of_scan_flat_dt_subnodes - scan sub-nodes of a node call callback on each.
0701  * @parent: parent node
0702  * @it: callback function
0703  * @data: context data pointer
0704  *
0705  * This function is used to scan sub-nodes of a node.
0706  */
0707 int __init of_scan_flat_dt_subnodes(unsigned long parent,
0708                     int (*it)(unsigned long node,
0709                           const char *uname,
0710                           void *data),
0711                     void *data)
0712 {
0713     const void *blob = initial_boot_params;
0714     int node;
0715 
0716     fdt_for_each_subnode(node, blob, parent) {
0717         const char *pathp;
0718         int rc;
0719 
0720         pathp = fdt_get_name(blob, node, NULL);
0721         rc = it(node, pathp, data);
0722         if (rc)
0723             return rc;
0724     }
0725     return 0;
0726 }
0727 
0728 /**
0729  * of_get_flat_dt_subnode_by_name - get the subnode by given name
0730  *
0731  * @node: the parent node
0732  * @uname: the name of subnode
0733  * @return offset of the subnode, or -FDT_ERR_NOTFOUND if there is none
0734  */
0735 
0736 int __init of_get_flat_dt_subnode_by_name(unsigned long node, const char *uname)
0737 {
0738     return fdt_subnode_offset(initial_boot_params, node, uname);
0739 }
0740 
0741 /*
0742  * of_get_flat_dt_root - find the root node in the flat blob
0743  */
0744 unsigned long __init of_get_flat_dt_root(void)
0745 {
0746     return 0;
0747 }
0748 
0749 /*
0750  * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
0751  *
0752  * This function can be used within scan_flattened_dt callback to get
0753  * access to properties
0754  */
0755 const void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
0756                        int *size)
0757 {
0758     return fdt_getprop(initial_boot_params, node, name, size);
0759 }
0760 
0761 /**
0762  * of_fdt_is_compatible - Return true if given node from the given blob has
0763  * compat in its compatible list
0764  * @blob: A device tree blob
0765  * @node: node to test
0766  * @compat: compatible string to compare with compatible list.
0767  *
0768  * Return: a non-zero value on match with smaller values returned for more
0769  * specific compatible values.
0770  */
0771 static int of_fdt_is_compatible(const void *blob,
0772               unsigned long node, const char *compat)
0773 {
0774     const char *cp;
0775     int cplen;
0776     unsigned long l, score = 0;
0777 
0778     cp = fdt_getprop(blob, node, "compatible", &cplen);
0779     if (cp == NULL)
0780         return 0;
0781     while (cplen > 0) {
0782         score++;
0783         if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
0784             return score;
0785         l = strlen(cp) + 1;
0786         cp += l;
0787         cplen -= l;
0788     }
0789 
0790     return 0;
0791 }
0792 
0793 /**
0794  * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
0795  * @node: node to test
0796  * @compat: compatible string to compare with compatible list.
0797  */
0798 int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
0799 {
0800     return of_fdt_is_compatible(initial_boot_params, node, compat);
0801 }
0802 
0803 /*
0804  * of_flat_dt_match - Return true if node matches a list of compatible values
0805  */
0806 static int __init of_flat_dt_match(unsigned long node, const char *const *compat)
0807 {
0808     unsigned int tmp, score = 0;
0809 
0810     if (!compat)
0811         return 0;
0812 
0813     while (*compat) {
0814         tmp = of_fdt_is_compatible(initial_boot_params, node, *compat);
0815         if (tmp && (score == 0 || (tmp < score)))
0816             score = tmp;
0817         compat++;
0818     }
0819 
0820     return score;
0821 }
0822 
0823 /*
0824  * of_get_flat_dt_phandle - Given a node in the flat blob, return the phandle
0825  */
0826 uint32_t __init of_get_flat_dt_phandle(unsigned long node)
0827 {
0828     return fdt_get_phandle(initial_boot_params, node);
0829 }
0830 
0831 struct fdt_scan_status {
0832     const char *name;
0833     int namelen;
0834     int depth;
0835     int found;
0836     int (*iterator)(unsigned long node, const char *uname, int depth, void *data);
0837     void *data;
0838 };
0839 
0840 const char * __init of_flat_dt_get_machine_name(void)
0841 {
0842     const char *name;
0843     unsigned long dt_root = of_get_flat_dt_root();
0844 
0845     name = of_get_flat_dt_prop(dt_root, "model", NULL);
0846     if (!name)
0847         name = of_get_flat_dt_prop(dt_root, "compatible", NULL);
0848     return name;
0849 }
0850 
0851 /**
0852  * of_flat_dt_match_machine - Iterate match tables to find matching machine.
0853  *
0854  * @default_match: A machine specific ptr to return in case of no match.
0855  * @get_next_compat: callback function to return next compatible match table.
0856  *
0857  * Iterate through machine match tables to find the best match for the machine
0858  * compatible string in the FDT.
0859  */
0860 const void * __init of_flat_dt_match_machine(const void *default_match,
0861         const void * (*get_next_compat)(const char * const**))
0862 {
0863     const void *data = NULL;
0864     const void *best_data = default_match;
0865     const char *const *compat;
0866     unsigned long dt_root;
0867     unsigned int best_score = ~1, score = 0;
0868 
0869     dt_root = of_get_flat_dt_root();
0870     while ((data = get_next_compat(&compat))) {
0871         score = of_flat_dt_match(dt_root, compat);
0872         if (score > 0 && score < best_score) {
0873             best_data = data;
0874             best_score = score;
0875         }
0876     }
0877     if (!best_data) {
0878         const char *prop;
0879         int size;
0880 
0881         pr_err("\n unrecognized device tree list:\n[ ");
0882 
0883         prop = of_get_flat_dt_prop(dt_root, "compatible", &size);
0884         if (prop) {
0885             while (size > 0) {
0886                 printk("'%s' ", prop);
0887                 size -= strlen(prop) + 1;
0888                 prop += strlen(prop) + 1;
0889             }
0890         }
0891         printk("]\n\n");
0892         return NULL;
0893     }
0894 
0895     pr_info("Machine model: %s\n", of_flat_dt_get_machine_name());
0896 
0897     return best_data;
0898 }
0899 
0900 static void __early_init_dt_declare_initrd(unsigned long start,
0901                        unsigned long end)
0902 {
0903     /* ARM64 would cause a BUG to occur here when CONFIG_DEBUG_VM is
0904      * enabled since __va() is called too early. ARM64 does make use
0905      * of phys_initrd_start/phys_initrd_size so we can skip this
0906      * conversion.
0907      */
0908     if (!IS_ENABLED(CONFIG_ARM64)) {
0909         initrd_start = (unsigned long)__va(start);
0910         initrd_end = (unsigned long)__va(end);
0911         initrd_below_start_ok = 1;
0912     }
0913 }
0914 
0915 /**
0916  * early_init_dt_check_for_initrd - Decode initrd location from flat tree
0917  * @node: reference to node containing initrd location ('chosen')
0918  */
0919 static void __init early_init_dt_check_for_initrd(unsigned long node)
0920 {
0921     u64 start, end;
0922     int len;
0923     const __be32 *prop;
0924 
0925     if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD))
0926         return;
0927 
0928     pr_debug("Looking for initrd properties... ");
0929 
0930     prop = of_get_flat_dt_prop(node, "linux,initrd-start", &len);
0931     if (!prop)
0932         return;
0933     start = of_read_number(prop, len/4);
0934 
0935     prop = of_get_flat_dt_prop(node, "linux,initrd-end", &len);
0936     if (!prop)
0937         return;
0938     end = of_read_number(prop, len/4);
0939 
0940     __early_init_dt_declare_initrd(start, end);
0941     phys_initrd_start = start;
0942     phys_initrd_size = end - start;
0943 
0944     pr_debug("initrd_start=0x%llx  initrd_end=0x%llx\n", start, end);
0945 }
0946 
0947 /**
0948  * early_init_dt_check_for_elfcorehdr - Decode elfcorehdr location from flat
0949  * tree
0950  * @node: reference to node containing elfcorehdr location ('chosen')
0951  */
0952 static void __init early_init_dt_check_for_elfcorehdr(unsigned long node)
0953 {
0954     const __be32 *prop;
0955     int len;
0956 
0957     if (!IS_ENABLED(CONFIG_CRASH_DUMP))
0958         return;
0959 
0960     pr_debug("Looking for elfcorehdr property... ");
0961 
0962     prop = of_get_flat_dt_prop(node, "linux,elfcorehdr", &len);
0963     if (!prop || (len < (dt_root_addr_cells + dt_root_size_cells)))
0964         return;
0965 
0966     elfcorehdr_addr = dt_mem_next_cell(dt_root_addr_cells, &prop);
0967     elfcorehdr_size = dt_mem_next_cell(dt_root_size_cells, &prop);
0968 
0969     pr_debug("elfcorehdr_start=0x%llx elfcorehdr_size=0x%llx\n",
0970          elfcorehdr_addr, elfcorehdr_size);
0971 }
0972 
0973 static unsigned long chosen_node_offset = -FDT_ERR_NOTFOUND;
0974 
0975 /*
0976  * The main usage of linux,usable-memory-range is for crash dump kernel.
0977  * Originally, the number of usable-memory regions is one. Now there may
0978  * be two regions, low region and high region.
0979  * To make compatibility with existing user-space and older kdump, the low
0980  * region is always the last range of linux,usable-memory-range if exist.
0981  */
0982 #define MAX_USABLE_RANGES       2
0983 
0984 /**
0985  * early_init_dt_check_for_usable_mem_range - Decode usable memory range
0986  * location from flat tree
0987  */
0988 void __init early_init_dt_check_for_usable_mem_range(void)
0989 {
0990     struct memblock_region rgn[MAX_USABLE_RANGES] = {0};
0991     const __be32 *prop, *endp;
0992     int len, i;
0993     unsigned long node = chosen_node_offset;
0994 
0995     if ((long)node < 0)
0996         return;
0997 
0998     pr_debug("Looking for usable-memory-range property... ");
0999 
1000     prop = of_get_flat_dt_prop(node, "linux,usable-memory-range", &len);
1001     if (!prop || (len % (dt_root_addr_cells + dt_root_size_cells)))
1002         return;
1003 
1004     endp = prop + (len / sizeof(__be32));
1005     for (i = 0; i < MAX_USABLE_RANGES && prop < endp; i++) {
1006         rgn[i].base = dt_mem_next_cell(dt_root_addr_cells, &prop);
1007         rgn[i].size = dt_mem_next_cell(dt_root_size_cells, &prop);
1008 
1009         pr_debug("cap_mem_regions[%d]: base=%pa, size=%pa\n",
1010              i, &rgn[i].base, &rgn[i].size);
1011     }
1012 
1013     memblock_cap_memory_range(rgn[0].base, rgn[0].size);
1014     for (i = 1; i < MAX_USABLE_RANGES && rgn[i].size; i++)
1015         memblock_add(rgn[i].base, rgn[i].size);
1016 }
1017 
1018 #ifdef CONFIG_SERIAL_EARLYCON
1019 
1020 int __init early_init_dt_scan_chosen_stdout(void)
1021 {
1022     int offset;
1023     const char *p, *q, *options = NULL;
1024     int l;
1025     const struct earlycon_id *match;
1026     const void *fdt = initial_boot_params;
1027     int ret;
1028 
1029     offset = fdt_path_offset(fdt, "/chosen");
1030     if (offset < 0)
1031         offset = fdt_path_offset(fdt, "/chosen@0");
1032     if (offset < 0)
1033         return -ENOENT;
1034 
1035     p = fdt_getprop(fdt, offset, "stdout-path", &l);
1036     if (!p)
1037         p = fdt_getprop(fdt, offset, "linux,stdout-path", &l);
1038     if (!p || !l)
1039         return -ENOENT;
1040 
1041     q = strchrnul(p, ':');
1042     if (*q != '\0')
1043         options = q + 1;
1044     l = q - p;
1045 
1046     /* Get the node specified by stdout-path */
1047     offset = fdt_path_offset_namelen(fdt, p, l);
1048     if (offset < 0) {
1049         pr_warn("earlycon: stdout-path %.*s not found\n", l, p);
1050         return 0;
1051     }
1052 
1053     for (match = __earlycon_table; match < __earlycon_table_end; match++) {
1054         if (!match->compatible[0])
1055             continue;
1056 
1057         if (fdt_node_check_compatible(fdt, offset, match->compatible))
1058             continue;
1059 
1060         ret = of_setup_earlycon(match, offset, options);
1061         if (!ret || ret == -EALREADY)
1062             return 0;
1063     }
1064     return -ENODEV;
1065 }
1066 #endif
1067 
1068 /*
1069  * early_init_dt_scan_root - fetch the top level address and size cells
1070  */
1071 int __init early_init_dt_scan_root(void)
1072 {
1073     const __be32 *prop;
1074     const void *fdt = initial_boot_params;
1075     int node = fdt_path_offset(fdt, "/");
1076 
1077     if (node < 0)
1078         return -ENODEV;
1079 
1080     dt_root_size_cells = OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
1081     dt_root_addr_cells = OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
1082 
1083     prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
1084     if (prop)
1085         dt_root_size_cells = be32_to_cpup(prop);
1086     pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
1087 
1088     prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
1089     if (prop)
1090         dt_root_addr_cells = be32_to_cpup(prop);
1091     pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
1092 
1093     return 0;
1094 }
1095 
1096 u64 __init dt_mem_next_cell(int s, const __be32 **cellp)
1097 {
1098     const __be32 *p = *cellp;
1099 
1100     *cellp = p + s;
1101     return of_read_number(p, s);
1102 }
1103 
1104 /*
1105  * early_init_dt_scan_memory - Look for and parse memory nodes
1106  */
1107 int __init early_init_dt_scan_memory(void)
1108 {
1109     int node;
1110     const void *fdt = initial_boot_params;
1111 
1112     fdt_for_each_subnode(node, fdt, 0) {
1113         const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
1114         const __be32 *reg, *endp;
1115         int l;
1116         bool hotpluggable;
1117 
1118         /* We are scanning "memory" nodes only */
1119         if (type == NULL || strcmp(type, "memory") != 0)
1120             continue;
1121 
1122         if (!of_fdt_device_is_available(fdt, node))
1123             continue;
1124 
1125         reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
1126         if (reg == NULL)
1127             reg = of_get_flat_dt_prop(node, "reg", &l);
1128         if (reg == NULL)
1129             continue;
1130 
1131         endp = reg + (l / sizeof(__be32));
1132         hotpluggable = of_get_flat_dt_prop(node, "hotpluggable", NULL);
1133 
1134         pr_debug("memory scan node %s, reg size %d,\n",
1135              fdt_get_name(fdt, node, NULL), l);
1136 
1137         while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
1138             u64 base, size;
1139 
1140             base = dt_mem_next_cell(dt_root_addr_cells, &reg);
1141             size = dt_mem_next_cell(dt_root_size_cells, &reg);
1142 
1143             if (size == 0)
1144                 continue;
1145             pr_debug(" - %llx, %llx\n", base, size);
1146 
1147             early_init_dt_add_memory_arch(base, size);
1148 
1149             if (!hotpluggable)
1150                 continue;
1151 
1152             if (memblock_mark_hotplug(base, size))
1153                 pr_warn("failed to mark hotplug range 0x%llx - 0x%llx\n",
1154                     base, base + size);
1155         }
1156     }
1157     return 0;
1158 }
1159 
1160 int __init early_init_dt_scan_chosen(char *cmdline)
1161 {
1162     int l, node;
1163     const char *p;
1164     const void *rng_seed;
1165     const void *fdt = initial_boot_params;
1166 
1167     node = fdt_path_offset(fdt, "/chosen");
1168     if (node < 0)
1169         node = fdt_path_offset(fdt, "/chosen@0");
1170     if (node < 0)
1171         return -ENOENT;
1172 
1173     chosen_node_offset = node;
1174 
1175     early_init_dt_check_for_initrd(node);
1176     early_init_dt_check_for_elfcorehdr(node);
1177 
1178     /* Retrieve command line */
1179     p = of_get_flat_dt_prop(node, "bootargs", &l);
1180     if (p != NULL && l > 0)
1181         strlcpy(cmdline, p, min(l, COMMAND_LINE_SIZE));
1182 
1183     /*
1184      * CONFIG_CMDLINE is meant to be a default in case nothing else
1185      * managed to set the command line, unless CONFIG_CMDLINE_FORCE
1186      * is set in which case we override whatever was found earlier.
1187      */
1188 #ifdef CONFIG_CMDLINE
1189 #if defined(CONFIG_CMDLINE_EXTEND)
1190     strlcat(cmdline, " ", COMMAND_LINE_SIZE);
1191     strlcat(cmdline, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
1192 #elif defined(CONFIG_CMDLINE_FORCE)
1193     strlcpy(cmdline, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
1194 #else
1195     /* No arguments from boot loader, use kernel's  cmdl*/
1196     if (!((char *)cmdline)[0])
1197         strlcpy(cmdline, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
1198 #endif
1199 #endif /* CONFIG_CMDLINE */
1200 
1201     pr_debug("Command line is: %s\n", (char *)cmdline);
1202 
1203     rng_seed = of_get_flat_dt_prop(node, "rng-seed", &l);
1204     if (rng_seed && l > 0) {
1205         add_bootloader_randomness(rng_seed, l);
1206 
1207         /* try to clear seed so it won't be found. */
1208         fdt_nop_property(initial_boot_params, node, "rng-seed");
1209 
1210         /* update CRC check value */
1211         of_fdt_crc32 = crc32_be(~0, initial_boot_params,
1212                 fdt_totalsize(initial_boot_params));
1213     }
1214 
1215     return 0;
1216 }
1217 
1218 #ifndef MIN_MEMBLOCK_ADDR
1219 #define MIN_MEMBLOCK_ADDR   __pa(PAGE_OFFSET)
1220 #endif
1221 #ifndef MAX_MEMBLOCK_ADDR
1222 #define MAX_MEMBLOCK_ADDR   ((phys_addr_t)~0)
1223 #endif
1224 
1225 void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
1226 {
1227     const u64 phys_offset = MIN_MEMBLOCK_ADDR;
1228 
1229     if (size < PAGE_SIZE - (base & ~PAGE_MASK)) {
1230         pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
1231             base, base + size);
1232         return;
1233     }
1234 
1235     if (!PAGE_ALIGNED(base)) {
1236         size -= PAGE_SIZE - (base & ~PAGE_MASK);
1237         base = PAGE_ALIGN(base);
1238     }
1239     size &= PAGE_MASK;
1240 
1241     if (base > MAX_MEMBLOCK_ADDR) {
1242         pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
1243             base, base + size);
1244         return;
1245     }
1246 
1247     if (base + size - 1 > MAX_MEMBLOCK_ADDR) {
1248         pr_warn("Ignoring memory range 0x%llx - 0x%llx\n",
1249             ((u64)MAX_MEMBLOCK_ADDR) + 1, base + size);
1250         size = MAX_MEMBLOCK_ADDR - base + 1;
1251     }
1252 
1253     if (base + size < phys_offset) {
1254         pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
1255             base, base + size);
1256         return;
1257     }
1258     if (base < phys_offset) {
1259         pr_warn("Ignoring memory range 0x%llx - 0x%llx\n",
1260             base, phys_offset);
1261         size -= phys_offset - base;
1262         base = phys_offset;
1263     }
1264     memblock_add(base, size);
1265 }
1266 
1267 static void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
1268 {
1269     void *ptr = memblock_alloc(size, align);
1270 
1271     if (!ptr)
1272         panic("%s: Failed to allocate %llu bytes align=0x%llx\n",
1273               __func__, size, align);
1274 
1275     return ptr;
1276 }
1277 
1278 bool __init early_init_dt_verify(void *params)
1279 {
1280     if (!params)
1281         return false;
1282 
1283     /* check device tree validity */
1284     if (fdt_check_header(params))
1285         return false;
1286 
1287     /* Setup flat device-tree pointer */
1288     initial_boot_params = params;
1289     of_fdt_crc32 = crc32_be(~0, initial_boot_params,
1290                 fdt_totalsize(initial_boot_params));
1291     return true;
1292 }
1293 
1294 
1295 void __init early_init_dt_scan_nodes(void)
1296 {
1297     int rc;
1298 
1299     /* Initialize {size,address}-cells info */
1300     early_init_dt_scan_root();
1301 
1302     /* Retrieve various information from the /chosen node */
1303     rc = early_init_dt_scan_chosen(boot_command_line);
1304     if (rc)
1305         pr_warn("No chosen node found, continuing without\n");
1306 
1307     /* Setup memory, calling early_init_dt_add_memory_arch */
1308     early_init_dt_scan_memory();
1309 
1310     /* Handle linux,usable-memory-range property */
1311     early_init_dt_check_for_usable_mem_range();
1312 }
1313 
1314 bool __init early_init_dt_scan(void *params)
1315 {
1316     bool status;
1317 
1318     status = early_init_dt_verify(params);
1319     if (!status)
1320         return false;
1321 
1322     early_init_dt_scan_nodes();
1323     return true;
1324 }
1325 
1326 /**
1327  * unflatten_device_tree - create tree of device_nodes from flat blob
1328  *
1329  * unflattens the device-tree passed by the firmware, creating the
1330  * tree of struct device_node. It also fills the "name" and "type"
1331  * pointers of the nodes so the normal device-tree walking functions
1332  * can be used.
1333  */
1334 void __init unflatten_device_tree(void)
1335 {
1336     __unflatten_device_tree(initial_boot_params, NULL, &of_root,
1337                 early_init_dt_alloc_memory_arch, false);
1338 
1339     /* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */
1340     of_alias_scan(early_init_dt_alloc_memory_arch);
1341 
1342     unittest_unflatten_overlay_base();
1343 }
1344 
1345 /**
1346  * unflatten_and_copy_device_tree - copy and create tree of device_nodes from flat blob
1347  *
1348  * Copies and unflattens the device-tree passed by the firmware, creating the
1349  * tree of struct device_node. It also fills the "name" and "type"
1350  * pointers of the nodes so the normal device-tree walking functions
1351  * can be used. This should only be used when the FDT memory has not been
1352  * reserved such is the case when the FDT is built-in to the kernel init
1353  * section. If the FDT memory is reserved already then unflatten_device_tree
1354  * should be used instead.
1355  */
1356 void __init unflatten_and_copy_device_tree(void)
1357 {
1358     int size;
1359     void *dt;
1360 
1361     if (!initial_boot_params) {
1362         pr_warn("No valid device tree found, continuing without\n");
1363         return;
1364     }
1365 
1366     size = fdt_totalsize(initial_boot_params);
1367     dt = early_init_dt_alloc_memory_arch(size,
1368                          roundup_pow_of_two(FDT_V17_SIZE));
1369 
1370     if (dt) {
1371         memcpy(dt, initial_boot_params, size);
1372         initial_boot_params = dt;
1373     }
1374     unflatten_device_tree();
1375 }
1376 
1377 #ifdef CONFIG_SYSFS
1378 static ssize_t of_fdt_raw_read(struct file *filp, struct kobject *kobj,
1379                    struct bin_attribute *bin_attr,
1380                    char *buf, loff_t off, size_t count)
1381 {
1382     memcpy(buf, initial_boot_params + off, count);
1383     return count;
1384 }
1385 
1386 static int __init of_fdt_raw_init(void)
1387 {
1388     static struct bin_attribute of_fdt_raw_attr =
1389         __BIN_ATTR(fdt, S_IRUSR, of_fdt_raw_read, NULL, 0);
1390 
1391     if (!initial_boot_params)
1392         return 0;
1393 
1394     if (of_fdt_crc32 != crc32_be(~0, initial_boot_params,
1395                      fdt_totalsize(initial_boot_params))) {
1396         pr_warn("not creating '/sys/firmware/fdt': CRC check failed\n");
1397         return 0;
1398     }
1399     of_fdt_raw_attr.size = fdt_totalsize(initial_boot_params);
1400     return sysfs_create_bin_file(firmware_kobj, &of_fdt_raw_attr);
1401 }
1402 late_initcall(of_fdt_raw_init);
1403 #endif
1404 
1405 #endif /* CONFIG_OF_EARLY_FLATTREE */