Boot: Remove platform specific code from bl2_main.c

Clean-up bl2_main.c and move all platform dependent code
to appropriate boot_hal.c

Signed-off-by: Balint Matyi <Balint.Matyi@arm.com>
Change-Id: Ieef1896ca6a0afc15c513bc4aa0acf3fa1a06c7a
diff --git a/bl2/ext/mcuboot/bl2_main.c b/bl2/ext/mcuboot/bl2_main.c
index e9fc75e..fcaab36 100644
--- a/bl2/ext/mcuboot/bl2_main.c
+++ b/bl2/ext/mcuboot/bl2_main.c
@@ -19,36 +19,21 @@
 #include <assert.h>
 #include "target.h"
 #include "tfm_hal_device_header.h"
-#include "Driver_Flash.h"
 #include "mbedtls/memory_buffer_alloc.h"
+#include "bootutil/security_cnt.h"
 #include "bootutil/bootutil_log.h"
 #include "bootutil/image.h"
 #include "bootutil/bootutil.h"
-#include "flash_map_backend/flash_map_backend.h"
 #include "bootutil/boot_record.h"
-#include "bootutil/security_cnt.h"
+#include "flash_map_backend/flash_map_backend.h"
 #include "boot_hal.h"
-#include "region.h"
-#if MCUBOOT_LOG_LEVEL > MCUBOOT_LOG_LEVEL_OFF
 #include "uart_stdout.h"
-#endif
-#if defined(CRYPTO_HW_ACCELERATOR) || \
-    defined(CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING)
-#include "crypto_hw.h"
-#endif
 
 /* Avoids the semihosting issue */
 #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
 __asm("  .global __ARM_use_no_argv\n");
 #endif
 
-#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
-REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
-#endif
-
-/* Flash device name must be specified by target */
-extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
-
 #ifdef MCUBOOT_ENCRYPT_RSA
 #define BL2_MBEDTLS_MEM_BUF_LEN 0x225C
 #else
@@ -84,31 +69,29 @@
                                          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");
-    }
 
 #if MCUBOOT_LOG_LEVEL > MCUBOOT_LOG_LEVEL_OFF
     stdio_uninit();
 #endif
+
     /* This function never returns, because it calls the secure application
-     * Reset_Handler()
+     * Reset_Handler().
      */
     boot_platform_quit(vt);
 }
 
 int main(void)
 {
-#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
-    uint32_t msp_stack_bottom =
-            (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
-#endif
     struct boot_rsp rsp;
     int rc;
 
-#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
-    __set_MSPLIM(msp_stack_bottom);
+    /* Initialise the mbedtls static memory allocator so that mbedtls allocates
+     * memory from the provided static buffer instead of from the heap.
+     */
+    mbedtls_memory_buffer_alloc_init(mbedtls_mem_buf, BL2_MBEDTLS_MEM_BUF_LEN);
+
+#if MCUBOOT_LOG_LEVEL > MCUBOOT_LOG_LEVEL_OFF
+    stdio_init();
 #endif
 
     /* Perform platform specific initialization */
@@ -117,25 +100,8 @@
             ;
     }
 
-#if MCUBOOT_LOG_LEVEL > MCUBOOT_LOG_LEVEL_OFF
-    stdio_init();
-#endif
-
     BOOT_LOG_INF("Starting bootloader");
 
-    /* Initialise the mbedtls static memory allocator so that mbedtls allocates
-     * memory from the provided static buffer instead of from the heap.
-     */
-    mbedtls_memory_buffer_alloc_init(mbedtls_mem_buf, BL2_MBEDTLS_MEM_BUF_LEN);
-
-#ifdef CRYPTO_HW_ACCELERATOR
-    rc = crypto_hw_accelerator_init();
-    if (rc) {
-        BOOT_LOG_ERR("Error while initializing cryptographic accelerator.");
-        while (1);
-    }
-#endif /* CRYPTO_HW_ACCELERATOR */
-
     rc = boot_nv_security_counter_init();
     if (rc != 0) {
         BOOT_LOG_ERR("Error while initializing the security counter");
@@ -150,32 +116,6 @@
             ;
     }
 
-#ifdef CRYPTO_HW_ACCELERATOR
-    rc = crypto_hw_accelerator_finish();
-    if (rc) {
-        BOOT_LOG_ERR("Error while uninitializing cryptographic accelerator.");
-        while (1);
-    }
-#endif /* CRYPTO_HW_ACCELERATOR */
-
-/* This is a workaround to program the TF-M related cryptographic keys
- * to CC312 OTP memory. This functionality is independent from secure boot,
- * this is usually done in the factory floor during chip manufacturing.
- */
-#ifdef CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING
-    BOOT_LOG_INF("OTP provisioning started.");
-    rc = crypto_hw_accelerator_otp_provisioning();
-    if (rc) {
-        BOOT_LOG_ERR("OTP provisioning FAILED: 0x%X", rc);
-        while (1);
-    } else {
-        BOOT_LOG_INF("OTP provisioning succeeded. TF-M won't be loaded.");
-
-        /* We don't need to boot - the only aim is provisioning. */
-        while (1);
-    }
-#endif /* CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING */
-
     BOOT_LOG_INF("Bootloader chainload address offset: 0x%x",
                  rsp.br_image_off);
     BOOT_LOG_INF("Jumping to the first image slot");
diff --git a/platform/ext/target/mps2/an519/boot_hal.c b/platform/ext/target/mps2/an519/boot_hal.c
index acb1fe3..8657000 100644
--- a/platform/ext/target/mps2/an519/boot_hal.c
+++ b/platform/ext/target/mps2/an519/boot_hal.c
@@ -7,9 +7,17 @@
 
 #include "cmsis.h"
 #include "region.h"
+#include "target_cfg.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;
 
 REGION_DECLARE(Image$$, ER_DATA, $$Base)[];
 REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[];
+REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
 
 __attribute__((naked)) void boot_clear_bl2_ram_area(void)
 {
@@ -32,3 +40,47 @@
         : "r0", "memory"
     );
 }
