Roman Okhrimenko | 13f79ed | 2021-03-11 19:05:41 +0200 | [diff] [blame] | 1 | /* |
| 2 | * SPDX-License-Identifier: Apache-2.0 |
| 3 | * |
| 4 | * Copyright (c) 2017-2019 Linaro LTD |
| 5 | * Copyright (c) 2016-2019 JUUL Labs |
| 6 | * Copyright (c) 2019-2020 Arm Limited |
| 7 | * Copyright (c) 2020 Cypress Semiconductors |
| 8 | * |
| 9 | * Original license: |
| 10 | * |
| 11 | * Licensed to the Apache Software Foundation (ASF) under one |
| 12 | * or more contributor license agreements. See the NOTICE file |
| 13 | * distributed with this work for additional information |
| 14 | * regarding copyright ownership. The ASF licenses this file |
| 15 | * to you under the Apache License, Version 2.0 (the |
| 16 | * "License"); you may not use this file except in compliance |
| 17 | * with the License. You may obtain a copy of the License at |
| 18 | * |
| 19 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 20 | * |
| 21 | * Unless required by applicable law or agreed to in writing, |
| 22 | * software distributed under the License is distributed on an |
| 23 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 24 | * KIND, either express or implied. See the License for the |
| 25 | * specific language governing permissions and limitations |
| 26 | * under the License. |
| 27 | */ |
| 28 | |
| 29 | #ifndef H_SWAP_STATUS_H_ |
| 30 | #define H_SWAP_STATUS_H_ |
| 31 | |
| 32 | #include <stdint.h> |
| 33 | #include "sysflash/sysflash.h" |
| 34 | #include "bootutil_priv.h" |
| 35 | |
| 36 | #include "mcuboot_config/mcuboot_config.h" |
| 37 | |
| 38 | #ifdef MCUBOOT_SWAP_USING_STATUS |
| 39 | |
| 40 | #define BOOT_LOG_SWAP_STATE_M(area, state) \ |
| 41 | BOOT_LOG_DBG("%s: magic=%s, swap_type=0x%x, copy_done=0x%x, " \ |
| 42 | "image_ok=0x%x", \ |
| 43 | (area), \ |
| 44 | ((state)->magic == (uint8_t)BOOT_MAGIC_GOOD ? "good" :\ |
| 45 | (state)->magic == (uint8_t)BOOT_MAGIC_UNSET ? "unset" :\ |
| 46 | "bad"), \ |
| 47 | (state)->swap_type, \ |
| 48 | (state)->copy_done, \ |
| 49 | (state)->image_ok) |
| 50 | |
| 51 | #define BOOT_SET_SWAP_INFO_M(swap_info, image, type) { \ |
| 52 | assert((int)((image) < 0xFu)); \ |
| 53 | assert((int)((type) < 0xFu)); \ |
| 54 | (swap_info) = (image) << 4u \ |
| 55 | | (type); \ |
| 56 | } |
| 57 | |
| 58 | #define BOOT_GET_SWAP_TYPE_M(swap_info) ((swap_info) & 0x0Fu) |
| 59 | #define BOOT_GET_IMAGE_NUM_M(swap_info) ((swap_info) >> 4u) |
| 60 | |
| 61 | extern const uint32_t stat_part_magic[1]; |
| 62 | |
| 63 | #define BOOT_SWAP_STATUS_MAGIC (0xDEADBEAFu) |
| 64 | |
| 65 | #define BOOT_SWAP_STATUS_ENCK1_SZ 16UL |
| 66 | #define BOOT_SWAP_STATUS_ENCK2_SZ 16UL |
| 67 | |
| 68 | struct image_status_trailer { |
| 69 | uint8_t enc_key1[BOOT_SWAP_STATUS_ENCK1_SZ]; |
| 70 | uint8_t enc_key2[BOOT_SWAP_STATUS_ENCK2_SZ]; |
| 71 | uint32_t swap_size; |
| 72 | uint8_t swap_type; |
| 73 | uint8_t copy_done; |
| 74 | uint8_t image_ok; |
| 75 | uint8_t magic[BOOT_MAGIC_SZ]; |
| 76 | }; |
| 77 | |
| 78 | #define BOOT_SWAP_STATUS_SWAPSZ_SZ 4UL |
| 79 | #define BOOT_SWAP_STATUS_SWAPINF_SZ 1UL |
| 80 | #define BOOT_SWAP_STATUS_COPY_DONE_SZ 1UL |
| 81 | #define BOOT_SWAP_STATUS_IMG_OK_SZ 1UL |
| 82 | |
| 83 | #define BOOT_SWAP_STATUS_MAGIC_SZ BOOT_MAGIC_SZ |
| 84 | |
| 85 | #define BOOT_SWAP_STATUS_MGCREC_SZ 4UL |
| 86 | #define BOOT_SWAP_STATUS_CNT_SZ 4UL |
| 87 | #define BOOT_SWAP_STATUS_CRC_SZ 4UL |
| 88 | |
| 89 | #define BOOT_SWAP_STATUS_ROW_SZ CY_FLASH_ALIGN |
| 90 | |
| 91 | /* agreed to name it "a record" */ |
| 92 | #define BOOT_SWAP_STATUS_PAYLD_SZ (BOOT_SWAP_STATUS_ROW_SZ -\ |
| 93 | BOOT_SWAP_STATUS_MGCREC_SZ - \ |
| 94 | BOOT_SWAP_STATUS_CNT_SZ - \ |
| 95 | BOOT_SWAP_STATUS_CRC_SZ) |
| 96 | #define BOOT_SWAP_STATUS_ROW_SZ_MIN 16UL |
| 97 | |
| 98 | /* INFO: defining record structure for better understanding */ |
| 99 | struct status_part_record{ |
| 100 | uint8_t payload[BOOT_SWAP_STATUS_PAYLD_SZ]; |
| 101 | uint8_t magic[BOOT_SWAP_STATUS_MGCREC_SZ]; |
| 102 | uint8_t counter[BOOT_SWAP_STATUS_CNT_SZ]; |
| 103 | uint8_t crc[BOOT_SWAP_STATUS_CRC_SZ]; |
| 104 | }; |
| 105 | |
| 106 | #if (BOOT_SWAP_STATUS_ROW_SZ % BOOT_SWAP_STATUS_ROW_SZ_MIN != 0) |
| 107 | #error "BOOT_SWAP_STATUS_ROW_SZ size is less then min value of 16 bytes" |
| 108 | #endif |
| 109 | |
| 110 | /* number of rows sector-status area should fit into */ |
| 111 | #define BOOT_SWAP_STATUS_SECT_ROWS_NUM (((BOOT_MAX_IMG_SECTORS-1u)/BOOT_SWAP_STATUS_PAYLD_SZ) + 1u) |
| 112 | |
| 113 | /* |
| 114 | Number of flash rows used to store swap info. It consists |
| 115 | of following fields. 16 bytes is a minimum required row size, |
| 116 | thus 64 bytes required at minimum size of swap info size. |
| 117 | |
| 118 | 16 bytes - uint8_t enc_key1[BOOT_SWAP_STATUS_ENCK1_SZ]; |
| 119 | 16 bytes - uint8_t enc_key2[BOOT_SWAP_STATUS_ENCK2_SZ]; |
| 120 | 4 bytes - uint32_t swap_size; |
| 121 | 1 byte - uint8_t swap_type; |
| 122 | 1 byte - uint8_t copy_done; |
| 123 | 1 byte - uint8_t image_ok; |
| 124 | 16 bytes - uint8_t magic[BOOT_MAGIC_SZ]; |
| 125 | = 55 bytes |
| 126 | */ |
| 127 | #define BOOT_SWAP_STATUS_TRAILER_SIZE 64UL |
| 128 | // TODO: check if min write size is 64 or larger |
| 129 | // TODO: small-magic, coutner and crc aren't coutned here |
| 130 | |
| 131 | /* number of rows trailer data should fit into */ |
| 132 | #define BOOT_SWAP_STATUS_TRAIL_ROWS_NUM (((BOOT_SWAP_STATUS_TRAILER_SIZE - 1u)/BOOT_SWAP_STATUS_PAYLD_SZ) + 1u) |
| 133 | |
| 134 | /* the size of one copy of status area */ |
| 135 | #define BOOT_SWAP_STATUS_D_SIZE (BOOT_SWAP_STATUS_ROW_SZ * \ |
| 136 | (BOOT_SWAP_STATUS_SECT_ROWS_NUM + \ |
| 137 | BOOT_SWAP_STATUS_TRAIL_ROWS_NUM)) |
| 138 | |
| 139 | /* the size of one copy of status area without cnt and crc fields */ |
| 140 | #define BOOT_SWAP_STATUS_D_SIZE_RAW (BOOT_SWAP_STATUS_PAYLD_SZ * \ |
| 141 | (BOOT_SWAP_STATUS_SECT_ROWS_NUM + \ |
| 142 | BOOT_SWAP_STATUS_TRAIL_ROWS_NUM)) |
| 143 | |
| 144 | /* multiplier which defines how many blocks will be used to reduce Flash wear |
| 145 | * 1 is for single write wear, 2 - twice less wear, 3 - three times less wear, etc */ |
| 146 | #define BOOT_SWAP_STATUS_MULT 2UL |
| 147 | |
| 148 | #define BOOT_SWAP_STATUS_SIZE (BOOT_SWAP_STATUS_MULT * BOOT_SWAP_STATUS_D_SIZE) |
| 149 | |
| 150 | #define BOOT_SWAP_STATUS_SZ_PRIM BOOT_SWAP_STATUS_SIZE |
| 151 | #define BOOT_SWAP_STATUS_SZ_SEC BOOT_SWAP_STATUS_SIZE |
| 152 | #define BOOT_SWAP_STATUS_SZ_SCRATCH BOOT_SWAP_STATUS_SIZE |
| 153 | |
| 154 | #define BOOT_SWAP_STATUS_OFFS_PRIM 0UL |
| 155 | #define BOOT_SWAP_STATUS_OFFS_SEC (BOOT_SWAP_STATUS_OFFS_PRIM + \ |
| 156 | BOOT_SWAP_STATUS_SZ_PRIM) |
| 157 | |
| 158 | int32_t swap_status_init_offset(uint32_t area_id); |
| 159 | int swap_status_update(uint32_t target_area_id, uint32_t offs, const void *data, uint32_t len); |
| 160 | int swap_status_retrieve(uint32_t target_area_id, uint32_t offs, void *data, uint32_t len); |
| 161 | |
| 162 | int boot_write_trailer(const struct flash_area *fap, uint32_t off, |
| 163 | const uint8_t *inbuf, uint8_t inlen); |
| 164 | |
| 165 | #endif /* MCUBOOT_SWAP_USING_STATUS */ |
| 166 | |
| 167 | #endif /* H_SWAP_STATUS_H_ */ |