1 // SPDX-License-Identifier: GPL-2.0-only
3 * The simple platform -- for booting when firmware doesn't supply a device
4 * tree or any platform configuration information.
5 * All data is extracted from an embedded device tree
8 * Authors: Scott Wood <scottwood@freescale.com>
9 * Grant Likely <grant.likely@secretlab.ca>
11 * Copyright (c) 2007 Freescale Semiconductor, Inc.
12 * Copyright (c) 2008 Secret Lab Technologies Ltd.
23 extern int platform_specific_init(void) __attribute__((weak
));
25 void platform_init(unsigned long r3
, unsigned long r4
, unsigned long r5
,
26 unsigned long r6
, unsigned long r7
)
28 const u32
*na
, *ns
, *reg
, *timebase
;
32 /* Make sure FDT blob is sane */
33 if (fdt_check_header(_dtb_start
) != 0)
34 fatal("Invalid device tree blob\n");
36 /* Find the #address-cells and #size-cells properties */
37 node
= fdt_path_offset(_dtb_start
, "/");
39 fatal("Cannot find root node\n");
40 na
= fdt_getprop(_dtb_start
, node
, "#address-cells", &size
);
41 if (!na
|| (size
!= 4))
42 fatal("Cannot find #address-cells property");
43 ns
= fdt_getprop(_dtb_start
, node
, "#size-cells", &size
);
44 if (!ns
|| (size
!= 4))
45 fatal("Cannot find #size-cells property");
47 /* Find the memory range */
48 node
= fdt_node_offset_by_prop_value(_dtb_start
, -1, "device_type",
49 "memory", sizeof("memory"));
51 fatal("Cannot find memory node\n");
52 reg
= fdt_getprop(_dtb_start
, node
, "reg", &size
);
53 if (size
< (*na
+*ns
) * sizeof(u32
))
54 fatal("cannot get memory range\n");
56 /* Only interested in memory based at 0 */
57 for (i
= 0; i
< *na
; i
++)
59 fatal("Memory range is not based at address 0\n");
61 /* get the memsize and truncate it to under 4G on 32 bit machines */
63 for (i
= 0; i
< *ns
; i
++)
64 memsize64
= (memsize64
<< 32) | *reg
++;
65 if (sizeof(void *) == 4 && memsize64
>= 0x100000000ULL
)
66 memsize64
= 0xffffffff;
68 /* finally, setup the timebase */
69 node
= fdt_node_offset_by_prop_value(_dtb_start
, -1, "device_type",
70 "cpu", sizeof("cpu"));
72 fatal("Cannot find cpu node\n");
73 timebase
= fdt_getprop(_dtb_start
, node
, "timebase-frequency", &size
);
74 if (timebase
&& (size
== 4))
75 timebase_period_ns
= 1000000000 / *timebase
;
77 /* Now we have the memory size; initialize the heap */
78 simple_alloc_init(_end
, memsize64
- (unsigned long)_end
, 32, 64);
80 /* prepare the device tree and find the console */
83 if (platform_specific_init
)
84 platform_specific_init();
86 serial_console_init();