/* * Copyright (C) 2024 ZHUHAI TAIXIN Co., Ltd. All rights reserved. * */ /****************************************************************************** * @file cld_cahce.h * @brief cldache Access Layer Header File * @version V1.0 * @date 2024.5.29 ******************************************************************************/ #ifndef __CLD_CACHE_H_GENERIC #define __CLD_CACHE_H_GENERIC #include #include #ifdef __cplusplus extern "C" { #endif /******************************************************************************* * definitions ******************************************************************************/ /** \ingroup @{ */ /* definitions */ typedef struct { __I uint32_t HWPARAMS; //0x000 __I uint32_t reserve0[3]; //0x004-0x00c __IO uint32_t CTRL; //0x010 __I uint32_t NSEC_ACCESS; //0x014 __I uint32_t reserve1[2]; //0x018-0x01c __O uint32_t MAINT_CTRL_ALL; //0x020 __O uint32_t MAINT_CTRL_LINES; //0x024 __I uint32_t MAINT_STATUS; //0x028 __I uint32_t reserve2[53]; //0x02c-0x0fc __I uint32_t SECIRQSTAT; //0x100; __O uint32_t SECIRQSCLR; //0x104; __IO uint32_t SECIRQEN; //0x108; __I uint32_t SECIRQINFO1; //0x10C; __I uint32_t SECIRQINFO2; //0x110; __I uint32_t reserve3[11]; //0x114-0x13c __I uint32_t NSECIRQSTAT; //0x140; __O uint32_t NSECIRQSCLR; //0x144; __IO uint32_t NSECIRQEN; //0x148; __I uint32_t NSECIRQINFO1; //0x14C; __I uint32_t NSECIRQINFO2; //0x150; __I uint32_t reserve4[107]; //0x154-0x2fc __I uint32_t SECHIT; //0x300; __I uint32_t SECMISS; //0x304; __IO uint32_t SECSTATCTRL; //0x308; __I uint32_t reserve5[1]; //0x30c __I uint32_t NSECHIT; //0x310; __I uint32_t NSECMISS; //0x314; __IO uint32_t NSECSTATCTRL; //0x318; __I uint32_t reserve6[813]; //0x31c-0xFCC __I uint32_t PIDR4; //0xFD0; __I uint32_t PIDR5; //0xFD4; __I uint32_t PIDR6; //0xFD8; __I uint32_t PIDR7; //0xFDC; __I uint32_t PIDR0; //0xFE0; __I uint32_t PIDR1; //0xFE4; __I uint32_t PIDR2; //0xFE8; __I uint32_t PIDR3; //0xFEC; __I uint32_t CIDR0; //0xFF0; __I uint32_t CIDR1; //0xFF4; __I uint32_t CIDR2; //0xFF8; __I uint32_t CIDR3; //0xFFC; } DCACHE_CTRL_TypeDef; #define DCACHE_CTRL_BASE2 ((uint32_t)0x50000000) #define DCACHE_CTRL ((DCACHE_CTRL_TypeDef *) DCACHE_CTRL_BASE2) /* THE memory is forced non-sec */ #define DCACHE_MAINT_NO_SEC ((uint32_t)0x00000004) #define DCACHE_STA_ENABLE ((uint32_t)0x00000001) #define DCACHE_STA_ONGOING_EN ((uint32_t)0x00000002) #define DCACHE_STA_ONGOING_MAINT ((uint32_t)0x00000004) #define DCACHE_STA_ONGOING_PWR_MAINT ((uint32_t)0x00000008) #define DCACHE_STA_IS_CLEAN ((uint32_t)0x00000010) static inline uint32_t cld_cache_get_status(void) { return DCACHE_CTRL->MAINT_STATUS; } static inline uint32_t cld_cache_is_maint_done(void) { return (0x4 == (DCACHE_CTRL->SECIRQSTAT & 0xC)); } static inline uint32_t cld_cache_is_maint_ignore(void) { return (DCACHE_CTRL->SECIRQSTAT & 0x8); } static inline void cld_cache_clr_maint_done(void) { DCACHE_CTRL->SECIRQSCLR = 0x4; } static inline void cld_cache_clr_maint_ignore(void) { DCACHE_CTRL->SECIRQSCLR = 0x8; } static inline void cld_cache_clr_all_pending(void) { DCACHE_CTRL->SECIRQSCLR = 0xFF; } static inline uint32_t cld_cache_is_enable(void) { return DCACHE_CTRL->MAINT_STATUS & DCACHE_STA_ENABLE; } static inline uint32_t cld_cache_is_clean(void) { return DCACHE_CTRL->MAINT_STATUS & DCACHE_STA_IS_CLEAN; } static inline uint32_t cld_cache_is_ongoing_enable(void) { return DCACHE_CTRL->MAINT_STATUS & DCACHE_STA_ONGOING_EN; } static inline uint32_t cld_cache_is_ongoing_maint(void) { return DCACHE_CTRL->MAINT_STATUS & DCACHE_STA_ONGOING_MAINT; } static inline uint32_t cld_cache_is_ongoing_pwr_maint(void) { return DCACHE_CTRL->MAINT_STATUS & DCACHE_STA_ONGOING_PWR_MAINT; } static inline uint32_t cld_cache_is_ongoing(void) { return DCACHE_CTRL->MAINT_STATUS & (DCACHE_STA_ONGOING_PWR_MAINT | DCACHE_STA_ONGOING_MAINT | DCACHE_STA_ONGOING_EN); } static inline void cld_cache_force_write_through(void) { DCACHE_CTRL->CTRL |= 1UL << 1; } /* TXW82x S_NS ONLY */ #define CLD_CACHE_MAINT_OPT_ATOMIC(opt)\ do {\ uint32 __disable_irq(void);\ void __enable_irq(void);\ uint32 flag = __disable_irq();\ cld_cache_clr_all_pending();\ opt;\ while (!cld_cache_is_maint_done());\ if(!flag) __enable_irq();\ } while (0); #define CLD_CACHE_MAINT_OPT(opt)\ do {\ cld_cache_clr_all_pending();\ opt;\ while (!cld_cache_is_maint_done());\ } while (0); #define CLD_CACHE_MAINT_OPT_WAIT() //do { while (cld_cache_is_ongoing_maint()); } while (0) #define CLD_CACHE_MAINT_FB_KICKOFF()\ do {\ extern uint32 psram_rsv_addr;\ CLD_CACHE_MAINT_OPT_ATOMIC(DCACHE_CTRL->MAINT_CTRL_LINES = (psram_rsv_addr & 0xFFFFFFE0) | 0x2 | DCACHE_MAINT_NO_SEC;);\ *(uint32 volatile*)((uint32_t)psram_rsv_addr);\ } while(0) static inline void cld_cache_clean_all(void) { CLD_CACHE_MAINT_OPT_ATOMIC(DCACHE_CTRL->MAINT_CTRL_ALL = 1;); } static inline void cld_cache_invalidate_all(void) { CLD_CACHE_MAINT_OPT_ATOMIC(DCACHE_CTRL->MAINT_CTRL_ALL = 2;); } static inline void cld_cache_clean_invalidate_all(void) { CLD_CACHE_MAINT_OPT_ATOMIC(DCACHE_CTRL->MAINT_CTRL_ALL = 3;); } static inline void cld_cache_disable(void) { __DSB(); cld_cache_invalidate_all(); DCACHE_CTRL->CTRL &= ~(1UL << 0); while (cld_cache_is_enable()); while (cld_cache_is_ongoing_maint()); } static inline void cld_cache_enable(void) { cld_cache_disable(); /* deny powerdown \ enable nsec stat、 maintain lines */ DCACHE_CTRL->CTRL |= 1UL << 0 | 0x10 | 0x70000; while (!cld_cache_is_enable()); } static inline void cld_cache_irq_enable(void) { /* ONLY ERROR : XOM_ERR(not support) & TR_ERR */ DCACHE_CTRL->SECIRQEN = 0x90; } static inline void cld_cache_clean_line(uint32_t addr) { CLD_CACHE_MAINT_OPT_ATOMIC(DCACHE_CTRL->MAINT_CTRL_LINES = ((uint32_t)addr & (0xFFFFFFFF << 5)) | 0x1 | DCACHE_MAINT_NO_SEC;); CLD_CACHE_MAINT_OPT_WAIT(); } /** \brief D-Cache Clean by address \details Cleans D-Cache for the given address \param[in] addr address (aligned to 32-byte boundary) \param[in] dsize size of memory block (in number of bytes) */ static inline void cld_cache_clean_range (uint32_t *addr, int32_t dsize) { int32_t op_size = ((uint32_t)addr & 0x1F) + dsize; uint32_t op_addr = (uint32_t)addr & (0xFFFFFFFF << 5); int32_t linesize = 32; op_addr |= 0x1 | DCACHE_MAINT_NO_SEC; while (op_size > 0) { CLD_CACHE_MAINT_OPT_ATOMIC(DCACHE_CTRL->MAINT_CTRL_LINES = op_addr; op_addr += linesize; op_size -= linesize;); CLD_CACHE_MAINT_OPT_WAIT(); } __DSB(); } /** \brief D-Cache Clean and Invalidate by address \details Cleans and invalidates D_Cache for the given address \param[in] addr address (aligned to 32-byte boundary) \param[in] dsize size of memory block (in number of bytes) */ static inline void cld_cache_clean_invalid_range (uint32_t *addr, int32_t dsize) { int32_t op_size = ((uint32_t)addr & 0x1F) + dsize; uint32_t op_addr = (uint32_t)addr & (0xFFFFFFFF << 5); int32_t linesize = 32; op_addr |= 0x3 | DCACHE_MAINT_NO_SEC; while (op_size > 0) { CLD_CACHE_MAINT_OPT_ATOMIC(DCACHE_CTRL->MAINT_CTRL_LINES = op_addr; op_addr += linesize; op_size -= linesize;); CLD_CACHE_MAINT_OPT_WAIT(); } __DSB(); } /** \brief D-Cache Invalidate by address \details Cleans and invalidates D_Cache for the given address \param[in] addr address (aligned to 32-byte boundary) \param[in] dsize size of memory block (in number of bytes) */ static inline void cld_cache_invalid_range (uint32_t *addr, int32_t dsize) { int32_t op_size = ((uint32_t)addr & 0x1F) + dsize; uint32_t op_addr = (uint32_t)addr & (0xFFFFFFFF << 5); int32_t linesize = 32; op_addr |= 0x2 | DCACHE_MAINT_NO_SEC; CLD_CACHE_MAINT_FB_KICKOFF(); while (op_size > 0) { CLD_CACHE_MAINT_OPT_ATOMIC(DCACHE_CTRL->MAINT_CTRL_LINES = op_addr; op_addr += linesize; op_size -= linesize;); CLD_CACHE_MAINT_OPT_WAIT(); } __DSB(); } static inline uint32_t cld_cache_get_nsec_hits(void) { return DCACHE_CTRL->NSECHIT; } static inline uint32_t cld_cache_get_nsec_miss(void) { return DCACHE_CTRL->NSECMISS; } static inline void cld_cache_reset_profile(void) { DCACHE_CTRL->NSECSTATCTRL |= 0x2; } static inline void cld_cache_enable_profile(void) { while (cld_cache_is_ongoing()); DCACHE_CTRL->NSECSTATCTRL |= 0x1; } static inline void cld_cache_disable_profile(void) { DCACHE_CTRL->NSECSTATCTRL &= ~ 0x1; } #ifdef __cplusplus } #endif #endif /* __CLD_CACHE_H_GENERIC */