This commit is contained in:
thomas committed 2026-10-18 14:06:40 +02:00
commit 2c2202e60d
2491 files changed
+1295990

No files matched your search

@@ -0,0 +1,512 @@
/**
******************************************************************************
* @file stm32h7rsxx_hal_icache.c
* @author MCD Application Team
* @brief ICACHE HAL module driver.
* This file provides firmware functions to manage the following
* functionalities of the Instruction Cache (ICACHE).
* + Initialization and Configuration
* + Invalidate functions
* + Monitoring management
* + Memory address remap management
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
@verbatim
==============================================================================
##### ICACHE main features #####
==============================================================================
[..]
The Texture Cache (ICACHE) is introduced on AXI read-only texture port of
the GPU2D to improve performance when reading texture data from internal and
external memories.
===============================================================================
##### How to use this driver #####
===============================================================================
[..]
The ICACHE HAL driver can be used as follows:
(#) Optionally configure the Instruction Cache mode with
HAL_ICACHE_ConfigAssociativityMode() if the default configuration
does not suit the application requirements.
(#) Enable and disable the Instruction Cache with respectively
HAL_ICACHE_Enable() and HAL_ICACHE_Disable().
Use HAL_ICACHE_IsEnabled() to get the Instruction Cache status.
To ensure a deterministic cache behavior after power on, system reset or after
a call to @ref HAL_ICACHE_Disable(), the application must call
@ref HAL_ICACHE_WaitForInvalidateComplete(). Indeed on power on, system reset
or cache disable, an automatic cache invalidation procedure is launched and the
cache is bypassed until the operation completes.
(#) Initiate the cache maintenance invalidation procedure with either
HAL_ICACHE_Invalidate() (blocking mode) or HAL_ICACHE_Invalidate_IT()
(interrupt mode). When interrupt mode is used, the callback function
HAL_ICACHE_InvalidateCompleteCallback() is called when the invalidate
procedure is complete. The function HAL_ICACHE_WaitForInvalidateComplete()
may be called to wait for the end of the invalidate procedure automatically
initiated when disabling the Instruction Cache with HAL_ICACHE_Disable().
The cache operation is bypassed during the invalidation procedure.
(#) Use the performance monitoring counters for Hit and Miss with the following
functions: HAL_ICACHE_Monitor_Start(), HAL_ICACHE_Monitor_Stop(),
HAL_ICACHE_Monitor_Reset(), HAL_ICACHE_Monitor_GetHitValue() and
HAL_ICACHE_Monitor_GetMissValue()
@endverbatim
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32h7rsxx_hal.h"
/** @addtogroup STM32H7RSxx_HAL_Driver
* @{
*/
/** @defgroup ICACHE ICACHE
* @brief HAL ICACHE module driver
* @{
*/
#if defined(ICACHE) && defined (HAL_ICACHE_MODULE_ENABLED)
/* Private typedef -----------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/** @addtogroup ICACHE_Private_Constants ICACHE Private Constants
* @{
*/
#define ICACHE_INVALIDATE_TIMEOUT_VALUE 1U /* 1ms */
#define ICACHE_DISABLE_TIMEOUT_VALUE 1U /* 1ms */
/**
* @}
*/
/* Private macros ------------------------------------------------------------*/
/** @defgroup ICACHE_Private_Macros ICACHE Private Macros
* @{
*/
#define IS_ICACHE_ASSOCIATIVITY_MODE(__MODE__) (((__MODE__) == ICACHE_1WAY) || \
((__MODE__) == ICACHE_4WAYS))
#define IS_ICACHE_MONITOR_TYPE(__TYPE__) (((__TYPE__) == ICACHE_MONITOR_HIT_MISS) || \
((__TYPE__) == ICACHE_MONITOR_HIT) || \
((__TYPE__) == ICACHE_MONITOR_MISS))
/**
* @}
*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup ICACHE_Exported_Functions ICACHE Exported Functions
* @{
*/
/** @defgroup ICACHE_Exported_Functions_Group1 Initialization and control functions
* @brief Initialization and control functions
*
@verbatim
==============================================================================
##### Initialization and control functions #####
==============================================================================
[..]
This section provides functions allowing to initialize and control the
Instruction Cache (mode, invalidate procedure, performance counters).
@endverbatim
* @{
*/
/**
* @brief Configure the Instruction Cache cache associativity mode selection.
* @param AssociativityMode Associativity mode selection
* This parameter can be one of the following values:
* @arg ICACHE_1WAY 1-way cache (direct mapped cache)
* @arg ICACHE_4WAYS 4-ways set associative cache (default)
* @retval HAL status (HAL_OK/HAL_ERROR)
*/
HAL_StatusTypeDef HAL_ICACHE_ConfigAssociativityMode(uint32_t AssociativityMode)
{
HAL_StatusTypeDef status = HAL_OK;
/* Check the parameters */
assert_param(IS_ICACHE_ASSOCIATIVITY_MODE(AssociativityMode));
/* Check cache is not enabled */
if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
{
status = HAL_ERROR;
}
else
{
MODIFY_REG(ICACHE->CR, ICACHE_CR_WAYSEL, AssociativityMode);
}
return status;
}
/**
* @brief DeInitialize the Instruction Cache.
* @retval HAL status (HAL_OK)
*/
HAL_StatusTypeDef HAL_ICACHE_DeInit(void)
{
/* Reset interrupt enable value */
WRITE_REG(ICACHE->IER, 0U);
/* Clear any pending flags */
WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF | ICACHE_FCR_CERRF);
/* Disable cache then set default associative mode value */
CLEAR_BIT(ICACHE->CR, ICACHE_CR_EN);
WRITE_REG(ICACHE->CR, ICACHE_CR_WAYSEL);
/* Stop monitor and reset monitor values */
CLEAR_BIT(ICACHE->CR, ICACHE_MONITOR_HIT_MISS);
SET_BIT(ICACHE->CR, (ICACHE_MONITOR_HIT_MISS << 2U));
CLEAR_BIT(ICACHE->CR, (ICACHE_MONITOR_HIT_MISS << 2U));
return HAL_OK;
}
/**
* @brief Enable the Instruction Cache.
* @note This function always returns HAL_OK even if there is any ongoing
* cache operation. The Instruction Cache is bypassed until the
* cache operation completes.
* @retval HAL status (HAL_OK)
*/
HAL_StatusTypeDef HAL_ICACHE_Enable(void)
{
SET_BIT(ICACHE->CR, ICACHE_CR_EN);
return HAL_OK;
}
/**
* @brief Disable the Instruction Cache.
* @note This function waits for the cache being disabled but
* not for the end of the automatic cache invalidation procedure.
* @retval HAL status (HAL_OK/HAL_TIMEOUT)
*/
HAL_StatusTypeDef HAL_ICACHE_Disable(void)
{
HAL_StatusTypeDef status = HAL_OK;
uint32_t tickstart;
/* Make sure BSYENDF is reset before to disable the instruction cache */
/* as it automatically starts a cache invalidation procedure */
WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
CLEAR_BIT(ICACHE->CR, ICACHE_CR_EN);
/* Get tick */
tickstart = HAL_GetTick();
/* Wait for instruction cache being disabled */
while (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
{
if ((HAL_GetTick() - tickstart) > ICACHE_DISABLE_TIMEOUT_VALUE)
{
/* New check to avoid false timeout detection in case of preemption */
if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U)
{
status = HAL_TIMEOUT;
break;
}
}
}
return status;
}
/**
* @brief Check whether the Instruction Cache is enabled or not.
* @retval Status (0: disabled, 1: enabled)
*/
uint32_t HAL_ICACHE_IsEnabled(void)
{
return ((READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U) ? 1UL : 0UL);
}
/**
* @brief Invalidate the Instruction Cache.
* @note This function waits for the end of cache invalidation procedure
* and clears the associated BSYENDF flag.
* @retval HAL status (HAL_OK/HAL_ERROR/HAL_TIMEOUT)
*/
HAL_StatusTypeDef HAL_ICACHE_Invalidate(void)
{
HAL_StatusTypeDef status;
/* Check if no ongoing operation */
if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) == 0U)
{
/* Launch cache invalidation */
SET_BIT(ICACHE->CR, ICACHE_CR_CACHEINV);
}
status = HAL_ICACHE_WaitForInvalidateComplete();
return status;
}
/**
* @brief Invalidate the Instruction Cache with interrupt.
* @note This function launches cache invalidation and returns.
* User application shall resort to interrupt generation to check
* the end of the cache invalidation with the BSYENDF flag and the
* HAL_ICACHE_InvalidateCompleteCallback() callback.
* @retval HAL status (HAL_OK/HAL_ERROR)
*/
HAL_StatusTypeDef HAL_ICACHE_Invalidate_IT(void)
{
HAL_StatusTypeDef status = HAL_OK;
/* Check no ongoing operation */
if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) != 0U)
{
status = HAL_ERROR;
}
else
{
/* Make sure BSYENDF is reset before to start cache invalidation */
WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
/* Enable end of cache invalidation interrupt */
SET_BIT(ICACHE->IER, ICACHE_IER_BSYENDIE);
/* Launch cache invalidation */
SET_BIT(ICACHE->CR, ICACHE_CR_CACHEINV);
}
return status;
}
/**
* @brief Wait for the end of the Instruction Cache invalidate procedure.
* @note This function checks and clears the BSYENDF flag when set.
* @retval HAL status (HAL_OK/HAL_TIMEOUT)
*/
HAL_StatusTypeDef HAL_ICACHE_WaitForInvalidateComplete(void)
{
HAL_StatusTypeDef status = HAL_OK;
uint32_t tickstart;
/* Check if ongoing invalidation operation */
if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) != 0U)
{
/* Get tick */
tickstart = HAL_GetTick();
/* Wait for end of cache invalidation */
while (READ_BIT(ICACHE->SR, ICACHE_SR_BSYENDF) == 0U)
{
if ((HAL_GetTick() - tickstart) > ICACHE_INVALIDATE_TIMEOUT_VALUE)
{
/* New check to avoid false timeout detection in case of preemption */
if (READ_BIT(ICACHE->SR, ICACHE_SR_BSYENDF) == 0U)
{
status = HAL_TIMEOUT;
break;
}
}
}
}
/* Clear BSYENDF */
WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
return status;
}
/**
* @brief Start the Instruction Cache performance monitoring.
* @param MonitorType Monitoring type
* This parameter can be one of the following values:
* @arg ICACHE_MONITOR_HIT_MISS Hit & Miss monitoring
* @arg ICACHE_MONITOR_HIT Hit monitoring
* @arg ICACHE_MONITOR_MISS Miss monitoring
* @retval HAL status (HAL_OK)
*/
HAL_StatusTypeDef HAL_ICACHE_Monitor_Start(uint32_t MonitorType)
{
/* Check the parameters */
assert_param(IS_ICACHE_MONITOR_TYPE(MonitorType));
SET_BIT(ICACHE->CR, MonitorType);
return HAL_OK;
}
/**
* @brief Stop the Instruction Cache performance monitoring.
* @note Stopping the monitoring does not reset the values.
* @param MonitorType Monitoring type
* This parameter can be one of the following values:
* @arg ICACHE_MONITOR_HIT_MISS Hit & Miss monitoring
* @arg ICACHE_MONITOR_HIT Hit monitoring
* @arg ICACHE_MONITOR_MISS Miss monitoring
* @retval HAL status (HAL_OK)
*/
HAL_StatusTypeDef HAL_ICACHE_Monitor_Stop(uint32_t MonitorType)
{
/* Check the parameters */
assert_param(IS_ICACHE_MONITOR_TYPE(MonitorType));
CLEAR_BIT(ICACHE->CR, MonitorType);
return HAL_OK;
}
/**
* @brief Reset the Instruction Cache performance monitoring values.
* @param MonitorType Monitoring type
* This parameter can be one of the following values:
* @arg ICACHE_MONITOR_HIT_MISS Hit & Miss monitoring
* @arg ICACHE_MONITOR_HIT Hit monitoring
* @arg ICACHE_MONITOR_MISS Miss monitoring
* @retval HAL status (HAL_OK)
*/
HAL_StatusTypeDef HAL_ICACHE_Monitor_Reset(uint32_t MonitorType)
{
/* Check the parameters */
assert_param(IS_ICACHE_MONITOR_TYPE(MonitorType));
/* Force/Release reset */
SET_BIT(ICACHE->CR, (MonitorType << 2U));
CLEAR_BIT(ICACHE->CR, (MonitorType << 2U));
return HAL_OK;
}
/**
* @brief Get the Instruction Cache performance Hit monitoring value.
* @note Upon reaching the 32-bit maximum value, monitor does not wrap.
* @retval Hit monitoring value
*/
uint32_t HAL_ICACHE_Monitor_GetHitValue(void)
{
return (ICACHE->HMONR);
}
/**
* @brief Get the Instruction Cache performance Miss monitoring value.
* @note Upon reaching the 32-bit maximum value, monitor does not wrap.
* @retval Miss monitoring value
*/
uint32_t HAL_ICACHE_Monitor_GetMissValue(void)
{
return (ICACHE->MMONR);
}
/**
* @}
*/
/** @defgroup ICACHE_Exported_Functions_Group2 IRQ and callback functions
* @brief IRQ and callback functions
*
@verbatim
==============================================================================
##### IRQ and callback functions #####
==============================================================================
[..]
This section provides functions allowing to handle ICACHE global interrupt
and the associated callback functions.
@endverbatim
* @{
*/
/**
* @brief Handle the Instruction Cache interrupt request.
* @note This function should be called under the ICACHE_IRQHandler().
* @note This function respectively disables the interrupt and clears the
* flag of any pending flag before calling the associated user callback.
* @retval None
*/
void HAL_ICACHE_IRQHandler(void)
{
/* Get current interrupt flags and interrupt sources value */
uint32_t itflags = READ_REG(ICACHE->SR);
uint32_t itsources = READ_REG(ICACHE->IER);
/* Check Instruction cache Error interrupt flag */
if (((itflags & itsources) & ICACHE_FLAG_ERROR) != 0U)
{
/* Disable error interrupt */
CLEAR_BIT(ICACHE->IER, ICACHE_IER_ERRIE);
/* Clear ERR pending flag */
WRITE_REG(ICACHE->FCR, ICACHE_FCR_CERRF);
/* Instruction cache error interrupt user callback */
HAL_ICACHE_ErrorCallback();
}
/* Check Instruction cache BusyEnd interrupt flag */
if (((itflags & itsources) & ICACHE_FLAG_BUSYEND) != 0U)
{
/* Disable end of cache invalidation interrupt */
CLEAR_BIT(ICACHE->IER, ICACHE_IER_BSYENDIE);
/* Clear BSYENDF pending flag */
WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF);
/* Instruction cache busyend interrupt user callback */
HAL_ICACHE_InvalidateCompleteCallback();
}
}
/**
* @brief Cache invalidation complete callback.
*/
__weak void HAL_ICACHE_InvalidateCompleteCallback(void)
{
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_ICACHE_InvalidateCompleteCallback() should be implemented in the user file
*/
}
/**
* @brief Error callback.
*/
__weak void HAL_ICACHE_ErrorCallback(void)
{
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_ICACHE_ErrorCallback() should be implemented in the user file
*/
}
/**
* @}
*/
/**
* @}
*/
#endif /* ICACHE && HAL_ICACHE_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/