123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- /**
- * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
- *
- * SPDX-License-Identifier: Apache-2.0
- ******************************************************************************
- * @file drv_cache.c
- * @version V0.1
- * @brief cpu cache interface
- *
- * Change Logs:
- * Date Author Notes
- * 2019-04-01 Cliff.Chen first implementation
- *
- ******************************************************************************
- */
- /** @addtogroup RKBSP_Driver_Reference
- * @{
- */
- /** @addtogroup Cache
- * @{
- */
- /** @defgroup Cache_How_To_Use How To Use
- * @{
- The Cache driver use to keeping data coherent between cpu and device, it can be used in the following three scenarios:
- - **The cpu want to read the latest data that has been modified by device**:
- - The device modify the data;
- - The cpu invalidate the data by rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE,
- addr, size);
- - The cpu read the latest data;
- - **The device want to read the latest data that was modified by cpu**:
- - The cpu modify the data;
- - The device flush the data by rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, addr, size);
- - The device read the latest data;
- - **The cpu want to execute two code section on the same memory**:
- - Loading the code A in the memory from start address of ADDR;
- - Executing the code A;
- - Loading the code B in the memory from start address of ADDR;
- - Invalidating by rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, ADDR, size);
- - Executing the code B
- @} */
- #include <rthw.h>
- #include "drv_cache.h"
- #include "hal_base.h"
- #if defined(ARCH_ARM_CORTEX_M)
- #ifdef RT_USING_CMBACKTRACE
- #include "cm_backtrace.h"
- #endif
- /********************* Private MACRO Definition ******************************/
- /** @defgroup CACHE_Private_Macro Private Macro
- * @{
- */
- /** @} */ // CACHE_Private_Macro
- /********************* Private Structure Definition **************************/
- /** @defgroup CACHE_Private_Structure Private Structure
- * @{
- */
- /** @} */ // CACHE_Private_Structure
- /********************* Private Variable Definition ***************************/
- /** @defgroup CACHE_Private_Variable Private Variable
- * @{
- */
- /** @} */ // CACHE_Private_Variable
- /********************* Private Function Definition ***************************/
- /** @defgroup CACHE_Private_Function Private Function
- * @{
- */
- /** @} */ // CACHE_Private_Function
- /********************* Public Function Definition ****************************/
- /** @defgroup CACHE_Public_Functions Public Functions
- * @{
- */
- /**
- * @brief Enable the icache of cpu.
- * @attention The cache will be enabled when board initialization, do not dynamically switch cache
- * unless specifically required.
- */
- void rt_hw_cpu_icache_enable(void)
- {
- HAL_ICACHE_Enable();
- }
- /**
- * @brief Disable the icache of cpu.
- * @attention The cache will be enabled when board initialization, do not dynamically switch cache
- * unless specifically required.
- */
- void rt_hw_cpu_icache_disable(void)
- {
- HAL_ICACHE_Disable();
- }
- /**
- * @brief Get icache status.
- * @return 0
- * @attention Not yet implemnted.
- */
- rt_base_t rt_hw_cpu_icache_status(void)
- {
- return 0;
- }
- /**
- * @brief Icache maintain operation.
- * @param ops: RT_HW_CACHE_INVALIDATE for cache invalidate.
- * @param addr: The start address of memory you want maintain.
- * @param size: The length of memory you want maintain.
- */
- void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
- {
- if (ops & RT_HW_CACHE_INVALIDATE)
- {
- HAL_ICACHE_InvalidateByRange((uint32_t)addr, size);
- }
- }
- /**
- * @brief Enable the dcache of cpu.
- * @attention The cache will be enabled when board initialization, do not dynamically switch cache
- * unless specifically required.
- */
- void rt_hw_cpu_dcache_enable(void)
- {
- HAL_DCACHE_Enable();
- }
- /**
- * @brief Disable the dcache of cpu.
- * @attention The cache will be enabled when board initialization, do not dynamically switch cache
- * unless specifically required.
- */
- void rt_hw_cpu_dcache_disable(void)
- {
- HAL_DCACHE_Disable();
- }
- /**
- * @brief Get dcache status.
- * @return 0
- * @attention Not yet implemnted.
- */
- rt_base_t rt_hw_cpu_dcache_status(void)
- {
- return 0;
- }
- /**
- * @brief Dcache maintain operation.
- * @param ops: RT_HW_CACHE_INVALIDATE for cache invalidate,
- * RT_HW_CACHE_FLUSH for cache clean.
- * @param addr: The start address of memory you want maintain.
- * @param size: The length of memory you want maintain.
- */
- void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
- {
- if ((ops & RT_HW_CACHE_FLUSH) && (ops & RT_HW_CACHE_INVALIDATE))
- {
- HAL_DCACHE_CleanInvalidateByRange((uint32_t)addr, size);
- }
- else if (ops & RT_HW_CACHE_FLUSH)
- {
- HAL_DCACHE_CleanByRange((uint32_t)addr, size);
- }
- else if (ops & RT_HW_CACHE_INVALIDATE)
- {
- HAL_DCACHE_InvalidateByRange((uint32_t)addr, size);
- }
- else
- {
- RT_ASSERT(0);
- }
- }
- /**
- * @brief Dump ahb error occur in icache & dcache, it called by cache interrupt.
- * @param fault_handler_lr: The value of LR register.
- * @param fault_handler_sp: The value of SP register.
- */
- void cache_dump_ahb_error(uint32_t fault_handler_lr, uint32_t fault_handler_sp)
- {
- uint32_t addr;
- if (HAL_ICACHE_GetInt())
- {
- addr = HAL_ICACHE_GetErrAddr();
- rt_kprintf("a ahb bus error occur in icache, addr=%p\n", (void *)addr);
- HAL_ICACHE_ClearInt();
- }
- if (HAL_DCACHE_GetInt())
- {
- addr = HAL_DCACHE_GetErrAddr();
- rt_kprintf("a ahb bus error occur in dcache, addr=%p\n", (void *)addr);
- HAL_DCACHE_ClearInt();
- }
- #ifdef RT_USING_CMBACKTRACE
- cm_backtrace_fault(fault_handler_lr, fault_handler_sp);
- #endif
- }
- extern void CACHE_IRQHandler(void);
- /**
- * @brief Enable cache interrupt and register the handler, it called by board initialization.
- * @return RT_EOK
- */
- int rt_hw_cpu_cache_init(void)
- {
- #if defined(ICACHE) || defined(DCACHE)
- HAL_ICACHE_EnableInt();
- HAL_DCACHE_EnableInt();
- #if defined(RKMCU_PISCES) || defined(RKMCU_RK2108)
- rt_hw_interrupt_install(CACHE_IRQn, (rt_isr_handler_t)CACHE_IRQHandler, RT_NULL, RT_NULL);
- rt_hw_interrupt_umask(CACHE_IRQn);
- #elif defined(RKMCU_RK2206)
- rt_hw_interrupt_install(CACHE0_I_IRQn, (rt_isr_handler_t)CACHE_IRQHandler, RT_NULL, RT_NULL);
- rt_hw_interrupt_install(CACHE0_D_IRQn, (rt_isr_handler_t)CACHE_IRQHandler, RT_NULL, RT_NULL);
- rt_hw_interrupt_umask(CACHE0_I_IRQn);
- rt_hw_interrupt_umask(CACHE0_D_IRQn);
- #endif
- #endif
- return RT_EOK;
- }
- /** @} */ // CACHE_Public_Functions
- #else
- RT_WEAK void rt_hw_cpu_icache_enable(void)
- {
- }
- RT_WEAK void rt_hw_cpu_icache_disable(void)
- {
- }
- RT_WEAK rt_base_t rt_hw_cpu_icache_status(void)
- {
- return 0;
- }
- RT_WEAK void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
- {
- }
- RT_WEAK void rt_hw_cpu_dcache_enable(void)
- {
- }
- RT_WEAK void rt_hw_cpu_dcache_disable(void)
- {
- }
- RT_WEAK rt_base_t rt_hw_cpu_dcache_status(void)
- {
- return 0;
- }
- RT_WEAK void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
- {
- }
- #endif
- /** @} */ // Cache
- /** @} */ // RKBSP_Driver_Reference
|