blob: d749e4996be5378dc7a06026c49e09ff2b27f86f [file] [log] [blame]
David Brownde7729e2017-01-09 10:41:35 -07001/* Run the boot image. */
2
3#include <setjmp.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <bootutil/bootutil.h>
8#include <bootutil/image.h>
9#include "flash_map/flash_map.h"
10
David Brownd2b18532017-07-12 09:51:31 -060011#include "../../../boot/bootutil/src/bootutil_priv.h"
David Brownde7729e2017-01-09 10:41:35 -070012
Fabio Utzig92be3fb2017-12-05 08:52:53 -020013#ifdef MCUBOOT_SIGN_EC256
14#include "../../../ext/tinycrypt/lib/include/tinycrypt/ecc_dsa.h"
15#endif
16
David Brown54b77792017-05-05 09:40:01 -060017#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_ERROR
David Brown75fd5dc2017-05-04 09:04:47 -060018#include <bootutil/bootutil_log.h>
19
David Brownbdb6db72017-07-06 10:14:37 -060020extern int sim_flash_erase(uint32_t offset, uint32_t size);
21extern int sim_flash_read(uint32_t offset, uint8_t *dest, uint32_t size);
22extern int sim_flash_write(uint32_t offset, const uint8_t *src, uint32_t size);
David Brownde7729e2017-01-09 10:41:35 -070023
David Brownde7729e2017-01-09 10:41:35 -070024static jmp_buf boot_jmpbuf;
25int flash_counter;
26
27int jumped = 0;
28
Fabio Utzig92be3fb2017-12-05 08:52:53 -020029int ecdsa256_sign_(const uint8_t *privkey, const uint8_t *hash,
30 unsigned hash_len, uint8_t *signature)
31{
32#ifdef MCUBOOT_SIGN_EC256
33 return uECC_sign(privkey, hash, hash_len, signature, uECC_secp256r1());
34#else
35 (void)privkey;
36 (void)hash;
37 (void)hash_len;
38 (void)signature;
39 return 0;
40#endif
41}
42
David Brown5acda262017-01-23 15:42:19 -070043uint8_t sim_flash_align = 1;
44uint8_t flash_area_align(const struct flash_area *area)
45{
Fabio Utzigcd5774b2017-11-29 10:18:26 -020046 (void)area;
David Brown7ad80882017-06-20 15:30:36 -060047 return sim_flash_align;
David Brown5acda262017-01-23 15:42:19 -070048}
49
David Brownde7729e2017-01-09 10:41:35 -070050struct area {
David Brown7ad80882017-06-20 15:30:36 -060051 struct flash_area whole;
52 struct flash_area *areas;
53 uint32_t num_areas;
54 uint8_t id;
David Brownde7729e2017-01-09 10:41:35 -070055};
56
57struct area_desc {
David Brown7ad80882017-06-20 15:30:36 -060058 struct area slots[16];
59 uint32_t num_slots;
David Brownde7729e2017-01-09 10:41:35 -070060};
61
62static struct area_desc *flash_areas;
63
David Brown7e701d82017-07-11 13:24:25 -060064void *(*mbedtls_calloc)(size_t n, size_t size);
65void (*mbedtls_free)(void *ptr);
66
David Brownbdb6db72017-07-06 10:14:37 -060067int invoke_boot_go(struct area_desc *adesc)
David Brownde7729e2017-01-09 10:41:35 -070068{
David Brown7ad80882017-06-20 15:30:36 -060069 int res;
70 struct boot_rsp rsp;
David Brownde7729e2017-01-09 10:41:35 -070071
David Brown7e701d82017-07-11 13:24:25 -060072 mbedtls_calloc = calloc;
73 mbedtls_free = free;
74
David Brown7ad80882017-06-20 15:30:36 -060075 flash_areas = adesc;
76 if (setjmp(boot_jmpbuf) == 0) {
77 res = boot_go(&rsp);
David Brownbdb6db72017-07-06 10:14:37 -060078 flash_areas = NULL;
David Brown7ad80882017-06-20 15:30:36 -060079 /* printf("boot_go off: %d (0x%08x)\n", res, rsp.br_image_off); */
80 return res;
81 } else {
David Brownbdb6db72017-07-06 10:14:37 -060082 flash_areas = NULL;
David Brown7ad80882017-06-20 15:30:36 -060083 return -0x13579;
84 }
David Brownde7729e2017-01-09 10:41:35 -070085}
86
87int hal_flash_read(uint8_t flash_id, uint32_t address, void *dst,
David Brown7ad80882017-06-20 15:30:36 -060088 uint32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -070089{
Fabio Utzigcd5774b2017-11-29 10:18:26 -020090 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -060091 // printf("hal_flash_read: %d, 0x%08x (0x%x)\n",
92 // flash_id, address, num_bytes);
David Brownbdb6db72017-07-06 10:14:37 -060093 return sim_flash_read(address, dst, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -070094}
95
96int hal_flash_write(uint8_t flash_id, uint32_t address,
David Brown7ad80882017-06-20 15:30:36 -060097 const void *src, int32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -070098{
Fabio Utzigcd5774b2017-11-29 10:18:26 -020099 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -0600100 // printf("hal_flash_write: 0x%08x (0x%x)\n", address, num_bytes);
101 // fflush(stdout);
102 if (--flash_counter == 0) {
103 jumped++;
104 longjmp(boot_jmpbuf, 1);
105 }
David Brownbdb6db72017-07-06 10:14:37 -0600106 return sim_flash_write(address, src, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -0700107}
108
109int hal_flash_erase(uint8_t flash_id, uint32_t address,
David Brown7ad80882017-06-20 15:30:36 -0600110 uint32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -0700111{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200112 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -0600113 // printf("hal_flash_erase: 0x%08x, (0x%x)\n", address, num_bytes);
114 // fflush(stdout);
115 if (--flash_counter == 0) {
116 jumped++;
117 longjmp(boot_jmpbuf, 1);
118 }
David Brownbdb6db72017-07-06 10:14:37 -0600119 return sim_flash_erase(address, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -0700120}
121
122uint8_t hal_flash_align(uint8_t flash_id)
123{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200124 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -0600125 return sim_flash_align;
David Brownde7729e2017-01-09 10:41:35 -0700126}
127
128void *os_malloc(size_t size)
129{
David Brown7ad80882017-06-20 15:30:36 -0600130 // printf("os_malloc 0x%x bytes\n", size);
131 return malloc(size);
David Brownde7729e2017-01-09 10:41:35 -0700132}
133
134int flash_area_id_from_image_slot(int slot)
135{
David Brown7ad80882017-06-20 15:30:36 -0600136 return slot + 1;
David Brownde7729e2017-01-09 10:41:35 -0700137}
138
139int flash_area_open(uint8_t id, const struct flash_area **area)
140{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200141 uint32_t i;
David Brownde7729e2017-01-09 10:41:35 -0700142
David Brown7ad80882017-06-20 15:30:36 -0600143 for (i = 0; i < flash_areas->num_slots; i++) {
144 if (flash_areas->slots[i].id == id)
145 break;
146 }
147 if (i == flash_areas->num_slots) {
148 printf("Unsupported area\n");
149 abort();
150 }
David Brownde7729e2017-01-09 10:41:35 -0700151
David Brown7ad80882017-06-20 15:30:36 -0600152 /* Unsure if this is right, just returning the first area. */
153 *area = &flash_areas->slots[i].whole;
154 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700155}
156
157void flash_area_close(const struct flash_area *area)
158{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200159 (void)area;
David Brownde7729e2017-01-09 10:41:35 -0700160}
161
162/*
163 * Read/write/erase. Offset is relative from beginning of flash area.
164 */
165int flash_area_read(const struct flash_area *area, uint32_t off, void *dst,
David Brown7ad80882017-06-20 15:30:36 -0600166 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700167{
David Brown7ad80882017-06-20 15:30:36 -0600168 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x",
169 __func__, area->fa_id, off, len);
170 return hal_flash_read(area->fa_id,
171 area->fa_off + off,
172 dst, len);
David Brownde7729e2017-01-09 10:41:35 -0700173}
174
175int flash_area_write(const struct flash_area *area, uint32_t off, const void *src,
David Brown7ad80882017-06-20 15:30:36 -0600176 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700177{
David Brown7ad80882017-06-20 15:30:36 -0600178 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
179 area->fa_id, off, len);
180 return hal_flash_write(area->fa_id,
181 area->fa_off + off,
182 src, len);
David Brownde7729e2017-01-09 10:41:35 -0700183}
184
185int flash_area_erase(const struct flash_area *area, uint32_t off, uint32_t len)
186{
David Brown7ad80882017-06-20 15:30:36 -0600187 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
188 area->fa_id, off, len);
189 return hal_flash_erase(area->fa_id,
190 area->fa_off + off,
191 len);
David Brownde7729e2017-01-09 10:41:35 -0700192}
193
194int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret)
195{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200196 uint32_t i;
David Brown7ad80882017-06-20 15:30:36 -0600197 struct area *slot;
David Brownde7729e2017-01-09 10:41:35 -0700198
David Brown7ad80882017-06-20 15:30:36 -0600199 for (i = 0; i < flash_areas->num_slots; i++) {
200 if (flash_areas->slots[i].id == idx)
201 break;
202 }
203 if (i == flash_areas->num_slots) {
204 printf("Unsupported area\n");
205 abort();
206 }
David Brownde7729e2017-01-09 10:41:35 -0700207
David Brown7ad80882017-06-20 15:30:36 -0600208 slot = &flash_areas->slots[i];
David Brownde7729e2017-01-09 10:41:35 -0700209
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200210 if (slot->num_areas > (uint32_t)*cnt) {
David Brown7ad80882017-06-20 15:30:36 -0600211 printf("Too many areas in slot\n");
212 abort();
213 }
David Brownde7729e2017-01-09 10:41:35 -0700214
David Brown7ad80882017-06-20 15:30:36 -0600215 *cnt = slot->num_areas;
216 memcpy(ret, slot->areas, slot->num_areas * sizeof(struct flash_area));
David Brownde7729e2017-01-09 10:41:35 -0700217
David Brown7ad80882017-06-20 15:30:36 -0600218 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700219}
220
David Brown60399f62017-05-11 10:20:34 -0600221int flash_area_get_sectors(int fa_id, uint32_t *count,
222 struct flash_sector *sectors)
223{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200224 uint32_t i;
David Brown7ad80882017-06-20 15:30:36 -0600225 struct area *slot;
David Brown60399f62017-05-11 10:20:34 -0600226
David Brown7ad80882017-06-20 15:30:36 -0600227 for (i = 0; i < flash_areas->num_slots; i++) {
228 if (flash_areas->slots[i].id == fa_id)
229 break;
230 }
231 if (i == flash_areas->num_slots) {
232 printf("Unsupported area\n");
233 abort();
234 }
David Brown60399f62017-05-11 10:20:34 -0600235
David Brown7ad80882017-06-20 15:30:36 -0600236 slot = &flash_areas->slots[i];
David Brown60399f62017-05-11 10:20:34 -0600237
David Brown7ad80882017-06-20 15:30:36 -0600238 if (slot->num_areas > *count) {
239 printf("Too many areas in slot\n");
240 abort();
241 }
David Brown60399f62017-05-11 10:20:34 -0600242
David Brown7ad80882017-06-20 15:30:36 -0600243 for (i = 0; i < slot->num_areas; i++) {
244 sectors[i].fs_off = slot->areas[i].fa_off -
245 slot->whole.fa_off;
246 sectors[i].fs_size = slot->areas[i].fa_size;
247 }
248 *count = slot->num_areas;
David Brown60399f62017-05-11 10:20:34 -0600249
David Brown7ad80882017-06-20 15:30:36 -0600250 return 0;
David Brown60399f62017-05-11 10:20:34 -0600251}