/* Register access functions for RISC-V system registers. SPDX-License-Identifier: Unlicense https://five-embeddev.com/ */ #ifndef RISCV_CSR_H #define RISCV_CSR_H #include #if __riscv_xlen == 32 typedef uint32_t uint_xlen_t; typedef uint32_t uint_csr32_t; typedef uint32_t uint_csr64_t; #elif __riscv_xlen == 64 typedef uint64_t uint_xlen_t; typedef uint32_t uint_csr32_t; typedef uint64_t uint_csr64_t; #else #error "Unknown XLEN" #endif // Test for Zicsr extension, if relevant #if defined(__riscv_arch_test) #if !defined(__riscv_zicsr) #error "-march must include zicsr to access CSRs" #endif #endif /******************************************* * misa - MRW - Machine ISA */ static inline uint_xlen_t csr_read_misa(void) { uint_xlen_t value; __asm__ volatile("csrr %0, misa" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_misa(uint_xlen_t value) { __asm__ volatile("csrw misa, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_misa(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, misa, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mvendorid - MRO - Machine Vendor ID */ static inline uint32_t csr_read_mvendorid(void) { uint_csr32_t value; __asm__ volatile("csrr %0, mvendorid" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * marchid - MRO - Machine Architecture ID */ static inline uint_xlen_t csr_read_marchid(void) { uint_xlen_t value; __asm__ volatile("csrr %0, marchid" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * mimpid - MRO - Machine Implementation ID */ static inline uint_xlen_t csr_read_mimpid(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mimpid" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * mhartid - MRO - Hardware Thread ID */ static inline uint_xlen_t csr_read_mhartid(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mhartid" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * mstatus - MRW - Machine Status */ static inline uint_xlen_t csr_read_mstatus(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mstatus" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mstatus(uint_xlen_t value) { __asm__ volatile("csrw mstatus, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mstatus(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mstatus, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_mstatus(uint_xlen_t mask) { __asm__ volatile("csrrs zero, mstatus, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_mstatus(uint_xlen_t mask) { __asm__ volatile("csrrc zero, mstatus, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_set_bits_mstatus(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrs %0, mstatus, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint_xlen_t csr_read_clr_bits_mstatus(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrc %0, mstatus, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* mstatus, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_MSTATUS(VALUE) \ __asm__ volatile("csrrwi zero, mstatus, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* mstatus, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_MSTATUS(MASK) \ __asm__ volatile("csrrsi zero, mstatus, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* mstatus, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_MSTATUS(MASK) \ __asm__ volatile("csrrci zero, mstatus, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define MSTATUS_MIE_BIT_OFFSET 3 #define MSTATUS_MIE_BIT_WIDTH 1 #define MSTATUS_MIE_BIT_MASK 0x8 #define MSTATUS_MIE_ALL_SET_MASK 0x1 #define MSTATUS_SIE_BIT_OFFSET 2 #define MSTATUS_SIE_BIT_WIDTH 1 #define MSTATUS_SIE_BIT_MASK 0x4 #define MSTATUS_SIE_ALL_SET_MASK 0x1 #define MSTATUS_MPIE_BIT_OFFSET 7 #define MSTATUS_MPIE_BIT_WIDTH 1 #define MSTATUS_MPIE_BIT_MASK 0x80 #define MSTATUS_MPIE_ALL_SET_MASK 0x1 #define MSTATUS_SPIE_BIT_OFFSET 5 #define MSTATUS_SPIE_BIT_WIDTH 1 #define MSTATUS_SPIE_BIT_MASK 0x20 #define MSTATUS_SPIE_ALL_SET_MASK 0x1 #define MSTATUS_MPRV_BIT_OFFSET 17 #define MSTATUS_MPRV_BIT_WIDTH 1 #define MSTATUS_MPRV_BIT_MASK 0x20000 #define MSTATUS_MPRV_ALL_SET_MASK 0x1 #define MSTATUS_MPP_BIT_OFFSET 11 #define MSTATUS_MPP_BIT_WIDTH 2 #define MSTATUS_MPP_BIT_MASK 0x1800 #define MSTATUS_MPP_ALL_SET_MASK 0x3 #define MSTATUS_SPP_BIT_OFFSET 8 #define MSTATUS_SPP_BIT_WIDTH 1 #define MSTATUS_SPP_BIT_MASK 0x100 #define MSTATUS_SPP_ALL_SET_MASK 0x1 /******************************************* * mstatush - MRW - Additional machine status register, RV32 only. */ static inline uint_xlen_t csr_read_mstatush(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mstatush" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mstatush(uint_xlen_t value) { __asm__ volatile("csrw mstatush, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mstatush(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mstatush, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mtvec - MRW - Machine Trap Vector Base Address */ static inline uint_xlen_t csr_read_mtvec(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mtvec" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mtvec(uint_xlen_t value) { __asm__ volatile("csrw mtvec, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mtvec(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mtvec, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_mtvec(uint_xlen_t mask) { __asm__ volatile("csrrs zero, mtvec, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_mtvec(uint_xlen_t mask) { __asm__ volatile("csrrc zero, mtvec, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_set_bits_mtvec(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrs %0, mtvec, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint_xlen_t csr_read_clr_bits_mtvec(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrc %0, mtvec, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* mtvec, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_MTVEC(VALUE) \ __asm__ volatile("csrrwi zero, mtvec, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* mtvec, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_MTVEC(MASK) \ __asm__ volatile("csrrsi zero, mtvec, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* mtvec, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_MTVEC(MASK) \ __asm__ volatile("csrrci zero, mtvec, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define MTVEC_BASE_BIT_OFFSET 2 #define MTVEC_BASE_BIT_WIDTH ((__riscv_xlen - 1) - (2) + 1) #define MTVEC_BASE_BIT_MASK ((1UL << (((__riscv_xlen - 1) - (2) + 1) - 1)) << (2)) #define MTVEC_BASE_ALL_SET_MASK ((1UL << (((__riscv_xlen - 1) - (2) + 1) - 1)) << (0)) #define MTVEC_MODE_BIT_OFFSET 0 #define MTVEC_MODE_BIT_WIDTH 2 #define MTVEC_MODE_BIT_MASK 0x3 #define MTVEC_MODE_ALL_SET_MASK 0x3 /******************************************* * medeleg - MRW - Machine Exception Delegation */ static inline uint_xlen_t csr_read_medeleg(void) { uint_xlen_t value; __asm__ volatile("csrr %0, medeleg" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_medeleg(uint_xlen_t value) { __asm__ volatile("csrw medeleg, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_medeleg(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, medeleg, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mideleg - MRW - Machine Interrupt Delegation */ static inline uint_xlen_t csr_read_mideleg(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mideleg" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mideleg(uint_xlen_t value) { __asm__ volatile("csrw mideleg, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mideleg(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mideleg, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mip - MRW - Machine Interrupt Pending */ static inline uint_xlen_t csr_read_mip(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mip" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mip(uint_xlen_t value) { __asm__ volatile("csrw mip, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mip(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mip, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_mip(uint_xlen_t mask) { __asm__ volatile("csrrs zero, mip, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_mip(uint_xlen_t mask) { __asm__ volatile("csrrc zero, mip, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_set_bits_mip(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrs %0, mip, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint_xlen_t csr_read_clr_bits_mip(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrc %0, mip, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* mip, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_MIP(VALUE) \ __asm__ volatile("csrrwi zero, mip, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* mip, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_MIP(MASK) \ __asm__ volatile("csrrsi zero, mip, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* mip, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_MIP(MASK) \ __asm__ volatile("csrrci zero, mip, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define MIP_MSI_BIT_OFFSET 3 #define MIP_MSI_BIT_WIDTH 1 #define MIP_MSI_BIT_MASK 0x8 #define MIP_MSI_ALL_SET_MASK 0x1 #define MIP_MTI_BIT_OFFSET 7 #define MIP_MTI_BIT_WIDTH 1 #define MIP_MTI_BIT_MASK 0x80 #define MIP_MTI_ALL_SET_MASK 0x1 #define MIP_MEI_BIT_OFFSET 11 #define MIP_MEI_BIT_WIDTH 1 #define MIP_MEI_BIT_MASK 0x800 #define MIP_MEI_ALL_SET_MASK 0x1 #define MIP_SSI_BIT_OFFSET 1 #define MIP_SSI_BIT_WIDTH 1 #define MIP_SSI_BIT_MASK 0x2 #define MIP_SSI_ALL_SET_MASK 0x1 #define MIP_STI_BIT_OFFSET 5 #define MIP_STI_BIT_WIDTH 1 #define MIP_STI_BIT_MASK 0x20 #define MIP_STI_ALL_SET_MASK 0x1 #define MIP_SEI_BIT_OFFSET 9 #define MIP_SEI_BIT_WIDTH 1 #define MIP_SEI_BIT_MASK 0x200 #define MIP_SEI_ALL_SET_MASK 0x1 #define MIP_USI_BIT_OFFSET 0 #define MIP_USI_BIT_WIDTH 1 #define MIP_USI_BIT_MASK 0x1 #define MIP_USI_ALL_SET_MASK 0x1 #define MIP_UTI_BIT_OFFSET 4 #define MIP_UTI_BIT_WIDTH 1 #define MIP_UTI_BIT_MASK 0x10 #define MIP_UTI_ALL_SET_MASK 0x1 #define MIP_UEI_BIT_OFFSET 8 #define MIP_UEI_BIT_WIDTH 1 #define MIP_UEI_BIT_MASK 0x100 #define MIP_UEI_ALL_SET_MASK 0x1 #define MIP_PLATFORM_DEFINED_BIT_OFFSET 16 #define MIP_PLATFORM_DEFINED_BIT_WIDTH ((__riscv_xlen) - (16) + 1) #define MIP_PLATFORM_DEFINED_BIT_MASK ((1UL << (((__riscv_xlen) - (16) + 1) - 1)) << (16)) #define MIP_PLATFORM_DEFINED_ALL_SET_MASK ((1UL << (((__riscv_xlen) - (16) + 1) - 1)) << (0)) /******************************************* * mie - MRW - Machine Interrupt Enable */ static inline uint_xlen_t csr_read_mie(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mie" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mie(uint_xlen_t value) { __asm__ volatile("csrw mie, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mie(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mie, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_mie(uint_xlen_t mask) { __asm__ volatile("csrrs zero, mie, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_mie(uint_xlen_t mask) { __asm__ volatile("csrrc zero, mie, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_set_bits_mie(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrs %0, mie, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint_xlen_t csr_read_clr_bits_mie(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrc %0, mie, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* mie, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_MIE(VALUE) \ __asm__ volatile("csrrwi zero, mie, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* mie, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_MIE(MASK) \ __asm__ volatile("csrrsi zero, mie, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* mie, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_MIE(MASK) \ __asm__ volatile("csrrci zero, mie, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define MIE_MSI_BIT_OFFSET 3 #define MIE_MSI_BIT_WIDTH 1 #define MIE_MSI_BIT_MASK 0x8 #define MIE_MSI_ALL_SET_MASK 0x1 #define MIE_MTI_BIT_OFFSET 7 #define MIE_MTI_BIT_WIDTH 1 #define MIE_MTI_BIT_MASK 0x80 #define MIE_MTI_ALL_SET_MASK 0x1 #define MIE_MEI_BIT_OFFSET 11 #define MIE_MEI_BIT_WIDTH 1 #define MIE_MEI_BIT_MASK 0x800 #define MIE_MEI_ALL_SET_MASK 0x1 #define MIE_SSI_BIT_OFFSET 1 #define MIE_SSI_BIT_WIDTH 1 #define MIE_SSI_BIT_MASK 0x2 #define MIE_SSI_ALL_SET_MASK 0x1 #define MIE_STI_BIT_OFFSET 5 #define MIE_STI_BIT_WIDTH 1 #define MIE_STI_BIT_MASK 0x20 #define MIE_STI_ALL_SET_MASK 0x1 #define MIE_SEI_BIT_OFFSET 9 #define MIE_SEI_BIT_WIDTH 1 #define MIE_SEI_BIT_MASK 0x200 #define MIE_SEI_ALL_SET_MASK 0x1 #define MIE_USI_BIT_OFFSET 0 #define MIE_USI_BIT_WIDTH 1 #define MIE_USI_BIT_MASK 0x1 #define MIE_USI_ALL_SET_MASK 0x1 #define MIE_UTI_BIT_OFFSET 4 #define MIE_UTI_BIT_WIDTH 1 #define MIE_UTI_BIT_MASK 0x10 #define MIE_UTI_ALL_SET_MASK 0x1 #define MIE_UEI_BIT_OFFSET 8 #define MIE_UEI_BIT_WIDTH 1 #define MIE_UEI_BIT_MASK 0x100 #define MIE_UEI_ALL_SET_MASK 0x1 #define MIE_PLATFORM_DEFINED_BIT_OFFSET 16 #define MIE_PLATFORM_DEFINED_BIT_WIDTH ((__riscv_xlen) - (16) + 1) #define MIE_PLATFORM_DEFINED_BIT_MASK ((1UL << (((__riscv_xlen) - (16) + 1) - 1)) << (16)) #define MIE_PLATFORM_DEFINED_ALL_SET_MASK ((1UL << (((__riscv_xlen) - (16) + 1) - 1)) << (0)) /******************************************* * mcountinhibit - MRW - Machine Counter Inhibit */ static inline uint32_t csr_read_mcountinhibit(void) { uint_csr32_t value; __asm__ volatile("csrr %0, mcountinhibit" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mcountinhibit(uint_csr32_t value) { __asm__ volatile("csrw mcountinhibit, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint32_t csr_read_write_mcountinhibit(uint32_t new_value) { uint_csr32_t prev_value; __asm__ volatile("csrrw %0, mcountinhibit, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_mcountinhibit(uint32_t mask) { __asm__ volatile("csrrs zero, mcountinhibit, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_mcountinhibit(uint32_t mask) { __asm__ volatile("csrrc zero, mcountinhibit, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint32_t csr_read_set_bits_mcountinhibit(uint32_t mask) { uint_csr32_t value; __asm__ volatile("csrrs %0, mcountinhibit, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint32_t csr_read_clr_bits_mcountinhibit(uint32_t mask) { uint_csr32_t value; __asm__ volatile("csrrc %0, mcountinhibit, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* mcountinhibit, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_MCOUNTINHIBIT(VALUE) \ __asm__ volatile("csrrwi zero, mcountinhibit, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* mcountinhibit, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_MCOUNTINHIBIT(MASK) \ __asm__ volatile("csrrsi zero, mcountinhibit, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* mcountinhibit, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_MCOUNTINHIBIT(MASK) \ __asm__ volatile("csrrci zero, mcountinhibit, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define MCOUNTINHIBIT_CY_BIT_OFFSET 0 #define MCOUNTINHIBIT_CY_BIT_WIDTH 1 #define MCOUNTINHIBIT_CY_BIT_MASK 0x1 #define MCOUNTINHIBIT_CY_ALL_SET_MASK 0x1 #define MCOUNTINHIBIT_IR_BIT_OFFSET 2 #define MCOUNTINHIBIT_IR_BIT_WIDTH 1 #define MCOUNTINHIBIT_IR_BIT_MASK 0x4 #define MCOUNTINHIBIT_IR_ALL_SET_MASK 0x1 #define MCOUNTINHIBIT_HPM_BIT_OFFSET 3 #define MCOUNTINHIBIT_HPM_BIT_WIDTH 29 #define MCOUNTINHIBIT_HPM_BIT_MASK 0xfffffff8 #define MCOUNTINHIBIT_HPM_ALL_SET_MASK 0x1fffffff /******************************************* * mcycle - MRW - Clock Cycles Executed Counter */ static inline uint64_t csr_read_mcycle(void) { uint_csr64_t value; __asm__ volatile("csrr %0, mcycle" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mcycle(uint_csr64_t value) { __asm__ volatile("csrw mcycle, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint64_t csr_read_write_mcycle(uint64_t new_value) { uint_csr64_t prev_value; __asm__ volatile("csrrw %0, mcycle, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * minstret - MRW - Number of Instructions Retired Counter */ static inline uint64_t csr_read_minstret(void) { uint_csr64_t value; __asm__ volatile("csrr %0, minstret" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_minstret(uint_csr64_t value) { __asm__ volatile("csrw minstret, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint64_t csr_read_write_minstret(uint64_t new_value) { uint_csr64_t prev_value; __asm__ volatile("csrrw %0, minstret, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mhpmcounter3 - MRW - Event Counters */ static inline uint64_t csr_read_mhpmcounter3(void) { uint_csr64_t value; __asm__ volatile("csrr %0, mhpmcounter3" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mhpmcounter3(uint_csr64_t value) { __asm__ volatile("csrw mhpmcounter3, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint64_t csr_read_write_mhpmcounter3(uint64_t new_value) { uint_csr64_t prev_value; __asm__ volatile("csrrw %0, mhpmcounter3, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mhpmevent3 - MRW - Event Counter Event Select */ static inline uint_xlen_t csr_read_mhpmevent3(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mhpmevent3" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mhpmevent3(uint_xlen_t value) { __asm__ volatile("csrw mhpmevent3, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mhpmevent3(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mhpmevent3, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mcounteren - MRW - Counter Enable */ static inline uint32_t csr_read_mcounteren(void) { uint_csr32_t value; __asm__ volatile("csrr %0, mcounteren" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mcounteren(uint_csr32_t value) { __asm__ volatile("csrw mcounteren, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint32_t csr_read_write_mcounteren(uint32_t new_value) { uint_csr32_t prev_value; __asm__ volatile("csrrw %0, mcounteren, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_mcounteren(uint32_t mask) { __asm__ volatile("csrrs zero, mcounteren, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_mcounteren(uint32_t mask) { __asm__ volatile("csrrc zero, mcounteren, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint32_t csr_read_set_bits_mcounteren(uint32_t mask) { uint_csr32_t value; __asm__ volatile("csrrs %0, mcounteren, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint32_t csr_read_clr_bits_mcounteren(uint32_t mask) { uint_csr32_t value; __asm__ volatile("csrrc %0, mcounteren, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* mcounteren, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_MCOUNTEREN(VALUE) \ __asm__ volatile("csrrwi zero, mcounteren, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* mcounteren, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_MCOUNTEREN(MASK) \ __asm__ volatile("csrrsi zero, mcounteren, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* mcounteren, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_MCOUNTEREN(MASK) \ __asm__ volatile("csrrci zero, mcounteren, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define MCOUNTEREN_CY_BIT_OFFSET 0 #define MCOUNTEREN_CY_BIT_WIDTH 1 #define MCOUNTEREN_CY_BIT_MASK 0x1 #define MCOUNTEREN_CY_ALL_SET_MASK 0x1 #define MCOUNTEREN_TM_BIT_OFFSET 1 #define MCOUNTEREN_TM_BIT_WIDTH 1 #define MCOUNTEREN_TM_BIT_MASK 0x2 #define MCOUNTEREN_TM_ALL_SET_MASK 0x1 #define MCOUNTEREN_IR_BIT_OFFSET 2 #define MCOUNTEREN_IR_BIT_WIDTH 1 #define MCOUNTEREN_IR_BIT_MASK 0x4 #define MCOUNTEREN_IR_ALL_SET_MASK 0x1 #define MCOUNTEREN_HPM_BIT_OFFSET 3 #define MCOUNTEREN_HPM_BIT_WIDTH 29 #define MCOUNTEREN_HPM_BIT_MASK 0xfffffff8 #define MCOUNTEREN_HPM_ALL_SET_MASK 0x1fffffff /******************************************* * scounteren - SRW - Counter Enable */ static inline uint_xlen_t csr_read_scounteren(void) { uint_xlen_t value; __asm__ volatile("csrr %0, scounteren" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_scounteren(uint_xlen_t value) { __asm__ volatile("csrw scounteren, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_scounteren(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, scounteren, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mscratch - MRW - Machine Mode Scratch Register */ static inline uint_xlen_t csr_read_mscratch(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mscratch" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mscratch(uint_xlen_t value) { __asm__ volatile("csrw mscratch, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mscratch(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mscratch, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mepc - MRW - Machine Exception Program Counter */ static inline uint_xlen_t csr_read_mepc(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mepc" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mepc(uint_xlen_t value) { __asm__ volatile("csrw mepc, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mepc(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mepc, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mcause - MRW - Machine Exception Cause */ static inline uint_xlen_t csr_read_mcause(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mcause" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mcause(uint_xlen_t value) { __asm__ volatile("csrw mcause, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mcause(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mcause, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_mcause(uint_xlen_t mask) { __asm__ volatile("csrrs zero, mcause, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_mcause(uint_xlen_t mask) { __asm__ volatile("csrrc zero, mcause, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_set_bits_mcause(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrs %0, mcause, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint_xlen_t csr_read_clr_bits_mcause(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrc %0, mcause, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* mcause, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_MCAUSE(VALUE) \ __asm__ volatile("csrrwi zero, mcause, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* mcause, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_MCAUSE(MASK) \ __asm__ volatile("csrrsi zero, mcause, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* mcause, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_MCAUSE(MASK) \ __asm__ volatile("csrrci zero, mcause, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define MCAUSE_INTERRUPT_BIT_OFFSET (__riscv_xlen - 1) #define MCAUSE_INTERRUPT_BIT_WIDTH 1 #define MCAUSE_INTERRUPT_BIT_MASK (0x1UL << ((__riscv_xlen - 1))) #define MCAUSE_INTERRUPT_ALL_SET_MASK 0x1 #define MCAUSE_EXCEPTION_CODE_BIT_OFFSET 0 #define MCAUSE_EXCEPTION_CODE_BIT_WIDTH ((__riscv_xlen - 2) - (0) + 1) #define MCAUSE_EXCEPTION_CODE_BIT_MASK ((1UL << (((__riscv_xlen - 2) - (0) + 1) - 1)) << (0)) #define MCAUSE_EXCEPTION_CODE_ALL_SET_MASK ((1UL << (((__riscv_xlen - 2) - (0) + 1) - 1)) << (0)) /******************************************* * mtval - MRW - Machine Trap Value */ static inline uint_xlen_t csr_read_mtval(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mtval" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mtval(uint_xlen_t value) { __asm__ volatile("csrw mtval, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mtval(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mtval, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * sscratch - SRW - Supervisor Mode Scratch Register */ static inline uint_xlen_t csr_read_sscratch(void) { uint_xlen_t value; __asm__ volatile("csrr %0, sscratch" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_sscratch(uint_xlen_t value) { __asm__ volatile("csrw sscratch, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_sscratch(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, sscratch, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * sepc - SRW - Supervisor Exception Program Counter */ static inline uint_xlen_t csr_read_sepc(void) { uint_xlen_t value; __asm__ volatile("csrr %0, sepc" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_sepc(uint_xlen_t value) { __asm__ volatile("csrw sepc, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_sepc(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, sepc, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * scause - SRW - Supervisor Exception Cause */ static inline uint_xlen_t csr_read_scause(void) { uint_xlen_t value; __asm__ volatile("csrr %0, scause" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_scause(uint_xlen_t value) { __asm__ volatile("csrw scause, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_scause(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, scause, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_scause(uint_xlen_t mask) { __asm__ volatile("csrrs zero, scause, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_scause(uint_xlen_t mask) { __asm__ volatile("csrrc zero, scause, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_set_bits_scause(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrs %0, scause, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint_xlen_t csr_read_clr_bits_scause(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrc %0, scause, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* scause, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_SCAUSE(VALUE) \ __asm__ volatile("csrrwi zero, scause, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* scause, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_SCAUSE(MASK) \ __asm__ volatile("csrrsi zero, scause, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* scause, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_SCAUSE(MASK) \ __asm__ volatile("csrrci zero, scause, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define SCAUSE_INTERRUPT_BIT_OFFSET (__riscv_xlen - 1) #define SCAUSE_INTERRUPT_BIT_WIDTH 1 #define SCAUSE_INTERRUPT_BIT_MASK (0x1UL << ((__riscv_xlen - 1))) #define SCAUSE_INTERRUPT_ALL_SET_MASK 0x1 #define SCAUSE_EXCEPTION_CODE_BIT_OFFSET 0 #define SCAUSE_EXCEPTION_CODE_BIT_WIDTH ((__riscv_xlen - 2) - (0) + 1) #define SCAUSE_EXCEPTION_CODE_BIT_MASK ((1UL << (((__riscv_xlen - 2) - (0) + 1) - 1)) << (0)) #define SCAUSE_EXCEPTION_CODE_ALL_SET_MASK ((1UL << (((__riscv_xlen - 2) - (0) + 1) - 1)) << (0)) /******************************************* * sstatus - SRW - Supervisor Status */ static inline uint_xlen_t csr_read_sstatus(void) { uint_xlen_t value; __asm__ volatile("csrr %0, sstatus" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_sstatus(uint_xlen_t value) { __asm__ volatile("csrw sstatus, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_sstatus(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, sstatus, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_sstatus(uint_xlen_t mask) { __asm__ volatile("csrrs zero, sstatus, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_sstatus(uint_xlen_t mask) { __asm__ volatile("csrrc zero, sstatus, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_set_bits_sstatus(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrs %0, sstatus, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint_xlen_t csr_read_clr_bits_sstatus(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrc %0, sstatus, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* sstatus, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_SSTATUS(VALUE) \ __asm__ volatile("csrrwi zero, sstatus, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* sstatus, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_SSTATUS(MASK) \ __asm__ volatile("csrrsi zero, sstatus, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* sstatus, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_SSTATUS(MASK) \ __asm__ volatile("csrrci zero, sstatus, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define SSTATUS_SIE_BIT_OFFSET 2 #define SSTATUS_SIE_BIT_WIDTH 1 #define SSTATUS_SIE_BIT_MASK 0x4 #define SSTATUS_SIE_ALL_SET_MASK 0x1 #define SSTATUS_SPIE_BIT_OFFSET 5 #define SSTATUS_SPIE_BIT_WIDTH 1 #define SSTATUS_SPIE_BIT_MASK 0x20 #define SSTATUS_SPIE_ALL_SET_MASK 0x1 #define SSTATUS_SPP_BIT_OFFSET 8 #define SSTATUS_SPP_BIT_WIDTH 1 #define SSTATUS_SPP_BIT_MASK 0x100 #define SSTATUS_SPP_ALL_SET_MASK 0x1 /******************************************* * stvec - SRW - Supervisor Trap Vector Base Address */ static inline uint_xlen_t csr_read_stvec(void) { uint_xlen_t value; __asm__ volatile("csrr %0, stvec" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_stvec(uint_xlen_t value) { __asm__ volatile("csrw stvec, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_stvec(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, stvec, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_stvec(uint_xlen_t mask) { __asm__ volatile("csrrs zero, stvec, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_stvec(uint_xlen_t mask) { __asm__ volatile("csrrc zero, stvec, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_set_bits_stvec(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrs %0, stvec, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint_xlen_t csr_read_clr_bits_stvec(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrc %0, stvec, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* stvec, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_STVEC(VALUE) \ __asm__ volatile("csrrwi zero, stvec, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* stvec, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_STVEC(MASK) \ __asm__ volatile("csrrsi zero, stvec, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* stvec, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_STVEC(MASK) \ __asm__ volatile("csrrci zero, stvec, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define STVEC_BASE_BIT_OFFSET 2 #define STVEC_BASE_BIT_WIDTH ((__riscv_xlen - 1) - (2) + 1) #define STVEC_BASE_BIT_MASK ((1UL << (((__riscv_xlen - 1) - (2) + 1) - 1)) << (2)) #define STVEC_BASE_ALL_SET_MASK ((1UL << (((__riscv_xlen - 1) - (2) + 1) - 1)) << (0)) #define STVEC_MODE_BIT_OFFSET 0 #define STVEC_MODE_BIT_WIDTH 2 #define STVEC_MODE_BIT_MASK 0x3 #define STVEC_MODE_ALL_SET_MASK 0x3 /******************************************* * sideleg - SRW - Supervisor Interrupt Delegation */ static inline uint_xlen_t csr_read_sideleg(void) { uint_xlen_t value; __asm__ volatile("csrr %0, sideleg" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_sideleg(uint_xlen_t value) { __asm__ volatile("csrw sideleg, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_sideleg(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, sideleg, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * sedeleg - SRW - Supervisor Exception Delegation */ static inline uint_xlen_t csr_read_sedeleg(void) { uint_xlen_t value; __asm__ volatile("csrr %0, sedeleg" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_sedeleg(uint_xlen_t value) { __asm__ volatile("csrw sedeleg, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_sedeleg(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, sedeleg, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * sip - SRW - Supervisor Interrupt Pending */ static inline uint_xlen_t csr_read_sip(void) { uint_xlen_t value; __asm__ volatile("csrr %0, sip" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_sip(uint_xlen_t value) { __asm__ volatile("csrw sip, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_sip(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, sip, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_sip(uint_xlen_t mask) { __asm__ volatile("csrrs zero, sip, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_sip(uint_xlen_t mask) { __asm__ volatile("csrrc zero, sip, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_set_bits_sip(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrs %0, sip, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint_xlen_t csr_read_clr_bits_sip(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrc %0, sip, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* sip, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_SIP(VALUE) \ __asm__ volatile("csrrwi zero, sip, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* sip, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_SIP(MASK) \ __asm__ volatile("csrrsi zero, sip, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* sip, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_SIP(MASK) \ __asm__ volatile("csrrci zero, sip, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define SIP_SSI_BIT_OFFSET 1 #define SIP_SSI_BIT_WIDTH 1 #define SIP_SSI_BIT_MASK 0x2 #define SIP_SSI_ALL_SET_MASK 0x1 #define SIP_STI_BIT_OFFSET 5 #define SIP_STI_BIT_WIDTH 1 #define SIP_STI_BIT_MASK 0x20 #define SIP_STI_ALL_SET_MASK 0x1 #define SIP_SEI_BIT_OFFSET 9 #define SIP_SEI_BIT_WIDTH 1 #define SIP_SEI_BIT_MASK 0x200 #define SIP_SEI_ALL_SET_MASK 0x1 #define SIP_USI_BIT_OFFSET 0 #define SIP_USI_BIT_WIDTH 1 #define SIP_USI_BIT_MASK 0x1 #define SIP_USI_ALL_SET_MASK 0x1 #define SIP_UTI_BIT_OFFSET 4 #define SIP_UTI_BIT_WIDTH 1 #define SIP_UTI_BIT_MASK 0x10 #define SIP_UTI_ALL_SET_MASK 0x1 #define SIP_UEI_BIT_OFFSET 8 #define SIP_UEI_BIT_WIDTH 1 #define SIP_UEI_BIT_MASK 0x100 #define SIP_UEI_ALL_SET_MASK 0x1 /******************************************* * sie - SRW - Supervisor Interrupt Enable */ static inline uint_xlen_t csr_read_sie(void) { uint_xlen_t value; __asm__ volatile("csrr %0, sie" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_sie(uint_xlen_t value) { __asm__ volatile("csrw sie, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_sie(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, sie, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_sie(uint_xlen_t mask) { __asm__ volatile("csrrs zero, sie, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_sie(uint_xlen_t mask) { __asm__ volatile("csrrc zero, sie, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_set_bits_sie(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrs %0, sie, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint_xlen_t csr_read_clr_bits_sie(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrc %0, sie, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* sie, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_SIE(VALUE) \ __asm__ volatile("csrrwi zero, sie, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* sie, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_SIE(MASK) \ __asm__ volatile("csrrsi zero, sie, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* sie, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_SIE(MASK) \ __asm__ volatile("csrrci zero, sie, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define SIE_SSI_BIT_OFFSET 1 #define SIE_SSI_BIT_WIDTH 1 #define SIE_SSI_BIT_MASK 0x2 #define SIE_SSI_ALL_SET_MASK 0x1 #define SIE_STI_BIT_OFFSET 5 #define SIE_STI_BIT_WIDTH 1 #define SIE_STI_BIT_MASK 0x20 #define SIE_STI_ALL_SET_MASK 0x1 #define SIE_SEI_BIT_OFFSET 9 #define SIE_SEI_BIT_WIDTH 1 #define SIE_SEI_BIT_MASK 0x200 #define SIE_SEI_ALL_SET_MASK 0x1 #define SIE_USI_BIT_OFFSET 0 #define SIE_USI_BIT_WIDTH 1 #define SIE_USI_BIT_MASK 0x1 #define SIE_USI_ALL_SET_MASK 0x1 #define SIE_UTI_BIT_OFFSET 4 #define SIE_UTI_BIT_WIDTH 1 #define SIE_UTI_BIT_MASK 0x10 #define SIE_UTI_ALL_SET_MASK 0x1 #define SIE_UEI_BIT_OFFSET 8 #define SIE_UEI_BIT_WIDTH 1 #define SIE_UEI_BIT_MASK 0x100 #define SIE_UEI_ALL_SET_MASK 0x1 /******************************************* * ustatus - URW - User mode restricted view of mstatus */ static inline uint_xlen_t csr_read_ustatus(void) { uint_xlen_t value; __asm__ volatile("csrr %0, ustatus" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_ustatus(uint_xlen_t value) { __asm__ volatile("csrw ustatus, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_ustatus(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, ustatus, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_ustatus(uint_xlen_t mask) { __asm__ volatile("csrrs zero, ustatus, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_ustatus(uint_xlen_t mask) { __asm__ volatile("csrrc zero, ustatus, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_set_bits_ustatus(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrs %0, ustatus, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint_xlen_t csr_read_clr_bits_ustatus(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrc %0, ustatus, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* ustatus, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_USTATUS(VALUE) \ __asm__ volatile("csrrwi zero, ustatus, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* ustatus, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_USTATUS(MASK) \ __asm__ volatile("csrrsi zero, ustatus, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* ustatus, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_USTATUS(MASK) \ __asm__ volatile("csrrci zero, ustatus, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define USTATUS_UIE_BIT_OFFSET 1 #define USTATUS_UIE_BIT_WIDTH 1 #define USTATUS_UIE_BIT_MASK 0x2 #define USTATUS_UIE_ALL_SET_MASK 0x1 #define USTATUS_UPIE_BIT_OFFSET 3 #define USTATUS_UPIE_BIT_WIDTH 1 #define USTATUS_UPIE_BIT_MASK 0x8 #define USTATUS_UPIE_ALL_SET_MASK 0x1 /******************************************* * uip - URW - User Interrupt Pending */ static inline uint_xlen_t csr_read_uip(void) { uint_xlen_t value; __asm__ volatile("csrr %0, uip" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_uip(uint_xlen_t value) { __asm__ volatile("csrw uip, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_uip(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, uip, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_uip(uint_xlen_t mask) { __asm__ volatile("csrrs zero, uip, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_uip(uint_xlen_t mask) { __asm__ volatile("csrrc zero, uip, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_set_bits_uip(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrs %0, uip, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint_xlen_t csr_read_clr_bits_uip(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrc %0, uip, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* uip, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_UIP(VALUE) \ __asm__ volatile("csrrwi zero, uip, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* uip, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_UIP(MASK) \ __asm__ volatile("csrrsi zero, uip, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* uip, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_UIP(MASK) \ __asm__ volatile("csrrci zero, uip, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define UIP_USI_BIT_OFFSET 0 #define UIP_USI_BIT_WIDTH 1 #define UIP_USI_BIT_MASK 0x1 #define UIP_USI_ALL_SET_MASK 0x1 #define UIP_UTI_BIT_OFFSET 4 #define UIP_UTI_BIT_WIDTH 1 #define UIP_UTI_BIT_MASK 0x10 #define UIP_UTI_ALL_SET_MASK 0x1 #define UIP_UEI_BIT_OFFSET 8 #define UIP_UEI_BIT_WIDTH 1 #define UIP_UEI_BIT_MASK 0x100 #define UIP_UEI_ALL_SET_MASK 0x1 /******************************************* * uie - URW - User Interrupt Enable */ static inline uint_xlen_t csr_read_uie(void) { uint_xlen_t value; __asm__ volatile("csrr %0, uie" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_uie(uint_xlen_t value) { __asm__ volatile("csrw uie, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_uie(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, uie, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_uie(uint_xlen_t mask) { __asm__ volatile("csrrs zero, uie, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_uie(uint_xlen_t mask) { __asm__ volatile("csrrc zero, uie, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_set_bits_uie(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrs %0, uie, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint_xlen_t csr_read_clr_bits_uie(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrc %0, uie, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* uie, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_UIE(VALUE) \ __asm__ volatile("csrrwi zero, uie, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* uie, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_UIE(MASK) \ __asm__ volatile("csrrsi zero, uie, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* uie, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_UIE(MASK) \ __asm__ volatile("csrrci zero, uie, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define UIE_USI_BIT_OFFSET 0 #define UIE_USI_BIT_WIDTH 1 #define UIE_USI_BIT_MASK 0x1 #define UIE_USI_ALL_SET_MASK 0x1 #define UIE_UTI_BIT_OFFSET 4 #define UIE_UTI_BIT_WIDTH 1 #define UIE_UTI_BIT_MASK 0x10 #define UIE_UTI_ALL_SET_MASK 0x1 #define UIE_UEI_BIT_OFFSET 8 #define UIE_UEI_BIT_WIDTH 1 #define UIE_UEI_BIT_MASK 0x100 #define UIE_UEI_ALL_SET_MASK 0x1 /******************************************* * uscratch - URW - User Mode Scratch Register */ static inline uint_xlen_t csr_read_uscratch(void) { uint_xlen_t value; __asm__ volatile("csrr %0, uscratch" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_uscratch(uint_xlen_t value) { __asm__ volatile("csrw uscratch, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_uscratch(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, uscratch, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * uepc - URW - User Exception Program Counter */ static inline uint_xlen_t csr_read_uepc(void) { uint_xlen_t value; __asm__ volatile("csrr %0, uepc" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_uepc(uint_xlen_t value) { __asm__ volatile("csrw uepc, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_uepc(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, uepc, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * ucause - URW - User Exception Cause */ static inline uint_xlen_t csr_read_ucause(void) { uint_xlen_t value; __asm__ volatile("csrr %0, ucause" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_ucause(uint_xlen_t value) { __asm__ volatile("csrw ucause, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_ucause(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, ucause, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_ucause(uint_xlen_t mask) { __asm__ volatile("csrrs zero, ucause, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_ucause(uint_xlen_t mask) { __asm__ volatile("csrrc zero, ucause, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_set_bits_ucause(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrs %0, ucause, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint_xlen_t csr_read_clr_bits_ucause(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrc %0, ucause, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* ucause, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_UCAUSE(VALUE) \ __asm__ volatile("csrrwi zero, ucause, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* ucause, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_UCAUSE(MASK) \ __asm__ volatile("csrrsi zero, ucause, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* ucause, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_UCAUSE(MASK) \ __asm__ volatile("csrrci zero, ucause, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define UCAUSE_INTERRUPT_BIT_OFFSET (__riscv_xlen - 1) #define UCAUSE_INTERRUPT_BIT_WIDTH 1 #define UCAUSE_INTERRUPT_BIT_MASK (0x1UL << ((__riscv_xlen - 1))) #define UCAUSE_INTERRUPT_ALL_SET_MASK 0x1 #define UCAUSE_EXCEPTION_CODE_BIT_OFFSET 0 #define UCAUSE_EXCEPTION_CODE_BIT_WIDTH ((__riscv_xlen - 2) - (0) + 1) #define UCAUSE_EXCEPTION_CODE_BIT_MASK ((1UL << (((__riscv_xlen - 2) - (0) + 1) - 1)) << (0)) #define UCAUSE_EXCEPTION_CODE_ALL_SET_MASK ((1UL << (((__riscv_xlen - 2) - (0) + 1) - 1)) << (0)) /******************************************* * utvec - URW - User Trap Vector Base Address */ static inline uint_xlen_t csr_read_utvec(void) { uint_xlen_t value; __asm__ volatile("csrr %0, utvec" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_utvec(uint_xlen_t value) { __asm__ volatile("csrw utvec, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_utvec(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, utvec, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /* Register CSR bit set and clear instructions */ static inline void csr_set_bits_utvec(uint_xlen_t mask) { __asm__ volatile("csrrs zero, utvec, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline void csr_clr_bits_utvec(uint_xlen_t mask) { __asm__ volatile("csrrc zero, utvec, %0" : /* output: none */ : "r"(mask) /* input : register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_set_bits_utvec(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrs %0, utvec, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } static inline uint_xlen_t csr_read_clr_bits_utvec(uint_xlen_t mask) { uint_xlen_t value; __asm__ volatile("csrrc %0, utvec, %1" : "=r"(value) /* output: register %0 */ : "r"(mask) /* input : register */ : /* clobbers: none */); return value; } /* utvec, CSR write value via immediate value (only up to 5 bits) */ #define CSR_WRITE_IMM_UTVEC(VALUE) \ __asm__ volatile("csrrwi zero, utvec, %0" \ : /* output: none */ \ : "i"(VALUE) /* input : immediate */ \ : /* clobbers: none */) /* utvec, CSR set bits via immediate value mask (only up to 5 bits) */ #define CSR_SET_BITS_IMM_UTVEC(MASK) \ __asm__ volatile("csrrsi zero, utvec, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) /* utvec, CSR clear bits via immediate value mask (only up to 5 bits) */ #define CSR_CLR_BITS_IMM_UTVEC(MASK) \ __asm__ volatile("csrrci zero, utvec, %0" \ : /* output: none */ \ : "i"(MASK) /* input : immediate */ \ : /* clobbers: none */) #define UTVEC_BASE_BIT_OFFSET 2 #define UTVEC_BASE_BIT_WIDTH ((__riscv_xlen - 1) - (2) + 1) #define UTVEC_BASE_BIT_MASK ((1UL << (((__riscv_xlen - 1) - (2) + 1) - 1)) << (2)) #define UTVEC_BASE_ALL_SET_MASK ((1UL << (((__riscv_xlen - 1) - (2) + 1) - 1)) << (0)) #define UTVEC_MODE_BIT_OFFSET 0 #define UTVEC_MODE_BIT_WIDTH 2 #define UTVEC_MODE_BIT_MASK 0x3 #define UTVEC_MODE_ALL_SET_MASK 0x3 /******************************************* * utval - URW - User Trap Value */ static inline uint_xlen_t csr_read_utval(void) { uint_xlen_t value; __asm__ volatile("csrr %0, utval" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_utval(uint_xlen_t value) { __asm__ volatile("csrw utval, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_utval(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, utval, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * fflags - URW - Floating-Point Accrued Exceptions. */ static inline uint_xlen_t csr_read_fflags(void) { uint_xlen_t value; __asm__ volatile("csrr %0, fflags" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_fflags(uint_xlen_t value) { __asm__ volatile("csrw fflags, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_fflags(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, fflags, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * frm - URW - Floating-Point Dynamic Rounding Mode. */ static inline uint_xlen_t csr_read_frm(void) { uint_xlen_t value; __asm__ volatile("csrr %0, frm" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_frm(uint_xlen_t value) { __asm__ volatile("csrw frm, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_frm(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, frm, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * fcsr - URW - Floating-Point Control and Status */ static inline uint_xlen_t csr_read_fcsr(void) { uint_xlen_t value; __asm__ volatile("csrr %0, fcsr" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_fcsr(uint_xlen_t value) { __asm__ volatile("csrw fcsr, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_fcsr(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, fcsr, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * cycle - URO - Cycle counter for RDCYCLE instruction. */ static inline uint_xlen_t csr_read_cycle(void) { uint_xlen_t value; __asm__ volatile("csrr %0, cycle" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * time - URO - Timer for RDTIME instruction. */ static inline uint_xlen_t csr_read_time(void) { uint_xlen_t value; __asm__ volatile("csrr %0, time" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * instret - URO - Instructions-retired counter for RDINSTRET instruction. */ static inline uint_xlen_t csr_read_instret(void) { uint_xlen_t value; __asm__ volatile("csrr %0, instret" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * hpmcounter3 - URO - Performance-monitoring counter. */ static inline uint_xlen_t csr_read_hpmcounter3(void) { uint_xlen_t value; __asm__ volatile("csrr %0, hpmcounter3" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * hpmcounter4 - URO - Performance-monitoring counter. */ static inline uint_xlen_t csr_read_hpmcounter4(void) { uint_xlen_t value; __asm__ volatile("csrr %0, hpmcounter4" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * hpmcounter31 - URO - Performance-monitoring counter. */ static inline uint_xlen_t csr_read_hpmcounter31(void) { uint_xlen_t value; __asm__ volatile("csrr %0, hpmcounter31" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * cycleh - URO - Upper 32 bits of cycle, RV32I only. */ static inline uint_xlen_t csr_read_cycleh(void) { uint_xlen_t value; __asm__ volatile("csrr %0, cycleh" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * timeh - URO - Upper 32 bits of time, RV32I only. */ static inline uint_xlen_t csr_read_timeh(void) { uint_xlen_t value; __asm__ volatile("csrr %0, timeh" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * instreth - URO - Upper 32 bits of instret, RV32I only. */ static inline uint_xlen_t csr_read_instreth(void) { uint_xlen_t value; __asm__ volatile("csrr %0, instreth" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * hpmcounter3h - URO - Upper 32 bits of hpmcounter3, RV32I only. */ static inline uint_xlen_t csr_read_hpmcounter3h(void) { uint_xlen_t value; __asm__ volatile("csrr %0, hpmcounter3h" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * hpmcounter4h - URO - Upper 32 bits of hpmcounter4, RV32I only. */ static inline uint_xlen_t csr_read_hpmcounter4h(void) { uint_xlen_t value; __asm__ volatile("csrr %0, hpmcounter4h" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * hpmcounter31h - URO - Upper 32 bits of hpmcounter31, RV32I only. */ static inline uint_xlen_t csr_read_hpmcounter31h(void) { uint_xlen_t value; __asm__ volatile("csrr %0, hpmcounter31h" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * stval - SRW - Supervisor bad address or instruction. */ static inline uint_xlen_t csr_read_stval(void) { uint_xlen_t value; __asm__ volatile("csrr %0, stval" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_stval(uint_xlen_t value) { __asm__ volatile("csrw stval, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_stval(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, stval, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * satp - SRW - Supervisor address translation and protection. */ static inline uint_xlen_t csr_read_satp(void) { uint_xlen_t value; __asm__ volatile("csrr %0, satp" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_satp(uint_xlen_t value) { __asm__ volatile("csrw satp, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_satp(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, satp, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * hstatus - HRW - Hypervisor status register. */ static inline uint_xlen_t csr_read_hstatus(void) { uint_xlen_t value; __asm__ volatile("csrr %0, hstatus" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_hstatus(uint_xlen_t value) { __asm__ volatile("csrw hstatus, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_hstatus(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, hstatus, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * hedeleg - HRW - Hypervisor exception delegation register. */ static inline uint_xlen_t csr_read_hedeleg(void) { uint_xlen_t value; __asm__ volatile("csrr %0, hedeleg" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_hedeleg(uint_xlen_t value) { __asm__ volatile("csrw hedeleg, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_hedeleg(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, hedeleg, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * hideleg - HRW - Hypervisor interrupt delegation register. */ static inline uint_xlen_t csr_read_hideleg(void) { uint_xlen_t value; __asm__ volatile("csrr %0, hideleg" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_hideleg(uint_xlen_t value) { __asm__ volatile("csrw hideleg, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_hideleg(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, hideleg, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * hcounteren - HRW - Hypervisor counter enable. */ static inline uint_xlen_t csr_read_hcounteren(void) { uint_xlen_t value; __asm__ volatile("csrr %0, hcounteren" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_hcounteren(uint_xlen_t value) { __asm__ volatile("csrw hcounteren, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_hcounteren(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, hcounteren, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * hgatp - HRW - Hypervisor guest address translation and protection. */ static inline uint_xlen_t csr_read_hgatp(void) { uint_xlen_t value; __asm__ volatile("csrr %0, hgatp" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_hgatp(uint_xlen_t value) { __asm__ volatile("csrw hgatp, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_hgatp(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, hgatp, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * htimedelta - HRW - Delta for VS/VU-mode timer. */ static inline uint_xlen_t csr_read_htimedelta(void) { uint_xlen_t value; __asm__ volatile("csrr %0, htimedelta" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_htimedelta(uint_xlen_t value) { __asm__ volatile("csrw htimedelta, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_htimedelta(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, htimedelta, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * htimedeltah - HRW - Upper 32 bits of htimedelta, RV32I only. */ static inline uint_xlen_t csr_read_htimedeltah(void) { uint_xlen_t value; __asm__ volatile("csrr %0, htimedeltah" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_htimedeltah(uint_xlen_t value) { __asm__ volatile("csrw htimedeltah, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_htimedeltah(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, htimedeltah, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * vsstatus - HRW - Virtual supervisor status register. */ static inline uint_xlen_t csr_read_vsstatus(void) { uint_xlen_t value; __asm__ volatile("csrr %0, vsstatus" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_vsstatus(uint_xlen_t value) { __asm__ volatile("csrw vsstatus, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_vsstatus(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, vsstatus, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * vsie - HRW - Virtual supervisor interrupt-enable register. */ static inline uint_xlen_t csr_read_vsie(void) { uint_xlen_t value; __asm__ volatile("csrr %0, vsie" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_vsie(uint_xlen_t value) { __asm__ volatile("csrw vsie, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_vsie(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, vsie, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * vstvec - HRW - Virtual supervisor trap handler base address. */ static inline uint_xlen_t csr_read_vstvec(void) { uint_xlen_t value; __asm__ volatile("csrr %0, vstvec" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_vstvec(uint_xlen_t value) { __asm__ volatile("csrw vstvec, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_vstvec(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, vstvec, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * vsscratch - HRW - Virtual supervisor scratch register. */ static inline uint_xlen_t csr_read_vsscratch(void) { uint_xlen_t value; __asm__ volatile("csrr %0, vsscratch" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_vsscratch(uint_xlen_t value) { __asm__ volatile("csrw vsscratch, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_vsscratch(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, vsscratch, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * vsepc - HRW - Virtual supervisor exception program counter. */ static inline uint_xlen_t csr_read_vsepc(void) { uint_xlen_t value; __asm__ volatile("csrr %0, vsepc" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_vsepc(uint_xlen_t value) { __asm__ volatile("csrw vsepc, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_vsepc(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, vsepc, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * vscause - HRW - Virtual supervisor trap cause. */ static inline uint_xlen_t csr_read_vscause(void) { uint_xlen_t value; __asm__ volatile("csrr %0, vscause" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_vscause(uint_xlen_t value) { __asm__ volatile("csrw vscause, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_vscause(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, vscause, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * vstval - HRW - Virtual supervisor bad address or instruction. */ static inline uint_xlen_t csr_read_vstval(void) { uint_xlen_t value; __asm__ volatile("csrr %0, vstval" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_vstval(uint_xlen_t value) { __asm__ volatile("csrw vstval, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_vstval(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, vstval, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * vsip - HRW - Virtual supervisor interrupt pending. */ static inline uint_xlen_t csr_read_vsip(void) { uint_xlen_t value; __asm__ volatile("csrr %0, vsip" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_vsip(uint_xlen_t value) { __asm__ volatile("csrw vsip, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_vsip(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, vsip, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * vsatp - HRW - Virtual supervisor address translation and protection. */ static inline uint_xlen_t csr_read_vsatp(void) { uint_xlen_t value; __asm__ volatile("csrr %0, vsatp" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_vsatp(uint_xlen_t value) { __asm__ volatile("csrw vsatp, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_vsatp(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, vsatp, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mbase - MRW - Base register. */ static inline uint_xlen_t csr_read_mbase(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mbase" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mbase(uint_xlen_t value) { __asm__ volatile("csrw mbase, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mbase(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mbase, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mbound - MRW - Bound register. */ static inline uint_xlen_t csr_read_mbound(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mbound" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mbound(uint_xlen_t value) { __asm__ volatile("csrw mbound, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mbound(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mbound, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mibase - MRW - Instruction base register. */ static inline uint_xlen_t csr_read_mibase(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mibase" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mibase(uint_xlen_t value) { __asm__ volatile("csrw mibase, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mibase(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mibase, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mibound - MRW - Instruction bound register. */ static inline uint_xlen_t csr_read_mibound(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mibound" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mibound(uint_xlen_t value) { __asm__ volatile("csrw mibound, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mibound(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mibound, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mdbase - MRW - Data base register. */ static inline uint_xlen_t csr_read_mdbase(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mdbase" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mdbase(uint_xlen_t value) { __asm__ volatile("csrw mdbase, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mdbase(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mdbase, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mdbound - MRW - Data bound register. */ static inline uint_xlen_t csr_read_mdbound(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mdbound" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mdbound(uint_xlen_t value) { __asm__ volatile("csrw mdbound, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mdbound(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mdbound, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * pmpcfg0 - MRW - Physical memory protection configuration. */ static inline uint_xlen_t csr_read_pmpcfg0(void) { uint_xlen_t value; __asm__ volatile("csrr %0, pmpcfg0" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_pmpcfg0(uint_xlen_t value) { __asm__ volatile("csrw pmpcfg0, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_pmpcfg0(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, pmpcfg0, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * pmpcfg1 - MRW - Physical memory protection configuration, RV32 only. */ static inline uint_xlen_t csr_read_pmpcfg1(void) { uint_xlen_t value; __asm__ volatile("csrr %0, pmpcfg1" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_pmpcfg1(uint_xlen_t value) { __asm__ volatile("csrw pmpcfg1, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_pmpcfg1(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, pmpcfg1, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * pmpcfg2 - MRW - Physical memory protection configuration. */ static inline uint_xlen_t csr_read_pmpcfg2(void) { uint_xlen_t value; __asm__ volatile("csrr %0, pmpcfg2" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_pmpcfg2(uint_xlen_t value) { __asm__ volatile("csrw pmpcfg2, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_pmpcfg2(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, pmpcfg2, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * pmpcfg3 - MRW - Physical memory protection configuration, RV32 only. */ static inline uint_xlen_t csr_read_pmpcfg3(void) { uint_xlen_t value; __asm__ volatile("csrr %0, pmpcfg3" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_pmpcfg3(uint_xlen_t value) { __asm__ volatile("csrw pmpcfg3, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_pmpcfg3(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, pmpcfg3, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * pmpaddr0 - MRW - Physical memory protection address register. */ static inline uint_xlen_t csr_read_pmpaddr0(void) { uint_xlen_t value; __asm__ volatile("csrr %0, pmpaddr0" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_pmpaddr0(uint_xlen_t value) { __asm__ volatile("csrw pmpaddr0, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_pmpaddr0(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, pmpaddr0, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * pmpaddr1 - MRW - Physical memory protection address register. */ static inline uint_xlen_t csr_read_pmpaddr1(void) { uint_xlen_t value; __asm__ volatile("csrr %0, pmpaddr1" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_pmpaddr1(uint_xlen_t value) { __asm__ volatile("csrw pmpaddr1, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_pmpaddr1(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, pmpaddr1, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * pmpaddr15 - MRW - Physical memory protection address register. */ static inline uint_xlen_t csr_read_pmpaddr15(void) { uint_xlen_t value; __asm__ volatile("csrr %0, pmpaddr15" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_pmpaddr15(uint_xlen_t value) { __asm__ volatile("csrw pmpaddr15, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_pmpaddr15(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, pmpaddr15, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mhpmcounter4 - MRW - Machine performance-monitoring counter. */ static inline uint_xlen_t csr_read_mhpmcounter4(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mhpmcounter4" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mhpmcounter4(uint_xlen_t value) { __asm__ volatile("csrw mhpmcounter4, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mhpmcounter4(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mhpmcounter4, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mhpmcounter31 - MRW - Machine performance-monitoring counter. */ static inline uint_xlen_t csr_read_mhpmcounter31(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mhpmcounter31" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mhpmcounter31(uint_xlen_t value) { __asm__ volatile("csrw mhpmcounter31, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mhpmcounter31(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mhpmcounter31, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mcycleh - MRW - Upper 32 bits of mcycle, RV32I only. */ static inline uint32_t csr_read_mcycleh(void) { uint_csr32_t value; __asm__ volatile("csrr %0, mcycleh" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mcycleh(uint_csr32_t value) { __asm__ volatile("csrw mcycleh, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint32_t csr_read_write_mcycleh(uint32_t new_value) { uint_csr32_t prev_value; __asm__ volatile("csrrw %0, mcycleh, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * minstreth - MRW - Upper 32 bits of minstret, RV32I only. */ static inline uint32_t csr_read_minstreth(void) { uint_csr32_t value; __asm__ volatile("csrr %0, minstreth" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_minstreth(uint_csr32_t value) { __asm__ volatile("csrw minstreth, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint32_t csr_read_write_minstreth(uint32_t new_value) { uint_csr32_t prev_value; __asm__ volatile("csrrw %0, minstreth, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mhpmcounter3h - MRW - Upper 32 bits of mhpmcounter3, RV32I only. */ static inline uint32_t csr_read_mhpmcounter3h(void) { uint_csr32_t value; __asm__ volatile("csrr %0, mhpmcounter3h" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mhpmcounter3h(uint_csr32_t value) { __asm__ volatile("csrw mhpmcounter3h, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint32_t csr_read_write_mhpmcounter3h(uint32_t new_value) { uint_csr32_t prev_value; __asm__ volatile("csrrw %0, mhpmcounter3h, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mhpmcounter4h - MRW - Upper 32 bits of mhpmcounter4, RV32I only. */ static inline uint32_t csr_read_mhpmcounter4h(void) { uint_csr32_t value; __asm__ volatile("csrr %0, mhpmcounter4h" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mhpmcounter4h(uint_csr32_t value) { __asm__ volatile("csrw mhpmcounter4h, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint32_t csr_read_write_mhpmcounter4h(uint32_t new_value) { uint_csr32_t prev_value; __asm__ volatile("csrrw %0, mhpmcounter4h, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mhpmcounter31h - MRW - Upper 32 bits of mhpmcounter31, RV32I only. */ static inline uint32_t csr_read_mhpmcounter31h(void) { uint_csr32_t value; __asm__ volatile("csrr %0, mhpmcounter31h" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mhpmcounter31h(uint_csr32_t value) { __asm__ volatile("csrw mhpmcounter31h, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint32_t csr_read_write_mhpmcounter31h(uint32_t new_value) { uint_csr32_t prev_value; __asm__ volatile("csrrw %0, mhpmcounter31h, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mhpmevent4 - MRW - Machine performance-monitoring event selector. */ static inline uint_xlen_t csr_read_mhpmevent4(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mhpmevent4" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mhpmevent4(uint_xlen_t value) { __asm__ volatile("csrw mhpmevent4, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mhpmevent4(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mhpmevent4, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mhpmevent31 - MRW - Machine performance-monitoring event selector. */ static inline uint_xlen_t csr_read_mhpmevent31(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mhpmevent31" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mhpmevent31(uint_xlen_t value) { __asm__ volatile("csrw mhpmevent31, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mhpmevent31(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mhpmevent31, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * tselect - MRW - Debug/Trace trigger register select. */ static inline uint_xlen_t csr_read_tselect(void) { uint_xlen_t value; __asm__ volatile("csrr %0, tselect" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_tselect(uint_xlen_t value) { __asm__ volatile("csrw tselect, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_tselect(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, tselect, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * tdata1 - MRW - First Debug/Trace trigger data register. */ static inline uint_xlen_t csr_read_tdata1(void) { uint_xlen_t value; __asm__ volatile("csrr %0, tdata1" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_tdata1(uint_xlen_t value) { __asm__ volatile("csrw tdata1, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_tdata1(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, tdata1, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * tdata2 - MRW - Second Debug/Trace trigger data register. */ static inline uint_xlen_t csr_read_tdata2(void) { uint_xlen_t value; __asm__ volatile("csrr %0, tdata2" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_tdata2(uint_xlen_t value) { __asm__ volatile("csrw tdata2, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_tdata2(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, tdata2, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * tdata3 - MRW - Third Debug/Trace trigger data register. */ static inline uint_xlen_t csr_read_tdata3(void) { uint_xlen_t value; __asm__ volatile("csrr %0, tdata3" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_tdata3(uint_xlen_t value) { __asm__ volatile("csrw tdata3, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_tdata3(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, tdata3, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * dcsr - DRW - Debug control and status register. */ static inline uint_xlen_t csr_read_dcsr(void) { uint_xlen_t value; __asm__ volatile("csrr %0, dcsr" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_dcsr(uint_xlen_t value) { __asm__ volatile("csrw dcsr, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_dcsr(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, dcsr, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * dpc - DRW - Debug PC. */ static inline uint_xlen_t csr_read_dpc(void) { uint_xlen_t value; __asm__ volatile("csrr %0, dpc" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_dpc(uint_xlen_t value) { __asm__ volatile("csrw dpc, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_dpc(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, dpc, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * dscratch0 - DRW - Debug scratch register 0. */ static inline uint_xlen_t csr_read_dscratch0(void) { uint_xlen_t value; __asm__ volatile("csrr %0, dscratch0" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_dscratch0(uint_xlen_t value) { __asm__ volatile("csrw dscratch0, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_dscratch0(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, dscratch0, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * dscratch1 - DRW - Debug scratch register 1. */ static inline uint_xlen_t csr_read_dscratch1(void) { uint_xlen_t value; __asm__ volatile("csrr %0, dscratch1" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_dscratch1(uint_xlen_t value) { __asm__ volatile("csrw dscratch1, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_dscratch1(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, dscratch1, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * hie - HRW - Hypervisor interrupt-enable register. */ static inline uint_xlen_t csr_read_hie(void) { uint_xlen_t value; __asm__ volatile("csrr %0, hie" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_hie(uint_xlen_t value) { __asm__ volatile("csrw hie, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_hie(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, hie, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * hgeie - HRW - Hypervisor guest external interrupt-enable register. */ static inline uint_xlen_t csr_read_hgeie(void) { uint_xlen_t value; __asm__ volatile("csrr %0, hgeie" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_hgeie(uint_xlen_t value) { __asm__ volatile("csrw hgeie, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_hgeie(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, hgeie, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * htval - HRW - Hypervisor bad guest physical address. */ static inline uint_xlen_t csr_read_htval(void) { uint_xlen_t value; __asm__ volatile("csrr %0, htval" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_htval(uint_xlen_t value) { __asm__ volatile("csrw htval, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_htval(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, htval, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * hip - HRW - Hypervisor interrupt pending. */ static inline uint_xlen_t csr_read_hip(void) { uint_xlen_t value; __asm__ volatile("csrr %0, hip" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_hip(uint_xlen_t value) { __asm__ volatile("csrw hip, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_hip(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, hip, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * htinst - HRW - Hypervisor trap instruction (transformed). */ static inline uint_xlen_t csr_read_htinst(void) { uint_xlen_t value; __asm__ volatile("csrr %0, htinst" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_htinst(uint_xlen_t value) { __asm__ volatile("csrw htinst, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_htinst(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, htinst, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * hgeip - HRO - Hypervisor guest external interrupt pending. */ static inline uint_xlen_t csr_read_hgeip(void) { uint_xlen_t value; __asm__ volatile("csrr %0, hgeip" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } /******************************************* * mtinst - MRW - Machine trap instruction (transformed). */ static inline uint_xlen_t csr_read_mtinst(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mtinst" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mtinst(uint_xlen_t value) { __asm__ volatile("csrw mtinst, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mtinst(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mtinst, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } /******************************************* * mtval2 - MRW - Machine bad guest physical address. */ static inline uint_xlen_t csr_read_mtval2(void) { uint_xlen_t value; __asm__ volatile("csrr %0, mtval2" : "=r"(value) /* output : register */ : /* input : none */ : /* clobbers: none */); return value; } static inline void csr_write_mtval2(uint_xlen_t value) { __asm__ volatile("csrw mtval2, %0" : /* output: none */ : "r"(value) /* input : from register */ : /* clobbers: none */); } static inline uint_xlen_t csr_read_write_mtval2(uint_xlen_t new_value) { uint_xlen_t prev_value; __asm__ volatile("csrrw %0, mtval2, %1" : "=r"(prev_value) /* output: register %0 */ : "r"(new_value) /* input : register */ : /* clobbers: none */); return prev_value; } #endif // #define RISCV_CSR_H