|  | // Copyright Microsoft and CHERIoT Contributors. | 
|  | // SPDX-License-Identifier: MIT | 
|  |  | 
|  | #ifndef _PRIV_RISCV_H_ | 
|  | #define _PRIV_RISCV_H_ | 
|  |  | 
|  | #include <stddef.h> | 
|  | #include <utils.hh> | 
|  |  | 
|  | namespace priv | 
|  | { | 
|  | #define CSR_ZIMM(val) (__builtin_constant_p(val) && ((unsigned long)(val) < 32)) | 
|  |  | 
|  | #define csr_swap(csr, val)                                                     \ | 
|  | ({                                                                         \ | 
|  | if (CSR_ZIMM(val))                                                     \ | 
|  | __asm __volatile("csrrwi %0, " #csr ", %1"                         \ | 
|  | : "=r"(val)                                       \ | 
|  | : "i"(val));                                      \ | 
|  | else                                                                   \ | 
|  | __asm __volatile("csrrw %0, " #csr ", %1" : "=r"(val) : "r"(val)); \ | 
|  | val;                                                                   \ | 
|  | }) | 
|  |  | 
|  | #define csr_write(csr, val)                                                    \ | 
|  | ({                                                                         \ | 
|  | if (CSR_ZIMM(val))                                                     \ | 
|  | __asm __volatile("csrwi " #csr ", %0" ::"i"(val));                 \ | 
|  | else                                                                   \ | 
|  | __asm __volatile("csrw " #csr ", %0" ::"r"(val));                  \ | 
|  | }) | 
|  |  | 
|  | #define csr_set(csr, val)                                                      \ | 
|  | ({                                                                         \ | 
|  | if (CSR_ZIMM(val))                                                     \ | 
|  | __asm __volatile("csrsi " #csr ", %0" ::"i"(val));                 \ | 
|  | else                                                                   \ | 
|  | __asm __volatile("csrs " #csr ", %0" ::"r"(val));                  \ | 
|  | }) | 
|  |  | 
|  | #define csr_clear(csr, val)                                                    \ | 
|  | ({                                                                         \ | 
|  | if (CSR_ZIMM(val))                                                     \ | 
|  | __asm __volatile("csrci " #csr ", %0" ::"i"(val));                 \ | 
|  | else                                                                   \ | 
|  | __asm __volatile("csrc " #csr ", %0" ::"r"(val));                  \ | 
|  | }) | 
|  |  | 
|  | #define csr_read(csr)                                                          \ | 
|  | ({                                                                         \ | 
|  | unsigned int val;                                                      \ | 
|  | __asm __volatile("csrr %0, " #csr : "=r"(val));                        \ | 
|  | val;                                                                   \ | 
|  | }) | 
|  |  | 
|  | #define wfi() __asm volatile("wfi") | 
|  |  | 
|  | constexpr size_t MCAUSE_INTR      = (1u << 31); | 
|  | constexpr size_t MCAUSE_CODE_MASK = (~MCAUSE_INTR); | 
|  | constexpr size_t MCAUSE_MTIME     = 7; | 
|  | constexpr size_t MCAUSE_MEXTERN   = 11; | 
|  |  | 
|  | constexpr size_t MCAUSE_INST_MISALIGNED     = 0; | 
|  | constexpr size_t MCAUSE_INST_ACCESS_FAULT   = 1; | 
|  | constexpr size_t MCAUSE_ILLEGAL_INSTRUCTION = 2; | 
|  | constexpr size_t MCAUSE_BREAKPOINT          = 3; | 
|  | constexpr size_t MCAUSE_LOAD_MISALIGNED     = 4; | 
|  | constexpr size_t MCAUSE_LOAD_ACCESS_FAULT   = 5; | 
|  | constexpr size_t MCAUSE_STORE_MISALIGNED    = 6; | 
|  | constexpr size_t MCAUSE_STORE_ACCESS_FAULT  = 7; | 
|  | constexpr size_t MCAUSE_ECALL_USER          = 8; | 
|  | constexpr size_t MCAUSE_ECALL_SUPERVISOR    = 9; | 
|  | constexpr size_t MCAUSE_ECALL_MACHINE       = 11; | 
|  | constexpr size_t MCAUSE_INST_PAGE_FAULT     = 12; | 
|  | constexpr size_t MCAUSE_LOAD_PAGE_FAULT     = 13; | 
|  | constexpr size_t MCAUSE_STORE_PAGE_FAULT    = 15; | 
|  | constexpr size_t MCAUSE_THREAD_EXIT         = 24; | 
|  | constexpr size_t MCAUSE_CHERI               = 28; | 
|  |  | 
|  | constexpr size_t MSTATUS_UIE = (1 << 0); | 
|  | constexpr size_t MSTATUS_SIE = (1 << 1); | 
|  | constexpr size_t MSTATUS_HIE = (1 << 2); | 
|  | constexpr size_t MSTATUS_MIE = (1 << 3); | 
|  | constexpr size_t MSTATUS_AIE = | 
|  | (MSTATUS_UIE | MSTATUS_SIE | MSTATUS_HIE | MSTATUS_MIE); | 
|  | constexpr size_t MSTATUS_UPIE       = (1 << 4); | 
|  | constexpr size_t MSTATUS_SPIE       = (1 << 5); | 
|  | constexpr size_t MSTATUS_SPIE_SHIFT = 5; | 
|  | constexpr size_t MSTATUS_HPIE       = (1 << 6); | 
|  | constexpr size_t MSTATUS_MPIE       = (1 << 7); | 
|  | constexpr size_t MSTATUS_MPIE_SHIFT = 7; | 
|  | constexpr size_t MSTATUS_SPP        = (1 << 8); | 
|  | constexpr size_t MSTATUS_SPP_SHIFT  = 8; | 
|  | constexpr size_t MSTATUS_HPP_MASK   = 0x3; | 
|  | constexpr size_t MSTATUS_HPP_SHIFT  = 9; | 
|  | constexpr size_t MSTATUS_MPP_MASK   = 0x3; | 
|  | constexpr size_t MSTATUS_MPP_SHIFT  = 11; | 
|  | constexpr size_t MSTATUS_FS_MASK    = 0x3; | 
|  | constexpr size_t MSTATUS_FS_SHIFT   = 13; | 
|  | constexpr size_t MSTATUS_XS_MASK    = 0x3; | 
|  | constexpr size_t MSTATUS_XS_SHIFT   = 15; | 
|  | constexpr size_t MSTATUS_MPRV       = (1 << 17); | 
|  | constexpr size_t MSTATUS_PUM        = (1 << 18); | 
|  | constexpr size_t MSTATUS_VM_MASK    = 0x1f; | 
|  | constexpr size_t MSTATUS_VM_SHIFT   = 24; | 
|  | constexpr size_t MSTATUS_VM_MBARE   = 0; | 
|  | constexpr size_t MSTATUS_VM_MBB     = 1; | 
|  | constexpr size_t MSTATUS_VM_MBBID   = 2; | 
|  | constexpr size_t MSTATUS_VM_SV32    = 8; | 
|  | constexpr size_t MSTATUS_VM_SV39    = 9; | 
|  | constexpr size_t MSTATUS_VM_SV48    = 10; | 
|  | constexpr size_t MSTATUS_VM_SV57    = 11; | 
|  | constexpr size_t MSTATUS_VM_SV64    = 12; | 
|  | constexpr size_t MSTATUS_SD         = (1 << 31); | 
|  |  | 
|  | constexpr size_t MSTATUS_PRV_U = 0; | 
|  | constexpr size_t MSTATUS_PRV_S = 1; | 
|  | constexpr size_t MSTATUS_PRV_H = 2; | 
|  | constexpr size_t MSTATUS_PRV_M = 3; | 
|  |  | 
|  | constexpr size_t MIE_USIE = (1 << 0); | 
|  | constexpr size_t MIE_SSIE = (1 << 1); | 
|  | constexpr size_t MIE_HSIE = (1 << 2); | 
|  | constexpr size_t MIE_MSIE = (1 << 3); | 
|  | constexpr size_t MIE_UTIE = (1 << 4); | 
|  | constexpr size_t MIE_STIE = (1 << 5); | 
|  | constexpr size_t MIE_HTIE = (1 << 6); | 
|  | constexpr size_t MIE_MTIE = (1 << 7); | 
|  |  | 
|  | constexpr size_t MIP_USIP = (1 << 0); | 
|  | constexpr size_t MIP_SSIP = (1 << 1); | 
|  | constexpr size_t MIP_HSIP = (1 << 2); | 
|  | constexpr size_t MIP_MSIP = (1 << 3); | 
|  | constexpr size_t MIP_UTIP = (1 << 4); | 
|  | constexpr size_t MIP_STIP = (1 << 5); | 
|  | constexpr size_t MIP_HTIP = (1 << 6); | 
|  | constexpr size_t MIP_MTIP = (1 << 7); | 
|  | constexpr size_t MIP_SEIP = (1 << 9); | 
|  | constexpr size_t MIP_MEIP = (1 << 11); | 
|  |  | 
|  | static inline size_t intr_disable(void) | 
|  | { | 
|  | size_t ret; | 
|  |  | 
|  | __asm volatile("csrrci %0, mstatus, %1" | 
|  | : "=&r"(ret) | 
|  | : "i"(MSTATUS_AIE)); | 
|  |  | 
|  | return (ret & (MSTATUS_AIE)); | 
|  | } | 
|  |  | 
|  | static inline void mie_enable() | 
|  | { | 
|  | csr_set(mie, 0x880); | 
|  | } | 
|  |  | 
|  | static inline void intr_restore(size_t s) | 
|  | { | 
|  | __asm volatile("csrs mstatus, %0" ::"r"(s)); | 
|  | } | 
|  |  | 
|  | static inline void intr_enable() | 
|  | { | 
|  | csr_set(mstatus, 0x08); | 
|  | } | 
|  |  | 
|  | } // namespace priv | 
|  |  | 
|  | #endif // _PRIV_RISCV_H_ |