blob: 467b21a4c89c58dd32a8b43acda641e4885899ac [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
11#include "../../boot/bootutil/src/bootutil_priv.h"
12
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 Brownde7729e2017-01-09 10:41:35 -070016extern int sim_flash_erase(void *flash, uint32_t offset, uint32_t size);
17extern int sim_flash_read(void *flash, uint32_t offset, uint8_t *dest, uint32_t size);
18extern int sim_flash_write(void *flash, uint32_t offset, const uint8_t *src, uint32_t size);
19
20static void *flash_device;
21static jmp_buf boot_jmpbuf;
22int flash_counter;
23
24int jumped = 0;
25
David Brown5acda262017-01-23 15:42:19 -070026uint8_t sim_flash_align = 1;
27uint8_t flash_area_align(const struct flash_area *area)
28{
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
46int invoke_boot_go(void *flash, struct area_desc *adesc)
47{
David Brown7ad80882017-06-20 15:30:36 -060048 int res;
49 struct boot_rsp rsp;
David Brownde7729e2017-01-09 10:41:35 -070050
David Brown7ad80882017-06-20 15:30:36 -060051 flash_device = flash;
52 flash_areas = adesc;
53 if (setjmp(boot_jmpbuf) == 0) {
54 res = boot_go(&rsp);
55 /* printf("boot_go off: %d (0x%08x)\n", res, rsp.br_image_off); */
56 return res;
57 } else {
58 return -0x13579;
59 }
David Brownde7729e2017-01-09 10:41:35 -070060}
61
62int hal_flash_read(uint8_t flash_id, uint32_t address, void *dst,
David Brown7ad80882017-06-20 15:30:36 -060063 uint32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -070064{
David Brown7ad80882017-06-20 15:30:36 -060065 // printf("hal_flash_read: %d, 0x%08x (0x%x)\n",
66 // flash_id, address, num_bytes);
67 return sim_flash_read(flash_device, address, dst, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -070068}
69
70int hal_flash_write(uint8_t flash_id, uint32_t address,
David Brown7ad80882017-06-20 15:30:36 -060071 const void *src, int32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -070072{
David Brown7ad80882017-06-20 15:30:36 -060073 // printf("hal_flash_write: 0x%08x (0x%x)\n", address, num_bytes);
74 // fflush(stdout);
75 if (--flash_counter == 0) {
76 jumped++;
77 longjmp(boot_jmpbuf, 1);
78 }
79 return sim_flash_write(flash_device, address, src, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -070080}
81
82int hal_flash_erase(uint8_t flash_id, uint32_t address,
David Brown7ad80882017-06-20 15:30:36 -060083 uint32_t num_bytes)
David Brownde7729e2017-01-09 10:41:35 -070084{
David Brown7ad80882017-06-20 15:30:36 -060085 // printf("hal_flash_erase: 0x%08x, (0x%x)\n", address, num_bytes);
86 // fflush(stdout);
87 if (--flash_counter == 0) {
88 jumped++;
89 longjmp(boot_jmpbuf, 1);
90 }
91 return sim_flash_erase(flash_device, address, num_bytes);
David Brownde7729e2017-01-09 10:41:35 -070092}
93
94uint8_t hal_flash_align(uint8_t flash_id)
95{
David Brown7ad80882017-06-20 15:30:36 -060096 return sim_flash_align;
David Brownde7729e2017-01-09 10:41:35 -070097}
98
99void *os_malloc(size_t size)
100{
David Brown7ad80882017-06-20 15:30:36 -0600101 // printf("os_malloc 0x%x bytes\n", size);
102 return malloc(size);
David Brownde7729e2017-01-09 10:41:35 -0700103}
104
105int flash_area_id_from_image_slot(int slot)
106{
David Brown7ad80882017-06-20 15:30:36 -0600107 return slot + 1;
David Brownde7729e2017-01-09 10:41:35 -0700108}
109
110int flash_area_open(uint8_t id, const struct flash_area **area)
111{
David Brown7ad80882017-06-20 15:30:36 -0600112 int i;
David Brownde7729e2017-01-09 10:41:35 -0700113
David Brown7ad80882017-06-20 15:30:36 -0600114 for (i = 0; i < flash_areas->num_slots; i++) {
115 if (flash_areas->slots[i].id == id)
116 break;
117 }
118 if (i == flash_areas->num_slots) {
119 printf("Unsupported area\n");
120 abort();
121 }
David Brownde7729e2017-01-09 10:41:35 -0700122
David Brown7ad80882017-06-20 15:30:36 -0600123 /* Unsure if this is right, just returning the first area. */
124 *area = &flash_areas->slots[i].whole;
125 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700126}
127
128void flash_area_close(const struct flash_area *area)
129{
130}
131
132/*
133 * Read/write/erase. Offset is relative from beginning of flash area.
134 */
135int flash_area_read(const struct flash_area *area, uint32_t off, void *dst,
David Brown7ad80882017-06-20 15:30:36 -0600136 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700137{
David Brown7ad80882017-06-20 15:30:36 -0600138 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x",
139 __func__, area->fa_id, off, len);
140 return hal_flash_read(area->fa_id,
141 area->fa_off + off,
142 dst, len);
David Brownde7729e2017-01-09 10:41:35 -0700143}
144
145int flash_area_write(const struct flash_area *area, uint32_t off, const void *src,
David Brown7ad80882017-06-20 15:30:36 -0600146 uint32_t len)
David Brownde7729e2017-01-09 10:41:35 -0700147{
David Brown7ad80882017-06-20 15:30:36 -0600148 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
149 area->fa_id, off, len);
150 return hal_flash_write(area->fa_id,
151 area->fa_off + off,
152 src, len);
David Brownde7729e2017-01-09 10:41:35 -0700153}
154
155int flash_area_erase(const struct flash_area *area, uint32_t off, uint32_t len)
156{
David Brown7ad80882017-06-20 15:30:36 -0600157 BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
158 area->fa_id, off, len);
159 return hal_flash_erase(area->fa_id,
160 area->fa_off + off,
161 len);
David Brownde7729e2017-01-09 10:41:35 -0700162}
163
164int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret)
165{
David Brown7ad80882017-06-20 15:30:36 -0600166 int i;
167 struct area *slot;
David Brownde7729e2017-01-09 10:41:35 -0700168
David Brown7ad80882017-06-20 15:30:36 -0600169 for (i = 0; i < flash_areas->num_slots; i++) {
170 if (flash_areas->slots[i].id == idx)
171 break;
172 }
173 if (i == flash_areas->num_slots) {
174 printf("Unsupported area\n");
175 abort();
176 }
David Brownde7729e2017-01-09 10:41:35 -0700177
David Brown7ad80882017-06-20 15:30:36 -0600178 slot = &flash_areas->slots[i];
David Brownde7729e2017-01-09 10:41:35 -0700179
David Brown7ad80882017-06-20 15:30:36 -0600180 if (slot->num_areas > *cnt) {
181 printf("Too many areas in slot\n");
182 abort();
183 }
David Brownde7729e2017-01-09 10:41:35 -0700184
David Brown7ad80882017-06-20 15:30:36 -0600185 *cnt = slot->num_areas;
186 memcpy(ret, slot->areas, slot->num_areas * sizeof(struct flash_area));
David Brownde7729e2017-01-09 10:41:35 -0700187
David Brown7ad80882017-06-20 15:30:36 -0600188 return 0;
David Brownde7729e2017-01-09 10:41:35 -0700189}
190
David Brown60399f62017-05-11 10:20:34 -0600191int flash_area_get_sectors(int fa_id, uint32_t *count,
192 struct flash_sector *sectors)
193{
David Brown7ad80882017-06-20 15:30:36 -0600194 int i;
195 struct area *slot;
David Brown60399f62017-05-11 10:20:34 -0600196
David Brown7ad80882017-06-20 15:30:36 -0600197 for (i = 0; i < flash_areas->num_slots; i++) {
198 if (flash_areas->slots[i].id == fa_id)
199 break;
200 }
201 if (i == flash_areas->num_slots) {
202 printf("Unsupported area\n");
203 abort();
204 }
David Brown60399f62017-05-11 10:20:34 -0600205
David Brown7ad80882017-06-20 15:30:36 -0600206 slot = &flash_areas->slots[i];
David Brown60399f62017-05-11 10:20:34 -0600207
David Brown7ad80882017-06-20 15:30:36 -0600208 if (slot->num_areas > *count) {
209 printf("Too many areas in slot\n");
210 abort();
211 }
David Brown60399f62017-05-11 10:20:34 -0600212
David Brown7ad80882017-06-20 15:30:36 -0600213 for (i = 0; i < slot->num_areas; i++) {
214 sectors[i].fs_off = slot->areas[i].fa_off -
215 slot->whole.fa_off;
216 sectors[i].fs_size = slot->areas[i].fa_size;
217 }
218 *count = slot->num_areas;
David Brown60399f62017-05-11 10:20:34 -0600219
David Brown7ad80882017-06-20 15:30:36 -0600220 return 0;
David Brown60399f62017-05-11 10:20:34 -0600221}
David Brownde7729e2017-01-09 10:41:35 -0700222
223int bootutil_img_validate(struct image_header *hdr,
224 const struct flash_area *fap,
225 uint8_t *tmp_buf, uint32_t tmp_buf_sz,
226 uint8_t *seed, int seed_len, uint8_t *out_hash)
227{
David Brown7ad80882017-06-20 15:30:36 -0600228 if (hal_flash_read(fap->fa_id, fap->fa_off, tmp_buf, 4)) {
229 printf("Flash read error\n");
230 abort();
231 }
David Brownde7729e2017-01-09 10:41:35 -0700232
David Brown7ad80882017-06-20 15:30:36 -0600233 return (*((uint32_t *) tmp_buf) != 0x96f3b83c);
David Brownde7729e2017-01-09 10:41:35 -0700234}