/* * Copyright (c) 2017, 2020 Nordic Semiconductor ASA * Copyright (c) 2017 Linaro Limited * Copyright (c) 2020 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #include #include #ifdef CONFIG_IMG_ERASE_PROGRESSIVELY #include #endif #include /* FLASH_AREA_ID() values used below are auto-generated by DT */ #ifdef CONFIG_TRUSTED_EXECUTION_NONSECURE #define UPLOAD_FLASH_AREA_ID FLASH_AREA_ID(image_1_nonsecure) #else #if FLASH_AREA_LABEL_EXISTS(image_1) #define UPLOAD_FLASH_AREA_ID FLASH_AREA_ID(image_1) #else #define UPLOAD_FLASH_AREA_ID FLASH_AREA_ID(image_0) #endif #endif /* CONFIG_TRUSTED_EXECUTION_NONSECURE */ #define FLASH_WRITE_BLOCK_SIZE \ DT_PROP(DT_CHOSEN(zephyr_flash), write_block_size) BUILD_ASSERT((CONFIG_IMG_BLOCK_BUF_SIZE % FLASH_WRITE_BLOCK_SIZE == 0), "CONFIG_IMG_BLOCK_BUF_SIZE is not a multiple of " "FLASH_WRITE_BLOCK_SIZE"); int flash_img_buffered_write(struct flash_img_context *ctx, const uint8_t *data, size_t len, bool flush) { int rc; rc = stream_flash_buffered_write(&ctx->stream, data, len, flush); if (!flush) { return rc; } #ifdef CONFIG_IMG_ERASE_PROGRESSIVELY rc = stream_flash_erase_page(&ctx->stream, ctx->flash_area->fa_off + BOOT_TRAILER_IMG_STATUS_OFFS(ctx->flash_area)); if (rc) { return rc; } #endif flash_area_close(ctx->flash_area); ctx->flash_area = NULL; return rc; } size_t flash_img_bytes_written(struct flash_img_context *ctx) { return stream_flash_bytes_written(&ctx->stream); } int flash_img_init_id(struct flash_img_context *ctx, uint8_t area_id) { int rc; const struct device *flash_dev; rc = flash_area_open(area_id, (const struct flash_area **)&(ctx->flash_area)); if (rc) { return rc; } flash_dev = flash_area_get_device(ctx->flash_area); return stream_flash_init(&ctx->stream, flash_dev, ctx->buf, CONFIG_IMG_BLOCK_BUF_SIZE, ctx->flash_area->fa_off, ctx->flash_area->fa_size, NULL); } int flash_img_init(struct flash_img_context *ctx) { return flash_img_init_id(ctx, UPLOAD_FLASH_AREA_ID); } #if defined(CONFIG_IMG_ENABLE_IMAGE_CHECK) int flash_img_check(struct flash_img_context *ctx, const struct flash_img_check *fic, uint8_t area_id) { struct flash_area_check fac; int rc; if (!ctx || !fic) { return -EINVAL; } rc = flash_area_open(area_id, (const struct flash_area **)&(ctx->flash_area)); if (rc) { return rc; } fac.match = fic->match; fac.clen = fic->clen; fac.off = 0; fac.rbuf = ctx->buf; fac.rblen = sizeof(ctx->buf); rc = flash_area_check_int_sha256(ctx->flash_area, &fac); flash_area_close(ctx->flash_area); ctx->flash_area = NULL; return rc; } #endif