blob: 9b5e36e0e595146c0bce88c625be76da890566cc [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"
Fabio Utzig57c40f72017-12-12 21:48:30 -020013#include "bootsim.h"
David Brownde7729e2017-01-09 10:41:35 -070014
Fabio Utzig92be3fb2017-12-05 08:52:53 -020015#ifdef MCUBOOT_SIGN_EC256
16#include "../../../ext/tinycrypt/lib/include/tinycrypt/ecc_dsa.h"
17#endif
18
David Brown54b77792017-05-05 09:40:01 -060019#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_ERROR
David Brown75fd5dc2017-05-04 09:04:47 -060020#include <bootutil/bootutil_log.h>
21
David Brownbdb6db72017-07-06 10:14:37 -060022extern int sim_flash_erase(uint32_t offset, uint32_t size);
23extern int sim_flash_read(uint32_t offset, uint8_t *dest, uint32_t size);
24extern int sim_flash_write(uint32_t offset, const uint8_t *src, uint32_t size);
David Brownde7729e2017-01-09 10:41:35 -070025
David Brownde7729e2017-01-09 10:41:35 -070026static jmp_buf boot_jmpbuf;
27int flash_counter;
28
29int jumped = 0;
Fabio Utzig9b0ee902017-11-23 19:49:00 -020030uint8_t c_asserts = 0;
31uint8_t c_catch_asserts = 0;
David Brownde7729e2017-01-09 10:41:35 -070032
Fabio Utzig92be3fb2017-12-05 08:52:53 -020033int ecdsa256_sign_(const uint8_t *privkey, const uint8_t *hash,
34 unsigned hash_len, uint8_t *signature)
35{
36#ifdef MCUBOOT_SIGN_EC256
37 return uECC_sign(privkey, hash, hash_len, signature, uECC_secp256r1());
38#else
39 (void)privkey;
40 (void)hash;
41 (void)hash_len;
42 (void)signature;
43 return 0;
44#endif
45}
46
David Brown5acda262017-01-23 15:42:19 -070047uint8_t sim_flash_align = 1;
48uint8_t flash_area_align(const struct flash_area *area)
49{
Fabio Utzigcd5774b2017-11-29 10:18:26 -020050 (void)area;
David Brown7ad80882017-06-20 15:30:36 -060051 return sim_flash_align;
David Brown5acda262017-01-23 15:42:19 -070052}
53
David Brownde7729e2017-01-09 10:41:35 -070054struct area {
David Brown7ad80882017-06-20 15:30:36 -060055 struct flash_area whole;
56 struct flash_area *areas;
57 uint32_t num_areas;
58 uint8_t id;
David Brownde7729e2017-01-09 10:41:35 -070059};
60
61struct area_desc {
David Brown7ad80882017-06-20 15:30:36 -060062 struct area slots[16];
63 uint32_t num_slots;
David Brownde7729e2017-01-09 10:41:35 -070064};
65
66static struct area_desc *flash_areas;
67
David Brown7e701d82017-07-11 13:24:25 -060068void *(*mbedtls_calloc)(size_t n, size_t size);
69void (*mbedtls_free)(void *ptr);
70
David Brownbdb6db72017-07-06 10:14:37 -060071int invoke_boot_go(struct area_desc *adesc)
David Brownde7729e2017-01-09 10:41:35 -070072{
David Brown7ad80882017-06-20 15:30:36 -060073 int res;
74 struct boot_rsp rsp;
David Brownde7729e2017-01-09 10:41:35 -070075
David Brown7e701d82017-07-11 13:24:25 -060076 mbedtls_calloc = calloc;
77 mbedtls_free = free;
78
David Brown7ad80882017-06-20 15:30:36 -060079 flash_areas = adesc;
80 if (setjmp(boot_jmpbuf) == 0) {
81 res = boot_go(&rsp);
David Brownbdb6db72017-07-06 10:14:37 -060082 flash_areas = NULL;
David Brown7ad80882017-06-20 15:30:36 -060083 /* printf("boot_go off: %d (0x%08x)\n", res, rsp.br_image_off); */
84 return res;
85 } else {
David Brownbdb6db72017-07-06 10:14:37 -060086 flash_areas = NULL;
David Brown7ad80882017-06-20 15:30:36 -060087 return -0x13579;
88 }
David Brownde7729e2017-01-09 10:41:35 -070089}
90
91int hal_flash_read(uint8_t flash_id, uint32_t address, void *dst,
David Brown7ad80882017-06-20 15:30:36 -060092 uint32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -070093{
Fabio Utzigcd5774b2017-11-29 10:18:26 -020094 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -060095 // printf("hal_flash_read: %d, 0x%08x (0x%x)\n",
96 // flash_id, address, num_bytes);
David Brownbdb6db72017-07-06 10:14:37 -060097 return sim_flash_read(address, dst, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -070098}
99
100int hal_flash_write(uint8_t flash_id, uint32_t address,
David Brown7ad80882017-06-20 15:30:36 -0600101 const void *src, int32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -0700102{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200103 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -0600104 // printf("hal_flash_write: 0x%08x (0x%x)\n", address, num_bytes);
105 // fflush(stdout);
106 if (--flash_counter == 0) {
107 jumped++;
108 longjmp(boot_jmpbuf, 1);
109 }
David Brownbdb6db72017-07-06 10:14:37 -0600110 return sim_flash_write(address, src, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -0700111}
112
113int hal_flash_erase(uint8_t flash_id, uint32_t address,
David Brown7ad80882017-06-20 15:30:36 -0600114 uint32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -0700115{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200116 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -0600117 // printf("hal_flash_erase: 0x%08x, (0x%x)\n", address, num_bytes);
118 // fflush(stdout);
119 if (--flash_counter == 0) {
120 jumped++;
121 longjmp(boot_jmpbuf, 1);
122 }
David Brownbdb6db72017-07-06 10:14:37 -0600123 return sim_flash_erase(address, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -0700124}
125
126uint8_t hal_flash_align(uint8_t flash_id)
127{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200128 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -0600129 return sim_flash_align;
David Brownde7729e2017-01-09 10:41:35 -0700130}
131
132void *os_malloc(size_t size)
133{
David Brown7ad80882017-06-20 15:30:36 -0600134 // printf("os_malloc 0x%x bytes\n", size);
135 return malloc(size);
David Brownde7729e2017-01-09 10:41:35 -0700136}
137
138int flash_area_id_from_image_slot(int slot)
139{
David Brown7ad80882017-06-20 15:30:36 -0600140 return slot + 1;
David Brownde7729e2017-01-09 10:41:35 -0700141}
142
143int flash_area_open(uint8_t id, const struct flash_area **area)
144{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200145 uint32_t i;
David Brownde7729e2017-01-09 10:41:35 -0700146
David Brown7ad80882017-06-20 15:30:36 -0600147 for (i = 0; i < flash_areas->num_slots; i++) {
148 if (flash_areas->slots[i].id == id)
149 break;
150 }
151 if (i == flash_areas->num_slots) {
152 printf("Unsupported area\n");
153 abort();
154 }
David Brownde7729e2017-01-09 10:41:35 -0700155
David Brown7ad80882017-06-20 15:30:36 -0600156 /* Unsure if this is right, just returning the first area. */
157 *area = &flash_areas->slots[i].whole;
158 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700159}
160
161void flash_area_close(const struct flash_area *area)
162{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200163 (void)area;
David Brownde7729e2017-01-09 10:41:35 -0700164}
165
166/*
167 * Read/write/erase. Offset is relative from beginning of flash area.
168 */
169int flash_area_read(const struct flash_area *area, uint32_t off, void *dst,
David Brown7ad80882017-06-20 15:30:36 -0600170 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700171{
David Brown7ad80882017-06-20 15:30:36 -0600172 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x",
173 __func__, area->fa_id, off, len);
174 return hal_flash_read(area->fa_id,
175 area->fa_off + off,
176 dst, len);
David Brownde7729e2017-01-09 10:41:35 -0700177}
178
179int flash_area_write(const struct flash_area *area, uint32_t off, const void *src,
David Brown7ad80882017-06-20 15:30:36 -0600180 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700181{
David Brown7ad80882017-06-20 15:30:36 -0600182 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
183 area->fa_id, off, len);
184 return hal_flash_write(area->fa_id,
185 area->fa_off + off,
186 src, len);
David Brownde7729e2017-01-09 10:41:35 -0700187}
188
189int flash_area_erase(const struct flash_area *area, uint32_t off, uint32_t len)
190{
David Brown7ad80882017-06-20 15:30:36 -0600191 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
192 area->fa_id, off, len);
193 return hal_flash_erase(area->fa_id,
194 area->fa_off + off,
195 len);
David Brownde7729e2017-01-09 10:41:35 -0700196}
197
198int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret)
199{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200200 uint32_t i;
David Brown7ad80882017-06-20 15:30:36 -0600201 struct area *slot;
David Brownde7729e2017-01-09 10:41:35 -0700202
David Brown7ad80882017-06-20 15:30:36 -0600203 for (i = 0; i < flash_areas->num_slots; i++) {
204 if (flash_areas->slots[i].id == idx)
205 break;
206 }
207 if (i == flash_areas->num_slots) {
208 printf("Unsupported area\n");
209 abort();
210 }
David Brownde7729e2017-01-09 10:41:35 -0700211
David Brown7ad80882017-06-20 15:30:36 -0600212 slot = &flash_areas->slots[i];
David Brownde7729e2017-01-09 10:41:35 -0700213
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200214 if (slot->num_areas > (uint32_t)*cnt) {
David Brown7ad80882017-06-20 15:30:36 -0600215 printf("Too many areas in slot\n");
216 abort();
217 }
David Brownde7729e2017-01-09 10:41:35 -0700218
David Brown7ad80882017-06-20 15:30:36 -0600219 *cnt = slot->num_areas;
220 memcpy(ret, slot->areas, slot->num_areas * sizeof(struct flash_area));
David Brownde7729e2017-01-09 10:41:35 -0700221
David Brown7ad80882017-06-20 15:30:36 -0600222 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700223}
224
David Brown60399f62017-05-11 10:20:34 -0600225int flash_area_get_sectors(int fa_id, uint32_t *count,
226 struct flash_sector *sectors)
227{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200228 uint32_t i;
David Brown7ad80882017-06-20 15:30:36 -0600229 struct area *slot;
David Brown60399f62017-05-11 10:20:34 -0600230
David Brown7ad80882017-06-20 15:30:36 -0600231 for (i = 0; i < flash_areas->num_slots; i++) {
232 if (flash_areas->slots[i].id == fa_id)
233 break;
234 }
235 if (i == flash_areas->num_slots) {
236 printf("Unsupported area\n");
237 abort();
238 }
David Brown60399f62017-05-11 10:20:34 -0600239
David Brown7ad80882017-06-20 15:30:36 -0600240 slot = &flash_areas->slots[i];
David Brown60399f62017-05-11 10:20:34 -0600241
David Brown7ad80882017-06-20 15:30:36 -0600242 if (slot->num_areas > *count) {
243 printf("Too many areas in slot\n");
244 abort();
245 }
David Brown60399f62017-05-11 10:20:34 -0600246
David Brown7ad80882017-06-20 15:30:36 -0600247 for (i = 0; i < slot->num_areas; i++) {
248 sectors[i].fs_off = slot->areas[i].fa_off -
249 slot->whole.fa_off;
250 sectors[i].fs_size = slot->areas[i].fa_size;
251 }
252 *count = slot->num_areas;
David Brown60399f62017-05-11 10:20:34 -0600253
David Brown7ad80882017-06-20 15:30:36 -0600254 return 0;
David Brown60399f62017-05-11 10:20:34 -0600255}
Fabio Utzig9b0ee902017-11-23 19:49:00 -0200256
257void sim_assert(int x, const char *assertion, const char *file, unsigned int line, const char *function)
258{
259 if (!(x)) {
260 if (c_catch_asserts) {
261 c_asserts++;
262 } else {
263 BOOT_LOG_ERR("%s:%d: %s: Assertion `%s' failed.", file, line, function, assertion);
264
265 /* NOTE: if the assert below is triggered, the place where it was originally
266 * asserted is printed by the message above...
267 */
268 assert(x);
269 }
270 }
271}