Boot: Add boot_plaftorm_quit to boot_hal template

This enables specific platform operations before launching the
secure application.

Change-Id: I6c87662aefadac6552e0b65f35000cfc73735fd2
Signed-off-by: Michel Jaouen <michel.jaouen@st.com>
diff --git a/bl2/ext/mcuboot/bl2_main.c b/bl2/ext/mcuboot/bl2_main.c
index 391a996..b7dd03e 100644
--- a/bl2/ext/mcuboot/bl2_main.c
+++ b/bl2/ext/mcuboot/bl2_main.c
@@ -54,60 +54,9 @@
 /* Static buffer to be used by mbedtls for memory allocation */
 static uint8_t mbedtls_mem_buf[BL2_MBEDTLS_MEM_BUF_LEN];
 
-struct arm_vector_table {
-    uint32_t msp;
-    uint32_t reset;
-};
-
-/*!
- * \brief Chain-loading the next image in the boot sequence.
- *
- * This function calls the Reset_Handler of the next image in the boot sequence,
- * usually it is the secure firmware. Before passing the execution to next image
- * there is conditional rule to remove the secrets from the memory. This must be
- * done if the following conditions are satisfied:
- *  - Memory is shared between SW components at different stages of the trusted
- *    boot process.
- *  - There are secrets in the memory: KDF parameter, symmetric key,
- *    manufacturer sensitive code/data, etc.
- */
-#if defined(__ICCARM__)
-#pragma required = boot_clear_bl2_ram_area
-#endif
-
-__attribute__((naked)) void boot_jump_to_next_image(uint32_t reset_handler_addr)
-{
-    __ASM volatile(
-#if !defined(__ICCARM__)
-        ".syntax unified                 \n"
-#endif
-        "mov     r7, r0                  \n"
-        "bl      boot_clear_bl2_ram_area \n" /* Clear RAM before jump */
-        "movs    r0, #0                  \n" /* Clear registers: R0-R12, */
-        "mov     r1, r0                  \n" /* except R7 */
-        "mov     r2, r0                  \n"
-        "mov     r3, r0                  \n"
-        "mov     r4, r0                  \n"
-        "mov     r5, r0                  \n"
-        "mov     r6, r0                  \n"
-        "mov     r8, r0                  \n"
-        "mov     r9, r0                  \n"
-        "mov     r10, r0                 \n"
-        "mov     r11, r0                 \n"
-        "mov     r12, r0                 \n"
-        "mov     lr,  r0                 \n"
-        "bx      r7                      \n" /* Jump to Reset_handler */
-    );
-}
-
 static void do_boot(struct boot_rsp *rsp)
 {
-    /* Clang at O0, stores variables on the stack with SP relative addressing.
-     * When manually set the SP then the place of reset vector is lost.
-     * Static variables are stored in 'data' or 'bss' section, change of SP has
-     * no effect on them.
-     */
-    static struct arm_vector_table *vt;
+    struct boot_arm_vector_table *vt;
     uintptr_t flash_base;
     int rc;
 
@@ -123,15 +72,14 @@
        /* The image has been copied to SRAM, find the vector table
         * at the load address instead of image's address in flash
         */
-        vt = (struct arm_vector_table *)(rsp->br_hdr->ih_load_addr +
+        vt = (struct boot_arm_vector_table *)(rsp->br_hdr->ih_load_addr +
                                          rsp->br_hdr->ih_hdr_size);
     } else {
         /* Using the flash address as not executing in SRAM */
-        vt = (struct arm_vector_table *)(flash_base +
+        vt = (struct boot_arm_vector_table *)(flash_base +
                                          rsp->br_image_off +
                                          rsp->br_hdr->ih_hdr_size);
     }
-
     rc = FLASH_DEV_NAME.Uninitialize();
     if(rc != ARM_DRIVER_OK) {
         BOOT_LOG_ERR("Error while uninitializing Flash Interface");
@@ -140,20 +88,10 @@
 #if MCUBOOT_LOG_LEVEL > MCUBOOT_LOG_LEVEL_OFF
     stdio_uninit();
 #endif
-
-#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
-    /* Restore the Main Stack Pointer Limit register's reset value
-     * before passing execution to runtime firmware to make the
-     * bootloader transparent to it.
+    /* This function never returns, because it calls the secure application
+     * Reset_Handler()
      */
-    __set_MSPLIM(0);
-#endif
-
-    __set_MSP(vt->msp);
-    __DSB();
-    __ISB();
-
-    boot_jump_to_next_image(vt->reset);
+    boot_platform_quit(vt);
 }
 
 int main(void)
diff --git a/bl2/include/boot_hal.h b/bl2/include/boot_hal.h
index 03ff53b..eaf4368 100644
--- a/bl2/include/boot_hal.h
+++ b/bl2/include/boot_hal.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020 STMicroelectronics. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -14,6 +15,11 @@
 extern "C" {
 #endif
 
+struct boot_arm_vector_table {
+    uint32_t msp;
+    uint32_t reset;
+};
+
 /*
  * \brief It clears that part of the RAM which was used by MCUBoot, expect the
  *        TFM_SHARED_DATA area, which is used to pass data to the TF-M runtime.
@@ -32,6 +38,14 @@
  */
 void boot_clear_bl2_ram_area(void);
 
+/*
+ * \brief Chain-loading the next image in the boot sequence.
+ *        Can be overridden for platform specific initialization.
+ * \param[in] reset_handler_addr Address of next image's Reset_Handler() in
+                                 the boot chain (TF-M SPE, etc.)
+ */
+void boot_jump_to_next_image(uint32_t reset_handler_addr);
+
 /**
  * \brief Platform peripherals and devices initialization.
  *        Can be overridden for platform specific initialization.
@@ -40,6 +54,14 @@
  */
 int32_t boot_platform_init(void);
 
+/**
+ * \brief Platform operation to start secure image.
+ *        Can be overridden for platform specific initialization.
+ *
+ * \param[in] vt  pointer to secure application vector table descriptor
+ */
+void boot_platform_quit(struct boot_arm_vector_table *vt);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/platform/ext/common/boot_hal.c b/platform/ext/common/boot_hal.c
index 16b0aa7..50a6834 100644
--- a/platform/ext/common/boot_hal.c
+++ b/platform/ext/common/boot_hal.c
@@ -7,12 +7,54 @@
 
 #include "target_cfg.h"
 #include "cmsis.h"
+#include "boot_hal.h"
 #include "Driver_Flash.h"
 #include "flash_layout.h"
 
 /* Flash device name must be specified by target */
 extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
 
+/*!
+ * \brief Chain-loading the next image in the boot sequence.
+ *
+ * This function calls the Reset_Handler of the next image in the boot sequence,
+ * usually it is the secure firmware. Before passing the execution to next image
+ * there is conditional rule to remove the secrets from the memory. This must be
+ * done if the following conditions are satisfied:
+ *  - Memory is shared between SW components at different stages of the trusted
+ *    boot process.
+ *  - There are secrets in the memory: KDF parameter, symmetric key,
+ *    manufacturer sensitive code/data, etc.
+ */
+#if defined(__ICCARM__)
+#pragma required = boot_clear_bl2_ram_area
+#endif
+
+__WEAK __attribute__((naked)) void boot_jump_to_next_image(uint32_t reset_handler_addr)
+{
+    __ASM volatile(
+#if !defined(__ICCARM__)
+        ".syntax unified                 \n"
+#endif
+        "mov     r7, r0                  \n"
+        "bl      boot_clear_bl2_ram_area \n" /* Clear RAM before jump */
+        "movs    r0, #0                  \n" /* Clear registers: R0-R12, */
+        "mov     r1, r0                  \n" /* except R7 */
+        "mov     r2, r0                  \n"
+        "mov     r3, r0                  \n"
+        "mov     r4, r0                  \n"
+        "mov     r5, r0                  \n"
+        "mov     r6, r0                  \n"
+        "mov     r8, r0                  \n"
+        "mov     r9, r0                  \n"
+        "mov     r10, r0                 \n"
+        "mov     r11, r0                 \n"
+        "mov     r12, r0                 \n"
+        "mov     lr,  r0                 \n"
+        "bx      r7                      \n" /* Jump to Reset_handler */
+    );
+}
+
 /* bootloader platform-specific hw initialization */
 __WEAK int32_t boot_platform_init(void)
 {
@@ -25,3 +67,28 @@
 
     return 1;
 }
+
+__WEAK void boot_platform_quit(struct boot_arm_vector_table *vt)
+{
+    /* Clang at O0, stores variables on the stack with SP relative addressing.
+     * When manually set the SP then the place of reset vector is lost.
+     * Static variables are stored in 'data' or 'bss' section, change of SP has
+     * no effect on them.
+     */
+    static struct boot_arm_vector_table *vt_cpy;
+
+    vt_cpy = vt;
+#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
+    /* Restore the Main Stack Pointer Limit register's reset value
+     * before passing execution to runtime firmware to make the
+     * bootloader transparent to it.
+     */
+    __set_MSPLIM(0);
+#endif
+    __set_MSP(vt->msp);
+    __DSB();
+    __ISB();
+
+    boot_jump_to_next_image(vt_cpy->reset);
+}
+
diff --git a/platform/ext/target/stm/stm32l5xx/stm32l5xx.cmake b/platform/ext/target/stm/stm32l5xx/stm32l5xx.cmake
index 2b53ffa..b5d45a3 100644
--- a/platform/ext/target/stm/stm32l5xx/stm32l5xx.cmake
+++ b/platform/ext/target/stm/stm32l5xx/stm32l5xx.cmake
@@ -81,6 +81,7 @@
     list(APPEND ALL_SRC_C_BL2 "${PLATFORM_DIR}/target/stm/stm32l5xx/Native_Driver/tick.c")
     list(APPEND ALL_SRC_C_BL2 "${PLATFORM_DIR}/common/template/crypto_keys.c")
     list(APPEND ALL_SRC_C_BL2 "${PLATFORM_DIR}/common/template/tfm_rotpk.c")
+    list(APPEND ALL_SRC_C_BL2 "${PLATFORM_DIR}/common/boot_hal.c")
 
 if (NOT DEFINED BUILD_NATIVE_DRIVERS)
   message(FATAL_ERROR "Configuration variable BUILD_NATIVE_DRIVERS (true|false) is undefined!")