Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * The simple platform -- for booting when firmware doesn't supply a device
0004  *                        tree or any platform configuration information.
0005  *                        All data is extracted from an embedded device tree
0006  *                        blob.
0007  *
0008  * Authors: Scott Wood <scottwood@freescale.com>
0009  *          Grant Likely <grant.likely@secretlab.ca>
0010  *
0011  * Copyright (c) 2007 Freescale Semiconductor, Inc.
0012  * Copyright (c) 2008 Secret Lab Technologies Ltd.
0013  */
0014 
0015 #include "ops.h"
0016 #include "types.h"
0017 #include "io.h"
0018 #include "stdio.h"
0019 #include <libfdt.h>
0020 
0021 BSS_STACK(4*1024);
0022 
0023 extern int platform_specific_init(void) __attribute__((weak));
0024 
0025 void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
0026            unsigned long r6, unsigned long r7)
0027 {
0028     const u32 *na, *ns, *reg, *timebase;
0029     u64 memsize64;
0030     int node, size, i;
0031 
0032     /* Make sure FDT blob is sane */
0033     if (fdt_check_header(_dtb_start) != 0)
0034         fatal("Invalid device tree blob\n");
0035 
0036     /* Find the #address-cells and #size-cells properties */
0037     node = fdt_path_offset(_dtb_start, "/");
0038     if (node < 0)
0039         fatal("Cannot find root node\n");
0040     na = fdt_getprop(_dtb_start, node, "#address-cells", &size);
0041     if (!na || (size != 4))
0042         fatal("Cannot find #address-cells property");
0043     ns = fdt_getprop(_dtb_start, node, "#size-cells", &size);
0044     if (!ns || (size != 4))
0045         fatal("Cannot find #size-cells property");
0046 
0047     /* Find the memory range */
0048     node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
0049                          "memory", sizeof("memory"));
0050     if (node < 0)
0051         fatal("Cannot find memory node\n");
0052     reg = fdt_getprop(_dtb_start, node, "reg", &size);
0053     if (size < (*na+*ns) * sizeof(u32))
0054         fatal("cannot get memory range\n");
0055 
0056     /* Only interested in memory based at 0 */
0057     for (i = 0; i < *na; i++)
0058         if (*reg++ != 0)
0059             fatal("Memory range is not based at address 0\n");
0060 
0061     /* get the memsize and truncate it to under 4G on 32 bit machines */
0062     memsize64 = 0;
0063     for (i = 0; i < *ns; i++)
0064         memsize64 = (memsize64 << 32) | *reg++;
0065     if (sizeof(void *) == 4 && memsize64 >= 0x100000000ULL)
0066         memsize64 = 0xffffffff;
0067 
0068     /* finally, setup the timebase */
0069     node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
0070                          "cpu", sizeof("cpu"));
0071     if (!node)
0072         fatal("Cannot find cpu node\n");
0073     timebase = fdt_getprop(_dtb_start, node, "timebase-frequency", &size);
0074     if (timebase && (size == 4))
0075         timebase_period_ns = 1000000000 / *timebase;
0076 
0077     /* Now we have the memory size; initialize the heap */
0078     simple_alloc_init(_end, memsize64 - (unsigned long)_end, 32, 64);
0079 
0080     /* prepare the device tree and find the console */
0081     fdt_init(_dtb_start);
0082 
0083     if (platform_specific_init)
0084         platform_specific_init();
0085 
0086     serial_console_init();
0087 }