blob: 62b93d984e1c37488761b3ca48006227ea274d7d [file] [log] [blame]
Tamas Banf70ef8c2017-12-19 15:35:09 +00001/*
2 * Copyright (c) 2012-2014 Wind River Systems, Inc.
David Vincze225c58f2019-12-09 17:32:48 +01003 * Copyright (c) 2017-2020 Arm Limited.
Tamas Banf70ef8c2017-12-19 15:35:09 +00004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
Balint Matyi2fe04922020-02-18 12:27:38 +000018#include "mcuboot_config/mcuboot_config.h"
Tamas Banf70ef8c2017-12-19 15:35:09 +000019#include <assert.h>
Tamas Ban581034a2017-12-19 19:54:37 +000020#include "bl2_util.h"
Tamas Banf70ef8c2017-12-19 15:35:09 +000021#include "target.h"
Kevin Pengbc5e5aa2019-10-16 10:55:17 +080022#include "tfm_hal_device_header.h"
Tamas Banc3828852018-02-01 12:24:16 +000023#include "Driver_Flash.h"
Tamas Banbd3f7512018-01-26 15:45:03 +000024#include "mbedtls/memory_buffer_alloc.h"
Tamas Banf70ef8c2017-12-19 15:35:09 +000025#include "bootutil/bootutil_log.h"
26#include "bootutil/image.h"
27#include "bootutil/bootutil.h"
David Vincze225c58f2019-12-09 17:32:48 +010028#include "flash_map_backend/flash_map_backend.h"
29#include "boot_record.h"
David Vincze060968d2019-05-23 01:13:14 +020030#include "security_cnt.h"
David Vincze225c58f2019-12-09 17:32:48 +010031#include "boot_hal.h"
TTornblom83d96372019-11-19 12:53:16 +010032#include "region.h"
David Vincze99f1b362019-12-12 16:17:35 +010033#if MCUBOOT_LOG_LEVEL > MCUBOOT_LOG_LEVEL_OFF
David Vincze73dfbc52019-10-11 13:54:58 +020034#include "uart_stdout.h"
35#endif
Tamas Banf824e742019-10-25 21:22:26 +010036#if defined(CRYPTO_HW_ACCELERATOR) || \
37 defined(CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING)
Raef Coles0e82adc2019-10-17 15:06:26 +010038#include "crypto_hw.h"
Tamas Banf824e742019-10-25 21:22:26 +010039#endif
Tamas Banf70ef8c2017-12-19 15:35:09 +000040
Tamas Ban581034a2017-12-19 19:54:37 +000041/* Avoids the semihosting issue */
42#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
43__asm(" .global __ARM_use_no_argv\n");
44#endif
45
David Hu5cc9a3f2019-06-14 13:10:40 +080046#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
David Vinczee0a3c2f2019-05-15 16:45:14 +020047REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
David Hu5cc9a3f2019-06-14 13:10:40 +080048#endif
David Vinczee0a3c2f2019-05-15 16:45:14 +020049
Tamas Banc3828852018-02-01 12:24:16 +000050/* Flash device name must be specified by target */
51extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
Tamas Banf70ef8c2017-12-19 15:35:09 +000052
Tamas Banbd3f7512018-01-26 15:45:03 +000053#define BL2_MBEDTLS_MEM_BUF_LEN 0x2000
54/* Static buffer to be used by mbedtls for memory allocation */
55static uint8_t mbedtls_mem_buf[BL2_MBEDTLS_MEM_BUF_LEN];
Tamas Banf70ef8c2017-12-19 15:35:09 +000056
Tamas Banf70ef8c2017-12-19 15:35:09 +000057struct arm_vector_table {
58 uint32_t msp;
59 uint32_t reset;
60};
61
Tamas Band4bf3472019-09-06 12:59:56 +010062/*!
63 * \brief Chain-loading the next image in the boot sequence.
64 *
65 * This function calls the Reset_Handler of the next image in the boot sequence,
66 * usually it is the secure firmware. Before passing the execution to next image
67 * there is conditional rule to remove the secrets from the memory. This must be
68 * done if the following conditions are satisfied:
69 * - Memory is shared between SW components at different stages of the trusted
70 * boot process.
71 * - There are secrets in the memory: KDF parameter, symmetric key,
72 * manufacturer sensitive code/data, etc.
73 */
74__attribute__((naked)) void boot_jump_to_next_image(uint32_t reset_handler_addr)
75{
76 __ASM volatile(
77 ".syntax unified \n"
78 "mov r7, r0 \n"
79 "bl boot_clear_bl2_ram_area \n" /* Clear RAM before jump */
80 "movs r0, #0 \n" /* Clear registers: R0-R12, */
81 "mov r1, r0 \n" /* except R7 */
82 "mov r2, r0 \n"
83 "mov r3, r0 \n"
84 "mov r4, r0 \n"
85 "mov r5, r0 \n"
86 "mov r6, r0 \n"
87 "mov r8, r0 \n"
88 "mov r9, r0 \n"
89 "mov r10, r0 \n"
90 "mov r11, r0 \n"
91 "mov r12, r0 \n"
92 "mov lr, r0 \n"
93 "bx r7 \n" /* Jump to Reset_handler */
94 );
95}
96
Tamas Banf70ef8c2017-12-19 15:35:09 +000097static void do_boot(struct boot_rsp *rsp)
98{
Tamas Ban581034a2017-12-19 19:54:37 +000099 /* Clang at O0, stores variables on the stack with SP relative addressing.
100 * When manually set the SP then the place of reset vector is lost.
101 * Static variables are stored in 'data' or 'bss' section, change of SP has
102 * no effect on them.
103 */
104 static struct arm_vector_table *vt;
Tamas Banf70ef8c2017-12-19 15:35:09 +0000105 uintptr_t flash_base;
106 int rc;
107
108 /* The beginning of the image is the ARM vector table, containing
109 * the initial stack pointer address and the reset vector
110 * consecutively. Manually set the stack pointer and jump into the
111 * reset vector
112 */
113 rc = flash_device_base(rsp->br_flash_dev_id, &flash_base);
114 assert(rc == 0);
115
Oliver Swedef9982442018-08-24 18:37:44 +0100116 if (rsp->br_hdr->ih_flags & IMAGE_F_RAM_LOAD) {
117 /* The image has been copied to SRAM, find the vector table
118 * at the load address instead of image's address in flash
119 */
120 vt = (struct arm_vector_table *)(rsp->br_hdr->ih_load_addr +
121 rsp->br_hdr->ih_hdr_size);
122 } else {
123 /* Using the flash address as not executing in SRAM */
124 vt = (struct arm_vector_table *)(flash_base +
125 rsp->br_image_off +
126 rsp->br_hdr->ih_hdr_size);
127 }
128
David Vinczeb57989f2018-09-24 10:59:04 +0200129 rc = FLASH_DEV_NAME.Uninitialize();
130 if(rc != ARM_DRIVER_OK) {
131 BOOT_LOG_ERR("Error while uninitializing Flash Interface");
132 }
133
David Vincze99f1b362019-12-12 16:17:35 +0100134#if MCUBOOT_LOG_LEVEL > MCUBOOT_LOG_LEVEL_OFF
David Vincze8da7f102018-09-24 10:53:46 +0200135 stdio_uninit();
David Vincze73dfbc52019-10-11 13:54:58 +0200136#endif
David Vincze8da7f102018-09-24 10:53:46 +0200137
David Hu5cc9a3f2019-06-14 13:10:40 +0800138#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
David Vinczee0a3c2f2019-05-15 16:45:14 +0200139 /* Restore the Main Stack Pointer Limit register's reset value
140 * before passing execution to runtime firmware to make the
141 * bootloader transparent to it.
142 */
143 __set_MSPLIM(0);
David Hu5cc9a3f2019-06-14 13:10:40 +0800144#endif
David Vinczee0a3c2f2019-05-15 16:45:14 +0200145
Tamas Ban581034a2017-12-19 19:54:37 +0000146 __set_MSP(vt->msp);
147 __DSB();
148 __ISB();
149
Tamas Band4bf3472019-09-06 12:59:56 +0100150 boot_jump_to_next_image(vt->reset);
Tamas Banf70ef8c2017-12-19 15:35:09 +0000151}
Tamas Banf70ef8c2017-12-19 15:35:09 +0000152
Tamas Ban581034a2017-12-19 19:54:37 +0000153int main(void)
Tamas Banf70ef8c2017-12-19 15:35:09 +0000154{
David Hu5cc9a3f2019-06-14 13:10:40 +0800155#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
David Vinczee0a3c2f2019-05-15 16:45:14 +0200156 uint32_t msp_stack_bottom =
157 (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
David Hu5cc9a3f2019-06-14 13:10:40 +0800158#endif
Tamas Banf70ef8c2017-12-19 15:35:09 +0000159 struct boot_rsp rsp;
160 int rc;
161
David Hu5cc9a3f2019-06-14 13:10:40 +0800162#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
David Vinczee0a3c2f2019-05-15 16:45:14 +0200163 __set_MSPLIM(msp_stack_bottom);
David Hu5cc9a3f2019-06-14 13:10:40 +0800164#endif
David Vinczee0a3c2f2019-05-15 16:45:14 +0200165
Andrei Narkevitchb0be4612020-01-27 17:26:19 -0800166 /* Perform platform specific initialization */
167 if (boot_platform_init() != 0) {
168 while (1)
169 ;
170 }
171
David Vincze99f1b362019-12-12 16:17:35 +0100172#if MCUBOOT_LOG_LEVEL > MCUBOOT_LOG_LEVEL_OFF
Gabor Kerteszeb953f52018-07-17 13:36:28 +0200173 stdio_init();
David Vincze73dfbc52019-10-11 13:54:58 +0200174#endif
Tamas Ban581034a2017-12-19 19:54:37 +0000175
Tamas Banf70ef8c2017-12-19 15:35:09 +0000176 BOOT_LOG_INF("Starting bootloader");
177
Tamas Banbd3f7512018-01-26 15:45:03 +0000178 /* Initialise the mbedtls static memory allocator so that mbedtls allocates
179 * memory from the provided static buffer instead of from the heap.
180 */
181 mbedtls_memory_buffer_alloc_init(mbedtls_mem_buf, BL2_MBEDTLS_MEM_BUF_LEN);
Tamas Banf70ef8c2017-12-19 15:35:09 +0000182
Raef Coles0e82adc2019-10-17 15:06:26 +0100183#ifdef CRYPTO_HW_ACCELERATOR
184 rc = crypto_hw_accelerator_init();
185 if (rc) {
186 BOOT_LOG_ERR("Error while initializing cryptographic accelerator.");
187 while (1);
188 }
189#endif /* CRYPTO_HW_ACCELERATOR */
190
David Vinczec3e313a2020-01-06 17:31:11 +0100191#ifndef MCUBOOT_USE_UPSTREAM
David Vincze060968d2019-05-23 01:13:14 +0200192 rc = boot_nv_security_counter_init();
193 if (rc != 0) {
194 BOOT_LOG_ERR("Error while initializing the security counter");
195 while (1)
196 ;
197 }
David Vinczec3e313a2020-01-06 17:31:11 +0100198#endif /* !MCUBOOT_USE_UPSTREAM */
David Vincze060968d2019-05-23 01:13:14 +0200199
Tamas Banf70ef8c2017-12-19 15:35:09 +0000200 rc = boot_go(&rsp);
201 if (rc != 0) {
202 BOOT_LOG_ERR("Unable to find bootable image");
203 while (1)
204 ;
205 }
206
Raef Coles0e82adc2019-10-17 15:06:26 +0100207#ifdef CRYPTO_HW_ACCELERATOR
208 rc = crypto_hw_accelerator_finish();
209 if (rc) {
210 BOOT_LOG_ERR("Error while uninitializing cryptographic accelerator.");
211 while (1);
212 }
213#endif /* CRYPTO_HW_ACCELERATOR */
214
Tamas Banf824e742019-10-25 21:22:26 +0100215/* This is a workaround to program the TF-M related cryptographic keys
216 * to CC312 OTP memory. This functionality is independent from secure boot,
217 * this is usually done in the factory floor during chip manufacturing.
218 */
219#ifdef CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING
220 BOOT_LOG_INF("OTP provisioning started.");
221 rc = crypto_hw_accelerator_otp_provisioning();
222 if (rc) {
223 BOOT_LOG_ERR("OTP provisioning FAILED: 0x%X", rc);
224 while (1);
225 } else {
226 BOOT_LOG_INF("OTP provisioning succeeded. TF-M won't be loaded.");
227
228 /* We don't need to boot - the only aim is provisioning. */
229 while (1);
230 }
231#endif /* CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING */
232
Tamas Banf70ef8c2017-12-19 15:35:09 +0000233 BOOT_LOG_INF("Bootloader chainload address offset: 0x%x",
234 rsp.br_image_off);
Tamas Banf70ef8c2017-12-19 15:35:09 +0000235 BOOT_LOG_INF("Jumping to the first image slot");
236 do_boot(&rsp);
237
238 BOOT_LOG_ERR("Never should get here");
239 while (1)
240 ;
241}