FWU: Add Firmware Update support in BL1 for ARM platforms
authorYatharth Kochar <yatharth.kochar@arm.com>
Sun, 11 Oct 2015 13:14:55 +0000 (14:14 +0100)
committerYatharth Kochar <yatharth.kochar@arm.com>
Wed, 9 Dec 2015 17:41:18 +0000 (17:41 +0000)
This patch adds Firmware Update support for ARM platforms.

New files arm_bl1_fwu.c and juno_bl1_setup.c were added to provide
platform specific Firmware update code.

BL1 now includes mmap entry for `ARM_MAP_NS_DRAM1` to map DRAM for
authenticating NS_BL2U image(For both FVP and JUNO platform).

Change-Id: Ie116cd83f5dc00aa53d904c2f1beb23d58926555

12 files changed:
include/plat/arm/board/common/board_arm_def.h
include/plat/arm/common/arm_def.h
include/plat/arm/common/plat_arm.h
include/plat/arm/css/common/css_def.h
plat/arm/board/common/board_css_common.c
plat/arm/board/fvp/aarch64/fvp_common.c
plat/arm/board/fvp/fvp_bl1_setup.c
plat/arm/board/juno/juno_bl1_setup.c [new file with mode: 0644]
plat/arm/board/juno/platform.mk
plat/arm/common/arm_bl1_fwu.c [new file with mode: 0644]
plat/arm/common/arm_common.mk
plat/arm/common/arm_io_storage.c

index 3abf235eb0dd004571f918cfc5174dfacf87549e..dae5418000beb76cb9e5eb703f8bae67e1b2d314 100644 (file)
  */
 #if IMAGE_BL1
 # if PLAT_fvp
-#  define PLAT_ARM_MMAP_ENTRIES                7
+#  if TRUSTED_BOARD_BOOT
+#   define PLAT_ARM_MMAP_ENTRIES       8
+#  else
+#   define PLAT_ARM_MMAP_ENTRIES       7
+#  endif       /* TRUSTED_BOARD_BOOT */
 # else
-#  define PLAT_ARM_MMAP_ENTRIES                6
-# endif
+#  if TRUSTED_BOARD_BOOT
+#   define PLAT_ARM_MMAP_ENTRIES       7
+#  else
+#   define PLAT_ARM_MMAP_ENTRIES       6
+#  endif       /* TRUSTED_BOARD_BOOT */
+# endif                /* PLAT_ */
 #endif
 #if IMAGE_BL2
 # if PLAT_fvp
  * Platform specific page table and MMU setup constants
  */
 #if IMAGE_BL1
-# if PLAT_juno
-#  define MAX_XLAT_TABLES              2
+# if TRUSTED_BOARD_BOOT
+#  define MAX_XLAT_TABLES              4
 # else
-#  define MAX_XLAT_TABLES              3
-# endif /* PLAT_ */
+#  if PLAT_juno
+#   define MAX_XLAT_TABLES             2
+#  else
+#   define MAX_XLAT_TABLES             3
+#  endif /* PLAT_ */
+# endif        /* TRUSTED_BOARD_BOOT */
 #elif IMAGE_BL2
 # if PLAT_juno
 #  define MAX_XLAT_TABLES              3
index 5c03feb9a414bb69e5cbe1609feac13f8136daa2..4a50c1c8cdea954a722f4d00567abc153cc98160 100644 (file)
 # error "Unsupported ARM_TSP_RAM_LOCATION_ID value"
 #endif
 
+/*******************************************************************************
+ * FWU Images: NS_BL1U, BL2U & NS_BL2U defines.
+ ******************************************************************************/
+#define BL2U_BASE                      BL2_BASE
+#define BL2U_LIMIT                     BL31_BASE
+#define NS_BL2U_BASE                   ARM_NS_DRAM1_BASE
+#define NS_BL1U_BASE                   (V2M_FLASH0_BASE + 0x03EB8000)
+
 /*
  * ID of the secure physical generic timer interrupt used by the TSP.
  */
index f0b3ff6753cc3725199dcc388e492151cd4e730b..f8541c75966278970ad2fc136a4f9404b2f7806d 100644 (file)
@@ -174,6 +174,8 @@ void arm_bl31_plat_arch_setup(void);
 /* TSP utility functions */
 void arm_tsp_early_platform_setup(void);
 
