blob: 391a996cd7d14967ec36ff08e8b6f648e3103acb [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 */
TTornblom99f0be22019-12-17 16:22:38 +010074#if defined(__ICCARM__)
75#pragma required = boot_clear_bl2_ram_area
76#endif
77
Tamas Band4bf3472019-09-06 12:59:56 +010078__attribute__((naked)) void boot_jump_to_next_image(uint32_t reset_handler_addr)
79{
80 __ASM volatile(
TTornblom99f0be22019-12-17 16:22:38 +010081#if !defined(__ICCARM__)
Tamas Band4bf3472019-09-06 12:59:56 +010082 ".syntax unified \n"
TTornblom99f0be22019-12-17 16:22:38 +010083#endif
Tamas Band4bf3472019-09-06 12:59:56 +010084 "mov r7, r0 \n"
85 "bl boot_clear_bl2_ram_area \n" /* Clear RAM before jump */
86 "movs r0, #0 \n" /* Clear registers: R0-R12, */
87 "mov r1, r0 \n" /* except R7 */
88 "mov r2, r0 \n"
89 "mov r3, r0 \n"
90 "mov r4, r0 \n"
91 "mov r5, r0 \n"
92 "mov r6, r0 \n"
93 "mov r8, r0 \n"
94 "mov r9, r0 \n"
95 "mov r10, r0 \n"
96 "mov r11, r0 \n"
97 "mov r12, r0 \n"
98 "mov lr, r0 \n"
99 "bx r7 \n" /* Jump to Reset_handler */
100 );
101}
102
Tamas Banf70ef8c2017-12-19 15:35:09 +0000103static void do_boot(struct boot_rsp *rsp)
104{
Tamas Ban581034a2017-12-19 19:54:37 +0000105 /* Clang at O0, stores variables on the stack with SP relative addressing.
106 * When manually set the SP then the place of reset vector is lost.
107 * Static variables are stored in 'data' or 'bss' section, change of SP has
108 * no effect on them.
109 */
110 static struct arm_vector_table *vt;
Tamas Banf70ef8c2017-12-19 15:35:09 +0000111 uintptr_t flash_base;
112 int rc;
113
114 /* The beginning of the image is the ARM vector table, containing
115 * the initial stack pointer address and the reset vector
116 * consecutively. Manually set the stack pointer and jump into the
117 * reset vector
118 */
119 rc = flash_device_base(rsp->br_flash_dev_id, &flash_base);
120 assert(rc == 0);
121
Oliver Swedef9982442018-08-24 18:37:44 +0100122 if (rsp->br_hdr->ih_flags & IMAGE_F_RAM_LOAD) {
123 /* The image has been copied to SRAM, find the vector table
124 * at the load address instead of image's address in flash
125 */
126 vt = (struct arm_vector_table *)(rsp->br_hdr->ih_load_addr +
127 rsp->br_hdr->ih_hdr_size);
128 } else {
129 /* Using the flash address as not executing in SRAM */
130 vt = (struct arm_vector_table *)(flash_base +
131 rsp->br_image_off +
132 rsp->br_hdr->ih_hdr_size);
133 }
134
David Vinczeb57989f2018-09-24 10:59:04 +0200135 rc = FLASH_DEV_NAME.Uninitialize();
136 if(rc != ARM_DRIVER_OK) {
137 BOOT_LOG_ERR("Error while uninitializing Flash Interface");
138 }
139
David Vincze99f1b362019-12-12 16:17:35 +0100140#if MCUBOOT_LOG_LEVEL > MCUBOOT_LOG_LEVEL_OFF
David Vincze8da7f102018-09-24 10:53:46 +0200141 stdio_uninit();
David Vincze73dfbc52019-10-11 13:54:58 +0200142#endif
David Vincze8da7f102018-09-24 10:53:46 +0200143
David Hu5cc9a3f2019-06-14 13:10:40 +0800144#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
David Vinczee0a3c2f2019-05-15 16:45:14 +0200145 /* Restore the Main Stack Pointer Limit register's reset value
146 * before passing execution to runtime firmware to make the
147 * bootloader transparent to it.
148 */
149 __set_MSPLIM(0);
David Hu5cc9a3f2019-06-14 13:10:40 +0800150#endif
David Vinczee0a3c2f2019-05-15 16:45:14 +0200151
Tamas Ban581034a2017-12-19 19:54:37 +0000152 __set_MSP(vt->msp);
153 __DSB();
154 __ISB();
155
Tamas Band4bf3472019-09-06 12:59:56 +0100156 boot_jump_to_next_image(vt->reset);
Tamas Banf70ef8c2017-12-19 15:35:09 +0000157}
Tamas Banf70ef8c2017-12-19 15:35:09 +0000158
Tamas Ban581034a2017-12-19 19:54:37 +0000159int main(void)
Tamas Banf70ef8c2017-12-19 15:35:09 +0000160{
David Hu5cc9a3f2019-06-14 13:10:40 +0800161#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
David Vinczee0a3c2f2019-05-15 16:45:14 +0200162 uint32_t msp_stack_bottom =
163 (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
David Hu5cc9a3f2019-06-14 13:10:40 +0800164#endif
Tamas Banf70ef8c2017-12-19 15:35:09 +0000165 struct boot_rsp rsp;
166 int rc;
167
David Hu5cc9a3f2019-06-14 13:10:40 +0800168#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
David Vinczee0a3c2f2019-05-15 16:45:14 +0200169 __set_MSPLIM(msp_stack_bottom);
David Hu5cc9a3f2019-06-14 13:10:40 +0800170#endif
David Vinczee0a3c2f2019-05-15 16:45:14 +0200171
Andrei Narkevitchb0be4612020-01-27 17:26:19 -0800172 /* Perform platform specific initialization */
173 if (boot_platform_init() != 0) {
174 while (1)
175 ;
176 }
177
David Vincze99f1b362019-12-12 16:17:35 +0100178#if MCUBOOT_LOG_LEVEL > MCUBOOT_LOG_LEVEL_OFF
Gabor Kerteszeb953f52018-07-17 13:36:28 +0200179 stdio_init();
David Vincze73dfbc52019-10-11 13:54:58 +0200180#endif
Tamas Ban581034a2017-12-19 19:54:37 +0000181
Tamas Banf70ef8c2017-12-19 15:35:09 +0000182 BOOT_LOG_INF("Starting bootloader");
183
Tamas Banbd3f7512018-01-26 15:45:03 +0000184 /* Initialise the mbedtls static memory allocator so that mbedtls allocates
185 * memory from the provided static buffer instead of from the heap.
186 */
187 mbedtls_memory_buffer_alloc_init(mbedtls_mem_buf, BL2_MBEDTLS_MEM_BUF_LEN);
Tamas Banf70ef8c2017-12-19 15:35:09 +0000188
Raef Coles0e82adc2019-10-17 15:06:26 +0100189#ifdef CRYPTO_HW_ACCELERATOR
190 rc = crypto_hw_accelerator_init();
191 if (rc) {
192 BOOT_LOG_ERR("Error while initializing cryptographic accelerator.");
193 while (1);
194 }
195#endif /* CRYPTO_HW_ACCELERATOR */
196
David Vinczec3e313a2020-01-06 17:31:11 +0100197#ifndef MCUBOOT_USE_UPSTREAM
David Vincze060968d2019-05-23 01:13:14 +0200198 rc = boot_nv_security_counter_init();
199 if (rc != 0) {
200 BOOT_LOG_ERR("Error while initializing the security counter");
201 while (1)
202 ;
203 }
David Vinczec3e313a2020-01-06 17:31:11 +0100204#endif /* !MCUBOOT_USE_UPSTREAM */
David Vincze060968d2019-05-23 01:13:14 +0200205
Tamas Banf70ef8c2017-12-19 15:35:09 +0000206 rc = boot_go(&rsp);
207 if (rc != 0) {
208 BOOT_LOG_ERR("Unable to find bootable image");
209 while (1)
210 ;
211 }
212
Raef Coles0e82adc2019-10-17 15:06:26 +0100213#ifdef CRYPTO_HW_ACCELERATOR
214 rc = crypto_hw_accelerator_finish();
215 if (rc) {
216 BOOT_LOG_ERR("Error while uninitializing cryptographic accelerator.");
217 while (1);
218 }
219#endif /* CRYPTO_HW_ACCELERATOR */
220
Tamas Banf824e742019-10-25 21:22:26 +0100221/* This is a workaround to program the TF-M related cryptographic keys
222 * to CC312 OTP memory. This functionality is independent from secure boot,
223 * this is usually done in the factory floor during chip manufacturing.
224 */
225#ifdef CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING
226 BOOT_LOG_INF("OTP provisioning started.");
227 rc = crypto_hw_accelerator_otp_provisioning();
228 if (rc) {
229 BOOT_LOG_ERR("OTP provisioning FAILED: 0x%X", rc);
230 while (1);
231 } else {
232 BOOT_LOG_INF("OTP provisioning succeeded. TF-M won't be loaded.");
233
234 /* We don't need to boot - the only aim is provisioning. */
235 while (1);
236 }
237#endif /* CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING */
238
Tamas Banf70ef8c2017-12-19 15:35:09 +0000239 BOOT_LOG_INF("Bootloader chainload address offset: 0x%x",
240 rsp.br_image_off);
Tamas Banf70ef8c2017-12-19 15:35:09 +0000241 BOOT_LOG_INF("Jumping to the first image slot");
242 do_boot(&rsp);
243
244 BOOT_LOG_ERR("Never should get here");
245 while (1)
246 ;
247}