simpleboot.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // SPDX-License-Identifier: GPL-2.0-only
  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. #include "ops.h"
  15. #include "types.h"
  16. #include "io.h"
  17. #include "stdio.h"
  18. #include <libfdt.h>
  19. BSS_STACK(4*1024);
  20. extern int platform_specific_init(void) __attribute__((weak));
  21. void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
  22. unsigned long r6, unsigned long r7)
  23. {
  24. const u32 *na, *ns, *reg, *timebase;
  25. u64 memsize64;
  26. int node, size, i;
  27. /* Make sure FDT blob is sane */
  28. if (fdt_check_header(_dtb_start) != 0)
  29. fatal("Invalid device tree blob\n");
  30. /* Find the #address-cells and #size-cells properties */
  31. node = fdt_path_offset(_dtb_start, "/");
  32. if (node < 0)
  33. fatal("Cannot find root node\n");
  34. na = fdt_getprop(_dtb_start, node, "#address-cells", &size);
  35. if (!na || (size != 4))
  36. fatal("Cannot find #address-cells property");
  37. ns = fdt_getprop(_dtb_start, node, "#size-cells", &size);
  38. if (!ns || (size != 4))
  39. fatal("Cannot find #size-cells property");
  40. /* Find the memory range */
  41. node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
  42. "memory", sizeof("memory"));
  43. if (node < 0)
  44. fatal("Cannot find memory node\n");
  45. reg = fdt_getprop(_dtb_start, node, "reg", &size);
  46. if (size < (*na+*ns) * sizeof(u32))
  47. fatal("cannot get memory range\n");
  48. /* Only interested in memory based at 0 */
  49. for (i = 0; i < *na; i++)
  50. if (*reg++ != 0)
  51. fatal("Memory range is not based at address 0\n");
  52. /* get the memsize and truncate it to under 4G on 32 bit machines */
  53. memsize64 = 0;
  54. for (i = 0; i < *ns; i++)
  55. memsize64 = (memsize64 << 32) | *reg++;
  56. if (sizeof(void *) == 4 && memsize64 >= 0x100000000ULL)
  57. memsize64 = 0xffffffff;
  58. /* finally, setup the timebase */
  59. node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
  60. "cpu", sizeof("cpu"));
  61. if (!node)
  62. fatal("Cannot find cpu node\n");
  63. timebase = fdt_getprop(_dtb_start, node, "timebase-frequency", &size);
  64. if (timebase && (size == 4))
  65. timebase_period_ns = 1000000000 / *timebase;
  66. /* Now we have the memory size; initialize the heap */
  67. simple_alloc_init(_end, memsize64 - (unsigned long)_end, 32, 64);
  68. /* prepare the device tree and find the console */
  69. fdt_init(_dtb_start);
  70. if (platform_specific_init)
  71. platform_specific_init();
  72. serial_console_init();
  73. }