+/* FIP TOC validity check */
+int arm_io_is_toc_valid(void);
 
 /*
  * Mandatory functions required in ARM standard platforms
index 99491f88bee2597ad6dbdd62155136af761a7079..3fa4c153d8d6d25272ec69b3cb021e50882fc654 100644 (file)
 #define NSRAM_BASE                     0x2e000000
 #define NSRAM_SIZE                     0x00008000
 
+/* System Security Control Registers */
+#define SSC_REG_BASE                   0x2a420000
+#define SSC_GPRETN                     (SSC_REG_BASE + 0x030)
+
 /* The slave_bootsecure controls access to GPU, DMC and CS. */
 #define CSS_NIC400_SLAVE_BOOTSECURE    8
 
  */
 #define BL30_BASE                      BL31_BASE
 
+#define SCP_BL2U_BASE                  BL31_BASE
+
 #define PLAT_ARM_SHARED_RAM_CACHED     MHU_PAYLOAD_CACHED
 
 /* Load address of Non-Secure Image for CSS platform ports */
index 7bf0273d14a082901e4b73b316733d218a59aacb..9af73f280af8dd335564b0106a9add0b666df039 100644 (file)
@@ -42,6 +42,9 @@ const mmap_region_t plat_arm_mmap[] = {
        V2M_MAP_IOFPGA,
        CSS_MAP_DEVICE,
        SOC_CSS_MAP_DEVICE,
+#if TRUSTED_BOARD_BOOT
+       ARM_MAP_NS_DRAM1,
+#endif
        {0}
 };
 #endif
index e089405dc3967c0294aa396b05838e49975b2163..42a903487bee8bb5ac75e7d806e132d5df86f53a 100644 (file)
@@ -82,6 +82,9 @@ const mmap_region_t plat_arm_mmap[] = {
        MAP_DEVICE0,
        MAP_DEVICE1,
        MAP_DEVICE2,
+#if TRUSTED_BOARD_BOOT
+       ARM_MAP_NS_DRAM1,
+#endif
        {0}
 };
 #endif
index 33712d1eff77289db171e6da5eca3af8a8180dba..91bc9c4ec45e8d16c9beed187c7a05ea8341539f 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #include <plat_arm.h>
+#include <tbbr_img_def.h>
 #include "fvp_private.h"
 
 
@@ -52,3 +53,16 @@ void bl1_early_platform_setup(void)
         */
        fvp_cci_enable();
 }
+
+/*******************************************************************************
+ * The following function checks if Firmware update is needed,
+ * by checking if TOC in FIP image is valid or not.
+ ******************************************************************************/
+unsigned int bl1_plat_get_next_image_id(void)
+{
+       if (!arm_io_is_toc_valid())
+               return NS_BL1U_IMAGE_ID;
+
+       return BL2_IMAGE_ID;
+}
+
diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c
new file mode 100644 (file)
index 0000000..61a5738
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <bl_common.h>
+#include <errno.h>
+#include <platform.h>
+#include <plat_arm.h>
+#include <tbbr_img_def.h>
+#include <v2m_def.h>
+
+#define RESET_REASON_WDOG_RESET                (0x2)
+
+/*******************************************************************************
+ * The following function checks if Firmware update is needed,
+ * by checking if TOC in FIP image is valid or watchdog reset happened.
+ ******************************************************************************/
+unsigned int bl1_plat_get_next_image_id(void)
+{
+       unsigned int *reset_flags_ptr = (unsigned int *)SSC_GPRETN;
+       unsigned int *nv_flags_ptr = (unsigned int *)
+                       (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGS);
+       /*
+        * Check if TOC is invalid or watchdog reset happened.
+        */
+       if ((arm_io_is_toc_valid() != 1) ||
+               ((*reset_flags_ptr & RESET_REASON_WDOG_RESET) &&
+               ((*nv_flags_ptr == -EAUTH) || (*nv_flags_ptr == -ENOENT))))
+               return NS_BL1U_IMAGE_ID;
+
+       return BL2_IMAGE_ID;
+}
+
+/*******************************************************************************
+ * On JUNO update the arg2 with address of SCP_BL2U image info.
+ ******************************************************************************/
+void bl1_plat_set_ep_info(unsigned int image_id,
+               entry_point_info_t *ep_info)
+{
+       if (image_id == BL2U_IMAGE_ID) {
+               image_desc_t *image_desc = bl1_plat_get_image_desc(SCP_BL2U_IMAGE_ID);
+               ep_info->args.arg2 = (unsigned long)&image_desc->image_info;
+       }
+}
+
+/*******************************************************************************
+ * On Juno clear SYS_NVFLAGS and wait for watchdog reset.
+ ******************************************************************************/
+__dead2 void bl1_plat_fwu_done(void *cookie, void *rsvd_ptr)
+{
+       unsigned int *nv_flags_clr = (unsigned int *)
+                       (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGSCLR);
+       unsigned int *nv_flags_ptr = (unsigned int *)
+                       (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGS);
+
+       /* Clear the NV flags register. */
+       *nv_flags_clr = *nv_flags_ptr;
+
+       while (1)
+               wfi();
+}
index 0212fddea54b89e785c08f69412e8d868ed173a6..152bd01d427ab71fd9c386d61a8b74387906f87a 100644 (file)
@@ -41,6 +41,7 @@ PLAT_BL_COMMON_SOURCES        :=      plat/arm/board/juno/aarch64/juno_helpers.S
 BL1_SOURCES            +=      lib/cpus/aarch64/cortex_a53.S           \
                                lib/cpus/aarch64/cortex_a57.S           \
                                lib/cpus/aarch64/cortex_a72.S           \
