18 #ifndef __CORE_FEATURE_SPMP_H__ 
   19 #define __CORE_FEATURE_SPMP_H__ 
   38 #include "core_feature_base.h" 
   39 #include "core_compatiable.h" 
   41 #if defined(__SPMP_PRESENT) && (__SPMP_PRESENT == 1) 
   58 #ifndef __SPMP_ENTRY_NUM 
   60 #error "__SPMP_ENTRY_NUM is not defined, please check!" 
   63 typedef struct SPMP_CONFIG {
 
  138     uint8_t csr_cfg_num = 0;
 
  139     uint16_t csr_idx = 0;
 
  140     uint16_t cfg_shift = 0;
 
  142     if (entry_idx >= __SPMP_ENTRY_NUM) 
return 0;
 
  144 #if __RISCV_XLEN == 32 
  146     csr_idx = entry_idx >> 2;
 
  147 #elif __RISCV_XLEN == 64 
  150     csr_idx = (entry_idx >> 2) & ~1;
 
  160     cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3;
 
  163     return (uint8_t)(__RV_EXTRACT_FIELD(spmpcfgx, 0xFF << cfg_shift));
 
  178     uint8_t csr_cfg_num = 0;
 
  179     uint16_t csr_idx = 0;
 
  180     uint16_t cfg_shift = 0;
 
  181     if (entry_idx >= __SPMP_ENTRY_NUM) 
return;
 
  183 #if __RISCV_XLEN == 32 
  185     csr_idx = entry_idx >> 2;
 
  186 #elif __RISCV_XLEN == 64 
  189     csr_idx = (entry_idx >> 2) & ~1;
 
  200     cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3;
 
  202     spmpcfgx = __RV_INSERT_FIELD(spmpcfgx, 0xFFUL << cfg_shift, spmpxcfg);
 
  277     unsigned int cfg_shift, cfg_csr_idx, addr_csr_idx = 0;
 
  278     unsigned long cfgmask, addrmask = 0;
 
  279     unsigned long spmpcfg, spmpaddr = 0;
 
  280     unsigned long protection, csr_cfg_num = 0;
 
  285 #if __RISCV_XLEN == 32 
  287     cfg_csr_idx = (entry_idx >> 2);
 
  288 #elif __RISCV_XLEN == 64 
  290     cfg_csr_idx = ((entry_idx >> 2)) & ~1;
 
  299     cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3;
 
  300     addr_csr_idx = entry_idx;
 
  303     protection = (
unsigned long)spmp_cfg->
protection;
 
  305     cfgmask = ~(0xFFUL << cfg_shift);
 
  307     spmpcfg |= ((protection << cfg_shift) & ~cfgmask);
 
  315         spmpaddr |= (addrmask >> 1);
 
  338     unsigned int cfg_shift, cfg_csr_idx, addr_csr_idx = 0;
 
  339     unsigned long cfgmask, spmpcfg, prot = 0;
 
  340     unsigned long t1, addr, spmpaddr, len = 0;
 
  341     uint8_t csr_cfg_num = 0;
 
  343     if (entry_idx >= __SPMP_ENTRY_NUM || !spmp_cfg) 
return -1;
 
  346 #if __RISCV_XLEN == 32 
  348     cfg_csr_idx = entry_idx >> 2;
 
  349 #elif __RISCV_XLEN == 64 
  351     cfg_csr_idx = (entry_idx >> 2) & ~1;
 
  357     cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3;
 
  358     addr_csr_idx = entry_idx;
 
  361     cfgmask = (0xFFUL << cfg_shift);
 
  363     prot    = spmpcfg >> cfg_shift;
 
  368         t1 = 
__CTZ(~spmpaddr);
 
  369         addr = (spmpaddr & ~((1UL << t1) - 1)) << 
SPMP_SHIFT;
 
  379     spmp_cfg->
order = len;
 
  384 #if defined(__SMPU_PRESENT) && (__SMPU_PRESENT == 1) 
  389 #define __get_SMPUCFGx      __get_sPMPCFGx 
  390 #define __set_SMPUCFGx      __set_sPMPCFGx 
  391 #define __get_SMPUxCFG      __get_sPMPxCFG 
  392 #define __set_SMPUxCFG      __set_sPMPxCFG 
  393 #define __get_SMPUADDRx     __get_sPMPADDRx 
  394 #define __set_SMPUADDRx     __set_sPMPADDRx 
  395 #define __set_SMPUENTRYx    __set_sPMPENTRYx 
  396 #define __get_SMPUENTRYx    __get_sPMPENTRYx 
  409 #if __RISCV_XLEN == 32 
  412 #elif __RISCV_XLEN == 64 
  429 #if __RISCV_XLEN == 32 
  433     return (uint64_t)((((uint64_t)hi) << 32) | lo);
 
  434 #elif __RISCV_XLEN == 64 
__STATIC_INLINE unsigned long __CTZ(unsigned long data)
Count tailing zero.
#define __RV_CSR_READ(csr)
CSR operation Macro for csrr instruction.
#define __RV_CSR_WRITE(csr, val)
CSR operation Macro for csrw instruction.
#define __STATIC_INLINE
Define a static function that may be inlined by the compiler.
unsigned long rv_csr_t
Type of Control and Status Register(CSR), depends on the XLEN defined in RISC-V.
#define __RISCV_XLEN
Refer to the width of an integer register in bits(either 32 or 64)
__STATIC_INLINE uint64_t __get_SMPUSWITCHx(void)
Get SMPU each entry's on/off status.
__STATIC_INLINE int __get_sPMPENTRYx(unsigned int entry_idx, spmp_config *spmp_cfg)
Get sPMP entry by entry idx.
__STATIC_INLINE void __set_sPMPADDRx(uint32_t csr_idx, rv_csr_t spmpaddr)
Set sPMPADDRx by CSR index.
__STATIC_INLINE void __set_sPMPCFGx(uint32_t csr_idx, rv_csr_t spmpcfg)
Set sPMPCFGx by csr index.
__STATIC_INLINE void __set_SMPUSWITCHx(uint64_t val)
Set SMPU each entry's on/off status.
__STATIC_INLINE rv_csr_t __get_sPMPADDRx(uint32_t csr_idx)
Get sPMPADDRx Register by CSR index.
spmp_config smpu_config
sPMP has upgraded to S-mode Memory Protection Unit, renamed as SMPU, but still share the apis with sP...
__STATIC_INLINE void __set_sPMPENTRYx(uint32_t entry_idx, const spmp_config *spmp_cfg)
Set sPMP entry by entry idx.
__STATIC_INLINE void __set_sPMPxCFG(uint32_t entry_idx, uint8_t spmpxcfg)
Set 8bit sPMPxCFG by spmp entry index.
__STATIC_INLINE rv_csr_t __get_sPMPCFGx(uint32_t csr_idx)
Get sPMPCFGx Register by csr index.
__STATIC_INLINE uint8_t __get_sPMPxCFG(uint32_t entry_idx)
Get 8bit sPMPxCFG Register by sPMP entry index.
unsigned long base_addr
Base address of memory region It must be 2^order aligned address.
unsigned int protection
Set permissions using macros SMPU_S/ SMPU_R/SMPU_W/ SMPU_X of SMPU; SPMP_L/ SPMP_U/SPMP_R/ SPMP_W/SPM...
unsigned long order
Size of memory region as power of 2, it has to be minimum 2 and maxium __RISCV_XLEN according to the ...