#ifndef INCLUDED_RISCV_H #define INCLUDED_RISCV_H #ifndef INCLUDED_OS_TYPES_H #include #endif /*INCLUDED_OS_TYPES_H*/ #ifndef INCLUDED_OS_COMPILER_H #include #endif /*INCLUDED_OS_COMPILER_H*/ /* ------------------------------------------------------------------------------------------------------------------ */ /* */ OS_STATIC_FORCE_INLINE void RISCV_enable_irq() { __asm volatile ("csrs mstatus, %0" : : "r" (0x88) ); } OS_STATIC_FORCE_INLINE void RISCV_disable_irq() { __asm volatile ("csrc mstatus, %0" : : "r" (0x88) ); } OS_STATIC_FORCE_INLINE void RISCV_NOP() { __asm volatile ("nop"); } /* ------------------------------------------------------------------------------------------------------------------ */ /* */ /********************************************************************* * @fn __AMOADD_W * * @brief Atomic Add with 32bit value * Atomically ADD 32bit value with value in memory using amoadd.d. * * @param addr - Address pointer to data, address need to be 4byte aligned * value - value to be ADDed * * @return return memory value + add value */ OS_STATIC_FORCE_INLINE int32_t RISCV_AMOADD_W(volatile int32_t *addr, int32_t value) { int32_t result; __asm volatile ("amoadd.w %0, %2, %1" : \ "=r"(result), "+A"(*addr) : "r"(value) : "memory"); return *addr; } /********************************************************************* * @fn __AMOAND_W * * @brief Atomic And with 32bit value * Atomically AND 32bit value with value in memory using amoand.d. * * @param addr - Address pointer to data, address need to be 4byte aligned * value - value to be ANDed * * @return return memory value & and value */ OS_STATIC_FORCE_INLINE int32_t RISCV_AMOAND_W(volatile int32_t *addr, int32_t value) { int32_t result; __asm volatile ("amoand.w %0, %2, %1" : \ "=r"(result), "+A"(*addr) : "r"(value) : "memory"); return *addr; } /********************************************************************* * @fn __AMOMAX_W * * @brief Atomic signed MAX with 32bit value * Atomically signed max compare 32bit value with value in memory using amomax.d. * * @param addr - Address pointer to data, address need to be 4byte aligned * value - value to be compared * * @return return the bigger value */ OS_STATIC_FORCE_INLINE int32_t RISCV_AMOMAX_W(volatile int32_t *addr, int32_t value) { int32_t result; __asm volatile ("amomax.w %0, %2, %1" : \ "=r"(result), "+A"(*addr) : "r"(value) : "memory"); return *addr; } OS_STATIC_FORCE_INLINE uint32_t RISCV_AMOMAXU_W(volatile uint32_t *addr, uint32_t value) { uint32_t result; __asm volatile ("amomaxu.w %0, %2, %1" : \ "=r"(result), "+A"(*addr) : "r"(value) : "memory"); return *addr; } /********************************************************************* * @fn __AMOMIN_W * * @brief Atomic signed MIN with 32bit value * Atomically signed min compare 32bit value with value in memory using amomin.d. * * @param addr - Address pointer to data, address need to be 4byte aligned * value - value to be compared * * @return return the smaller value */ OS_STATIC_FORCE_INLINE int32_t RISCV_AMOMIN_W(volatile int32_t *addr, int32_t value) { int32_t result; __asm volatile ("amomin.w %0, %2, %1" : \ "=r"(result), "+A"(*addr) : "r"(value) : "memory"); return *addr; } /********************************************************************* * @fn __AMOMINU_W * * @brief Atomic unsigned MIN with 32bit value * Atomically unsigned min compare 32bit value with value in memory using amominu.d. * * @param addr - Address pointer to data, address need to be 4byte aligned * value - value to be compared * * @return return the smaller value */ OS_STATIC_FORCE_INLINE uint32_t RISCV_AMOMINU_W(volatile uint32_t *addr, uint32_t value) { uint32_t result; __asm volatile ("amominu.w %0, %2, %1" : \ "=r"(result), "+A"(*addr) : "r"(value) : "memory"); return *addr; } /********************************************************************* * @fn __AMOOR_W * * @brief Atomic OR with 32bit value * Atomically OR 32bit value with value in memory using amoor.d. * * @param addr - Address pointer to data, address need to be 4byte aligned * value - value to be ORed * * @return return memory value | and value */ OS_STATIC_FORCE_INLINE int32_t RISCV_AMOOR_W(volatile int32_t *addr, int32_t value) { int32_t result; __asm volatile ("amoor.w %0, %2, %1" : \ "=r"(result), "+A"(*addr) : "r"(value) : "memory"); return *addr; } /********************************************************************* * @fn __AMOSWAP_W * * @brief Atomically swap new 32bit value into memory using amoswap.d. * * @param addr - Address pointer to data, address need to be 4byte aligned * newval - New value to be stored into the address * * @return return the original value in memory */ OS_STATIC_FORCE_INLINE uint32_t RISCV_AMOSWAP_W(volatile uint32_t *addr, uint32_t newval) { uint32_t result; __asm volatile ("amoswap.w %0, %2, %1" : \ "=r"(result), "+A"(*addr) : "r"(newval) : "memory"); return result; } /********************************************************************* * @fn __AMOXOR_W * * @brief Atomic XOR with 32bit value * Atomically XOR 32bit value with value in memory using amoxor.d. * * @param addr - Address pointer to data, address need to be 4byte aligned * value - value to be XORed * * @return return memory value ^ and value */ OS_STATIC_FORCE_INLINE int32_t RISCV_AMOXOR_W(volatile int32_t *addr, int32_t value) { int32_t result; __asm volatile ("amoxor.w %0, %2, %1" : \ "=r"(result), "+A"(*addr) : "r"(value) : "memory"); return *addr; } /* ------------------------------------------------------------------------------------------------------------------ */ /* */ extern uint32_t RISCV_get_MSTATUS(void); extern void RISCV_set_MSTATUS(uint32_t value); extern uint32_t RISCV_get_MISA(void); extern void RISCV_set_MISA(uint32_t value); extern uint32_t RISCV_get_MTVEC(void); extern void RISCV_set_MTVEC(uint32_t value); extern uint32_t RISCV_get_MSCRATCH(void); extern void RISCV_set_MSCRATCH(uint32_t value); extern uint32_t RISCV_get_MEPC(void); extern void RISCV_set_MEPC(uint32_t value); extern uint32_t RISCV_get_MCAUSE(void); extern void RISCV_set_MCAUSE(uint32_t value); extern uint32_t RISCV_get_MTVAL(void); extern void RISCV_set_MTVAL(uint32_t value); extern uint32_t RISCV_get_MVENDORID(void); extern uint32_t RISCV_get_MARCHID(void); extern uint32_t RISCV_get_MIMPID(void); extern uint32_t RISCV_get_MHARTID(void); extern uint32_t RISCV_get_SP(void); #endif /*INCLUDED_RISCV_H*/