blob: dc27d64a756cb842020d3225e06b78ccd2849a3c [file] [log] [blame]
Roman Okhrimenko13f79ed2021-03-11 19:05:41 +02001/*
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
61extern 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
68struct 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 */
99struct 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
158int32_t swap_status_init_offset(uint32_t area_id);
159int swap_status_update(uint32_t target_area_id, uint32_t offs, const void *data, uint32_t len);
160int swap_status_retrieve(uint32_t target_area_id, uint32_t offs, void *data, uint32_t len);
161
162int 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_ */