Add support for BL3-2 in BL2
authorAchin Gupta <achin.gupta@arm.com>
Wed, 19 Feb 2014 17:52:35 +0000 (17:52 +0000)
committerDan Handley <dan.handley@arm.com>
Thu, 20 Feb 2014 19:06:34 +0000 (19:06 +0000)
This patch adds support for loading a BL3-2 image in BL2. In case a
BL3-2 image is found, it also passes information to BL3-1 about where it
is located and the extents of memory available to it. Information about
memory extents is populated by platform specific code.

The documentation has also been updated to reflect the above changes.

Change-Id: I526b2efb80babebab1318f2b02e319a86d6758b0
Co-authored-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
bl2/bl2_main.c
docs/porting-guide.md
docs/user-guide.md
plat/fvp/bl2_plat_setup.c
plat/fvp/platform.h

index a3e0cdfdd202583ac80ae91fcd3eca42c8da69f5..74952dafafaa1388b9ea6b0fafdf685c4b85fdd0 100644 (file)
@@ -49,7 +49,7 @@ void bl2_main(void)
 {
        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 */
@@ -89,6 +89,20 @@ void bl2_main(void)
         */
        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 @@ void bl2_main(void)
                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));
index 91b2a20007a4129f11e4547e6f830edd1efa2fb9..720c877f0b9288878062bbf09c095b6e611d15a0 100644 (file)
@@ -536,6 +536,34 @@ using the `platform_is_primary_cpu()` function. BL1 passed control to BL2 at
     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 @@ internal pointer (`bl2_to_bl31_args`) to a `bl31_args` which will be used by
 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`.
index 011f233e4cea49eaf9cbf6e8c1078d9fe6123505..589d0b19dd35028e22df6dd5a6efc1d2767fe0c6 100644 (file)
@@ -799,7 +799,8 @@ information regarding the trusted SRAM populated by BL1 using a
 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 @@ the load address of the normal world software image. The `CPSR` is determined as
 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
index 2e367d713191417df01234dfb7009a4abd395496..f0d6e448447e2a937a985841450bbcc36a66ddaf 100644 (file)
@@ -122,6 +122,12 @@ void bl2_platform_setup()
        /* 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 @@ void bl2_platform_setup()
        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;
 }
 
 /*******************************************************************************
index 76a9fca4963d15ea2b5c8ef55cdada65598f1c3b..11b62cc202a68e2875ee61de9644f923326d1cc7 100644 (file)
  ******************************************************************************/
 #define BL31_BASE                      0x0400C000
 
+/*******************************************************************************
+ * BL32 specific defines.
+ ******************************************************************************/
+#define BL32_BASE                      (TZDRAM_BASE + 0x2000)
+
 /*******************************************************************************
  * Platform specific page table and MMU setup constants
  ******************************************************************************/