+
+int32_t boot_platform_init(void)
+{
+    int32_t result;
+
+    /* Initialize stack limit register */
+    uint32_t msp_stack_bottom =
+            (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
+
+    __set_MSPLIM(msp_stack_bottom);
+
+    result = FLASH_DEV_NAME.Initialize(NULL);
+    if (result != ARM_DRIVER_OK) {
+        return 1;
+    }
+
+    return 0;
+}
+
+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;
+    int32_t result;
+
+    result = FLASH_DEV_NAME.Uninitialize();
+    if (result != ARM_DRIVER_OK) {
+        while (1);
+    }
+
+    vt_cpy = vt;
+
+    __set_MSPLIM(0);
+    __set_MSP(vt->msp);
+    __DSB();
+    __ISB();
+
+    boot_jump_to_next_image(vt_cpy->reset);
+}
+
diff --git a/platform/ext/target/mps2/an521/boot_hal.c b/platform/ext/target/mps2/an521/boot_hal.c
index d5a804d..9e93972 100644
--- a/platform/ext/target/mps2/an521/boot_hal.c
+++ b/platform/ext/target/mps2/an521/boot_hal.c
@@ -7,9 +7,17 @@
 
 #include "cmsis.h"
 #include "region.h"
+#include "target_cfg.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;
 
 REGION_DECLARE(Image$$, ER_DATA, $$Base)[];
 REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[];
+REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
 
 __attribute__((naked)) void boot_clear_bl2_ram_area(void)
 {
@@ -28,3 +36,47 @@
         : "r0", "memory"
     );
 }
+
+int32_t boot_platform_init(void)
+{
+    int32_t result;
+
+    /* Initialize stack limit register */
+    uint32_t msp_stack_bottom =
+            (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
+
+    __set_MSPLIM(msp_stack_bottom);
+
+    result = FLASH_DEV_NAME.Initialize(NULL);
+    if (result != ARM_DRIVER_OK) {
+        return 1;
+    }
+
+    return 0;
+}
+
+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;
+    int32_t result;
+
+    result = FLASH_DEV_NAME.Uninitialize();
+    if (result != ARM_DRIVER_OK) {
+        while (1);
+    }
+
+    vt_cpy = vt;
+
+    __set_MSPLIM(0);
+    __set_MSP(vt->msp);
+    __DSB();
+    __ISB();
+
+    boot_jump_to_next_image(vt_cpy->reset);
+}
+
diff --git a/platform/ext/target/mps2/an539/boot_hal.c b/platform/ext/target/mps2/an539/boot_hal.c
index acb1fe3..8657000 100644
--- a/platform/ext/target/mps2/an539/boot_hal.c
+++ b/platform/ext/target/mps2/an539/boot_hal.c
@@ -7,9 +7,17 @@
 
 #include "cmsis.h"
 #include "region.h"
+#include "target_cfg.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;
 
 REGION_DECLARE(Image$$, ER_DATA, $$Base)[];
 REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[];
+REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
 
 __attribute__((naked)) void boot_clear_bl2_ram_area(void)
 {
@@ -32,3 +40,47 @@
         : "r0", "memory"
     );
 }
+
+int32_t boot_platform_init(void)
+{
+    int32_t result;
+
+    /* Initialize stack limit register */
+    uint32_t msp_stack_bottom =
+            (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
+
+    __set_MSPLIM(msp_stack_bottom);
+
+    result = FLASH_DEV_NAME.Initialize(NULL);
+    if (result != ARM_DRIVER_OK) {
+        return 1;
+    }
+
+    return 0;
+}
+
+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;
+    int32_t result;
+
+    result = FLASH_DEV_NAME.Uninitialize();
+    if (result != ARM_DRIVER_OK) {
+        while (1);
+    }
+
+    vt_cpy = vt;
+
+    __set_MSPLIM(0);
+    __set_MSP(vt->msp);
+    __DSB();
+    __ISB();
+
+    boot_jump_to_next_image(vt_cpy->reset);
+}
+
diff --git a/platform/ext/target/mps2/fvp_sse300/boot_hal.c b/platform/ext/target/mps2/fvp_sse300/boot_hal.c
index d5a804d..9e93972 100644
--- a/platform/ext/target/mps2/fvp_sse300/boot_hal.c
+++ b/platform/ext/target/mps2/fvp_sse300/boot_hal.c
@@ -7,9 +7,17 @@
 
 #include "cmsis.h"
 #include "region.h"
+#include "target_cfg.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;
 
 REGION_DECLARE(Image$$, ER_DATA, $$Base)[];
 REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[];
+REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
 
 __attribute__((naked)) void boot_clear_bl2_ram_area(void)
 {
@@ -28,3 +36,47 @@
         : "r0", "memory"
     );
 }
+
+int32_t boot_platform_init(void)
+{
+    int32_t result;
+
+    /* Initialize stack limit register */
+    uint32_t msp_stack_bottom =
+            (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
+
+    __set_MSPLIM(msp_stack_bottom);
+
+    result = FLASH_DEV_NAME.Initialize(NULL);
+    if (result != ARM_DRIVER_OK) {
+        return 1;
+    }
+
+    return 0;
+}
+
+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;
+    int32_t result;
+
+    result = FLASH_DEV_NAME.Uninitialize();
+    if (result != ARM_DRIVER_OK) {
+        while (1);
+    }
+
+    vt_cpy = vt;
+
+    __set_MSPLIM(0);
+    __set_MSP(vt->msp);
+    __DSB();
+    __ISB();
+
+    boot_jump_to_next_image(vt_cpy->reset);
+}
+
diff --git a/platform/ext/target/mps2/sse-200_aws/boot_hal.c b/platform/ext/target/mps2/sse-200_aws/boot_hal.c
index bea5786..9e93972 100644
--- a/platform/ext/target/mps2/sse-200_aws/boot_hal.c
+++ b/platform/ext/target/mps2/sse-200_aws/boot_hal.c
@@ -7,10 +7,17 @@
 
 #include "cmsis.h"
 #include "region.h"
+#include "target_cfg.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;
 
 REGION_DECLARE(Image$$, ER_DATA, $$Base)[];
 REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[];
+REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
 
 __attribute__((naked)) void boot_clear_bl2_ram_area(void)
 {
@@ -29,3 +36,47 @@
         : "r0", "memory"
     );
 }
+
+int32_t boot_platform_init(void)
+{
+    int32_t result;
+
+    /* Initialize stack limit register */
+    uint32_t msp_stack_bottom =
+            (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
+
+    __set_MSPLIM(msp_stack_bottom);
+
+    result = FLASH_DEV_NAME.Initialize(NULL);
+    if (result != ARM_DRIVER_OK) {
+        return 1;
+    }
+
+    return 0;
+}
+
+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;
+    int32_t result;
+
+    result = FLASH_DEV_NAME.Uninitialize();
+    if (result != ARM_DRIVER_OK) {
+        while (1);
+    }
+
+    vt_cpy = vt;
+
+    __set_MSPLIM(0);
+    __set_MSP(vt->msp);
+    __DSB();
+    __ISB();
+
+    boot_jump_to_next_image(vt_cpy->reset);
+}
+
diff --git a/platform/ext/target/mps3/an524/boot_hal.c b/platform/ext/target/mps3/an524/boot_hal.c
index d5a804d..9e93972 100644
--- a/platform/ext/target/mps3/an524/boot_hal.c
+++ b/platform/ext/target/mps3/an524/boot_hal.c
@@ -7,9 +7,17 @@
 
 #include "cmsis.h"
 #include "region.h"
