123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567 |
- /*
- * The Clear BSD License
- * Copyright 2013-2016 Freescale Semiconductor, Inc.
- * Copyright 2016-2018 NXP
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted (subject to the limitations in the
- * disclaimer below) provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of the copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
- * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
- * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- #include "fsl_ftfx_cache.h"
- /*******************************************************************************
- * Definitions
- ******************************************************************************/
- /*!
- * @name Flash cache and speculation control defines
- * @{
- */
- #if defined(MCM_PLACR_CFCC_MASK)
- #define FLASH_CACHE_IS_CONTROLLED_BY_MCM (1)
- #else
- #define FLASH_CACHE_IS_CONTROLLED_BY_MCM (0)
- #endif
- #define FLASH_CACHE_IS_CONTROLLED_BY_MSCM (0)
- #if defined(FMC_PFB0CR_CINV_WAY_MASK) || defined(FMC_PFB01CR_CINV_WAY_MASK)
- #define FLASH_CACHE_IS_CONTROLLED_BY_FMC (1)
- #else
- #define FLASH_CACHE_IS_CONTROLLED_BY_FMC (0)
- #endif
- #if defined(MCM_PLACR_DFCS_MASK)
- #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM (1)
- #else
- #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM (0)
- #endif
- #if defined(MSCM_OCMDR_OCMC1_MASK) || defined(MSCM_OCMDR_OCM1_MASK) || defined(MSCM_OCMDR0_OCM1_MASK) || \
- defined(MSCM_OCMDR1_OCM1_MASK)
- #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM (1)
- #else
- #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM (0)
- #endif
- #if defined(FMC_PFB0CR_S_INV_MASK) || defined(FMC_PFB0CR_S_B_INV_MASK) || defined(FMC_PFB01CR_S_INV_MASK) || \
- defined(FMC_PFB01CR_S_B_INV_MASK)
- #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC (1)
- #else
- #define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC (0)
- #endif
- #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM || FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC || \
- FLASH_CACHE_IS_CONTROLLED_BY_MCM || FLASH_CACHE_IS_CONTROLLED_BY_FMC || FLASH_CACHE_IS_CONTROLLED_BY_MSCM
- #define FLASH_IS_CACHE_INVALIDATION_AVAILABLE (1)
- #else
- #define FLASH_IS_CACHE_INVALIDATION_AVAILABLE (0)
- #endif
- /*@}*/
- /*! @brief A function pointer used to point to relocated ftfx_common_bit_operation() */
- typedef void (*callftfxCommonBitOperation_t)(FTFx_REG32_ACCESS_TYPE base,
- uint32_t bitMask,
- uint32_t bitShift,
- uint32_t bitValue);
- /*******************************************************************************
- * Prototypes
- ******************************************************************************/
- #if FLASH_CACHE_IS_CONTROLLED_BY_MCM
- /*! @brief Performs the cache clear to the flash by MCM.*/
- void mcm_flash_cache_clear(ftfx_cache_config_t *config);
- #endif /* FLASH_CACHE_IS_CONTROLLED_BY_MCM */
- #if FLASH_CACHE_IS_CONTROLLED_BY_MSCM
- /*! @brief Performs the cache clear to the flash by MSCM.*/
- void mscm_flash_cache_clear(ftfx_cache_config_t *config);
- #endif /* FLASH_CACHE_IS_CONTROLLED_BY_MSCM */
- #if FLASH_CACHE_IS_CONTROLLED_BY_FMC
- /*! @brief Performs the cache clear to the flash by FMC.*/
- void fmc_flash_cache_clear(ftfx_cache_config_t *config);
- #endif /* FLASH_CACHE_IS_CONTROLLED_BY_FMC */
- #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
- /*! @brief Sets the prefetch speculation buffer to the flash by MSCM.*/
- void mscm_flash_prefetch_speculation_enable(ftfx_cache_config_t *config, bool enable);
- #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM */
- #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC
- /*! @brief Performs the prefetch speculation buffer clear to the flash by FMC.*/
- void fmc_flash_prefetch_speculation_clear(ftfx_cache_config_t *config);
- #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC */
- #if FTFx_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE
- /*! @brief Copy flash_cache_clear_command() to RAM*/
- static void ftfx_copy_common_bit_operation_to_ram(uint32_t *ftfxCommonBitOperation);
- #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
- /*******************************************************************************
- * Variables
- ******************************************************************************/
- #if FTFx_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE
- /*!
- * @brief Position independent code of ftfx_common_bit_operation()
- *
- * Note1: The prototype of C function is shown as below:
- * @code
- * void ftfx_common_bit_operation(FTFx_REG32_ACCESS_TYPE base, uint32_t bitMask, uint32_t bitShift, uint32_t
- * bitValue)
- * {
- * if (bitMask)
- * {
- * uint32_t value = (((uint32_t)(((uint32_t)(bitValue)) << bitShift)) & bitMask);
- * *base = (*base & (~bitMask)) | value;
- * }
- *
- * __ISB();
- * __DSB();
- * }
- * @endcode
- * Note2: The binary code is generated by IAR 7.70.1
- */
- static const uint16_t s_ftfxCommonBitOperationFunctionCode[] = {
- 0xb510, /* PUSH {R4, LR} */
- 0x2900, /* CMP R1, #0 */
- 0xd005, /* BEQ.N @12 */
- 0x6804, /* LDR R4, [R0] */
- 0x438c, /* BICS R4, R4, R1 */
- 0x4093, /* LSLS R3, R3, R2 */
- 0x4019, /* ANDS R1, R1, R3 */
- 0x4321, /* ORRS R1, R1, R4 */
- 0x6001, /* STR R1, [R0] */
- /* @12: */
- 0xf3bf, 0x8f6f, /* ISB */
- 0xf3bf, 0x8f4f, /* DSB */
- 0xbd10 /* POP {R4, PC} */
- };
- #if (!FTFx_DRIVER_IS_EXPORTED)
- /*! @brief A static buffer used to hold ftfx_common_bit_operation() */
- static uint32_t s_ftfxCommonBitOperation[kFTFx_CACHE_RamFuncMaxSizeInWords];
- #endif /* (!FTFx_DRIVER_IS_EXPORTED) */
- #endif /* FLASH_IS_CACHE_INVALIDATION_AVAILABLE && FTFx_DRIVER_IS_FLASH_RESIDENT */
- /*******************************************************************************
- * Code
- ******************************************************************************/
- status_t FTFx_CACHE_Init(ftfx_cache_config_t *config)
- {
- if (config == NULL)
- {
- return kStatus_FTFx_InvalidArgument;
- }
- /* copy required flash commands to RAM */
- #if FTFx_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE
- if (NULL == config->comBitOperFuncAddr)
- {
- #if FTFx_DRIVER_IS_EXPORTED
- return kStatus_FTFx_ExecuteInRamFunctionNotReady;
- #else
- config->comBitOperFuncAddr = s_ftfxCommonBitOperation;
- #endif /* FTFx_DRIVER_IS_EXPORTED */
- }
- ftfx_copy_common_bit_operation_to_ram(config->comBitOperFuncAddr);
- #endif /* FLASH_IS_CACHE_INVALIDATION_AVAILABLE && FTFx_DRIVER_IS_FLASH_RESIDENT */
- return kStatus_FTFx_Success;
- }
- /*!
- * @brief Flash Cache/Prefetch/Speculation Clear Process
- *
- * This function is used to perform the cache and prefetch speculation clear process to the flash.
- */
- status_t FTFx_CACHE_ClearCachePrefetchSpeculation(ftfx_cache_config_t *config, bool isPreProcess)
- {
- /* We pass the ftfx register address as a parameter to ftfx_common_bit_operation() instead of using
- * pre-processed MACROs or a global variable in ftfx_common_bit_operation()
- * to make sure that ftfx_common_bit_operation() will be compiled into position-independent code (PIC). */
- if (!isPreProcess)
- {
- #if FLASH_CACHE_IS_CONTROLLED_BY_MCM
- mcm_flash_cache_clear(config);
- #endif
- #if FLASH_CACHE_IS_CONTROLLED_BY_MSCM
- mscm_flash_cache_clear(config);
- #endif
- #if FLASH_CACHE_IS_CONTROLLED_BY_FMC
- fmc_flash_cache_clear(config);
- #endif
- #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
- mscm_flash_prefetch_speculation_enable(config, true);
- #endif
- #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC
- fmc_flash_prefetch_speculation_clear(config);
- #endif
- }
- if (isPreProcess)
- {
- #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
- mscm_flash_prefetch_speculation_enable(config, false);
- #endif
- }
- return kStatus_FTFx_Success;
- }
- status_t FTFx_CACHE_PflashSetPrefetchSpeculation(ftfx_prefetch_speculation_status_t *speculationStatus)
- {
- #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM
- {
- if (speculationStatus->instructionOff)
- {
- if (!speculationStatus->dataOff)
- {
- return kStatus_FTFx_InvalidSpeculationOption;
- }
- else
- {
- MCM0_CACHE_REG |= MCM_PLACR_DFCS_MASK;
- }
- }
- else
- {
- MCM0_CACHE_REG &= ~MCM_PLACR_DFCS_MASK;
- if (!speculationStatus->dataOff)
- {
- MCM0_CACHE_REG |= MCM_PLACR_EFDS_MASK;
- }
- else
- {
- MCM0_CACHE_REG &= ~MCM_PLACR_EFDS_MASK;
- }
- }
- }
- #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC
- {
- if (!speculationStatus->instructionOff)
- {
- FMC_CACHE_REG |= FMC_CACHE_B0IPE_MASK;
- }
- else
- {
- FMC_CACHE_REG &= ~FMC_CACHE_B0IPE_MASK;
- }
- if (!speculationStatus->dataOff)
- {
- FMC_CACHE_REG |= FMC_CACHE_B0DPE_MASK;
- }
- else
- {
- FMC_CACHE_REG &= ~FMC_CACHE_B0DPE_MASK;
- }
- /* Invalidate Prefetch Speculation Buffer */
- FMC_SPECULATION_INVALIDATE_REG |= FMC_SPECULATION_INVALIDATE_MASK;
- }
- #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
- {
- if (speculationStatus->instructionOff)
- {
- if (!speculationStatus->dataOff)
- {
- return kStatus_FTFx_InvalidSpeculationOption;
- }
- else
- {
- MSCM_OCMDR0_REG |= MSCM_OCMDR_OCMC1_DFCS_MASK;
- }
- }
- else
- {
- MSCM_OCMDR0_REG &= ~MSCM_OCMDR_OCMC1_DFCS_MASK;
- if (!speculationStatus->dataOff)
- {
- MSCM_OCMDR0_REG &= ~MSCM_OCMDR_OCMC1_DFDS_MASK;
- }
- else
- {
- MSCM_OCMDR0_REG |= MSCM_OCMDR_OCMC1_DFDS_MASK;
- }
- }
- }
- #endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */
- return kStatus_FTFx_Success;
- }
- status_t FTFx_CACHE_PflashGetPrefetchSpeculation(ftfx_prefetch_speculation_status_t *speculationStatus)
- {
- memset(speculationStatus, 0, sizeof(ftfx_prefetch_speculation_status_t));
- /* Assuming that all speculation options are enabled. */
- speculationStatus->instructionOff = false;
- speculationStatus->dataOff = false;
- #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM
- {
- uint32_t value = MCM0_CACHE_REG;
- if (value & MCM_PLACR_DFCS_MASK)
- {
- /* Speculation buffer is off. */
- speculationStatus->instructionOff = true;
- speculationStatus->dataOff = true;
- }
- else
- {
- /* Speculation buffer is on for instruction. */
- if (!(value & MCM_PLACR_EFDS_MASK))
- {
- /* Speculation buffer is off for data. */
- speculationStatus->dataOff = true;
- }
- }
- }
- #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC
- {
- uint32_t value = FMC_CACHE_REG;
- if (!(value & FMC_CACHE_B0DPE_MASK))
- {
- /* Do not prefetch in response to data references. */
- speculationStatus->dataOff = true;
- }
- if (!(value & FMC_CACHE_B0IPE_MASK))
- {
- /* Do not prefetch in response to instruction fetches. */
- speculationStatus->instructionOff = true;
- }
- }
- #elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
- {
- uint32_t value = MSCM_OCMDR0_REG;
- if (value & MSCM_OCMDR_OCMC1_DFCS_MASK)
- {
- /* Speculation buffer is off. */
- speculationStatus->instructionOff = true;
- speculationStatus->dataOff = true;
- }
- else
- {
- /* Speculation buffer is on for instruction. */
- if (value & MSCM_OCMDR_OCMC1_DFDS_MASK)
- {
- /* Speculation buffer is off for data. */
- speculationStatus->dataOff = true;
- }
- }
- }
- #endif
- return kStatus_FTFx_Success;
- }
- #if FTFx_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE
- /*! @brief Copy PIC of ftfx_common_bit_operation() to RAM */
- static void ftfx_copy_common_bit_operation_to_ram(uint32_t *ftfxCommonBitOperation)
- {
- assert(sizeof(s_ftfxCommonBitOperationFunctionCode) <= (kFTFx_CACHE_RamFuncMaxSizeInWords * 4));
- memcpy(ftfxCommonBitOperation, s_ftfxCommonBitOperationFunctionCode,
- sizeof(s_ftfxCommonBitOperationFunctionCode));
- }
- #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT && FLASH_IS_CACHE_INVALIDATION_AVAILABLE */
- #if FLASH_CACHE_IS_CONTROLLED_BY_MCM
- /*! @brief Performs the cache clear to the flash by MCM.*/
- void mcm_flash_cache_clear(ftfx_cache_config_t *config)
- {
- FTFx_REG32_ACCESS_TYPE regBase;
- #if defined(MCM0_CACHE_REG)
- regBase = (FTFx_REG32_ACCESS_TYPE)&MCM0_CACHE_REG;
- #elif defined(MCM1_CACHE_REG)
- regBase = (FTFx_REG32_ACCESS_TYPE)&MCM1_CACHE_REG;
- #endif
- #if FTFx_DRIVER_IS_FLASH_RESIDENT
- /* Since the value of ARM function pointer is always odd, but the real start address
- * of function memory should be even, that's why +1 operation exist. */
- callftfxCommonBitOperation_t callftfxCommonBitOperation = (callftfxCommonBitOperation_t)((uint32_t)config->comBitOperFuncAddr + 1);
- callftfxCommonBitOperation(regBase, MCM_CACHE_CLEAR_MASK, MCM_CACHE_CLEAR_SHIFT, 1U);
- #else /* !FTFx_DRIVER_IS_FLASH_RESIDENT */
- *regBase |= MCM_CACHE_CLEAR_MASK;
- /* Memory barriers for good measure.
- * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */
- __ISB();
- __DSB();
- #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
- }
- #endif /* FLASH_CACHE_IS_CONTROLLED_BY_MCM */
- #if FLASH_CACHE_IS_CONTROLLED_BY_MSCM
- /*! @brief Performs the cache clear to the flash by MSCM.*/
- void mscm_flash_cache_clear(ftfx_cache_config_t *config)
- {
- uint8_t setValue = 0x1U;
- /* The OCMDR[0] is always used to cache main Pflash*/
- /* For device with FlexNVM support, the OCMDR[1] is used to cache Dflash.
- * For device with secondary flash support, the OCMDR[1] is used to cache secondary Pflash. */
- #if FTFx_DRIVER_IS_FLASH_RESIDENT
- /* Since the value of ARM function pointer is always odd, but the real start address
- * of function memory should be even, that's why +1 operation exist. */
- callftfxCommonBitOperation_t callftfxCommonBitOperation = (callftfxCommonBitOperation_t)((uint32_t)config->comBitOperFuncAddr + 1);
- switch (config->flashMemoryIndex)
- {
- case kFLASH_MemoryIndexSecondaryFlash:
- callftfxCommonBitOperation((FTFx_REG32_ACCESS_TYPE)&MSCM_OCMDR1_REG, MSCM_CACHE_CLEAR_MASK,
- MSCM_CACHE_CLEAR_SHIFT, setValue);
- break;
- case kFLASH_MemoryIndexPrimaryFlash:
- default:
- callftfxCommonBitOperation((FTFx_REG32_ACCESS_TYPE)&MSCM_OCMDR0_REG, MSCM_CACHE_CLEAR_MASK,
- MSCM_CACHE_CLEAR_SHIFT, setValue);
- break;
- }
- #else /* !FTFx_DRIVER_IS_FLASH_RESIDENT */
- switch (config->flashMemoryIndex)
- {
- case kFLASH_MemoryIndexSecondaryFlash:
- MSCM_OCMDR1_REG = (MSCM_OCMDR1_REG & (~MSCM_CACHE_CLEAR_MASK)) | MSCM_CACHE_CLEAR(setValue);
- /* Each cahce clear instaruction should be followed by below code*/
- __ISB();
- __DSB();
- break;
- case kFLASH_MemoryIndexPrimaryFlash:
- default:
- MSCM_OCMDR0_REG = (MSCM_OCMDR0_REG & (~MSCM_CACHE_CLEAR_MASK)) | MSCM_CACHE_CLEAR(setValue);
- /* Memory barriers for good measure.
- * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */
- __ISB();
- __DSB();
- break;
- }
- #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
- }
- #endif /* FLASH_CACHE_IS_CONTROLLED_BY_MSCM */
- #if FLASH_CACHE_IS_CONTROLLED_BY_FMC
- /*! @brief Performs the cache clear to the flash by FMC.*/
- void fmc_flash_cache_clear(ftfx_cache_config_t *config)
- {
- #if FTFx_DRIVER_IS_FLASH_RESIDENT
- /* Since the value of ARM function pointer is always odd, but the real start address
- * of function memory should be even, that's why +1 operation exist. */
- callftfxCommonBitOperation_t callftfxCommonBitOperation = (callftfxCommonBitOperation_t)((uint32_t)config->comBitOperFuncAddr + 1);
- callftfxCommonBitOperation((FTFx_REG32_ACCESS_TYPE)&FMC_CACHE_REG, FMC_CACHE_CLEAR_MASK, FMC_CACHE_CLEAR_SHIFT, 0xFU);
- #else /* !FTFx_DRIVER_IS_FLASH_RESIDENT */
- FMC_CACHE_REG = (FMC_CACHE_REG & (~FMC_CACHE_CLEAR_MASK)) | FMC_CACHE_CLEAR(~0);
- /* Memory barriers for good measure.
- * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */
- __ISB();
- __DSB();
- #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
- }
- #endif /* FLASH_CACHE_IS_CONTROLLED_BY_FMC */
- #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM
- /*! @brief Performs the prefetch speculation buffer clear to the flash by MSCM.*/
- void mscm_flash_prefetch_speculation_enable(ftfx_cache_config_t *config, bool enable)
- {
- uint8_t setValue;
- if (enable)
- {
- setValue = 0x0U;
- }
- else
- {
- setValue = 0x3U;
- }
- /* The OCMDR[0] is always used to prefetch main Pflash*/
- /* For device with FlexNVM support, the OCMDR[1] is used to prefetch Dflash.
- * For device with secondary flash support, the OCMDR[1] is used to prefetch secondary Pflash. */
- #if FTFx_DRIVER_IS_FLASH_RESIDENT
- /* Since the value of ARM function pointer is always odd, but the real start address
- * of function memory should be even, that's why +1 operation exist. */
- callftfxCommonBitOperation_t callftfxCommonBitOperation = (callftfxCommonBitOperation_t)((uint32_t)config->comBitOperFuncAddr + 1);
- switch (config->flashMemoryIndex)
- {
- case 1:
- callftfxCommonBitOperation((FTFx_REG32_ACCESS_TYPE)&MSCM_OCMDR1_REG, MSCM_SPECULATION_SET_MASK,
- MSCM_SPECULATION_SET_SHIFT, setValue);
- break;
- case 0:
- default:
- callftfxCommonBitOperation((FTFx_REG32_ACCESS_TYPE)&MSCM_OCMDR0_REG, MSCM_SPECULATION_SET_MASK,
- MSCM_SPECULATION_SET_SHIFT, setValue);
- break;
- }
- #else /* !FTFx_DRIVER_IS_FLASH_RESIDENT */
- switch (config->flashMemoryIndex)
- {
- case kFLASH_MemoryIndexSecondaryFlash:
- MSCM_OCMDR1_REG = (MSCM_OCMDR1_REG & (~MSCM_SPECULATION_SET_MASK)) | MSCM_SPECULATION_SET(setValue);
- /* Each cahce clear instaruction should be followed by below code*/
- __ISB();
- __DSB();
- break;
- case kFLASH_MemoryIndexPrimaryFlash:
- default:
- MSCM_OCMDR0_REG = (MSCM_OCMDR0_REG & (~MSCM_SPECULATION_SET_MASK)) | MSCM_SPECULATION_SET(setValue);
- /* Memory barriers for good measure.
- * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */
- __ISB();
- __DSB();
- break;
- }
- #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
- }
- #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM */
- #if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC
- /*! @brief Performs the prefetch speculation buffer clear to the flash by FMC.*/
- void fmc_flash_prefetch_speculation_clear(ftfx_cache_config_t *config)
- {
- #if FTFx_DRIVER_IS_FLASH_RESIDENT
- /* Since the value of ARM function pointer is always odd, but the real start address
- * of function memory should be even, that's why +1 operation exist. */
- callftfxCommonBitOperation_t callftfxCommonBitOperation = (callftfxCommonBitOperation_t)((uint32_t)config->comBitOperFuncAddr + 1);
- callftfxCommonBitOperation((FTFx_REG32_ACCESS_TYPE)&FMC_SPECULATION_INVALIDATE_REG, FMC_SPECULATION_INVALIDATE_MASK, FMC_SPECULATION_INVALIDATE_SHIFT, 1U);
- #else /* !FTFx_DRIVER_IS_FLASH_RESIDENT */
- FMC_SPECULATION_INVALIDATE_REG |= FMC_SPECULATION_INVALIDATE_MASK;
- /* Memory barriers for good measure.
- * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */
- __ISB();
- __DSB();
- #endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */
- }
- #endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC */
|