1 /*
2  * Copyright 2021 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 #ifndef _FSL_MEM_INTERFACE_H_
8 #define _FSL_MEM_INTERFACE_H_
9 
10 #include "fsl_sbloader.h"
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup memory_interface
15  * @{
16  */
17 /*******************************************************************************
18  * Definitions
19  ******************************************************************************/
20 
21 /*! @brief Bit mask for device ID. */
22 #define DEVICE_ID_MASK (0xffU)
23 /*! @brief Bit position of device ID. */
24 #define DEVICE_ID_SHIFT 0U
25 /*! @brief Bit mask for group ID. */
26 #define GROUP_ID_MASK (0xf00U)
27 /*! @brief Bit position of group ID. */
28 #define GROUP_ID_SHIFT 8U
29 
30 /*! @brief Construct a memory ID from a given group ID and device ID. */
31 #define MAKE_MEMORYID(group, device) \
32     ((((group) << GROUP_ID_SHIFT) & GROUP_ID_MASK) | (((device) << DEVICE_ID_SHIFT) & DEVICE_ID_MASK))
33 /*! @brief Get group ID from a given memory ID. */
34 #define GROUPID(memoryId) (((memoryId) & GROUP_ID_MASK) >> GROUP_ID_SHIFT)
35 
36 /*! @brief Get device ID from a given memory ID. */
37 #define DEVICEID(memoryId) (((memoryId) & DEVICE_ID_MASK) >> DEVICE_ID_SHIFT)
38 
39 /*! @brief Memory group definition. */
40 enum
41 {
42     kMemoryGroup_Internal = 0U, /*!<  Memory belongs internal 4G memory region. */
43     kMemoryGroup_External = 1U, /*!<  Memory belongs external memory region. */
44 };
45 
46 /*! @brief Memory device ID definition. */
47 enum
48 {
49     /*  Memory ID bitfiled definition.
50         | 11 | 10 | 9 |    8    |  7   |  6   |  5   |  4  |  3   |  2   |  1  |  0  |
51         |  Reserved   | INT/EXT | Type                     | Sub-Type                |
52         |             | 0: INT  | INT:                     |                         |
53         |             | 1: EXT  | 0: NorFlash0             | 0: Internal Flash(FTFX) |
54         |             |         |                          | 1: QSPI                 |
55         |             |         |                          | 4: IFR                  |
56         |             |         |                          | 5: LPC FFR              |
57         |             |         |                          | 8: SEMC                 |
58         |             |         |                          | 9: FlexSPI              |
59         |             |         |                          | others: Unused          |
60         |             |         |                          |                         |
61         |             |         | 1: ExecuteOnlyRegion     | 0: Internal Flash(FTFX) |
62         |             |         |                          | others: Unused          |
63         |             |         |                          |                         |
64         |             |         | others: Unused           |                         |
65         |             |         |                          |                         |
66         |             |         | EXT:                     |                         |
67         |             |         | 0: NandFlash             | 0: SEMC                 |
68         |             |         |                          | 1: FlexSPI              |
69         |             |         |                          | others: Unused          |
70         |             |         |                          |                         |
71         |             |         | 1: NorFlash/EEPROM       | 0: LPSPI                |
72         |             |         |                          | 1: LPI2C                |
73         |             |         |                          | others: Unused          |
74         |             |         |                          |                         |
75         |             |         | 2: SD/SDHC/SDXC/MMC/eMMC | 0: uSDHC SD             |
76         |             |         |                          | 1: uSDHC MMC            |
77         |             |         |                          | others: Unused          |
78         |             |         | others: Unused           |                         |
79 
80         INT : Internal 4G memory, including internal memory modules, and XIP external memory modules.
81         EXT : Non-XIP external memory modules.
82     */
83     kMemoryInternal = MAKE_MEMORYID(kMemoryGroup_Internal, 0U), /*!< Internal memory (include all on chip memory) */
84     kMemoryQuadSpi0 = MAKE_MEMORYID(kMemoryGroup_Internal, 1U), /*!< Qsuad SPI memory 0 */
85     kMemoryIFR0 =
86         MAKE_MEMORYID(kMemoryGroup_Internal, 4U), /*!< Nonvolatile information register 0. Only used by SB loader. */
87     kMemoryFFR              = MAKE_MEMORYID(kMemoryGroup_Internal, 5U),    /*!< LPCc040hd flash FFR region. */
88     kMemorySemcNor          = MAKE_MEMORYID(kMemoryGroup_Internal, 8U),    /*!< SEMC Nor memory */
89     kMemoryFlexSpiNor       = MAKE_MEMORYID(kMemoryGroup_Internal, 9U),    /*!< Flex SPI Nor memory */
90     kMemorySpifiNor         = MAKE_MEMORYID(kMemoryGroup_Internal, 0xAU),  /*!< SPIFI Nor memory */
91     kMemoryFlashExecuteOnly = MAKE_MEMORYID(kMemoryGroup_Internal, 0x10U), /*!< Execute-only region on internal Flash */
92 
93     kMemorySemcNand     = MAKE_MEMORYID(kMemoryGroup_External, 0U),        /*!< SEMC NAND memory */
94     kMemorySpiNand      = MAKE_MEMORYID(kMemoryGroup_External, 1U),        /*!< SPI NAND memory */
95     kMemorySpiNorEeprom = MAKE_MEMORYID(kMemoryGroup_External, 0x10U),     /*!< SPI NOR/EEPROM memory */
96     kMemoryI2cNorEeprom = MAKE_MEMORYID(kMemoryGroup_External, 0x11U),     /*!< I2C NOR/EEPROM memory */
97     kMemorySDCard       = MAKE_MEMORYID(kMemoryGroup_External, 0x20U),     /*!< eSD, SD, SDHC, SDXC memory Card */
98     kMemoryMMCCard      = MAKE_MEMORYID(kMemoryGroup_External, 0x21U),     /*!< MMC, eMMC memory Card */
99 };
100 
101 /*! @brief Bootloader status group numbers.
102  *
103  * @ingroup bl_core
104  */
105 enum
106 {
107     kStatusGroup_Bootloader      = 100, /*!< Bootloader status group number (100). */
108     kStatusGroup_MemoryInterface = 102, /*!< Memory interface status group number (102). */
109 };
110 
111 /*! @brief Memory interface status codes. */
112 enum
113 {
114     kStatusMemoryRangeInvalid    = MAKE_STATUS(kStatusGroup_MemoryInterface, 0), /*!< Status: Memory Range Invalid    */
115     kStatusMemoryReadFailed      = MAKE_STATUS(kStatusGroup_MemoryInterface, 1), /*!< Status: Memory Read Failed    */
116     kStatusMemoryWriteFailed     = MAKE_STATUS(kStatusGroup_MemoryInterface, 2), /*!< Status: Memory Write Failed    */
117     kStatusMemoryCumulativeWrite = MAKE_STATUS(kStatusGroup_MemoryInterface, 3), /*!< Status: Memory Cumulative Write */
118     kStatusMemoryAppOverlapWithExecuteOnlyRegion =
119         MAKE_STATUS(kStatusGroup_MemoryInterface, 4), /*!< Status: Memory AppOverlapWithExecuteOnlyRegion */
120     kStatusMemoryNotConfigured  = MAKE_STATUS(kStatusGroup_MemoryInterface, 5), /*!< Status: Memory Not Configured */
121     kStatusMemoryAlignmentError = MAKE_STATUS(kStatusGroup_MemoryInterface, 6), /*!< Status: Memory Alignment Error */
122     kStatusMemoryVerifyFailed   = MAKE_STATUS(kStatusGroup_MemoryInterface, 7), /*!< Status: Memory Verify Failed */
123     kStatusMemoryWriteProtected = MAKE_STATUS(kStatusGroup_MemoryInterface, 8), /*!< Status: Memory Write Protected */
124     kStatusMemoryAddressError   = MAKE_STATUS(kStatusGroup_MemoryInterface, 9), /*!< Status: Memory Address Error */
125     kStatusMemoryBlankCheckFailed =
126         MAKE_STATUS(kStatusGroup_MemoryInterface, 10), /*!< Status: Memory Blank Check Failed              */
127     kStatusMemoryBlankPageReadDisallowed =
128         MAKE_STATUS(kStatusGroup_MemoryInterface, 11), /*!< Status: Memory Blank Page Read Disallowed      */
129     kStatusMemoryProtectedPageReadDisallowed =
130         MAKE_STATUS(kStatusGroup_MemoryInterface, 12), /*!< Status: Memory Protected Page Read Disallowed  */
131     kStatusMemoryFfrSpecRegionWriteBroken =
132         MAKE_STATUS(kStatusGroup_MemoryInterface, 13), /*!< Status: Memory Ffr Spec Region Write Broken    */
133     kStatusMemoryUnsupportedCommand =
134         MAKE_STATUS(kStatusGroup_MemoryInterface, 14), /*!< Status: Memory Unsupported Command             */
135 };
136 
137 /*! @brief Bootloader status codes. */
138 enum
139 {
140     kStatus_UnknownCommand     = MAKE_STATUS(kStatusGroup_Bootloader, 0), /*!< Status: Unknown Command */
141     kStatus_SecurityViolation  = MAKE_STATUS(kStatusGroup_Bootloader, 1), /*!< Status: Security Violation*/
142     kStatus_AbortDataPhase     = MAKE_STATUS(kStatusGroup_Bootloader, 2), /*!< Status: Abort Data Phase */
143     kStatus_Ping               = MAKE_STATUS(kStatusGroup_Bootloader, 3), /*!< Status: Ping */
144     kStatus_NoResponse         = MAKE_STATUS(kStatusGroup_Bootloader, 4), /*!< Status: No Response */
145     kStatus_NoResponseExpected = MAKE_STATUS(kStatusGroup_Bootloader, 5), /*!< Status: No Response Expected */
146     kStatus_CommandUnsupported = MAKE_STATUS(kStatusGroup_Bootloader, 6), /*!< Status: Command Unsupported */
147 };
148 
149 /*!
150  * @brief Interface to memory operations.
151  *
152  * This is the main abstract interface to all memory operations.
153  */
154 typedef struct
155 {
156     status_t (*init)(void);
157     status_t (*read)(uint32_t address, uint32_t length, uint8_t *buffer, uint32_t memoryId);
158     status_t (*write)(uint32_t address, uint32_t length, const uint8_t *buffer, uint32_t memoryId);
159     status_t (*fill)(uint32_t address, uint32_t length, uint32_t pattern);
160     status_t (*flush)(void);
161     status_t (*finalize)(void);
162     status_t (*erase)(uint32_t address, uint32_t length, uint32_t memoryId);
163 } memory_interface_t;
164 
165 /*! @brief Interface to memory operations for one region of memory. */
166 typedef struct
167 {
168     status_t (*init)(void);
169     status_t (*read)(uint32_t address, uint32_t length, uint8_t *buffer);
170     status_t (*write)(uint32_t address, uint32_t length, const uint8_t *buffer);
171     status_t (*fill)(uint32_t address, uint32_t length, uint32_t pattern);
172     status_t (*flush)(void);
173     status_t (*erase)(uint32_t address, uint32_t length);
174     status_t (*config)(uint32_t *buffer);
175     status_t (*erase_all)(void);
176 } memory_region_interface_t;
177 
178 //! @brief Structure of a memory map entry.
179 typedef struct
180 {
181     uint32_t startAddress;
182     uint32_t endAddress;
183     uint32_t memoryProperty;
184     uint32_t memoryId;
185     const memory_region_interface_t *memoryInterface;
186 } memory_map_entry_t;
187 
188 /*! @brief Structure of version property. */
189 typedef union StandardVersion
190 {
191     struct
192     {
193         uint8_t bugfix; /*!< bugfix version [7:0] */
194         uint8_t minor;  /*!< minor version [15:8] */
195         uint8_t major;  /*!< major version [23:16] */
196         char name;      /*!< name [31:24] */
197     };
198     uint32_t version;   /*!< combined version numbers */
199 } standard_version_t;
200 
201 /*! @brief API initialization data structure */
202 typedef struct kb_api_parameter_struct
203 {
204     uint32_t allocStart;
205     uint32_t allocSize;
206 } kp_api_init_param_t;
207 
208 #ifdef __cplusplus
209 extern "C" {
210 #endif
211 
212 /*******************************************************************************
213  * API
214  ******************************************************************************/
215 
216 standard_version_t API_Version(void);
217 
218 /*! @brief Initialize the IAP API runtime environment */
219 status_t API_Init(api_core_context_t *coreCtx, const kp_api_init_param_t *param);
220 
221 /*! @brief Deinitialize the IAP API runtime environment */
222 status_t API_Deinit(api_core_context_t *coreCtx);
223 
224 /*!
225  * @brief Initialize memory interface.
226  *
227  * @retval #kStatus_Fail
228  * @retval #kStatus_Success
229  */
230 status_t MEM_Init(api_core_context_t *coreCtx);
231 
232 /*!
233  * @brief Configure memory interface
234  *
235  * @param coreCtx A pointer to the storage for the driver runtime state.
236  * @param config memory configure struct.
237  * @param memoryId Indicates the index of the memory type. Please refer to "Memory group definition"
238 
239  * @retval #kStatus_Success
240  * @retval #kStatus_CommandUnsupported
241  * @retval #kStatus_InvalidArgument
242  * @retval #kStatus_FLASH_ModifyProtectedAreaDisallowed
243  * @retval #kStatusMemoryRangeInvalid
244  * @retval #kStatus_Fail
245  * @retval #kStatus_OutOfRange
246 */
247 status_t MEM_Config(api_core_context_t *coreCtx, uint32_t *config, uint32_t memoryId);
248 
249 /*!
250  * @brief Write memory.
251  *
252  * @param coreCtx A pointer to the storage for the driver runtime state.
253  * @param start The start address of the desired flash memory to be programmed.
254                   For internal flash the address need to be 512bytes-aligned.
255  * @param lengthInBytes Number of bytes to be programmed.
256  * @param buf A pointer to the source buffer of data that is to be programmed into the flash.
257  * @param memoryId Indicates the index of the memory type. Please refer to "Memory group definition"
258  *
259  * @retval #kStatus_Success
260  * @retval #kStatus_Fail
261  * @retval #kStatusMemoryRangeInvalid
262  * @retval #kStatus_CommandUnsupported
263  * @retval #kStatus_FLASH_AlignmentError
264  * @retval #kStatusMemoryCumulativeWrite
265  * @retval #kStatus_FLASH_InvalidArgument
266  * @retval #kStatus_FLASH_AddressError
267  * @retval #kStatus_FLASH_ModifyProtectedAreaDisallowed
268  * @retval #kStatus_FLASH_CommandFailure
269  * @retval #kStatus_FLASH_CommandNotSupported
270  * @retval #kStatus_FLASH_EccError
271  * @retval #kStatus_FLASH_RegulationLoss
272  * @retval #kStatus_FLASH_Success
273  * @retval #kStatus_FLASH_ReadHidingAreaDisallowed
274  * @retval #kStatus_FLASH_CompareError
275  * @retval #kStatusMemoryNotConfigured
276  * @retval #kStatusMemoryVerifyFailed
277  */
278 status_t MEM_Write(
279     api_core_context_t *coreCtx, uint32_t start, uint32_t lengthInBytes, const uint8_t *buf, uint32_t memoryId);
280 
281 /*!
282  * @brief Fill memory with a word pattern.
283  *
284  * @param coreCtx A pointer to the storage for the driver runtime state.
285  * @param start The start address of the desired flash memory to be programmed.
286  *                For internal flash the address need to be 512bytes-aligned.
287  * @param lengthInBytes  Number of bytes to be programmed.
288  * @param pattern The data to be written into the specified memory area.
289  * @param memoryId Indicates the index of the memory type. Please refer to "Memory group definition"
290  *
291  * @retval #kStatus_CommandUnsupported
292  * @retval #kStatus_Success
293  * @retval #kStatus_FLASH_AlignmentError
294  * @retval #kStatusMemoryCumulativeWrite
295  * @retval #kStatus_Fail
296  * @retval #kStatus_FLASH_InvalidArgument
297  * @retval #kStatus_FLASH_AddressError
298  * @retval #kStatus_FLASH_Success
299  * @retval #kStatus_FLASH_ModifyProtectedAreaDisallowed
300  * @retval #kStatus_FLASH_CommandFailure
301  * @retval #kStatus_FLASH_CommandNotSupported
302  * @retval #kStatus_FLASH_EccError
303  * @retval #kStatus_FLASH_RegulationLoss
304  * @retval #kStatus_FLASH_ReadHidingAreaDisallowed
305  */
306 status_t MEM_Fill(
307     api_core_context_t *coreCtx, uint32_t start, uint32_t lengthInBytes, uint32_t pattern, uint32_t memoryId);
308 
309 /*!
310  * @brief Flush memory.
311  *
312  * @retval #kStatus_Success
313  * @retval #kStatus_Fail
314  * @retval #kStatusMemoryCumulativeWrite
315  * @retval #kStatus_FLASH_InvalidArgument
316  * @retval #kStatus_FLASH_AlignmentError
317  * @retval #kStatus_FLASH_Success
318  * @retval #kStatus_FLASH_AddressError
319  * @retval #kStatus_FLASH_ModifyProtectedAreaDisallowed
320  * @retval #kStatus_FLASH_CommandFailure
321  * @retval #kStatus_FLASH_CommandNotSupported
322  * @retval #kStatus_FLASH_EccError
323  * @retval #kStatus_FLASH_RegulationLoss
324  * @retval #kStatus_FLASH_ReadHidingAreaDisallowed
325  * @retval #kStatusMemoryVerifyFailed
326  */
327 status_t MEM_Flush(api_core_context_t *coreCtx);
328 
329 /*!
330  * @brief Erase memory.
331  *
332  * @param coreCtx A pointer to the storage for the driver runtime state.
333  * @param start The start address of the desired flash memory to be erased.
334  * @param lengthInBytes Number of bytes to be read.
335  * @param memoryId Indicates the index of the memory type. Please refer to "Memory group definition"
336  *
337  * @retval #kStatus_Success
338  * @retval #kStatusMemoryRangeInvalid
339  * @retval #kStatusMemoryAddressError
340  * @retval #kStatus_FLASH_InvalidArgument
341  * @retval #kStatus_FLASH_AlignmentError
342  * @retval #kStatus_FLASH_Success
343  * @retval #kStatus_FLASH_AddressError
344  * @retval #kStatus_FLASH_EraseKeyError
345  * @retval #kStatus_FLASH_ModifyProtectedAreaDisallowed
346  * @retval #kStatus_Fail
347  * @retval #kStatus_FLASH_CommandFailure
348  * @retval #kStatus_FLASH_CommandNotSupported
349  * @retval #kStatus_FLASH_EccError
350  * @retval #kStatus_FLASH_RegulationLoss
351  * @retval #kStatusMemoryNotConfigured
352  * @retval #kStatusMemoryVerifyFailed
353 
354  */
355 status_t MEM_Erase(api_core_context_t *coreCtx, uint32_t start, uint32_t lengthInBytes, uint32_t memoryId);
356 
357 /*!
358  * @brief Erase entire memory based on memoryId
359  *
360  * @param coreCtx A pointer to the storage for the driver runtime state.
361  * @param memoryId Indicates the index of the memory type. Please refer to "Memory group definition"
362  *
363  * @retval #kStatus_Success
364  * @retval #kStatus_Fail
365  * @retval #kStatus_CommandUnsupported
366  * @retval #kStatus_FLASH_InvalidArgument
367  * @retval #kStatus_FLASH_AlignmentError
368  * @retval #kStatus_FLASH_Success
369  * @retval #kStatus_FLASH_AddressError
370  * @retval #kStatus_FLASH_EraseKeyError
371  * @retval #kStatus_FLASH_CommandFailure
372  * @retval #kStatus_FLASH_CommandNotSupported
373  * @retval #kStatus_FLASH_EccError
374  * @retval #kStatus_FLASH_RegulationLoss
375  * @retval #kStatus_FLASH_ModifyProtectedAreaDisallowed
376  * @retval #kStatusMemoryVerifyFailed
377  * @retval #kStatusMemoryNotConfigured
378  * @retval #kStatus_InvalidArgument
379  */
380 status_t MEM_EraseAll(api_core_context_t *coreCtx, uint32_t memoryId);
381 
382 #ifdef __cplusplus
383 }
384 #endif
385 
386 /**
387  * @}
388  */
389 
390 #endif /* _FSL_MEM_INTERFACE_H_ */
391