blob: 7010988c824f805be86e7aa556554b6b0c0a79b8 [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
David Brown54b77792017-05-05 09:40:01 -060013#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_ERROR
David Brown75fd5dc2017-05-04 09:04:47 -060014#include <bootutil/bootutil_log.h>
15
David Brownbdb6db72017-07-06 10:14:37 -060016extern int sim_flash_erase(uint32_t offset, uint32_t size);
17extern int sim_flash_read(uint32_t offset, uint8_t *dest, uint32_t size);
18extern int sim_flash_write(uint32_t offset, const uint8_t *src, uint32_t size);
David Brownde7729e2017-01-09 10:41:35 -070019
David Brownde7729e2017-01-09 10:41:35 -070020static jmp_buf boot_jmpbuf;
21int flash_counter;
22
23int jumped = 0;
24
David Brown5acda262017-01-23 15:42:19 -070025uint8_t sim_flash_align = 1;
26uint8_t flash_area_align(const struct flash_area *area)
27{
Fabio Utzigcd5774b2017-11-29 10:18:26 -020028 (void)area;
David Brown7ad80882017-06-20 15:30:36 -060029 return sim_flash_align;
David Brown5acda262017-01-23 15:42:19 -070030}
31
David Brownde7729e2017-01-09 10:41:35 -070032struct area {
David Brown7ad80882017-06-20 15:30:36 -060033 struct flash_area whole;
34 struct flash_area *areas;
35 uint32_t num_areas;
36 uint8_t id;
David Brownde7729e2017-01-09 10:41:35 -070037};
38
39struct area_desc {
David Brown7ad80882017-06-20 15:30:36 -060040 struct area slots[16];
41 uint32_t num_slots;
David Brownde7729e2017-01-09 10:41:35 -070042};
43
44static struct area_desc *flash_areas;
45
David Brown7e701d82017-07-11 13:24:25 -060046void *(*mbedtls_calloc)(size_t n, size_t size);
47void (*mbedtls_free)(void *ptr);
48
David Brownbdb6db72017-07-06 10:14:37 -060049int invoke_boot_go(struct area_desc *adesc)
David Brownde7729e2017-01-09 10:41:35 -070050{
David Brown7ad80882017-06-20 15:30:36 -060051 int res;
52 struct boot_rsp rsp;
David Brownde7729e2017-01-09 10:41:35 -070053
David Brown7e701d82017-07-11 13:24:25 -060054 mbedtls_calloc = calloc;
55 mbedtls_free = free;
56
David Brown7ad80882017-06-20 15:30:36 -060057 flash_areas = adesc;
58 if (setjmp(boot_jmpbuf) == 0) {
59 res = boot_go(&rsp);
David Brownbdb6db72017-07-06 10:14:37 -060060 flash_areas = NULL;
David Brown7ad80882017-06-20 15:30:36 -060061 /* printf("boot_go off: %d (0x%08x)\n", res, rsp.br_image_off); */
62 return res;
63 } else {
David Brownbdb6db72017-07-06 10:14:37 -060064 flash_areas = NULL;
David Brown7ad80882017-06-20 15:30:36 -060065 return -0x13579;
66 }
David Brownde7729e2017-01-09 10:41:35 -070067}
68
69int hal_flash_read(uint8_t flash_id, uint32_t address, void *dst,
David Brown7ad80882017-06-20 15:30:36 -060070 uint32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -070071{
Fabio Utzigcd5774b2017-11-29 10:18:26 -020072 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -060073 // printf("hal_flash_read: %d, 0x%08x (0x%x)\n",
74 // flash_id, address, num_bytes);
David Brownbdb6db72017-07-06 10:14:37 -060075 return sim_flash_read(address, dst, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -070076}
77
78int hal_flash_write(uint8_t flash_id, uint32_t address,
David Brown7ad80882017-06-20 15:30:36 -060079 const void *src, int32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -070080{
Fabio Utzigcd5774b2017-11-29 10:18:26 -020081 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -060082 // printf("hal_flash_write: 0x%08x (0x%x)\n", address, num_bytes);
83 // fflush(stdout);
84 if (--flash_counter == 0) {
85 jumped++;
86 longjmp(boot_jmpbuf, 1);
87 }
David Brownbdb6db72017-07-06 10:14:37 -060088 return sim_flash_write(address, src, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -070089}
90
91int hal_flash_erase(uint8_t flash_id, uint32_t address,
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_erase: 0x%08x, (0x%x)\n", address, num_bytes);
96 // fflush(stdout);
97 if (--flash_counter == 0) {
98 jumped++;
99 longjmp(boot_jmpbuf, 1);
100 }
David Brownbdb6db72017-07-06 10:14:37 -0600101 return sim_flash_erase(address, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -0700102}
103
104uint8_t hal_flash_align(uint8_t flash_id)
105{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200106 (void)flash_id;
David Brown7ad80882017-06-20 15:30:36 -0600107 return sim_flash_align;
David Brownde7729e2017-01-09 10:41:35 -0700108}
109
110void *os_malloc(size_t size)
111{
David Brown7ad80882017-06-20 15:30:36 -0600112 // printf("os_malloc 0x%x bytes\n", size);
113 return malloc(size);
David Brownde7729e2017-01-09 10:41:35 -0700114}
115
116int flash_area_id_from_image_slot(int slot)
117{
David Brown7ad80882017-06-20 15:30:36 -0600118 return slot + 1;
David Brownde7729e2017-01-09 10:41:35 -0700119}
120
121int flash_area_open(uint8_t id, const struct flash_area **area)
122{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200123 uint32_t i;
David Brownde7729e2017-01-09 10:41:35 -0700124
David Brown7ad80882017-06-20 15:30:36 -0600125 for (i = 0; i < flash_areas->num_slots; i++) {
126 if (flash_areas->slots[i].id == id)
127 break;
128 }
129 if (i == flash_areas->num_slots) {
130 printf("Unsupported area\n");
131 abort();
132 }
David Brownde7729e2017-01-09 10:41:35 -0700133
David Brown7ad80882017-06-20 15:30:36 -0600134 /* Unsure if this is right, just returning the first area. */
135 *area = &flash_areas->slots[i].whole;
136 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700137}
138
139void flash_area_close(const struct flash_area *area)
140{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200141 (void)area;
David Brownde7729e2017-01-09 10:41:35 -0700142}
143
144/*
145 * Read/write/erase. Offset is relative from beginning of flash area.
146 */
147int flash_area_read(const struct flash_area *area, uint32_t off, void *dst,
David Brown7ad80882017-06-20 15:30:36 -0600148 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700149{
David Brown7ad80882017-06-20 15:30:36 -0600150 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x",
151 __func__, area->fa_id, off, len);
152 return hal_flash_read(area->fa_id,
153 area->fa_off + off,
154 dst, len);
David Brownde7729e2017-01-09 10:41:35 -0700155}
156
157int flash_area_write(const struct flash_area *area, uint32_t off, const void *src,
David Brown7ad80882017-06-20 15:30:36 -0600158 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700159{
David Brown7ad80882017-06-20 15:30:36 -0600160 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
161 area->fa_id, off, len);
162 return hal_flash_write(area->fa_id,
163 area->fa_off + off,
164 src, len);
David Brownde7729e2017-01-09 10:41:35 -0700165}
166
167int flash_area_erase(const struct flash_area *area, uint32_t off, uint32_t len)
168{
David Brown7ad80882017-06-20 15:30:36 -0600169 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
170 area->fa_id, off, len);
171 return hal_flash_erase(area->fa_id,
172 area->fa_off + off,
173 len);
David Brownde7729e2017-01-09 10:41:35 -0700174}
175
176int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret)
177{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200178 uint32_t i;
David Brown7ad80882017-06-20 15:30:36 -0600179 struct area *slot;
David Brownde7729e2017-01-09 10:41:35 -0700180
David Brown7ad80882017-06-20 15:30:36 -0600181 for (i = 0; i < flash_areas->num_slots; i++) {
182 if (flash_areas->slots[i].id == idx)
183 break;
184 }
185 if (i == flash_areas->num_slots) {
186 printf("Unsupported area\n");
187 abort();
188 }
David Brownde7729e2017-01-09 10:41:35 -0700189
David Brown7ad80882017-06-20 15:30:36 -0600190 slot = &flash_areas->slots[i];
David Brownde7729e2017-01-09 10:41:35 -0700191
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200192 if (slot->num_areas > (uint32_t)*cnt) {
David Brown7ad80882017-06-20 15:30:36 -0600193 printf("Too many areas in slot\n");
194 abort();
195 }
David Brownde7729e2017-01-09 10:41:35 -0700196
David Brown7ad80882017-06-20 15:30:36 -0600197 *cnt = slot->num_areas;
198 memcpy(ret, slot->areas, slot->num_areas * sizeof(struct flash_area));
David Brownde7729e2017-01-09 10:41:35 -0700199
David Brown7ad80882017-06-20 15:30:36 -0600200 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700201}
202
David Brown60399f62017-05-11 10:20:34 -0600203int flash_area_get_sectors(int fa_id, uint32_t *count,
204 struct flash_sector *sectors)
205{
Fabio Utzigcd5774b2017-11-29 10:18:26 -0200206 uint32_t i;
David Brown7ad80882017-06-20 15:30:36 -0600207 struct area *slot;
David Brown60399f62017-05-11 10:20:34 -0600208
David Brown7ad80882017-06-20 15:30:36 -0600209 for (i = 0; i < flash_areas->num_slots; i++) {
210 if (flash_areas->slots[i].id == fa_id)
211 break;
212 }
213 if (i == flash_areas->num_slots) {
214 printf("Unsupported area\n");
215 abort();
216 }
David Brown60399f62017-05-11 10:20:34 -0600217
David Brown7ad80882017-06-20 15:30:36 -0600218 slot = &flash_areas->slots[i];
David Brown60399f62017-05-11 10:20:34 -0600219
David Brown7ad80882017-06-20 15:30:36 -0600220 if (slot->num_areas > *count) {
221 printf("Too many areas in slot\n");
222 abort();
223 }
David Brown60399f62017-05-11 10:20:34 -0600224
David Brown7ad80882017-06-20 15:30:36 -0600225 for (i = 0; i < slot->num_areas; i++) {
226 sectors[i].fs_off = slot->areas[i].fa_off -
227 slot->whole.fa_off;
228 sectors[i].fs_size = slot->areas[i].fa_size;
229 }
230 *count = slot->num_areas;
David Brown60399f62017-05-11 10:20:34 -0600231
David Brown7ad80882017-06-20 15:30:36 -0600232 return 0;
David Brown60399f62017-05-11 10:20:34 -0600233}