1 /*
2  * Copyright 2021 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 #ifndef _FSL_SBLOADER_H_
8 #define _FSL_SBLOADER_H_
9 
10 #include "fsl_flash.h"
11 #include "fsl_flexspi_nor_flash.h"
12 #include "fsl_sbloader_v3.h"
13 #include "fsl_common.h"
14 /*!
15  * @addtogroup sbloader
16  * @{
17  */
18 
19 /*******************************************************************************
20  * Definitions
21  ******************************************************************************/
22 
23 /*! @brief Determines the version of SB loader implementation (1: sb1.0; 2: sb2.0; 3.1: sb3.1) */
24 #define SB_FILE_MAJOR_VERSION (3)
25 #define SB_FILE_MINOR_VERSION (1)
26 
27 /*! @brief Bootloader status group numbers */
28 #define kStatusGroup_SBLoader (101U)
29 
30 /*! @brief Contiguous RAM region count */
31 #define RAM_REGION_COUNT (2U)
32 
33 /*! @brief Contiguous FLASH region count */
34 #define FLASH_REGION_COUNT (1U)
35 
36 /*! @brief Contiguous FFR region count */
37 #define FFR_REGION_COUNT (1U)
38 
39 /*! @brief Memory Interface count */
40 #define MEM_INTERFACE_COUNT (4U)
41 
42 /*! @brief Contiguous FLEXSPINOR meomry count */
43 #define FLEXSPINOR_REGION_COUNT (1U)
44 
45 /*! @brief SB loader status codes.*/
46 enum
47 {
48     kStatusRomLdrSectionOverrun  = MAKE_STATUS(kStatusGroup_SBLoader, 0),
49     kStatusRomLdrSignature       = MAKE_STATUS(kStatusGroup_SBLoader, 1),
50     kStatusRomLdrSectionLength   = MAKE_STATUS(kStatusGroup_SBLoader, 2),
51     kStatusRomLdrUnencryptedOnly = MAKE_STATUS(kStatusGroup_SBLoader, 3),
52     kStatusRomLdrEOFReached      = MAKE_STATUS(kStatusGroup_SBLoader, 4),
53     kStatusRomLdrChecksum        = MAKE_STATUS(kStatusGroup_SBLoader, 5),
54     kStatusRomLdrCrc32Error      = MAKE_STATUS(kStatusGroup_SBLoader, 6),
55     kStatusRomLdrUnknownCommand  = MAKE_STATUS(kStatusGroup_SBLoader, 7),
56     kStatusRomLdrIdNotFound      = MAKE_STATUS(kStatusGroup_SBLoader, 8),
57     kStatusRomLdrDataUnderrun    = MAKE_STATUS(kStatusGroup_SBLoader, 9),
58     kStatusRomLdrJumpReturned    = MAKE_STATUS(kStatusGroup_SBLoader, 10),
59     kStatusRomLdrCallFailed      = MAKE_STATUS(kStatusGroup_SBLoader, 11),
60     kStatusRomLdrKeyNotFound     = MAKE_STATUS(kStatusGroup_SBLoader, 12),
61     kStatusRomLdrSecureOnly      = MAKE_STATUS(kStatusGroup_SBLoader, 13),
62     kStatusRomLdrResetReturned   = MAKE_STATUS(kStatusGroup_SBLoader, 14),
63 
64     kStatusRomLdrRollbackBlocked        = MAKE_STATUS(kStatusGroup_SBLoader, 15),
65     kStatusRomLdrInvalidSectionMacCount = MAKE_STATUS(kStatusGroup_SBLoader, 16),
66     kStatusRomLdrUnexpectedCommand      = MAKE_STATUS(kStatusGroup_SBLoader, 17),
67     kStatusRomLdrBadSBKEK               = MAKE_STATUS(kStatusGroup_SBLoader, 18),
68     kStatusRomLdrPendingJumpCommand     = MAKE_STATUS(kStatusGroup_SBLoader, 19),
69 };
70 
71 /*!
72  * @brief Defines the number of bytes in a cipher block (chunk). This is dictated by
73  * the encryption algorithm.
74  */
75 #define BYTES_PER_CHUNK 16
76 
77 #define SB_SECTION_COUNT_MAX 8
78 
79 /*! @brief Boot image signature in 32-bit little-endian format "PMTS" */
80 #define BOOT_SIGNATURE 0x504d5453
81 
82 /*! @brief Boot image signature in 32-bit little-endian format "ltgs" */
83 #define BOOT_SIGNATURE2 0x6c746773
84 
85 /*! @brief These define file header flags */
86 #define FFLG_DISPLAY_PROGRESS 0x0001
87 
88 /*! @brief These define section header flags */
89 #define SFLG_SECTION_BOOTABLE 0x0001
90 
91 /*! @brief These define boot command flags */
92 #define CFLG_LAST_TAG 0x01
93 
94 /*! @brief ROM_ERASE_CMD flags */
95 #define ROM_ERASE_ALL_MASK          0x01
96 #define ROM_ERASE_ALL_UNSECURE_MASK 0x02
97 
98 /*! @brief ROM_JUMP_CMD flags */
99 #define ROM_JUMP_SP_MASK 0x02
100 
101 /*! @brief Memory device id shift at sb command flags */
102 #define ROM_MEM_DEVICE_ID_SHIFT 0x8
103 
104 /*! @brief Memory device id mask */
105 #define ROM_MEM_DEVICE_ID_MASK 0xff00
106 
107 /*! @brief Memory group id shift at sb command flags */
108 #define ROM_MEM_GROUP_ID_SHIFT 0x4
109 
110 /*! @brief Memory group id flags mask */
111 #define ROM_MEM_GROUP_ID_MASK 0xf0
112 
113 /*! @brief ROM_PROG_CMD flags */
114 #define ROM_PROG_8BYTE_MASK 0x01
115 
116 /*! @brief These define the boot command tags */
117 #define ROM_NOP_CMD        0x00
118 #define ROM_TAG_CMD        0x01
119 #define ROM_LOAD_CMD       0x02
120 #define ROM_FILL_CMD       0x03
121 #define ROM_JUMP_CMD       0x04
122 #define ROM_CALL_CMD       0x05
123 #define ROM_MODE_CMD       0x06
124 #define ROM_ERASE_CMD      0x07
125 #define ROM_RESET_CMD      0x08
126 #define ROM_MEM_ENABLE_CMD 0x09
127 #define ROM_PROG_CMD       0x0a
128 #define ROM_FW_VER_CHK     0x0b
129 
130 #if SB_FILE_MAJOR_VERSION == 2
131 #define SBLOADER_CMD_SET_IN_ISP_MODE (SBLOADER_V2_CMD_SET_IN_ISP_MODE)
132 #define SBLOADER_CMD_SET_IN_REC_MODE (SBLOADER_V2_CMD_SET_IN_REC_MODE)
133 #elif SB_FILE_MAJOR_VERSION == 3
134 #define SBLOADER_CMD_SET_IN_ISP_MODE (SBLOADER_V3_CMD_SET_IN_ISP_MODE)
135 #define SBLOADER_CMD_SET_IN_REC_MODE (SBLOADER_V3_CMD_SET_IN_REC_MODE)
136 #endif
137 
138 /*! @brief Plugin return codes */
139 #define ROM_BOOT_SECTION_ID 1
140 #define ROM_BOOT_IMAGE_ID   2
141 
142 enum _fw_version_check_option
143 {
144     kRomLdr_FwCheckOption_SecureVersion    = 0x0U,
145     kRomLdr_FwCheckOption_NonSecureVersion = 0x1U,
146 };
147 
148 typedef uint8_t chunk_t[BYTES_PER_CHUNK];
149 
150 /*! @brief Boot command definition */
151 typedef struct _boot_cmd
152 {
153     uint8_t checksum; /*!< 8-bit checksum over command chunk */
154     uint8_t tag;      /*!< command tag (identifier) */
155     uint16_t flags;   /*!< command flags (modifier) */
156     uint32_t address; /*!< address argument */
157     uint32_t count;   /*!< count argument */
158     uint32_t data;    /*!< data argument */
159 } boot_cmd_t;
160 
161 /*! @brief Definition for boot image file header chunk 1 */
162 typedef struct _boot_hdr1
163 {
164     uint32_t hash;       /*!< last 32-bits of SHA-1 hash */
165     uint32_t signature;  /*!< must equal "STMP" */
166     uint8_t major;       /*!< major file format version */
167     uint8_t minor;       /*!< minor file format version */
168     uint16_t fileFlags;  /*!< global file flags */
169     uint32_t fileChunks; /*!< total chunks in the file */
170 } boot_hdr1_t;
171 
172 /*! @brief Definition for boot image file header chunk 2 */
173 typedef struct _boot_hdr2
174 {
175     uint32_t bootOffset; /*!< chunk offset to the first boot section */
176     uint32_t bootSectID; /*!< section ID of the first boot section */
177     uint16_t keyCount;   /*!< number of keys in the key dictionary */
178     uint16_t keyOffset;  /*!< chunk offset to the key dictionary */
179     uint16_t hdrChunks;  /*!< number of chunks in the header */
180     uint16_t sectCount;  /*!< number of sections in the image */
181 } boot_hdr2_t;
182 
183 /*! @brief Provides forward reference to the loader context definition. */
184 typedef struct _ldr_Context ldr_Context_t;
185 
186 /*! @brief Function pointer definition for all loader action functions. */
187 typedef status_t (*pLdrFnc_t)(ldr_Context_t *);
188 
189 /*! @brief Jump command function pointer definition. */
190 typedef status_t (*pJumpFnc_t)(uint32_t);
191 
192 /*! @brief Call command function pointer definition. */
193 typedef status_t (*pCallFnc_t)(uint32_t, uint32_t *);
194 
195 /*! @brief State information for the CRC32 algorithm. */
196 typedef struct Crc32Data
197 {
198     uint32_t currentCrc;   /*!< Current CRC value. */
199     uint32_t byteCountCrc; /*!< Number of bytes processed. */
200 } crc32_data_t;
201 
202 /*! @brief Loader context definition. */
203 struct _ldr_Context
204 {
205     pLdrFnc_t Action;        /*!<  pointer to loader action function */
206     uint32_t fileChunks;     /*!<  chunks remaining in file */
207     uint32_t sectChunks;     /*!<  chunks remaining in section */
208     uint32_t bootSectChunks; /*!<  number of chunks we need to complete the boot section */
209     uint32_t receivedChunks; /*!<  number of chunks we need to complete the boot section */
210     uint16_t fileFlags;      /*!<  file header flags */
211     uint16_t keyCount;       /*!<  number of keys in the key dictionary */
212     uint32_t objectID;       /*!<  ID of the current boot section or image */
213     crc32_data_t crc32;      /*!<  crc calculated over load command payload */
214     uint8_t *src;            /*!<  source buffer address */
215     chunk_t initVector;      /*!<  decryption initialization vector */
216     chunk_t dek;             /*!<  chunk size DEK if the image is encrypted */
217     chunk_t scratchPad;      /*!<  chunk size scratch pad area */
218     boot_cmd_t bootCmd;      /*!<  current boot command */
219     uint32_t skipCount;      /*!<  Number of chunks to skip */
220     bool skipToEnd;          /*!<  true if skipping to end of file */
221 
222     // extended for SB 2.0
223     uint32_t nonce[4];
224     uint32_t keyBlobBlock;
225     uint32_t keyBlobBlockCount;
226     uint8_t *keyBlobBuffer;
227     uint32_t offsetSignatureBytes; /*!< offset to signagure block header in bytesn */
228     uint8_t *headerBuffer;
229 };
230 
231 typedef struct soc_memory_map_struct
232 {
233     struct
234     {
235         uint32_t start;
236         uint32_t end;
237     } ramRegions[RAM_REGION_COUNT];
238     struct
239     {
240         uint32_t start;
241         uint32_t end;
242     } flashRegions[FLASH_REGION_COUNT];
243     struct
244     {
245         uint32_t start;
246         uint32_t end;
247     } ffrRegions[FFR_REGION_COUNT];
248     struct
249     {
250         uint32_t start;
251         uint32_t end;
252     } flexspiNorRegions[FLEXSPINOR_REGION_COUNT];
253 } soc_mem_regions_t;
254 
255 typedef struct arena_context
256 {
257     uint32_t start;
258     uint32_t end;
259     uint32_t nextAddr;
260 } arena_context_t;
261 
262 /*! @brief Memory region information table */
263 typedef struct mem_region
264 {
265     uint32_t start;
266     uint32_t end;
267 } mem_region_t;
268 
269 /*! @brief Memory Attribute Structure */
270 typedef struct memory_attribute_struct
271 {
272     uint32_t memId;
273     uint32_t regionCount;
274     mem_region_t *memRegions;
275     void *context;
276 } mem_attribute_t;
277 
278 /*! @brief Memory context structure */
279 typedef struct memory_context_struct
280 {
281     status_t (*flush)(mem_attribute_t *attr);
282     mem_attribute_t *attr;
283 } mem_context_t;
284 
285 /*! @brief Memory region interface structure */
286 typedef struct api_memory_region_interface
287 {
288     status_t (*init)(mem_attribute_t *attr);
289 #if ROM_API_HAS_FEATURE_MEM_READ
290     status_t (*read)(mem_attribute_t *attr, uint32_t addr, uint32_t leth, uint8_t *buf);
291 #endif
292     status_t (*write)(mem_attribute_t *attr, uint32_t addr, uint32_t len, const uint8_t *buf);
293     status_t (*fill)(mem_attribute_t *attr, uint32_t addr, uint32_t len, uint32_t pattern);
294     status_t (*flush)(mem_attribute_t *attr);
295     status_t (*erase)(mem_attribute_t *attr, uint32_t addr, uint32_t len);
296     status_t (*config)(mem_attribute_t *attr, uint32_t *buf);
297     status_t (*erase_all)(mem_attribute_t *attr);
298     status_t (*alloc_ctx)(arena_context_t *ctx, mem_attribute_t *attr, void *miscParams);
299 } api_memory_region_interface_t;
300 
301 /*! @brief Memory entry data structure */
302 typedef struct memory_map_entry
303 {
304     mem_attribute_t *memoryAttribute;
305     const api_memory_region_interface_t *memoryInterface;
306 } api_memory_map_entry_t;
307 
308 /*! @brief The API context structure */
309 typedef struct api_core_context
310 {
311     soc_mem_regions_t memRegions;
312     arena_context_t arenaCtx;
313     flash_config_t flashConfig;
314     flexspi_nor_config_t flexspinorCfg;
315     mem_context_t memCtx;
316     ldr_Context_v3_t *sbloaderCtx;
317     nboot_context_t *nbootCtx;
318     uint8_t *sharedBuf;
319     api_memory_map_entry_t memEntries[MEM_INTERFACE_COUNT];
320 } api_core_context_t;
321 
322 /*******************************************************************************
323  * API
324  ******************************************************************************/
325 
326 #if defined(__cplusplus)
327 extern "C" {
328 #endif /* _cplusplus */
329 
330 /*!
331  * @brief Perform the Sbloader runtime environment initialization
332  * This API is used for initializing the sbloader state machine before calling
333  * the api_sbloader_pump. This API should be called after the iap_api_init API.
334  *
335  * @param ctx Pointer to IAP API core context structure.
336  *
337  * @retval #kStatus_Success Api was executed succesfuly.
338  */
339 status_t Sbloader_Init(api_core_context_t *ctx);
340 
341 /*!
342  * @brief Handle the SB data stream
343  * This API is used for handling the secure binary(SB3.1 format) data stream,
344  * which is used for image update, lifecycle advancing, etc.
345  * This API should be called after the iap_api_init and api_sbloader_init APIs.
346 
347  * @param ctx Pointer to IAP API core context structure.
348  * @param data Pointer to source data that is the sb file buffer data.
349  * @param length The size of the process buffer data.
350  *
351  * @retval #kStatus_Success Api was executed succesfuly.
352  * @retval #kStatus_InvalidArgument An invalid argument is provided.
353  * @retval #kStatus_Fail API execution failed.
354  */
355 status_t Sbloader_Pump(api_core_context_t *ctx, uint8_t *data, uint32_t length);
356 
357 /*!
358  * @brief Finish the sbloader handling
359  * The API is used for finalizing the sbloader operations.
360  *
361  * @param ctx Pointer to IAP API core context structure.
362  *
363  * @retval #kStatus_Success Api was executed succesfuly.
364  */
365 status_t Sbloader_Finalize(api_core_context_t *ctx);
366 
367 #if defined(__cplusplus)
368 }
369 #endif
370 
371 /*! @}*/
372 
373 #endif /* _FSL_SBLOADER_H_ */
374