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 | |
Roman Okhrimenko | 977b375 | 2022-03-31 14:40:48 +0300 | [diff] [blame] | 40 | #define BOOT_LOG_SWAP_STATE_M(area, state) \ |
| 41 | BOOT_LOG_DBG("%s: magic=%s, swap_type=0x%x, copy_done=0x%x, image_ok=0x%x", \ |
| 42 | (area), \ |
| 43 | ((state)->magic == (uint8_t)BOOT_MAGIC_GOOD ? "good" : \ |
| 44 | (state)->magic == (uint8_t)BOOT_MAGIC_UNSET ? "unset" : \ |
| 45 | "bad"), \ |
| 46 | (unsigned)(state)->swap_type, \ |
| 47 | (unsigned)(state)->copy_done, \ |
| 48 | (unsigned)(state)->image_ok) |
Roman Okhrimenko | 13f79ed | 2021-03-11 19:05:41 +0200 | [diff] [blame] | 49 | |
Roman Okhrimenko | 977b375 | 2022-03-31 14:40:48 +0300 | [diff] [blame] | 50 | #define BOOT_SET_SWAP_INFO_M(swap_info, image, type) do { \ |
| 51 | assert((image) < 0xFu); \ |
| 52 | assert((type) < 0xFu); \ |
| 53 | (swap_info) = (image) << 4u \ |
| 54 | | (type); \ |
| 55 | } while (false) |
Roman Okhrimenko | 13f79ed | 2021-03-11 19:05:41 +0200 | [diff] [blame] | 56 | |
Roman Okhrimenko | 977b375 | 2022-03-31 14:40:48 +0300 | [diff] [blame] | 57 | #define BOOT_GET_SWAP_TYPE_M(swap_info) ((swap_info) & 0x0Fu) |
| 58 | #define BOOT_GET_IMAGE_NUM_M(swap_info) ((swap_info) >> 4u) |
Roman Okhrimenko | 13f79ed | 2021-03-11 19:05:41 +0200 | [diff] [blame] | 59 | |
| 60 | extern const uint32_t stat_part_magic[1]; |
| 61 | |
Roman Okhrimenko | 977b375 | 2022-03-31 14:40:48 +0300 | [diff] [blame] | 62 | #define BOOT_SWAP_STATUS_MAGIC (0xDEADBEEFu) |
Roman Okhrimenko | 13f79ed | 2021-03-11 19:05:41 +0200 | [diff] [blame] | 63 | |
| 64 | #define BOOT_SWAP_STATUS_ENCK1_SZ 16UL |
| 65 | #define BOOT_SWAP_STATUS_ENCK2_SZ 16UL |
| 66 | |
| 67 | struct image_status_trailer { |
| 68 | uint8_t enc_key1[BOOT_SWAP_STATUS_ENCK1_SZ]; |
| 69 | uint8_t enc_key2[BOOT_SWAP_STATUS_ENCK2_SZ]; |
| 70 | uint32_t swap_size; |
| 71 | uint8_t swap_type; |
| 72 | uint8_t copy_done; |
| 73 | uint8_t image_ok; |
| 74 | uint8_t magic[BOOT_MAGIC_SZ]; |
| 75 | }; |
| 76 | |
| 77 | #define BOOT_SWAP_STATUS_SWAPSZ_SZ 4UL |
| 78 | #define BOOT_SWAP_STATUS_SWAPINF_SZ 1UL |
| 79 | #define BOOT_SWAP_STATUS_COPY_DONE_SZ 1UL |
| 80 | #define BOOT_SWAP_STATUS_IMG_OK_SZ 1UL |
| 81 | |
| 82 | #define BOOT_SWAP_STATUS_MAGIC_SZ BOOT_MAGIC_SZ |
| 83 | |
| 84 | #define BOOT_SWAP_STATUS_MGCREC_SZ 4UL |
| 85 | #define BOOT_SWAP_STATUS_CNT_SZ 4UL |
| 86 | #define BOOT_SWAP_STATUS_CRC_SZ 4UL |
| 87 | |
Roman Okhrimenko | dc0ca08 | 2023-06-21 20:49:51 +0300 | [diff] [blame^] | 88 | #define BOOT_SWAP_STATUS_ROW_SZ MEMORY_ALIGN |
Roman Okhrimenko | 13f79ed | 2021-03-11 19:05:41 +0200 | [diff] [blame] | 89 | |
| 90 | /* agreed to name it "a record" */ |
| 91 | #define BOOT_SWAP_STATUS_PAYLD_SZ (BOOT_SWAP_STATUS_ROW_SZ -\ |
Roman Okhrimenko | 977b375 | 2022-03-31 14:40:48 +0300 | [diff] [blame] | 92 | BOOT_SWAP_STATUS_MGCREC_SZ - \ |
| 93 | BOOT_SWAP_STATUS_CNT_SZ - \ |
| 94 | BOOT_SWAP_STATUS_CRC_SZ) |
Roman Okhrimenko | 13f79ed | 2021-03-11 19:05:41 +0200 | [diff] [blame] | 95 | #define BOOT_SWAP_STATUS_ROW_SZ_MIN 16UL |
| 96 | |
| 97 | /* INFO: defining record structure for better understanding */ |
| 98 | struct status_part_record{ |
| 99 | uint8_t payload[BOOT_SWAP_STATUS_PAYLD_SZ]; |
| 100 | uint8_t magic[BOOT_SWAP_STATUS_MGCREC_SZ]; |
| 101 | uint8_t counter[BOOT_SWAP_STATUS_CNT_SZ]; |
| 102 | uint8_t crc[BOOT_SWAP_STATUS_CRC_SZ]; |
| 103 | }; |
| 104 | |
| 105 | #if (BOOT_SWAP_STATUS_ROW_SZ % BOOT_SWAP_STATUS_ROW_SZ_MIN != 0) |
| 106 | #error "BOOT_SWAP_STATUS_ROW_SZ size is less then min value of 16 bytes" |
| 107 | #endif |
| 108 | |
| 109 | /* number of rows sector-status area should fit into */ |
| 110 | #define BOOT_SWAP_STATUS_SECT_ROWS_NUM (((BOOT_MAX_IMG_SECTORS-1u)/BOOT_SWAP_STATUS_PAYLD_SZ) + 1u) |
| 111 | |
| 112 | /* |
| 113 | Number of flash rows used to store swap info. It consists |
| 114 | of following fields. 16 bytes is a minimum required row size, |
| 115 | thus 64 bytes required at minimum size of swap info size. |
| 116 | |
| 117 | 16 bytes - uint8_t enc_key1[BOOT_SWAP_STATUS_ENCK1_SZ]; |
| 118 | 16 bytes - uint8_t enc_key2[BOOT_SWAP_STATUS_ENCK2_SZ]; |
| 119 | 4 bytes - uint32_t swap_size; |
| 120 | 1 byte - uint8_t swap_type; |
| 121 | 1 byte - uint8_t copy_done; |
| 122 | 1 byte - uint8_t image_ok; |
| 123 | 16 bytes - uint8_t magic[BOOT_MAGIC_SZ]; |
| 124 | = 55 bytes |
| 125 | */ |
| 126 | #define BOOT_SWAP_STATUS_TRAILER_SIZE 64UL |
| 127 | // TODO: check if min write size is 64 or larger |
| 128 | // TODO: small-magic, coutner and crc aren't coutned here |
| 129 | |
| 130 | /* number of rows trailer data should fit into */ |
| 131 | #define BOOT_SWAP_STATUS_TRAIL_ROWS_NUM (((BOOT_SWAP_STATUS_TRAILER_SIZE - 1u)/BOOT_SWAP_STATUS_PAYLD_SZ) + 1u) |
| 132 | |
| 133 | /* the size of one copy of status area */ |
| 134 | #define BOOT_SWAP_STATUS_D_SIZE (BOOT_SWAP_STATUS_ROW_SZ * \ |
Roman Okhrimenko | 977b375 | 2022-03-31 14:40:48 +0300 | [diff] [blame] | 135 | (BOOT_SWAP_STATUS_SECT_ROWS_NUM + \ |
| 136 | BOOT_SWAP_STATUS_TRAIL_ROWS_NUM)) |
Roman Okhrimenko | 13f79ed | 2021-03-11 19:05:41 +0200 | [diff] [blame] | 137 | |
| 138 | /* the size of one copy of status area without cnt and crc fields */ |
| 139 | #define BOOT_SWAP_STATUS_D_SIZE_RAW (BOOT_SWAP_STATUS_PAYLD_SZ * \ |
Roman Okhrimenko | 977b375 | 2022-03-31 14:40:48 +0300 | [diff] [blame] | 140 | (BOOT_SWAP_STATUS_SECT_ROWS_NUM + \ |
| 141 | BOOT_SWAP_STATUS_TRAIL_ROWS_NUM)) |
Roman Okhrimenko | 13f79ed | 2021-03-11 19:05:41 +0200 | [diff] [blame] | 142 | |
| 143 | /* multiplier which defines how many blocks will be used to reduce Flash wear |
| 144 | * 1 is for single write wear, 2 - twice less wear, 3 - three times less wear, etc */ |
| 145 | #define BOOT_SWAP_STATUS_MULT 2UL |
| 146 | |
| 147 | #define BOOT_SWAP_STATUS_SIZE (BOOT_SWAP_STATUS_MULT * BOOT_SWAP_STATUS_D_SIZE) |
| 148 | |
| 149 | #define BOOT_SWAP_STATUS_SZ_PRIM BOOT_SWAP_STATUS_SIZE |
| 150 | #define BOOT_SWAP_STATUS_SZ_SEC BOOT_SWAP_STATUS_SIZE |
| 151 | #define BOOT_SWAP_STATUS_SZ_SCRATCH BOOT_SWAP_STATUS_SIZE |
| 152 | |
| 153 | #define BOOT_SWAP_STATUS_OFFS_PRIM 0UL |
| 154 | #define BOOT_SWAP_STATUS_OFFS_SEC (BOOT_SWAP_STATUS_OFFS_PRIM + \ |
Roman Okhrimenko | 977b375 | 2022-03-31 14:40:48 +0300 | [diff] [blame] | 155 | BOOT_SWAP_STATUS_SZ_PRIM) |
Roman Okhrimenko | 13f79ed | 2021-03-11 19:05:41 +0200 | [diff] [blame] | 156 | |
Roman Okhrimenko | 977b375 | 2022-03-31 14:40:48 +0300 | [diff] [blame] | 157 | /* size Limit for primary slot trailer buffer */ |
Roman Okhrimenko | dc0ca08 | 2023-06-21 20:49:51 +0300 | [diff] [blame^] | 158 | #define MAX_TRAILER_BUF_SIZE PLATFORM_MAX_TRAILER_PAGE_SIZE |
Roman Okhrimenko | 13f79ed | 2021-03-11 19:05:41 +0200 | [diff] [blame] | 159 | |
Roman Okhrimenko | 977b375 | 2022-03-31 14:40:48 +0300 | [diff] [blame] | 160 | int32_t swap_status_init_offset(uint8_t area_id); |
| 161 | int swap_status_update(uint8_t target_area_id, uint32_t offs, const void *data, uint32_t len); |
| 162 | int swap_status_retrieve(uint8_t target_area_id, uint32_t offs, void *data, uint32_t len); |
| 163 | int swap_status_to_image_trailer(const struct flash_area *fap); |
Roman Okhrimenko | 13f79ed | 2021-03-11 19:05:41 +0200 | [diff] [blame] | 164 | |
| 165 | #endif /* MCUBOOT_SWAP_USING_STATUS */ |
| 166 | |
| 167 | #endif /* H_SWAP_STATUS_H_ */ |