rpi4: Determine BL33 entry point at runtime
authorAndre Przywara <andre.przywara@arm.com>
Thu, 11 Jul 2019 00:42:12 +0000 (01:42 +0100)
committerAndre Przywara <andre.przywara@arm.com>
Wed, 25 Sep 2019 10:45:35 +0000 (11:45 +0100)
Now that we have the armstub magic value in place, the GPU firmware will
write the kernel load address (and DTB address) into our special page,
so we can always easily access the actual location without hardcoding
any addresses into the BL31 image.

Make the compile-time defined PRELOADED_BL33_BASE macro optional, and
read the BL33 entry point from the magic location, if the macro was not
defined. We do the same for the DTB address.

This also splits the currently "common" definition of
plat_get_ns_image_entrypoint() to be separate between RPi3 and RPi4.

Change-Id: I6f26c0adc6fce2df47786b271c490928b4529abb
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
plat/rpi/common/rpi3_common.c
plat/rpi/rpi3/rpi3_bl31_setup.c
plat/rpi/rpi4/platform.mk
plat/rpi/rpi4/rpi4_bl31_setup.c

index 4317b3a26fac3bc9c24a13818630b944c7d03971..ff3369427d2a4149c34cae4891eac85c37e06020 100644 (file)
@@ -175,18 +175,6 @@ void rpi3_setup_page_tables(uintptr_t total_base, size_t total_size,
        init_xlat_tables();
 }
 
-/*******************************************************************************
- * Return entrypoint of BL33.
- ******************************************************************************/
-uintptr_t plat_get_ns_image_entrypoint(void)
-{
-#ifdef PRELOADED_BL33_BASE
-       return PRELOADED_BL33_BASE;
-#else
-       return PLAT_RPI3_NS_IMAGE_OFFSET;
-#endif
-}
-
 /*******************************************************************************
  * Gets SPSR for BL32 entry
  ******************************************************************************/
index c16dbffaaf96c8355ff00fefa97e7a9cfef18929..24a56139be554b439f9f82e82df4f59e8bc44669 100644 (file)
@@ -47,6 +47,18 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
        }
 }
 
+/*******************************************************************************
+ * Return entrypoint of BL33.
+ ******************************************************************************/
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+#ifdef PRELOADED_BL33_BASE
+       return PRELOADED_BL33_BASE;
+#else
+       return PLAT_RPI3_NS_IMAGE_OFFSET;
+#endif
+}
+
 /*******************************************************************************
  * Perform any BL31 early platform setup. Here is an opportunity to copy
  * parameters passed by the calling EL (S-EL1 in BL2 & EL3 in BL1) before
index b20251cf462f8b2e77d249df923ad99cdd138b5b..6ac21691e498757c7b52d4cfe6899ad73bad5185 100644 (file)
@@ -68,8 +68,8 @@ USE_COHERENT_MEM              := 1
 # Platform build flags
 # --------------------
 
-# Assume that BL33 isn't the Linux kernel by default
-RPI3_DIRECT_LINUX_BOOT         := 0
+# There is not much else than a Linux kernel to load at the moment.
+RPI3_DIRECT_LINUX_BOOT         := 1
 
 # BL33 images are in AArch64 by default
 RPI3_BL33_IN_AARCH32           := 0
@@ -92,15 +92,6 @@ endif
 $(eval $(call add_define,RPI3_RUNTIME_UART))
 $(eval $(call add_define,RPI3_USE_UEFI_MAP))
 
-# Verify build config
-# -------------------
-#
-ifneq (${RPI3_DIRECT_LINUX_BOOT}, 0)
-  ifndef RPI3_PRELOADED_DTB_BASE
-      $(error Error: RPI3_PRELOADED_DTB_BASE needed if RPI3_DIRECT_LINUX_BOOT=1)
-  endif
-endif
-
 ifeq (${ARCH},aarch32)
   $(error Error: AArch32 not supported on rpi4)
 endif
index 58025b27a688c965139700aff18d36b09d53ecc8..f5f74bdd2230b16b8fd4badf51d2fde16a5e7821 100644 (file)
@@ -27,6 +27,8 @@
  * confirmation and puts the kernel and DT address in the following words.
  */
 extern uint32_t stub_magic;
+extern uint32_t dtb_ptr32;
+extern uint32_t kernel_entry32;
 
 static const gicv2_driver_data_t rpi4_gic_data = {
        .gicd_base = RPI4_GIC_GICD_BASE,
@@ -63,6 +65,34 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
        }
 }
 
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+#ifdef PRELOADED_BL33_BASE
+       return PRELOADED_BL33_BASE;
+#else
+       /* Cleared by the GPU if kernel address is valid. */
+       if (stub_magic == 0)
+               return kernel_entry32;
+
+       WARN("Stub magic failure, using default kernel address 0x80000\n");
+       return 0x80000;
+#endif
+}
+
+static uintptr_t rpi4_get_dtb_address(void)
+{
+#ifdef RPI3_PRELOADED_DTB_BASE
+       return RPI3_PRELOADED_DTB_BASE;
+#else
+       /* Cleared by the GPU if DTB address is valid. */
+       if (stub_magic == 0)
+               return dtb_ptr32;
+
+       WARN("Stub magic failure, DTB address unknown\n");
+       return 0;
+#endif
+}
+
 static void ldelay(register_t delay)
 {
        __asm__ volatile (
@@ -114,12 +144,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
                div_reg = 1;
        rpi3_console_init(PLAT_RPI4_VPU_CLK_RATE / div_reg);
 
-#if RPI3_DIRECT_LINUX_BOOT
        bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
-       bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
-                                         DISABLE_ALL_EXCEPTIONS);
+       bl33_image_ep_info.spsr = rpi3_get_spsr_for_bl33_entry();
        SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
 
+#if RPI3_DIRECT_LINUX_BOOT
 # if RPI3_BL33_IN_AARCH32
        /*
         * According to the file ``Documentation/arm/Booting`` of the Linux
@@ -131,7 +160,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
        VERBOSE("rpi4: Preparing to boot 32-bit Linux kernel\n");
        bl33_image_ep_info.args.arg0 = 0U;
        bl33_image_ep_info.args.arg1 = ~0U;
-       bl33_image_ep_info.args.arg2 = (u_register_t) RPI3_PRELOADED_DTB_BASE;
+       bl33_image_ep_info.args.arg2 = rpi4_get_dtb_address();
 # else
        /*
         * According to the file ``Documentation/arm64/booting.txt`` of the
@@ -140,7 +169,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
         * must be 0.
         */
        VERBOSE("rpi4: Preparing to boot 64-bit Linux kernel\n");
-       bl33_image_ep_info.args.arg0 = (u_register_t) RPI3_PRELOADED_DTB_BASE;
+       bl33_image_ep_info.args.arg0 = rpi4_get_dtb_address();
        bl33_image_ep_info.args.arg1 = 0ULL;
        bl33_image_ep_info.args.arg2 = 0ULL;
        bl33_image_ep_info.args.arg3 = 0ULL;