From cf2c8a33e02029d9b15f4b428b1ddd0ec4e687a4 Mon Sep 17 00:00:00 2001 From: Antonio Nino Diaz Date: Mon, 15 Feb 2016 14:53:10 +0000 Subject: [PATCH] Enable preloaded BL33 alternative boot flow Enable alternative boot flow where BL2 does not load BL33 from non-volatile storage, and BL31 hands execution over to a preloaded BL33. The flag used to enable this bootflow is BL33_BASE, which must hold the entrypoint address of the BL33 image. The User Guide has been updated with an example of how to use this option with a bootwrapped kernel. Change-Id: I48087421a7b0636ac40dca7d457d745129da474f --- Makefile | 52 +++++++++++++++++++++++++----- bl2/bl2_main.c | 16 +++++++++- docs/porting-guide.md | 30 +++++++++++------- docs/user-guide.md | 73 +++++++++++++++++++++++++++++++++++++------ 4 files changed, 141 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index ac688ba8..3ab44afc 100644 --- a/Makefile +++ b/Makefile @@ -300,6 +300,29 @@ endif include lib/cpus/cpu-ops.mk +################################################################################ +# Check incompatible options +################################################################################ + +ifdef EL3_PAYLOAD_BASE + ifdef BL33_BASE + $(warning "BL33_BASE and EL3_PAYLOAD_BASE are incompatible \ + build options. EL3_PAYLOAD_BASE has priority.") + endif +endif + +ifeq (${NEED_BL33},yes) + ifdef EL3_PAYLOAD_BASE + $(warning "BL33 image is not needed when option \ + BL33_PAYLOAD_BASE is used and won't be added to the FIP file.") + endif + ifdef BL33_BASE + $(warning "BL33 image is not needed when option BL33_BASE is \ + used and won't be added to the FIP file.") + endif +endif + + ################################################################################ # Process platform overrideable behaviour ################################################################################ @@ -313,12 +336,19 @@ endif # supplied for the FIP and Certificate generation tools. This flag can be # overridden by the platform. ifdef BL2_SOURCES -ifndef EL3_PAYLOAD_BASE -NEED_BL33 ?= yes -else -# The BL33 image is not needed when booting an EL3 payload. -NEED_BL33 := no -endif + ifdef EL3_PAYLOAD_BASE + # If booting an EL3 payload there is no need for a BL33 image + # in the FIP file. + NEED_BL33 := no + else + ifdef BL33_BASE + # If booting a BL33 preloaded image there is no need of + # another one in the FIP file. + NEED_BL33 := no + else + NEED_BL33 ?= yes + endif + endif endif # Process TBB related flags @@ -398,11 +428,17 @@ $(eval $(call add_define,PSCI_EXTENDED_STATE_ID)) $(eval $(call add_define,ERROR_DEPRECATED)) $(eval $(call add_define,ENABLE_PLAT_COMPAT)) $(eval $(call add_define,SPIN_ON_BL1_EXIT)) +$(eval $(call add_define,PL011_GENERIC_UART)) # Define the EL3_PAYLOAD_BASE flag only if it is provided. ifdef EL3_PAYLOAD_BASE -$(eval $(call add_define,EL3_PAYLOAD_BASE)) + $(eval $(call add_define,EL3_PAYLOAD_BASE)) +else + # Define the BL33_BASE flag only if it is provided and EL3_PAYLOAD_BASE + # is not defined, as it has priority. + ifdef BL33_BASE + $(eval $(call add_define,BL33_BASE)) + endif endif -$(eval $(call add_define,PL011_GENERIC_UART)) ################################################################################ diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c index 9ff75d29..73781dd0 100644 --- a/bl2/bl2_main.c +++ b/bl2/bl2_main.c @@ -169,6 +169,7 @@ static int load_bl32(bl31_params_t *bl2_to_bl31_params) return e; } +#ifndef BL33_BASE /******************************************************************************* * Load the BL33 image. * The bl2_to_bl31_params param will be updated with the relevant BL33 @@ -199,6 +200,8 @@ static int load_bl33(bl31_params_t *bl2_to_bl31_params) return e; } +#endif /* BL33_BASE */ + #endif /* EL3_PAYLOAD_BASE */ /******************************************************************************* @@ -253,7 +256,7 @@ void bl2_main(void) * bl31_params_t structure makes sense in the context of EL3 payloads. * This will be refined in the future. */ - VERBOSE("BL2: Populating the entrypoint info for the EL3 payload\n"); + INFO("BL2: Populating the entrypoint info for the EL3 payload\n"); bl31_ep_info->pc = EL3_PAYLOAD_BASE; bl31_ep_info->args.arg0 = (unsigned long) bl2_to_bl31_params; bl2_plat_set_bl31_ep_info(NULL, bl31_ep_info); @@ -274,11 +277,22 @@ void bl2_main(void) } } +#ifdef BL33_BASE + /* + * In this case, don't load the BL33 image as it's already loaded in + * memory. Update BL33 entrypoint information. + */ + INFO("BL2: Populating the entrypoint info for the preloaded BL33\n"); + bl2_to_bl31_params->bl33_ep_info->pc = BL33_BASE; + bl2_plat_set_bl33_ep_info(NULL, bl2_to_bl31_params->bl33_ep_info); +#else e = load_bl33(bl2_to_bl31_params); if (e) { ERROR("Failed to load BL33 (%i)\n", e); plat_error_handler(e); } +#endif /* BL33_BASE */ + #endif /* EL3_PAYLOAD_BASE */ /* Flush the params to be passed to memory */ diff --git a/docs/porting-guide.md b/docs/porting-guide.md index 56ddbb1c..7c9f404b 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -230,11 +230,6 @@ platform port to define additional platform porting constants in Defines the maximum address in secure RAM that the BL31 image can occupy. -* **#define : NS_IMAGE_OFFSET** - - Defines the base address in non-secure DRAM where BL2 loads the BL33 binary - image. Must be aligned on a page-size boundary. - For every image, the platform must define individual identifiers that will be used by BL1 or BL2 to load the corresponding image into memory from non-volatile storage. For the sake of performance, integer numbers will be used as @@ -1012,10 +1007,10 @@ using the `platform_is_primary_cpu()` function. BL1 passed control to BL2 at structure in memory provided by the platform with information about how BL31 should pass control to the BL32 image. -5. Loading the normal world BL33 binary image into non-secure DRAM from - platform storage and arranging for BL31 to pass control to this image. This - address is determined using the `plat_get_ns_image_entrypoint()` function - described below. +5. (Optional) Loading the normal world BL33 binary image (if not loaded by + other means) into non-secure DRAM from platform storage and arranging for + BL31 to pass control to this image. This address is determined using the + `plat_get_ns_image_entrypoint()` function described below. 6. BL2 populates an `entry_point_info` structure in memory provided by the platform with information about how BL31 should pass control to the @@ -1183,6 +1178,10 @@ This function is called after loading BL33 image and it can be used to overwrite the entry point set by loader and also set the security state and SPSR which represents the entry point system state for BL33. +In the preloaded BL33 alternative boot flow, this function is called after +populating its entry point address. It is passed a null pointer as its first +argument in this case. + ### Function : bl2_plat_get_bl32_meminfo() [mandatory] @@ -1204,6 +1203,9 @@ BL33 image. The meminfo provided by this is used by load_image() to validate whether the BL33 image can be loaded with in the given memory from the given base. +This function isn't needed if either `BL33_BASE` or `EL3_PAYLOAD_BASE` build +options are used. + ### Function : bl2_plat_flush_bl31_params() [mandatory] Argument : void @@ -1226,6 +1228,9 @@ entrypoint of that image, which BL31 uses to jump to it. BL2 is responsible for loading the normal world BL33 image (e.g. UEFI). +This function isn't needed if either `BL33_BASE` or `EL3_PAYLOAD_BASE` build +options are used. + 3.3 FWU Boot Loader Stage 2 (BL2U) ---------------------------------- @@ -1899,9 +1904,10 @@ build system. * **NEED_BL33** By default, this flag is defined `yes` by the build system and `BL33` - build option should be supplied as a build option. The platform has the option - of excluding the BL33 image in the `fip` image by defining this flag to - `no`. + build option should be supplied as a build option. The platform has the + option of excluding the BL33 image in the `fip` image by defining this flag + to `no`. If any of the options `EL3_PAYLOAD_BASE` or `BL33_BASE` are used, + this flag will be set to `no` automatically. 5. C Library ------------- diff --git a/docs/user-guide.md b/docs/user-guide.md index e6929134..d6c6c93f 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -10,10 +10,11 @@ Contents : 5. [Building the Trusted Firmware](#5--building-the-trusted-firmware) 6. [Building the rest of the software stack](#6--building-the-rest-of-the-software-stack) 7. [EL3 payloads alternative boot flow](#7--el3-payloads-alternative-boot-flow) -8. [Preparing the images to run on FVP](#8--preparing-the-images-to-run-on-fvp) -9. [Running the software on FVP](#9--running-the-software-on-fvp) -10. [Running the software on Juno](#10--running-the-software-on-juno) -11. [Changes required for booting Linux on FVP in GICv3 mode](#11--changes-required-for-booting-linux-on-fvp-in-gicv3-mode) +8. [Preloaded BL33 alternative boot flow](#8--preloaded-bl33-alternative-boot-flow) +9. [Preparing the images to run on FVP](#9--preparing-the-images-to-run-on-fvp) +10. [Running the software on FVP](#10--running-the-software-on-fvp) +11. [Running the software on Juno](#11--running-the-software-on-juno) +12. [Changes required for booting Linux on FVP in GICv3 mode](#12--changes-required-for-booting-linux-on-fvp-in-gicv3-mode) 1. Introduction @@ -407,6 +408,12 @@ performed. payload. Please refer to the "Booting an EL3 payload" section for more details. +* `BL33_BASE`: This option enables booting a preloaded BL33 image instead of + the normal boot flow. When defined, it must specify the entry point address + for the preloaded BL33 image. This option is incompatible with + `EL3_PAYLOAD_BASE`. If both are defined, `EL3_PAYLOAD_BASE` has priority + over `BL33_BASE`. + * `PL011_GENERIC_UART`: Boolean option to indicate the PL011 driver that the underlying hardware is not a full PL011 UART but a minimally compliant generic UART, which is a subset of the PL011. The driver will not access @@ -938,7 +945,55 @@ Alternatively, the same DS-5 command mentioned in the FVP section above can be used to load the EL3 payload's ELF file over JTAG on Juno. -8. Preparing the images to run on FVP +8. Preloaded BL33 alternative boot flow +---------------------------------------- + +Some platforms have the ability to preload BL33 into memory instead of relying +on Trusted Firmware to load it. This may simplify packaging of the normal world +code and improve performance in a development environment. When secure world +cold boot is complete, Trusted Firmware simply jumps to a BL33 base address +provided at build time. + +For this option to be used, the `BL33_BASE` build option has to be used when +compiling the Trusted Firmware. For example, the following command will create +a FIP without a BL33 and prepare to jump to a BL33 image loaded at address +0x80000000: + + CROSS_COMPILE=/bin/aarch64-linux-gnu- \ + make BL33_BASE=0x80000000 PLAT=fvp all fip + +#### Boot of a preloaded bootwrapped kernel image on Base FVP + +The following example uses the AArch64 boot wrapper. This simplifies normal +world booting while also making use of TF features. It can be obtained from its +repository with: + + git clone git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git + +After compiling it, an ELF file is generated. It can be loaded with the +following command: + + /FVP_Base_AEMv8A-AEMv8A \ + -C bp.secureflashloader.fname=bl1.bin \ + -C bp.flashloader0.fname=fip.bin \ + -a cluster0.cpu0= \ + --start cluster0.cpu0=0x0 + +The `-a cluster0.cpu0=` option loads the ELF file. It +also sets the PC register to the ELF entry point address, which is not the +desired behaviour, so the `--start cluster0.cpu0=0x0` option forces the PC back +to 0x0 (the BL1 entry point address) on CPU #0. The `BL33_BASE` define used when +compiling the FIP must match the ELF entry point. + +#### Boot of a preloaded bootwrapped kernel image on Juno + +The procedure to obtain and compile the boot wrapper is very similar to the case +of the FVP. Once compiled, the `SPIN_ON_BL1_EXIT=1` loading method explained +above in the EL3 payload boot flow section may be used to load the ELF file over +JTAG on Juno. + + +9. Preparing the images to run on FVP -------------------------------------- Note: This section can be ignored when booting an EL3 payload, as no Flattened @@ -991,8 +1046,8 @@ Copy the kernel image file `linux/arch/arm64/boot/Image` to the directory from which the FVP is launched. Alternatively a symbolic link may be used. -9. Running the software on FVP -------------------------------- +10. Running the software on FVP +-------------------------------- This version of the ARM Trusted Firmware has been tested on the following ARM FVPs (64-bit versions only). @@ -1290,7 +1345,7 @@ The `bp.variant` parameter corresponds to the build variant field of the detect the legacy VE memory map while configuring the GIC. -10. Running the software on Juno +11. Running the software on Juno --------------------------------- This version of the ARM Trusted Firmware has been tested on Juno r0 and Juno r1. @@ -1372,7 +1427,7 @@ The Juno board should suspend to RAM and then wakeup after 10 seconds due to wakeup interrupt from RTC. -11. Changes required for booting Linux on FVP in GICv3 mode +12. Changes required for booting Linux on FVP in GICv3 mode ------------------------------------------------------------ In case the TF FVP port is built with the build option -- 2.30.2