blob: 91d779abe03c8c3df0d80b82f57860b0215b058c [file] [log] [blame]
David Brownde7729e2017-01-09 10:41:35 -07001/* Run the boot image. */
2
Fabio Utzig9b0ee902017-11-23 19:49:00 -02003#include <assert.h>
David Brownde7729e2017-01-09 10:41:35 -07004#include <setjmp.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8#include <bootutil/bootutil.h>
9#include <bootutil/image.h>
10#include "flash_map/flash_map.h"
11
David Brownd2b18532017-07-12 09:51:31 -060012#include "../../../boot/bootutil/src/bootutil_priv.h"
David Brownde7729e2017-01-09 10:41:35 -070013
Fabio Utzig92be3fb2017-12-05 08:52:53 -020014#ifdef MCUBOOT_SIGN_EC256
15#include "../../../ext/tinycrypt/lib/include/tinycrypt/ecc_dsa.h"
16#endif
17
David Brown54b77792017-05-05 09:40:01 -060018#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_ERROR
David Brown75fd5dc2017-05-04 09:04:47 -060019#include <bootutil/bootutil_log.h>
20
David Brownbdb6db72017-07-06 10:14:37 -060021extern int sim_flash_erase(uint32_t offset, uint32_t size);
22extern int sim_flash_read(uint32_t offset, uint8_t *dest, uint32_t size);
23extern int sim_flash_write(uint32_t offset, const uint8_t *src, uint32_t size);
David Brownde7729e2017-01-09 10:41:35 -070024
David Brownde7729e2017-01-09 10:41:35 -070025static jmp_buf boot_jmpbuf;
26int flash_counter;
27
28int jumped = 0;
Fabio Utzig9b0ee902017-11-23 19:49:00 -020029uint8_t c_asserts = 0;
30uint8_t c_catch_asserts = 0;
David Brownde7729e2017-01-09 10:41:35 -070031
Fabio Utzig92be3fb2017-12-05 08:52:53 -020032int ecdsa256_sign_(const uint8_t *privkey, const uint8_t *hash,
33 unsigned hash_len, uint8_t *signature)
34{
35#ifdef MCUBOOT_SIGN_EC256
36 return uECC_sign(privkey, hash, hash_len, signature, uECC_secp256r1());
37#else
38 (void)privkey;
39 (void)hash;
40 (void)hash_len;
41 (void)signature;
42 return 0;
43#endif
44}
45
David Brown5acda262017-01-23 15:42:19 -070046uint8_t sim_flash_align = 1;
47uint8_t flash_area_align(const struct flash_area *area)
48{
Fabio Utzigcd5774b2017-11-29 10:18:26 -020049 (void)area;
David Brown7ad80882017-06-20 15:30:36 -060050 return sim_flash_align;
David Brown5acda262017-01-23 15:42:19 -070051}
52
David Brownde7729e2017-01-09 10:41:35 -070053struct area {
David Brown7ad80882017-06-20 15:30:36 -060054 struct flash_area whole;
55 struct flash_area *areas;
56 uint32_t num_areas;
57 uint8_t id;
David Brownde7729e2017-01-09 10:41:35 -070058};
59
60struct area_desc {
David Brown7ad80882017-06-20 15:30:36 -060061 struct area slots[16];
62 uint32_t num_slots;
David Brownde7729e2017-01-09 10:41:35 -070063};
64
65static struct area_desc *flash_areas;
66
David Brown7e701d82017-07-11 13:24:25 -060067void *(*mbedtls_calloc)(size_t n, size_t size);
68void (*mbedtls_free)(void *ptr);
69
David Brownbdb6db72017-07-06 10:14:37 -060070int invoke_boot_go(struct area_desc *adesc)
David Brownde7729e2017-01-09 10:41:35 -070071{
David Brown7ad80882017-06-20 15:30:36 -060072 int res;
73 struct boot_rsp rsp;
David Brownde7729e2017-01-09 10:41:35 -070074
David Brown7e701d82017-07-11 13:24:25 -060075 mbedtls_calloc = calloc;
76 mbedtls_free = free;
77
David Brown7ad80882017-06-20 15:30:36 -060078 flash_areas = adesc;
79 if (setjmp(boot_jmpbuf) == 0) {
80 res = boot_go(&rsp);
David Brownbdb6db72017-07-06 10:14:37 -060081 flash_areas = NULL;
David Brown7ad80882017-06-20 15:30:36 -060082 /* printf("boot_go off: %d (0x%08x)\n", res, rsp.br_image_off); */
83 return res;
84 } else {
David Brownbdb6db72017-07-06 10:14:37 -060085 flash_areas = NULL;
David Brown7ad80882017-06-20 15:30:36 -060086 return -0x13579;
87 }
David Brownde7729e2017-01-09 10:41:35 -070088}
89
90int hal_flash_read(uint8_t flash_id, uint32_t address, void *dst,
David Brown7ad80882017-06-20 15:30:36 -060091 uint32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -070092{
Fabio Utzigcd5774b2017-11-29 10:18:26 -020093 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -060094 // printf("hal_flash_read: %d, 0x%08x (0x%x)\n",
95 // flash_id, address, num_bytes);
David Brownbdb6db72017-07-06 10:14:37 -060096 return sim_flash_read(address, dst, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -070097}
98
99int hal_flash_write(uint8_t flash_id, uint32_t address,
David Brown7ad80882017-06-20 15:30:36 -0600100 const void *src, int32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -0700101{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200102 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -0600103 // printf("hal_flash_write: 0x%08x (0x%x)\n", address, num_bytes);
104 // fflush(stdout);
105 if (--flash_counter == 0) {
106 jumped++;
107 longjmp(boot_jmpbuf, 1);
108 }
David Brownbdb6db72017-07-06 10:14:37 -0600109 return sim_flash_write(address, src, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -0700110}
111
112int hal_flash_erase(uint8_t flash_id, uint32_t address,
David Brown7ad80882017-06-20 15:30:36 -0600113 uint32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -0700114{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200115 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -0600116 // printf("hal_flash_erase: 0x%08x, (0x%x)\n", address, num_bytes);
117 // fflush(stdout);
118 if (--flash_counter == 0) {
119 jumped++;
120 longjmp(boot_jmpbuf, 1);
121 }
David Brownbdb6db72017-07-06 10:14:37 -0600122 return sim_flash_erase(address, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -0700123}
124
125uint8_t hal_flash_align(uint8_t flash_id)
126{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200127 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -0600128 return sim_flash_align;
David Brownde7729e2017-01-09 10:41:35 -0700129}
130
131void *os_malloc(size_t size)
132{
David Brown7ad80882017-06-20 15:30:36 -0600133 // printf("os_malloc 0x%x bytes\n", size);
134 return malloc(size);
David Brownde7729e2017-01-09 10:41:35 -0700135}
136
137int flash_area_id_from_image_slot(int slot)
138{
David Brown7ad80882017-06-20 15:30:36 -0600139 return slot + 1;
David Brownde7729e2017-01-09 10:41:35 -0700140}
141
142int flash_area_open(uint8_t id, const struct flash_area **area)
143{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200144 uint32_t i;
David Brownde7729e2017-01-09 10:41:35 -0700145
David Brown7ad80882017-06-20 15:30:36 -0600146 for (i = 0; i < flash_areas->num_slots; i++) {
147 if (flash_areas->slots[i].id == id)
148 break;
149 }
150 if (i == flash_areas->num_slots) {
151 printf("Unsupported area\n");
152 abort();
153 }
David Brownde7729e2017-01-09 10:41:35 -0700154
David Brown7ad80882017-06-20 15:30:36 -0600155 /* Unsure if this is right, just returning the first area. */
156 *area = &flash_areas->slots[i].whole;
157 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700158}
159
160void flash_area_close(const struct flash_area *area)
161{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200162 (void)area;
David Brownde7729e2017-01-09 10:41:35 -0700163}
164
165/*
166 * Read/write/erase. Offset is relative from beginning of flash area.
167 */
168int flash_area_read(const struct flash_area *area, uint32_t off, void *dst,
David Brown7ad80882017-06-20 15:30:36 -0600169 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700170{
David Brown7ad80882017-06-20 15:30:36 -0600171 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x",
172 __func__, area->fa_id, off, len);
173 return hal_flash_read(area->fa_id,
174 area->fa_off + off,
175 dst, len);
David Brownde7729e2017-01-09 10:41:35 -0700176}
177
178int flash_area_write(const struct flash_area *area, uint32_t off, const void *src,
David Brown7ad80882017-06-20 15:30:36 -0600179 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700180{
David Brown7ad80882017-06-20 15:30:36 -0600181 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
182 area->fa_id, off, len);
183 return hal_flash_write(area->fa_id,
184 area->fa_off + off,
185 src, len);
David Brownde7729e2017-01-09 10:41:35 -0700186}
187
188int flash_area_erase(const struct flash_area *area, uint32_t off, uint32_t len)
189{
David Brown7ad80882017-06-20 15:30:36 -0600190 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
191 area->fa_id, off, len);
192 return hal_flash_erase(area->fa_id,
193 area->fa_off + off,
194 len);
David Brownde7729e2017-01-09 10:41:35 -0700195}
196
197int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret)
198{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200199 uint32_t i;
David Brown7ad80882017-06-20 15:30:36 -0600200 struct area *slot;
David Brownde7729e2017-01-09 10:41:35 -0700201
David Brown7ad80882017-06-20 15:30:36 -0600202 for (i = 0; i < flash_areas->num_slots; i++) {
203 if (flash_areas->slots[i].id == idx)
204 break;
205 }
206 if (i == flash_areas->num_slots) {
207 printf("Unsupported area\n");
208 abort();
209 }
David Brownde7729e2017-01-09 10:41:35 -0700210
David Brown7ad80882017-06-20 15:30:36 -0600211 slot = &flash_areas->slots[i];
David Brownde7729e2017-01-09 10:41:35 -0700212
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200213 if (slot->num_areas > (uint32_t)*cnt) {
David Brown7ad80882017-06-20 15:30:36 -0600214 printf("Too many areas in slot\n");
215 abort();
216 }
David Brownde7729e2017-01-09 10:41:35 -0700217
David Brown7ad80882017-06-20 15:30:36 -0600218 *cnt = slot->num_areas;
219 memcpy(ret, slot->areas, slot->num_areas * sizeof(struct flash_area));
David Brownde7729e2017-01-09 10:41:35 -0700220
David Brown7ad80882017-06-20 15:30:36 -0600221 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700222}
223
David Brown60399f62017-05-11 10:20:34 -0600224int flash_area_get_sectors(int fa_id, uint32_t *count,
225 struct flash_sector *sectors)
226{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200227 uint32_t i;
David Brown7ad80882017-06-20 15:30:36 -0600228 struct area *slot;
David Brown60399f62017-05-11 10:20:34 -0600229
David Brown7ad80882017-06-20 15:30:36 -0600230 for (i = 0; i < flash_areas->num_slots; i++) {
231 if (flash_areas->slots[i].id == fa_id)
232 break;
233 }
234 if (i == flash_areas->num_slots) {
235 printf("Unsupported area\n");
236 abort();
237 }
David Brown60399f62017-05-11 10:20:34 -0600238
David Brown7ad80882017-06-20 15:30:36 -0600239 slot = &flash_areas->slots[i];
David Brown60399f62017-05-11 10:20:34 -0600240
David Brown7ad80882017-06-20 15:30:36 -0600241 if (slot->num_areas > *count) {
242 printf("Too many areas in slot\n");
243 abort();
244 }
David Brown60399f62017-05-11 10:20:34 -0600245
David Brown7ad80882017-06-20 15:30:36 -0600246 for (i = 0; i < slot->num_areas; i++) {
247 sectors[i].fs_off = slot->areas[i].fa_off -
248 slot->whole.fa_off;
249 sectors[i].fs_size = slot->areas[i].fa_size;
250 }
251 *count = slot->num_areas;
David Brown60399f62017-05-11 10:20:34 -0600252
David Brown7ad80882017-06-20 15:30:36 -0600253 return 0;
David Brown60399f62017-05-11 10:20:34 -0600254}
Fabio Utzig9b0ee902017-11-23 19:49:00 -0200255
256void sim_assert(int x, const char *assertion, const char *file, unsigned int line, const char *function)
257{
258 if (!(x)) {
259 if (c_catch_asserts) {
260 c_asserts++;
261 } else {
262 BOOT_LOG_ERR("%s:%d: %s: Assertion `%s' failed.", file, line, function, assertion);
263
264 /* NOTE: if the assert below is triggered, the place where it was originally
265 * asserted is printed by the message above...
266 */
267 assert(x);
268 }
269 }
270}