1 /*
2 * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2017 NXP
4 * All rights reserved.
5 *
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 */
9
10 #include "fsl_flash.h"
11
12 /*******************************************************************************
13 * Definitions
14 ******************************************************************************/
15
16 /*!
17 * @name Misc utility defines
18 * @{
19 */
20 /*! @brief Alignment utility. */
21 #ifndef ALIGN_DOWN
22 #define ALIGN_DOWN(x, a) ((x) & (uint32_t)(-((int32_t)(a))))
23 #endif
24 #ifndef ALIGN_UP
25 #define ALIGN_UP(x, a) (-((int32_t)((uint32_t)(-((int32_t)(x))) & (uint32_t)(-((int32_t)(a))))))
26 #endif
27
28 /*! @brief Join bytes to word utility. */
29 #define B1P4(b) (((uint32_t)(b)&0xFFU) << 24)
30 #define B1P3(b) (((uint32_t)(b)&0xFFU) << 16)
31 #define B1P2(b) (((uint32_t)(b)&0xFFU) << 8)
32 #define B1P1(b) ((uint32_t)(b)&0xFFU)
33 #define B2P3(b) (((uint32_t)(b)&0xFFFFU) << 16)
34 #define B2P2(b) (((uint32_t)(b)&0xFFFFU) << 8)
35 #define B2P1(b) ((uint32_t)(b)&0xFFFFU)
36 #define B3P2(b) (((uint32_t)(b)&0xFFFFFFU) << 8)
37 #define B3P1(b) ((uint32_t)(b)&0xFFFFFFU)
38 #define BYTES_JOIN_TO_WORD_1_3(x, y) (B1P4(x) | B3P1(y))
39 #define BYTES_JOIN_TO_WORD_2_2(x, y) (B2P3(x) | B2P1(y))
40 #define BYTES_JOIN_TO_WORD_3_1(x, y) (B3P2(x) | B1P1(y))
41 #define BYTES_JOIN_TO_WORD_1_1_2(x, y, z) (B1P4(x) | B1P3(y) | B2P1(z))
42 #define BYTES_JOIN_TO_WORD_1_2_1(x, y, z) (B1P4(x) | B2P2(y) | B1P1(z))
43 #define BYTES_JOIN_TO_WORD_2_1_1(x, y, z) (B2P3(x) | B1P2(y) | B1P1(z))
44 #define BYTES_JOIN_TO_WORD_1_1_1_1(x, y, z, w) (B1P4(x) | B1P3(y) | B1P2(z) | B1P1(w))
45 /*@}*/
46
47 /*!
48 * @name Secondary flash configuration
49 * @{
50 */
51 /*! @brief Indicates whether the secondary flash has its own protection register in flash module. */
52 #if defined(FSL_FEATURE_FLASH_HAS_MULTIPLE_FLASH) && defined(FTFE_FPROTS_PROTS_MASK)
53 #define FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER (1)
54 #else
55 #define FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER (0)
56 #endif
57
58 /*! @brief Indicates whether the secondary flash has its own Execute-Only access register in flash module. */
59 #if defined(FSL_FEATURE_FLASH_HAS_MULTIPLE_FLASH) && defined(FTFE_FACSSS_SGSIZE_S_MASK)
60 #define FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER (1)
61 #else
62 #define FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER (0)
63 #endif
64 /*@}*/
65
66 /*!
67 * @name Dual core/flash configuration
68 * @{
69 */
70 /*! @brief Redefines some flash features. */
71 #if defined(FSL_FEATURE_FLASH_CURRENT_CORE_ID)
72 #if (FSL_FEATURE_FLASH_CURRENT_CORE_ID == 0u)
73 #define MAIN_FLASH_FEATURE_PFLASH_START_ADDRESS FSL_FEATURE_FLASH_PFLASH_START_ADDRESS
74 #define MAIN_FLASH_FEATURE_PFLASH_BLOCK_COUNT FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT
75 #define MAIN_FLASH_FEATURE_PFLASH_BLOCK_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE
76 #define MAIN_FLASH_FEATURE_PFLASH_BLOCK_SECTOR_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE
77 #define MAIN_FLASH_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE
78 #define MAIN_FLASH_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT
79 #define MAIN_FLASH_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT
80 #define MAIN_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT
81 #define SECONDARY_FLASH_FEATURE_PFLASH_START_ADDRESS FSL_FEATURE_FLASH_PFLASH_1_START_ADDRESS
82 #define SECONDARY_FLASH_FEATURE_PFLASH_BLOCK_COUNT FSL_FEATURE_FLASH_PFLASH_1_BLOCK_COUNT
83 #define SECONDARY_FLASH_FEATURE_PFLASH_BLOCK_SIZE FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SIZE
84 #define SECONDARY_FLASH_FEATURE_PFLASH_BLOCK_SECTOR_SIZE FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SECTOR_SIZE
85 #define SECONDARY_FLASH_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE FSL_FEATURE_FLASH_PFLASH_1_BLOCK_WRITE_UNIT_SIZE
86 #define SECONDARY_FLASH_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_1_SECTOR_CMD_ADDRESS_ALIGMENT
87 #define SECONDARY_FLASH_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_1_SECTION_CMD_ADDRESS_ALIGMENT
88 #define SECONDARY_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT FSL_FEATURE_FLASH_PFLASH_1_PROTECTION_REGION_COUNT
89 #elif (FSL_FEATURE_FLASH_CURRENT_CORE_ID == 1u)
90 #define MAIN_FLASH_FEATURE_PFLASH_START_ADDRESS FSL_FEATURE_FLASH_PFLASH_1_START_ADDRESS
91 #define MAIN_FLASH_FEATURE_PFLASH_BLOCK_COUNT FSL_FEATURE_FLASH_PFLASH_1_BLOCK_COUNT
92 #define MAIN_FLASH_FEATURE_PFLASH_BLOCK_SIZE FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SIZE
93 #define MAIN_FLASH_FEATURE_PFLASH_BLOCK_SECTOR_SIZE FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SECTOR_SIZE
94 #define MAIN_FLASH_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE FSL_FEATURE_FLASH_PFLASH_1_BLOCK_WRITE_UNIT_SIZE
95 #define MAIN_FLASH_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_1_SECTOR_CMD_ADDRESS_ALIGMENT
96 #define MAIN_FLASH_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_1_SECTION_CMD_ADDRESS_ALIGMENT
97 #define MAIN_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT FSL_FEATURE_FLASH_PFLASH_1_PROTECTION_REGION_COUNT
98 #define SECONDARY_FLASH_FEATURE_PFLASH_START_ADDRESS FSL_FEATURE_FLASH_PFLASH_START_ADDRESS
99 #define SECONDARY_FLASH_FEATURE_PFLASH_BLOCK_COUNT FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT
100 #define SECONDARY_FLASH_FEATURE_PFLASH_BLOCK_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE
101 #define SECONDARY_FLASH_FEATURE_PFLASH_BLOCK_SECTOR_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE
102 #define SECONDARY_FLASH_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE
103 #define SECONDARY_FLASH_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT
104 #define SECONDARY_FLASH_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT
105 #define SECONDARY_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT
106 #endif
107 #else
108 #define MAIN_FLASH_FEATURE_PFLASH_START_ADDRESS FSL_FEATURE_FLASH_PFLASH_START_ADDRESS
109 #define MAIN_FLASH_FEATURE_PFLASH_BLOCK_COUNT FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT
110 #define MAIN_FLASH_FEATURE_PFLASH_BLOCK_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE
111 #define MAIN_FLASH_FEATURE_PFLASH_BLOCK_SECTOR_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE
112 #define MAIN_FLASH_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE
113 #define MAIN_FLASH_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT
114 #define MAIN_FLASH_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT
115 #define MAIN_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT
116 #endif
117 /*@}*/
118
119 /*!
120 * @name Flash cache and speculation control defines
121 * @{
122 */
123 #if defined(MCM_PLACR_CFCC_MASK) || defined(MCM_CPCR2_CCBC_MASK)
124 #define FLASH_CACHE_IS_CONTROLLED_BY_MCM (1)
125 #else
126 #define FLASH_CACHE_IS_CONTROLLED_BY_MCM (0)
127 #endif
128 #if defined(FMC_PFB0CR_CINV_WAY_MASK) || defined(FMC_PFB01CR_CINV_WAY_MASK)
129 #define FLASH_CACHE_IS_CONTROLLED_BY_FMC (1)
130 #else
131 #define FLASH_CACHE_IS_CONTROLLED_BY_FMC (0)
132 #endif
133 #if defined(MCM_PLACR_DFCS_MASK)
134 #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM (1)
135 #else
136 #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM (0)
137 #endif
138 #if defined(MSCM_OCMDR_OCMC1_MASK) || defined(MSCM_OCMDR_OCM1_MASK) || defined(MSCM_OCMDR0_OCM1_MASK) || \
139 defined(MSCM_OCMDR1_OCM1_MASK)
140 #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM (1)
141 #else
142 #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM (0)
143 #endif
144 #if defined(FMC_PFB0CR_S_INV_MASK) || defined(FMC_PFB0CR_S_B_INV_MASK) || defined(FMC_PFB01CR_S_INV_MASK) || \
145 defined(FMC_PFB01CR_S_B_INV_MASK)
146 #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC (1)
147 #else
148 #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC (0)
149 #endif
150
151 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM || FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC || \
152 FLASH_CACHE_IS_CONTROLLED_BY_MCM || FLASH_CACHE_IS_CONTROLLED_BY_FMC
153 #define FLASH_IS_CACHE_INVALIDATION_AVAILABLE (1)
154 #else
155 #define FLASH_IS_CACHE_INVALIDATION_AVAILABLE (0)
156 #endif
157 /*@}*/
158
159 /*! @brief Data flash IFR map Field*/
160 #if defined(FSL_FEATURE_FLASH_IS_FTFE) && FSL_FEATURE_FLASH_IS_FTFE
161 #define DFLASH_IFR_READRESOURCE_START_ADDRESS 0x8003F8U
162 #else /* FSL_FEATURE_FLASH_IS_FTFL == 1 or FSL_FEATURE_FLASH_IS_FTFA = =1 */
163 #define DFLASH_IFR_READRESOURCE_START_ADDRESS 0x8000F8U
164 #endif
165
166 /*!
167 * @name Reserved FlexNVM size (For a variety of purposes) defines
168 * @{
169 */
170 #define FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED 0xFFFFFFFFU
171 #define FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED 0xFFFFU
172 /*@}*/
173
174 /*!
175 * @name Flash Program Once Field defines
176 * @{
177 */
178 #if defined(FSL_FEATURE_FLASH_IS_FTFA) && FSL_FEATURE_FLASH_IS_FTFA
179 /* FTFA parts(eg. K80, KL80, L5K) support both 4-bytes and 8-bytes unit size */
180 #define FLASH_PROGRAM_ONCE_MIN_ID_8BYTES \
181 0x10U /* Minimum Index indcating one of Progam Once Fields which is accessed in 8-byte records */
182 #define FLASH_PROGRAM_ONCE_MAX_ID_8BYTES \
183 0x13U /* Maximum Index indcating one of Progam Once Fields which is accessed in 8-byte records */
184 #define FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT 1
185 #define FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT 1
186 #elif defined(FSL_FEATURE_FLASH_IS_FTFE) && FSL_FEATURE_FLASH_IS_FTFE
187 /* FTFE parts(eg. K65, KE18) only support 8-bytes unit size */
188 #define FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT 0
189 #define FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT 1
190 #elif defined(FSL_FEATURE_FLASH_IS_FTFL) && FSL_FEATURE_FLASH_IS_FTFL
191 /* FTFL parts(eg. K20) only support 4-bytes unit size */
192 #define FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT 1
193 #define FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT 0
194 #endif
195 /*@}*/
196
197 /*!
198 * @name Flash security status defines
199 * @{
200 */
201 #define FLASH_SECURITY_STATE_KEYEN 0x80U
202 #define FLASH_SECURITY_STATE_UNSECURED 0x02U
203 #define FLASH_NOT_SECURE 0x01U
204 #define FLASH_SECURE_BACKDOOR_ENABLED 0x02U
205 #define FLASH_SECURE_BACKDOOR_DISABLED 0x04U
206 /*@}*/
207
208 /*!
209 * @name Flash controller command numbers
210 * @{
211 */
212 #define FTFx_VERIFY_BLOCK 0x00U /*!< RD1BLK*/
213 #define FTFx_VERIFY_SECTION 0x01U /*!< RD1SEC*/
214 #define FTFx_PROGRAM_CHECK 0x02U /*!< PGMCHK*/
215 #define FTFx_READ_RESOURCE 0x03U /*!< RDRSRC*/
216 #define FTFx_PROGRAM_LONGWORD 0x06U /*!< PGM4*/
217 #define FTFx_PROGRAM_PHRASE 0x07U /*!< PGM8*/
218 #define FTFx_ERASE_BLOCK 0x08U /*!< ERSBLK*/
219 #define FTFx_ERASE_SECTOR 0x09U /*!< ERSSCR*/
220 #define FTFx_PROGRAM_SECTION 0x0BU /*!< PGMSEC*/
221 #define FTFx_GENERATE_CRC 0x0CU /*!< CRCGEN*/
222 #define FTFx_VERIFY_ALL_BLOCK 0x40U /*!< RD1ALL*/
223 #define FTFx_READ_ONCE 0x41U /*!< RDONCE or RDINDEX*/
224 #define FTFx_PROGRAM_ONCE 0x43U /*!< PGMONCE or PGMINDEX*/
225 #define FTFx_ERASE_ALL_BLOCK 0x44U /*!< ERSALL*/
226 #define FTFx_SECURITY_BY_PASS 0x45U /*!< VFYKEY*/
227 #define FTFx_SWAP_CONTROL 0x46U /*!< SWAP*/
228 #define FTFx_ERASE_ALL_BLOCK_UNSECURE 0x49U /*!< ERSALLU*/
229 #define FTFx_VERIFY_ALL_EXECUTE_ONLY_SEGMENT 0x4AU /*!< RD1XA*/
230 #define FTFx_ERASE_ALL_EXECUTE_ONLY_SEGMENT 0x4BU /*!< ERSXA*/
231 #define FTFx_PROGRAM_PARTITION 0x80U /*!< PGMPART)*/
232 #define FTFx_SET_FLEXRAM_FUNCTION 0x81U /*!< SETRAM*/
233 /*@}*/
234
235 /*!
236 * @name Common flash register info defines
237 * @{
238 */
239 #if defined(FTFA)
240 #define FTFx FTFA
241 #define FTFx_BASE FTFA_BASE
242 #define FTFx_FSTAT_CCIF_MASK FTFA_FSTAT_CCIF_MASK
243 #define FTFx_FSTAT_RDCOLERR_MASK FTFA_FSTAT_RDCOLERR_MASK
244 #define FTFx_FSTAT_ACCERR_MASK FTFA_FSTAT_ACCERR_MASK
245 #define FTFx_FSTAT_FPVIOL_MASK FTFA_FSTAT_FPVIOL_MASK
246 #define FTFx_FSTAT_MGSTAT0_MASK FTFA_FSTAT_MGSTAT0_MASK
247 #define FTFx_FSEC_SEC_MASK FTFA_FSEC_SEC_MASK
248 #define FTFx_FSEC_KEYEN_MASK FTFA_FSEC_KEYEN_MASK
249 #if defined(FSL_FEATURE_FLASH_HAS_FLEX_RAM) && FSL_FEATURE_FLASH_HAS_FLEX_RAM
250 #define FTFx_FCNFG_RAMRDY_MASK FTFA_FCNFG_RAMRDY_MASK
251 #endif /* FSL_FEATURE_FLASH_HAS_FLEX_RAM */
252 #if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM
253 #define FTFx_FCNFG_EEERDY_MASK FTFA_FCNFG_EEERDY_MASK
254 #endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */
255 #elif defined(FTFE)
256 #define FTFx FTFE
257 #define FTFx_BASE FTFE_BASE
258 #define FTFx_FSTAT_CCIF_MASK FTFE_FSTAT_CCIF_MASK
259 #define FTFx_FSTAT_RDCOLERR_MASK FTFE_FSTAT_RDCOLERR_MASK
260 #define FTFx_FSTAT_ACCERR_MASK FTFE_FSTAT_ACCERR_MASK
261 #define FTFx_FSTAT_FPVIOL_MASK FTFE_FSTAT_FPVIOL_MASK
262 #define FTFx_FSTAT_MGSTAT0_MASK FTFE_FSTAT_MGSTAT0_MASK
263 #define FTFx_FSEC_SEC_MASK FTFE_FSEC_SEC_MASK
264 #define FTFx_FSEC_KEYEN_MASK FTFE_FSEC_KEYEN_MASK
265 #if defined(FSL_FEATURE_FLASH_HAS_FLEX_RAM) && FSL_FEATURE_FLASH_HAS_FLEX_RAM
266 #define FTFx_FCNFG_RAMRDY_MASK FTFE_FCNFG_RAMRDY_MASK
267 #endif /* FSL_FEATURE_FLASH_HAS_FLEX_RAM */
268 #if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM
269 #define FTFx_FCNFG_EEERDY_MASK FTFE_FCNFG_EEERDY_MASK
270 #endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */
271 #elif defined(FTFL)
272 #define FTFx FTFL
273 #define FTFx_BASE FTFL_BASE
274 #define FTFx_FSTAT_CCIF_MASK FTFL_FSTAT_CCIF_MASK
275 #define FTFx_FSTAT_RDCOLERR_MASK FTFL_FSTAT_RDCOLERR_MASK
276 #define FTFx_FSTAT_ACCERR_MASK FTFL_FSTAT_ACCERR_MASK
277 #define FTFx_FSTAT_FPVIOL_MASK FTFL_FSTAT_FPVIOL_MASK
278 #define FTFx_FSTAT_MGSTAT0_MASK FTFL_FSTAT_MGSTAT0_MASK
279 #define FTFx_FSEC_SEC_MASK FTFL_FSEC_SEC_MASK
280 #define FTFx_FSEC_KEYEN_MASK FTFL_FSEC_KEYEN_MASK
281 #if defined(FSL_FEATURE_FLASH_HAS_FLEX_RAM) && FSL_FEATURE_FLASH_HAS_FLEX_RAM
282 #define FTFx_FCNFG_RAMRDY_MASK FTFL_FCNFG_RAMRDY_MASK
283 #endif /* FSL_FEATURE_FLASH_HAS_FLEX_RAM */
284 #if defined(FSL_FEATURE_FLASH_HAS_FLEX_NVM) && FSL_FEATURE_FLASH_HAS_FLEX_NVM
285 #define FTFx_FCNFG_EEERDY_MASK FTFL_FCNFG_EEERDY_MASK
286 #endif /* FSL_FEATURE_FLASH_HAS_FLEX_NVM */
287 #else
288 #error "Unknown flash controller"
289 #endif
290 /*@}*/
291
292 /*!
293 * @name Common flash register access info defines
294 * @{
295 */
296 #define FTFx_FCCOB3_REG (FTFx->FCCOB3)
297 #define FTFx_FCCOB5_REG (FTFx->FCCOB5)
298 #define FTFx_FCCOB6_REG (FTFx->FCCOB6)
299 #define FTFx_FCCOB7_REG (FTFx->FCCOB7)
300
301 #if defined(FTFA_FPROTH0_PROT_MASK) || defined(FTFE_FPROTH0_PROT_MASK) || defined(FTFL_FPROTH0_PROT_MASK)
302 #define FTFx_FPROT_HIGH_REG (FTFx->FPROTH3)
303 #define FTFx_FPROTH3_REG (FTFx->FPROTH3)
304 #define FTFx_FPROTH2_REG (FTFx->FPROTH2)
305 #define FTFx_FPROTH1_REG (FTFx->FPROTH1)
306 #define FTFx_FPROTH0_REG (FTFx->FPROTH0)
307 #endif
308
309 #if defined(FTFA_FPROTL0_PROT_MASK) || defined(FTFE_FPROTL0_PROT_MASK) || defined(FTFL_FPROTL0_PROT_MASK)
310 #define FTFx_FPROT_LOW_REG (FTFx->FPROTL3)
311 #define FTFx_FPROTL3_REG (FTFx->FPROTL3)
312 #define FTFx_FPROTL2_REG (FTFx->FPROTL2)
313 #define FTFx_FPROTL1_REG (FTFx->FPROTL1)
314 #define FTFx_FPROTL0_REG (FTFx->FPROTL0)
315 #elif defined(FTFA_FPROT0_PROT_MASK) || defined(FTFE_FPROT0_PROT_MASK) || defined(FTFL_FPROT0_PROT_MASK)
316 #define FTFx_FPROT_LOW_REG (FTFx->FPROT3)
317 #define FTFx_FPROTL3_REG (FTFx->FPROT3)
318 #define FTFx_FPROTL2_REG (FTFx->FPROT2)
319 #define FTFx_FPROTL1_REG (FTFx->FPROT1)
320 #define FTFx_FPROTL0_REG (FTFx->FPROT0)
321 #endif
322
323 #if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER
324 #define FTFx_FPROTSH_REG (FTFx->FPROTSH)
325 #define FTFx_FPROTSL_REG (FTFx->FPROTSL)
326 #endif
327
328 #define FTFx_XACCH3_REG (FTFx->XACCH3)
329 #define FTFx_XACCL3_REG (FTFx->XACCL3)
330
331 #if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER
332 #define FTFx_XACCSH_REG (FTFx->XACCSH)
333 #define FTFx_XACCSL_REG (FTFx->XACCSL)
334 #endif
335 /*@}*/
336
337 /*!
338 * @brief Enumeration for access segment property.
339 */
340 enum _flash_access_segment_property
341 {
342 kFLASH_AccessSegmentBase = 256UL,
343 };
344
345 /*!
346 * @brief Enumeration for flash config area.
347 */
348 enum _flash_config_area_range
349 {
350 kFLASH_ConfigAreaStart = 0x400U,
351 kFLASH_ConfigAreaEnd = 0x40FU
352 };
353
354 /*!
355 * @name Flash register access type defines
356 * @{
357 */
358 #define FTFx_REG8_ACCESS_TYPE volatile uint8_t *
359 #define FTFx_REG32_ACCESS_TYPE volatile uint32_t *
360 /*@}*/
361
362 /*!
363 * @brief MCM cache register access info defines.
364 */
365 #if defined(MCM_PLACR_CFCC_MASK)
366 #define MCM_CACHE_CLEAR_MASK MCM_PLACR_CFCC_MASK
367 #define MCM_CACHE_CLEAR_SHIFT MCM_PLACR_CFCC_SHIFT
368 #if defined(MCM0)
369 #define MCM0_CACHE_REG MCM0->PLACR
370 #elif defined(MCM) && (!defined(MCM1))
371 #define MCM0_CACHE_REG MCM->PLACR
372 #endif
373 #if defined(MCM1)
374 #define MCM1_CACHE_REG MCM1->PLACR
375 #elif defined(MCM) && (!defined(MCM0))
376 #define MCM1_CACHE_REG MCM->PLACR
377 #endif
378 #elif defined(MCM_CPCR2_CCBC_MASK)
379 #define MCM_CACHE_CLEAR_MASK MCM_CPCR2_CCBC_MASK
380 #define MCM_CACHE_CLEAR_SHIFT MCM_CPCR2_CCBC_SHIFT
381 #if defined(MCM0)
382 #define MCM0_CACHE_REG MCM0->CPCR2
383 #elif defined(MCM) && (!defined(MCM1))
384 #define MCM0_CACHE_REG MCM->CPCR2
385 #endif
386 #if defined(MCM1)
387 #define MCM1_CACHE_REG MCM1->CPCR2
388 #elif defined(MCM) && (!defined(MCM0))
389 #define MCM1_CACHE_REG MCM->CPCR2
390 #endif
391 #endif
392
393 /*!
394 * @brief Enumeration for ARM core part number.
395 */
396 enum _arm_core_part_number
397 {
398 kARM_CorePartNumber_CM0 = 0xc20U,
399 kARM_CorePartNumber_CM0P = 0xc60U,
400 kARM_CorePartNumber_CM1 = 0xc21U,
401 kARM_CorePartNumber_CM3 = 0xc23U,
402 kARM_CorePartNumber_CM4 = 0xc24U,
403 kARM_CorePartNumber_CM7 = 0xc27U,
404 kARM_CorePartNumber_CM23 = 0xd20U,
405 kARM_CorePartNumber_CM33 = 0xd21U,
406
407 kARM_CorePartNumber_Invalid = 0xFFFFU,
408 };
409
410 #if defined(BL_TARGET_ROM) && defined(MCM0_CACHE_REG) && defined(MCM1_CACHE_REG) && \
411 defined(FSL_FEATURE_FLASH_CURRENT_CORE_ID)
412 FTFx_REG32_ACCESS_TYPE const s_mcmModuleAccessTypeArray[] = {
413 (FTFx_REG32_ACCESS_TYPE)&MCM0_CACHE_REG,
414 (FTFx_REG32_ACCESS_TYPE)&MCM1_CACHE_REG
415 };
416
417 static const uint16_t s_armCorePartNumberArray[] = {
418 kARM_CorePartNumber_CM0P,
419 kARM_CorePartNumber_CM1,
420 kARM_CorePartNumber_Invalid,
421 kARM_CorePartNumber_CM3,
422 kARM_CorePartNumber_CM4,
423 kARM_CorePartNumber_Invalid,
424 kARM_CorePartNumber_Invalid,
425 kARM_CorePartNumber_CM7
426 };
427 #endif
428
429 /*!
430 * @brief MSCM cache register access info defines.
431 */
432 #if defined(MSCM_OCMDR_OCM1_MASK)
433 #define MSCM_SPECULATION_DISABLE_MASK MSCM_OCMDR_OCM1_MASK
434 #define MSCM_SPECULATION_DISABLE_SHIFT MSCM_OCMDR_OCM1_SHIFT
435 #define MSCM_SPECULATION_DISABLE(x) MSCM_OCMDR_OCM1(x)
436 #elif defined(MSCM_OCMDR0_OCM1_MASK) || defined(MSCM_OCMDR1_OCM1_MASK)
437 #define MSCM_SPECULATION_DISABLE_MASK MSCM_OCMDR0_OCM1_MASK
438 #define MSCM_SPECULATION_DISABLE_SHIFT MSCM_OCMDR0_OCM1_SHIFT
439 #define MSCM_SPECULATION_DISABLE(x) MSCM_OCMDR0_OCM1(x)
440 #elif defined(MSCM_OCMDR_OCMC1_MASK)
441 #define MSCM_SPECULATION_DISABLE_MASK MSCM_OCMDR_OCMC1_MASK
442 #define MSCM_SPECULATION_DISABLE_SHIFT MSCM_OCMDR_OCMC1_SHIFT
443 #define MSCM_SPECULATION_DISABLE(x) MSCM_OCMDR_OCMC1(x)
444 #endif
445
446 #if defined(MSCM_OCMDR_OCM1_MASK) || defined(MSCM_OCMDR_OCMC1_MASK)
447 #define MSCM_OCMDR0_REG MSCM->OCMDR[0]
448 #define MSCM_OCMDR1_REG MSCM->OCMDR[1]
449 #elif defined(MSCM_OCMDR0_OCM1_MASK) || defined(MSCM_OCMDR1_OCM1_MASK)
450 #define MSCM_OCMDR0_REG MSCM->OCMDR0
451 #define MSCM_OCMDR1_REG MSCM->OCMDR1
452 #endif
453
454 /*!
455 * @brief MSCM prefetch speculation defines.
456 */
457 #define MSCM_OCMDR_OCMC1_DFDS_MASK (0x10U)
458 #define MSCM_OCMDR_OCMC1_DFCS_MASK (0x20U)
459
460 #define MSCM_OCMDR_OCMC1_DFDS_SHIFT (4U)
461 #define MSCM_OCMDR_OCMC1_DFCS_SHIFT (5U)
462
463 /*******************************************************************************
464 * Prototypes
465 ******************************************************************************/
466
467 #if FLASH_DRIVER_IS_FLASH_RESIDENT
468 /*! @brief Copy flash_run_command() to RAM*/
469 static void copy_flash_run_command(uint32_t *flashRunCommand);
470 #if FLASH_IS_CACHE_INVALIDATION_AVAILABLE
471 /*! @brief Copy flash_cache_clear_command() to RAM*/
472 static void copy_flash_common_bit_operation(uint32_t *flashCommonBitOperation);
473 #endif
474 /*! @brief Check whether flash execute-in-ram functions are ready*/
475 static status_t flash_check_execute_in_ram_function_info(flash_config_t *config);
476 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */
477
478 /*! @brief Internal function Flash command sequence. Called by driver APIs only*/
479 static status_t flash_command_sequence(flash_config_t *config);
480
481 /*! @brief Perform the cache clear to the flash*/
482 void flash_cache_clear(flash_config_t *config);
483
484 /*! @brief Process the cache to the flash*/
485 static void flash_cache_clear_process(flash_config_t *config, flash_cache_clear_process_t process);
486
487 /*! @brief Validates the range and alignment of the given address range.*/
488 static status_t flash_check_range(flash_config_t *config,
489 uint32_t startAddress,
490 uint32_t lengthInBytes,
491 uint32_t alignmentBaseline);
492 /*! @brief Gets the right address, sector and block size of current flash type which is indicated by address.*/
493 static status_t flash_get_matched_operation_info(flash_config_t *config,
494 uint32_t address,
495 flash_operation_config_t *info);
496 /*! @brief Validates the given user key for flash erase APIs.*/
497 static status_t flash_check_user_key(uint32_t key);
498
499 #if FLASH_SSD_IS_FLEXNVM_ENABLED
500 /*! @brief Updates FlexNVM memory partition status according to data flash 0 IFR.*/
501 static status_t flash_update_flexnvm_memory_partition_status(flash_config_t *config);
502 #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */
503
504 #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD
505 /*! @brief Validates the range of the given resource address.*/
506 static status_t flash_check_resource_range(uint32_t start,
507 uint32_t lengthInBytes,
508 uint32_t alignmentBaseline,
509 flash_read_resource_option_t option);
510 #endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */
511
512 #if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD
513 /*! @brief Validates the gived swap control option.*/
514 static status_t flash_check_swap_control_option(flash_swap_control_option_t option);
515 #endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */
516
517 #if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP
518 /*! @brief Validates the gived address to see if it is equal to swap indicator address in pflash swap IFR.*/
519 static status_t flash_validate_swap_indicator_address(flash_config_t *config, uint32_t address);
520 #endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */
521
522 #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
523 /*! @brief Validates the gived flexram function option.*/
524 static inline status_t flasn_check_flexram_function_option_range(flash_flexram_function_option_t option);
525 #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
526
527 /*! @brief Gets the flash protection information (region size, region count).*/
528 static status_t flash_get_protection_info(flash_config_t *config, flash_protection_config_t *info);
529
530 #if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL
531 /*! @brief Gets the flash Execute-Only access information (Segment size, Segment count).*/
532 static status_t flash_get_access_info(flash_config_t *config, flash_access_config_t *info);
533 #endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */
534
535 #if FLASH_CACHE_IS_CONTROLLED_BY_MCM
536 /*! @brief Performs the cache clear to the flash by MCM.*/
537 void mcm_flash_cache_clear(void);
538 #endif /* FLASH_CACHE_IS_CONTROLLED_BY_MCM */
539
540 #if FLASH_CACHE_IS_CONTROLLED_BY_FMC
541 /*! @brief Performs the cache clear to the flash by FMC.*/
542 void fmc_flash_cache_clear(void);
543 #endif /* FLASH_CACHE_IS_CONTROLLED_BY_FMC */
544
545 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
546 /*! @brief Sets the prefetch speculation buffer to the flash by MSCM.*/
547 void mscm_flash_prefetch_speculation_enable(uint32_t flashIndex, bool enable);
548 #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM */
549
550 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC
551 /*! @brief Performs the prefetch speculation buffer clear to the flash by FMC.*/
552 void fmc_flash_prefetch_speculation_clear(void);
553 #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC */
554
555 /*******************************************************************************
556 * Variables
557 ******************************************************************************/
558
559 /*! @brief Access to FTFx->FCCOB */
560 volatile uint32_t *const kFCCOBx = (volatile uint32_t *)&FTFx_FCCOB3_REG;
561 /*! @brief Access to FTFx->FPROT */
562 volatile uint32_t *const kFPROTL = (volatile uint32_t *)&FTFx_FPROT_LOW_REG;
563 #if defined(FTFx_FPROT_HIGH_REG)
564 volatile uint32_t *const kFPROTH = (volatile uint32_t *)&FTFx_FPROT_HIGH_REG;
565 #endif
566
567 #if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER
568 volatile uint8_t *const kFPROTSL = (volatile uint8_t *)&FTFx_FPROTSL_REG;
569 volatile uint8_t *const kFPROTSH = (volatile uint8_t *)&FTFx_FPROTSH_REG;
570 #endif
571
572 #if FLASH_DRIVER_IS_FLASH_RESIDENT
573 /*! @brief A function pointer used to point to relocated flash_run_command() */
574 static void (*callFlashRunCommand)(FTFx_REG8_ACCESS_TYPE ftfx_fstat);
575
576 /*!
577 * @brief Position independent code of flash_run_command()
578 *
579 * Note1: The prototype of C function is shown as below:
580 * @code
581 * void flash_run_command(FTFx_REG8_ACCESS_TYPE ftfx_fstat)
582 * {
583 * // clear CCIF bit
584 * *ftfx_fstat = FTFx_FSTAT_CCIF_MASK;
585 *
586 * // Check CCIF bit of the flash status register, wait till it is set.
587 * // IP team indicates that this loop will always complete.
588 * while (!((*ftfx_fstat) & FTFx_FSTAT_CCIF_MASK))
589 * {
590 * }
591 * }
592 * @endcode
593 * Note2: The binary code is generated by IAR 7.70.1
594 */
595 #if defined(__riscv)
596 /* Build with zero riscy core configuration. */
597 static const uint16_t s_flashRunCommandFunctionCode[] = {
598 0x0793, 0xf800, /* li a5,-128 */
599 0x0023, 0x00f5, /* sb a5,0(a0) */
600 0x4783, 0x0005, /* lbu a5,0(a0) */
601 0x07e2, /* slli a5,a5,0x18 */
602 0x87e1, /* srai a5,a5,0x18 */
603 0xdce3, 0xfe07, /* bgez a5, <flash_run_command+0x8> */
604 0x8082 /* ret */
605 };
606 #else
607 static const uint16_t s_flashRunCommandFunctionCode[] = {
608 0x2180, /* MOVS R1, #128 ; 0x80 */
609 0x7001, /* STRB R1, [R0] */
610 /* @4: */
611 0x7802, /* LDRB R2, [R0] */
612 0x420a, /* TST R2, R1 */
613 0xd0fc, /* BEQ.N @4 */
614 0x4770 /* BX LR */
615 };
616 #endif
617
618 #if FLASH_IS_CACHE_INVALIDATION_AVAILABLE
619 /*! @brief A function pointer used to point to relocated flash_common_bit_operation() */
620 static void (*callFlashCommonBitOperation)(FTFx_REG32_ACCESS_TYPE base,
621 uint32_t bitMask,
622 uint32_t bitShift,
623 uint32_t bitValue);
624
625 /*!
626 * @brief Position independent code of flash_common_bit_operation()
627 *
628 * Note1: The prototype of C function is shown as below:
629 * @code
630 * void flash_common_bit_operation(FTFx_REG32_ACCESS_TYPE base, uint32_t bitMask, uint32_t bitShift, uint32_t
631 * bitValue)
632 * {
633 * if (bitMask)
634 * {
635 * uint32_t value = (((uint32_t)(((uint32_t)(bitValue)) << bitShift)) & bitMask);
636 * *base = (*base & (~bitMask)) | value;
637 * }
638 *
639 * __ISB();
640 * __DSB();
641 * }
642 * @endcode
643 * Note2: The binary code is generated by IAR 7.70.1
644 */
645 #if defined(__riscv)
646 /* Build with zero riscy core configuration. */
647 static const uint16_t s_flashCommonBitOperationFunctionCode[] = {
648 0xc981, /* beqz a1, <flash_common_bit_operation+0x10> */
649 0x411c, /* lw a5,0(a0) */
650 0x96b3, 0x00c6, /* sll a3,a3,a2 */
651 0x8ebd, /* xor a3,a3,a5 */
652 0x8df5, /* and a1,a1,a3 */
653 0x8dbd, /* xor a1,a1,a5 */
654 0xc10c, /* sw a1,0(a0) */
655 0x0001, /* nop */
656 0x0001, /* nop */
657 0x8082, /* ret */
658 };
659 #else
660 static const uint16_t s_flashCommonBitOperationFunctionCode[] = {
661 0xb510, /* PUSH {R4, LR} */
662 0x2900, /* CMP R1, #0 */
663 0xd005, /* BEQ.N @12 */
664 0x6804, /* LDR R4, [R0] */
665 0x438c, /* BICS R4, R4, R1 */
666 0x4093, /* LSLS R3, R3, R2 */
667 0x4019, /* ANDS R1, R1, R3 */
668 0x4321, /* ORRS R1, R1, R4 */
669 0x6001, /* STR R1, [R0] */
670 /* @12: */
671 0xf3bf, 0x8f6f, /* ISB */
672 0xf3bf, 0x8f4f, /* DSB */
673 0xbd10 /* POP {R4, PC} */
674 };
675 #endif
676 #endif /* FLASH_IS_CACHE_INVALIDATION_AVAILABLE */
677 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */
678
679 #if (FLASH_DRIVER_IS_FLASH_RESIDENT && !FLASH_DRIVER_IS_EXPORTED)
680 /*! @brief A static buffer used to hold flash_run_command() */
681 static uint32_t s_flashRunCommand[kFLASH_ExecuteInRamFunctionMaxSizeInWords];
682 #if FLASH_IS_CACHE_INVALIDATION_AVAILABLE
683 /*! @brief A static buffer used to hold flash_common_bit_operation() */
684 static uint32_t s_flashCommonBitOperation[kFLASH_ExecuteInRamFunctionMaxSizeInWords];
685 #endif
686 /*! @brief Flash execute-in-ram function information */
687 static flash_execute_in_ram_function_config_t s_flashExecuteInRamFunctionInfo;
688 #endif
689
690 /*!
691 * @brief Table of pflash sizes.
692 *
693 * The index into this table is the value of the SIM_FCFG1.PFSIZE bitfield.
694 *
695 * The values in this table have been right shifted 10 bits so that they will all fit within
696 * an 16-bit integer. To get the actual flash density, you must left shift the looked up value
697 * by 10 bits.
698 *
699 * Elements of this table have a value of 0 in cases where the PFSIZE bitfield value is
700 * reserved.
701 *
702 * Code to use the table:
703 * @code
704 * uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_PFSIZE_MASK) >> SIM_FCFG1_PFSIZE_SHIFT;
705 * flashDensity = ((uint32_t)kPFlashDensities[pfsize]) << 10;
706 * @endcode
707 */
708 #if defined(FSL_FEATURE_FLASH_SIZE_ENCODING_RULE_VERSION) && (FSL_FEATURE_FLASH_SIZE_ENCODING_RULE_VERSION == 1)
709 const uint16_t kPFlashDensities[] = {
710 0, /* 0x0 - undefined */
711 0, /* 0x1 - undefined */
712 0, /* 0x2 - undefined */
713 0, /* 0x3 - undefined */
714 0, /* 0x4 - undefined */
715 0, /* 0x5 - undefined */
716 0, /* 0x6 - undefined */
717 0, /* 0x7 - undefined */
718 0, /* 0x8 - undefined */
719 0, /* 0x9 - undefined */
720 256, /* 0xa - 262144, 256KB */
721 0, /* 0xb - undefined */
722 1024, /* 0xc - 1048576, 1MB */
723 0, /* 0xd - undefined */
724 0, /* 0xe - undefined */
725 0, /* 0xf - undefined */
726 };
727 #else
728 const uint16_t kPFlashDensities[] = {
729 8, /* 0x0 - 8192, 8KB */
730 16, /* 0x1 - 16384, 16KB */
731 24, /* 0x2 - 24576, 24KB */
732 32, /* 0x3 - 32768, 32KB */
733 48, /* 0x4 - 49152, 48KB */
734 64, /* 0x5 - 65536, 64KB */
735 96, /* 0x6 - 98304, 96KB */
736 128, /* 0x7 - 131072, 128KB */
737 192, /* 0x8 - 196608, 192KB */
738 256, /* 0x9 - 262144, 256KB */
739 384, /* 0xa - 393216, 384KB */
740 512, /* 0xb - 524288, 512KB */
741 768, /* 0xc - 786432, 768KB */
742 1024, /* 0xd - 1048576, 1MB */
743 1536, /* 0xe - 1572864, 1.5MB */
744 /* 2048, 0xf - 2097152, 2MB */
745 };
746 #endif
747
748 /*******************************************************************************
749 * Code
750 ******************************************************************************/
751
FLASH_Init(flash_config_t * config)752 status_t FLASH_Init(flash_config_t *config)
753 {
754 if (config == NULL)
755 {
756 return kStatus_FLASH_InvalidArgument;
757 }
758
759 #if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED
760 if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash)
761 {
762 /* calculate the flash density from SIM_FCFG1.PFSIZE */
763 #if defined(SIM_FCFG1_CORE1_PFSIZE_MASK)
764 uint32_t flashDensity;
765 uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_CORE1_PFSIZE_MASK) >> SIM_FCFG1_CORE1_PFSIZE_SHIFT;
766 if (pfsize == 0xf)
767 {
768 flashDensity = SECONDARY_FLASH_FEATURE_PFLASH_BLOCK_COUNT * SECONDARY_FLASH_FEATURE_PFLASH_BLOCK_SIZE;
769 }
770 else
771 {
772 flashDensity = ((uint32_t)kPFlashDensities[pfsize]) << 10;
773 }
774 config->PFlashTotalSize = flashDensity;
775 #else
776 /* Unused code to solve MISRA-C issue*/
777 config->PFlashBlockBase = kPFlashDensities[0];
778 config->PFlashTotalSize = SECONDARY_FLASH_FEATURE_PFLASH_BLOCK_COUNT * SECONDARY_FLASH_FEATURE_PFLASH_BLOCK_SIZE;
779 #endif
780 config->PFlashBlockBase = SECONDARY_FLASH_FEATURE_PFLASH_START_ADDRESS;
781 config->PFlashBlockCount = SECONDARY_FLASH_FEATURE_PFLASH_BLOCK_COUNT;
782 config->PFlashSectorSize = SECONDARY_FLASH_FEATURE_PFLASH_BLOCK_SECTOR_SIZE;
783 }
784 else
785 #endif /* FLASH_SSD_IS_SECONDARY_FLASH_ENABLED */
786 {
787 uint32_t flashDensity;
788
789 /* calculate the flash density from SIM_FCFG1.PFSIZE */
790 #if defined(SIM_FCFG1_CORE0_PFSIZE_MASK)
791 uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_CORE0_PFSIZE_MASK) >> SIM_FCFG1_CORE0_PFSIZE_SHIFT;
792 #elif defined(SIM_FCFG1_PFSIZE_MASK)
793 uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_PFSIZE_MASK) >> SIM_FCFG1_PFSIZE_SHIFT;
794 #else
795 #error "Unknown flash size"
796 #endif
797 /* PFSIZE=0xf means that on customer parts the IFR was not correctly programmed.
798 * We just use the pre-defined flash size in feature file here to support pre-production parts */
799 if (pfsize == 0xf)
800 {
801 flashDensity = MAIN_FLASH_FEATURE_PFLASH_BLOCK_COUNT * MAIN_FLASH_FEATURE_PFLASH_BLOCK_SIZE;
802 }
803 else
804 {
805 flashDensity = ((uint32_t)kPFlashDensities[pfsize]) << 10;
806 }
807
808 /* fill out a few of the structure members */
809 config->PFlashBlockBase = MAIN_FLASH_FEATURE_PFLASH_START_ADDRESS;
810 config->PFlashTotalSize = flashDensity;
811 config->PFlashBlockCount = MAIN_FLASH_FEATURE_PFLASH_BLOCK_COUNT;
812 config->PFlashSectorSize = MAIN_FLASH_FEATURE_PFLASH_BLOCK_SECTOR_SIZE;
813 }
814
815 {
816 #if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL
817 #if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER
818 if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash)
819 {
820 config->PFlashAccessSegmentSize = kFLASH_AccessSegmentBase << FTFx->FACSSS;
821 config->PFlashAccessSegmentCount = FTFx->FACSNS;
822 }
823 else
824 #endif
825 {
826 config->PFlashAccessSegmentSize = kFLASH_AccessSegmentBase << FTFx->FACSS;
827 config->PFlashAccessSegmentCount = FTFx->FACSN;
828 }
829 #else
830 config->PFlashAccessSegmentSize = 0;
831 config->PFlashAccessSegmentCount = 0;
832 #endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */
833 }
834
835 /* copy required flash commands to RAM */
836 #if (FLASH_DRIVER_IS_FLASH_RESIDENT && !FLASH_DRIVER_IS_EXPORTED)
837 if (kStatus_FLASH_Success != flash_check_execute_in_ram_function_info(config))
838 {
839 s_flashExecuteInRamFunctionInfo.activeFunctionCount = 0;
840 s_flashExecuteInRamFunctionInfo.flashRunCommand = s_flashRunCommand;
841 #if FLASH_IS_CACHE_INVALIDATION_AVAILABLE
842 s_flashExecuteInRamFunctionInfo.flashCommonBitOperation = s_flashCommonBitOperation;
843 #endif
844 config->flashExecuteInRamFunctionInfo = &s_flashExecuteInRamFunctionInfo.activeFunctionCount;
845 FLASH_PrepareExecuteInRamFunctions(config);
846 }
847 #endif
848
849 config->FlexRAMBlockBase = FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS;
850 config->FlexRAMTotalSize = FSL_FEATURE_FLASH_FLEX_RAM_SIZE;
851
852 #if FLASH_SSD_IS_FLEXNVM_ENABLED
853 {
854 status_t returnCode;
855 config->DFlashBlockBase = FSL_FEATURE_FLASH_FLEX_NVM_START_ADDRESS;
856 returnCode = flash_update_flexnvm_memory_partition_status(config);
857 if (returnCode != kStatus_FLASH_Success)
858 {
859 return returnCode;
860 }
861 }
862 #endif
863
864 return kStatus_FLASH_Success;
865 }
866
867 #if FLASH_DRIVER_IS_FLASH_RESIDENT
FLASH_PrepareExecuteInRamFunctions(flash_config_t * config)868 status_t FLASH_PrepareExecuteInRamFunctions(flash_config_t *config)
869 {
870 flash_execute_in_ram_function_config_t *flashExecuteInRamFunctionInfo;
871
872 if ((config == NULL) || (config->flashExecuteInRamFunctionInfo == NULL))
873 {
874 return kStatus_FLASH_InvalidArgument;
875 }
876
877 flashExecuteInRamFunctionInfo = (flash_execute_in_ram_function_config_t *)config->flashExecuteInRamFunctionInfo;
878
879 copy_flash_run_command(flashExecuteInRamFunctionInfo->flashRunCommand);
880 #if FLASH_IS_CACHE_INVALIDATION_AVAILABLE
881 copy_flash_common_bit_operation(flashExecuteInRamFunctionInfo->flashCommonBitOperation);
882 #endif
883 flashExecuteInRamFunctionInfo->activeFunctionCount = kFLASH_ExecuteInRamFunctionTotalNum;
884
885 return kStatus_FLASH_Success;
886 }
887 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */
888
FLASH_EraseAll(flash_config_t * config,uint32_t key)889 status_t FLASH_EraseAll(flash_config_t *config, uint32_t key)
890 {
891 status_t returnCode;
892
893 if (config == NULL)
894 {
895 return kStatus_FLASH_InvalidArgument;
896 }
897
898 /* preparing passing parameter to erase all flash blocks */
899 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_ALL_BLOCK, 0xFFFFFFU);
900
901 /* Validate the user key */
902 returnCode = flash_check_user_key(key);
903 if (returnCode)
904 {
905 return returnCode;
906 }
907
908 flash_cache_clear_process(config, kFLASH_CacheClearProcessPre);
909
910 /* calling flash command sequence function to execute the command */
911 returnCode = flash_command_sequence(config);
912
913 flash_cache_clear(config);
914
915 #if FLASH_SSD_IS_FLEXNVM_ENABLED
916 /* Data flash IFR will be erased by erase all command, so we need to
917 * update FlexNVM memory partition status synchronously */
918 if (returnCode == kStatus_FLASH_Success)
919 {
920 returnCode = flash_update_flexnvm_memory_partition_status(config);
921 }
922 #endif
923
924 return returnCode;
925 }
926
FLASH_Erase(flash_config_t * config,uint32_t start,uint32_t lengthInBytes,uint32_t key)927 status_t FLASH_Erase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key)
928 {
929 uint32_t sectorSize;
930 flash_operation_config_t flashOperationInfo;
931 uint32_t endAddress; /* storing end address */
932 uint32_t numberOfSectors; /* number of sectors calculated by endAddress */
933 status_t returnCode;
934
935 flash_get_matched_operation_info(config, start, &flashOperationInfo);
936
937 /* Check the supplied address range. */
938 returnCode = flash_check_range(config, start, lengthInBytes, flashOperationInfo.sectorCmdAddressAligment);
939 if (returnCode)
940 {
941 return returnCode;
942 }
943
944 /* Validate the user key */
945 returnCode = flash_check_user_key(key);
946 if (returnCode)
947 {
948 return returnCode;
949 }
950
951 start = flashOperationInfo.convertedAddress;
952 sectorSize = flashOperationInfo.activeSectorSize;
953
954 /* calculating Flash end address */
955 endAddress = start + lengthInBytes - 1;
956
957 /* re-calculate the endAddress and align it to the start of the next sector
958 * which will be used in the comparison below */
959 if (endAddress % sectorSize)
960 {
961 numberOfSectors = endAddress / sectorSize + 1;
962 endAddress = numberOfSectors * sectorSize - 1;
963 }
964
965 flash_cache_clear_process(config, kFLASH_CacheClearProcessPre);
966
967 /* the start address will increment to the next sector address
968 * until it reaches the endAdddress */
969 while (start <= endAddress)
970 {
971 /* preparing passing parameter to erase a flash block */
972 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_SECTOR, start);
973
974 /* calling flash command sequence function to execute the command */
975 returnCode = flash_command_sequence(config);
976
977 /* checking the success of command execution */
978 if (kStatus_FLASH_Success != returnCode)
979 {
980 break;
981 }
982 else
983 {
984 /* Increment to the next sector */
985 start += sectorSize;
986 }
987 }
988
989 flash_cache_clear(config);
990
991 return (returnCode);
992 }
993
994 #if defined(FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD) && FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD
FLASH_EraseAllUnsecure(flash_config_t * config,uint32_t key)995 status_t FLASH_EraseAllUnsecure(flash_config_t *config, uint32_t key)
996 {
997 status_t returnCode;
998
999 if (config == NULL)
1000 {
1001 return kStatus_FLASH_InvalidArgument;
1002 }
1003
1004 /* Prepare passing parameter to erase all flash blocks (unsecure). */
1005 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_ALL_BLOCK_UNSECURE, 0xFFFFFFU);
1006
1007 /* Validate the user key */
1008 returnCode = flash_check_user_key(key);
1009 if (returnCode)
1010 {
1011 return returnCode;
1012 }
1013
1014 flash_cache_clear_process(config, kFLASH_CacheClearProcessPre);
1015
1016 /* calling flash command sequence function to execute the command */
1017 returnCode = flash_command_sequence(config);
1018
1019 flash_cache_clear(config);
1020
1021 #if FLASH_SSD_IS_FLEXNVM_ENABLED
1022 /* Data flash IFR will be erased by erase all unsecure command, so we need to
1023 * update FlexNVM memory partition status synchronously */
1024 if (returnCode == kStatus_FLASH_Success)
1025 {
1026 returnCode = flash_update_flexnvm_memory_partition_status(config);
1027 }
1028 #endif
1029
1030 return returnCode;
1031 }
1032 #endif /* FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD */
1033
FLASH_EraseAllExecuteOnlySegments(flash_config_t * config,uint32_t key)1034 status_t FLASH_EraseAllExecuteOnlySegments(flash_config_t *config, uint32_t key)
1035 {
1036 status_t returnCode;
1037
1038 if (config == NULL)
1039 {
1040 return kStatus_FLASH_InvalidArgument;
1041 }
1042
1043 /* preparing passing parameter to erase all execute-only segments
1044 * 1st element for the FCCOB register */
1045 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_ALL_EXECUTE_ONLY_SEGMENT, 0xFFFFFFU);
1046
1047 /* Validate the user key */
1048 returnCode = flash_check_user_key(key);
1049 if (returnCode)
1050 {
1051 return returnCode;
1052 }
1053
1054 flash_cache_clear_process(config, kFLASH_CacheClearProcessPre);
1055
1056 /* calling flash command sequence function to execute the command */
1057 returnCode = flash_command_sequence(config);
1058
1059 flash_cache_clear(config);
1060
1061 return returnCode;
1062 }
1063
FLASH_Program(flash_config_t * config,uint32_t start,uint32_t * src,uint32_t lengthInBytes)1064 status_t FLASH_Program(flash_config_t *config, uint32_t start, uint32_t *src, uint32_t lengthInBytes)
1065 {
1066 status_t returnCode;
1067 flash_operation_config_t flashOperationInfo;
1068
1069 if (src == NULL)
1070 {
1071 return kStatus_FLASH_InvalidArgument;
1072 }
1073
1074 flash_get_matched_operation_info(config, start, &flashOperationInfo);
1075
1076 /* Check the supplied address range. */
1077 returnCode = flash_check_range(config, start, lengthInBytes, flashOperationInfo.blockWriteUnitSize);
1078 if (returnCode)
1079 {
1080 return returnCode;
1081 }
1082
1083 start = flashOperationInfo.convertedAddress;
1084
1085 flash_cache_clear_process(config, kFLASH_CacheClearProcessPre);
1086
1087 while (lengthInBytes > 0)
1088 {
1089 /* preparing passing parameter to program the flash block */
1090 kFCCOBx[1] = *src++;
1091 if (4 == flashOperationInfo.blockWriteUnitSize)
1092 {
1093 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_LONGWORD, start);
1094 }
1095 else if (8 == flashOperationInfo.blockWriteUnitSize)
1096 {
1097 kFCCOBx[2] = *src++;
1098 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_PHRASE, start);
1099 }
1100 else
1101 {
1102 }
1103
1104 /* calling flash command sequence function to execute the command */
1105 returnCode = flash_command_sequence(config);
1106
1107 /* checking for the success of command execution */
1108 if (kStatus_FLASH_Success != returnCode)
1109 {
1110 break;
1111 }
1112 else
1113 {
1114 /* update start address for next iteration */
1115 start += flashOperationInfo.blockWriteUnitSize;
1116
1117 /* update lengthInBytes for next iteration */
1118 lengthInBytes -= flashOperationInfo.blockWriteUnitSize;
1119 }
1120 }
1121
1122 flash_cache_clear(config);
1123
1124 return (returnCode);
1125 }
1126
FLASH_ProgramOnce(flash_config_t * config,uint32_t index,uint32_t * src,uint32_t lengthInBytes)1127 status_t FLASH_ProgramOnce(flash_config_t *config, uint32_t index, uint32_t *src, uint32_t lengthInBytes)
1128 {
1129 status_t returnCode;
1130
1131 if ((config == NULL) || (src == NULL))
1132 {
1133 return kStatus_FLASH_InvalidArgument;
1134 }
1135
1136 /* pass paramters to FTFx */
1137 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_PROGRAM_ONCE, index, 0xFFFFU);
1138
1139 kFCCOBx[1] = *src;
1140
1141 /* Note: Have to seperate the first index from the rest if it equals 0
1142 * to avoid a pointless comparison of unsigned int to 0 compiler warning */
1143 #if FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT
1144 #if FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT
1145 if (((index == FLASH_PROGRAM_ONCE_MIN_ID_8BYTES) ||
1146 /* Range check */
1147 ((index >= FLASH_PROGRAM_ONCE_MIN_ID_8BYTES + 1) && (index <= FLASH_PROGRAM_ONCE_MAX_ID_8BYTES))) &&
1148 (lengthInBytes == 8))
1149 #endif /* FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT */
1150 {
1151 kFCCOBx[2] = *(src + 1);
1152 }
1153 #endif /* FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT */
1154
1155 flash_cache_clear_process(config, kFLASH_CacheClearProcessPre);
1156
1157 /* calling flash command sequence function to execute the command */
1158 returnCode = flash_command_sequence(config);
1159
1160 flash_cache_clear(config);
1161
1162 return returnCode;
1163 }
1164
1165 #if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD
FLASH_ProgramSection(flash_config_t * config,uint32_t start,uint32_t * src,uint32_t lengthInBytes)1166 status_t FLASH_ProgramSection(flash_config_t *config, uint32_t start, uint32_t *src, uint32_t lengthInBytes)
1167 {
1168 status_t returnCode;
1169 uint32_t sectorSize;
1170 flash_operation_config_t flashOperationInfo;
1171 #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
1172 bool needSwitchFlexRamMode = false;
1173 #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
1174
1175 if (src == NULL)
1176 {
1177 return kStatus_FLASH_InvalidArgument;
1178 }
1179
1180 flash_get_matched_operation_info(config, start, &flashOperationInfo);
1181
1182 /* Check the supplied address range. */
1183 returnCode = flash_check_range(config, start, lengthInBytes, flashOperationInfo.sectionCmdAddressAligment);
1184 if (returnCode)
1185 {
1186 return returnCode;
1187 }
1188
1189 start = flashOperationInfo.convertedAddress;
1190 sectorSize = flashOperationInfo.activeSectorSize;
1191
1192 #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
1193 /* Switch function of FlexRAM if needed */
1194 if (!(FTFx->FCNFG & FTFx_FCNFG_RAMRDY_MASK))
1195 {
1196 needSwitchFlexRamMode = true;
1197
1198 returnCode = FLASH_SetFlexramFunction(config, kFLASH_FlexramFunctionOptionAvailableAsRam);
1199 if (returnCode != kStatus_FLASH_Success)
1200 {
1201 return kStatus_FLASH_SetFlexramAsRamError;
1202 }
1203 }
1204 #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
1205
1206 flash_cache_clear_process(config, kFLASH_CacheClearProcessPre);
1207
1208 while (lengthInBytes > 0)
1209 {
1210 /* Make sure the write operation doesn't span two sectors */
1211 uint32_t endAddressOfCurrentSector = ALIGN_UP(start, sectorSize);
1212 uint32_t lengthTobeProgrammedOfCurrentSector;
1213 uint32_t currentOffset = 0;
1214
1215 if (endAddressOfCurrentSector == start)
1216 {
1217 endAddressOfCurrentSector += sectorSize;
1218 }
1219
1220 if (lengthInBytes + start > endAddressOfCurrentSector)
1221 {
1222 lengthTobeProgrammedOfCurrentSector = endAddressOfCurrentSector - start;
1223 }
1224 else
1225 {
1226 lengthTobeProgrammedOfCurrentSector = lengthInBytes;
1227 }
1228
1229 /* Program Current Sector */
1230 while (lengthTobeProgrammedOfCurrentSector > 0)
1231 {
1232 /* Make sure the program size doesn't exceeds Acceleration RAM size */
1233 uint32_t programSizeOfCurrentPass;
1234 uint32_t numberOfPhases;
1235
1236 if (lengthTobeProgrammedOfCurrentSector > kFLASH_AccelerationRamSize)
1237 {
1238 programSizeOfCurrentPass = kFLASH_AccelerationRamSize;
1239 }
1240 else
1241 {
1242 programSizeOfCurrentPass = lengthTobeProgrammedOfCurrentSector;
1243 }
1244
1245 /* Copy data to FlexRAM */
1246 memcpy((void *)FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS, src + currentOffset / 4, programSizeOfCurrentPass);
1247 /* Set start address of the data to be programmed */
1248 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_SECTION, start + currentOffset);
1249 /* Set program size in terms of FEATURE_FLASH_SECTION_CMD_ADDRESS_ALIGMENT */
1250 numberOfPhases = programSizeOfCurrentPass / flashOperationInfo.sectionCmdAddressAligment;
1251
1252 kFCCOBx[1] = BYTES_JOIN_TO_WORD_2_2(numberOfPhases, 0xFFFFU);
1253
1254 /* Peform command sequence */
1255 returnCode = flash_command_sequence(config);
1256
1257 if (returnCode != kStatus_FLASH_Success)
1258 {
1259 flash_cache_clear(config);
1260 return returnCode;
1261 }
1262
1263 lengthTobeProgrammedOfCurrentSector -= programSizeOfCurrentPass;
1264 currentOffset += programSizeOfCurrentPass;
1265 }
1266
1267 src += currentOffset / 4;
1268 start += currentOffset;
1269 lengthInBytes -= currentOffset;
1270 }
1271
1272 flash_cache_clear(config);
1273
1274 #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
1275 /* Restore function of FlexRAM if needed. */
1276 if (needSwitchFlexRamMode)
1277 {
1278 returnCode = FLASH_SetFlexramFunction(config, kFLASH_FlexramFunctionOptionAvailableForEeprom);
1279 if (returnCode != kStatus_FLASH_Success)
1280 {
1281 return kStatus_FLASH_RecoverFlexramAsEepromError;
1282 }
1283 }
1284 #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
1285
1286 return returnCode;
1287 }
1288 #endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD */
1289
1290 #if FLASH_SSD_IS_FLEXNVM_ENABLED
FLASH_EepromWrite(flash_config_t * config,uint32_t start,uint8_t * src,uint32_t lengthInBytes)1291 status_t FLASH_EepromWrite(flash_config_t *config, uint32_t start, uint8_t *src, uint32_t lengthInBytes)
1292 {
1293 status_t returnCode;
1294 bool needSwitchFlexRamMode = false;
1295
1296 if (config == NULL)
1297 {
1298 return kStatus_FLASH_InvalidArgument;
1299 }
1300
1301 /* Validates the range of the given address */
1302 if ((start < config->FlexRAMBlockBase) ||
1303 ((start + lengthInBytes) > (config->FlexRAMBlockBase + config->EEpromTotalSize)))
1304 {
1305 return kStatus_FLASH_AddressError;
1306 }
1307
1308 returnCode = kStatus_FLASH_Success;
1309
1310 /* Switch function of FlexRAM if needed */
1311 if (!(FTFx->FCNFG & FTFx_FCNFG_EEERDY_MASK))
1312 {
1313 needSwitchFlexRamMode = true;
1314
1315 returnCode = FLASH_SetFlexramFunction(config, kFLASH_FlexramFunctionOptionAvailableForEeprom);
1316 if (returnCode != kStatus_FLASH_Success)
1317 {
1318 return kStatus_FLASH_SetFlexramAsEepromError;
1319 }
1320 }
1321
1322 /* Write data to FlexRAM when it is used as EEPROM emulator */
1323 while (lengthInBytes > 0)
1324 {
1325 if ((!(start & 0x3U)) && (lengthInBytes >= 4))
1326 {
1327 *(uint32_t *)start = *(uint32_t *)src;
1328 start += 4;
1329 src += 4;
1330 lengthInBytes -= 4;
1331 }
1332 else if ((!(start & 0x1U)) && (lengthInBytes >= 2))
1333 {
1334 *(uint16_t *)start = *(uint16_t *)src;
1335 start += 2;
1336 src += 2;
1337 lengthInBytes -= 2;
1338 }
1339 else
1340 {
1341 *(uint8_t *)start = *src;
1342 start += 1;
1343 src += 1;
1344 lengthInBytes -= 1;
1345 }
1346 /* Wait till EEERDY bit is set */
1347 while (!(FTFx->FCNFG & FTFx_FCNFG_EEERDY_MASK))
1348 {
1349 }
1350
1351 /* Check for protection violation error */
1352 if (FTFx->FSTAT & FTFx_FSTAT_FPVIOL_MASK)
1353 {
1354 return kStatus_FLASH_ProtectionViolation;
1355 }
1356 }
1357
1358 /* Switch function of FlexRAM if needed */
1359 if (needSwitchFlexRamMode)
1360 {
1361 returnCode = FLASH_SetFlexramFunction(config, kFLASH_FlexramFunctionOptionAvailableAsRam);
1362 if (returnCode != kStatus_FLASH_Success)
1363 {
1364 return kStatus_FLASH_RecoverFlexramAsRamError;
1365 }
1366 }
1367
1368 return returnCode;
1369 }
1370 #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */
1371
1372 #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD
FLASH_ReadResource(flash_config_t * config,uint32_t start,uint32_t * dst,uint32_t lengthInBytes,flash_read_resource_option_t option)1373 status_t FLASH_ReadResource(
1374 flash_config_t *config, uint32_t start, uint32_t *dst, uint32_t lengthInBytes, flash_read_resource_option_t option)
1375 {
1376 status_t returnCode;
1377 flash_operation_config_t flashOperationInfo;
1378
1379 if ((config == NULL) || (dst == NULL))
1380 {
1381 return kStatus_FLASH_InvalidArgument;
1382 }
1383
1384 flash_get_matched_operation_info(config, start, &flashOperationInfo);
1385
1386 /* Check the supplied address range. */
1387 returnCode =
1388 flash_check_resource_range(start, lengthInBytes, flashOperationInfo.resourceCmdAddressAligment, option);
1389 if (returnCode != kStatus_FLASH_Success)
1390 {
1391 return returnCode;
1392 }
1393
1394 while (lengthInBytes > 0)
1395 {
1396 /* preparing passing parameter */
1397 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_READ_RESOURCE, start);
1398 if (flashOperationInfo.resourceCmdAddressAligment == 4)
1399 {
1400 kFCCOBx[2] = BYTES_JOIN_TO_WORD_1_3(option, 0xFFFFFFU);
1401 }
1402 else if (flashOperationInfo.resourceCmdAddressAligment == 8)
1403 {
1404 kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_3(option, 0xFFFFFFU);
1405 }
1406 else
1407 {
1408 }
1409
1410 /* calling flash command sequence function to execute the command */
1411 returnCode = flash_command_sequence(config);
1412
1413 if (kStatus_FLASH_Success != returnCode)
1414 {
1415 break;
1416 }
1417
1418 /* fetch data */
1419 *dst++ = kFCCOBx[1];
1420 if (flashOperationInfo.resourceCmdAddressAligment == 8)
1421 {
1422 *dst++ = kFCCOBx[2];
1423 }
1424 /* update start address for next iteration */
1425 start += flashOperationInfo.resourceCmdAddressAligment;
1426 /* update lengthInBytes for next iteration */
1427 lengthInBytes -= flashOperationInfo.resourceCmdAddressAligment;
1428 }
1429
1430 return (returnCode);
1431 }
1432 #endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */
1433
FLASH_ReadOnce(flash_config_t * config,uint32_t index,uint32_t * dst,uint32_t lengthInBytes)1434 status_t FLASH_ReadOnce(flash_config_t *config, uint32_t index, uint32_t *dst, uint32_t lengthInBytes)
1435 {
1436 status_t returnCode;
1437
1438 if ((config == NULL) || (dst == NULL))
1439 {
1440 return kStatus_FLASH_InvalidArgument;
1441 }
1442
1443 /* pass paramters to FTFx */
1444 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_READ_ONCE, index, 0xFFFFU);
1445
1446 /* calling flash command sequence function to execute the command */
1447 returnCode = flash_command_sequence(config);
1448
1449 if (kStatus_FLASH_Success == returnCode)
1450 {
1451 *dst = kFCCOBx[1];
1452 /* Note: Have to seperate the first index from the rest if it equals 0
1453 * to avoid a pointless comparison of unsigned int to 0 compiler warning */
1454 #if FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT
1455 #if FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT
1456 if (((index == FLASH_PROGRAM_ONCE_MIN_ID_8BYTES) ||
1457 /* Range check */
1458 ((index >= FLASH_PROGRAM_ONCE_MIN_ID_8BYTES + 1) && (index <= FLASH_PROGRAM_ONCE_MAX_ID_8BYTES))) &&
1459 (lengthInBytes == 8))
1460 #endif /* FLASH_PROGRAM_ONCE_IS_4BYTES_UNIT_SUPPORT */
1461 {
1462 *(dst + 1) = kFCCOBx[2];
1463 }
1464 #endif /* FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT */
1465 }
1466
1467 return returnCode;
1468 }
1469
FLASH_GetSecurityState(flash_config_t * config,flash_security_state_t * state)1470 status_t FLASH_GetSecurityState(flash_config_t *config, flash_security_state_t *state)
1471 {
1472 /* store data read from flash register */
1473 uint8_t registerValue;
1474
1475 if ((config == NULL) || (state == NULL))
1476 {
1477 return kStatus_FLASH_InvalidArgument;
1478 }
1479
1480 /* Get flash security register value */
1481 registerValue = FTFx->FSEC;
1482
1483 /* check the status of the flash security bits in the security register */
1484 if (FLASH_SECURITY_STATE_UNSECURED == (registerValue & FTFx_FSEC_SEC_MASK))
1485 {
1486 /* Flash in unsecured state */
1487 *state = kFLASH_SecurityStateNotSecure;
1488 }
1489 else
1490 {
1491 /* Flash in secured state
1492 * check for backdoor key security enable bit */
1493 if (FLASH_SECURITY_STATE_KEYEN == (registerValue & FTFx_FSEC_KEYEN_MASK))
1494 {
1495 /* Backdoor key security enabled */
1496 *state = kFLASH_SecurityStateBackdoorEnabled;
1497 }
1498 else
1499 {
1500 /* Backdoor key security disabled */
1501 *state = kFLASH_SecurityStateBackdoorDisabled;
1502 }
1503 }
1504
1505 return (kStatus_FLASH_Success);
1506 }
1507
FLASH_SecurityBypass(flash_config_t * config,const uint8_t * backdoorKey)1508 status_t FLASH_SecurityBypass(flash_config_t *config, const uint8_t *backdoorKey)
1509 {
1510 uint8_t registerValue; /* registerValue */
1511 status_t returnCode; /* return code variable */
1512
1513 if ((config == NULL) || (backdoorKey == NULL))
1514 {
1515 return kStatus_FLASH_InvalidArgument;
1516 }
1517
1518 /* set the default return code as kStatus_Success */
1519 returnCode = kStatus_FLASH_Success;
1520
1521 /* Get flash security register value */
1522 registerValue = FTFx->FSEC;
1523
1524 /* Check to see if flash is in secure state (any state other than 0x2)
1525 * If not, then skip this since flash is not secure */
1526 if (0x02 != (registerValue & 0x03))
1527 {
1528 /* preparing passing parameter to erase a flash block */
1529 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_SECURITY_BY_PASS, 0xFFFFFFU);
1530 kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_1_1_1(backdoorKey[0], backdoorKey[1], backdoorKey[2], backdoorKey[3]);
1531 kFCCOBx[2] = BYTES_JOIN_TO_WORD_1_1_1_1(backdoorKey[4], backdoorKey[5], backdoorKey[6], backdoorKey[7]);
1532
1533 /* calling flash command sequence function to execute the command */
1534 returnCode = flash_command_sequence(config);
1535 }
1536
1537 return (returnCode);
1538 }
1539
FLASH_VerifyEraseAll(flash_config_t * config,flash_margin_value_t margin)1540 status_t FLASH_VerifyEraseAll(flash_config_t *config, flash_margin_value_t margin)
1541 {
1542 if (config == NULL)
1543 {
1544 return kStatus_FLASH_InvalidArgument;
1545 }
1546
1547 /* preparing passing parameter to verify all block command */
1548 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_VERIFY_ALL_BLOCK, margin, 0xFFFFU);
1549
1550 /* calling flash command sequence function to execute the command */
1551 return flash_command_sequence(config);
1552 }
1553
FLASH_VerifyErase(flash_config_t * config,uint32_t start,uint32_t lengthInBytes,flash_margin_value_t margin)1554 status_t FLASH_VerifyErase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, flash_margin_value_t margin)
1555 {
1556 /* Check arguments. */
1557 uint32_t blockSize;
1558 flash_operation_config_t flashOperationInfo;
1559 uint32_t nextBlockStartAddress;
1560 uint32_t remainingBytes;
1561 status_t returnCode;
1562
1563 flash_get_matched_operation_info(config, start, &flashOperationInfo);
1564
1565 returnCode = flash_check_range(config, start, lengthInBytes, flashOperationInfo.sectionCmdAddressAligment);
1566 if (returnCode)
1567 {
1568 return returnCode;
1569 }
1570
1571 flash_get_matched_operation_info(config, start, &flashOperationInfo);
1572 start = flashOperationInfo.convertedAddress;
1573 blockSize = flashOperationInfo.activeBlockSize;
1574
1575 nextBlockStartAddress = ALIGN_UP(start, blockSize);
1576 if (nextBlockStartAddress == start)
1577 {
1578 nextBlockStartAddress += blockSize;
1579 }
1580
1581 remainingBytes = lengthInBytes;
1582
1583 while (remainingBytes)
1584 {
1585 uint32_t numberOfPhrases;
1586 uint32_t verifyLength = nextBlockStartAddress - start;
1587 if (verifyLength > remainingBytes)
1588 {
1589 verifyLength = remainingBytes;
1590 }
1591
1592 numberOfPhrases = verifyLength / flashOperationInfo.sectionCmdAddressAligment;
1593
1594 /* Fill in verify section command parameters. */
1595 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_VERIFY_SECTION, start);
1596 kFCCOBx[1] = BYTES_JOIN_TO_WORD_2_1_1(numberOfPhrases, margin, 0xFFU);
1597
1598 /* calling flash command sequence function to execute the command */
1599 returnCode = flash_command_sequence(config);
1600 if (returnCode)
1601 {
1602 return returnCode;
1603 }
1604
1605 remainingBytes -= verifyLength;
1606 start += verifyLength;
1607 nextBlockStartAddress += blockSize;
1608 }
1609
1610 return kStatus_FLASH_Success;
1611 }
1612
FLASH_VerifyProgram(flash_config_t * config,uint32_t start,uint32_t lengthInBytes,const uint32_t * expectedData,flash_margin_value_t margin,uint32_t * failedAddress,uint32_t * failedData)1613 status_t FLASH_VerifyProgram(flash_config_t *config,
1614 uint32_t start,
1615 uint32_t lengthInBytes,
1616 const uint32_t *expectedData,
1617 flash_margin_value_t margin,
1618 uint32_t *failedAddress,
1619 uint32_t *failedData)
1620 {
1621 status_t returnCode;
1622 flash_operation_config_t flashOperationInfo;
1623
1624 if (expectedData == NULL)
1625 {
1626 return kStatus_FLASH_InvalidArgument;
1627 }
1628
1629 flash_get_matched_operation_info(config, start, &flashOperationInfo);
1630
1631 returnCode = flash_check_range(config, start, lengthInBytes, flashOperationInfo.checkCmdAddressAligment);
1632 if (returnCode)
1633 {
1634 return returnCode;
1635 }
1636
1637 start = flashOperationInfo.convertedAddress;
1638
1639 while (lengthInBytes)
1640 {
1641 /* preparing passing parameter to program check the flash block */
1642 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_CHECK, start);
1643 kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_3(margin, 0xFFFFFFU);
1644 kFCCOBx[2] = *expectedData;
1645
1646 /* calling flash command sequence function to execute the command */
1647 returnCode = flash_command_sequence(config);
1648
1649 /* checking for the success of command execution */
1650 if (kStatus_FLASH_Success != returnCode)
1651 {
1652 if (failedAddress)
1653 {
1654 *failedAddress = start;
1655 }
1656 if (failedData)
1657 {
1658 *failedData = 0;
1659 }
1660 break;
1661 }
1662
1663 lengthInBytes -= flashOperationInfo.checkCmdAddressAligment;
1664 expectedData += flashOperationInfo.checkCmdAddressAligment / sizeof(*expectedData);
1665 start += flashOperationInfo.checkCmdAddressAligment;
1666 }
1667
1668 return (returnCode);
1669 }
1670
FLASH_VerifyEraseAllExecuteOnlySegments(flash_config_t * config,flash_margin_value_t margin)1671 status_t FLASH_VerifyEraseAllExecuteOnlySegments(flash_config_t *config, flash_margin_value_t margin)
1672 {
1673 if (config == NULL)
1674 {
1675 return kStatus_FLASH_InvalidArgument;
1676 }
1677
1678 /* preparing passing parameter to verify erase all execute-only segments command */
1679 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_VERIFY_ALL_EXECUTE_ONLY_SEGMENT, margin, 0xFFFFU);
1680
1681 /* calling flash command sequence function to execute the command */
1682 return flash_command_sequence(config);
1683 }
1684
FLASH_IsProtected(flash_config_t * config,uint32_t start,uint32_t lengthInBytes,flash_protection_state_t * protection_state)1685 status_t FLASH_IsProtected(flash_config_t *config,
1686 uint32_t start,
1687 uint32_t lengthInBytes,
1688 flash_protection_state_t *protection_state)
1689 {
1690 uint32_t endAddress; /* end address for protection check */
1691 uint32_t regionCheckedCounter; /* increments each time the flash address was checked for
1692 * protection status */
1693 uint32_t regionCounter; /* incrementing variable used to increment through the flash
1694 * protection regions */
1695 uint32_t protectStatusCounter; /* increments each time a flash region was detected as protected */
1696
1697 uint8_t flashRegionProtectStatus[MAIN_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT]; /* array of the protection
1698 * status for each
1699 * protection region */
1700 uint32_t flashRegionAddress[MAIN_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT +
1701 1]; /* array of the start addresses for each flash
1702 * protection region. Note this is REGION_COUNT+1
1703 * due to requiring the next start address after
1704 * the end of flash for loop-check purposes below */
1705 flash_protection_config_t flashProtectionInfo; /* flash protection information */
1706 status_t returnCode;
1707
1708 if (protection_state == NULL)
1709 {
1710 return kStatus_FLASH_InvalidArgument;
1711 }
1712
1713 /* Check the supplied address range. */
1714 returnCode = flash_check_range(config, start, lengthInBytes, MAIN_FLASH_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE);
1715 if (returnCode)
1716 {
1717 return returnCode;
1718 }
1719
1720 /* Get necessary flash protection information. */
1721 returnCode = flash_get_protection_info(config, &flashProtectionInfo);
1722 if (returnCode)
1723 {
1724 return returnCode;
1725 }
1726
1727 /* calculating Flash end address */
1728 endAddress = start + lengthInBytes;
1729
1730 /* populate the flashRegionAddress array with the start address of each flash region */
1731 regionCounter = 0; /* make sure regionCounter is initialized to 0 first */
1732
1733 /* populate up to 33rd element of array, this is the next address after end of flash array */
1734 while (regionCounter <= flashProtectionInfo.regionCount)
1735 {
1736 flashRegionAddress[regionCounter] =
1737 flashProtectionInfo.regionBase + flashProtectionInfo.regionSize * regionCounter;
1738 regionCounter++;
1739 }
1740
1741 /* populate flashRegionProtectStatus array with status information
1742 * Protection status for each region is stored in the FPROT[3:0] registers
1743 * Each bit represents one region of flash
1744 * 4 registers * 8-bits-per-register = 32-bits (32-regions)
1745 * The convention is:
1746 * FPROT3[bit 0] is the first protection region (start of flash memory)
1747 * FPROT0[bit 7] is the last protection region (end of flash memory)
1748 * regionCounter is used to determine which FPROT[3:0] register to check for protection status
1749 * Note: FPROT=1 means NOT protected, FPROT=0 means protected */
1750 regionCounter = 0; /* make sure regionCounter is initialized to 0 first */
1751 while (regionCounter < flashProtectionInfo.regionCount)
1752 {
1753 #if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER
1754 if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash)
1755 {
1756 if (regionCounter < 8)
1757 {
1758 flashRegionProtectStatus[regionCounter] = (FTFx_FPROTSL_REG >> regionCounter) & (0x01u);
1759 }
1760 else if ((regionCounter >= 8) && (regionCounter < 16))
1761 {
1762 flashRegionProtectStatus[regionCounter] = (FTFx_FPROTSH_REG >> (regionCounter - 8)) & (0x01u);
1763 }
1764 else
1765 {
1766 break;
1767 }
1768 }
1769 else
1770 #endif
1771 {
1772 /* Note: So far protection region count may be 16/20/24/32/64 */
1773 if (regionCounter < 8)
1774 {
1775 flashRegionProtectStatus[regionCounter] = (FTFx_FPROTL3_REG >> regionCounter) & (0x01u);
1776 }
1777 else if ((regionCounter >= 8) && (regionCounter < 16))
1778 {
1779 flashRegionProtectStatus[regionCounter] = (FTFx_FPROTL2_REG >> (regionCounter - 8)) & (0x01u);
1780 }
1781 #if defined(MAIN_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT) && (MAIN_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT > 16)
1782 #if (MAIN_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT == 20)
1783 else if ((regionCounter >= 16) && (regionCounter < 20))
1784 {
1785 flashRegionProtectStatus[regionCounter] = (FTFx_FPROTL1_REG >> (regionCounter - 16)) & (0x01u);
1786 }
1787 #else
1788 else if ((regionCounter >= 16) && (regionCounter < 24))
1789 {
1790 flashRegionProtectStatus[regionCounter] = (FTFx_FPROTL1_REG >> (regionCounter - 16)) & (0x01u);
1791 }
1792 #endif /* (MAIN_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT == 20) */
1793 #endif
1794 #if defined(MAIN_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT) && (MAIN_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT > 24)
1795 else if ((regionCounter >= 24) && (regionCounter < 32))
1796 {
1797 flashRegionProtectStatus[regionCounter] = (FTFx_FPROTL0_REG >> (regionCounter - 24)) & (0x01u);
1798 }
1799 #endif
1800 #if defined(MAIN_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT) && \
1801 (MAIN_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT == 64)
1802 else if (regionCounter < 40)
1803 {
1804 flashRegionProtectStatus[regionCounter] = (FTFx_FPROTH3_REG >> (regionCounter - 32)) & (0x01u);
1805 }
1806 else if (regionCounter < 48)
1807 {
1808 flashRegionProtectStatus[regionCounter] = (FTFx_FPROTH2_REG >> (regionCounter - 40)) & (0x01u);
1809 }
1810 else if (regionCounter < 56)
1811 {
1812 flashRegionProtectStatus[regionCounter] = (FTFx_FPROTH1_REG >> (regionCounter - 48)) & (0x01u);
1813 }
1814 else if (regionCounter < 64)
1815 {
1816 flashRegionProtectStatus[regionCounter] = (FTFx_FPROTH0_REG >> (regionCounter - 56)) & (0x01u);
1817 }
1818 #endif
1819 else
1820 {
1821 break;
1822 }
1823 }
1824
1825 regionCounter++;
1826 }
1827
1828 /* loop through the flash regions and check
1829 * desired flash address range for protection status
1830 * loop stops when it is detected that start has exceeded the endAddress */
1831 regionCounter = 0; /* make sure regionCounter is initialized to 0 first */
1832 regionCheckedCounter = 0;
1833 protectStatusCounter = 0; /* make sure protectStatusCounter is initialized to 0 first */
1834 while (start < endAddress)
1835 {
1836 /* check to see if the address falls within this protection region
1837 * Note that if the entire flash is to be checked, the last protection
1838 * region checked would consist of the last protection start address and
1839 * the start address following the end of flash */
1840 if ((start >= flashRegionAddress[regionCounter]) && (start < flashRegionAddress[regionCounter + 1]))
1841 {
1842 /* increment regionCheckedCounter to indicate this region was checked */
1843 regionCheckedCounter++;
1844
1845 /* check the protection status of this region
1846 * Note: FPROT=1 means NOT protected, FPROT=0 means protected */
1847 if (!flashRegionProtectStatus[regionCounter])
1848 {
1849 /* increment protectStatusCounter to indicate this region is protected */
1850 protectStatusCounter++;
1851 }
1852 start += flashProtectionInfo.regionSize; /* increment to an address within the next region */
1853 }
1854 regionCounter++; /* increment regionCounter to check for the next flash protection region */
1855 }
1856
1857 /* if protectStatusCounter == 0, then no region of the desired flash region is protected */
1858 if (protectStatusCounter == 0)
1859 {
1860 *protection_state = kFLASH_ProtectionStateUnprotected;
1861 }
1862 /* if protectStatusCounter == regionCheckedCounter, then each region checked was protected */
1863 else if (protectStatusCounter == regionCheckedCounter)
1864 {
1865 *protection_state = kFLASH_ProtectionStateProtected;
1866 }
1867 /* if protectStatusCounter != regionCheckedCounter, then protection status is mixed
1868 * In other words, some regions are protected while others are unprotected */
1869 else
1870 {
1871 *protection_state = kFLASH_ProtectionStateMixed;
1872 }
1873
1874 return (returnCode);
1875 }
1876
FLASH_IsExecuteOnly(flash_config_t * config,uint32_t start,uint32_t lengthInBytes,flash_execute_only_access_state_t * access_state)1877 status_t FLASH_IsExecuteOnly(flash_config_t *config,
1878 uint32_t start,
1879 uint32_t lengthInBytes,
1880 flash_execute_only_access_state_t *access_state)
1881 {
1882 #if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL
1883 flash_access_config_t flashAccessInfo; /* flash Execute-Only information */
1884 #endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */
1885 status_t returnCode;
1886
1887 if (access_state == NULL)
1888 {
1889 return kStatus_FLASH_InvalidArgument;
1890 }
1891
1892 /* Check the supplied address range. */
1893 returnCode = flash_check_range(config, start, lengthInBytes, MAIN_FLASH_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE);
1894 if (returnCode)
1895 {
1896 return returnCode;
1897 }
1898
1899 #if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL
1900 /* Get necessary flash Execute-Only information. */
1901 returnCode = flash_get_access_info(config, &flashAccessInfo);
1902 if (returnCode)
1903 {
1904 return returnCode;
1905 }
1906
1907 {
1908 uint32_t executeOnlySegmentCounter = 0;
1909
1910 /* calculating end address */
1911 uint32_t endAddress = start + lengthInBytes;
1912
1913 /* Aligning start address and end address */
1914 uint32_t alignedStartAddress = ALIGN_DOWN(start, flashAccessInfo.SegmentSize);
1915 uint32_t alignedEndAddress = ALIGN_UP(endAddress, flashAccessInfo.SegmentSize);
1916
1917 uint32_t segmentIndex = 0;
1918 uint32_t maxSupportedExecuteOnlySegmentCount =
1919 (alignedEndAddress - alignedStartAddress) / flashAccessInfo.SegmentSize;
1920
1921 while (start < endAddress)
1922 {
1923 uint32_t xacc;
1924 bool isInvalidSegmentIndex = false;
1925
1926 segmentIndex = (start - flashAccessInfo.SegmentBase) / flashAccessInfo.SegmentSize;
1927
1928 #if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER
1929 if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash)
1930 {
1931 /* For secondary flash, The two XACCS registers allow up to 16 restricted segments of equal memory size.
1932 */
1933 if (segmentIndex < 8)
1934 {
1935 xacc = *(const volatile uint8_t *)&FTFx_XACCSL_REG;
1936 }
1937 else if (segmentIndex < flashAccessInfo.SegmentCount)
1938 {
1939 xacc = *(const volatile uint8_t *)&FTFx_XACCSH_REG;
1940 segmentIndex -= 8;
1941 }
1942 else
1943 {
1944 isInvalidSegmentIndex = true;
1945 }
1946 }
1947 else
1948 #endif
1949 {
1950 /* For primary flash, The eight XACC registers allow up to 64 restricted segments of equal memory size.
1951 */
1952 if (segmentIndex < 32)
1953 {
1954 xacc = *(const volatile uint32_t *)&FTFx_XACCL3_REG;
1955 }
1956 else if (segmentIndex < flashAccessInfo.SegmentCount)
1957 {
1958 xacc = *(const volatile uint32_t *)&FTFx_XACCH3_REG;
1959 segmentIndex -= 32;
1960 }
1961 else
1962 {
1963 isInvalidSegmentIndex = true;
1964 }
1965 }
1966
1967 if (isInvalidSegmentIndex)
1968 {
1969 break;
1970 }
1971
1972 /* Determine if this address range is in a execute-only protection flash segment. */
1973 if ((~xacc) & (1u << segmentIndex))
1974 {
1975 executeOnlySegmentCounter++;
1976 }
1977
1978 start += flashAccessInfo.SegmentSize;
1979 }
1980
1981 if (executeOnlySegmentCounter < 1u)
1982 {
1983 *access_state = kFLASH_AccessStateUnLimited;
1984 }
1985 else if (executeOnlySegmentCounter < maxSupportedExecuteOnlySegmentCount)
1986 {
1987 *access_state = kFLASH_AccessStateMixed;
1988 }
1989 else
1990 {
1991 *access_state = kFLASH_AccessStateExecuteOnly;
1992 }
1993 }
1994 #else
1995 *access_state = kFLASH_AccessStateUnLimited;
1996 #endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */
1997
1998 return (returnCode);
1999 }
2000
FLASH_GetProperty(flash_config_t * config,flash_property_tag_t whichProperty,uint32_t * value)2001 status_t FLASH_GetProperty(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t *value)
2002 {
2003 if ((config == NULL) || (value == NULL))
2004 {
2005 return kStatus_FLASH_InvalidArgument;
2006 }
2007
2008 switch (whichProperty)
2009 {
2010 case kFLASH_PropertyPflashSectorSize:
2011 *value = config->PFlashSectorSize;
2012 break;
2013
2014 case kFLASH_PropertyPflashTotalSize:
2015 *value = config->PFlashTotalSize;
2016 break;
2017
2018 case kFLASH_PropertyPflashBlockSize:
2019 *value = config->PFlashTotalSize / (uint32_t)config->PFlashBlockCount;
2020 break;
2021
2022 case kFLASH_PropertyPflashBlockCount:
2023 *value = (uint32_t)config->PFlashBlockCount;
2024 break;
2025
2026 case kFLASH_PropertyPflashBlockBaseAddr:
2027 *value = config->PFlashBlockBase;
2028 break;
2029
2030 case kFLASH_PropertyPflashFacSupport:
2031 #if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL)
2032 *value = FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL;
2033 #else
2034 *value = 0;
2035 #endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */
2036 break;
2037
2038 case kFLASH_PropertyPflashAccessSegmentSize:
2039 *value = config->PFlashAccessSegmentSize;
2040 break;
2041
2042 case kFLASH_PropertyPflashAccessSegmentCount:
2043 *value = config->PFlashAccessSegmentCount;
2044 break;
2045
2046 case kFLASH_PropertyFlexRamBlockBaseAddr:
2047 *value = config->FlexRAMBlockBase;
2048 break;
2049
2050 case kFLASH_PropertyFlexRamTotalSize:
2051 *value = config->FlexRAMTotalSize;
2052 break;
2053
2054 #if FLASH_SSD_IS_FLEXNVM_ENABLED
2055 case kFLASH_PropertyDflashSectorSize:
2056 *value = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE;
2057 break;
2058 case kFLASH_PropertyDflashTotalSize:
2059 *value = config->DFlashTotalSize;
2060 break;
2061 case kFLASH_PropertyDflashBlockSize:
2062 *value = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SIZE;
2063 break;
2064 case kFLASH_PropertyDflashBlockCount:
2065 *value = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT;
2066 break;
2067 case kFLASH_PropertyDflashBlockBaseAddr:
2068 *value = config->DFlashBlockBase;
2069 break;
2070 case kFLASH_PropertyEepromTotalSize:
2071 *value = config->EEpromTotalSize;
2072 break;
2073 #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */
2074
2075 default: /* catch inputs that are not recognized */
2076 return kStatus_FLASH_UnknownProperty;
2077 }
2078
2079 return kStatus_FLASH_Success;
2080 }
2081
FLASH_SetProperty(flash_config_t * config,flash_property_tag_t whichProperty,uint32_t value)2082 status_t FLASH_SetProperty(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t value)
2083 {
2084 status_t status = kStatus_FLASH_Success;
2085
2086 if (config == NULL)
2087 {
2088 return kStatus_FLASH_InvalidArgument;
2089 }
2090
2091 switch (whichProperty)
2092 {
2093 #if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED
2094 case kFLASH_PropertyFlashMemoryIndex:
2095 if ((value != (uint32_t)kFLASH_MemoryIndexPrimaryFlash) &&
2096 (value != (uint32_t)kFLASH_MemoryIndexSecondaryFlash))
2097 {
2098 return kStatus_FLASH_InvalidPropertyValue;
2099 }
2100 config->FlashMemoryIndex = (uint8_t)value;
2101 break;
2102 #endif /* FLASH_SSD_IS_SECONDARY_FLASH_ENABLED */
2103
2104 case kFLASH_PropertyPflashSectorSize:
2105 case kFLASH_PropertyPflashTotalSize:
2106 case kFLASH_PropertyPflashBlockSize:
2107 case kFLASH_PropertyPflashBlockCount:
2108 case kFLASH_PropertyPflashBlockBaseAddr:
2109 case kFLASH_PropertyPflashFacSupport:
2110 case kFLASH_PropertyPflashAccessSegmentSize:
2111 case kFLASH_PropertyPflashAccessSegmentCount:
2112 case kFLASH_PropertyFlexRamBlockBaseAddr:
2113 case kFLASH_PropertyFlexRamTotalSize:
2114 #if FLASH_SSD_IS_FLEXNVM_ENABLED
2115 case kFLASH_PropertyDflashSectorSize:
2116 case kFLASH_PropertyDflashTotalSize:
2117 case kFLASH_PropertyDflashBlockSize:
2118 case kFLASH_PropertyDflashBlockCount:
2119 case kFLASH_PropertyDflashBlockBaseAddr:
2120 case kFLASH_PropertyEepromTotalSize:
2121 #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */
2122 status = kStatus_FLASH_ReadOnlyProperty;
2123 break;
2124 default: /* catch inputs that are not recognized */
2125 status = kStatus_FLASH_UnknownProperty;
2126 break;
2127 }
2128
2129 return status;
2130 }
2131
2132 #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
FLASH_SetFlexramFunction(flash_config_t * config,flash_flexram_function_option_t option)2133 status_t FLASH_SetFlexramFunction(flash_config_t *config, flash_flexram_function_option_t option)
2134 {
2135 status_t status;
2136
2137 if (config == NULL)
2138 {
2139 return kStatus_FLASH_InvalidArgument;
2140 }
2141
2142 status = flasn_check_flexram_function_option_range(option);
2143 if (status != kStatus_FLASH_Success)
2144 {
2145 return status;
2146 }
2147
2148 /* preparing passing parameter to verify all block command */
2149 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_1_2(FTFx_SET_FLEXRAM_FUNCTION, option, 0xFFFFU);
2150
2151 /* calling flash command sequence function to execute the command */
2152 return flash_command_sequence(config);
2153 }
2154 #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
2155
2156 #if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD
FLASH_SwapControl(flash_config_t * config,uint32_t address,flash_swap_control_option_t option,flash_swap_state_config_t * returnInfo)2157 status_t FLASH_SwapControl(flash_config_t *config,
2158 uint32_t address,
2159 flash_swap_control_option_t option,
2160 flash_swap_state_config_t *returnInfo)
2161 {
2162 status_t returnCode;
2163
2164 if ((config == NULL) || (returnInfo == NULL))
2165 {
2166 return kStatus_FLASH_InvalidArgument;
2167 }
2168
2169 if (address & (FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT - 1))
2170 {
2171 return kStatus_FLASH_AlignmentError;
2172 }
2173
2174 /* Make sure address provided is in the lower half of Program flash but not in the Flash Configuration Field */
2175 if ((address >= (config->PFlashTotalSize / 2)) ||
2176 ((address >= kFLASH_ConfigAreaStart) && (address <= kFLASH_ConfigAreaEnd)))
2177 {
2178 return kStatus_FLASH_SwapIndicatorAddressError;
2179 }
2180
2181 /* Check the option. */
2182 returnCode = flash_check_swap_control_option(option);
2183 if (returnCode)
2184 {
2185 return returnCode;
2186 }
2187
2188 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_SWAP_CONTROL, address);
2189 kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_3(option, 0xFFFFFFU);
2190
2191 returnCode = flash_command_sequence(config);
2192
2193 returnInfo->flashSwapState = (flash_swap_state_t)FTFx_FCCOB5_REG;
2194 returnInfo->currentSwapBlockStatus = (flash_swap_block_status_t)FTFx_FCCOB6_REG;
2195 returnInfo->nextSwapBlockStatus = (flash_swap_block_status_t)FTFx_FCCOB7_REG;
2196
2197 return returnCode;
2198 }
2199 #endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */
2200
2201 #if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP
FLASH_Swap(flash_config_t * config,uint32_t address,flash_swap_function_option_t option)2202 status_t FLASH_Swap(flash_config_t *config, uint32_t address, flash_swap_function_option_t option)
2203 {
2204 flash_swap_state_config_t returnInfo;
2205 status_t returnCode;
2206
2207 memset(&returnInfo, 0xFFU, sizeof(returnInfo));
2208
2209 do
2210 {
2211 returnCode = FLASH_SwapControl(config, address, kFLASH_SwapControlOptionReportStatus, &returnInfo);
2212 if (returnCode != kStatus_FLASH_Success)
2213 {
2214 return returnCode;
2215 }
2216
2217 if (kFLASH_SwapFunctionOptionDisable == option)
2218 {
2219 if (returnInfo.flashSwapState == kFLASH_SwapStateDisabled)
2220 {
2221 return kStatus_FLASH_Success;
2222 }
2223 else if (returnInfo.flashSwapState == kFLASH_SwapStateUninitialized)
2224 {
2225 /* The swap system changed to the DISABLED state with Program flash block 0
2226 * located at relative flash address 0x0_0000 */
2227 returnCode = FLASH_SwapControl(config, address, kFLASH_SwapControlOptionDisableSystem, &returnInfo);
2228 }
2229 else
2230 {
2231 /* Swap disable should be requested only when swap system is in the uninitialized state */
2232 return kStatus_FLASH_SwapSystemNotInUninitialized;
2233 }
2234 }
2235 else
2236 {
2237 /* When first swap: the initial swap state is Uninitialized, flash swap inidicator address is unset,
2238 * the swap procedure should be Uninitialized -> Update-Erased -> Complete.
2239 * After the first swap has been completed, the flash swap inidicator address cannot be modified
2240 * unless EraseAllBlocks command is issued, the swap procedure is changed to Update -> Update-Erased ->
2241 * Complete. */
2242 switch (returnInfo.flashSwapState)
2243 {
2244 case kFLASH_SwapStateUninitialized:
2245 /* If current swap mode is Uninitialized, Initialize Swap to Initialized/READY state. */
2246 returnCode =
2247 FLASH_SwapControl(config, address, kFLASH_SwapControlOptionIntializeSystem, &returnInfo);
2248 break;
2249 case kFLASH_SwapStateReady:
2250 /* Validate whether the address provided to the swap system is matched to
2251 * swap indicator address in the IFR */
2252 returnCode = flash_validate_swap_indicator_address(config, address);
2253 if (returnCode == kStatus_FLASH_Success)
2254 {
2255 /* If current swap mode is Initialized/Ready, Initialize Swap to UPDATE state. */
2256 returnCode =
2257 FLASH_SwapControl(config, address, kFLASH_SwapControlOptionSetInUpdateState, &returnInfo);
2258 }
2259 break;
2260 case kFLASH_SwapStateUpdate:
2261 /* If current swap mode is Update, Erase indicator sector in non active block
2262 * to proceed swap system to update-erased state */
2263 returnCode = FLASH_Erase(config, address + (config->PFlashTotalSize >> 1),
2264 FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT, kFLASH_ApiEraseKey);
2265 break;
2266 case kFLASH_SwapStateUpdateErased:
2267 /* If current swap mode is Update or Update-Erased, progress Swap to COMPLETE State */
2268 returnCode =
2269 FLASH_SwapControl(config, address, kFLASH_SwapControlOptionSetInCompleteState, &returnInfo);
2270 break;
2271 case kFLASH_SwapStateComplete:
2272 break;
2273 case kFLASH_SwapStateDisabled:
2274 /* When swap system is in disabled state, We need to clear swap system back to uninitialized
2275 * by issuing EraseAllBlocks command */
2276 returnCode = kStatus_FLASH_SwapSystemNotInUninitialized;
2277 break;
2278 default:
2279 returnCode = kStatus_FLASH_InvalidArgument;
2280 break;
2281 }
2282 }
2283 if (returnCode != kStatus_FLASH_Success)
2284 {
2285 break;
2286 }
2287 } while (!((kFLASH_SwapStateComplete == returnInfo.flashSwapState) && (kFLASH_SwapFunctionOptionEnable == option)));
2288
2289 return returnCode;
2290 }
2291 #endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */
2292
2293 #if defined(FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD) && FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD
FLASH_ProgramPartition(flash_config_t * config,flash_partition_flexram_load_option_t option,uint32_t eepromDataSizeCode,uint32_t flexnvmPartitionCode)2294 status_t FLASH_ProgramPartition(flash_config_t *config,
2295 flash_partition_flexram_load_option_t option,
2296 uint32_t eepromDataSizeCode,
2297 uint32_t flexnvmPartitionCode)
2298 {
2299 status_t returnCode;
2300
2301 if (config == NULL)
2302 {
2303 return kStatus_FLASH_InvalidArgument;
2304 }
2305
2306 /* eepromDataSizeCode[7:6], flexnvmPartitionCode[7:4] should be all 1'b0
2307 * or it will cause access error. */
2308 /* eepromDataSizeCode &= 0x3FU; */
2309 /* flexnvmPartitionCode &= 0x0FU; */
2310
2311 /* preparing passing parameter to program the flash block */
2312 kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_2_1(FTFx_PROGRAM_PARTITION, 0xFFFFU, option);
2313 kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_1_2(eepromDataSizeCode, flexnvmPartitionCode, 0xFFFFU);
2314
2315 flash_cache_clear_process(config, kFLASH_CacheClearProcessPre);
2316
2317 /* calling flash command sequence function to execute the command */
2318 returnCode = flash_command_sequence(config);
2319
2320 flash_cache_clear(config);
2321
2322 #if FLASH_SSD_IS_FLEXNVM_ENABLED
2323 /* Data flash IFR will be updated by program partition command during reset sequence,
2324 * so we just set reserved values for partitioned FlexNVM size here */
2325 config->EEpromTotalSize = FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED;
2326 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
2327 #endif
2328
2329 return (returnCode);
2330 }
2331 #endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD */
2332
FLASH_PflashSetProtection(flash_config_t * config,pflash_protection_status_t * protectStatus)2333 status_t FLASH_PflashSetProtection(flash_config_t *config, pflash_protection_status_t *protectStatus)
2334 {
2335 if (config == NULL)
2336 {
2337 return kStatus_FLASH_InvalidArgument;
2338 }
2339
2340 #if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER
2341 if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash)
2342 {
2343 *kFPROTSL = protectStatus->valueLow32b.prots16b.protsl;
2344 if (protectStatus->valueLow32b.prots16b.protsl != *kFPROTSL)
2345 {
2346 return kStatus_FLASH_CommandFailure;
2347 }
2348
2349 *kFPROTSH = protectStatus->valueLow32b.prots16b.protsh;
2350 if (protectStatus->valueLow32b.prots16b.protsh != *kFPROTSH)
2351 {
2352 return kStatus_FLASH_CommandFailure;
2353 }
2354 }
2355 else
2356 #endif
2357 {
2358 *kFPROTL = protectStatus->valueLow32b.protl32b;
2359 if (protectStatus->valueLow32b.protl32b != *kFPROTL)
2360 {
2361 return kStatus_FLASH_CommandFailure;
2362 }
2363
2364 #if defined(FTFx_FPROT_HIGH_REG)
2365 *kFPROTH = protectStatus->valueHigh32b.proth32b;
2366 if (protectStatus->valueHigh32b.proth32b != *kFPROTH)
2367 {
2368 return kStatus_FLASH_CommandFailure;
2369 }
2370 #endif
2371 }
2372
2373 return kStatus_FLASH_Success;
2374 }
2375
FLASH_PflashGetProtection(flash_config_t * config,pflash_protection_status_t * protectStatus)2376 status_t FLASH_PflashGetProtection(flash_config_t *config, pflash_protection_status_t *protectStatus)
2377 {
2378 if ((config == NULL) || (protectStatus == NULL))
2379 {
2380 return kStatus_FLASH_InvalidArgument;
2381 }
2382
2383 #if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER
2384 if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash)
2385 {
2386 protectStatus->valueLow32b.prots16b.protsl = *kFPROTSL;
2387 protectStatus->valueLow32b.prots16b.protsh = *kFPROTSH;
2388 }
2389 else
2390 #endif
2391 {
2392 protectStatus->valueLow32b.protl32b = *kFPROTL;
2393 #if defined(FTFx_FPROT_HIGH_REG)
2394 protectStatus->valueHigh32b.proth32b = *kFPROTH;
2395 #endif
2396 }
2397
2398 return kStatus_FLASH_Success;
2399 }
2400
2401 #if FLASH_SSD_IS_FLEXNVM_ENABLED
FLASH_DflashSetProtection(flash_config_t * config,uint8_t protectStatus)2402 status_t FLASH_DflashSetProtection(flash_config_t *config, uint8_t protectStatus)
2403 {
2404 if (config == NULL)
2405 {
2406 return kStatus_FLASH_InvalidArgument;
2407 }
2408
2409 if ((config->DFlashTotalSize == 0) || (config->DFlashTotalSize == FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED))
2410 {
2411 return kStatus_FLASH_CommandNotSupported;
2412 }
2413
2414 FTFx->FDPROT = protectStatus;
2415
2416 if (FTFx->FDPROT != protectStatus)
2417 {
2418 return kStatus_FLASH_CommandFailure;
2419 }
2420
2421 return kStatus_FLASH_Success;
2422 }
2423 #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */
2424
2425 #if FLASH_SSD_IS_FLEXNVM_ENABLED
FLASH_DflashGetProtection(flash_config_t * config,uint8_t * protectStatus)2426 status_t FLASH_DflashGetProtection(flash_config_t *config, uint8_t *protectStatus)
2427 {
2428 if ((config == NULL) || (protectStatus == NULL))
2429 {
2430 return kStatus_FLASH_InvalidArgument;
2431 }
2432
2433 if ((config->DFlashTotalSize == 0) || (config->DFlashTotalSize == FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED))
2434 {
2435 return kStatus_FLASH_CommandNotSupported;
2436 }
2437
2438 *protectStatus = FTFx->FDPROT;
2439
2440 return kStatus_FLASH_Success;
2441 }
2442 #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */
2443
2444 #if FLASH_SSD_IS_FLEXNVM_ENABLED
FLASH_EepromSetProtection(flash_config_t * config,uint8_t protectStatus)2445 status_t FLASH_EepromSetProtection(flash_config_t *config, uint8_t protectStatus)
2446 {
2447 if (config == NULL)
2448 {
2449 return kStatus_FLASH_InvalidArgument;
2450 }
2451
2452 if ((config->EEpromTotalSize == 0) || (config->EEpromTotalSize == FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED))
2453 {
2454 return kStatus_FLASH_CommandNotSupported;
2455 }
2456
2457 FTFx->FEPROT = protectStatus;
2458
2459 if (FTFx->FEPROT != protectStatus)
2460 {
2461 return kStatus_FLASH_CommandFailure;
2462 }
2463
2464 return kStatus_FLASH_Success;
2465 }
2466 #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */
2467
2468 #if FLASH_SSD_IS_FLEXNVM_ENABLED
FLASH_EepromGetProtection(flash_config_t * config,uint8_t * protectStatus)2469 status_t FLASH_EepromGetProtection(flash_config_t *config, uint8_t *protectStatus)
2470 {
2471 if ((config == NULL) || (protectStatus == NULL))
2472 {
2473 return kStatus_FLASH_InvalidArgument;
2474 }
2475
2476 if ((config->EEpromTotalSize == 0) || (config->EEpromTotalSize == FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED))
2477 {
2478 return kStatus_FLASH_CommandNotSupported;
2479 }
2480
2481 *protectStatus = FTFx->FEPROT;
2482
2483 return kStatus_FLASH_Success;
2484 }
2485 #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */
2486
FLASH_PflashSetPrefetchSpeculation(flash_prefetch_speculation_status_t * speculationStatus)2487 status_t FLASH_PflashSetPrefetchSpeculation(flash_prefetch_speculation_status_t *speculationStatus)
2488 {
2489 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM
2490 {
2491 FTFx_REG32_ACCESS_TYPE regBase;
2492 #if defined(MCM)
2493 regBase = (FTFx_REG32_ACCESS_TYPE)&MCM->PLACR;
2494 #elif defined(MCM0)
2495 regBase = (FTFx_REG32_ACCESS_TYPE)&MCM0->PLACR;
2496 #endif
2497 if (speculationStatus->instructionOption == kFLASH_prefetchSpeculationOptionDisable)
2498 {
2499 if (speculationStatus->dataOption == kFLASH_prefetchSpeculationOptionEnable)
2500 {
2501 return kStatus_FLASH_InvalidSpeculationOption;
2502 }
2503 else
2504 {
2505 *regBase |= MCM_PLACR_DFCS_MASK;
2506 }
2507 }
2508 else
2509 {
2510 *regBase &= ~MCM_PLACR_DFCS_MASK;
2511 if (speculationStatus->dataOption == kFLASH_prefetchSpeculationOptionEnable)
2512 {
2513 *regBase |= MCM_PLACR_EFDS_MASK;
2514 }
2515 else
2516 {
2517 *regBase &= ~MCM_PLACR_EFDS_MASK;
2518 }
2519 }
2520 }
2521 #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC
2522 {
2523 FTFx_REG32_ACCESS_TYPE regBase;
2524 uint32_t b0dpeMask, b0ipeMask;
2525 #if defined(FMC_PFB01CR_B0DPE_MASK)
2526 regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB01CR;
2527 b0dpeMask = FMC_PFB01CR_B0DPE_MASK;
2528 b0ipeMask = FMC_PFB01CR_B0IPE_MASK;
2529 #elif defined(FMC_PFB0CR_B0DPE_MASK)
2530 regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB0CR;
2531 b0dpeMask = FMC_PFB0CR_B0DPE_MASK;
2532 b0ipeMask = FMC_PFB0CR_B0IPE_MASK;
2533 #endif
2534 if (speculationStatus->instructionOption == kFLASH_prefetchSpeculationOptionEnable)
2535 {
2536 *regBase |= b0ipeMask;
2537 }
2538 else
2539 {
2540 *regBase &= ~b0ipeMask;
2541 }
2542 if (speculationStatus->dataOption == kFLASH_prefetchSpeculationOptionEnable)
2543 {
2544 *regBase |= b0dpeMask;
2545 }
2546 else
2547 {
2548 *regBase &= ~b0dpeMask;
2549 }
2550
2551 /* Invalidate Prefetch Speculation Buffer */
2552 #if defined(FMC_PFB01CR_S_INV_MASK)
2553 FMC->PFB01CR |= FMC_PFB01CR_S_INV_MASK;
2554 #elif defined(FMC_PFB01CR_S_B_INV_MASK)
2555 FMC->PFB01CR |= FMC_PFB01CR_S_B_INV_MASK;
2556 #elif defined(FMC_PFB0CR_S_INV_MASK)
2557 FMC->PFB0CR |= FMC_PFB0CR_S_INV_MASK;
2558 #elif defined(FMC_PFB0CR_S_B_INV_MASK)
2559 FMC->PFB0CR |= FMC_PFB0CR_S_B_INV_MASK;
2560 #endif
2561 }
2562 #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
2563 {
2564 FTFx_REG32_ACCESS_TYPE regBase;
2565 uint32_t flashSpeculationMask, dataPrefetchMask;
2566 regBase = (FTFx_REG32_ACCESS_TYPE)&MSCM_OCMDR0_REG;
2567 flashSpeculationMask = MSCM_OCMDR_OCMC1_DFCS_MASK;
2568 dataPrefetchMask = MSCM_OCMDR_OCMC1_DFDS_MASK;
2569
2570 if (speculationStatus->instructionOption == kFLASH_prefetchSpeculationOptionDisable)
2571 {
2572 if (speculationStatus->dataOption == kFLASH_prefetchSpeculationOptionEnable)
2573 {
2574 return kStatus_FLASH_InvalidSpeculationOption;
2575 }
2576 else
2577 {
2578 *regBase |= flashSpeculationMask;
2579 }
2580 }
2581 else
2582 {
2583 *regBase &= ~flashSpeculationMask;
2584 if (speculationStatus->dataOption == kFLASH_prefetchSpeculationOptionEnable)
2585 {
2586 *regBase &= ~dataPrefetchMask;
2587 }
2588 else
2589 {
2590 *regBase |= dataPrefetchMask;
2591 }
2592 }
2593 }
2594 #endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */
2595
2596 return kStatus_FLASH_Success;
2597 }
2598
FLASH_PflashGetPrefetchSpeculation(flash_prefetch_speculation_status_t * speculationStatus)2599 status_t FLASH_PflashGetPrefetchSpeculation(flash_prefetch_speculation_status_t *speculationStatus)
2600 {
2601 memset(speculationStatus, 0, sizeof(flash_prefetch_speculation_status_t));
2602
2603 /* Assuming that all speculation options are enabled. */
2604 speculationStatus->instructionOption = kFLASH_prefetchSpeculationOptionEnable;
2605 speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionEnable;
2606
2607 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM
2608 {
2609 uint32_t value;
2610 #if defined(MCM)
2611 value = MCM->PLACR;
2612 #elif defined(MCM0)
2613 value = MCM0->PLACR;
2614 #endif
2615 if (value & MCM_PLACR_DFCS_MASK)
2616 {
2617 /* Speculation buffer is off. */
2618 speculationStatus->instructionOption = kFLASH_prefetchSpeculationOptionDisable;
2619 speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionDisable;
2620 }
2621 else
2622 {
2623 /* Speculation buffer is on for instruction. */
2624 if (!(value & MCM_PLACR_EFDS_MASK))
2625 {
2626 /* Speculation buffer is off for data. */
2627 speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionDisable;
2628 }
2629 }
2630 }
2631 #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC
2632 {
2633 uint32_t value;
2634 uint32_t b0dpeMask, b0ipeMask;
2635 #if defined(FMC_PFB01CR_B0DPE_MASK)
2636 value = FMC->PFB01CR;
2637 b0dpeMask = FMC_PFB01CR_B0DPE_MASK;
2638 b0ipeMask = FMC_PFB01CR_B0IPE_MASK;
2639 #elif defined(FMC_PFB0CR_B0DPE_MASK)
2640 value = FMC->PFB0CR;
2641 b0dpeMask = FMC_PFB0CR_B0DPE_MASK;
2642 b0ipeMask = FMC_PFB0CR_B0IPE_MASK;
2643 #endif
2644 if (!(value & b0dpeMask))
2645 {
2646 /* Do not prefetch in response to data references. */
2647 speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionDisable;
2648 }
2649 if (!(value & b0ipeMask))
2650 {
2651 /* Do not prefetch in response to instruction fetches. */
2652 speculationStatus->instructionOption = kFLASH_prefetchSpeculationOptionDisable;
2653 }
2654 }
2655 #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
2656 {
2657 uint32_t value;
2658 uint32_t flashSpeculationMask, dataPrefetchMask;
2659 value = MSCM_OCMDR0_REG;
2660 flashSpeculationMask = MSCM_OCMDR_OCMC1_DFCS_MASK;
2661 dataPrefetchMask = MSCM_OCMDR_OCMC1_DFDS_MASK;
2662
2663 if (value & flashSpeculationMask)
2664 {
2665 /* Speculation buffer is off. */
2666 speculationStatus->instructionOption = kFLASH_prefetchSpeculationOptionDisable;
2667 speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionDisable;
2668 }
2669 else
2670 {
2671 /* Speculation buffer is on for instruction. */
2672 if (value & dataPrefetchMask)
2673 {
2674 /* Speculation buffer is off for data. */
2675 speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionDisable;
2676 }
2677 }
2678 }
2679 #endif
2680
2681 return kStatus_FLASH_Success;
2682 }
2683
2684 #if FLASH_DRIVER_IS_FLASH_RESIDENT
2685 /*!
2686 * @brief Copy PIC of flash_run_command() to RAM
2687 */
copy_flash_run_command(uint32_t * flashRunCommand)2688 static void copy_flash_run_command(uint32_t *flashRunCommand)
2689 {
2690 assert(sizeof(s_flashRunCommandFunctionCode) <= (kFLASH_ExecuteInRamFunctionMaxSizeInWords * 4));
2691
2692 /* Since the value of ARM function pointer is always odd, but the real start address
2693 * of function memory should be even, that's why +1 operation exist. */
2694 memcpy((void *)flashRunCommand, (void *)s_flashRunCommandFunctionCode, sizeof(s_flashRunCommandFunctionCode));
2695 callFlashRunCommand = (void (*)(FTFx_REG8_ACCESS_TYPE ftfx_fstat))((uint32_t)flashRunCommand + 1);
2696 }
2697 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */
2698
2699 /*!
2700 * @brief Flash Command Sequence
2701 *
2702 * This function is used to perform the command write sequence to the flash.
2703 *
2704 * @param driver Pointer to storage for the driver runtime state.
2705 * @return An error code or kStatus_FLASH_Success
2706 */
flash_command_sequence(flash_config_t * config)2707 static status_t flash_command_sequence(flash_config_t *config)
2708 {
2709 uint8_t registerValue;
2710
2711 #if FLASH_DRIVER_IS_FLASH_RESIDENT
2712 /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */
2713 FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK;
2714
2715 status_t returnCode = flash_check_execute_in_ram_function_info(config);
2716 if (kStatus_FLASH_Success != returnCode)
2717 {
2718 return returnCode;
2719 }
2720
2721 /* We pass the ftfx_fstat address as a parameter to flash_run_comamnd() instead of using
2722 * pre-processed MICRO sentences or operating global variable in flash_run_comamnd()
2723 * to make sure that flash_run_command() will be compiled into position-independent code (PIC). */
2724 callFlashRunCommand((FTFx_REG8_ACCESS_TYPE)(&FTFx->FSTAT));
2725 #else
2726 /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */
2727 FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK;
2728
2729 /* clear CCIF bit */
2730 FTFx->FSTAT = FTFx_FSTAT_CCIF_MASK;
2731
2732 /* Check CCIF bit of the flash status register, wait till it is set.
2733 * IP team indicates that this loop will always complete. */
2734 while (!(FTFx->FSTAT & FTFx_FSTAT_CCIF_MASK))
2735 {
2736 }
2737 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */
2738
2739 /* Check error bits */
2740 /* Get flash status register value */
2741 registerValue = FTFx->FSTAT;
2742
2743 /* checking access error */
2744 if (registerValue & FTFx_FSTAT_ACCERR_MASK)
2745 {
2746 return kStatus_FLASH_AccessError;
2747 }
2748 /* checking protection error */
2749 else if (registerValue & FTFx_FSTAT_FPVIOL_MASK)
2750 {
2751 return kStatus_FLASH_ProtectionViolation;
2752 }
2753 /* checking MGSTAT0 non-correctable error */
2754 else if (registerValue & FTFx_FSTAT_MGSTAT0_MASK)
2755 {
2756 return kStatus_FLASH_CommandFailure;
2757 }
2758 else
2759 {
2760 return kStatus_FLASH_Success;
2761 }
2762 }
2763
2764 #if FLASH_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE
2765 /*!
2766 * @brief Copy PIC of flash_common_bit_operation() to RAM
2767 *
2768 */
copy_flash_common_bit_operation(uint32_t * flashCommonBitOperation)2769 static void copy_flash_common_bit_operation(uint32_t *flashCommonBitOperation)
2770 {
2771 assert(sizeof(s_flashCommonBitOperationFunctionCode) <= (kFLASH_ExecuteInRamFunctionMaxSizeInWords * 4));
2772
2773 /* Since the value of ARM function pointer is always odd, but the real start address
2774 * of function memory should be even, that's why +1 operation exist. */
2775 memcpy((void *)flashCommonBitOperation, (void *)s_flashCommonBitOperationFunctionCode,
2776 sizeof(s_flashCommonBitOperationFunctionCode));
2777 callFlashCommonBitOperation = (void (*)(FTFx_REG32_ACCESS_TYPE base, uint32_t bitMask, uint32_t bitShift,
2778 uint32_t bitValue))((uint32_t)flashCommonBitOperation + 1);
2779 }
2780 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE */
2781
2782 #if FLASH_CACHE_IS_CONTROLLED_BY_MCM
2783 /*! @brief Performs the cache clear to the flash by MCM.*/
mcm_flash_cache_clear(void)2784 void mcm_flash_cache_clear(void)
2785 {
2786 FTFx_REG32_ACCESS_TYPE regBase;
2787
2788 #if defined(BL_TARGET_ROM) && defined(MCM0_CACHE_REG) && defined(MCM1_CACHE_REG) && \
2789 defined(FSL_FEATURE_FLASH_CURRENT_CORE_ID)
2790 {
2791 uint16_t armPartNumber = (uint16_t)((SCB->CPUID & SCB_CPUID_PARTNO_Msk) >> SCB_CPUID_PARTNO_Pos);
2792 uint32_t cortexVersion = __CORTEX_M;
2793 uint32_t coreId = FSL_FEATURE_FLASH_CURRENT_CORE_ID;
2794 #if (__CORTEX_M <= 7)
2795 /* Note: Below code only apply to dual core device */
2796 if (s_armCorePartNumberArray[cortexVersion] != armPartNumber)
2797 {
2798 coreId ^= 0x1;
2799 }
2800 regBase = s_mcmModuleAccessTypeArray[coreId];
2801 #else
2802 #error "Inapplicable ARM Cortext Version!"
2803 #endif
2804 }
2805 #elif defined(MCM0_CACHE_REG)
2806 regBase = (FTFx_REG32_ACCESS_TYPE)&MCM0_CACHE_REG;
2807 #elif defined(MCM1_CACHE_REG)
2808 regBase = (FTFx_REG32_ACCESS_TYPE)&MCM1_CACHE_REG;
2809 #endif
2810
2811 #if FLASH_DRIVER_IS_FLASH_RESIDENT
2812 callFlashCommonBitOperation(regBase, MCM_CACHE_CLEAR_MASK, MCM_CACHE_CLEAR_SHIFT, 1U);
2813 #else /* !FLASH_DRIVER_IS_FLASH_RESIDENT */
2814 *regBase |= MCM_CACHE_CLEAR_MASK;
2815
2816 /* Memory barriers for good measure.
2817 * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */
2818 __ISB();
2819 __DSB();
2820 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */
2821 }
2822 #endif /* FLASH_CACHE_IS_CONTROLLED_BY_MCM */
2823
2824 #if FLASH_CACHE_IS_CONTROLLED_BY_FMC
2825 /*! @brief Performs the cache clear to the flash by FMC.*/
fmc_flash_cache_clear(void)2826 void fmc_flash_cache_clear(void)
2827 {
2828 #if FLASH_DRIVER_IS_FLASH_RESIDENT
2829 FTFx_REG32_ACCESS_TYPE regBase = (FTFx_REG32_ACCESS_TYPE)0;
2830 #if defined(FMC_PFB01CR_CINV_WAY_MASK)
2831 regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB01CR;
2832 callFlashCommonBitOperation(regBase, FMC_PFB01CR_CINV_WAY_MASK, FMC_PFB01CR_CINV_WAY_SHIFT, 0xFU);
2833 #else
2834 regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB0CR;
2835 callFlashCommonBitOperation(regBase, FMC_PFB0CR_CINV_WAY_MASK, FMC_PFB0CR_CINV_WAY_SHIFT, 0xFU);
2836 #endif
2837 #else /* !FLASH_DRIVER_IS_FLASH_RESIDENT */
2838 #if defined(FMC_PFB01CR_CINV_WAY_MASK)
2839 FMC->PFB01CR = (FMC->PFB01CR & ~FMC_PFB01CR_CINV_WAY_MASK) | FMC_PFB01CR_CINV_WAY(~0);
2840 #else
2841 FMC->PFB0CR = (FMC->PFB0CR & ~FMC_PFB0CR_CINV_WAY_MASK) | FMC_PFB0CR_CINV_WAY(~0);
2842 #endif
2843 /* Memory barriers for good measure.
2844 * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */
2845 __ISB();
2846 __DSB();
2847 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */
2848 }
2849 #endif /* FLASH_CACHE_IS_CONTROLLED_BY_FMC */
2850
2851 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
2852 /*! @brief Performs the prefetch speculation buffer clear to the flash by MSCM.*/
mscm_flash_prefetch_speculation_enable(uint32_t flashIndex,bool enable)2853 void mscm_flash_prefetch_speculation_enable(uint32_t flashIndex, bool enable)
2854 {
2855 uint8_t setValue;
2856 if (enable)
2857 {
2858 setValue = 0x0U;
2859 }
2860 else
2861 {
2862 setValue = 0x3U;
2863 }
2864
2865 /* The OCMDR[0] is always used to prefetch main Pflash*/
2866 /* For device with FlexNVM support, the OCMDR[1] is used to prefetch Dflash.
2867 * For device with secondary flash support, the OCMDR[1] is used to prefetch secondary Pflash. */
2868 #if FLASH_DRIVER_IS_FLASH_RESIDENT
2869 switch (flashIndex)
2870 {
2871 #if FLASH_SSD_IS_FLEXNVM_ENABLED || FLASH_SSD_IS_SECONDARY_FLASH_ENABLED
2872 case kFLASH_MemoryIndexSecondaryFlash:
2873 callFlashCommonBitOperation((FTFx_REG32_ACCESS_TYPE)&MSCM_OCMDR1_REG, MSCM_SPECULATION_DISABLE_MASK,
2874 MSCM_SPECULATION_DISABLE_SHIFT, setValue);
2875 break;
2876 #endif
2877 case kFLASH_MemoryIndexPrimaryFlash:
2878 default:
2879 callFlashCommonBitOperation((FTFx_REG32_ACCESS_TYPE)&MSCM_OCMDR0_REG, MSCM_SPECULATION_DISABLE_MASK,
2880 MSCM_SPECULATION_DISABLE_SHIFT, setValue);
2881 break;
2882 }
2883 #else /* !FLASH_DRIVER_IS_FLASH_RESIDENT */
2884 switch (flashIndex)
2885 {
2886 #if FLASH_SSD_IS_FLEXNVM_ENABLED || FLASH_SSD_IS_SECONDARY_FLASH_ENABLED
2887 case kFLASH_MemoryIndexSecondaryFlash:
2888 MSCM_OCMDR1_REG = (MSCM_OCMDR1_REG & (~MSCM_SPECULATION_DISABLE_MASK)) | MSCM_SPECULATION_DISABLE(setValue);
2889 /* Each cahce clear instaruction should be followed by below code*/
2890 __ISB();
2891 __DSB();
2892 break;
2893 #endif
2894 case kFLASH_MemoryIndexPrimaryFlash:
2895 default:
2896 MSCM_OCMDR0_REG = (MSCM_OCMDR0_REG & (~MSCM_SPECULATION_DISABLE_MASK)) | MSCM_SPECULATION_DISABLE(setValue);
2897 /* Memory barriers for good measure.
2898 * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */
2899 __ISB();
2900 __DSB();
2901 break;
2902 }
2903 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */
2904 }
2905 #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM */
2906
2907 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC
2908 /*! @brief Performs the prefetch speculation buffer clear to the flash by FMC.*/
fmc_flash_prefetch_speculation_clear(void)2909 void fmc_flash_prefetch_speculation_clear(void)
2910 {
2911 #if FLASH_DRIVER_IS_FLASH_RESIDENT
2912 FTFx_REG32_ACCESS_TYPE regBase = (FTFx_REG32_ACCESS_TYPE)0;
2913 #if defined(FMC_PFB01CR_S_INV_MASK)
2914 regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB01CR;
2915 callFlashCommonBitOperation(regBase, FMC_PFB01CR_S_INV_MASK, FMC_PFB01CR_S_INV_SHIFT, 1U);
2916 #elif defined(FMC_PFB01CR_S_B_INV_MASK)
2917 regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB01CR;
2918 callFlashCommonBitOperation(regBase, FMC_PFB01CR_S_B_INV_MASK, FMC_PFB01CR_S_B_INV_SHIFT, 1U);
2919 #elif defined(FMC_PFB0CR_S_INV_MASK)
2920 regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB0CR;
2921 callFlashCommonBitOperation(regBase, FMC_PFB0CR_S_INV_MASK, FMC_PFB0CR_S_INV_SHIFT, 1U);
2922 #elif defined(FMC_PFB0CR_S_B_INV_MASK)
2923 regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB0CR;
2924 callFlashCommonBitOperation(regBase, FMC_PFB0CR_S_B_INV_MASK, FMC_PFB0CR_S_B_INV_SHIFT, 1U);
2925 #endif
2926 #else /* !FLASH_DRIVER_IS_FLASH_RESIDENT */
2927 #if defined(FMC_PFB01CR_S_INV_MASK)
2928 FMC->PFB01CR |= FMC_PFB01CR_S_INV_MASK;
2929 #elif defined(FMC_PFB01CR_S_B_INV_MASK)
2930 FMC->PFB01CR |= FMC_PFB01CR_S_B_INV_MASK;
2931 #elif defined(FMC_PFB0CR_S_INV_MASK)
2932 FMC->PFB0CR |= FMC_PFB0CR_S_INV_MASK;
2933 #elif defined(FMC_PFB0CR_S_B_INV_MASK)
2934 FMC->PFB0CR |= FMC_PFB0CR_S_B_INV_MASK;
2935 #endif
2936 /* Memory barriers for good measure.
2937 * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */
2938 __ISB();
2939 __DSB();
2940 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */
2941 }
2942 #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC */
2943
2944 /*!
2945 * @brief Flash Cache Clear
2946 *
2947 * This function is used to perform the cache and prefetch speculation clear to the flash.
2948 */
flash_cache_clear(flash_config_t * config)2949 void flash_cache_clear(flash_config_t *config)
2950 {
2951 flash_cache_clear_process(config, kFLASH_CacheClearProcessPost);
2952 }
2953
2954 /*!
2955 * @brief Flash Cache Clear Process
2956 *
2957 * This function is used to perform the cache and prefetch speculation clear process to the flash.
2958 */
flash_cache_clear_process(flash_config_t * config,flash_cache_clear_process_t process)2959 static void flash_cache_clear_process(flash_config_t *config, flash_cache_clear_process_t process)
2960 {
2961 #if FLASH_DRIVER_IS_FLASH_RESIDENT
2962 status_t returnCode = flash_check_execute_in_ram_function_info(config);
2963 if (kStatus_FLASH_Success != returnCode)
2964 {
2965 return;
2966 }
2967 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */
2968
2969 /* We pass the ftfx register address as a parameter to flash_common_bit_operation() instead of using
2970 * pre-processed MACROs or a global variable in flash_common_bit_operation()
2971 * to make sure that flash_common_bit_operation() will be compiled into position-independent code (PIC). */
2972 if (process == kFLASH_CacheClearProcessPost)
2973 {
2974 #if FLASH_CACHE_IS_CONTROLLED_BY_MCM
2975 mcm_flash_cache_clear();
2976 #endif
2977 #if FLASH_CACHE_IS_CONTROLLED_BY_FMC
2978 fmc_flash_cache_clear();
2979 #endif
2980 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
2981 mscm_flash_prefetch_speculation_enable(config->FlashMemoryIndex, true);
2982 #endif
2983 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC
2984 fmc_flash_prefetch_speculation_clear();
2985 #endif
2986 }
2987 if (process == kFLASH_CacheClearProcessPre)
2988 {
2989 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
2990 mscm_flash_prefetch_speculation_enable(config->FlashMemoryIndex, false);
2991 #endif
2992 }
2993 }
2994
2995 #if FLASH_DRIVER_IS_FLASH_RESIDENT
2996 /*! @brief Check whether flash execute-in-ram functions are ready */
flash_check_execute_in_ram_function_info(flash_config_t * config)2997 static status_t flash_check_execute_in_ram_function_info(flash_config_t *config)
2998 {
2999 flash_execute_in_ram_function_config_t *flashExecuteInRamFunctionInfo;
3000
3001 if (config == NULL)
3002 {
3003 return kStatus_FLASH_InvalidArgument;
3004 }
3005
3006 flashExecuteInRamFunctionInfo = (flash_execute_in_ram_function_config_t *)config->flashExecuteInRamFunctionInfo;
3007
3008 if ((config->flashExecuteInRamFunctionInfo) &&
3009 (kFLASH_ExecuteInRamFunctionTotalNum == flashExecuteInRamFunctionInfo->activeFunctionCount))
3010 {
3011 return kStatus_FLASH_Success;
3012 }
3013
3014 return kStatus_FLASH_ExecuteInRamFunctionNotReady;
3015 }
3016 #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */
3017
3018 /*! @brief Validates the range and alignment of the given address range.*/
flash_check_range(flash_config_t * config,uint32_t startAddress,uint32_t lengthInBytes,uint32_t alignmentBaseline)3019 static status_t flash_check_range(flash_config_t *config,
3020 uint32_t startAddress,
3021 uint32_t lengthInBytes,
3022 uint32_t alignmentBaseline)
3023 {
3024 if (config == NULL)
3025 {
3026 return kStatus_FLASH_InvalidArgument;
3027 }
3028
3029 /* Verify the start and length are alignmentBaseline aligned. */
3030 if ((startAddress & (alignmentBaseline - 1)) || (lengthInBytes & (alignmentBaseline - 1)))
3031 {
3032 return kStatus_FLASH_AlignmentError;
3033 }
3034
3035 /* check for valid range of the target addresses */
3036 if (
3037 #if FLASH_SSD_IS_FLEXNVM_ENABLED
3038 ((startAddress >= config->DFlashBlockBase) &&
3039 ((startAddress + lengthInBytes) <= (config->DFlashBlockBase + config->DFlashTotalSize))) ||
3040 #endif
3041 ((startAddress >= config->PFlashBlockBase) &&
3042 ((startAddress + lengthInBytes) <= (config->PFlashBlockBase + config->PFlashTotalSize))))
3043 {
3044 return kStatus_FLASH_Success;
3045 }
3046
3047 return kStatus_FLASH_AddressError;
3048 }
3049
3050 /*! @brief Gets the right address, sector and block size of current flash type which is indicated by address.*/
flash_get_matched_operation_info(flash_config_t * config,uint32_t address,flash_operation_config_t * info)3051 static status_t flash_get_matched_operation_info(flash_config_t *config,
3052 uint32_t address,
3053 flash_operation_config_t *info)
3054 {
3055 if ((config == NULL) || (info == NULL))
3056 {
3057 return kStatus_FLASH_InvalidArgument;
3058 }
3059
3060 /* Clean up info Structure*/
3061 memset(info, 0, sizeof(flash_operation_config_t));
3062
3063 #if FLASH_SSD_IS_FLEXNVM_ENABLED
3064 if ((address >= config->DFlashBlockBase) && (address <= (config->DFlashBlockBase + config->DFlashTotalSize)))
3065 {
3066 /* When required by the command, address bit 23 selects between program flash memory
3067 * (=0) and data flash memory (=1).*/
3068 info->convertedAddress = address - config->DFlashBlockBase + 0x800000U;
3069 info->activeSectorSize = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE;
3070 info->activeBlockSize = config->DFlashTotalSize / FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT;
3071
3072 info->blockWriteUnitSize = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_WRITE_UNIT_SIZE;
3073 info->sectorCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_SECTOR_CMD_ADDRESS_ALIGMENT;
3074 info->sectionCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_SECTION_CMD_ADDRESS_ALIGMENT;
3075 info->resourceCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_RESOURCE_CMD_ADDRESS_ALIGMENT;
3076 info->checkCmdAddressAligment = FSL_FEATURE_FLASH_FLEX_NVM_CHECK_CMD_ADDRESS_ALIGMENT;
3077 }
3078 else
3079 #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */
3080 {
3081 info->convertedAddress = address - config->PFlashBlockBase;
3082 info->activeSectorSize = config->PFlashSectorSize;
3083 info->activeBlockSize = config->PFlashTotalSize / config->PFlashBlockCount;
3084 #if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED
3085 if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash)
3086 {
3087 #if FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER || FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER
3088 /* When required by the command, address bit 23 selects between main flash memory
3089 * (=0) and secondary flash memory (=1).*/
3090 info->convertedAddress += 0x800000U;
3091 #endif
3092 info->blockWriteUnitSize = SECONDARY_FLASH_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE;
3093 info->sectorCmdAddressAligment = SECONDARY_FLASH_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT;
3094 info->sectionCmdAddressAligment = SECONDARY_FLASH_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT;
3095 }
3096 else
3097 #endif /* FLASH_SSD_IS_SECONDARY_FLASH_ENABLED */
3098 {
3099 info->blockWriteUnitSize = MAIN_FLASH_FEATURE_PFLASH_BLOCK_WRITE_UNIT_SIZE;
3100 info->sectorCmdAddressAligment = MAIN_FLASH_FEATURE_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT;
3101 info->sectionCmdAddressAligment = MAIN_FLASH_FEATURE_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT;
3102 }
3103
3104 info->resourceCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_RESOURCE_CMD_ADDRESS_ALIGMENT;
3105 info->checkCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_CHECK_CMD_ADDRESS_ALIGMENT;
3106 }
3107
3108 return kStatus_FLASH_Success;
3109 }
3110
3111 /*! @brief Validates the given user key for flash erase APIs.*/
flash_check_user_key(uint32_t key)3112 static status_t flash_check_user_key(uint32_t key)
3113 {
3114 /* Validate the user key */
3115 if (key != kFLASH_ApiEraseKey)
3116 {
3117 return kStatus_FLASH_EraseKeyError;
3118 }
3119
3120 return kStatus_FLASH_Success;
3121 }
3122
3123 #if FLASH_SSD_IS_FLEXNVM_ENABLED
3124 /*! @brief Updates FlexNVM memory partition status according to data flash 0 IFR.*/
flash_update_flexnvm_memory_partition_status(flash_config_t * config)3125 static status_t flash_update_flexnvm_memory_partition_status(flash_config_t *config)
3126 {
3127 struct
3128 {
3129 uint32_t reserved0;
3130 uint8_t FlexNVMPartitionCode;
3131 uint8_t EEPROMDataSetSize;
3132 uint16_t reserved1;
3133 } dataIFRReadOut;
3134 status_t returnCode;
3135
3136 if (config == NULL)
3137 {
3138 return kStatus_FLASH_InvalidArgument;
3139 }
3140
3141 #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD
3142 /* Get FlexNVM memory partition info from data flash IFR */
3143 returnCode = FLASH_ReadResource(config, DFLASH_IFR_READRESOURCE_START_ADDRESS, (uint32_t *)&dataIFRReadOut,
3144 sizeof(dataIFRReadOut), kFLASH_ResourceOptionFlashIfr);
3145 if (returnCode != kStatus_FLASH_Success)
3146 {
3147 return kStatus_FLASH_PartitionStatusUpdateFailure;
3148 }
3149 #else
3150 #error "Cannot get FlexNVM memory partition info"
3151 #endif
3152
3153 /* Fill out partitioned EEPROM size */
3154 dataIFRReadOut.EEPROMDataSetSize &= 0x0FU;
3155 switch (dataIFRReadOut.EEPROMDataSetSize)
3156 {
3157 case 0x00U:
3158 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0000;
3159 break;
3160 case 0x01U:
3161 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0001;
3162 break;
3163 case 0x02U:
3164 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0010;
3165 break;
3166 case 0x03U:
3167 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0011;
3168 break;
3169 case 0x04U:
3170 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0100;
3171 break;
3172 case 0x05U:
3173 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0101;
3174 break;
3175 case 0x06U:
3176 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0110;
3177 break;
3178 case 0x07U:
3179 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0111;
3180 break;
3181 case 0x08U:
3182 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1000;
3183 break;
3184 case 0x09U:
3185 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1001;
3186 break;
3187 case 0x0AU:
3188 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1010;
3189 break;
3190 case 0x0BU:
3191 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1011;
3192 break;
3193 case 0x0CU:
3194 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1100;
3195 break;
3196 case 0x0DU:
3197 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1101;
3198 break;
3199 case 0x0EU:
3200 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1110;
3201 break;
3202 case 0x0FU:
3203 config->EEpromTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1111;
3204 break;
3205 default:
3206 config->EEpromTotalSize = FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_RESERVED;
3207 break;
3208 }
3209
3210 /* Fill out partitioned DFlash size */
3211 dataIFRReadOut.FlexNVMPartitionCode &= 0x0FU;
3212 switch (dataIFRReadOut.FlexNVMPartitionCode)
3213 {
3214 case 0x00U:
3215 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000 != 0xFFFFFFFF)
3216 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000;
3217 #else
3218 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3219 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000 */
3220 break;
3221 case 0x01U:
3222 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001 != 0xFFFFFFFF)
3223 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001;
3224 #else
3225 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3226 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001 */
3227 break;
3228 case 0x02U:
3229 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010 != 0xFFFFFFFF)
3230 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010;
3231 #else
3232 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3233 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010 */
3234 break;
3235 case 0x03U:
3236 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011 != 0xFFFFFFFF)
3237 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011;
3238 #else
3239 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3240 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011 */
3241 break;
3242 case 0x04U:
3243 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100 != 0xFFFFFFFF)
3244 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100;
3245 #else
3246 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3247 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100 */
3248 break;
3249 case 0x05U:
3250 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101 != 0xFFFFFFFF)
3251 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101;
3252 #else
3253 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3254 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101 */
3255 break;
3256 case 0x06U:
3257 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110 != 0xFFFFFFFF)
3258 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110;
3259 #else
3260 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3261 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110 */
3262 break;
3263 case 0x07U:
3264 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111 != 0xFFFFFFFF)
3265 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111;
3266 #else
3267 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3268 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111 */
3269 break;
3270 case 0x08U:
3271 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000 != 0xFFFFFFFF)
3272 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000;
3273 #else
3274 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3275 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000 */
3276 break;
3277 case 0x09U:
3278 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001 != 0xFFFFFFFF)
3279 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001;
3280 #else
3281 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3282 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001 */
3283 break;
3284 case 0x0AU:
3285 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010 != 0xFFFFFFFF)
3286 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010;
3287 #else
3288 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3289 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010 */
3290 break;
3291 case 0x0BU:
3292 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011 != 0xFFFFFFFF)
3293 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011;
3294 #else
3295 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3296 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011 */
3297 break;
3298 case 0x0CU:
3299 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100 != 0xFFFFFFFF)
3300 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100;
3301 #else
3302 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3303 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100 */
3304 break;
3305 case 0x0DU:
3306 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101 != 0xFFFFFFFF)
3307 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101;
3308 #else
3309 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3310 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101 */
3311 break;
3312 case 0x0EU:
3313 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110 != 0xFFFFFFFF)
3314 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110;
3315 #else
3316 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3317 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110 */
3318 break;
3319 case 0x0FU:
3320 #if (FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111 != 0xFFFFFFFF)
3321 config->DFlashTotalSize = FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111;
3322 #else
3323 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3324 #endif /* FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111 */
3325 break;
3326 default:
3327 config->DFlashTotalSize = FLEX_NVM_DFLASH_SIZE_FOR_DEPART_RESERVED;
3328 break;
3329 }
3330
3331 return kStatus_FLASH_Success;
3332 }
3333 #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */
3334
3335 #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD
3336 /*! @brief Validates the range of the given resource address.*/
flash_check_resource_range(uint32_t start,uint32_t lengthInBytes,uint32_t alignmentBaseline,flash_read_resource_option_t option)3337 static status_t flash_check_resource_range(uint32_t start,
3338 uint32_t lengthInBytes,
3339 uint32_t alignmentBaseline,
3340 flash_read_resource_option_t option)
3341 {
3342 status_t status;
3343 uint32_t maxReadbleAddress;
3344
3345 if ((start & (alignmentBaseline - 1)) || (lengthInBytes & (alignmentBaseline - 1)))
3346 {
3347 return kStatus_FLASH_AlignmentError;
3348 }
3349
3350 status = kStatus_FLASH_Success;
3351
3352 maxReadbleAddress = start + lengthInBytes - 1;
3353 if (option == kFLASH_ResourceOptionVersionId)
3354 {
3355 if ((start != kFLASH_ResourceRangeVersionIdStart) ||
3356 ((start + lengthInBytes - 1) != kFLASH_ResourceRangeVersionIdEnd))
3357 {
3358 status = kStatus_FLASH_InvalidArgument;
3359 }
3360 }
3361 else if (option == kFLASH_ResourceOptionFlashIfr)
3362 {
3363 if (maxReadbleAddress < kFLASH_ResourceRangePflashIfrSizeInBytes)
3364 {
3365 }
3366 #if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP
3367 else if ((start >= kFLASH_ResourceRangePflashSwapIfrStart) &&
3368 (maxReadbleAddress <= kFLASH_ResourceRangePflashSwapIfrEnd))
3369 {
3370 }
3371 #endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */
3372 else if ((start >= kFLASH_ResourceRangeDflashIfrStart) &&
3373 (maxReadbleAddress <= kFLASH_ResourceRangeDflashIfrEnd))
3374 {
3375 }
3376 else
3377 {
3378 status = kStatus_FLASH_InvalidArgument;
3379 }
3380 }
3381 else
3382 {
3383 status = kStatus_FLASH_InvalidArgument;
3384 }
3385
3386 return status;
3387 }
3388 #endif /* FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD */
3389
3390 #if defined(FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD) && FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD
3391 /*! @brief Validates the gived swap control option.*/
flash_check_swap_control_option(flash_swap_control_option_t option)3392 static status_t flash_check_swap_control_option(flash_swap_control_option_t option)
3393 {
3394 if ((option == kFLASH_SwapControlOptionIntializeSystem) || (option == kFLASH_SwapControlOptionSetInUpdateState) ||
3395 (option == kFLASH_SwapControlOptionSetInCompleteState) || (option == kFLASH_SwapControlOptionReportStatus) ||
3396 (option == kFLASH_SwapControlOptionDisableSystem))
3397 {
3398 return kStatus_FLASH_Success;
3399 }
3400
3401 return kStatus_FLASH_InvalidArgument;
3402 }
3403 #endif /* FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD */
3404
3405 #if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP
3406 /*! @brief Validates the gived address to see if it is equal to swap indicator address in pflash swap IFR.*/
flash_validate_swap_indicator_address(flash_config_t * config,uint32_t address)3407 static status_t flash_validate_swap_indicator_address(flash_config_t *config, uint32_t address)
3408 {
3409 flash_swap_ifr_field_data_t flashSwapIfrFieldData;
3410 uint32_t swapIndicatorAddress;
3411
3412 status_t returnCode;
3413 #if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD
3414 returnCode =
3415 FLASH_ReadResource(config, kFLASH_ResourceRangePflashSwapIfrStart, flashSwapIfrFieldData.flashSwapIfrData,
3416 sizeof(flashSwapIfrFieldData.flashSwapIfrData), kFLASH_ResourceOptionFlashIfr);
3417
3418 if (returnCode != kStatus_FLASH_Success)
3419 {
3420 return returnCode;
3421 }
3422 #else
3423 {
3424 /* From RM, the actual info are stored in FCCOB6,7 */
3425 uint32_t returnValue[2];
3426 returnCode = FLASH_ReadOnce(config, kFLASH_RecordIndexSwapAddr, returnValue, 4);
3427 if (returnCode != kStatus_FLASH_Success)
3428 {
3429 return returnCode;
3430 }
3431 flashSwapIfrFieldData.flashSwapIfrField.swapIndicatorAddress = (uint16_t)returnValue[0];
3432 returnCode = FLASH_ReadOnce(config, kFLASH_RecordIndexSwapEnable, returnValue, 4);
3433 if (returnCode != kStatus_FLASH_Success)
3434 {
3435 return returnCode;
3436 }
3437 flashSwapIfrFieldData.flashSwapIfrField.swapEnableWord = (uint16_t)returnValue[0];
3438 returnCode = FLASH_ReadOnce(config, kFLASH_RecordIndexSwapDisable, returnValue, 4);
3439 if (returnCode != kStatus_FLASH_Success)
3440 {
3441 return returnCode;
3442 }
3443 flashSwapIfrFieldData.flashSwapIfrField.swapDisableWord = (uint16_t)returnValue[0];
3444 }
3445 #endif
3446
3447 /* The high bits value of Swap Indicator Address is stored in Program Flash Swap IFR Field,
3448 * the low severval bit value of Swap Indicator Address is always 1'b0 */
3449 swapIndicatorAddress = (uint32_t)flashSwapIfrFieldData.flashSwapIfrField.swapIndicatorAddress *
3450 FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT;
3451 if (address != swapIndicatorAddress)
3452 {
3453 return kStatus_FLASH_SwapIndicatorAddressError;
3454 }
3455
3456 return returnCode;
3457 }
3458 #endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */
3459
3460 #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
3461 /*! @brief Validates the gived flexram function option.*/
flasn_check_flexram_function_option_range(flash_flexram_function_option_t option)3462 static inline status_t flasn_check_flexram_function_option_range(flash_flexram_function_option_t option)
3463 {
3464 if ((option != kFLASH_FlexramFunctionOptionAvailableAsRam) &&
3465 (option != kFLASH_FlexramFunctionOptionAvailableForEeprom))
3466 {
3467 return kStatus_FLASH_InvalidArgument;
3468 }
3469
3470 return kStatus_FLASH_Success;
3471 }
3472 #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */
3473
3474 /*! @brief Gets the flash protection information (region size, region count).*/
flash_get_protection_info(flash_config_t * config,flash_protection_config_t * info)3475 static status_t flash_get_protection_info(flash_config_t *config, flash_protection_config_t *info)
3476 {
3477 uint32_t pflashTotalSize;
3478
3479 if ((config == NULL) || (info == NULL))
3480 {
3481 return kStatus_FLASH_InvalidArgument;
3482 }
3483
3484 /* Clean up info Structure*/
3485 memset(info, 0, sizeof(flash_protection_config_t));
3486
3487 /* Note: KW40 has a secondary flash, but it doesn't have independent protection register*/
3488 #if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && (!FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER)
3489 pflashTotalSize = MAIN_FLASH_FEATURE_PFLASH_BLOCK_COUNT * MAIN_FLASH_FEATURE_PFLASH_BLOCK_SIZE +
3490 FSL_FEATURE_FLASH_PFLASH_1_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SIZE;
3491 info->regionBase = MAIN_FLASH_FEATURE_PFLASH_START_ADDRESS;
3492 #else
3493 pflashTotalSize = config->PFlashTotalSize;
3494 info->regionBase = config->PFlashBlockBase;
3495 #endif
3496
3497 #if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER
3498 if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash)
3499 {
3500 info->regionCount = SECONDARY_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT;
3501 }
3502 else
3503 #endif
3504 {
3505 info->regionCount = MAIN_FLASH_FEATURE_PFLASH_PROTECTION_REGION_COUNT;
3506 }
3507
3508 /* Calculate the size of the flash protection region
3509 * If the flash density is > 32KB, then protection region is 1/32 of total flash density
3510 * Else if flash density is < 32KB, then flash protection region is set to 1KB */
3511 if (pflashTotalSize > info->regionCount * 1024)
3512 {
3513 info->regionSize = (pflashTotalSize) / info->regionCount;
3514 }
3515 else
3516 {
3517 info->regionSize = 1024;
3518 }
3519
3520 return kStatus_FLASH_Success;
3521 }
3522
3523 #if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL
3524 /*! @brief Gets the flash Execute-Only access information (Segment size, Segment count).*/
flash_get_access_info(flash_config_t * config,flash_access_config_t * info)3525 static status_t flash_get_access_info(flash_config_t *config, flash_access_config_t *info)
3526 {
3527 if ((config == NULL) || (info == NULL))
3528 {
3529 return kStatus_FLASH_InvalidArgument;
3530 }
3531
3532 /* Clean up info Structure*/
3533 memset(info, 0, sizeof(flash_access_config_t));
3534
3535 /* Note: KW40 has a secondary flash, but it doesn't have independent access register*/
3536 #if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && (!FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER)
3537 info->SegmentBase = MAIN_FLASH_FEATURE_PFLASH_START_ADDRESS;
3538 #else
3539 info->SegmentBase = config->PFlashBlockBase;
3540 #endif
3541 info->SegmentSize = config->PFlashAccessSegmentSize;
3542 info->SegmentCount = config->PFlashAccessSegmentCount;
3543
3544 return kStatus_FLASH_Success;
3545 }
3546 #endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */
3547