Files
BPI-CM9-Linux/aml-comp/uboot/bl30/rtos_sdk/soc/riscv/riscv_cache.h
T

663 lines
18 KiB
C

/*
* Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
*
* SPDX-License-Identifier: MIT
*/
#ifndef RISCV_CACHE_H
#define RISCV_CACHE_H
#include "riscv_encoding.h"
#define MCACHE_CTL_IC_EN (1<<0)
#define MCACHE_CTL_IC_SCPD_MOD (1<<1)
#define MCACHE_CTL_IC_ECC_EN (1<<2)
#define MCACHE_CTL_IC_ECC_EXCP_EN (1<<3)
#define MCACHE_CTL_IC_TRAM_ECC_INJ_EN (1<<4)
#define MCACHE_CTL_IC_RWTECC (1<<4)
#define MCACHE_CTL_IC_RWDECC (1<<5)
#define MCACHE_CTL_IC_DRAM_ECC_INJ_EN (1<<5)
#define MCACHE_CTL_IC_PF_EN (1<<6)
#define MCACHE_CTL_IC_CANCEL_EN (1<<7)
#define MCACHE_CTL_IC_ECC_CHK_EN (1<<8)
#define MCACHE_CTL_DC_EN (1<<16)
#define MCACHE_CTL_DC_ECC_EN (1<<17)
#define MCACHE_CTL_DC_ECC_EXCP_EN (1<<18)
#define MCACHE_CTL_DC_TRAM_ECC_INJ_EN (1<<19)
#define MCACHE_CTL_DC_RWTECC (1<<19)
#define MCACHE_CTL_DC_RWDECC (1<<20)
#define MCACHE_CTL_DC_DRAM_ECC_INJ_EN (1<<20)
#define MCACHE_CTL_DC_ECC_CHK_EN (1<<21)
#define MCFG_INFO_ICACHE (1<<9)
#define MCFG_INFO_DCACHE (1<<10)
#define __FENCE(p, s) __asm volatile ("fence " #p "," #s : : : "memory")
#define __RWMB() __FENCE(iorw, iorw)
/*!< Lock Succeed */
/*!< Exceed the number of lockable ways(N-Way I/D-Cache, lockable is N-1) */
/*!< PMP/sPMP/Page-Table X(I-Cache)/R(D-Cache) permission check failed,
* or belong to Device/Non-Cacheable address range
*/
/*!< Refill has Bus Error */
typedef enum CCM_OP_FINFO {
CCM_OP_SUCCESS = 0x0,
CCM_OP_EXCEED_ERR = 0x1,
CCM_OP_PERM_CHECK_ERR = 0x2,
CCM_OP_REFILL_BUS_ERR = 0x3,
} CCM_OP_FINFO_Type;
/*!< Unlock and invalidate D-Cache line specified by CSR CCM_XBEGINADDR */
/*!< Flush the specific D-Cache line specified by CSR CCM_XBEGINADDR */
/*!< Unlock, flush and invalidate the specific D-Cache line specified by CSR CCM_XBEGINADDR */
/*!< Lock the specific D-Cache line specified by CSR CCM_XBEGINADDR */
/*!< Unlock the specific D-Cache line specified by CSR CCM_XBEGINADDR */
/*!< Unlock and flush and invalidate all the valid and dirty D-Cache lines */
/*!< Flush all the valid and dirty D-Cache lines */
/*!< Unlock and invalidate all the D-Cache lines */
/*!< Unlock and invalidate I-Cache line specified by CSR CCM_XBEGINADDR */
/*!< Lock the specific I-Cache line specified by CSR CCM_XBEGINADDR */
/*!< Unlock the specific I-Cache line specified by CSR CCM_XBEGINADDR */
/*!< Unlock and invalidate all the I-Cache lines */
typedef enum CCM_CMD {
CCM_DC_INVAL = 0x0,
CCM_DC_WB = 0x1,
CCM_DC_WBINVAL = 0x2,
CCM_DC_LOCK = 0x3,
CCM_DC_UNLOCK = 0x4,
CCM_DC_WBINVAL_ALL = 0x6,
CCM_DC_WB_ALL = 0x7,
CCM_DC_INVAL_ALL = 0x17,
CCM_IC_INVAL = 0x8,
CCM_IC_LOCK = 0xb,
CCM_IC_UNLOCK = 0xc,
CCM_IC_INVAL_ALL = 0xd
} CCM_CMD_Type;
/**
* brief Flush pipeline after CCM operation
* details
* This function is used to flush pipeline after CCM operations
* on Cache, it will ensure latest instructions or data can be
* seen by pipeline.
* remarks
* This function can be called in M/S/U-Mode only.
*/
static inline void vFlushPipeCCM(void)
{
write_csr(ccm_fpipe, 0x1);
}
/**
* brief Check DCache Unit Present or Not
* details
* This function check dcache unit present or not via mcfg_info csr
* remarks
* This function might not work for some old nuclei processors
* Please make sure the version of your nuclei processor contain DCACHE bit in mcfg_info
* return 1 if present otherwise 0
*/
static inline uint32_t ulDCachePresent(void)
{
if (read_csr(mcfg_info) & MCFG_INFO_DCACHE)
return 1;
return 0;
}
/**
* brief Enable DCache
* details
* This function enable D-Cache
* remarks
* This function can be called in M-Mode only.
* This \ref mcache_ctl register control D Cache enable.
* sa
* ref vDisableDCache
*/
static inline void vEnableDCache(void)
{
set_csr(mcache_ctl, MCACHE_CTL_DC_EN);
}
/**
* brief Disable DCache
* details
* This function Disable D-Cache
* remarks
* This function can be called in M-Mode only.
* This \ref mcache_ctl register control D Cache enable.
* sa
* ref vEnableDCache
*/
static inline void vDisableDCache(void)
{
clear_csr(mcache_ctl, MCACHE_CTL_DC_EN);
}
/**
* brief Enable DCache ECC
* details
* This function enable D-Cache ECC
* remarks
* This function can be called in M-Mode only.
* This \ref mcache_ctl register control D Cache ECC enable.
* sa
* ref vDisableDCacheECC
*/
static inline void vEnableDCacheECC(void)
{
set_csr(mcache_ctl, MCACHE_CTL_DC_ECC_EN);
}
/**
* brief Disable DCache ECC
* details
* This function disable D-Cache ECC
* remarks
* This function can be called in M-Mode only.
* This \ref mcache_ctl register control D Cache ECC enable.
* sa
* ref EnableDCacheECC
*/
static inline void vDisableDCacheECC(void)
{
clear_csr(mcache_ctl, MCACHE_CTL_DC_ECC_EN);
}
/**
* brief Invalidate one D-Cache line specified by address in M-Mode
* details
* This function unlock and invalidate one D-Cache line specified
* by the address.
* Command \ref CCM_DC_INVAL is written to CSR \ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be invalidated
*/
static inline void vMInvalDCacheLine(unsigned long addr)
{
write_csr(ccm_mbeginaddr, addr);
write_csr(ccm_mcommand, CCM_DC_INVAL);
vFlushPipeCCM();
__RWMB();
}
/**
* brief Invalidate several D-Cache lines specified by address in M-Mode
* details
* This function unlock and invalidate several D-Cache lines specified
* by the address and line count.
* Command \ref CCM_DC_INVAL is written to CSR \ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be invalidated
* param [in] cnt count of cache lines to be invalidated
*/
static inline void vMInvalDCacheLines(unsigned long addr, unsigned long cnt)
{
if (cnt > 0) {
unsigned long i;
write_csr(ccm_mbeginaddr, addr);
for (i = 0; i < cnt; i++)
write_csr(ccm_mcommand, CCM_DC_INVAL);
vFlushPipeCCM();
__RWMB();
}
}
/**
* brief Flush one D-Cache line specified by address in M-Mode
* details
* This function flush one D-Cache line specified by the address.
* Command \ref CCM_DC_WB is written to CSR \ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be flushed
*/
static inline void vMFlushDCacheLine(unsigned long addr)
{
write_csr(ccm_mbeginaddr, addr);
write_csr(ccm_mcommand, CCM_DC_WB);
vFlushPipeCCM();
__RWMB();
}
/**
* brief Flush several D-Cache lines specified by address in M-Mode
* details
* This function flush several D-Cache lines specified
* by the address and line count.
* Command ref CCM_DC_WB is written to CSR ref ccm_mcommand.
* \remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be flushed
* param [in] cnt count of cache lines to be flushed
*/
static inline void vMFlushDCacheLines(unsigned long addr, unsigned long cnt)
{
if (cnt > 0) {
unsigned long i;
write_csr(ccm_mbeginaddr, addr);
for (i = 0; i < cnt; i++)
write_csr(ccm_mcommand, CCM_DC_WB);
vFlushPipeCCM();
__RWMB();
}
}
/**
* brief Flush and invalidate one D-Cache line specified by address in M-Mode
* details
* This function flush and invalidate one D-Cache line specified by the address.
* Command \ref CCM_DC_WBINVAL is written to CSR \ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be flushed and invalidated
*/
static inline void vMFlushInvalDCacheLine(unsigned long addr)
{
write_csr(ccm_mbeginaddr, addr);
write_csr(ccm_mcommand, CCM_DC_WBINVAL);
vFlushPipeCCM();
__RWMB();
}
/**
* brief Flush and invalidate several D-Cache lines specified by address in M-Mode
* details
* This function flush and invalidate several D-Cache lines specified
* by the address and line count.
* Command \ref CCM_DC_WBINVAL is written to CSR \ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be flushed and invalidated
* param [in] cnt count of cache lines to be flushed and invalidated
*/
static inline void vMFlushInvalDCacheLines(unsigned long addr, unsigned long cnt)
{
if (cnt > 0) {
unsigned long i;
write_csr(ccm_mbeginaddr, addr);
for (i = 0; i < cnt; i++)
write_csr(ccm_mcommand, CCM_DC_WBINVAL);
vFlushPipeCCM();
__RWMB();
}
}
/**
* brief Lock one D-Cache line specified by address in M-Mode
* details
* This function lock one D-Cache line specified by the address.
* Command \ref CCM_DC_LOCK is written to CSR \ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be locked
* return result of CCM lock operation, see enum \ref CCM_OP_FINFO
*/
static inline unsigned long ulMLockDCacheLine(unsigned long addr)
{
write_csr(ccm_mbeginaddr, addr);
write_csr(ccm_mcommand, CCM_DC_LOCK);
vFlushPipeCCM();
__RWMB();
return read_csr(ccm_mdata);
}
/**
* brief Lock several D-Cache lines specified by address in M-Mode
* details
* This function lock several D-Cache lines specified by the address
* and line count.
* Command \ref CCM_DC_LOCK is written to CSR \ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be locked
* param [in] cnt count of cache lines to be locked
* return result of CCM lock operation, see enum \ref CCM_OP_FINFO
*/
static inline unsigned long ulMLockDCacheLines(unsigned long addr, unsigned long cnt)
{
if (cnt > 0) {
unsigned long i;
unsigned long fail_info = CCM_OP_SUCCESS;
write_csr(ccm_mbeginaddr, addr);
for (i = 0; i < cnt; i++) {
write_csr(ccm_mcommand, CCM_DC_LOCK);
vFlushPipeCCM();
__RWMB();
fail_info = read_csr(ccm_mdata);
if (CCM_OP_SUCCESS != fail_info)
return fail_info;
}
}
return CCM_OP_SUCCESS;
}
/**
* brief Unlock one D-Cache line specified by address in M-Mode
* details
* This function unlock one D-Cache line specified by the address.
* Command \ref CCM_DC_UNLOCK is written to CSR \ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be unlocked
*/
static inline void MUnlockDCacheLine(unsigned long addr)
{
write_csr(ccm_mbeginaddr, addr);
write_csr(ccm_mcommand, CCM_DC_UNLOCK);
vFlushPipeCCM();
__RWMB();
}
/**
* brief Unlock several D-Cache lines specified by address in M-Mode
* details
* This function unlock several D-Cache lines specified
* by the address and line count.
* Command \ref CCM_DC_UNLOCK is written to CSR \ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be unlocked
* param [in] cnt count of cache lines to be unlocked
*/
static inline void vMUnlockDCacheLines(unsigned long addr, unsigned long cnt)
{
if (cnt > 0) {
unsigned long i;
write_csr(ccm_mbeginaddr, addr);
for (i = 0; i < cnt; i++)
write_csr(ccm_mcommand, CCM_DC_UNLOCK);
vFlushPipeCCM();
__RWMB();
}
}
/**
* brief Invalidate all D-Cache lines in M-Mode
* details
* This function invalidate all D-Cache lines.
* Command \ref CCM_DC_INVAL_ALL is written to CSR \ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be invalidated
*/
static inline void vMInvalDCache(void)
{
write_csr(ccm_mcommand, CCM_DC_INVAL_ALL);
vFlushPipeCCM();
__RWMB();
}
/**
* brief Flush all D-Cache lines in M-Mode
* details
* This function flush all D-Cache lines.
* Command \ref CCM_DC_WB_ALL is written to CSR \ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be flushed
*/
static inline void vMFlushDCache(void)
{
write_csr(ccm_mcommand, CCM_DC_WB_ALL);
vFlushPipeCCM();
__RWMB();
}
/**
* brief Flush and invalidate all D-Cache lines in M-Mode
* details
* This function flush and invalidate all D-Cache lines.
* Command \ref CCM_DC_WBINVAL_ALL is written to CSR \ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be flushed and locked
*/
static inline void vMFlushInvalDCache(void)
{
write_csr(ccm_mcommand, CCM_DC_WBINVAL_ALL);
vFlushPipeCCM();
__RWMB();
}
/**
* brief Check ICache Unit Present or Not
* details
* This function check icache unit present or not via mcfg_info csr
* remarks
* This function might not work for some old nuclei processors
* Please make sure the version of your nuclei processor contain ICACHE bit in mcfg_info
* return 1 if present otherwise 0
*/
static inline uint32_t ulICachePresent(void)
{
if (read_csr(mcfg_info) & MCFG_INFO_ICACHE)
return 1;
return 0;
}
/**
* brief Enable ICache
* details
* This function enable I-Cache
* remarks
* This function can be called in M-Mode only.
* This ref mcache_ctl register control I Cache enable.
* sa
* ref vDisableICache
*/
static inline void vEnableICache(void)
{
set_csr(mcache_ctl, MCACHE_CTL_IC_EN);
}
/**
* brief Disable ICache
* details
* This function Disable I-Cache
* remarks
* This function can be called in M-Mode only.
* This \ref mcache_ctl register control I Cache enable.
* sa
* ref vEnableICache
*/
static inline void vDisableICache(void)
{
clear_csr(mcache_ctl, MCACHE_CTL_IC_EN);
}
/**
* brief Enable ICache ECC
* details
* This function enable I-Cache ECC
* remarks
* This function can be called in M-Mode only.
* This \ref mcache_ctl register control I Cache ECC enable.
* sa
* ref vDisableICacheECC
*/
static inline void vEnableICacheECC(void)
{
set_csr(mcache_ctl, MCACHE_CTL_IC_ECC_EN);
}
/**
* brief Disable ICache ECC
* details
* This function disable I-Cache ECC
* remarks
* This function can be called in M-Mode only.
* This \ref mcache_ctl register control I Cache ECC enable.
* sa
* ref vEnableICacheECC
*/
static inline void vDisableICacheECC(void)
{
clear_csr(mcache_ctl, MCACHE_CTL_IC_ECC_EN);
}
/**
* brief Invalidate one I-Cache line specified by address in M-Mode
* details
* This function unlock and invalidate one I-Cache line specified
* by the address.
* Command ref CCM_IC_INVAL is written to CSR ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be invalidated
*/
static inline void vMInvalICacheLine(unsigned long addr)
{
write_csr(ccm_mbeginaddr, addr);
write_csr(ccm_mcommand, CCM_IC_INVAL);
vFlushPipeCCM();
__RWMB();
}
/**
* brief Invalidate several I-Cache lines specified by address in M-Mode
* details
* This function unlock and invalidate several I-Cache lines specified
* by the address and line count.
* Command ref CCM_IC_INVAL is written to CSR ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be invalidated
* param [in] cnt count of cache lines to be invalidated
*/
static inline void vMInvalICacheLines(unsigned long addr, unsigned long cnt)
{
if (cnt > 0) {
unsigned long i;
write_csr(ccm_mbeginaddr, addr);
for (i = 0; i < cnt; i++)
write_csr(ccm_mcommand, CCM_IC_INVAL);
vFlushPipeCCM();
__RWMB();
}
}
/**
* brief Invalidate all I-Cache lines in M-Mode
* details
* This function invalidate all I-Cache lines.
* Command ref CCM_IC_INVAL_ALL is written to CSR ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be invalidated
*/
static inline void vMInvalICache(void)
{
write_csr(ccm_mcommand, CCM_IC_INVAL_ALL);
vFlushPipeCCM();
__RWMB();
}
/**
* brief Lock one I-Cache line specified by address in M-Mode
* details
* This function lock one I-Cache line specified by the address.
* Command ref CCM_IC_LOCK is written to CSR ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be locked
* return result of CCM lock operation, see enum ref CCM_OP_FINFO
*/
static inline unsigned long ulMLockICacheLine(unsigned long addr)
{
write_csr(ccm_mbeginaddr, addr);
write_csr(ccm_mcommand, CCM_IC_LOCK);
vFlushPipeCCM();
__RWMB();
return read_csr(ccm_mdata);
}
/**
* brief Lock several I-Cache lines specified by address in M-Mode
* details
* This function lock several I-Cache lines specified by the address
* and line count.
* Command ref CCM_IC_LOCK is written to CSR ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be locked
* param [in] cnt count of cache lines to be locked
* return result of CCM lock operation, see enum ref CCM_OP_FINFO
*/
static inline unsigned long ulMLockICacheLines(unsigned long addr, unsigned long cnt)
{
if (cnt > 0) {
unsigned long i;
unsigned long fail_info = CCM_OP_SUCCESS;
write_csr(ccm_mbeginaddr, addr);
for (i = 0; i < cnt; i++) {
write_csr(ccm_mcommand, CCM_IC_LOCK);
vFlushPipeCCM();
__RWMB();
fail_info = read_csr(ccm_mdata);
if (CCM_OP_SUCCESS != fail_info)
return fail_info;
}
}
return CCM_OP_SUCCESS;
}
/**
* brief Unlock one I-Cache line specified by address in M-Mode
* details
* This function unlock one I-Cache line specified by the address.
* Command ref CCM_IC_UNLOCK is written to CSR ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be unlocked
*/
static inline void vMUnlockICacheLine(unsigned long addr)
{
write_csr(ccm_mbeginaddr, addr);
write_csr(ccm_mcommand, CCM_IC_UNLOCK);
vFlushPipeCCM();
__RWMB();
}
/**
* brief Unlock several I-Cache lines specified by address in M-Mode
* details
* This function unlock several I-Cache lines specified
* by the address and line count.
* Command ref CCM_IC_UNLOCK is written to CSR ref ccm_mcommand.
* remarks
* This function must be executed in M-Mode only.
* param [in] addr start address to be unlocked
* param [in] cnt count of cache lines to be unlocked
*/
static inline void vMUnlockICacheLines(unsigned long addr, unsigned long cnt)
{
if (cnt > 0) {
unsigned long i;
write_csr(ccm_mbeginaddr, addr);
for (i = 0; i < cnt; i++)
write_csr(ccm_mcommand, CCM_IC_UNLOCK);
vFlushPipeCCM();
__RWMB();
}
}
#endif