| /* |
| * Copyright (c) 2019-2020, Arm Limited. All rights reserved. |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| * |
| */ |
| |
| #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) |
| { |
| int32_t result; |
| |
| result = FLASH_DEV_NAME.Initialize(NULL); |
| if (result == ARM_DRIVER_OK) { |
| return 0; |
| } |
| |
| 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_cpy->msp); |
| __DSB(); |
| __ISB(); |
| |
| boot_jump_to_next_image(vt_cpy->reset); |
| } |
| |