+#include "target_cfg.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;
 
 REGION_DECLARE(Image$$, ER_DATA, $$Base)[];
 REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[];
+REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
 
 __attribute__((naked)) void boot_clear_bl2_ram_area(void)
 {
@@ -28,3 +36,47 @@
         : "r0", "memory"
     );
 }
+
+int32_t boot_platform_init(void)
+{
+    int32_t result;
+
+    /* Initialize stack limit register */
+    uint32_t msp_stack_bottom =
+            (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
+
+    __set_MSPLIM(msp_stack_bottom);
+
+    result = FLASH_DEV_NAME.Initialize(NULL);
+    if (result != ARM_DRIVER_OK) {
+        return 1;
+    }
+
+    return 0;
+}
+
+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;
+    int32_t result;
+
+    result = FLASH_DEV_NAME.Uninitialize();
+    if (result != ARM_DRIVER_OK) {
+        while (1);
+    }
+
+    vt_cpy = vt;
+
+    __set_MSPLIM(0);
+    __set_MSP(vt->msp);
+    __DSB();
+    __ISB();
+
+    boot_jump_to_next_image(vt_cpy->reset);
+}
+
diff --git a/platform/ext/target/musca_a/boot_hal.c b/platform/ext/target/musca_a/boot_hal.c
index d5a804d..9e93972 100644
--- a/platform/ext/target/musca_a/boot_hal.c
+++ b/platform/ext/target/musca_a/boot_hal.c
@@ -7,9 +7,17 @@
 
 #include "cmsis.h"
 #include "region.h"
+#include "target_cfg.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;
 
 REGION_DECLARE(Image$$, ER_DATA, $$Base)[];
 REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[];
+REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
 
 __attribute__((naked)) void boot_clear_bl2_ram_area(void)
 {
@@ -28,3 +36,47 @@
         : "r0", "memory"
     );
 }
+
+int32_t boot_platform_init(void)
+{
+    int32_t result;
+
+    /* Initialize stack limit register */
+    uint32_t msp_stack_bottom =
+            (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
+
+    __set_MSPLIM(msp_stack_bottom);
+
+    result = FLASH_DEV_NAME.Initialize(NULL);
+    if (result != ARM_DRIVER_OK) {
+        return 1;
+    }
+
+    return 0;
+}
+
+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;
+    int32_t result;
+
+    result = FLASH_DEV_NAME.Uninitialize();
+    if (result != ARM_DRIVER_OK) {
+        while (1);
+    }
+
+    vt_cpy = vt;
+
+    __set_MSPLIM(0);
+    __set_MSP(vt->msp);
+    __DSB();
+    __ISB();
+
+    boot_jump_to_next_image(vt_cpy->reset);
+}
+
diff --git a/platform/ext/target/musca_b1/boot_hal.c b/platform/ext/target/musca_b1/boot_hal.c
index d5a804d..1956bec 100644
--- a/platform/ext/target/musca_b1/boot_hal.c
+++ b/platform/ext/target/musca_b1/boot_hal.c
@@ -7,9 +7,22 @@
 
 #include "cmsis.h"
 #include "region.h"
+#include "target_cfg.h"
+#include "boot_hal.h"
+#include "Driver_Flash.h"
+#include "flash_layout.h"
+
+#if defined(CRYPTO_HW_ACCELERATOR) || \
+    defined(CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING)
+#include "crypto_hw.h"
+#endif
+
+/* Flash device name must be specified by target */
+extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
 
 REGION_DECLARE(Image$$, ER_DATA, $$Base)[];
 REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[];
+REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
 
 __attribute__((naked)) void boot_clear_bl2_ram_area(void)
 {
@@ -28,3 +41,80 @@
         : "r0", "memory"
     );
 }
