diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c index a3e0cdf..74952da 100644 --- a/bl2/bl2_main.c +++ b/bl2/bl2_main.c @@ -49,7 +49,7 @@ { meminfo *bl2_tzram_layout; bl31_args *bl2_to_bl31_args; - unsigned long bl31_base, bl33_base, el_status; + unsigned long bl31_base, bl32_base = 0, bl33_base, el_status; unsigned int bl2_load, bl31_load, mode; /* Perform remaining generic architectural setup in S-El1 */ @@ -90,6 +90,20 @@ bl2_to_bl31_args = bl2_get_bl31_args_ptr(); /* + * Load the BL32 image if there's one. It is upto to platform + * to specify where BL32 should be loaded if it exists. It + * could create space in the secure sram or point to a + * completely different memory. A zero size indicates that the + * platform does not want to load a BL32 image. + */ + if (bl2_to_bl31_args->bl32_meminfo.total_size) + bl32_base = load_image(&bl2_to_bl31_args->bl32_meminfo, + BL32_IMAGE_NAME, + bl2_to_bl31_args->bl32_meminfo.attr & + LOAD_MASK, + BL32_BASE); + + /* * Create a new layout of memory for BL31 as seen by BL2. This * will gobble up all the BL2 memory. */ @@ -132,6 +146,18 @@ make_spsr(mode, MODE_SP_ELX, MODE_RW_64); bl2_to_bl31_args->bl33_image_info.security_state = NON_SECURE; + if (bl32_base) { + /* Fill BL32 image info */ + bl2_to_bl31_args->bl32_image_info.entrypoint = bl32_base; + bl2_to_bl31_args->bl32_image_info.security_state = SECURE; + + /* + * The Secure Payload Dispatcher service is responsible for + * setting the SPSR prior to entry into the BL32 image. + */ + bl2_to_bl31_args->bl32_image_info.spsr = 0; + } + /* Flush the entire BL31 args buffer */ flush_dcache_range((unsigned long) bl2_to_bl31_args, sizeof(*bl2_to_bl31_args)); diff --git a/docs/porting-guide.md b/docs/porting-guide.md index 91b2a20..720c877 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -536,6 +536,34 @@ if the platform wants to restrict the amount of memory visible to BL3-1. Details of this function are given below. +4. Loading the BL3-2 binary image (if present) in platform provided memory + using semi-hosting. To load the BL3-2 image, BL2 makes use of the + `bl32_meminfo` field in the `bl31_args` structure to which a pointer is + returned by the `bl2_get_bl31_args_ptr()` function. The platform also + defines the address in memory where BL3-2 is loaded through the constant + `BL32_BASE`. BL2 uses this information to determine if there is enough + memory to load the BL3-2 image. + +5. Arranging to pass control to the BL3-2 image (if present) that has been + pre-loaded at `BL32_BASE`. BL2 populates an `el_change_info` structure + in memory provided by the platform with information about how BL3-1 should + pass control to the BL3-2 image. This structure follows the + `el_change_info` structure populated for the normal world BL image in 2. + above. + +6. Populating a `meminfo` structure with the following information in + memory that is accessible by BL3-1 immediately upon entry. + + meminfo.total_base = Base address of memory visible to BL3-2 + meminfo.total_size = Size of memory visible to BL3-2 + meminfo.free_base = Base address of memory available for allocation + to BL3-2 + meminfo.free_size = Size of memory available for allocation to + BL3-2 + + BL2 populates this information in the `bl32_meminfo` field of the pointer + returned by the `bl2_get_bl31_args_ptr() function. + The following functions must be implemented by the platform port to enable BL2 to perform the above tasks. @@ -585,6 +613,11 @@ BL2 to pass information to BL3_1. The pointer is initialized to the base address of Secure DRAM (`0x06000000`). +The ARM FVP port also populates the `bl32_meminfo` field in the `bl31_args` +structure pointed to by `bl2_to_bl31_args` with the extents of memory available +for use by the BL3-2 image. The memory is allocated in the Secure DRAM from the +address defined by the constant `BL32_BASE`. + The non-secure memory extents used for loading BL3-3 are also initialized in this function. This information is accessible in the `bl33_meminfo` field in the `bl31_args` structure pointed to by `bl2_to_bl31_args`. diff --git a/docs/user-guide.md b/docs/user-guide.md index 011f233..589d0b1 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -799,7 +799,8 @@ platform-specific mechanism. It calculates the limits of DRAM (main memory) to determine whether there is enough space to load the normal world software images. A platform defined base address is used to specify the load address for -the BL3-1 image. +the BL3-1 image. It also defines the extents of memory available for use by the +BL3-2 image. #### Normal world image load @@ -811,6 +812,16 @@ specified in Section 5.13 of the [PSCI PDD] [PSCI]. This information is passed to BL3-1. +#### BL3-2 (Secure Payload) image load + +BL2 loads the optional BL3-2 image. The image executes in the secure world. BL2 +relies on BL3-1 to pass control to the BL3-2 image, if present. Hence, BL2 +populates a platform- specific area of memory with the entrypoint and Current +Program Status Register (`CPSR`) of the BL3-2 image. The entrypoint is the load +address of the BL3-2 image. The `CPSR` is initialized with Secure EL1 and Stack +pointer set to SP_EL1 (EL1h) as the mode, exception bits disabled (DAIF bits) +and AArch64 execution state. This information is passed to BL3-1. + ##### UEFI firmware load BL2 loads the BL3-3 (UEFI) image into non-secure memory as defined by the diff --git a/plat/fvp/bl2_plat_setup.c b/plat/fvp/bl2_plat_setup.c index 2e367d7..f0d6e44 100644 --- a/plat/fvp/bl2_plat_setup.c +++ b/plat/fvp/bl2_plat_setup.c @@ -122,6 +122,12 @@ /* Initialise the IO layer and register platform IO devices */ io_setup(); + /* + * Ensure that the secure DRAM memory used for passing BL31 arguments + * does not overlap with the BL32_BASE. + */ + assert (BL32_BASE > TZDRAM_BASE + sizeof(bl31_args)); + /* Use the Trusted DRAM for passing args to BL31 */ bl2_to_bl31_args = (bl31_args *) TZDRAM_BASE; @@ -132,6 +138,22 @@ bl2_to_bl31_args->bl33_meminfo.free_size = DRAM_SIZE; bl2_to_bl31_args->bl33_meminfo.attr = 0; bl2_to_bl31_args->bl33_meminfo.next = 0; + + /* + * Populate the extents of memory available for loading BL32. + * TODO: We are temporarily executing BL2 from TZDRAM; will eventually + * move to Trusted SRAM + */ + bl2_to_bl31_args->bl32_meminfo.total_base = BL32_BASE; + bl2_to_bl31_args->bl32_meminfo.free_base = BL32_BASE; + + bl2_to_bl31_args->bl32_meminfo.total_size = + (TZDRAM_BASE + TZDRAM_SIZE) - BL32_BASE; + bl2_to_bl31_args->bl32_meminfo.free_size = + (TZDRAM_BASE + TZDRAM_SIZE) - BL32_BASE; + + bl2_to_bl31_args->bl32_meminfo.attr = BOT_LOAD; + bl2_to_bl31_args->bl32_meminfo.next = 0; } /******************************************************************************* diff --git a/plat/fvp/platform.h b/plat/fvp/platform.h index 76a9fca..11b62cc 100644 --- a/plat/fvp/platform.h +++ b/plat/fvp/platform.h @@ -236,6 +236,11 @@ #define BL31_BASE 0x0400C000 /******************************************************************************* + * BL32 specific defines. + ******************************************************************************/ +#define BL32_BASE (TZDRAM_BASE + 0x2000) + +/******************************************************************************* * Platform specific page table and MMU setup constants ******************************************************************************/ #define EL3_ADDR_SPACE_SIZE (1ull << 32)