/* * Copyright (c) 2017 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #define BOOT_MAGIC_VAL_W0 0xf395c277 #define BOOT_MAGIC_VAL_W1 0x7fefd260 #define BOOT_MAGIC_VAL_W2 0x0f505235 #define BOOT_MAGIC_VAL_W3 0x8079b62c #define BOOT_MAGIC_VALUES {BOOT_MAGIC_VAL_W0, BOOT_MAGIC_VAL_W1,\ BOOT_MAGIC_VAL_W2, BOOT_MAGIC_VAL_W3 } static void erase_image_status_page(const struct flash_area *fa) { int ret; struct flash_pages_info page; const struct device *sf_dev; sf_dev = flash_area_get_device(fa); /* Erase flash page to which image status belongs. */ ret = flash_get_page_info_by_offs(sf_dev, fa->fa_off + fa->fa_size - 1, &page); zassert_true(ret == 0, "can't get the trailer's flash page info."); ret = flash_erase(sf_dev, page.start_offset, page.size); zassert_true(ret == 0, "can't erase the trailer flash page."); } static void _test_request_upgrade_n(uint8_t fa_id, int img_index, int confirmed) { const struct flash_area *fa; const uint32_t expectation[6] = { 0xffffffff, 0xffffffff, BOOT_MAGIC_VAL_W0, BOOT_MAGIC_VAL_W1, BOOT_MAGIC_VAL_W2, BOOT_MAGIC_VAL_W3 }; uint32_t readout[ARRAY_SIZE(expectation)]; int ret; ret = flash_area_open(fa_id, &fa); zassert_true(ret == 0, "can't open the images's flash area."); erase_image_status_page(fa); ret = (confirmed) ? BOOT_UPGRADE_PERMANENT : BOOT_UPGRADE_TEST; zassert_true(boot_request_upgrade_multi(img_index, ret) == 0, "Can' request the upgrade of the %d. image.", img_index); ret = flash_area_read(fa, fa->fa_size - sizeof(expectation), &readout, sizeof(readout)); zassert_true(ret == 0, "Read from flash"); if (confirmed) { zassert_true(memcmp(&expectation[2], &readout[2], sizeof(expectation) - 2 * sizeof(expectation[0])) == 0, "unexpected trailer value"); zassert_equal(1, readout[0] & 0xff, "confirmation error"); } else { zassert_true(memcmp(expectation, readout, sizeof(expectation)) == 0, "unexpected trailer value"); } } ZTEST(mcuboot_multi, test_request_upgrade_multi) { _test_request_upgrade_n(FIXED_PARTITION_ID(slot1_partition), 0, 0); _test_request_upgrade_n(FIXED_PARTITION_ID(slot3_partition), 1, 1); } static void _test_write_confirm_n(uint8_t fa_id, int img_index) { const uint32_t img_magic[4] = BOOT_MAGIC_VALUES; uint32_t readout[ARRAY_SIZE(img_magic)]; uint8_t flag[BOOT_MAX_ALIGN]; const struct flash_area *fa; int ret; flag[0] = 0x01; memset(&flag[1], 0xff, sizeof(flag) - 1); ret = flash_area_open(fa_id, &fa); zassert_true(ret == 0, "can't open the images's flash area."); erase_image_status_page(fa); ret = flash_area_read(fa, fa->fa_size - sizeof(img_magic), &readout, sizeof(img_magic)); zassert_true(ret == 0, "Read from flash"); if (memcmp(img_magic, readout, sizeof(img_magic)) != 0) { ret = flash_area_write(fa, fa->fa_size - 16, img_magic, 16); zassert_true(ret == 0, "Write to flash"); } /* set copy-done flag */ ret = flash_area_write(fa, fa->fa_size - 32, &flag, sizeof(flag)); zassert_true(ret == 0, "Write to flash"); ret = boot_write_img_confirmed_multi(img_index); zassert(ret == 0, "pass", "fail (%d)", ret); ret = flash_area_read(fa, fa->fa_size - 24, readout, sizeof(readout[0])); zassert_true(ret == 0, "Read from flash"); zassert_equal(1, readout[0] & 0xff, "confirmation error"); } ZTEST(mcuboot_multi, test_write_confirm_multi) { _test_write_confirm_n(FIXED_PARTITION_ID(slot0_partition), 0); _test_write_confirm_n(FIXED_PARTITION_ID(slot2_partition), 1); } ZTEST_SUITE(mcuboot_multi, NULL, NULL, NULL, NULL, NULL);