blob: 261f24a0328cf294fbd70f11fbd4f4fd7507b9e0 [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{
David Brown7ad80882017-06-20 15:30:36 -060028 return sim_flash_align;
David Brown5acda262017-01-23 15:42:19 -070029}
30
David Brownde7729e2017-01-09 10:41:35 -070031struct area {
David Brown7ad80882017-06-20 15:30:36 -060032 struct flash_area whole;
33 struct flash_area *areas;
34 uint32_t num_areas;
35 uint8_t id;
David Brownde7729e2017-01-09 10:41:35 -070036};
37
38struct area_desc {
David Brown7ad80882017-06-20 15:30:36 -060039 struct area slots[16];
40 uint32_t num_slots;
David Brownde7729e2017-01-09 10:41:35 -070041};
42
43static struct area_desc *flash_areas;
44
David Brown7e701d82017-07-11 13:24:25 -060045void *(*mbedtls_calloc)(size_t n, size_t size);
46void (*mbedtls_free)(void *ptr);
47
David Brownbdb6db72017-07-06 10:14:37 -060048int invoke_boot_go(struct area_desc *adesc)
David Brownde7729e2017-01-09 10:41:35 -070049{
David Brown7ad80882017-06-20 15:30:36 -060050 int res;
51 struct boot_rsp rsp;
David Brownde7729e2017-01-09 10:41:35 -070052
David Brown7e701d82017-07-11 13:24:25 -060053 mbedtls_calloc = calloc;
54 mbedtls_free = free;
55
David Brown7ad80882017-06-20 15:30:36 -060056 flash_areas = adesc;
57 if (setjmp(boot_jmpbuf) == 0) {
58 res = boot_go(&rsp);
David Brownbdb6db72017-07-06 10:14:37 -060059 flash_areas = NULL;
David Brown7ad80882017-06-20 15:30:36 -060060 /* printf("boot_go off: %d (0x%08x)\n", res, rsp.br_image_off); */
61 return res;
62 } else {
David Brownbdb6db72017-07-06 10:14:37 -060063 flash_areas = NULL;
David Brown7ad80882017-06-20 15:30:36 -060064 return -0x13579;
65 }
David Brownde7729e2017-01-09 10:41:35 -070066}
67
68int hal_flash_read(uint8_t flash_id, uint32_t address, void *dst,
David Brown7ad80882017-06-20 15:30:36 -060069 uint32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -070070{
David Brown7ad80882017-06-20 15:30:36 -060071 // printf("hal_flash_read: %d, 0x%08x (0x%x)\n",
72 // flash_id, address, num_bytes);
David Brownbdb6db72017-07-06 10:14:37 -060073 return sim_flash_read(address, dst, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -070074}
75
76int hal_flash_write(uint8_t flash_id, uint32_t address,
David Brown7ad80882017-06-20 15:30:36 -060077 const void *src, int32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -070078{
David Brown7ad80882017-06-20 15:30:36 -060079 // printf("hal_flash_write: 0x%08x (0x%x)\n", address, num_bytes);
80 // fflush(stdout);
81 if (--flash_counter == 0) {
82 jumped++;
83 longjmp(boot_jmpbuf, 1);
84 }
David Brownbdb6db72017-07-06 10:14:37 -060085 return sim_flash_write(address, src, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -070086}
87
88int hal_flash_erase(uint8_t flash_id, uint32_t address,
David Brown7ad80882017-06-20 15:30:36 -060089 uint32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -070090{
David Brown7ad80882017-06-20 15:30:36 -060091 // printf("hal_flash_erase: 0x%08x, (0x%x)\n", address, num_bytes);
92 // fflush(stdout);
93 if (--flash_counter == 0) {
94 jumped++;
95 longjmp(boot_jmpbuf, 1);
96 }
David Brownbdb6db72017-07-06 10:14:37 -060097 return sim_flash_erase(address, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -070098}
99
100uint8_t hal_flash_align(uint8_t flash_id)
101{
David Brown7ad80882017-06-20 15:30:36 -0600102 return sim_flash_align;
David Brownde7729e2017-01-09 10:41:35 -0700103}
104
105void *os_malloc(size_t size)
106{
David Brown7ad80882017-06-20 15:30:36 -0600107 // printf("os_malloc 0x%x bytes\n", size);
108 return malloc(size);
David Brownde7729e2017-01-09 10:41:35 -0700109}
110
111int flash_area_id_from_image_slot(int slot)
112{
David Brown7ad80882017-06-20 15:30:36 -0600113 return slot + 1;
David Brownde7729e2017-01-09 10:41:35 -0700114}
115
116int flash_area_open(uint8_t id, const struct flash_area **area)
117{
David Brown7ad80882017-06-20 15:30:36 -0600118 int i;
David Brownde7729e2017-01-09 10:41:35 -0700119
David Brown7ad80882017-06-20 15:30:36 -0600120 for (i = 0; i < flash_areas->num_slots; i++) {
121 if (flash_areas->slots[i].id == id)
122 break;
123 }
124 if (i == flash_areas->num_slots) {
125 printf("Unsupported area\n");
126 abort();
127 }
David Brownde7729e2017-01-09 10:41:35 -0700128
David Brown7ad80882017-06-20 15:30:36 -0600129 /* Unsure if this is right, just returning the first area. */
130 *area = &flash_areas->slots[i].whole;
131 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700132}
133
134void flash_area_close(const struct flash_area *area)
135{
136}
137
138/*
139 * Read/write/erase. Offset is relative from beginning of flash area.
140 */
141int flash_area_read(const struct flash_area *area, uint32_t off, void *dst,
David Brown7ad80882017-06-20 15:30:36 -0600142 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700143{
David Brown7ad80882017-06-20 15:30:36 -0600144 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x",
145 __func__, area->fa_id, off, len);
146 return hal_flash_read(area->fa_id,
147 area->fa_off + off,
148 dst, len);
David Brownde7729e2017-01-09 10:41:35 -0700149}
150
151int flash_area_write(const struct flash_area *area, uint32_t off, const void *src,
David Brown7ad80882017-06-20 15:30:36 -0600152 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700153{
David Brown7ad80882017-06-20 15:30:36 -0600154 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
155 area->fa_id, off, len);
156 return hal_flash_write(area->fa_id,
157 area->fa_off + off,
158 src, len);
David Brownde7729e2017-01-09 10:41:35 -0700159}
160
161int flash_area_erase(const struct flash_area *area, uint32_t off, uint32_t len)
162{
David Brown7ad80882017-06-20 15:30:36 -0600163 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
164 area->fa_id, off, len);
165 return hal_flash_erase(area->fa_id,
166 area->fa_off + off,
167 len);
David Brownde7729e2017-01-09 10:41:35 -0700168}
169
170int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret)
171{
David Brown7ad80882017-06-20 15:30:36 -0600172 int i;
173 struct area *slot;
David Brownde7729e2017-01-09 10:41:35 -0700174
David Brown7ad80882017-06-20 15:30:36 -0600175 for (i = 0; i < flash_areas->num_slots; i++) {
176 if (flash_areas->slots[i].id == idx)
177 break;
178 }
179 if (i == flash_areas->num_slots) {
180 printf("Unsupported area\n");
181 abort();
182 }
David Brownde7729e2017-01-09 10:41:35 -0700183
David Brown7ad80882017-06-20 15:30:36 -0600184 slot = &flash_areas->slots[i];
David Brownde7729e2017-01-09 10:41:35 -0700185
David Brown7ad80882017-06-20 15:30:36 -0600186 if (slot->num_areas > *cnt) {
187 printf("Too many areas in slot\n");
188 abort();
189 }
David Brownde7729e2017-01-09 10:41:35 -0700190
David Brown7ad80882017-06-20 15:30:36 -0600191 *cnt = slot->num_areas;
192 memcpy(ret, slot->areas, slot->num_areas * sizeof(struct flash_area));
David Brownde7729e2017-01-09 10:41:35 -0700193
David Brown7ad80882017-06-20 15:30:36 -0600194 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700195}
196
David Brown60399f62017-05-11 10:20:34 -0600197int flash_area_get_sectors(int fa_id, uint32_t *count,
198 struct flash_sector *sectors)
199{
David Brown7ad80882017-06-20 15:30:36 -0600200 int i;
201 struct area *slot;
David Brown60399f62017-05-11 10:20:34 -0600202
David Brown7ad80882017-06-20 15:30:36 -0600203 for (i = 0; i < flash_areas->num_slots; i++) {
204 if (flash_areas->slots[i].id == fa_id)
205 break;
206 }
207 if (i == flash_areas->num_slots) {
208 printf("Unsupported area\n");
209 abort();
210 }
David Brown60399f62017-05-11 10:20:34 -0600211
David Brown7ad80882017-06-20 15:30:36 -0600212 slot = &flash_areas->slots[i];
David Brown60399f62017-05-11 10:20:34 -0600213
David Brown7ad80882017-06-20 15:30:36 -0600214 if (slot->num_areas > *count) {
215 printf("Too many areas in slot\n");
216 abort();
217 }
David Brown60399f62017-05-11 10:20:34 -0600218
David Brown7ad80882017-06-20 15:30:36 -0600219 for (i = 0; i < slot->num_areas; i++) {
220 sectors[i].fs_off = slot->areas[i].fa_off -
221 slot->whole.fa_off;
222 sectors[i].fs_size = slot->areas[i].fa_size;
223 }
224 *count = slot->num_areas;
David Brown60399f62017-05-11 10:20:34 -0600225
David Brown7ad80882017-06-20 15:30:36 -0600226 return 0;
David Brown60399f62017-05-11 10:20:34 -0600227}