1 /*
2 * Copyright 2013-2016 Freescale Semiconductor, Inc.
3 * Copyright 2016-2020 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 *
8 */
9
10 #include "fsl_ftfx_cache.h"
11
12 /*******************************************************************************
13 * Definitions
14 ******************************************************************************/
15
16 /* Component ID definition, used by tools. */
17 #ifndef FSL_COMPONENT_ID
18 #define FSL_COMPONENT_ID "platform.drivers.flash"
19 #endif
20
21 /*!
22 * @name Flash cache and speculation control defines
23 * @{
24 */
25 #if defined(MCM_PLACR_CFCC_MASK)
26 #define FLASH_CACHE_IS_CONTROLLED_BY_MCM (1u)
27 #else
28 #define FLASH_CACHE_IS_CONTROLLED_BY_MCM (0u)
29 #endif
30
31 #define FLASH_CACHE_IS_CONTROLLED_BY_MSCM (0u)
32
33 #if defined(FMC_PFB0CR_CINV_WAY_MASK) || defined(FMC_PFB01CR_CINV_WAY_MASK)
34 #define FLASH_CACHE_IS_CONTROLLED_BY_FMC (1u)
35 #else
36 #define FLASH_CACHE_IS_CONTROLLED_BY_FMC (0u)
37 #endif
38
39 #if defined(MCM_PLACR_DFCS_MASK)
40 #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM (1u)
41 #else
42 #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM (0u)
43 #endif
44
45 #if defined(MSCM_OCMDR_OCMC1_MASK) || defined(MSCM_OCMDR_OCM1_MASK) || defined(MSCM_OCMDR0_OCM1_MASK) || \
46 defined(MSCM_OCMDR1_OCM1_MASK)
47 #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM (1u)
48 #else
49 #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM (0u)
50 #endif
51
52 #if defined(FMC_PFB0CR_S_INV_MASK) || defined(FMC_PFB0CR_S_B_INV_MASK) || defined(FMC_PFB01CR_S_INV_MASK) || \
53 defined(FMC_PFB01CR_S_B_INV_MASK)
54 #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC (1u)
55 #else
56 #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC (0u)
57 #endif
58
59 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM || FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC || \
60 FLASH_CACHE_IS_CONTROLLED_BY_MCM || FLASH_CACHE_IS_CONTROLLED_BY_FMC || FLASH_CACHE_IS_CONTROLLED_BY_MSCM
61 #define FLASH_IS_CACHE_INVALIDATION_AVAILABLE (1)
62 #else
63 #define FLASH_IS_CACHE_INVALIDATION_AVAILABLE (0u)
64 #endif
65 /*@}*/
66
67 /*! @brief A function pointer used to point to relocated ftfx_common_bit_operation() */
68 typedef void (*callftfxCommonBitOperation_t)(FTFx_REG32_ACCESS_TYPE base,
69 uint32_t bitMask,
70 uint32_t bitShift,
71 uint32_t bitValue);
72
73 /*******************************************************************************
74 * Prototypes
75 ******************************************************************************/
76
77 #if FLASH_CACHE_IS_CONTROLLED_BY_MCM
78 /*! @brief Performs the cache clear to the flash by MCM.*/
79 void mcm_flash_cache_clear(ftfx_cache_config_t *config);
80 #endif /* FLASH_CACHE_IS_CONTROLLED_BY_MCM */
81
82 #if FLASH_CACHE_IS_CONTROLLED_BY_MSCM
83 /*! @brief Performs the cache clear to the flash by MSCM.*/
84 void mscm_flash_cache_clear(ftfx_cache_config_t *config);
85 #endif /* FLASH_CACHE_IS_CONTROLLED_BY_MSCM */
86
87 #if FLASH_CACHE_IS_CONTROLLED_BY_FMC
88 /*! @brief Performs the cache clear to the flash by FMC.*/
89 void fmc_flash_cache_clear(ftfx_cache_config_t *config);
90 #endif /* FLASH_CACHE_IS_CONTROLLED_BY_FMC */
91
92 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
93 /*! @brief Sets the prefetch speculation buffer to the flash by MSCM.*/
94 void mscm_flash_prefetch_speculation_enable(ftfx_cache_config_t *config, bool enable);
95 #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM */
96
97 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC
98 /*! @brief Performs the prefetch speculation buffer clear to the flash by FMC.*/
99 void fmc_flash_prefetch_speculation_clear(ftfx_cache_config_t *config);
100 #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC */
101
102 #if FTFx_DRIVER_IS_FLASH_RESIDENT && \
103 (FLASH_CACHE_IS_CONTROLLED_BY_MCM || FLASH_CACHE_IS_CONTROLLED_BY_MSCM || \
104 FLASH_CACHE_IS_CONTROLLERD_BY_FMC || FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM || \
105 FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC)
106 static void ftfx_common_bit_operation_command_sequence(
107 ftfx_cache_config_t *config, FTFx_REG32_ACCESS_TYPE base, uint32_t bitMask, uint32_t bitShift, uint32_t bitValue);
108 #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
109
110 #if FTFx_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE
111 /*! @brief Copy flash_cache_clear_command() to RAM*/
112 static void ftfx_copy_common_bit_operation_to_ram(uint32_t *ftfxCommonBitOperation);
113 #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
114
115 /*******************************************************************************
116 * Variables
117 ******************************************************************************/
118
119 #if FTFx_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE
120 /*!
121 * @brief Position independent code of ftfx_common_bit_operation()
122 *
123 * Note1: The prototype of C function is shown as below:
124 * @code
125 * void ftfx_common_bit_operation(FTFx_REG32_ACCESS_TYPE base, uint32_t bitMask, uint32_t bitShift, uint32_t
126 * bitValue)
127 * {
128 * if (bitMask)
129 * {
130 * uint32_t value = (((uint32_t)(((uint32_t)(bitValue)) << bitShift)) & bitMask);
131 * *base = (*base & (~bitMask)) | value;
132 * }
133 *
134 * __ISB();
135 * __DSB();
136 * }
137 * @endcode
138 * Note2: The binary code is generated by IAR 7.70.1
139 */
140 static const uint32_t s_ftfxCommonBitOperationFunctionCode[] = {
141 0x2900b510u, 0x6804d005u, 0x4093438cu, 0x43214019u, 0xf3bf6001u, 0xf3bf8f6fu, 0xbd108f4fu,
142 };
143
144 #if (!FTFx_DRIVER_IS_EXPORTED)
145 /*! @brief A static buffer used to hold ftfx_common_bit_operation() */
146 static uint32_t s_ftfxCommonBitOperation[kFTFx_CACHE_RamFuncMaxSizeInWords];
147 #endif /* (!FTFx_DRIVER_IS_EXPORTED) */
148 #endif /* FLASH_IS_CACHE_INVALIDATION_AVAILABLE && FTFx_DRIVER_IS_FLASH_RESIDENT */
149
150 /*******************************************************************************
151 * Code
152 ******************************************************************************/
153
FTFx_CACHE_Init(ftfx_cache_config_t * config)154 status_t FTFx_CACHE_Init(ftfx_cache_config_t *config)
155 {
156 if (config == NULL)
157 {
158 return kStatus_FTFx_InvalidArgument;
159 }
160
161 /* copy required flash commands to RAM */
162 #if FTFx_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE
163 if (NULL == config->bitOperFuncAddr.callFlashCommand)
164 {
165 #if FTFx_DRIVER_IS_EXPORTED
166 return kStatus_FTFx_ExecuteInRamFunctionNotReady;
167 #else
168 config->bitOperFuncAddr.commadAddr = (uint32_t)s_ftfxCommonBitOperation;
169 #endif /* FTFx_DRIVER_IS_EXPORTED */
170 }
171
172 ftfx_copy_common_bit_operation_to_ram((uint32_t *)config->bitOperFuncAddr.commadAddr);
173 #endif /* FLASH_IS_CACHE_INVALIDATION_AVAILABLE && FTFx_DRIVER_IS_FLASH_RESIDENT */
174
175 return kStatus_FTFx_Success;
176 }
177
178 /*!
179 * @brief Flash Cache/Prefetch/Speculation Clear Process
180 *
181 * This function is used to perform the cache and prefetch speculation clear process to the flash.
182 */
FTFx_CACHE_ClearCachePrefetchSpeculation(ftfx_cache_config_t * config,bool isPreProcess)183 status_t FTFx_CACHE_ClearCachePrefetchSpeculation(ftfx_cache_config_t *config, bool isPreProcess)
184 {
185 /* We pass the ftfx register address as a parameter to ftfx_common_bit_operation() instead of using
186 * pre-processed MACROs or a global variable in ftfx_common_bit_operation()
187 * to make sure that ftfx_common_bit_operation() will be compiled into position-independent code (PIC). */
188 if (!isPreProcess)
189 {
190 #if FLASH_CACHE_IS_CONTROLLED_BY_MCM
191 mcm_flash_cache_clear(config);
192 #endif
193 #if FLASH_CACHE_IS_CONTROLLED_BY_MSCM
194 mscm_flash_cache_clear(config);
195 #endif
196 #if FLASH_CACHE_IS_CONTROLLED_BY_FMC
197 fmc_flash_cache_clear(config);
198 #endif
199 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
200 mscm_flash_prefetch_speculation_enable(config, true);
201 #endif
202 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC
203 fmc_flash_prefetch_speculation_clear(config);
204 #endif
205 }
206 if (isPreProcess)
207 {
208 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
209 mscm_flash_prefetch_speculation_enable(config, false);
210 #endif
211 }
212
213 return kStatus_FTFx_Success;
214 }
215
FTFx_CACHE_PflashSetPrefetchSpeculation(ftfx_prefetch_speculation_status_t * speculationStatus)216 status_t FTFx_CACHE_PflashSetPrefetchSpeculation(ftfx_prefetch_speculation_status_t *speculationStatus)
217 {
218 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM
219 {
220 if (true == speculationStatus->instructionOff)
221 {
222 if (false == speculationStatus->dataOff)
223 {
224 return kStatus_FTFx_InvalidSpeculationOption;
225 }
226 else
227 {
228 MCM0_CACHE_REG |= MCM_PLACR_DFCS_MASK;
229 }
230 }
231 else
232 {
233 MCM0_CACHE_REG &= ~MCM_PLACR_DFCS_MASK;
234 if (false == speculationStatus->dataOff)
235 {
236 MCM0_CACHE_REG |= MCM_PLACR_EFDS_MASK;
237 }
238 else
239 {
240 MCM0_CACHE_REG &= ~MCM_PLACR_EFDS_MASK;
241 }
242 }
243 }
244 #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC
245 {
246 if (false == speculationStatus->instructionOff)
247 {
248 FMC_CACHE_REG |= FMC_CACHE_B0IPE_MASK;
249 }
250 else
251 {
252 FMC_CACHE_REG &= ~FMC_CACHE_B0IPE_MASK;
253 }
254 if (false == speculationStatus->dataOff)
255 {
256 FMC_CACHE_REG |= FMC_CACHE_B0DPE_MASK;
257 }
258 else
259 {
260 FMC_CACHE_REG &= ~FMC_CACHE_B0DPE_MASK;
261 }
262
263 /* Invalidate Prefetch Speculation Buffer */
264 FMC_SPECULATION_INVALIDATE_REG |= FMC_SPECULATION_INVALIDATE_MASK;
265 }
266 #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
267 {
268 if (true == speculationStatus->instructionOff)
269 {
270 if (false == speculationStatus->dataOff)
271 {
272 return kStatus_FTFx_InvalidSpeculationOption;
273 }
274 else
275 {
276 MSCM_OCMDR0_REG |= MSCM_OCMDR_OCMC1_DFCS_MASK;
277 }
278 }
279 else
280 {
281 MSCM_OCMDR0_REG &= ~MSCM_OCMDR_OCMC1_DFCS_MASK;
282 if (false == speculationStatus->dataOff)
283 {
284 MSCM_OCMDR0_REG &= ~MSCM_OCMDR_OCMC1_DFDS_MASK;
285 }
286 else
287 {
288 MSCM_OCMDR0_REG |= MSCM_OCMDR_OCMC1_DFDS_MASK;
289 }
290 }
291 }
292 #endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */
293
294 return kStatus_FTFx_Success;
295 }
296
FTFx_CACHE_PflashGetPrefetchSpeculation(ftfx_prefetch_speculation_status_t * speculationStatus)297 status_t FTFx_CACHE_PflashGetPrefetchSpeculation(ftfx_prefetch_speculation_status_t *speculationStatus)
298 {
299 (void)memset(speculationStatus, 0, sizeof(ftfx_prefetch_speculation_status_t));
300
301 /* Assuming that all speculation options are enabled. */
302 speculationStatus->instructionOff = false;
303 speculationStatus->dataOff = false;
304
305 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM
306 {
307 uint32_t value = MCM0_CACHE_REG;
308 if (0U != (value & MCM_PLACR_DFCS_MASK))
309 {
310 /* Speculation buffer is off. */
311 speculationStatus->instructionOff = true;
312 speculationStatus->dataOff = true;
313 }
314 else
315 {
316 /* Speculation buffer is on for instruction. */
317 if (0U == (value & MCM_PLACR_EFDS_MASK))
318 {
319 /* Speculation buffer is off for data. */
320 speculationStatus->dataOff = true;
321 }
322 }
323 }
324 #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC
325 {
326 uint32_t value = FMC_CACHE_REG;
327 if (0U == (value & FMC_CACHE_B0DPE_MASK))
328 {
329 /* Do not prefetch in response to data references. */
330 speculationStatus->dataOff = true;
331 }
332 if (0U == (value & FMC_CACHE_B0IPE_MASK))
333 {
334 /* Do not prefetch in response to instruction fetches. */
335 speculationStatus->instructionOff = true;
336 }
337 }
338 #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
339 {
340 uint32_t value = MSCM_OCMDR0_REG;
341 if (0U != (value & MSCM_OCMDR_OCMC1_DFCS_MASK))
342 {
343 /* Speculation buffer is off. */
344 speculationStatus->instructionOff = true;
345 speculationStatus->dataOff = true;
346 }
347 else
348 {
349 /* Speculation buffer is on for instruction. */
350 if (0U != (value & MSCM_OCMDR_OCMC1_DFDS_MASK))
351 {
352 /* Speculation buffer is off for data. */
353 speculationStatus->dataOff = true;
354 }
355 }
356 }
357 #endif
358
359 return kStatus_FTFx_Success;
360 }
361
362 #if FTFx_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE
363 /*! @brief Copy PIC of ftfx_common_bit_operation() to RAM */
ftfx_copy_common_bit_operation_to_ram(uint32_t * ftfxCommonBitOperation)364 static void ftfx_copy_common_bit_operation_to_ram(uint32_t *ftfxCommonBitOperation)
365 {
366 assert(sizeof(s_ftfxCommonBitOperationFunctionCode) <= ((uint32_t)kFTFx_CACHE_RamFuncMaxSizeInWords * 4U));
367
368 (void)memcpy(ftfxCommonBitOperation, s_ftfxCommonBitOperationFunctionCode,
369 sizeof(s_ftfxCommonBitOperationFunctionCode));
370 }
371 #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE */
372
373 #if FTFx_DRIVER_IS_FLASH_RESIDENT && \
374 (FLASH_CACHE_IS_CONTROLLED_BY_MCM || FLASH_CACHE_IS_CONTROLLED_BY_MSCM || \
375 FLASH_CACHE_IS_CONTROLLED_BY_FMC || FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM || \
376 FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC)
ftfx_common_bit_operation_command_sequence(ftfx_cache_config_t * config,FTFx_REG32_ACCESS_TYPE base,uint32_t bitMask,uint32_t bitShift,uint32_t bitValue)377 static void ftfx_common_bit_operation_command_sequence(
378 ftfx_cache_config_t *config, FTFx_REG32_ACCESS_TYPE base, uint32_t bitMask, uint32_t bitShift, uint32_t bitValue)
379 {
380 uint32_t *ftfxCommonBitOperationAddr;
381 ftfxCommonBitOperationAddr = &config->bitOperFuncAddr.commadAddr;
382 /* Since the value of ARM function pointer is always odd, but the real start
383 * address
384 * of function memory should be even, that's why +1 operation exist. */
385 *ftfxCommonBitOperationAddr += 1UL;
386 callftfxCommonBitOperation_t ftfxCommonBitOperationCommand = config->bitOperFuncAddr.callFlashCommand;
387 /* Workround for some devices which doesn't need this function */
388 ftfxCommonBitOperationCommand((FTFx_REG32_ACCESS_TYPE)base, bitMask, bitShift, bitValue);
389 *ftfxCommonBitOperationAddr -= 1UL;
390 }
391 #endif /*FTFx_DRIVER_IS_FLASH_RESIDENT*/
392
393 #if FLASH_CACHE_IS_CONTROLLED_BY_MCM
394 /*! @brief Performs the cache clear to the flash by MCM.*/
mcm_flash_cache_clear(ftfx_cache_config_t * config)395 void mcm_flash_cache_clear(ftfx_cache_config_t *config)
396 {
397 FTFx_REG32_ACCESS_TYPE regBase;
398
399 #if defined(MCM0_CACHE_REG)
400 regBase = (FTFx_REG32_ACCESS_TYPE)&MCM0_CACHE_REG;
401 #elif defined(MCM1_CACHE_REG)
402 regBase = (FTFx_REG32_ACCESS_TYPE)&MCM1_CACHE_REG;
403 #endif
404
405 #if FTFx_DRIVER_IS_FLASH_RESIDENT
406 /* calling flash command sequence function to execute the command */
407 ftfx_common_bit_operation_command_sequence(config, regBase, MCM_CACHE_CLEAR_MASK, MCM_CACHE_CLEAR_SHIFT, 1UL);
408
409 #else /* !FTFx_DRIVER_IS_FLASH_RESIDENT */
410 *regBase |= MCM_CACHE_CLEAR_MASK;
411
412 /* Memory barriers for good measure.
413 * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */
414 __ISB();
415 __DSB();
416 #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
417 }
418 #endif /* FLASH_CACHE_IS_CONTROLLED_BY_MCM */
419
420 #if FLASH_CACHE_IS_CONTROLLED_BY_MSCM
421 /*! @brief Performs the cache clear to the flash by MSCM.*/
mscm_flash_cache_clear(ftfx_cache_config_t * config)422 void mscm_flash_cache_clear(ftfx_cache_config_t *config)
423 {
424 uint8_t setValue = 0x1U;
425
426 /* The OCMDR[0] is always used to cache main Pflash*/
427 /* For device with FlexNVM support, the OCMDR[1] is used to cache Dflash.
428 * For device with secondary flash support, the OCMDR[1] is used to cache secondary Pflash. */
429 #if FTFx_DRIVER_IS_FLASH_RESIDENT
430 switch (config->flashMemoryIndex)
431 {
432 case kFLASH_MemoryIndexSecondaryFlash:
433 /* calling flash command sequence function to execute the command */
434 ftfx_common_bit_operation_command_sequence(config, (FTFx_REG32_ACCESS_TYPE)&MSCM_OCMDR1_REG,
435 MSCM_CACHE_CLEAR_MASK, MSCM_CACHE_CLEAR_SHIFT, setValue);
436 break;
437 case kFLASH_MemoryIndexPrimaryFlash:
438 default:
439 /* calling flash command sequence function to execute the command */
440 ftfx_common_bit_operation_command_sequence(config, (FTFx_REG32_ACCESS_TYPE)&MSCM_OCMDR0_REG,
441 MSCM_CACHE_CLEAR_MASK, MSCM_CACHE_CLEAR_SHIFT, setValue);
442 break;
443 }
444 #else /* !FTFx_DRIVER_IS_FLASH_RESIDENT */
445 switch (config->flashMemoryIndex)
446 {
447 case kFLASH_MemoryIndexSecondaryFlash:
448 MSCM_OCMDR1_REG = (MSCM_OCMDR1_REG & (~MSCM_CACHE_CLEAR_MASK)) | MSCM_CACHE_CLEAR(setValue);
449 /* Each cache clear instruction should be followed by below code*/
450 __ISB();
451 __DSB();
452 break;
453 case kFLASH_MemoryIndexPrimaryFlash:
454 default:
455 MSCM_OCMDR0_REG = (MSCM_OCMDR0_REG & (~MSCM_CACHE_CLEAR_MASK)) | MSCM_CACHE_CLEAR(setValue);
456 /* Memory barriers for good measure.
457 * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */
458 __ISB();
459 __DSB();
460 break;
461 }
462 #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
463 }
464 #endif /* FLASH_CACHE_IS_CONTROLLED_BY_MSCM */
465
466 #if FLASH_CACHE_IS_CONTROLLED_BY_FMC
467 /*! @brief Performs the cache clear to the flash by FMC.*/
fmc_flash_cache_clear(ftfx_cache_config_t * config)468 void fmc_flash_cache_clear(ftfx_cache_config_t *config)
469 {
470 #if FTFx_DRIVER_IS_FLASH_RESIDENT
471 /* calling flash command sequence function to execute the command */
472 ftfx_common_bit_operation_command_sequence(config, (FTFx_REG32_ACCESS_TYPE)&FMC_CACHE_REG, FMC_CACHE_CLEAR_MASK,
473 FMC_CACHE_CLEAR_SHIFT, 0xFUL);
474 #else /* !FTFx_DRIVER_IS_FLASH_RESIDENT */
475 FMC_CACHE_REG = (FMC_CACHE_REG & (~FMC_CACHE_CLEAR_MASK)) | FMC_CACHE_CLEAR(~0);
476 /* Memory barriers for good measure.
477 * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */
478 __ISB();
479 __DSB();
480 #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
481 }
482 #endif /* FLASH_CACHE_IS_CONTROLLED_BY_FMC */
483
484 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
485 /*! @brief Performs the prefetch speculation buffer clear to the flash by MSCM.*/
mscm_flash_prefetch_speculation_enable(ftfx_cache_config_t * config,bool enable)486 void mscm_flash_prefetch_speculation_enable(ftfx_cache_config_t *config, bool enable)
487 {
488 uint8_t setValue;
489 if (enable)
490 {
491 setValue = 0x0U;
492 }
493 else
494 {
495 setValue = 0x3U;
496 }
497
498 /* The OCMDR[0] is always used to prefetch main Pflash*/
499 /* For device with FlexNVM support, the OCMDR[1] is used to prefetch Dflash.
500 * For device with secondary flash support, the OCMDR[1] is used to prefetch secondary Pflash. */
501 #if FTFx_DRIVER_IS_FLASH_RESIDENT
502
503 switch (config->flashMemoryIndex)
504 {
505 case 1:
506 /* calling flash command sequence function to execute the command */
507 ftfx_common_bit_operation_command_sequence(config, (FTFx_REG32_ACCESS_TYPE)&MSCM_OCMDR1_REG,
508 MSCM_SPECULATION_SET_MASK, MSCM_SPECULATION_SET_SHIFT, setValue);
509 break;
510 case 0:
511 default:
512 /* calling flash command sequence function to execute the command */
513 ftfx_common_bit_operation_command_sequence(config, (FTFx_REG32_ACCESS_TYPE)&MSCM_OCMDR0_REG,
514 MSCM_SPECULATION_SET_MASK, MSCM_SPECULATION_SET_SHIFT, setValue);
515 break;
516 }
517 #else /* !FTFx_DRIVER_IS_FLASH_RESIDENT */
518 switch (config->flashMemoryIndex)
519 {
520 case kFLASH_MemoryIndexSecondaryFlash:
521 MSCM_OCMDR1_REG = (MSCM_OCMDR1_REG & (~MSCM_SPECULATION_SET_MASK)) | MSCM_SPECULATION_SET(setValue);
522 /* Each cache clear instruction should be followed by below code*/
523 __ISB();
524 __DSB();
525 break;
526 case kFLASH_MemoryIndexPrimaryFlash:
527 default:
528 MSCM_OCMDR0_REG = (MSCM_OCMDR0_REG & (~MSCM_SPECULATION_SET_MASK)) | MSCM_SPECULATION_SET(setValue);
529 /* Memory barriers for good measure.
530 * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */
531 __ISB();
532 __DSB();
533 break;
534 }
535 #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
536 }
537 #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM */
538
539 #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC
540 /*! @brief Performs the prefetch speculation buffer clear to the flash by FMC.*/
fmc_flash_prefetch_speculation_clear(ftfx_cache_config_t * config)541 void fmc_flash_prefetch_speculation_clear(ftfx_cache_config_t *config)
542 {
543 #if FTFx_DRIVER_IS_FLASH_RESIDENT
544 /* calling flash command sequence function to execute the command */
545 ftfx_common_bit_operation_command_sequence(config, (FTFx_REG32_ACCESS_TYPE)&FMC_SPECULATION_INVALIDATE_REG,
546 FMC_SPECULATION_INVALIDATE_MASK, FMC_SPECULATION_INVALIDATE_SHIFT, 1UL);
547 #else /* !FTFx_DRIVER_IS_FLASH_RESIDENT */
548 FMC_SPECULATION_INVALIDATE_REG |= FMC_SPECULATION_INVALIDATE_MASK;
549 /* Memory barriers for good measure.
550 * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */
551 __ISB();
552 __DSB();
553 #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
554 }
555 #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC */
556