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