aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plat/allwinner/common/allwinner-common.mk2
-rw-r--r--plat/allwinner/common/include/platform_def.h2
-rw-r--r--plat/allwinner/common/sunxi_bl31_setup.c55
3 files changed, 58 insertions, 1 deletions
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index 8c772bfc2..2dc058f54 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -13,6 +13,8 @@ PLAT_INCLUDES := -Iinclude/plat/arm/common \
-I${AW_PLAT}/common/include \
-I${AW_PLAT}/${PLAT}/include
+include lib/libfdt/libfdt.mk
+
PLAT_BL_COMMON_SOURCES := drivers/console/${ARCH}/console.S \
drivers/ti/uart/${ARCH}/16550_console.S \
${XLAT_TABLES_LIB_SRCS} \
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index 4f9c00ed1..08eb5cf2b 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.h
@@ -21,7 +21,7 @@
/* How much memory to reserve as secure for BL32, if configured */
#define SUNXI_DRAM_SEC_SIZE (32U << 20)
-/* How much DRAM to map */
+/* How much DRAM to map (to map BL33, for fetching the DTB from U-Boot) */
#define SUNXI_DRAM_MAP_SIZE (64U << 20)
#define CACHE_WRITEBACK_SHIFT 6
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index 6c47e89fc..94b123a64 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -10,6 +10,7 @@
#include <debug.h>
#include <generic_delay_timer.h>
#include <gicv2.h>
+#include <libfdt.h>
#include <platform.h>
#include <platform_def.h>
#include <sunxi_def.h>
@@ -28,6 +29,47 @@ static const gicv2_driver_data_t sunxi_gic_data = {
.gicc_base = SUNXI_GICC_BASE,
};
+/*
+ * Try to find a DTB loaded in memory by previous stages.
+ *
+ * At the moment we implement a heuristic to find the DTB attached to U-Boot:
+ * U-Boot appends its DTB to the end of the image. Assuming that BL33 is
+ * U-Boot, try to find the size of the U-Boot image to learn the DTB address.
+ * The generic ARMv8 U-Boot image contains the load address and its size
+ * as u64 variables at the beginning of the image. There might be padding
+ * or other headers before that data, so scan the first 2KB after the BL33
+ * entry point to find the load address, which should be followed by the
+ * size. Adding those together gives us the address of the DTB.
+ */
+static void *sunxi_find_dtb(void)
+{
+ uint64_t *u_boot_base;
+ int i;
+
+ u_boot_base = (void *)(SUNXI_DRAM_VIRT_BASE + SUNXI_DRAM_SEC_SIZE);
+
+ for (i = 0; i < 2048 / sizeof(uint64_t); i++) {
+ uint32_t *dtb_base;
+
+ if (u_boot_base[i] != PLAT_SUNXI_NS_IMAGE_OFFSET)
+ continue;
+
+ /* Does the suspected U-Boot size look anyhow reasonable? */
+ if (u_boot_base[i + 1] >= 256 * 1024 * 1024)
+ continue;
+
+ /* end of the image: base address + size */
+ dtb_base = (void *)((char *)u_boot_base + u_boot_base[i + 1]);
+
+ if (fdt_check_header(dtb_base) != 0)
+ continue;
+
+ return dtb_base;
+ }
+
+ return NULL;
+}
+
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
@@ -66,6 +108,7 @@ void bl31_platform_setup(void)
{
const char *soc_name;
uint16_t soc_id = sunxi_read_soc_id();
+ void *fdt;
switch (soc_id) {
case SUNXI_SOC_A64:
@@ -85,6 +128,18 @@ void bl31_platform_setup(void)
generic_delay_timer_init();
+ fdt = sunxi_find_dtb();
+ if (fdt) {
+ const char *model;
+ int length;
+
+ model = fdt_getprop(fdt, 0, "model", &length);
+ NOTICE("BL31: Found U-Boot DTB at %p, model: %s\n", fdt,
+ model ?: "unknown");
+ } else {
+ NOTICE("BL31: No DTB found.\n");
+ }
+
/* Configure the interrupt controller */
gicv2_driver_init(&sunxi_gic_data);
gicv2_distif_init();