+
+int32_t boot_platform_init(void)
+{
+    int32_t result;
+
+    /* Initialize stack limit register */
+    uint32_t msp_stack_bottom =
+            (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
+
+    __set_MSPLIM(msp_stack_bottom);
+
+    result = FLASH_DEV_NAME.Initialize(NULL);
+    if (result != ARM_DRIVER_OK) {
+        return 1;
+    }
+
+#ifdef CRYPTO_HW_ACCELERATOR
+    result = crypto_hw_accelerator_init();
+    if (result) {
+        BOOT_LOG_ERR("Error while initializing cryptographic accelerator.");
+        return 1;
+    }
+#endif /* CRYPTO_HW_ACCELERATOR */
+
+/* This is a workaround to program the TF-M related cryptographic keys
+ * to CC312 OTP memory. This functionality is independent from secure boot,
+ * this is usually done on the factory floor during chip manufacturing.
+ */
+#ifdef CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING
+    BOOT_LOG_INF("OTP provisioning started.");
+    result = crypto_hw_accelerator_otp_provisioning();
+    if (result) {
+        BOOT_LOG_ERR("OTP provisioning FAILED: 0x%X", result);
+        return 1;
+    } else {
+        BOOT_LOG_INF("OTP provisioning succeeded. TF-M won't be loaded.");
+
+        /* We don't need to boot - the only aim is provisioning. */
+        while (1);
+    }
+#endif /* CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING */
+
+    return 0;
+}
+
+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;
+    int32_t result;
+
+#ifdef CRYPTO_HW_ACCELERATOR
+    result = crypto_hw_accelerator_finish();
+    if (result) {
+        while (1);
+    }
+#endif /* CRYPTO_HW_ACCELERATOR */
+
+    result = FLASH_DEV_NAME.Uninitialize();
+    if (result != ARM_DRIVER_OK) {
+        while (1);
+    }
+
+    vt_cpy = vt;
+
+    __set_MSPLIM(0);
+    __set_MSP(vt->msp);
+    __DSB();
+    __ISB();
+
+    boot_jump_to_next_image(vt_cpy->reset);
+}
+
diff --git a/platform/ext/target/musca_s1/boot_hal.c b/platform/ext/target/musca_s1/boot_hal.c
index d5a804d..1956bec 100644
--- a/platform/ext/target/musca_s1/boot_hal.c
+++ b/platform/ext/target/musca_s1/boot_hal.c
@@ -7,9 +7,22 @@
 
 #include "cmsis.h"
 #include "region.h"
+#include "target_cfg.h"
+#include "boot_hal.h"
+#include "Driver_Flash.h"
+#include "flash_layout.h"
+
+#if defined(CRYPTO_HW_ACCELERATOR) || \
+    defined(CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING)
+#include "crypto_hw.h"
+#endif
+
+/* Flash device name must be specified by target */
+extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
 
 REGION_DECLARE(Image$$, ER_DATA, $$Base)[];
 REGION_DECLARE(Image$$, ARM_LIB_HEAP, $$ZI$$Limit)[];
+REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
 
 __attribute__((naked)) void boot_clear_bl2_ram_area(void)
 {
@@ -28,3 +41,80 @@
         : "r0", "memory"
     );
 }
+
+int32_t boot_platform_init(void)
+{
+    int32_t result;
+
+    /* Initialize stack limit register */
+    uint32_t msp_stack_bottom =
+            (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
+
+    __set_MSPLIM(msp_stack_bottom);
+
+    result = FLASH_DEV_NAME.Initialize(NULL);
+    if (result != ARM_DRIVER_OK) {
+        return 1;
+    }
+
+#ifdef CRYPTO_HW_ACCELERATOR
+    result = crypto_hw_accelerator_init();
+    if (result) {
+        BOOT_LOG_ERR("Error while initializing cryptographic accelerator.");
+        return 1;
+    }
+#endif /* CRYPTO_HW_ACCELERATOR */
+
+/* This is a workaround to program the TF-M related cryptographic keys
+ * to CC312 OTP memory. This functionality is independent from secure boot,
+ * this is usually done on the factory floor during chip manufacturing.
+ */
+#ifdef CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING
+    BOOT_LOG_INF("OTP provisioning started.");
+    result = crypto_hw_accelerator_otp_provisioning();
+    if (result) {
+        BOOT_LOG_ERR("OTP provisioning FAILED: 0x%X", result);
+        return 1;
+    } else {
+        BOOT_LOG_INF("OTP provisioning succeeded. TF-M won't be loaded.");
+
+        /* We don't need to boot - the only aim is provisioning. */
+        while (1);
+    }
+#endif /* CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING */
+
+    return 0;
+}
+
+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;
+    int32_t result;
+
+#ifdef CRYPTO_HW_ACCELERATOR
+    result = crypto_hw_accelerator_finish();
+    if (result) {
+        while (1);
+    }
+#endif /* CRYPTO_HW_ACCELERATOR */
+
+    result = FLASH_DEV_NAME.Uninitialize();
+    if (result != ARM_DRIVER_OK) {
+        while (1);
+    }
+
+    vt_cpy = vt;
+
+    __set_MSPLIM(0);
+    __set_MSP(vt->msp);
+    __DSB();
+    __ISB();
+
+    boot_jump_to_next_image(vt_cpy->reset);
+}
+