#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*/ #ifndef INCLUDED_OS_MACROS_H #include #endif /*INCLUDED_OS_MACROS_H*/ /* ------------------------------------------------------------------------------------------------------------------ */ /* */ /* IO definitions */ #ifdef __cplusplus #define __I volatile /* defines 'read only' permissions */ #else #define __I volatile const /* defines 'read only' permissions */ #endif #define __O volatile /* defines 'write only' permissions */ #define __IO volatile /* defines 'read / write' permissions */ /* ------------------------------------------------------------------------------------------------------------------ */ /* */ typedef enum {QK_NoREADY = 0, QK_READY = !QK_NoREADY} QK_ErrorStatus; typedef enum {QK_DISABLE = 0, QK_ENABLE = !QK_DISABLE} QK_FunctionalState; typedef enum {QK_RESET = 0, QK_SET = !QK_RESET} QK_FlagStatus, QK_ITStatus; /* ------------------------------------------------------------------------------------------------------------------ */ /* */ extern volatile uint32_t QK_WFE_MASK; extern volatile uint32_t WFE_WkupSource; /* ------------------------------------------------------------------------------------------------------------------ */ /* */ /* memory mapped structure for HSEM */ typedef struct { __IO uint32_t RX[32]; uint8_t RESERVED0[0x80]; __I uint32_t RLRX[32]; uint8_t RESERVED1[0x80]; __IO uint32_t LSE; uint8_t RESERVED2[4]; __IO uint32_t CLR; __IO uint32_t KEY; uint8_t RESERVED3[0xF0]; __IO uint32_t IER; uint8_t RESERVED4[4]; __IO uint32_t ISR; uint8_t RESERVE5[4]; __I uint32_t ISM; uint8_t RESERVED6[4]; __I uint32_t LSM; }QK_HSEM_Type; /* memory mapped structure for IPC */ typedef struct { __IO uint32_t CTLR; __I uint32_t ISR; __I uint32_t ISM; uint32_t RESERVED0; __IO uint32_t ENA; __IO uint32_t STS; __O uint32_t SET; __O uint32_t CLR; __IO uint32_t MSG[4]; }QK_IPC_Type; /* memory mapped structure for Program Fast Interrupt Controller (PFIC) */ typedef struct{ __I uint32_t ISR[8]; __I uint32_t IPR[8]; __IO uint32_t ITHRESDR; uint32_t RESERVED; __IO uint32_t CFGR; __I uint32_t GISR; __IO uint8_t VTFIDR[4]; uint8_t RESERVED0[12]; __IO uint32_t VTFADDR[4]; uint8_t RESERVED1[0x90]; __O uint32_t IENR[8]; uint8_t RESERVED2[0x60]; __O uint32_t IRER[8]; uint8_t RESERVED3[0x60]; __O uint32_t IPSR[8]; uint8_t RESERVED4[0x60]; __O uint32_t IPRR[8]; uint8_t RESERVED5[0x60]; __IO uint32_t IACTR[8]; uint8_t RESERVED6[0xE0]; __IO uint8_t IPRIOR[256]; uint8_t RESERVED7[0x100]; __IO uint8_t IALLOCR[256]; __I uint32_t IAUTR[8]; __IO uint32_t WAKEIP[2]; uint8_t RESERVED8[0x58]; __I uint32_t CSTAR[2]; uint8_t RESERVED9[0x4F8]; __IO uint32_t EENR; __IO uint32_t EPR; __IO uint32_t EWUPR; uint8_t RESERVED10[0x84]; __IO uint32_t SCTLR; }QK_PFIC_Type; /* memory mapped structure for SysTick */ typedef struct { __IO uint32_t CTLR; __IO uint32_t ISR; //only for SysTick0 __IO uint32_t CNT; uint32_t RESERVED0; __IO uint32_t CMP; }QK_SysTick_Type; /* ------------------------------------------------------------------------------------------------------------------ */ /* */ #define QK_HSEM ((QK_HSEM_Type *) 0xE000C000 ) #define QK_IPC ((QK_IPC_Type *) 0xE000D000 ) #define QK_PFIC ((QK_PFIC_Type *) 0xE000E000 ) #define QK_NVIC QK_PFIC #define QK_NVIC_KEY3 ((uint32_t)0xBEEF0000) #define QK_SysTick0 ((QK_SysTick_Type *) 0xE000F000) #define QK_SysTick1 ((QK_SysTick_Type *) 0xE000F080) /* Core_ID */ #define QK_Core_ID_V3F ((uint8_t)0x00) #define QK_Core_ID_V5F ((uint8_t)0x01) /* ------------------------------------------------------------------------------------------------------------------ */ /* */ /********************************************************************* * @fn __enable_irq * * @brief Enable Global Interrupt * * @return none */ OS_STATIC_FORCE_INLINE void RISCV_enable_irq() { __asm volatile ("csrs 0x800, %0" : : "r" (0x88) ); } /********************************************************************* * @fn __disable_irq * * @brief Disable Global Interrupt * * @return none */ OS_STATIC_FORCE_INLINE void RISCV_disable_irq() { __asm volatile ("csrc 0x800, %0" : : "r" (0x88) ); __asm volatile ("fence.i"); } /********************************************************************* * @fn __NOP * * @brief nop * * @return none */ OS_STATIC_FORCE_INLINE void RISCV_NOP() { __asm volatile ("nop"); } /* ------------------------------------------------------------------------------------------------------------------ */ /* QingKe RISCV */ /********************************************************************* * @fn NVIC_EnableIRQ * * @brief Enable Interrupt * * @param IRQn - Interrupt Numbers * * @return none */ OS_STATIC_FORCE_INLINE void QK_NVIC_EnableIRQ(uint32_t IRQn) { QK_NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); } /********************************************************************* * @fn NVIC_DisableIRQ * * @brief Disable Interrupt * * @param IRQn - Interrupt Numbers * * @return none */ OS_STATIC_FORCE_INLINE void QK_NVIC_DisableIRQ(uint32_t IRQn) { QK_NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); __asm volatile ("fence.i"); } /********************************************************************* * @fn NVIC_GetStatusIRQ * * @brief Get Interrupt Enable State * * @param IRQn - Interrupt Numbers * * @return 1 - Interrupt Enable * 0 - Interrupt Disable */ OS_STATIC_FORCE_INLINE uint32_t QK_NVIC_GetStatusIRQ(uint32_t IRQn) { return((uint32_t) ((QK_NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); } /********************************************************************* * @fn NVIC_GetPendingIRQ * * @brief Get Interrupt Pending State * * @param IRQn - Interrupt Numbers * * @return 1 - Interrupt Pending Enable * 0 - Interrupt Pending Disable */ OS_STATIC_FORCE_INLINE uint32_t QK_NVIC_GetPendingIRQ(uint32_t IRQn) { return((uint32_t) ((QK_NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); } /********************************************************************* * @fn NVIC_SetPendingIRQ * * @brief Set Interrupt Pending * * @param IRQn - Interrupt Numbers * * @return none */ OS_STATIC_FORCE_INLINE void QK_NVIC_SetPendingIRQ(uint32_t IRQn) { QK_NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); } /********************************************************************* * @fn NVIC_ClearPendingIRQ * * @brief Clear Interrupt Pending * * @param IRQn - Interrupt Numbers * * @return none */ OS_STATIC_FORCE_INLINE void QK_NVIC_ClearPendingIRQ(uint32_t IRQn) { QK_NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); } /********************************************************************* * @fn NVIC_GetActive * * @brief Get Interrupt Active State * * @param IRQn - Interrupt Numbers * * @return 1 - Interrupt Active * 0 - Interrupt No Active */ OS_STATIC_FORCE_INLINE uint32_t QK_NVIC_GetActive(uint32_t IRQn) { return((uint32_t)((QK_NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); } /********************************************************************* * @fn NVIC_SetPriority * * @brief Set Interrupt Priority * * @param IRQn - Interrupt Numbers * V5F: * interrupt nesting enable- 5~8 Level(CSR-0x804 bit1 = 1 bit[3:2] = 3) * priority - bit[7:5] - Preemption Priority * bit[4] - Sub priority * bit[3:0] - Reserve * interrupt nesting enable- 3~4 Level(CSR-0x804 bit1 = 1 bit[3:2] = 2) * priority - bit[7:6] - Preemption Priority * bit[5:4] - Sub priority * bit[3:0] - Reserve * interrupt nesting enable-2 Level(CSR-0x804 bit1 = 1 bit[3:2] = 1) * priority - bit[7] - Preemption Priority * bit[6:4] - Sub priority * bit[3:0] - Reserve * interrupt nesting disable(CSR-0x804 bit1 = 0) * priority - bit[7:4] - Sub priority * bit[3:0] - Reserve * V3F: * interrupt nesting enable-2 Level(CSR-0x804 bit1 = 1 bit[3:2] = 1) * priority - bit[7] - Preemption Priority * bit[6:4] - Sub priority * bit[3:0] - Reserve * interrupt nesting disable(CSR-0x804 bit1 = 0) * priority - bit[7:4] - Sub priority * bit[3:0] - Reserve * * @return none */ OS_STATIC_FORCE_INLINE void QK_NVIC_SetPriority(uint32_t IRQn, uint8_t priority) { QK_NVIC->IPRIOR[(uint32_t)(IRQn)] = priority; } /********************************************************************* * @fn NVIC_GetAllocateIRQ * * @brief Get Interrupt Allocate * * @param IRQn - Interrupt Numbers * * @return 1 - Allocate to V5F * 0 - Allocate to V3F */ OS_STATIC_FORCE_INLINE uint32_t QK_NVIC_GetAllocateIRQ(uint32_t IRQn) { return((uint32_t)((QK_NVIC->IALLOCR[(uint32_t)(IRQn)] & (1 << 0))?1:0)); } /********************************************************************* * @fn NVIC_SetAllocateIRQ * * @brief Set Interrupt Allocate * * @param IRQn - Interrupt Numbers ( >31 ) * Core_ID - Core ID * Core_ID_V5F - V5F * Core_ID_V3F - V3F * * @return none */ OS_STATIC_FORCE_INLINE void QK_NVIC_SetAllocateIRQ(uint32_t IRQn, uint8_t Core_ID) { if(IRQn > 31) QK_NVIC->IALLOCR[(uint32_t)(IRQn)] = Core_ID; } /********************************************************************* * @fn NVIC_OwnCoreGetAllocateIRQ * * @brief Own Core Get Interrupt Allocate * * @param IRQn - Interrupt Numbers * * @return 1 - Allocate to own core * 0 - No allocate to own core */ OS_STATIC_FORCE_INLINE uint32_t QK_NVIC_OwnCoreGetAllocateIRQ(uint32_t IRQn) { return((uint32_t) ((QK_NVIC->IAUTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); } /********************************************************************* * @fn __WFI * * @brief Wait for Interrupt * * @return none */ OS_STATIC_FORCE_INLINE void QK__WFI(void) { QK_NVIC->SCTLR &= ~(1<<3); // wfi asm volatile ("wfi"); } /********************************************************************* * @fn _SEV * * @brief Set Event * * @return none */ OS_STATIC_FORCE_INLINE void QK_SEV(void) { uint32_t t; t = QK_NVIC->SCTLR; QK_NVIC->SCTLR |= (1<<3)|(1<<5); QK_NVIC->SCTLR = (QK_NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5)); } /********************************************************************* * @fn __WFE_IDSET * * @brief Set Events ID * * @return none */ OS_STATIC_FORCE_INLINE void QK__WFE_IDSET(uint32_t LINE_ID) { QK_WFE_MASK |= LINE_ID; } /********************************************************************* * @fn __WFE * * @brief Wait for Events * * @return none */ OS_STATIC_FORCE_INLINE void QK__WFE(void) { __attribute__((unused)) uint32_t t=0; *(__IO uint32_t*)0x40010400 |= QK_WFE_MASK; WFE_WkupSource = 0; QK_NVIC->EPR = 0xFFFFFFFF; QK_NVIC->SCTLR |= (1<<3); asm volatile ("wfi"); for(;;) { t = *(__IO uint32_t*)0x40010414; if((t & QK_WFE_MASK) || (QK_WFE_MASK == 0)) { break; } else{ asm volatile ("wfi"); } } WFE_WkupSource = *(__IO uint32_t*)0x40010414; *(__IO uint32_t*)0x40010400 &= ~QK_WFE_MASK; *(__IO uint32_t*)0x40010414 |= QK_WFE_MASK; } /********************************************************************* * @fn SetVTFIRQ * * @brief Set VTF Interrupt * * @param addr - VTF interrupt service function base address. * IRQn -Interrupt Numbers * num - VTF Interrupt Numbers * NewState - DISABLE or ENABLE * * @return none */ OS_STATIC_FORCE_INLINE void QK_SetVTFIRQ(uint32_t addr, uint32_t IRQn, uint8_t num, QK_FunctionalState NewState) { if(num > 3) return ; if (NewState != QK_DISABLE) { QK_NVIC->VTFIDR[num] = IRQn; QK_NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1); } else { QK_NVIC->VTFIDR[num] = IRQn; QK_NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1)); } } /********************************************************************* * @fn NVIC_SystemReset * * @brief Initiate a system reset request * * @return none */ OS_STATIC_FORCE_INLINE void QK_NVIC_SystemReset(void) { QK_NVIC->CFGR = QK_NVIC_KEY3|(1<<7); } /********************************************************************* * @fn NVIC_WakeUp_V3F * * @brief Wake up V3F and set address for PC * * @param addr - V3F wake up address for PC(addr%1024 == 0). * * @return none */ OS_STATIC_FORCE_INLINE void QK_NVIC_WakeUp_V3F(uint32_t addr) { addr &= ~0x3FF; QK_NVIC->WAKEIP[0] = addr; QK_NVIC->SCTLR |= (1<<5); } /********************************************************************* * @fn NVIC_WakeUp_V5F * * @brief Wake up V5F and set address for PC * * @param addr - V5F wake up address for PC(addr%1024 == 0). * * @return none */ OS_STATIC_FORCE_INLINE void QK_NVIC_WakeUp_V5F(uint32_t addr) { addr &= ~0x3FF; QK_NVIC->WAKEIP[1] = addr; QK_NVIC->SCTLR |= (1<<5); } /********************************************************************* * @fn NVIC_GetCurrentCoreID * * @brief Get Current Core ID * * @return 1 - V5F * 0 - V3F */ OS_STATIC_FORCE_INLINE uint32_t QK_NVIC_GetCurrentCoreID(void) { return((uint32_t)(QK_NVIC->SCTLR & (1<<16))?1:0); } /********************************************************************* * @fn NVIC_EventWakeUPCmd * * @brief Enables or disables the event wake up. * * @param EVTn - Event Numbers ( <=31 ) * NewState - DISABLE or ENABLE * * @return none */ OS_STATIC_FORCE_INLINE void QK_NVIC_EventWakeUPCmd(uint32_t EVTn, QK_FunctionalState NewState) { if(EVTn > 31) return ; if (NewState != QK_DISABLE) { QK_NVIC->EENR |= 1 << EVTn; } else { QK_NVIC->EENR &= (~(1 << EVTn)); } } /********************************************************************* * @fn NVIC_ClearPendingWakeUpEvent * * @brief Clear wake up event pending * * @param EVTn - Event Numbers (from 8 to 31) * * @return none */ OS_STATIC_FORCE_INLINE void QK_NVIC_ClearPendingWakeUpEvent(uint32_t EVTn) { if((EVTn > 31) || (EVTn < 8)) return ; QK_NVIC->EPR = 1 << EVTn; } /********************************************************************* * @fn NVIC_GetPendingWakeUpEvent * * @brief Get wake up event pending * * @param IRQn - Event Numbers( <=31) * * @return 1 - Event pending * 0 - Event no pending */ OS_STATIC_FORCE_INLINE uint32_t QK_NVIC_GetPendingWakeUpEvent(uint32_t EVTn) { return((uint32_t)((QK_NVIC->EPR & (1 << EVTn))?1:0)); } /********************************************************************* * @fn NVIC_GetWakeUpEvent * * @brief Get wake up event * * @param IRQn - Interrupt Numbers( <=31) * * @return 1 - The event wake up core * 0 - The event do not wake up core */ OS_STATIC_FORCE_INLINE uint32_t QK_NVIC_GetWakeUpEvent(uint32_t EVTn) { return((uint32_t)((QK_NVIC->EWUPR & (1 << EVTn))?1:0)); } /********************************************************************* * @fn ASM_MCPY * * @brief Implement the assembly instruction function of mcpy, copy * the continuous data from the starting address of SrcAddrStart * to the ending address of SrcAddrEnd to the starting address * of DstAddrStart.(Only for V3F) * * @param SA - Copy the start address of the source region. * EA - Copy the end address of the source region. * DA - Copy the start address of the destination region. * * @return none */ static inline void QKV3F_ASM_MCPY(uint8_t* DA,uint8_t* SA,uint8_t* EA) { __asm__ volatile("mcpy %2, %0, %1" :"+r"(SA) , "+r"(DA):"r"(EA):"memory"); } /* ------------------------------------------------------------------------------------------------------------------ */ /* ATOMIC */ /********************************************************************* * @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; } /********************************************************************* * @fn __AMOMAXU_W * * @brief Atomic unsigned MAX with 32bit value * Atomically unsigned max compare 32bit value with value in memory using amomaxu.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 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; } /* ------------------------------------------------------------------------------------------------------------------ */ /* Core_Exported_Functions */ extern uint32_t RISCV_get_FFLAGS(void); extern void RISCV_set_FFLAGS(uint32_t value); extern uint32_t RISCV_get_FRM(void); extern void RISCV_set_FRM(uint32_t value); extern uint32_t RISCV_get_FCSR(void); extern void RISCV_set_FCSR(uint32_t value); 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); void RISCV_set_MCOUNT_INHIBIT(uint32_t value); uint32_t RISCV_get_MCOUNT_INHIBIT(void); void RISCV_set_MCYCLE(uint32_t value); uint32_t RISCV_get_MCYCLE(void); void RISCV_set_MINSTRET(uint32_t value); uint32_t RISCV_get_MINSTRET(void); void RISCV_set_UCYCLE(uint32_t value); uint32_t RISCV_get_UCYCLE(void); void RISCV_set_UINSTRET(uint32_t value); uint32_t RISCV_get_UINSTRET(void); /* ------------------------------------------------------------------------------------------------------------------ */ /* */ OS_STATIC_FORCE_INLINE uint32_t RISCV_get_set_MSTATUS(uint32_t value){ uint32_t result; __asm volatile ( "csrrw %0, mstatus, %1" : "=r" (result) : "r"(value) : "memory"); return (result); } /* ------------------------------------------------------------------------------------------------------------------ */ /* HSEM */ /* HSEM_ID_enumeration */ typedef enum { QK_HSEM_ID0 = 0, QK_HSEM_ID1, QK_HSEM_ID2, QK_HSEM_ID3, QK_HSEM_ID4, QK_HSEM_ID5, QK_HSEM_ID6, QK_HSEM_ID7, QK_HSEM_ID8, QK_HSEM_ID9, QK_HSEM_ID10, QK_HSEM_ID11, QK_HSEM_ID12, QK_HSEM_ID13, QK_HSEM_ID14, QK_HSEM_ID15, QK_HSEM_ID16, QK_HSEM_ID17, QK_HSEM_ID18, QK_HSEM_ID19, QK_HSEM_ID20, QK_HSEM_ID21, QK_HSEM_ID22, QK_HSEM_ID23, QK_HSEM_ID24, QK_HSEM_ID25, QK_HSEM_ID26, QK_HSEM_ID27, QK_HSEM_ID28, QK_HSEM_ID29, QK_HSEM_ID30, QK_HSEM_ID31 } QK_HSEM_ID_TypeDef; /* HSEM_Core_ID */ #define QK_HSEM_Core_ID_V3F ((uint32_t)0x00000000) #define QK_HSEM_Core_ID_V5F ((uint32_t)0x00000100) QK_ErrorStatus QK_HSEM_Take(QK_HSEM_ID_TypeDef HSEM_ID, uint32_t ProcessID); QK_ErrorStatus QK_HSEM_FastTake(QK_HSEM_ID_TypeDef HSEM_ID); QK_FunctionalState QK_HSEM_GetOneSemTakenState(QK_HSEM_ID_TypeDef HSEM_ID); uint32_t QK_HSEM_GetAllSemTakenState(void); uint32_t QK_HSEM_OwnCoreGetAllSemTakenState(void); void QK_HSEM_ReleaseOneSem(QK_HSEM_ID_TypeDef HSEM_ID, uint32_t ProcessID); void QK_HSEM_ReleaseAllSem(void); void QK_HSEM_ReleaseSem_MatchCID_PID(uint32_t CoreID, uint32_t ProcessID); void QK_HSEM_ReleaseSem_MatchCID(uint32_t CoreID); void QK_HSEM_ReleaseSem_MatchPID(uint32_t ProcessID); void QK_HSEM_SetClearKey(uint32_t Key); uint32_t QK_HSEM_GetClearKey(void); void QK_HSEM_ITConfig(QK_HSEM_ID_TypeDef HSEM_ID, QK_FunctionalState NewState); QK_FlagStatus QK_HSEM_GetFlagStatus(QK_HSEM_ID_TypeDef HSEM_ID); void QK_HSEM_ClearFlag(QK_HSEM_ID_TypeDef HSEM_ID); QK_ITStatus QK_HSEM_GetITStatus(QK_HSEM_ID_TypeDef HSEM_ID); void QK_HSEM_ClearITPendingBit(QK_HSEM_ID_TypeDef HSEM_ID); #endif /*INCLUDED_RISCV_H*/