+                               plat/arm/board/juno/juno_bl1_setup.c    \
                                plat/arm/board/juno/juno_err.c
 
 BL2_SOURCES            +=      plat/arm/board/juno/juno_security.c     \
diff --git a/plat/arm/common/arm_bl1_fwu.c b/plat/arm/common/arm_bl1_fwu.c
new file mode 100644 (file)
index 0000000..9a0d93a
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <errno.h>
+#include <plat_arm.h>
+#include <tbbr_img_desc.h>
+
+
+/* Struct to keep track of usable memory */
+typedef struct bl1_mem_info{
+       uintptr_t mem_base;
+       unsigned int mem_size;
+} bl1_mem_info_t;
+
+bl1_mem_info_t fwu_addr_map_secure[] = {
+       {
+               .mem_base = ARM_SHARED_RAM_BASE,
+               .mem_size = ARM_SHARED_RAM_SIZE
+       },
+       {
+               .mem_size = 0
+       }
+};
+
+bl1_mem_info_t fwu_addr_map_non_secure[] = {
+       {
+               .mem_base = ARM_NS_DRAM1_BASE,
+               .mem_size = ARM_NS_DRAM1_SIZE
+       },
+       {
+               .mem_base = V2M_FLASH0_BASE,
+               .mem_size = V2M_FLASH0_SIZE
+       },
+       {
+               .mem_size = 0
+       }
+};
+
+int bl1_plat_mem_check(uintptr_t mem_base,
+               unsigned int mem_size,
+               unsigned int flags)
+{
+       unsigned int index = 0;
+       bl1_mem_info_t *mmap;
+
+       assert(mem_base);
+       assert(mem_size);
+
+       /*
+        * Check the given image source and size.
+        */
+       if (GET_SEC_STATE(flags) == SECURE)
+               mmap = fwu_addr_map_secure;
+       else
+               mmap = fwu_addr_map_non_secure;
+
+       while (mmap[index].mem_size) {
+               if ((mem_base >= mmap[index].mem_base) &&
+                       ((mem_base + mem_size)
+                       <= (mmap[index].mem_base +
+                       mmap[index].mem_size)))
+                       return 0;
+
+               index++;
+       }
+
+       return -ENOMEM;
+}
+
+/*******************************************************************************
+ * This function does linear search for image_id and returns image_desc.
+ ******************************************************************************/
+image_desc_t *bl1_plat_get_image_desc(unsigned int image_id)
+{
+       unsigned int index = 0;
+
+       while (bl1_tbbr_image_descs[index].image_id != INVALID_IMAGE_ID) {
+               if (bl1_tbbr_image_descs[index].image_id == image_id)
+                       return &bl1_tbbr_image_descs[index];
+               index++;
+       }
+
+       return NULL;
+}
index 1336e2307d8f8d95c3d525ce804fdf0fccc3a59b..37dfb7e63313b596355260c3246e48d662f50497 100644 (file)
@@ -127,7 +127,12 @@ ifneq (${TRUSTED_BOARD_BOOT},0)
                                drivers/auth/img_parser_mod.c                   \
                                drivers/auth/tbbr/tbbr_cot.c                    \
 
-    BL1_SOURCES                +=      ${AUTH_SOURCES}
+    PLAT_INCLUDES      +=      -Iinclude/bl1/tbbr
+
+    BL1_SOURCES                +=      ${AUTH_SOURCES}                 \
+                               bl1/tbbr/tbbr_img_desc.c        \
+                               plat/arm/common/arm_bl1_fwu.c
+
     BL2_SOURCES                +=      ${AUTH_SOURCES}
 
     MBEDTLS_KEY_ALG    :=      ${KEY_ALG}
index ae67cde00deed17fe093be1d55e3a42aa61b3d12..f7e99e9c4c188da151d251202ddc8f1775d230d6 100644 (file)
@@ -308,3 +308,17 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
 
        return result;
 }
+
+/*
+ * See if a Firmware Image Package is available,
+ * by checking if TOC is valid or not.
+ */
+int arm_io_is_toc_valid(void)
+{
+       int result;
+
+       result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
+
+       return (result == 0);
+}
+