| 1 | |
| 2 | |
| 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
|
| 6 | * blob.
|
| 7 | *
|
| 8 | * Authors: Scott Wood <[email protected]>
|
| 9 | * Grant Likely <[email protected]>
|
| 10 | *
|
| 11 | * Copyright (c) 2007 Freescale Semiconductor, Inc.
|
| 12 | * Copyright (c) 2008 Secret Lab Technologies Ltd.
|
| 13 |
|
| 14 |
|
| 15 | #include "ops.h"
|
| 16 | #include "types.h"
|
| 17 | #include "io.h"
|
| 18 | #include "stdio.h"
|
| 19 | #include <libfdt.h>
|
| 20 |
|
| 21 | BSS_STACK(4*1024);
|
| 22 |
|
| 23 | extern int platform_specific_init(void) __attribute__((weak));
|
| 24 |
|
| 25 | void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
|
| 26 | unsigned long r6, unsigned long r7)
|
| 27 | {
|
| 28 | const u32 *na, *ns, *reg, *timebase;
|
| 29 | u64 memsize64;
|
| 30 | int node, size, i;
|
| 31 |
|
| 32 |
|
| 33 | if (fdt_check_header(_dtb_start) != 0)
|
| 34 | fatal("Invalid device tree blob\n");
|
| 35 |
|
| 36 |
|
| 37 | node = fdt_path_offset(_dtb_start, "/");
|
| 38 | if (node < 0)
|
| 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");
|
| 46 |
|
| 47 |
|
| 48 | node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
|
| 49 | "memory", sizeof("memory"));
|
| 50 | if (node < 0)
|
| 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");
|
| 55 |
|
| 56 |
|
| 57 | for (i = 0; i < *na; i++)
|
| 58 | if (*reg++ != 0)
|
| 59 | fatal("Memory range is not based at address 0\n");
|
| 60 |
|
| 61 |
|
| 62 | memsize64 = 0;
|
| 63 | for (i = 0; i < *ns; i++)
|
| 64 | memsize64 = (memsize64 << 32) | *reg++;
|
| 65 | if (sizeof(void *) == 4 && memsize64 >= 0x100000000ULL)
|
| 66 | memsize64 = 0xffffffff;
|
| 67 |
|
| 68 |
|
| 69 | node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
|
| 70 | "cpu", sizeof("cpu"));
|
| 71 | if (node < 0)
|
| 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;
|
| 76 |
|
| 77 |
|
| 78 | simple_alloc_init(_end, memsize64 - (unsigned long)_end, 32, 64);
|
| 79 |
|
| 80 |
|
| 81 | fdt_init(_dtb_start);
|
| 82 |
|
| 83 | if (platform_specific_init)
|
| 84 | platform_specific_init();
|
| 85 |
|
| 86 | serial_console_init();
|
| 87 | }
|