plat/arm: Introduce ARM_LINUX_KERNEL_AS_BL33 build option
authorAntonio Nino Diaz <antonio.ninodiaz@arm.com>
Fri, 11 May 2018 10:15:10 +0000 (11:15 +0100)
committerAntonio Nino Diaz <antonio.ninodiaz@arm.com>
Fri, 11 May 2018 10:15:10 +0000 (11:15 +0100)
Normally, BL33 needs to contain a boot loader like U-Boot or UEFI that
eventually gives control to the OS. However, in some cases, this boot
sequence may be too slow. For example, when doing tests in a
cycle-accurate emulator, the user may only be interested in the
interaction between the Trusted Firmware and the OS, not in the boot
process itself.

The new option ARM_LINUX_KERNEL_AS_BL33 allows BL33 to contain the Linux
kernel image by changing the value of registers x0-x3 to the values
expected by the kernel. This option requires the device tree blob (DTB)
to be present in memory. Its address must be specified in the newly
introduced ARM_PRELOADED_DTB_BASE build option. For now, it only supports
AArch64 kernels.

This option is only available when RESET_TO_BL31=1. For this reason
the BL33 binary must be preloaded in memory and PRELOADED_BL33_BASE must
be used.

For example, if the kernel is loaded at 0x80080000 and the DTB is loaded
at address 0x82000000, the firmware could be built like this:

    CROSS_COMPILE=aarch64-linux-gnu-  \
    make PLAT=fvp DEBUG=1             \
    RESET_TO_BL31=1                   \
    ARM_LINUX_KERNEL_AS_BL33=1        \
    PRELOADED_BL33_BASE=0x80080000    \
    ARM_PRELOADED_DTB_BASE=0x82000000 \
    all fip

Change-Id: If9dc847c65ae2d0c27b51f0fd44fc06b28497db9
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
docs/user-guide.rst
plat/arm/common/arm_bl31_setup.c
plat/arm/common/arm_common.mk

index aed54a63152660cd08ca703c5fc4da01fa2d63b5..4a8c3a156775c8d5340a4b1942a9478c896adf6d 100644 (file)
@@ -590,7 +590,7 @@ Common build options
    firmware images have been loaded in memory, and the MMU and caches are
    turned off. Refer to the "Debugging options" section for more details.
 
-- ``SP_MIN_WITH_SECURE_FIQ``: Boolean flag to indicate the SP_MIN handles
+-  ``SP_MIN_WITH_SECURE_FIQ``: Boolean flag to indicate the SP_MIN handles
    secure interrupts (caught through the FIQ line). Platforms can enable
    this directive if they need to handle such interruption. When enabled,
    the FIQ are handled in monitor mode and non secure world is not allowed
@@ -678,6 +678,15 @@ Arm development platform specific build options
    Trusted Watchdog may be disabled at build time for testing or development
    purposes.
 
+-  ``ARM_LINUX_KERNEL_AS_BL33``: The Linux kernel expects registers x0-x3 to
+   have specific values at boot. This boolean option allows the Trusted Firmware
+   to have a Linux kernel image as BL33 by preparing the registers to these
+   values before jumping to BL33. This option defaults to 0 (disabled). For now,
+   it  only supports AArch64 kernels. ``RESET_TO_BL31`` must be 1 when using it.
+   If this option is set to 1, ``ARM_PRELOADED_DTB_BASE`` must be set to the
+   location of a device tree blob (DTB) already loaded in memory.  The Linux
+   Image address must be specified using the ``PRELOADED_BL33_BASE`` option.
+
 -  ``ARM_RECOM_STATE_ID_ENC``: The PSCI1.0 specification recommends an encoding
    for the construction of composite state-ID in the power-state parameter.
    The existing PSCI clients currently do not support this encoding of
index 3c70f9de85607d35aefc82e96b722cb1275a140f..ae0bf0488af350e7d92d91c78c5574d720866568 100644 (file)
@@ -80,7 +80,7 @@ void arm_bl31_early_platform_setup(bl31_params_t *from_bl2, uintptr_t soc_fw_con
        assert(from_bl2 == NULL);
        assert(plat_params_from_bl2 == NULL);
 
-#ifdef BL32_BASE
+# ifdef BL32_BASE
        /* Populate entry point information for BL32 */
        SET_PARAM_HEAD(&bl32_image_ep_info,
                                PARAM_EP,
@@ -89,7 +89,7 @@ void arm_bl31_early_platform_setup(bl31_params_t *from_bl2, uintptr_t soc_fw_con
        SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
        bl32_image_ep_info.pc = BL32_BASE;
        bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry();
-#endif /* BL32_BASE */
+# endif /* BL32_BASE */
 
        /* Populate entry point information for BL33 */
        SET_PARAM_HEAD(&bl33_image_ep_info,
@@ -105,6 +105,19 @@ void arm_bl31_early_platform_setup(bl31_params_t *from_bl2, uintptr_t soc_fw_con
        bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
        SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
 
+# if ARM_LINUX_KERNEL_AS_BL33
+       /*
+        * According to the file ``Documentation/arm64/booting.txt`` of the
+        * Linux kernel tree, Linux expects the physical address of the device
+        * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
+        * must be 0.
+        */
+       bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+       bl33_image_ep_info.args.arg1 = 0U;
+       bl33_image_ep_info.args.arg2 = 0U;
+       bl33_image_ep_info.args.arg3 = 0U;
+# endif
+
 #else /* RESET_TO_BL31 */
 
        /*
index 015e454a125c3ef8f40258666df0e9f847109654..055819bf99e990cc260022978f446d605b17ee5f 100644 (file)
@@ -80,6 +80,27 @@ ARM_XLAT_TABLES_LIB_V1               :=      0
 $(eval $(call assert_boolean,ARM_XLAT_TABLES_LIB_V1))
 $(eval $(call add_define,ARM_XLAT_TABLES_LIB_V1))
 
+# Don't have the Linux kernel as a BL33 image by default
+ARM_LINUX_KERNEL_AS_BL33       :=      0
+$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
+
+ifeq (${ARM_LINUX_KERNEL_AS_BL33},1)
+  ifneq (${ARCH},aarch64)
+    $(error "ARM_LINUX_KERNEL_AS_BL33 is only available in AArch64.")
+  endif
+  ifneq (${RESET_TO_BL31},1)
+    $(error "ARM_LINUX_KERNEL_AS_BL33 is only available if RESET_TO_BL31=1.")
+  endif
+  ifndef PRELOADED_BL33_BASE
+    $(error "PRELOADED_BL33_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.")
+  endif
+  ifndef ARM_PRELOADED_DTB_BASE
+    $(error "ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.")
+  endif
+  $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+endif
+
 # Use an implementation of SHA-256 with a smaller memory footprint but reduced
 # speed.
 $(eval $(call add_define,MBEDTLS_SHA256_SMALLER))