241 lines
6.9 KiB
C
241 lines
6.9 KiB
C
#ifndef INCLUDED_RISCV_H
|
|
#define INCLUDED_RISCV_H
|
|
|
|
#ifndef INCLUDED_OS_TYPES_H
|
|
#include <os_types.h>
|
|
#endif /*INCLUDED_OS_TYPES_H*/
|
|
|
|
#ifndef INCLUDED_OS_COMPILER_H
|
|
#include <os_compiler.h>
|
|
#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_set_MSTATUS(uint32_t value);
|
|
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*/
|