blob: d88210196cef9fb0be33fd90a2d31e7d48719d5e [file] [log] [blame]
Christopher Collins92ea77f2016-12-12 15:59:26 -08001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#include "boot_test.h"
21
22/** Internal flash layout. */
23struct flash_area boot_test_area_descs[] = {
24 [0] = { .fa_off = 0x00020000, .fa_size = 128 * 1024 },
25 [1] = { .fa_off = 0x00040000, .fa_size = 128 * 1024 },
26 [2] = { .fa_off = 0x00060000, .fa_size = 128 * 1024 },
27 [3] = { .fa_off = 0x00080000, .fa_size = 128 * 1024 },
28 [4] = { .fa_off = 0x000a0000, .fa_size = 128 * 1024 },
29 [5] = { .fa_off = 0x000c0000, .fa_size = 128 * 1024 },
30 [6] = { .fa_off = 0x000e0000, .fa_size = 128 * 1024 },
31 [7] = { 0 },
32};
33
34/** Areas representing the beginning of image slots. */
35uint8_t boot_test_slot_areas[] = {
36 0, 3,
37};
38
39/** Flash offsets of the two image slots. */
40struct boot_test_img_addrs boot_test_img_addrs[] = {
41 { 0, 0x20000 },
42 { 0, 0x80000 },
43};
44
45#define BOOT_TEST_AREA_IDX_SCRATCH 6
46
47uint8_t
48boot_test_util_byte_at(int img_msb, uint32_t image_offset)
49{
50 uint32_t u32;
51 uint8_t *u8p;
52
53 TEST_ASSERT(image_offset < 0x01000000);
54 u32 = image_offset + (img_msb << 24);
55 u8p = (void *)&u32;
56 return u8p[image_offset % 4];
57}
58
59
60void
61boot_test_util_init_flash(void)
62{
63 const struct flash_area *area_desc;
64 int rc;
65
66 rc = hal_flash_init();
67 TEST_ASSERT(rc == 0);
68
69 for (area_desc = boot_test_area_descs;
70 area_desc->fa_size != 0;
71 area_desc++) {
72
73 rc = flash_area_erase(area_desc, 0, area_desc->fa_size);
74 TEST_ASSERT(rc == 0);
75 }
76}
77
78void
79boot_test_util_copy_area(int from_area_idx, int to_area_idx)
80{
81 const struct flash_area *from_area_desc;
82 const struct flash_area *to_area_desc;
83 void *buf;
84 int rc;
85
86 from_area_desc = boot_test_area_descs + from_area_idx;
87 to_area_desc = boot_test_area_descs + to_area_idx;
88
89 TEST_ASSERT(from_area_desc->fa_size == to_area_desc->fa_size);
90
91 buf = malloc(from_area_desc->fa_size);
92 TEST_ASSERT(buf != NULL);
93
94 rc = flash_area_read(from_area_desc, 0, buf,
95 from_area_desc->fa_size);
96 TEST_ASSERT(rc == 0);
97
98 rc = flash_area_erase(to_area_desc,
99 0,
100 to_area_desc->fa_size);
101 TEST_ASSERT(rc == 0);
102
103 rc = flash_area_write(to_area_desc, 0, buf,
104 to_area_desc->fa_size);
105 TEST_ASSERT(rc == 0);
106
107 free(buf);
108}
109
110static uint32_t
111boot_test_util_area_write_size(int dst_idx, uint32_t off, uint32_t size)
112{
113 const struct flash_area *desc;
114 int64_t diff;
115 uint32_t trailer_start;
116
117 if (dst_idx != BOOT_TEST_AREA_IDX_SCRATCH - 1) {
118 return size;
119 }
120
121 /* Don't include trailer in copy to second slot. */
122 desc = boot_test_area_descs + dst_idx;
123 trailer_start = desc->fa_size - boot_trailer_sz(1);
124 diff = off + size - trailer_start;
125 if (diff > 0) {
126 if (diff > size) {
127 size = 0;
128 } else {
129 size -= diff;
130 }
131 }
132
133 return size;
134}
135
136void
137boot_test_util_swap_areas(int area_idx1, int area_idx2)
138{
139 const struct flash_area *area_desc1;
140 const struct flash_area *area_desc2;
141 uint32_t size;
142 void *buf1;
143 void *buf2;
144 int rc;
145
146 area_desc1 = boot_test_area_descs + area_idx1;
147 area_desc2 = boot_test_area_descs + area_idx2;
148
149 TEST_ASSERT(area_desc1->fa_size == area_desc2->fa_size);
150
151 buf1 = malloc(area_desc1->fa_size);
152 TEST_ASSERT(buf1 != NULL);
153
154 buf2 = malloc(area_desc2->fa_size);
155 TEST_ASSERT(buf2 != NULL);
156
157 rc = flash_area_read(area_desc1, 0, buf1, area_desc1->fa_size);
158 TEST_ASSERT(rc == 0);
159
160 rc = flash_area_read(area_desc2, 0, buf2, area_desc2->fa_size);
161 TEST_ASSERT(rc == 0);
162
163 rc = flash_area_erase(area_desc1, 0, area_desc1->fa_size);
164 TEST_ASSERT(rc == 0);
165
166 rc = flash_area_erase(area_desc2, 0, area_desc2->fa_size);
167 TEST_ASSERT(rc == 0);
168
169 size = boot_test_util_area_write_size(area_idx1, 0, area_desc1->fa_size);
170 rc = flash_area_write(area_desc1, 0, buf2, size);
171 TEST_ASSERT(rc == 0);
172
173 size = boot_test_util_area_write_size(area_idx2, 0, area_desc2->fa_size);
174 rc = flash_area_write(area_desc2, 0, buf1, size);
175 TEST_ASSERT(rc == 0);
176
177 free(buf1);
178 free(buf2);
179}
180
181void
182boot_test_util_write_image(const struct image_header *hdr, int slot)
183{
184 uint32_t image_off;
185 uint32_t off;
186 uint8_t flash_id;
187 uint8_t buf[256];
188 int chunk_sz;
189 int rc;
190 int i;
191
192 TEST_ASSERT(slot == 0 || slot == 1);
193
194 flash_id = boot_test_img_addrs[slot].flash_id;
195 off = boot_test_img_addrs[slot].address;
196
197 rc = hal_flash_write(flash_id, off, hdr, sizeof *hdr);
198 TEST_ASSERT(rc == 0);
199
200 off += hdr->ih_hdr_size;
201
202 image_off = 0;
203 while (image_off < hdr->ih_img_size) {
204 if (hdr->ih_img_size - image_off > sizeof buf) {
205 chunk_sz = sizeof buf;
206 } else {
207 chunk_sz = hdr->ih_img_size - image_off;
208 }
209
210 for (i = 0; i < chunk_sz; i++) {
211 buf[i] = boot_test_util_byte_at(slot, image_off + i);
212 }
213
214 rc = hal_flash_write(flash_id, off + image_off, buf, chunk_sz);
215 TEST_ASSERT(rc == 0);
216
217 image_off += chunk_sz;
218 }
219}
220
221
222void
223boot_test_util_write_hash(const struct image_header *hdr, int slot)
224{
225 uint8_t tmpdata[1024];
226 uint8_t hash[32];
227 int rc;
228 uint32_t off;
229 uint32_t blk_sz;
230 uint32_t sz;
231 mbedtls_sha256_context ctx;
232 uint8_t flash_id;
233 uint32_t addr;
234 struct image_tlv tlv;
235
236 mbedtls_sha256_init(&ctx);
237 mbedtls_sha256_starts(&ctx, 0);
238
239 flash_id = boot_test_img_addrs[slot].flash_id;
240 addr = boot_test_img_addrs[slot].address;
241
242 sz = hdr->ih_hdr_size + hdr->ih_img_size;
243 for (off = 0; off < sz; off += blk_sz) {
244 blk_sz = sz - off;
245 if (blk_sz > sizeof(tmpdata)) {
246 blk_sz = sizeof(tmpdata);
247 }
248 rc = hal_flash_read(flash_id, addr + off, tmpdata, blk_sz);
249 TEST_ASSERT(rc == 0);
250 mbedtls_sha256_update(&ctx, tmpdata, blk_sz);
251 }
252 mbedtls_sha256_finish(&ctx, hash);
253
254 tlv.it_type = IMAGE_TLV_SHA256;
255 tlv._pad = 0;
256 tlv.it_len = sizeof(hash);
257
258 rc = hal_flash_write(flash_id, addr + off, &tlv, sizeof(tlv));
259 TEST_ASSERT(rc == 0);
260 off += sizeof(tlv);
261 rc = hal_flash_write(flash_id, addr + off, hash, sizeof(hash));
262 TEST_ASSERT(rc == 0);
263}
264
265static void
266boot_test_util_write_swap_state(int flash_area_id,
267 const struct boot_swap_state *state)
268{
269 const struct flash_area *fap;
270 int rc;
271
272 rc = flash_area_open(flash_area_id, &fap);
273 TEST_ASSERT_FATAL(rc == 0);
274
275 switch (state->magic) {
276 case 0:
277 break;
278
279 case BOOT_MAGIC_GOOD:
280 rc = boot_write_magic(fap);
281 TEST_ASSERT_FATAL(rc == 0);
282 break;
283
284 default:
285 TEST_ASSERT_FATAL(0);
286 break;
287 }
288
289 if (state->copy_done != 0xff) {
290 rc = boot_write_copy_done(fap);
291 TEST_ASSERT_FATAL(rc == 0);
292 }
293
294 if (state->image_ok != 0xff) {
295 rc = boot_write_image_ok(fap);
296 TEST_ASSERT_FATAL(rc == 0);
297 }
298}
299
300void
301boot_test_util_mark_revert(void)
302{
303 struct boot_swap_state state_slot0 = {
304 .magic = BOOT_MAGIC_GOOD,
305 .copy_done = 0x01,
306 .image_ok = 0xff,
307 };
308
309 boot_test_util_write_swap_state(FLASH_AREA_IMAGE_0, &state_slot0);
310}
311
312void
313boot_test_util_verify_area(const struct flash_area *area_desc,
314 const struct image_header *hdr,
315 uint32_t image_addr, int img_msb)
316{
317 struct image_header temp_hdr;
318 uint32_t area_end;
319 uint32_t img_size;
320 uint32_t img_off;
321 uint32_t img_end;
322 uint32_t addr;
323 uint8_t buf[256];
324 int rem_area;
325 int past_image;
326 int chunk_sz;
327 int rem_img;
328 int rc;
329 int i;
330
331 addr = area_desc->fa_off;
332
333 if (hdr != NULL) {
334 img_size = hdr->ih_img_size;
335
336 if (addr == image_addr) {
337 rc = hal_flash_read(area_desc->fa_device_id, image_addr,
338 &temp_hdr, sizeof temp_hdr);
339 TEST_ASSERT(rc == 0);
340 TEST_ASSERT(memcmp(&temp_hdr, hdr, sizeof *hdr) == 0);
341
342 addr += hdr->ih_hdr_size;
343 }
344 } else {
345 img_size = 0;
346 }
347
348 area_end = area_desc->fa_off + area_desc->fa_size;
349 img_end = image_addr + img_size;
350 past_image = addr >= img_end;
351
352 while (addr < area_end) {
353 rem_area = area_end - addr;
354 rem_img = img_end - addr;
355
356 if (hdr != NULL) {
357 img_off = addr - image_addr - hdr->ih_hdr_size;
358 } else {
359 img_off = 0;
360 }
361
362 if (rem_area > sizeof buf) {
363 chunk_sz = sizeof buf;
364 } else {
365 chunk_sz = rem_area;
366 }
367
368 rc = hal_flash_read(area_desc->fa_device_id, addr, buf, chunk_sz);
369 TEST_ASSERT(rc == 0);
370
371 for (i = 0; i < chunk_sz; i++) {
372 if (rem_img > 0) {
373 TEST_ASSERT(buf[i] == boot_test_util_byte_at(img_msb,
374 img_off + i));
375 } else if (past_image) {
376#if 0
377 TEST_ASSERT(buf[i] == 0xff);
378#endif
379 }
380 }
381
382 addr += chunk_sz;
383 }
384}
385
386
387void
388boot_test_util_verify_status_clear(void)
389{
390 struct boot_swap_state state_slot0;
391 int rc;
392
393 rc = boot_read_swap_state_img(0, &state_slot0);
394 assert(rc == 0);
395
396 TEST_ASSERT(state_slot0.magic != BOOT_MAGIC_UNSET ||
397 state_slot0.copy_done != 0);
398}
399
400
401void
402boot_test_util_verify_flash(const struct image_header *hdr0, int orig_slot_0,
403 const struct image_header *hdr1, int orig_slot_1)
404{
405 const struct flash_area *area_desc;
406 int area_idx;
407
408 area_idx = 0;
409
410 while (1) {
411 area_desc = boot_test_area_descs + area_idx;
412 if (area_desc->fa_off == boot_test_img_addrs[1].address &&
413 area_desc->fa_device_id == boot_test_img_addrs[1].flash_id) {
414 break;
415 }
416
417 boot_test_util_verify_area(area_desc, hdr0,
418 boot_test_img_addrs[0].address, orig_slot_0);
419 area_idx++;
420 }
421
422 while (1) {
423 if (area_idx == BOOT_TEST_AREA_IDX_SCRATCH) {
424 break;
425 }
426
427 area_desc = boot_test_area_descs + area_idx;
428 boot_test_util_verify_area(area_desc, hdr1,
429 boot_test_img_addrs[1].address, orig_slot_1);
430 area_idx++;
431 }
432}
433
434void
435boot_test_util_verify_all(int expected_swap_type,
436 const struct image_header *hdr0,
437 const struct image_header *hdr1)
438{
439 const struct image_header *slot0hdr;
440 const struct image_header *slot1hdr;
441 struct boot_rsp rsp;
442 int orig_slot_0;
443 int orig_slot_1;
444 int num_swaps;
445 int rc;
446 int i;
447
448 TEST_ASSERT_FATAL(hdr0 != NULL || hdr1 != NULL);
449
450 num_swaps = 0;
451 for (i = 0; i < 3; i++) {
452 rc = boot_go(&rsp);
453 TEST_ASSERT_FATAL(rc == 0);
454
455 if (expected_swap_type != BOOT_SWAP_TYPE_NONE) {
456 num_swaps++;
457 }
458
459 if (num_swaps % 2 == 0) {
460 if (hdr0 != NULL) {
461 slot0hdr = hdr0;
462 slot1hdr = hdr1;
463 } else {
464 slot0hdr = hdr1;
465 slot1hdr = hdr0;
466 }
467 orig_slot_0 = 0;
468 orig_slot_1 = 1;
469 } else {
470 if (hdr1 != NULL) {
471 slot0hdr = hdr1;
472 slot1hdr = hdr0;
473 } else {
474 slot0hdr = hdr0;
475 slot1hdr = hdr1;
476 }
477 orig_slot_0 = 1;
478 orig_slot_1 = 0;
479 }
480
481 TEST_ASSERT(memcmp(rsp.br_hdr, slot0hdr, sizeof *slot0hdr) == 0);
482 TEST_ASSERT(rsp.br_flash_id == boot_test_img_addrs[0].flash_id);
483 TEST_ASSERT(rsp.br_image_addr == boot_test_img_addrs[0].address);
484
485 boot_test_util_verify_flash(slot0hdr, orig_slot_0,
486 slot1hdr, orig_slot_1);
487 boot_test_util_verify_status_clear();
488
489 if (expected_swap_type != BOOT_SWAP_TYPE_NONE) {
490 switch (expected_swap_type) {
491 case BOOT_SWAP_TYPE_TEST:
492 expected_swap_type = BOOT_SWAP_TYPE_REVERT;
493 break;
494
495 case BOOT_SWAP_TYPE_REVERT:
496 expected_swap_type = BOOT_SWAP_TYPE_NONE;
497 break;
498
499 default:
500 TEST_ASSERT_FATAL(0);
501 break;
502 }
503 }
504 }
505}