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