static void boot_test_util_write_image(const struct image_header *hdr, int slot) { uint32_t image_off; uint32_t off; uint8_t flash_id; uint8_t buf[256]; int chunk_sz; int rc; int i; TEST_ASSERT(slot == 0 || slot == 1); flash_id = boot_test_img_addrs[slot].flash_id; off = boot_test_img_addrs[slot].address; rc = hal_flash_write(flash_id, off, hdr, sizeof *hdr); TEST_ASSERT(rc == 0); off += hdr->ih_hdr_size; image_off = 0; while (image_off < hdr->ih_img_size) { if (hdr->ih_img_size - image_off > sizeof buf) { chunk_sz = sizeof buf; } else { chunk_sz = hdr->ih_img_size - image_off; } for (i = 0; i < chunk_sz; i++) { buf[i] = boot_test_util_byte_at(slot, image_off + i); } rc = hal_flash_write(flash_id, off + image_off, buf, chunk_sz); TEST_ASSERT(rc == 0); image_off += chunk_sz; } }
static void boot_test_util_verify_area(const struct nffs_area_desc *area_desc, const struct image_header *hdr, uint32_t image_addr, int img_msb) { struct image_header temp_hdr; uint32_t area_end; uint32_t img_size; uint32_t img_off; uint32_t img_end; uint32_t addr; uint8_t buf[256]; int rem_area; int past_image; int chunk_sz; int rem_img; int rc; int i; addr = area_desc->nad_offset; if (hdr != NULL) { img_size = hdr->ih_img_size; if (addr == image_addr) { rc = hal_flash_read(area_desc->nad_flash_id, image_addr, &temp_hdr, sizeof temp_hdr); TEST_ASSERT(rc == 0); TEST_ASSERT(memcmp(&temp_hdr, hdr, sizeof *hdr) == 0); addr += hdr->ih_hdr_size; } } else { img_size = 0; } area_end = area_desc->nad_offset + area_desc->nad_length; img_end = image_addr + img_size; past_image = addr >= img_end; while (addr < area_end) { rem_area = area_end - addr; rem_img = img_end - addr; if (hdr != NULL) { img_off = addr - image_addr - hdr->ih_hdr_size; } else { img_off = 0; } if (rem_area > sizeof buf) { chunk_sz = sizeof buf; } else { chunk_sz = rem_area; } rc = hal_flash_read(area_desc->nad_flash_id, addr, buf, chunk_sz); TEST_ASSERT(rc == 0); for (i = 0; i < chunk_sz; i++) { if (rem_img > 0) { TEST_ASSERT(buf[i] == boot_test_util_byte_at(img_msb, img_off + i)); } else if (past_image) { TEST_ASSERT(buf[i] == 0xff); } } addr += chunk_sz; } }
void boot_test_util_mark_revert(void) { struct boot_swap_state state_slot0 = { .magic = BOOT_MAGIC_GOOD, .copy_done = 0x01, .image_ok = 0xff, }; boot_test_util_write_swap_state(FLASH_AREA_IMAGE_0, &state_slot0); } void boot_test_util_verify_area(const struct flash_area *area_desc, const struct image_header *hdr, uint32_t image_addr, int img_msb) { struct image_header temp_hdr; uint32_t area_end; uint32_t img_size; uint32_t img_off; uint32_t img_end; uint32_t addr; uint8_t buf[256]; int rem_area; int past_image; int chunk_sz; int rem_img; int rc; int i; addr = area_desc->fa_off; if (hdr != NULL) { img_size = hdr->ih_img_size; if (addr == image_addr) { rc = hal_flash_read(area_desc->fa_device_id, image_addr, &temp_hdr, sizeof temp_hdr); TEST_ASSERT(rc == 0); TEST_ASSERT(memcmp(&temp_hdr, hdr, sizeof *hdr) == 0); addr += hdr->ih_hdr_size; } } else { img_size = 0; } area_end = area_desc->fa_off + area_desc->fa_size; img_end = image_addr + img_size; past_image = addr >= img_end; while (addr < area_end) { rem_area = area_end - addr; rem_img = img_end - addr; if (hdr != NULL) { img_off = addr - image_addr - hdr->ih_hdr_size; } else { img_off = 0; } if (rem_area > sizeof buf) { chunk_sz = sizeof buf; } else { chunk_sz = rem_area; } rc = hal_flash_read(area_desc->fa_device_id, addr, buf, chunk_sz); TEST_ASSERT(rc == 0); for (i = 0; i < chunk_sz; i++) { if (rem_img > 0) { TEST_ASSERT(buf[i] == boot_test_util_byte_at(img_msb, img_off + i)); } else if (past_image) { #if 0 TEST_ASSERT(buf[i] == 0xff); #endif } } addr += chunk_sz; } } void boot_test_util_verify_status_clear(void) { struct boot_swap_state state_slot0; int rc; rc = boot_read_swap_state_img(0, &state_slot0); assert(rc == 0); TEST_ASSERT(state_slot0.magic != BOOT_MAGIC_UNSET || state_slot0.copy_done != 0); } void boot_test_util_verify_flash(const struct image_header *hdr0, int orig_slot_0, const struct image_header *hdr1, int orig_slot_1) { const struct flash_area *area_desc; int area_idx; area_idx = 0; while (1) { area_desc = boot_test_area_descs + area_idx; if (area_desc->fa_off == boot_test_img_addrs[1].address && area_desc->fa_device_id == boot_test_img_addrs[1].flash_id) { break; } boot_test_util_verify_area(area_desc, hdr0, boot_test_img_addrs[0].address, orig_slot_0); area_idx++; } while (1) { if (area_idx == BOOT_TEST_AREA_IDX_SCRATCH) { break; } area_desc = boot_test_area_descs + area_idx; boot_test_util_verify_area(area_desc, hdr1, boot_test_img_addrs[1].address, orig_slot_1); area_idx++; } } void boot_test_util_verify_all(int expected_swap_type, const struct image_header *hdr0, const struct image_header *hdr1) { const struct image_header *slot0hdr; const struct image_header *slot1hdr; struct boot_rsp rsp; int orig_slot_0; int orig_slot_1; int num_swaps; int rc; int i; TEST_ASSERT_FATAL(hdr0 != NULL || hdr1 != NULL); num_swaps = 0; for (i = 0; i < 3; i++) { rc = boot_go(&rsp); TEST_ASSERT_FATAL(rc == 0); if (expected_swap_type != BOOT_SWAP_TYPE_NONE) { num_swaps++; } if (num_swaps % 2 == 0) { if (hdr0 != NULL) { slot0hdr = hdr0; slot1hdr = hdr1; } else { slot0hdr = hdr1; slot1hdr = hdr0; } orig_slot_0 = 0; orig_slot_1 = 1; } else { if (hdr1 != NULL) { slot0hdr = hdr1; slot1hdr = hdr0; } else { slot0hdr = hdr0; slot1hdr = hdr1; } orig_slot_0 = 1; orig_slot_1 = 0; } TEST_ASSERT(memcmp(rsp.br_hdr, slot0hdr, sizeof *slot0hdr) == 0); TEST_ASSERT(rsp.br_flash_id == boot_test_img_addrs[0].flash_id); TEST_ASSERT(rsp.br_image_addr == boot_test_img_addrs[0].address); boot_test_util_verify_flash(slot0hdr, orig_slot_0, slot1hdr, orig_slot_1); boot_test_util_verify_status_clear(); if (expected_swap_type != BOOT_SWAP_TYPE_NONE) { switch (expected_swap_type) { case BOOT_SWAP_TYPE_TEST: expected_swap_type = BOOT_SWAP_TYPE_REVERT; break; case BOOT_SWAP_TYPE_REVERT: expected_swap_type = BOOT_SWAP_TYPE_NONE; break; default: TEST_ASSERT_FATAL(0); break; } } } }