| // 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_ |