Compare commits

..

13 Commits
eal6 ... master

24 changed files with 3705 additions and 173 deletions

View File

@ -0,0 +1,3 @@
SRC_FILES := core_riscv.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,527 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : core_riscv.c
* Author : WCH
* Version : V1.0.1
* Date : 2025/09/15
* Description : RISC-V V3F_V5F Core Peripheral Access Layer Source File for CH32H417_416_415
*********************************************************************************
* Copyright (c) 2025 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#include <stdint.h>
/* define compiler specific symbols */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#endif
volatile uint32_t WFE_MASK = 0;
/*********************************************************************
* @fn __get_FFLAGS
*
* @brief Return the Floating-Point Accrued Exceptions
*
* @return fflags value
*/
uint32_t __get_FFLAGS(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "fflags" : "=r" (result) );
return (result);
}
/*********************************************************************
* @fn __set_FFLAGS
*
* @brief Set the Floating-Point Accrued Exceptions
*
* @param value - set FFLAGS value
*
* @return none
*/
void __set_FFLAGS(uint32_t value)
{
__ASM volatile ("csrw fflags, %0" : : "r" (value) );
}
/*********************************************************************
* @fn __get_FRM
*
* @brief Return the Floating-Point Dynamic Rounding Mode
*
* @return frm value
*/
uint32_t __get_FRM(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "frm" : "=r" (result) );
return (result);
}
/*********************************************************************
* @fn __set_FRM
*
* @brief Set the Floating-Point Dynamic Rounding Mode
*
* @param value - set frm value
*
* @return none
*/
void __set_FRM(uint32_t value)
{
__ASM volatile ("csrw frm, %0" : : "r" (value) );
}
/*********************************************************************
* @fn __get_FCSR
*
* @brief Return the Floating-Point Control and Status Register
*
* @return fcsr value
*/
uint32_t __get_FCSR(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "fcsr" : "=r" (result) );
return (result);
}
/*********************************************************************
* @fn __set_FCSR
*
* @brief Set the Floating-Point Dynamic Rounding Mode
*
* @param value - set fcsr value
*
* @return none
*/
void __set_FCSR(uint32_t value)
{
__ASM volatile ("csrw fcsr, %0" : : "r" (value) );
}
/*********************************************************************
* @fn __get_MSTATUS
*
* @brief Return the Machine Status Register
*
* @return mstatus value
*/
uint32_t __get_MSTATUS(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mstatus" : "=r" (result) );
return (result);
}
/*********************************************************************
* @fn __set_MSTATUS
*
* @brief Set the Machine Status Register
*
* @param value - set mstatus value
*
* @return none
*/
void __set_MSTATUS(uint32_t value)
{
__ASM volatile ("csrw mstatus, %0" : : "r" (value) );
}
/*********************************************************************
* @fn __get_MISA
*
* @brief Return the Machine ISA Register
*
* @return misa value
*/
uint32_t __get_MISA(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "misa" : "=r" (result) );
return (result);
}
/*********************************************************************
* @fn __set_MISA
*
* @brief Set the Machine ISA Register
*
* @param value - set misa value
*
* @return none
*/
void __set_MISA(uint32_t value)
{
__ASM volatile ("csrw misa, %0" : : "r" (value) );
}
/*********************************************************************
* @fn __get_MTVEC
*
* @brief Return the Machine Trap-Vector Base-Address Register
*
* @return mtvec value
*/
uint32_t __get_MTVEC(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mtvec" : "=r" (result) );
return (result);
}
/*********************************************************************
* @fn __set_MTVEC
*
* @brief Set the Machine Trap-Vector Base-Address Register
*
* @param value - set mtvec value
*
* @return none
*/
void __set_MTVEC(uint32_t value)
{
__ASM volatile ("csrw mtvec, %0" : : "r" (value) );
}
/*********************************************************************
* @fn __get_MSCRATCH
*
* @brief Return the Machine Seratch Register
*
* @return mscratch value
*/
uint32_t __get_MSCRATCH(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mscratch" : "=r" (result) );
return (result);
}
/*********************************************************************
* @fn __set_MSCRATCH
*
* @brief Set the Machine Seratch Register
*
* @param value - set mscratch value
*
* @return none
*/
void __set_MSCRATCH(uint32_t value)
{
__ASM volatile ("csrw mscratch, %0" : : "r" (value) );
}
/*********************************************************************
* @fn __get_MEPC
*
* @brief Return the Machine Exception Program Register
*
* @return mepc value
*/
uint32_t __get_MEPC(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mepc" : "=r" (result) );
return (result);
}
/*********************************************************************
* @fn __set_MEPC
*
* @brief Set the Machine Exception Program Register
*
* @return mepc value
*/
void __set_MEPC(uint32_t value)
{
__ASM volatile ("csrw mepc, %0" : : "r" (value) );
}
/*********************************************************************
* @fn __get_MCAUSE
*
* @brief Return the Machine Cause Register
*
* @return mcause value
*/
uint32_t __get_MCAUSE(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mcause" : "=r" (result) );
return (result);
}
/*********************************************************************
* @fn __set_MEPC
*
* @brief Set the Machine Cause Register
*
* @return mcause value
*/
void __set_MCAUSE(uint32_t value)
{
__ASM volatile ("csrw mcause, %0" : : "r" (value) );
}
/*********************************************************************
* @fn __get_MTVAL
*
* @brief Return the Machine Trap Value Register
*
* @return mtval value
*/
uint32_t __get_MTVAL(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mtval" : "=r" (result) );
return (result);
}
/*********************************************************************
* @fn __set_MTVAL
*
* @brief Set the Machine Trap Value Register
*
* @return mtval value
*/
void __set_MTVAL(uint32_t value)
{
__ASM volatile ("csrw mtval, %0" : : "r" (value) );
}
/*********************************************************************
* @fn __get_MVENDORID
*
* @brief Return Vendor ID Register
*
* @return mvendorid value
*/
uint32_t __get_MVENDORID(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mvendorid" : "=r" (result) );
return (result);
}
/*********************************************************************
* @fn __get_MARCHID
*
* @brief Return Machine Architecture ID Register
*
* @return marchid value
*/
uint32_t __get_MARCHID(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "marchid" : "=r" (result) );
return (result);
}
/*********************************************************************
* @fn __get_MIMPID
*
* @brief Return Machine Implementation ID Register
*
* @return mimpid value
*/
uint32_t __get_MIMPID(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mimpid" : "=r" (result) );
return (result);
}
/*********************************************************************
* @fn __get_MHARTID
*
* @brief Return Hart ID Register
*
* @return mhartid value
*/
uint32_t __get_MHARTID(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mhartid" : "=r" (result) );
return (result);
}
/*********************************************************************
* @fn __get_SP
*
* @brief Return SP Register
*
* @return SP value
*/
uint32_t __get_SP(void)
{
uint32_t result;
__ASM volatile ( "mv %0," "sp" : "=r"(result) : );
return (result);
}
/*********************************************************************
* @fn __set_MCOUNT_INHIBIT
*
* @brief Set Instruction and cycle count shield switch in machine mode
*
* @return mcause value
*/
void __set_MCOUNT_INHIBIT(uint32_t value)
{
__ASM volatile ("csrw mucounteren, %0" : : "r" (value) );
}
/*********************************************************************
* @fn __get_MCOUNT_INHIBIT
*
* @brief Return Instruction and cycle count shield switch in machine mode
*
* @return SP value
*/
uint32_t __get_MCOUNT_INHIBIT(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mucounteren" : "=r"(result) : );
return (result);
}
/*********************************************************************
* @fn __set_MCYCLE
*
* @brief Set the number of cycles in machine mode
*
* @return mcause value
*/
void __set_MCYCLE(uint32_t value)
{
__ASM volatile ("csrw mcycle, %0" : : "r" (value) );
}
/*********************************************************************
* @fn __get_MCYCLE
*
* @brief Return the number of cycles in machine mode
*
* @return SP value
*/
uint32_t __get_MCYCLE(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mcycle" : "=r"(result) : );
return (result);
}
/*********************************************************************
* @fn __set_MINSTRET
*
* @brief Set the number of completed instructions in machine mode
*
* @return mcause value
*/
void __set_MINSTRET(uint32_t value)
{
__ASM volatile ("csrw minstret, %0" : : "r" (value) );
}
/*********************************************************************
* @fn __get_MINSTRET
*
* @brief Return the number of completed instructions in machine mode
*
* @return SP value
*/
uint32_t __get_MINSTRET(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "minstret" : "=r"(result) : );
return (result);
}
/*********************************************************************
* @fn __set_UCYCLE
*
* @brief Set the number of cycles in user mode
*
* @return mcause value
*/
void __set_UCYCLE(uint32_t value)
{
__ASM volatile ("csrw cycle, %0" : : "r" (value) );
}
/*********************************************************************
* @fn __get_UCYCLE
*
* @brief Return the number of cycles in user mode
*
* @return SP value
*/
uint32_t __get_UCYCLE(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "cycle" : "=r"(result) : );
return (result);
}
/*********************************************************************
* @fn __set_UINSTRET
*
* @brief Set the number of completed instructions in user mode
*
* @return mcause value
*/
void __set_UINSTRET(uint32_t value)
{
__ASM volatile ("csrw instret, %0" : : "r" (value) );
}
/*********************************************************************
* @fn __get_UINSTRET
*
* @brief Return the number of completed instructions in user mode
*
* @return SP value
*/
uint32_t __get_UINSTRET(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "instret" : "=r"(result) : );
return (result);
}

View File

@ -0,0 +1,871 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : core_riscv.h
* Author : WCH
* Version : V1.0.1
* Date : 2025/09/15
* Description : RISC-V V3F_V5F Core Peripheral Access Layer Header File for CH32H417_416_415
*********************************************************************************
* Copyright (c) 2025 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef __CORE_RISCV_H__
#define __CORE_RISCV_H__
#ifdef __cplusplus
extern "C" {
#endif
/* 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 */
/* Standard Peripheral Library old types (maintained for legacy purpose) */
typedef __I uint64_t vuc64; /* Read Only */
typedef __I uint32_t vuc32; /* Read Only */
typedef __I uint16_t vuc16; /* Read Only */
typedef __I uint8_t vuc8; /* Read Only */
typedef const uint64_t uc64; /* Read Only */
typedef const uint32_t uc32; /* Read Only */
typedef const uint16_t uc16; /* Read Only */
typedef const uint8_t uc8; /* Read Only */
typedef __I int64_t vsc64; /* Read Only */
typedef __I int32_t vsc32; /* Read Only */
typedef __I int16_t vsc16; /* Read Only */
typedef __I int8_t vsc8; /* Read Only */
typedef const int64_t sc64; /* Read Only */
typedef const int32_t sc32; /* Read Only */
typedef const int16_t sc16; /* Read Only */
typedef const int8_t sc8; /* Read Only */
typedef __IO uint64_t vu64;
typedef __IO uint32_t vu32;
typedef __IO uint16_t vu16;
typedef __IO uint8_t vu8;
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef __IO int64_t vs64;
typedef __IO int32_t vs32;
typedef __IO int16_t vs16;
typedef __IO int8_t vs8;
typedef int64_t s64;
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
typedef enum {NoREADY = 0, READY = !NoREADY} ErrorStatus;
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
#define RV_STATIC_INLINE static inline
/* 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;
}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];
}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;
}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;
}SysTick_Type;
#define HSEM ((HSEM_Type *) 0xE000C000 )
#define IPC ((IPC_Type *) 0xE000D000 )
#define PFIC ((PFIC_Type *) 0xE000E000 )
#define NVIC PFIC
#define NVIC_KEY3 ((uint32_t)0xBEEF0000)
#define SysTick0 ((SysTick_Type *) 0xE000F000)
#define SysTick1 ((SysTick_Type *) 0xE000F080)
/* Core_ID */
#define Core_ID_V3F ((uint8_t)0x00)
#define Core_ID_V5F ((uint8_t)0x01)
extern volatile uint32_t WFE_MASK;
extern volatile uint32_t WFE_WkupSource;
/*********************************************************************
* @fn __enable_irq
*
* @brief Enable Global Interrupt
*
* @return none
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __enable_irq()
{
__asm volatile ("csrs 0x800, %0" : : "r" (0x88) );
}
/*********************************************************************
* @fn __disable_irq
*
* @brief Disable Global Interrupt
*
* @return none
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __disable_irq()
{
__asm volatile ("csrc 0x800, %0" : : "r" (0x88) );
__asm volatile ("fence.i");
}
/*********************************************************************
* @fn __NOP
*
* @brief nop
*
* @return none
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __NOP()
{
__asm volatile ("nop");
}
/*********************************************************************
* @fn NVIC_EnableIRQ
*
* @brief Enable Interrupt
*
* @param IRQn - Interrupt Numbers
*
* @return none
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/*********************************************************************
* @fn NVIC_DisableIRQ
*
* @brief Disable Interrupt
*
* @param IRQn - Interrupt Numbers
*
* @return none
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetStatusIRQ(IRQn_Type IRQn)
{
return((uint32_t) ((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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t) ((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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/*********************************************************************
* @fn NVIC_ClearPendingIRQ
*
* @brief Clear Interrupt Pending
*
* @param IRQn - Interrupt Numbers
*
* @return none
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
{
return((uint32_t)((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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority)
{
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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetAllocateIRQ(IRQn_Type IRQn)
{
return((uint32_t)((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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetAllocateIRQ(IRQn_Type IRQn, uint8_t Core_ID)
{
if(IRQn > 31) return ;
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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_OwnCoreGetAllocateIRQ(IRQn_Type IRQn)
{
return((uint32_t) ((NVIC->IAUTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
/*********************************************************************
* @fn __WFI
*
* @brief Wait for Interrupt
*
* @return none
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void)
{
NVIC->SCTLR &= ~(1<<3); // wfi
asm volatile ("wfi");
}
/*********************************************************************
* @fn _SEV
*
* @brief Set Event
*
* @return none
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _SEV(void)
{
uint32_t t;
t = NVIC->SCTLR;
NVIC->SCTLR |= (1<<3)|(1<<5);
NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5));
}
/*********************************************************************
* @fn __WFE_IDSET
*
* @brief Set Events ID
*
* @return none
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE_IDSET(uint32_t LINE_ID)
{
WFE_MASK |= LINE_ID;
}
/*********************************************************************
* @fn __WFE
*
* @brief Wait for Events
*
* @return none
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void)
{
__attribute__((unused)) uint32_t t=0;
*(__IO uint32_t*)0x40010400 |= WFE_MASK;
WFE_WkupSource = 0;
NVIC->EPR = 0xFFFFFFFF;
NVIC->SCTLR |= (1<<3);
asm volatile ("wfi");
for(;;)
{
t = *(__IO uint32_t*)0x40010414;
if((t & WFE_MASK) || (WFE_MASK == 0))
{
break;
} else{
asm volatile ("wfi");
}
}
WFE_WkupSource = *(__IO uint32_t*)0x40010414;
*(__IO uint32_t*)0x40010400 &= ~WFE_MASK;
*(__IO uint32_t*)0x40010414 |= 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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState)
{
if(num > 3) return ;
if (NewState != DISABLE)
{
NVIC->VTFIDR[num] = IRQn;
NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1);
}
else
{
NVIC->VTFIDR[num] = IRQn;
NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1));
}
}
/*********************************************************************
* @fn NVIC_SystemReset
*
* @brief Initiate a system reset request
*
* @return none
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SystemReset(void)
{
NVIC->CFGR = 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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_WakeUp_V3F(uint32_t addr)
{
addr &= ~0x3FF;
NVIC->WAKEIP[0] = addr;
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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_WakeUp_V5F(uint32_t addr)
{
addr &= ~0x3FF;
NVIC->WAKEIP[1] = addr;
NVIC->SCTLR |= (1<<5);
}
/*********************************************************************
* @fn NVIC_GetCurrentCoreID
*
* @brief Get Current Core ID
*
* @return 1 - V5F
* 0 - V3F
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetCurrentCoreID(void)
{
return((uint32_t)(NVIC->SCTLR & (1<<16))?1:0);
}
/*********************************************************************
* @fn NVIC_EventWakeUPCmd
*
* @brief Enables or disables the event wake up.
*
* @param IRQn -Interrupt Numbers ( <=31 )
* NewState - DISABLE or ENABLE
*
* @return none
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_EventWakeUPCmd(IRQn_Type IRQn, FunctionalState NewState)
{
if(IRQn > 31) return ;
if (NewState != DISABLE)
{
NVIC->EENR |= IRQn;
}
else
{
NVIC->EENR &= (~IRQn);
}
}
/*********************************************************************
* @fn NVIC_ClearPendingWakeuUpEvent
*
* @brief Clear wake up event pending
*
* @param IRQn - Interrupt Numbers (from 8 to 31)
*
* @return none
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_ClearPendingWakeuUpEvent(IRQn_Type IRQn)
{
if((IRQn > 31) && (IRQn < 8)) return ;
NVIC->EPR = IRQn;
}
/*********************************************************************
* @fn NVIC_GetPendingWakeuUpEvent
*
* @brief Get wake up event pending
*
* @param IRQn - Interrupt Numbers( <=31)
*
* @return 1 - Event pending
* 0 - Event no pending
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetPendingWakeuUpEvent(IRQn_Type IRQn)
{
return((uint32_t)((NVIC->EPR & (1 << IRQn))?1:0));
}
/*********************************************************************
* @fn NVIC_GetWakeuUpEvent
*
* @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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetWakeuUpEvent(IRQn_Type IRQn)
{
return((uint32_t)((NVIC->EWUPR & (1 << IRQn))?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 ASM_MCPY(uint8_t* DA,uint8_t* SA,uint8_t* EA)
{
__asm__ volatile("mcpy %2, %0, %1" :"+r"(SA) , "+r"(DA):"r"(EA):"memory");
}
/*********************************************************************
* @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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __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
*/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __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 __get_FFLAGS(void);
extern void __set_FFLAGS(uint32_t value);
extern uint32_t __get_FRM(void);
extern void __set_FRM(uint32_t value);
extern uint32_t __get_FCSR(void);
extern void __set_FCSR(uint32_t value);
extern uint32_t __get_MSTATUS(void);
extern void __set_MSTATUS(uint32_t value);
extern uint32_t __get_MISA(void);
extern void __set_MISA(uint32_t value);
extern uint32_t __get_MTVEC(void);
extern void __set_MTVEC(uint32_t value);
extern uint32_t __get_MSCRATCH(void);
extern void __set_MSCRATCH(uint32_t value);
extern uint32_t __get_MEPC(void);
extern void __set_MEPC(uint32_t value);
extern uint32_t __get_MCAUSE(void);
extern void __set_MCAUSE(uint32_t value);
extern uint32_t __get_MTVAL(void);
extern void __set_MTVAL(uint32_t value);
extern uint32_t __get_MVENDORID(void);
extern uint32_t __get_MARCHID(void);
extern uint32_t __get_MIMPID(void);
extern uint32_t __get_MHARTID(void);
extern uint32_t __get_SP(void);
void __set_MCOUNT_INHIBIT(uint32_t value);
uint32_t __get_MCOUNT_INHIBIT(void);
void __set_MCYCLE(uint32_t value);
uint32_t __get_MCYCLE(void);
void __set_MINSTRET(uint32_t value);
uint32_t __get_MINSTRET(void);
void __set_UCYCLE(uint32_t value);
uint32_t __get_UCYCLE(void);
void __set_UINSTRET(uint32_t value);
uint32_t __get_UINSTRET(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,3 @@
SRC_FILES := debug.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,229 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : debug.c
* Author : WCH
* Version : V1.0.1
* Date : 2025/07/16
* Description : This file contains all the functions prototypes for UART
* Printf , Delay functions.
*********************************************************************************
* Copyright (c) 2025 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#include "debug.h"
static uint16_t p_us = 0;
static uint32_t p_ms = 0;
/*********************************************************************
* @fn Delay_Init
*
* @brief Initializes Delay Funcation.
*
* @return none
*/
void Delay_Init(void)
{
p_us = HCLKClock / 1000000;
p_ms = (uint16_t)p_us * 1000;
}
/*********************************************************************
* @fn Delay_Us
*
* @brief Microsecond Delay Time.
*
* @param n - Microsecond number.
*
* @return none
*/
void Delay_Us(uint32_t n)
{
uint32_t i;
#ifdef Core_V3F
SysTick0->ISR &= ~(1 << 0);
i = (uint32_t)n * p_us;
SysTick0->CNT = 0;
SysTick0->CMP = i;
SysTick0->CTLR = (1 << 2);
SysTick0->CTLR |= (1 << 0);
while((SysTick0->ISR & (1 << 0)) != (1 << 0))
;
SysTick0->CTLR &= ~(1 << 0);
#elif defined(Core_V5F)
SysTick0->ISR &= ~(1 << 1);
i = (uint32_t)n * p_us;
SysTick1->CNT = 0;
SysTick1->CMP = i;
SysTick1->CTLR = (1 << 2);
SysTick1->CTLR |= (1 << 0);
while((SysTick0->ISR & (1 << 1)) != (1 << 1))
;
SysTick1->CTLR &= ~(1 << 0);
#endif
}
/*********************************************************************
* @fn Delay_Ms
*
* @brief Millisecond Delay Time.
*
* @param n - Millisecond number.
*
* @return none
*/
void Delay_Ms(uint32_t n)
{
uint32_t i;
#ifdef Core_V3F
SysTick0->ISR &= ~(1 << 0);
i = (uint32_t)n * p_ms;
SysTick0->CNT = 0;
SysTick0->CMP = i;
SysTick0->CTLR = (1 << 2);
SysTick0->CTLR |= (1 << 0);
while((SysTick0->ISR & (1 << 0)) != (1 << 0))
;
SysTick0->CTLR &= ~(1 << 0);
#elif defined(Core_V5F)
SysTick0->ISR &= ~(1 << 1);
i = (uint32_t)n * p_ms;
SysTick1->CNT = 0;
SysTick1->CMP = i;
SysTick1->CTLR = (1 << 2);
SysTick1->CTLR |= (1 << 0);
while((SysTick0->ISR & (1 << 1)) != (1 << 1))
;
SysTick1->CTLR &= ~(1 << 0);
#endif
}
/*********************************************************************
* @fn USART_Printf_Init
*
* @brief Initializes the USARTx peripheral.
*
* @param baudrate - USART communication baud rate.
*
* @return none
*/
void USART_Printf_Init(uint32_t baudrate)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
USART_InitTypeDef USART_InitStructure = {0};
#if(DEBUG == DEBUG_UART1)
RCC_HB2PeriphClockCmd(RCC_HB2Periph_AFIO | RCC_HB2Periph_USART1 | RCC_HB2Periph_GPIOA, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF7);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Very_High;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
#elif(DEBUG == DEBUG_UART8)
RCC_HB2PeriphClockCmd(RCC_HB2Periph_AFIO | RCC_HB2Periph_GPIOB, ENABLE);
RCC_HB1PeriphClockCmd(RCC_HB1Periph_USART8, ENABLE);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF11);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Very_High;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
#elif(DEBUG == DEBUG_UART6)
RCC_HB2PeriphClockCmd(RCC_HB2Periph_AFIO | RCC_HB2Periph_GPIOB, ENABLE);
RCC_HB1PeriphClockCmd(RCC_HB1Periph_USART6, ENABLE);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF8);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Very_High;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
#endif
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
#if(DEBUG == DEBUG_UART1)
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
#elif(DEBUG == DEBUG_UART8)
USART_Init(USART8, &USART_InitStructure);
USART_Cmd(USART8, ENABLE);
#elif(DEBUG == DEBUG_UART6)
USART_Init(USART6, &USART_InitStructure);
USART_Cmd(USART6, ENABLE);
#endif
}
/*********************************************************************
* @fn _write
*
* @brief Support Printf Function
*
* @param *buf - UART send Data.
* size - Data length
*
* @return size: Data length
*/
__attribute__((used)) int _write(int fd, char *buf, int size)
{
int i = 0;
for(i = 0; i < size; i++)
{
#if(DEBUG == DEBUG_UART1)
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
USART_SendData(USART1, *buf++);
#elif(DEBUG == DEBUG_UART8)
while(USART_GetFlagStatus(USART8, USART_FLAG_TC) == RESET);
USART_SendData(USART8, *buf++);
#elif(DEBUG == DEBUG_UART6)
while(USART_GetFlagStatus(USART6, USART_FLAG_TC) == RESET);
USART_SendData(USART6, *buf++);
#endif
}
return size;
}
/*********************************************************************
* @fn _sbrk
*
* @brief Change the spatial position of data segment.
*
* @return size: Data length
*/
__attribute__((used)) void *_sbrk(ptrdiff_t incr)
{
extern char _end[];
extern char _heap_end[];
static char *curbrk = _end;
if ((curbrk + incr < _end) || (curbrk + incr > _heap_end))
return NULL - 1;
curbrk += incr;
return curbrk - incr;
}

View File

@ -0,0 +1,75 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : debug.h
* Author : WCH
* Version : V1.0.1
* Date : 2025/09/16
* Description : This file contains all the functions prototypes for UART
* Printf , Delay functions.
*********************************************************************************
* Copyright (c) 2025 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef __DEBUG_H
#define __DEBUG_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stdio.h"
#include "ch32h417.h"
/* UART Printf Definition */
#define DEBUG_UART1 1
#define DEBUG_UART8 2
#define DEBUG_UART6 3
/* DEBUG UATR Definition */
#ifndef DEBUG
#ifdef Core_V3F
#define DEBUG DEBUG_UART1
#elif defined(Core_V5F)
#define DEBUG DEBUG_UART8
#endif
#endif
/* Run Core Definition */
#define Run_Core_V3F 0
#define Run_Core_V5F 1
#define Run_Core_V3FandV5F 2
#ifndef Run_Core
#define Run_Core Run_Core_V3FandV5F
// #define Run_Core Run_Core_V5F
// #define Run_Core Run_Core_V3F
#endif
/* Core start addrress Definition */
#ifndef Core_V3F_StartAddr
#define Core_V3F_StartAddr 0x00000000
#endif
#ifndef Core_V5F_StartAddr
#define Core_V5F_StartAddr 0x00040000
#endif
extern volatile uint32_t WFE_WkupSource;
void Delay_Init(void);
void Delay_Us (uint32_t n);
void Delay_Ms (uint32_t n);
void USART_Printf_Init(uint32_t baudrate);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,10 @@
ifeq ($(CONFIG_RISC_V3F),y)
SRC_FILES := boot_v3f.S
endif
ifeq ($(CONFIG_RISC_V5F),y)
SRC_FILES := boot_v5f.S
endif
SRC_FILES += interrupt.c tick.c switch.S prepare_rhwstack.c interrupt_switch.S
SRC_DIR := Core Debug
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,13 @@
#ifndef ARCH_INTERRUPT_H__
#define ARCH_INTERRUPT_H__
#include "ch32h417_it.h"
#include "core_riscv.h"
#define ARCH_MAX_IRQ_NUM 256
#define ARCH_IRQ_NUM_OFFSET 0
int ArchEnableHwIrq(uint32_t irq_num);
int ArchDisableHwIrq(uint32_t irq_num);
#endif

View File

@ -0,0 +1,560 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : startup_ch32h417_v3f.s
* Author : WCH
* Version : V1.0.2
* Date : 2025/10/21
* Description : CH32h417_416_415 V3F StartUp File.
*********************************************************************************
* Copyright (c) 2025 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
.section .init,"ax",@progbits
.global _start
.align 2
_start:
j handle_reset
.section .vector,"ax",@progbits
.align 1
_vector_base:
.option norvc;
.word _start
.word 0
.word NMI_Handler
.word HardFault_Handler
.word 0
.word Ecall_M_Mode_Handler
.word 0
.word 0
.word Ecall_U_Mode_Handler
.word Break_Point_Handler
.word 0
.word 0
.word SysTick0_Handler
.word SysTick1_Handler
.word SW_Handler
.word 0
.word IPC_CH0_Handler
.word IPC_CH1_Handler
.word IPC_CH2_Handler
.word IPC_CH3_Handler
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word HSEM_Handler
.word 0
.word 0
.word 0
/* External Interrupts */
.word WWDG_IRQHandler
.word EXTI15_8_IRQHandler
.word FLASH_IRQHandler
.word RCC_IRQHandler
.word EXTI7_0_IRQHandler
.word SPI1_IRQHandler
.word DMA1_Channel2_IRQHandler
.word DMA1_Channel3_IRQHandler
.word DMA1_Channel4_IRQHandler
.word DMA1_Channel5_IRQHandler
.word DMA1_Channel6_IRQHandler
.word DMA1_Channel7_IRQHandler
.word DMA1_Channel8_IRQHandler
.word USART2_IRQHandler
.word I2C1_EV_IRQHandler
.word I2C1_ER_IRQHandler
.word USART1_IRQHandler
.word SPI2_IRQHandler
.word SPI3_IRQHandler
.word SPI4_IRQHandler
.word I2C2_EV_IRQHandler
.word I2C2_ER_IRQHandler
.word USBPD_IRQHandler
.word USBPDWakeUp_IRQHandler
.word USBHS_IRQHandler
.word DMA1_Channel1_IRQHandler
.word CAN1_SCE_IRQHandler
.word CAN1_TX_IRQHandler
.word CAN1_RX0_IRQHandler
.word CAN1_RX1_IRQHandler
.word USBSS_IRQHandler
.word USBSS_LINK_IRQHandler
.word USBHSWakeup_IRQHandler
.word USBSSWakeup_IRQHandler
.word RTCAlarm_IRQHandler
.word USBFS_IRQHandler
.word USBFSWakeup_IRQHandler
.word ADC1_2_IRQHandler
.word TIM1_BRK_IRQHandler
.word TIM1_UP_IRQHandler
.word TIM1_TRG_COM_IRQHandler
.word TIM1_CC_IRQHandler
.word TIM2_IRQHandler
.word TIM3_IRQHandler
.word TIM4_IRQHandler
.word TIM5_IRQHandler
.word I2C3_EV_IRQHandler
.word I2C3_ER_IRQHandler
.word I2C4_EV_IRQHandler
.word I2C4_ER_IRQHandler
.word QSPI1_IRQHandler
.word SERDES_IRQHandler
.word USART3_IRQHandler
.word USART4_IRQHandler
.word TIM8_BRK_IRQHandler
.word TIM8_UP_IRQHandler
.word TIM8_TRG_COM_IRQHandler
.word TIM8_CC_IRQHandler
.word TIM9_IRQHandler
.word TIM10_IRQHandler
.word TIM11_IRQHandler
.word TIM12_IRQHandler
.word FMC_IRQHandler
.word SDMMC_IRQHandler
.word LPTIM1_IRQHandler
.word LPTIM2_IRQHandler
.word USART5_IRQHandler
.word USART6_IRQHandler
.word TIM6_IRQHandler
.word TIM7_IRQHandler
.word DMA2_Channel1_IRQHandler
.word DMA2_Channel2_IRQHandler
.word DMA2_Channel3_IRQHandler
.word DMA2_Channel4_IRQHandler
.word DMA2_Channel5_IRQHandler
.word DMA2_Channel6_IRQHandler
.word DMA2_Channel7_IRQHandler
.word DMA2_Channel8_IRQHandler
.word ETH_IRQHandler
.word ETH_WKUP_IRQHandler
.word CAN2_SCE_IRQHandler
.word CAN2_TX_IRQHandler
.word CAN2_RX0_IRQHandler
.word CAN2_RX1_IRQHandler
.word USART7_IRQHandler
.word USART8_IRQHandler
.word I3C_EV_IRQHandler
.word I3C_ER_IRQHandler
.word DVP_IRQHandler
.word ECDC_IRQHandler
.word PIOC_IRQHandler
.word SAI_IRQHandler
.word LTDC_IRQHandler
.word GPHA_IRQHandler
.word 0
.word DFSDM0_IRQHandler
.word DFSDM1_IRQHandler
.word 0
.word 0
.word SWPMI_IRQHandler
.word 0
.word 0
.word QSPI2_IRQHandler
.word SWPMI_WKUP_IRQHandler
.word CAN3_SCE_IRQHandler
.word CAN3_TX_IRQHandler
.word CAN3_RX0_IRQHandler
.word CAN3_RX1_IRQHandler
.word LPTIM2_WKUP_IRQHandler
.word LPTIM1_WKUP_IRQHandler
.word I3C_WKUP_IRQHandler
.word RTC_IRQHandler
.word HSADC_IRQHandler
.word UHSIF_IRQHandler
.word RNG_IRQHandler
.word SDIO_IRQHandler
.word USART_WKUP_IRQHandler
.option rvc;
.section .text.vector_handler, "ax", @progbits
.weak NMI_Handler
.weak HardFault_Handler
.weak Ecall_M_Mode_Handler
.weak Ecall_U_Mode_Handler
.weak Break_Point_Handler
.weak SysTick0_Handler
.weak SysTick1_Handler
.weak SW_Handler
.weak IPC_CH0_Handler
.weak IPC_CH1_Handler
.weak IPC_CH2_Handler
.weak IPC_CH3_Handler
.weak HSEM_Handler
.weak WWDG_IRQHandler
.weak EXTI15_8_IRQHandler
.weak FLASH_IRQHandler
.weak RCC_IRQHandler
.weak EXTI7_0_IRQHandler
.weak SPI1_IRQHandler
.weak DMA1_Channel2_IRQHandler
.weak DMA1_Channel3_IRQHandler
.weak DMA1_Channel4_IRQHandler
.weak DMA1_Channel5_IRQHandler
.weak DMA1_Channel6_IRQHandler
.weak DMA1_Channel7_IRQHandler
.weak DMA1_Channel8_IRQHandler
.weak USART2_IRQHandler
.weak I2C1_EV_IRQHandler
.weak I2C1_ER_IRQHandler
.weak USART1_IRQHandler
.weak SPI2_IRQHandler
.weak SPI3_IRQHandler
.weak SPI4_IRQHandler
.weak I2C2_EV_IRQHandler
.weak I2C2_ER_IRQHandler
.weak USBPD_IRQHandler
.weak USBPDWakeUp_IRQHandler
.weak USBHS_IRQHandler
.weak DMA1_Channel1_IRQHandler
.weak CAN1_SCE_IRQHandler
.weak CAN1_TX_IRQHandler
.weak CAN1_RX0_IRQHandler
.weak CAN1_RX1_IRQHandler
.weak USBSS_IRQHandler
.weak USBSS_LINK_IRQHandler
.weak USBHSWakeup_IRQHandler
.weak USBSSWakeup_IRQHandler
.weak RTCAlarm_IRQHandler
.weak USBFS_IRQHandler
.weak USBFSWakeup_IRQHandler
.weak ADC1_2_IRQHandler
.weak TIM1_BRK_IRQHandler
.weak TIM1_UP_IRQHandler
.weak TIM1_TRG_COM_IRQHandler
.weak TIM1_CC_IRQHandler
.weak TIM2_IRQHandler
.weak TIM3_IRQHandler
.weak TIM4_IRQHandler
.weak TIM5_IRQHandler
.weak I2C3_EV_IRQHandler
.weak I2C3_ER_IRQHandler
.weak I2C4_EV_IRQHandler
.weak I2C4_ER_IRQHandler
.weak QSPI1_IRQHandler
.weak SERDES_IRQHandler
.weak USART3_IRQHandler
.weak USART4_IRQHandler
.weak TIM8_BRK_IRQHandler
.weak TIM8_UP_IRQHandler
.weak TIM8_TRG_COM_IRQHandler
.weak TIM8_CC_IRQHandler
.weak TIM9_IRQHandler
.weak TIM10_IRQHandler
.weak TIM11_IRQHandler
.weak TIM12_IRQHandler
.weak FMC_IRQHandler
.weak SDMMC_IRQHandler
.weak LPTIM1_IRQHandler
.weak LPTIM2_IRQHandler
.weak USART5_IRQHandler
.weak USART6_IRQHandler
.weak TIM6_IRQHandler
.weak TIM7_IRQHandler
.weak DMA2_Channel1_IRQHandler
.weak DMA2_Channel2_IRQHandler
.weak DMA2_Channel3_IRQHandler
.weak DMA2_Channel4_IRQHandler
.weak DMA2_Channel5_IRQHandler
.weak DMA2_Channel6_IRQHandler
.weak DMA2_Channel7_IRQHandler
.weak DMA2_Channel8_IRQHandler
.weak ETH_IRQHandler
.weak ETH_WKUP_IRQHandler
.weak CAN2_SCE_IRQHandler
.weak CAN2_TX_IRQHandler
.weak CAN2_RX0_IRQHandler
.weak CAN2_RX1_IRQHandler
.weak USART7_IRQHandler
.weak USART8_IRQHandler
.weak I3C_EV_IRQHandler
.weak I3C_ER_IRQHandler
.weak DVP_IRQHandler
.weak ECDC_IRQHandler
.weak PIOC_IRQHandler
.weak SAI_IRQHandler
.weak LTDC_IRQHandler
.weak GPHA_IRQHandler
.weak DFSDM0_IRQHandler
.weak DFSDM1_IRQHandler
.weak SWPMI_IRQHandler
.weak QSPI2_IRQHandler
.weak SWPMI_WKUP_IRQHandler
.weak CAN3_SCE_IRQHandler
.weak CAN3_TX_IRQHandler
.weak CAN3_RX0_IRQHandler
.weak CAN3_RX1_IRQHandler
.weak LPTIM2_WKUP_IRQHandler
.weak LPTIM1_WKUP_IRQHandler
.weak I3C_WKUP_IRQHandler
.weak RTC_IRQHandler
.weak HSADC_IRQHandler
.weak UHSIF_IRQHandler
.weak RNG_IRQHandler
.weak SDIO_IRQHandler
.weak USART_WKUP_IRQHandler
NMI_Handler:
HardFault_Handler:
Ecall_M_Mode_Handler:
Ecall_U_Mode_Handler:
Break_Point_Handler:
SysTick0_Handler:
SysTick1_Handler:
SW_Handler:
IPC_CH0_Handler:
IPC_CH1_Handler:
IPC_CH2_Handler:
IPC_CH3_Handler:
HSEM_Handler:
WWDG_IRQHandler:
EXTI15_8_IRQHandler:
FLASH_IRQHandler:
RCC_IRQHandler:
EXTI7_0_IRQHandler:
SPI1_IRQHandler:
DMA1_Channel2_IRQHandler:
DMA1_Channel3_IRQHandler:
DMA1_Channel4_IRQHandler:
DMA1_Channel5_IRQHandler:
DMA1_Channel6_IRQHandler:
DMA1_Channel7_IRQHandler:
DMA1_Channel8_IRQHandler:
USART2_IRQHandler:
I2C1_EV_IRQHandler:
I2C1_ER_IRQHandler:
USART1_IRQHandler:
SPI2_IRQHandler:
SPI3_IRQHandler:
SPI4_IRQHandler:
I2C2_EV_IRQHandler:
I2C2_ER_IRQHandler:
USBPD_IRQHandler:
USBPDWakeUp_IRQHandler:
USBHS_IRQHandler:
DMA1_Channel1_IRQHandler:
CAN1_SCE_IRQHandler:
CAN1_TX_IRQHandler:
CAN1_RX0_IRQHandler:
CAN1_RX1_IRQHandler:
USBSS_IRQHandler:
USBSS_LINK_IRQHandler:
USBHSWakeup_IRQHandler:
USBSSWakeup_IRQHandler:
RTCAlarm_IRQHandler:
USBFS_IRQHandler:
USBFSWakeup_IRQHandler:
ADC1_2_IRQHandler:
TIM1_BRK_IRQHandler:
TIM1_UP_IRQHandler:
TIM1_TRG_COM_IRQHandler:
TIM1_CC_IRQHandler:
TIM2_IRQHandler:
TIM3_IRQHandler:
TIM4_IRQHandler:
TIM5_IRQHandler:
I2C3_EV_IRQHandler:
I2C3_ER_IRQHandler:
I2C4_EV_IRQHandler:
I2C4_ER_IRQHandler:
QSPI1_IRQHandler:
SERDES_IRQHandler:
USART3_IRQHandler:
USART4_IRQHandler:
TIM8_BRK_IRQHandler:
TIM8_UP_IRQHandler:
TIM8_TRG_COM_IRQHandler:
TIM8_CC_IRQHandler:
TIM9_IRQHandler:
TIM10_IRQHandler:
TIM11_IRQHandler:
TIM12_IRQHandler:
FMC_IRQHandler:
SDMMC_IRQHandler:
LPTIM1_IRQHandler:
LPTIM2_IRQHandler:
USART5_IRQHandler:
USART6_IRQHandler:
TIM6_IRQHandler:
TIM7_IRQHandler:
DMA2_Channel1_IRQHandler:
DMA2_Channel2_IRQHandler:
DMA2_Channel3_IRQHandler:
DMA2_Channel4_IRQHandler:
DMA2_Channel5_IRQHandler:
DMA2_Channel6_IRQHandler:
DMA2_Channel7_IRQHandler:
DMA2_Channel8_IRQHandler:
ETH_IRQHandler:
ETH_WKUP_IRQHandler:
CAN2_SCE_IRQHandler:
CAN2_TX_IRQHandler:
CAN2_RX0_IRQHandler:
CAN2_RX1_IRQHandler:
USART7_IRQHandler:
USART8_IRQHandler:
I3C_EV_IRQHandler:
I3C_ER_IRQHandler:
DVP_IRQHandler:
ECDC_IRQHandler:
PIOC_IRQHandler:
SAI_IRQHandler:
LTDC_IRQHandler:
GPHA_IRQHandler:
DFSDM0_IRQHandler:
DFSDM1_IRQHandler:
SWPMI_IRQHandler:
QSPI2_IRQHandler:
SWPMI_WKUP_IRQHandler:
CAN3_SCE_IRQHandler:
CAN3_TX_IRQHandler:
CAN3_RX0_IRQHandler:
CAN3_RX1_IRQHandler:
LPTIM2_WKUP_IRQHandler:
LPTIM1_WKUP_IRQHandler:
I3C_WKUP_IRQHandler:
RTC_IRQHandler:
HSADC_IRQHandler:
UHSIF_IRQHandler:
RNG_IRQHandler:
SDIO_IRQHandler:
USART_WKUP_IRQHandler:
1:
j 1b
.section .load,"ax",@progbits
.align 1
_load_base:
/*Enable RCC 14*HSI_Value/5 = 70MHz*/
lui s1 ,0x40021
li a1, 0x40E
sw a1 ,8(s1)
/*enable pll*/
lw t0,0(s1)
li t1,0x1000000
or t0,t0,t1
sw t0,0(s1)
1:
lw t2,0(s1)
li t3,0x2000000
and t2,t2,t3
beqz t2 ,1b
/*enable pll gate*/
lw t4,8(s1)
li t5,0x80000000
or t4,t4,t5
sw t4,8(s1)
/*choose pll */
li t6, 0x2
sw t6 ,4(s1)
1:
lw s2, 4(s1)
li s3 ,0x8
and s2,s2,s3
beqz s2, 1b
/* Load highcode code section from flash to RAM */
la a0, _highcode_lma
la a1, _highcode_vma_start
la a2, _highcode_vma_end
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
/* Load highcode code section from flash to RAM */
2:
la a0, _highcode_lma1
la a1, _highcode_vma_start1
la a2, _highcode_vma_end1
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
/* Load data section from flash to RAM */
2:
la a0, _data_lma
la a1, _data_vma
la a2, _edata
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
2:
/* Clear bss section */
la a0, _sbss
la a1, _ebss
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b
2:
ret
.section .handle_reset,"ax",@progbits
.weak handle_reset
.align 1
handle_reset:
.option push
.option norelax
la gp, __global_pointer$
.option pop
la sp, _eusrstack
/* Load loadcode section from flash to RAM */
la a0, _loadcode_lma
la a1, _loadcode_vma_start
la a2, _loadcode_vma_end
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
2:
call _load_base
/* Configure Prefetch */
li t0, 0x123703E1
csrw 0xBC0, t0
/* Configure nesting level */
li t0, 0x01
csrw 0xBC1, t0
/* Enable interrupt nesting and hardware stack */
li t0, 0x0A
csrw 0x804, t0
/* Enable floating point and global interrupt, configure privileged mode */
li t0, 0x1800
csrw mstatus, t0
/* Configure the interrupt vector table recognition mode and entry address mode */
la t0, _vector_base
ori t0, t0, 3
csrw mtvec, t0
BP: la t0, entry
csrw mepc, t0
mret

View File

@ -0,0 +1,538 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : startup_ch32h417_v5f.s
* Author : WCH
* Version : V1.0.2
* Date : 2025/10/21
* Description : CH32h417_416_415 V5F StartUp File.
*********************************************************************************
* Copyright (c) 2025 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
.section .init,"ax",@progbits
.global _start
.align 2
_start:
j handle_reset
.section .vector,"ax",@progbits
.align 1
_vector_base:
.option norvc;
.word _start
.word 0
.word NMI_Handler
.word HardFault_Handler
.word 0
.word Ecall_M_Mode_Handler
.word 0
.word 0
.word Ecall_U_Mode_Handler
.word Break_Point_Handler
.word 0
.word 0
.word SysTick0_Handler
.word SysTick1_Handler
.word SW_Handler
.word 0
.word IPC_CH0_Handler
.word IPC_CH1_Handler
.word IPC_CH2_Handler
.word IPC_CH3_Handler
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word HSEM_Handler
.word 0
.word 0
.word 0
/* External Interrupts */
.word WWDG_IRQHandler
.word EXTI15_8_IRQHandler
.word FLASH_IRQHandler
.word RCC_IRQHandler
.word EXTI7_0_IRQHandler
.word SPI1_IRQHandler
.word DMA1_Channel2_IRQHandler
.word DMA1_Channel3_IRQHandler
.word DMA1_Channel4_IRQHandler
.word DMA1_Channel5_IRQHandler
.word DMA1_Channel6_IRQHandler
.word DMA1_Channel7_IRQHandler
.word DMA1_Channel8_IRQHandler
.word USART2_IRQHandler
.word I2C1_EV_IRQHandler
.word I2C1_ER_IRQHandler
.word USART1_IRQHandler
.word SPI2_IRQHandler
.word SPI3_IRQHandler
.word SPI4_IRQHandler
.word I2C2_EV_IRQHandler
.word I2C2_ER_IRQHandler
.word USBPD_IRQHandler
.word USBPDWakeUp_IRQHandler
.word USBHS_IRQHandler
.word DMA1_Channel1_IRQHandler
.word CAN1_SCE_IRQHandler
.word CAN1_TX_IRQHandler
.word CAN1_RX0_IRQHandler
.word CAN1_RX1_IRQHandler
.word USBSS_IRQHandler
.word USBSS_LINK_IRQHandler
.word USBHSWakeup_IRQHandler
.word USBSSWakeup_IRQHandler
.word RTCAlarm_IRQHandler
.word USBFS_IRQHandler
.word USBFSWakeup_IRQHandler
.word ADC1_2_IRQHandler
.word TIM1_BRK_IRQHandler
.word TIM1_UP_IRQHandler
.word TIM1_TRG_COM_IRQHandler
.word TIM1_CC_IRQHandler
.word TIM2_IRQHandler
.word TIM3_IRQHandler
.word TIM4_IRQHandler
.word TIM5_IRQHandler
.word I2C3_EV_IRQHandler
.word I2C3_ER_IRQHandler
.word I2C4_EV_IRQHandler
.word I2C4_ER_IRQHandler
.word QSPI1_IRQHandler
.word SERDES_IRQHandler
.word USART3_IRQHandler
.word USART4_IRQHandler
.word TIM8_BRK_IRQHandler
.word TIM8_UP_IRQHandler
.word TIM8_TRG_COM_IRQHandler
.word TIM8_CC_IRQHandler
.word TIM9_IRQHandler
.word TIM10_IRQHandler
.word TIM11_IRQHandler
.word TIM12_IRQHandler
.word FMC_IRQHandler
.word SDMMC_IRQHandler
.word LPTIM1_IRQHandler
.word LPTIM2_IRQHandler
.word USART5_IRQHandler
.word USART6_IRQHandler
.word TIM6_IRQHandler
.word TIM7_IRQHandler
.word DMA2_Channel1_IRQHandler
.word DMA2_Channel2_IRQHandler
.word DMA2_Channel3_IRQHandler
.word DMA2_Channel4_IRQHandler
.word DMA2_Channel5_IRQHandler
.word DMA2_Channel6_IRQHandler
.word DMA2_Channel7_IRQHandler
.word DMA2_Channel8_IRQHandler
.word ETH_IRQHandler
.word ETH_WKUP_IRQHandler
.word CAN2_SCE_IRQHandler
.word CAN2_TX_IRQHandler
.word CAN2_RX0_IRQHandler
.word CAN2_RX1_IRQHandler
.word USART7_IRQHandler
.word USART8_IRQHandler
.word I3C_EV_IRQHandler
.word I3C_ER_IRQHandler
.word DVP_IRQHandler
.word ECDC_IRQHandler
.word PIOC_IRQHandler
.word SAI_IRQHandler
.word LTDC_IRQHandler
.word GPHA_IRQHandler
.word 0
.word DFSDM0_IRQHandler
.word DFSDM1_IRQHandler
.word 0
.word 0
.word SWPMI_IRQHandler
.word 0
.word 0
.word QSPI2_IRQHandler
.word SWPMI_WKUP_IRQHandler
.word CAN3_SCE_IRQHandler
.word CAN3_TX_IRQHandler
.word CAN3_RX0_IRQHandler
.word CAN3_RX1_IRQHandler
.word LPTIM2_WKUP_IRQHandler
.word LPTIM1_WKUP_IRQHandler
.word I3C_WKUP_IRQHandler
.word RTC_IRQHandler
.word HSADC_IRQHandler
.word UHSIF_IRQHandler
.word RNG_IRQHandler
.word SDIO_IRQHandler
.word USART_WKUP_IRQHandler
.option rvc;
.section .text.vector_handler, "ax", @progbits
.weak NMI_Handler
.weak HardFault_Handler
.weak Ecall_M_Mode_Handler
.weak Ecall_U_Mode_Handler
.weak Break_Point_Handler
.weak SysTick0_Handler
.weak SysTick1_Handler
.weak SW_Handler
.weak IPC_CH0_Handler
.weak IPC_CH1_Handler
.weak IPC_CH2_Handler
.weak IPC_CH3_Handler
.weak HSEM_Handler
.weak WWDG_IRQHandler
.weak EXTI15_8_IRQHandler
.weak FLASH_IRQHandler
.weak RCC_IRQHandler
.weak EXTI7_0_IRQHandler
.weak SPI1_IRQHandler
.weak DMA1_Channel2_IRQHandler
.weak DMA1_Channel3_IRQHandler
.weak DMA1_Channel4_IRQHandler
.weak DMA1_Channel5_IRQHandler
.weak DMA1_Channel6_IRQHandler
.weak DMA1_Channel7_IRQHandler
.weak DMA1_Channel8_IRQHandler
.weak USART2_IRQHandler
.weak I2C1_EV_IRQHandler
.weak I2C1_ER_IRQHandler
.weak USART1_IRQHandler
.weak SPI2_IRQHandler
.weak SPI3_IRQHandler
.weak SPI4_IRQHandler
.weak I2C2_EV_IRQHandler
.weak I2C2_ER_IRQHandler
.weak USBPD_IRQHandler
.weak USBPDWakeUp_IRQHandler
.weak USBHS_IRQHandler
.weak DMA1_Channel1_IRQHandler
.weak CAN1_SCE_IRQHandler
.weak CAN1_TX_IRQHandler
.weak CAN1_RX0_IRQHandler
.weak CAN1_RX1_IRQHandler
.weak USBSS_IRQHandler
.weak USBSS_LINK_IRQHandler
.weak USBHSWakeup_IRQHandler
.weak USBSSWakeup_IRQHandler
.weak RTCAlarm_IRQHandler
.weak USBFS_IRQHandler
.weak USBFSWakeup_IRQHandler
.weak ADC1_2_IRQHandler
.weak TIM1_BRK_IRQHandler
.weak TIM1_UP_IRQHandler
.weak TIM1_TRG_COM_IRQHandler
.weak TIM1_CC_IRQHandler
.weak TIM2_IRQHandler
.weak TIM3_IRQHandler
.weak TIM4_IRQHandler
.weak TIM5_IRQHandler
.weak I2C3_EV_IRQHandler
.weak I2C3_ER_IRQHandler
.weak I2C4_EV_IRQHandler
.weak I2C4_ER_IRQHandler
.weak QSPI1_IRQHandler
.weak SERDES_IRQHandler
.weak USART3_IRQHandler
.weak USART4_IRQHandler
.weak TIM8_BRK_IRQHandler
.weak TIM8_UP_IRQHandler
.weak TIM8_TRG_COM_IRQHandler
.weak TIM8_CC_IRQHandler
.weak TIM9_IRQHandler
.weak TIM10_IRQHandler
.weak TIM11_IRQHandler
.weak TIM12_IRQHandler
.weak FMC_IRQHandler
.weak SDMMC_IRQHandler
.weak LPTIM1_IRQHandler
.weak LPTIM2_IRQHandler
.weak USART5_IRQHandler
.weak USART6_IRQHandler
.weak TIM6_IRQHandler
.weak TIM7_IRQHandler
.weak DMA2_Channel1_IRQHandler
.weak DMA2_Channel2_IRQHandler
.weak DMA2_Channel3_IRQHandler
.weak DMA2_Channel4_IRQHandler
.weak DMA2_Channel5_IRQHandler
.weak DMA2_Channel6_IRQHandler
.weak DMA2_Channel7_IRQHandler
.weak DMA2_Channel8_IRQHandler
.weak ETH_IRQHandler
.weak ETH_WKUP_IRQHandler
.weak CAN2_SCE_IRQHandler
.weak CAN2_TX_IRQHandler
.weak CAN2_RX0_IRQHandler
.weak CAN2_RX1_IRQHandler
.weak USART7_IRQHandler
.weak USART8_IRQHandler
.weak I3C_EV_IRQHandler
.weak I3C_ER_IRQHandler
.weak DVP_IRQHandler
.weak ECDC_IRQHandler
.weak PIOC_IRQHandler
.weak SAI_IRQHandler
.weak LTDC_IRQHandler
.weak GPHA_IRQHandler
.weak DFSDM0_IRQHandler
.weak DFSDM1_IRQHandler
.weak SWPMI_IRQHandler
.weak QSPI2_IRQHandler
.weak SWPMI_WKUP_IRQHandler
.weak CAN3_SCE_IRQHandler
.weak CAN3_TX_IRQHandler
.weak CAN3_RX0_IRQHandler
.weak CAN3_RX1_IRQHandler
.weak LPTIM2_WKUP_IRQHandler
.weak LPTIM1_WKUP_IRQHandler
.weak I3C_WKUP_IRQHandler
.weak RTC_IRQHandler
.weak HSADC_IRQHandler
.weak UHSIF_IRQHandler
.weak RNG_IRQHandler
.weak SDIO_IRQHandler
.weak USART_WKUP_IRQHandler
NMI_Handler:
HardFault_Handler:
Ecall_M_Mode_Handler:
Ecall_U_Mode_Handler:
Break_Point_Handler:
SysTick0_Handler:
SysTick1_Handler:
SW_Handler:
IPC_CH0_Handler:
IPC_CH1_Handler:
IPC_CH2_Handler:
IPC_CH3_Handler:
HSEM_Handler:
WWDG_IRQHandler:
EXTI15_8_IRQHandler:
FLASH_IRQHandler:
RCC_IRQHandler:
EXTI7_0_IRQHandler:
SPI1_IRQHandler:
DMA1_Channel2_IRQHandler:
DMA1_Channel3_IRQHandler:
DMA1_Channel4_IRQHandler:
DMA1_Channel5_IRQHandler:
DMA1_Channel6_IRQHandler:
DMA1_Channel7_IRQHandler:
DMA1_Channel8_IRQHandler:
USART2_IRQHandler:
I2C1_EV_IRQHandler:
I2C1_ER_IRQHandler:
USART1_IRQHandler:
SPI2_IRQHandler:
SPI3_IRQHandler:
SPI4_IRQHandler:
I2C2_EV_IRQHandler:
I2C2_ER_IRQHandler:
USBPD_IRQHandler:
USBPDWakeUp_IRQHandler:
USBHS_IRQHandler:
DMA1_Channel1_IRQHandler:
CAN1_SCE_IRQHandler:
CAN1_TX_IRQHandler:
CAN1_RX0_IRQHandler:
CAN1_RX1_IRQHandler:
USBSS_IRQHandler:
USBSS_LINK_IRQHandler:
USBHSWakeup_IRQHandler:
USBSSWakeup_IRQHandler:
RTCAlarm_IRQHandler:
USBFS_IRQHandler:
USBFSWakeup_IRQHandler:
ADC1_2_IRQHandler:
TIM1_BRK_IRQHandler:
TIM1_UP_IRQHandler:
TIM1_TRG_COM_IRQHandler:
TIM1_CC_IRQHandler:
TIM2_IRQHandler:
TIM3_IRQHandler:
TIM4_IRQHandler:
TIM5_IRQHandler:
I2C3_EV_IRQHandler:
I2C3_ER_IRQHandler:
I2C4_EV_IRQHandler:
I2C4_ER_IRQHandler:
QSPI1_IRQHandler:
SERDES_IRQHandler:
USART3_IRQHandler:
USART4_IRQHandler:
TIM8_BRK_IRQHandler:
TIM8_UP_IRQHandler:
TIM8_TRG_COM_IRQHandler:
TIM8_CC_IRQHandler:
TIM9_IRQHandler:
TIM10_IRQHandler:
TIM11_IRQHandler:
TIM12_IRQHandler:
FMC_IRQHandler:
SDMMC_IRQHandler:
LPTIM1_IRQHandler:
LPTIM2_IRQHandler:
USART5_IRQHandler:
USART6_IRQHandler:
TIM6_IRQHandler:
TIM7_IRQHandler:
DMA2_Channel1_IRQHandler:
DMA2_Channel2_IRQHandler:
DMA2_Channel3_IRQHandler:
DMA2_Channel4_IRQHandler:
DMA2_Channel5_IRQHandler:
DMA2_Channel6_IRQHandler:
DMA2_Channel7_IRQHandler:
DMA2_Channel8_IRQHandler:
ETH_IRQHandler:
ETH_WKUP_IRQHandler:
CAN2_SCE_IRQHandler:
CAN2_TX_IRQHandler:
CAN2_RX0_IRQHandler:
CAN2_RX1_IRQHandler:
USART7_IRQHandler:
USART8_IRQHandler:
I3C_EV_IRQHandler:
I3C_ER_IRQHandler:
DVP_IRQHandler:
ECDC_IRQHandler:
PIOC_IRQHandler:
SAI_IRQHandler:
LTDC_IRQHandler:
GPHA_IRQHandler:
DFSDM0_IRQHandler:
DFSDM1_IRQHandler:
SWPMI_IRQHandler:
QSPI2_IRQHandler:
SWPMI_WKUP_IRQHandler:
CAN3_SCE_IRQHandler:
CAN3_TX_IRQHandler:
CAN3_RX0_IRQHandler:
CAN3_RX1_IRQHandler:
LPTIM2_WKUP_IRQHandler:
LPTIM1_WKUP_IRQHandler:
I3C_WKUP_IRQHandler:
RTC_IRQHandler:
HSADC_IRQHandler:
UHSIF_IRQHandler:
RNG_IRQHandler:
SDIO_IRQHandler:
USART_WKUP_IRQHandler:
1:
j 1b
.section .load,"ax",@progbits
.align 1
_load_base:
/* Load highcode code section from flash to RAM */
la a0, _highcode_lma
la a1, _highcode_vma_start
la a2, _highcode_vma_end
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
/* Load highcode code section from flash to RAM */
2:
la a0, _highcode_lma1
la a1, _highcode_vma_start1
la a2, _highcode_vma_end1
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
/* Load data section from flash to RAM */
2:
la a0, _data_lma
la a1, _data_vma
la a2, _edata
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
2:
/* Clear bss section */
la a0, _sbss
la a1, _ebss
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b
2:
/* Configure Prefetch */
li t0, 0x123733E0
csrw 0xBC0, t0
/* Configure nesting level */
li t0, 0x07
csrw 0xBC1, t0
/* Enable interrupt nesting and hardware stack */
li t0, 0x0E
csrw 0x804, t0
/* Enable floating point and global interrupt, configure privileged mode */
li t0, 0x1800
csrw mstatus, t0
/* Configure the interrupt vector table recognition mode and entry address mode */
la t0, _vector_base
ori t0, t0, 3
csrw mtvec, t0
la t0, entry
csrw mepc, t0
mret
.section .handle_reset,"ax",@progbits
.weak handle_reset
.align 1
handle_reset:
.option push
.option norelax
la gp, __global_pointer$
.option pop
la sp, _eusrstack
lui a3, 0x40022
lw a4,0(a3)
li a5,0x3
or a5,a4,a5
sw a5,0(a3)
/* Load loadcode section from flash to RAM */
la a0, _loadcode_lma
la a1, _loadcode_vma_start
la a2, _loadcode_vma_end
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
2:
sw a4,0(a3)
call _load_base

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-09-09 WCH the first version
*/
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#ifndef CPUPORT_H__
#define CPUPORT_H__
/* bytes of register width */
//#define ARCH_RISCV_FPU
#define ARCH_RISCV_FPU_S
#ifdef ARCH_CPU_64BIT
#define STORE sd
#define LOAD ld
#define StoreDS "sd"
#define LoadDS "ld"
#define REGBYTES 8
#define RegLength 8
#define RegLengthS "8"
#else
#define STORE sw
#define LOAD lw
#define StoreDS "sw"
#define LoadDS "lw"
#define RegLength 4
#define REGBYTES 4
#define RegLengthS "4"
#endif
/* FPU */
#ifdef ARCH_RISCV_FPU
#ifdef ARCH_RISCV_FPU_D
#define FSTORE fsd
#define FLOAD fld
#define FREGBYTES 8
#endif
#ifdef ARCH_RISCV_FPU_S
#define FSTORE fsw
#define FLOAD flw
#define FREGBYTES 4
#endif
#endif
#endif

View File

@ -0,0 +1,151 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include <xs_assign.h>
#include <xs_base.h>
#include <xs_isr.h>
#include <xs_ktask.h>
#include "ch32h417.h"
#include "cpuport.h"
#include "core_riscv.h"
#ifdef TASK_ISOLATION
#include <xs_service.h>
#endif
extern x_ubase interrupt_from_sp;
extern x_ubase interrupt_to_sp;
extern x_ubase interrupt_new_task;
#ifdef Core_V3F
#define SysTick SysTick0
#elif defined(Core_V5F)
#define SysTick SysTick1
#endif
/*
* trigger soft interrupt
*/
void sw_setpend(void)
{
NVIC_SetPendingIRQ(Software_IRQn);
}
/*
* clear soft interrupt
*/
void sw_clearpend(void)
{
NVIC_ClearPendingIRQ(Software_IRQn);
}
x_base DisableLocalInterrupt()
{
x_base level;
asm volatile ("csrrci %0, mstatus, 8" : "=r"(level));
return level;
}
void EnableLocalInterrupt(x_base level)
{
asm volatile ("csrw mstatus, %0" :: "r"(level));
}
int ArchEnableHwIrq(uint32_t irq_num)
{
NVIC_SetPriority(irq_num, 1);
NVIC_EnableIRQ(irq_num);
}
int ArchDisableHwIrq(uint32_t irq_num)
{
NVIC_DisableIRQ(irq_num);
}
struct ExceptionStackFrame
{
uint64_t x1;
uint64_t x2;
uint64_t x3;
uint64_t x4;
uint64_t x5;
uint64_t x6;
uint64_t x7;
uint64_t x8;
uint64_t x9;
uint64_t x10;
uint64_t x11;
uint64_t x12;
uint64_t x13;
uint64_t x14;
uint64_t x15;
uint64_t x16;
uint64_t x17;
uint64_t x18;
uint64_t x19;
uint64_t x20;
uint64_t x21;
uint64_t x22;
uint64_t x23;
uint64_t x24;
uint64_t x25;
uint64_t x26;
uint64_t x27;
uint64_t x28;
uint64_t x29;
uint64_t x30;
uint64_t x31;
};
void PrintStackFrame(uintptr_t * sp)
{
struct ExceptionStackFrame * esf = (struct ExceptionStackFrame *)(sp+1);
KPrintf("\n=================================================================\n");
KPrintf("x1 (ra : Return address ) ==> 0x%08x%08x\n", esf->x1 >> 32 , esf->x1 & UINT32_MAX);
KPrintf("x2 (sp : Stack pointer ) ==> 0x%08x%08x\n", esf->x2 >> 32 , esf->x2 & UINT32_MAX);
KPrintf("x3 (gp : Global pointer ) ==> 0x%08x%08x\n", esf->x3 >> 32 , esf->x3 & UINT32_MAX);
KPrintf("x4 (tp : Task pointer ) ==> 0x%08x%08x\n", esf->x4 >> 32 , esf->x4 & UINT32_MAX);
KPrintf("x5 (t0 : Temporary ) ==> 0x%08x%08x\n", esf->x5 >> 32 , esf->x5 & UINT32_MAX);
KPrintf("x6 (t1 : Temporary ) ==> 0x%08x%08x\n", esf->x6 >> 32 , esf->x6 & UINT32_MAX);
KPrintf("x7 (t2 : Temporary ) ==> 0x%08x%08x\n", esf->x7 >> 32 , esf->x7 & UINT32_MAX);
KPrintf("x8 (s0/fp: Save register,frame pointer ) ==> 0x%08x%08x\n", esf->x8 >> 32 , esf->x8 & UINT32_MAX);
KPrintf("x9 (s1 : Save register ) ==> 0x%08x%08x\n", esf->x9 >> 32 , esf->x9 & UINT32_MAX);
KPrintf("x10(a0 : Function argument,return value) ==> 0x%08x%08x\n", esf->x10 >> 32 , esf->x10 & UINT32_MAX);
KPrintf("x11(a1 : Function argument,return value) ==> 0x%08x%08x\n", esf->x11 >> 32 , esf->x11 & UINT32_MAX);
KPrintf("x12(a2 : Function argument ) ==> 0x%08x%08x\n", esf->x12 >> 32 , esf->x12 & UINT32_MAX);
KPrintf("x13(a3 : Function argument ) ==> 0x%08x%08x\n", esf->x13 >> 32 , esf->x13 & UINT32_MAX);
KPrintf("x14(a4 : Function argument ) ==> 0x%08x%08x\n", esf->x14 >> 32 , esf->x14 & UINT32_MAX);
KPrintf("x15(a5 : Function argument ) ==> 0x%08x%08x\n", esf->x15 >> 32 , esf->x15 & UINT32_MAX);
KPrintf("x16(a6 : Function argument ) ==> 0x%08x%08x\n", esf->x16 >> 32 , esf->x16 & UINT32_MAX);
KPrintf("x17(a7 : Function argument ) ==> 0x%08x%08x\n", esf->x17 >> 32 , esf->x17 & UINT32_MAX);
KPrintf("x18(s2 : Save register ) ==> 0x%08x%08x\n", esf->x18 >> 32 , esf->x18 & UINT32_MAX);
KPrintf("x19(s3 : Save register ) ==> 0x%08x%08x\n", esf->x19 >> 32 , esf->x19 & UINT32_MAX);
KPrintf("x20(s4 : Save register ) ==> 0x%08x%08x\n", esf->x20 >> 32 , esf->x20 & UINT32_MAX);
KPrintf("x21(s5 : Save register ) ==> 0x%08x%08x\n", esf->x21 >> 32 , esf->x21 & UINT32_MAX);
KPrintf("x22(s6 : Save register ) ==> 0x%08x%08x\n", esf->x22 >> 32 , esf->x22 & UINT32_MAX);
KPrintf("x23(s7 : Save register ) ==> 0x%08x%08x\n", esf->x23 >> 32 , esf->x23 & UINT32_MAX);
KPrintf("x24(s8 : Save register ) ==> 0x%08x%08x\n", esf->x24 >> 32 , esf->x24 & UINT32_MAX);
KPrintf("x25(s9 : Save register ) ==> 0x%08x%08x\n", esf->x25 >> 32 , esf->x25 & UINT32_MAX);
KPrintf("x26(s10 : Save register ) ==> 0x%08x%08x\n", esf->x26 >> 32 , esf->x26 & UINT32_MAX);
KPrintf("x27(s11 : Save register ) ==> 0x%08x%08x\n", esf->x27 >> 32 , esf->x27 & UINT32_MAX);
KPrintf("x28(t3 : Temporary ) ==> 0x%08x%08x\n", esf->x28 >> 32 , esf->x28 & UINT32_MAX);
KPrintf("x29(t4 : Temporary ) ==> 0x%08x%08x\n", esf->x29 >> 32 , esf->x29 & UINT32_MAX);
KPrintf("x30(t5 : Temporary ) ==> 0x%08x%08x\n", esf->x30 >> 32 , esf->x30 & UINT32_MAX);
KPrintf("x31(t6 : Temporary ) ==> 0x%08x%08x\n", esf->x31 >> 32 , esf->x31 & UINT32_MAX);
KPrintf("=================================================================\n");
}
void HwInterruptcontextSwitch(x_ubase from_sp, x_ubase to_sp, struct TaskDescriptor* new_task, void* context) {
interrupt_from_sp = (x_ubase)from_sp;
interrupt_to_sp = (x_ubase)to_sp;
interrupt_new_task = (x_ubase)new_task;
sw_setpend();
}

View File

@ -0,0 +1,116 @@
#include "cpuport.h"
.global SW_Handler
.align 2
SW_Handler:
/* save all from thread context */
#ifdef ARCH_RISCV_FPU
addi sp, sp, -32 * FREGBYTES
FSTORE f0, 0 * FREGBYTES(sp)
FSTORE f1, 1 * FREGBYTES(sp)
FSTORE f2, 2 * FREGBYTES(sp)
FSTORE f3, 3 * FREGBYTES(sp)
FSTORE f4, 4 * FREGBYTES(sp)
FSTORE f5, 5 * FREGBYTES(sp)
FSTORE f6, 6 * FREGBYTES(sp)
FSTORE f7, 7 * FREGBYTES(sp)
FSTORE f8, 8 * FREGBYTES(sp)
FSTORE f9, 9 * FREGBYTES(sp)
FSTORE f10, 10 * FREGBYTES(sp)
FSTORE f11, 11 * FREGBYTES(sp)
FSTORE f12, 12 * FREGBYTES(sp)
FSTORE f13, 13 * FREGBYTES(sp)
FSTORE f14, 14 * FREGBYTES(sp)
FSTORE f15, 15 * FREGBYTES(sp)
FSTORE f16, 16 * FREGBYTES(sp)
FSTORE f17, 17 * FREGBYTES(sp)
FSTORE f18, 18 * FREGBYTES(sp)
FSTORE f19, 19 * FREGBYTES(sp)
FSTORE f20, 20 * FREGBYTES(sp)
FSTORE f21, 21 * FREGBYTES(sp)
FSTORE f22, 22 * FREGBYTES(sp)
FSTORE f23, 23 * FREGBYTES(sp)
FSTORE f24, 24 * FREGBYTES(sp)
FSTORE f25, 25 * FREGBYTES(sp)
FSTORE f26, 26 * FREGBYTES(sp)
FSTORE f27, 27 * FREGBYTES(sp)
FSTORE f28, 28 * FREGBYTES(sp)
FSTORE f29, 29 * FREGBYTES(sp)
FSTORE f30, 30 * FREGBYTES(sp)
FSTORE f31, 31 * FREGBYTES(sp)
#endif
addi sp, sp, -32 * REGBYTES
STORE x5, 5 * REGBYTES(sp)
/* saved MPIE */
li t0, 0x80
STORE t0, 2 * REGBYTES(sp)
/* Temporarily disable HPE */
li t0, 0x20
csrs 0x804, t0
STORE x1, 1 * REGBYTES(sp)
STORE x4, 4 * REGBYTES(sp)
STORE x6, 6 * REGBYTES(sp)
STORE x7, 7 * REGBYTES(sp)
STORE x8, 8 * REGBYTES(sp)
STORE x9, 9 * REGBYTES(sp)
STORE x10, 10 * REGBYTES(sp)
STORE x11, 11 * REGBYTES(sp)
STORE x12, 12 * REGBYTES(sp)
STORE x13, 13 * REGBYTES(sp)
STORE x14, 14 * REGBYTES(sp)
STORE x15, 15 * REGBYTES(sp)
STORE x16, 16 * REGBYTES(sp)
STORE x17, 17 * REGBYTES(sp)
STORE x18, 18 * REGBYTES(sp)
STORE x19, 19 * REGBYTES(sp)
STORE x20, 20 * REGBYTES(sp)
STORE x21, 21 * REGBYTES(sp)
STORE x22, 22 * REGBYTES(sp)
STORE x23, 23 * REGBYTES(sp)
STORE x24, 24 * REGBYTES(sp)
STORE x25, 25 * REGBYTES(sp)
STORE x26, 26 * REGBYTES(sp)
STORE x27, 27 * REGBYTES(sp)
STORE x28, 28 * REGBYTES(sp)
STORE x29, 29 * REGBYTES(sp)
STORE x30, 30 * REGBYTES(sp)
STORE x31, 31 * REGBYTES(sp)
csrr a0, mepc
STORE a0, 0 * REGBYTES(sp)
/* switch to interrupt stack */
csrrw sp,mscratch,sp
/* clear interrupt */
jal sw_clearpend
/* switch to from thread stack */
csrrw sp,mscratch,sp
csrr a0, mepc
STORE a0, 0 * REGBYTES(sp)
la s0, interrupt_from_sp
LOAD s1, 0(s0)
STORE sp, 0(s1)
la s0, interrupt_to_sp
LOAD s1, 0(s0)
LOAD sp, 0(s1)
LOAD a0, 0 * REGBYTES(sp)
csrw mepc, a0
LOAD x1, 1 * REGBYTES(sp)
li t0,0x7800
csrs mstatus, t0
LOAD t0, 2*REGBYTES(sp)
csrs mstatus, t0
j SwitchKTaskContextExit

View File

@ -0,0 +1,156 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "cpuport.h"
#include <board.h>
#include <xs_base.h>
#include <xs_ktask.h>
#include <xs_isr.h>
#ifdef TASK_ISOLATION
#include "encoding.h"
#include <stdint.h>
#include <xs_isolation.h>
#endif
volatile x_ubase interrupt_from_sp = 0;
volatile x_ubase interrupt_to_sp = 0;
volatile x_ubase interrupt_new_task = 0;
struct StackRegisterContext
{
x_ubase epc;
x_ubase ra;
x_ubase mstatus;
x_ubase gp;
x_ubase tp;
x_ubase t0;
x_ubase t1;
x_ubase t2;
x_ubase s0_fp;
x_ubase s1;
x_ubase a0;
x_ubase a1;
x_ubase a2;
x_ubase a3;
x_ubase a4;
x_ubase a5;
x_ubase a6;
x_ubase a7;
x_ubase s2;
x_ubase s3;
x_ubase s4;
x_ubase s5;
x_ubase s6;
x_ubase s7;
x_ubase s8;
x_ubase s9;
x_ubase s10;
x_ubase s11;
x_ubase t3;
x_ubase t4;
x_ubase t5;
x_ubase t6;
/* float register */
#ifdef ARCH_RISCV_FPU
x_ubase f0; /* f0 */
x_ubase f1; /* f1 */
x_ubase f2; /* f2 */
x_ubase f3; /* f3 */
x_ubase f4; /* f4 */
x_ubase f5; /* f5 */
x_ubase f6; /* f6 */
x_ubase f7; /* f7 */
x_ubase f8; /* f8 */
x_ubase f9; /* f9 */
x_ubase f10; /* f10 */
x_ubase f11; /* f11 */
x_ubase f12; /* f12 */
x_ubase f13; /* f13 */
x_ubase f14; /* f14 */
x_ubase f15; /* f15 */
x_ubase f16; /* f16 */
x_ubase f17; /* f17 */
x_ubase f18; /* f18 */
x_ubase f19; /* f19 */
x_ubase f20; /* f20 */
x_ubase f21; /* f21 */
x_ubase f22; /* f22 */
x_ubase f23; /* f23 */
x_ubase f24; /* f24 */
x_ubase f25; /* f25 */
x_ubase f26; /* f26 */
x_ubase f27; /* f27 */
x_ubase f28; /* f28 */
x_ubase f29; /* f29 */
x_ubase f30; /* f30 */
x_ubase f31; /* f31 */
#endif
};
uint8 KTaskStackSetup(struct TaskDescriptor *task)
{
struct StackRegisterContext *stack_contex;
int i;
task->stack_point = (uint8 *)ALIGN_MEN_DOWN((x_ubase)(task->task_base_info.stack_start + task->task_base_info.stack_depth), RegLength);
task->stack_point -= sizeof(struct StackRegisterContext);
stack_contex = (struct StackRegisterContext *)task->stack_point;
for (i = 0; i < sizeof(struct StackRegisterContext) / sizeof(x_ubase); i++)
((x_ubase *)stack_contex)[i] = 0xfadeface;
#ifdef SEPARATE_COMPILE
if (task->task_dync_sched_member.isolation_flag == 1) {
stack_contex->ra = (unsigned long)USERSPACE->us_taskquit;
} else {
stack_contex->ra = (x_ubase)KTaskQuit;
}
#else
stack_contex->ra = (x_ubase)KTaskQuit;
#endif
stack_contex->a0 = (x_ubase)task->task_base_info.func_param;
stack_contex->epc = (x_ubase)task->task_base_info.func_entry;
#ifdef TASK_ISOLATION
stack_contex->tp = (x_ubase)task;
if(task->task_dync_sched_member.isolation_flag == 1)
stack_contex->mstatus = 0x00006080;
else
#endif
/* force to machine mode(MPP=11) and set MPIE to 1 */
#ifdef ARCH_RISCV_FPU
stack_contex->mstatus = 0x7880;
#else
stack_contex->mstatus = 0x1880;
#endif
return EOK;
}
#ifdef TASK_ISOLATION
void RestoreMstatus(uintptr_t *sp)
{
struct TaskDescriptor *tid;
tid = (struct TaskDescriptor *)(sp[4]);
if(tid->task_dync_sched_member.isolation_flag == 1 && tid->task_dync_sched_member.isolation_status == 0){
CLEAR_CSR(mstatus, (MSTATUS_MPP));
#ifdef MOMERY_PROTECT_ENABLE
mem_access.Load(tid->task_dync_sched_member.isolation);
#endif
}else{
SET_CSR(mstatus, MSTATUS_MPP);
}
}
#endif

View File

@ -0,0 +1,208 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "cpuport.h"
.global SwitchKTaskContextExit
SwitchKTaskContextExit:
/* resw ra to mepc */
LOAD a0, 0 * REGBYTES(sp)
csrw mepc, a0
LOAD ra, 1 * REGBYTES(sp)
/* keep machine mode */
li a0, 0x7800
csrw mstatus, a0
/* resume MPIE */
LOAD a0, 2*REGBYTES(sp)
csrs mstatus, a0
LOAD x4, 4 * REGBYTES(sp)
LOAD x5, 5 * REGBYTES(sp)
LOAD x6, 6 * REGBYTES(sp)
LOAD x7, 7 * REGBYTES(sp)
LOAD x8, 8 * REGBYTES(sp)
LOAD x9, 9 * REGBYTES(sp)
LOAD x10, 10 * REGBYTES(sp)
LOAD x11, 11 * REGBYTES(sp)
LOAD x12, 12 * REGBYTES(sp)
LOAD x13, 13 * REGBYTES(sp)
LOAD x14, 14 * REGBYTES(sp)
LOAD x15, 15 * REGBYTES(sp)
LOAD x16, 16 * REGBYTES(sp)
LOAD x17, 17 * REGBYTES(sp)
LOAD x18, 18 * REGBYTES(sp)
LOAD x19, 19 * REGBYTES(sp)
LOAD x20, 20 * REGBYTES(sp)
LOAD x21, 21 * REGBYTES(sp)
LOAD x22, 22 * REGBYTES(sp)
LOAD x23, 23 * REGBYTES(sp)
LOAD x24, 24 * REGBYTES(sp)
LOAD x25, 25 * REGBYTES(sp)
LOAD x26, 26 * REGBYTES(sp)
LOAD x27, 27 * REGBYTES(sp)
LOAD x28, 28 * REGBYTES(sp)
LOAD x29, 29 * REGBYTES(sp)
LOAD x30, 30 * REGBYTES(sp)
LOAD x31, 31 * REGBYTES(sp)
addi sp, sp, 32 * REGBYTES
/* load float reg */
#ifdef ARCH_RISCV_FPU
FLOAD f0, 0 * FREGBYTES(sp)
FLOAD f1, 1 * FREGBYTES(sp)
FLOAD f2, 2 * FREGBYTES(sp)
FLOAD f3, 3 * FREGBYTES(sp)
FLOAD f4, 4 * FREGBYTES(sp)
FLOAD f5, 5 * FREGBYTES(sp)
FLOAD f6, 6 * FREGBYTES(sp)
FLOAD f7, 7 * FREGBYTES(sp)
FLOAD f8, 8 * FREGBYTES(sp)
FLOAD f9, 9 * FREGBYTES(sp)
FLOAD f10, 10 * FREGBYTES(sp)
FLOAD f11, 11 * FREGBYTES(sp)
FLOAD f12, 12 * FREGBYTES(sp)
FLOAD f13, 13 * FREGBYTES(sp)
FLOAD f14, 14 * FREGBYTES(sp)
FLOAD f15, 15 * FREGBYTES(sp)
FLOAD f16, 16 * FREGBYTES(sp)
FLOAD f17, 17 * FREGBYTES(sp)
FLOAD f18, 18 * FREGBYTES(sp)
FLOAD f19, 19 * FREGBYTES(sp)
FLOAD f20, 20 * FREGBYTES(sp)
FLOAD f21, 21 * FREGBYTES(sp)
FLOAD f22, 22 * FREGBYTES(sp)
FLOAD f23, 23 * FREGBYTES(sp)
FLOAD f24, 24 * FREGBYTES(sp)
FLOAD f25, 25 * FREGBYTES(sp)
FLOAD f26, 26 * FREGBYTES(sp)
FLOAD f27, 27 * FREGBYTES(sp)
FLOAD f28, 28 * FREGBYTES(sp)
FLOAD f29, 29 * FREGBYTES(sp)
FLOAD f30, 30 * FREGBYTES(sp)
FLOAD f31, 31 * FREGBYTES(sp)
addi sp, sp, 32 * FREGBYTES
#endif
mret
.global SwitchKtaskContextTo
SwitchKtaskContextTo:
/*
* if it is an assembly entry code, the SP offset value is determined by the assembly code,
* but the C code is determined by the compiler, so we subtract 512 here as a reservation.
* When entering the interrupt function of C code, the compiler automatically presses the stack
* into the task stack. We can only change the SP value used by the calling function after switching
* the interrupt stack.This problem can be solved by modifying the interrupt to the assembly entry,
* and there is no need to reserve 512 bytes. You only need to switch the interrupt stack at the
* beginning of the interrupt function
*/
la t0, _eusrstack
addi t0, t0, -512
csrw mscratch,t0
LOAD sp, (a0)
MOVE a0, a1
jal RestoreCpusLockStatus
LOAD a0, 2 * REGBYTES(sp)
csrw mstatus, a0
j SwitchKTaskContextExit
.global SwitchKtaskContext
SwitchKtaskContext:
/* switch in thread */
#ifdef ARCH_RISCV_FPU
addi sp, sp, -32*FREGBYTES
FSTORE f0, 0 * FREGBYTES(sp)
FSTORE f1, 1 * FREGBYTES(sp)
FSTORE f2, 2 * FREGBYTES(sp)
FSTORE f3, 3 * FREGBYTES(sp)
FSTORE f4, 4 * FREGBYTES(sp)
FSTORE f5, 5 * FREGBYTES(sp)
FSTORE f6, 6 * FREGBYTES(sp)
FSTORE f7, 7 * FREGBYTES(sp)
FSTORE f8, 8 * FREGBYTES(sp)
FSTORE f9, 9 * FREGBYTES(sp)
FSTORE f10, 10 * FREGBYTES(sp)
FSTORE f11, 11 * FREGBYTES(sp)
FSTORE f12, 12 * FREGBYTES(sp)
FSTORE f13, 13 * FREGBYTES(sp)
FSTORE f14, 14 * FREGBYTES(sp)
FSTORE f15, 15 * FREGBYTES(sp)
FSTORE f16, 16 * FREGBYTES(sp)
FSTORE f17, 17 * FREGBYTES(sp)
FSTORE f18, 18 * FREGBYTES(sp)
FSTORE f19, 19 * FREGBYTES(sp)
FSTORE f20, 20 * FREGBYTES(sp)
FSTORE f21, 21 * FREGBYTES(sp)
FSTORE f22, 22 * FREGBYTES(sp)
FSTORE f23, 23 * FREGBYTES(sp)
FSTORE f24, 24 * FREGBYTES(sp)
FSTORE f25, 25 * FREGBYTES(sp)
FSTORE f26, 26 * FREGBYTES(sp)
FSTORE f27, 27 * FREGBYTES(sp)
FSTORE f28, 28 * FREGBYTES(sp)
FSTORE f29, 29 * FREGBYTES(sp)
FSTORE f30, 30 * FREGBYTES(sp)
FSTORE f31, 31 * FREGBYTES(sp)
#endif
addi sp, sp, -32 * REGBYTES
/* save from sp */
STORE sp, 0(a0)
/* save ra to epc */
STORE x1, 0 * REGBYTES(sp)
STORE x1, 1 * REGBYTES(sp)
STORE x5, 5 * REGBYTES(sp)
csrr t0, mstatus
andi t0, t0, 8
/* if MIE be enabled,set MPIE */
beqz t0, 1f
li t0, 0x80
1: STORE t0, 2 * REGBYTES(sp)
STORE x4, 4 * REGBYTES(sp)
STORE x6, 6 * REGBYTES(sp)
STORE x7, 7 * REGBYTES(sp)
STORE x8, 8 * REGBYTES(sp)
STORE x9, 9 * REGBYTES(sp)
STORE x10, 10 * REGBYTES(sp)
STORE x11, 11 * REGBYTES(sp)
STORE x12, 12 * REGBYTES(sp)
STORE x13, 13 * REGBYTES(sp)
STORE x14, 14 * REGBYTES(sp)
STORE x15, 15 * REGBYTES(sp)
STORE x16, 16 * REGBYTES(sp)
STORE x17, 17 * REGBYTES(sp)
STORE x18, 18 * REGBYTES(sp)
STORE x19, 19 * REGBYTES(sp)
STORE x20, 20 * REGBYTES(sp)
STORE x21, 21 * REGBYTES(sp)
STORE x22, 22 * REGBYTES(sp)
STORE x23, 23 * REGBYTES(sp)
STORE x24, 24 * REGBYTES(sp)
STORE x25, 25 * REGBYTES(sp)
STORE x26, 26 * REGBYTES(sp)
STORE x27, 27 * REGBYTES(sp)
STORE x28, 28 * REGBYTES(sp)
STORE x29, 29 * REGBYTES(sp)
STORE x30, 30 * REGBYTES(sp)
STORE x31, 31 * REGBYTES(sp)
/* get "to" thread sp */
LOAD sp, (a1)
/*MOVE a0, a2
jal RestoreCpusLockStatus*/
j SwitchKTaskContextExit

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include <xs_ktick.h>
#include <xs_isr.h>
#include <xs_assign.h>
#include "ch32h417.h"
#include "ch32h417_it.h"
#include "core_riscv.h"
extern void KTaskOsAssignAfterIrq(void *);
void SysTick_Handler(void)
{
GET_INT_SP();
/* enter interrupt */
x_base level;
level = DisableLocalInterrupt();
isrManager.done->incCounter();
EnableLocalInterrupt(level);
#ifdef Core_V3F
SysTick0->ISR &= ~(1 << 0);
#elif defined(Core_V5F)
SysTick0->ISR &= ~(1 << 1);
#endif
TickAndTaskTimesliceUpdate();
KTaskOsAssignAfterIrq(NONE);
/* leave interrupt */
level = DisableLocalInterrupt();
isrManager.done->decCounter();
EnableLocalInterrupt(level);
FREE_INT_SP();
}
void SysTick0_Handler(void) __attribute__((interrupt()));
void SysTick0_Handler(void)
{
SysTick_Handler();
}
void SysTick1_Handler(void) __attribute__((interrupt()));
void SysTick1_Handler(void)
{
SysTick_Handler();
}

View File

@ -114,7 +114,7 @@ x_err_t PmpClearRegion(void *task_pmp, x_ubase addr)
if (!IsDoubleLinkListEmpty(&pmp->tor_list)) {
DOUBLE_LINKLIST_FOR_EACH(link, &pmp->tor_list) {
tor_node = CONTAINER_OF(link, struct PmpRegionTor, link);
if ( addr = tor_node->start ){
if ( addr == tor_node->start ){
pmp->count = pmp->count -2;
goto __free ;
}
@ -123,7 +123,7 @@ x_err_t PmpClearRegion(void *task_pmp, x_ubase addr)
if (!IsDoubleLinkListEmpty(&pmp->tor_swap_list)) {
DOUBLE_LINKLIST_FOR_EACH(link, &pmp->tor_swap_list) {
tor_node = CONTAINER_OF(link, struct PmpRegionTor, link);
if ( addr = tor_node->start ) {
if ( addr == tor_node->start ) {
goto __free;
}
}
@ -308,7 +308,7 @@ x_bool PmpAccessFaultHandle(void *task_pmp, x_ubase addr)
pmp = (struct Pmp *)task_pmp ;
x_bool ret = RET_FALSE;
uint8_t region_type;
uint8_t region_type = 0;
DoubleLinklistType *link = NONE;
struct PmpRegionTor *tor_node = NONE;
@ -327,7 +327,7 @@ x_bool PmpAccessFaultHandle(void *task_pmp, x_ubase addr)
__swap:
if ( region_type = PMP_TOR ) {
if ( region_type == PMP_TOR ) {
if( pmp->count < PMP_MAX_ENTRY_NUMBER - 2) {
DoubleLinkListRmNode(&(tor_node->link));
DoubleLinkListInsertNodeBefore(&pmp->tor_list, &tor_node->link);
@ -340,9 +340,7 @@ __swap:
DoubleLinkListInsertNodeBefore(&pmp->tor_list, &tor_node->link);
DoubleLinkListInsertNodeBefore(&pmp->tor_swap_list, &swap_node->link);
swap_node->swap_count ++;
}
}
ret = RET_TRUE;

View File

@ -78,6 +78,7 @@ struct MemGather
typedef struct MemGather *GatherMemType;
x_err_t InitMemGather(struct MemGather *gm_handler, const char *gm_name, void *begin_address, x_size_t gm_size, x_size_t one_block_size);
/* Caller must FreeBlockMemGather all blocks before RemoveMemGather/DeleteMemGather. */
x_err_t RemoveMemGather(struct MemGather *gm_handler);
GatherMemType CreateMemGather(const char *gm_name, x_size_t block_number, x_size_t one_block_size);
x_err_t DeleteMemGather(GatherMemType gm_handler);

View File

@ -41,10 +41,10 @@ struct Semaphore
typedef struct {
int32 (*SemaphoreCreate)(uint16 val);
void (*SemaphoreDelete)(struct Semaphore *sem);
int32 (*SemaphoreObtain)(struct Semaphore *sem, int32 wait_time);
int32 (*SemaphoreAbandon)(struct Semaphore *sem);
int32 (*SemaphoreSetValue)(struct Semaphore *sem, uint16 val);
void (*SemaphoreDelete)(int32 id);
int32 (*SemaphoreObtain)(int32 id, int32 wait_time);
int32 (*SemaphoreAbandon)(int32 id);
int32 (*SemaphoreSetValue)(int32 id, uint16 val);
} SemaphoreDoneType;
int32 KSemaphoreCreate(uint16 val);

View File

@ -53,6 +53,11 @@ x_err_t InitMemGather(struct MemGather *gm_handler, const char *gm_name, void *
CHECK(gm_size >= 1 && one_block_size >= 1);
if (ALIGN_MEN_DOWN(gm_size, MEM_ALIGN_SIZE) <
ALIGN_MEN_UP(one_block_size, MEM_ALIGN_SIZE) + sizeof(uint8 *)) {
return ERROR;
}
lock = CriticalAreaLock();
/* try to find gatherblock object */
@ -97,8 +102,10 @@ x_err_t InitMemGather(struct MemGather *gm_handler, const char *gm_name, void *
(uint8 *)(block_ptr + (off_block + 1) * (one_block_size + sizeof(uint8 *)));
}
*(uint8 **)(block_ptr + (off_block - 1) * (one_block_size + sizeof(uint8 *))) =
NONE;
if (gm_handler->block_total_number > 0) {
*(uint8 **)(block_ptr + (off_block - 1) * (one_block_size + sizeof(uint8 *))) =
NONE;
}
gm_handler->m_block_link = block_ptr;
@ -108,11 +115,12 @@ x_err_t InitMemGather(struct MemGather *gm_handler, const char *gm_name, void *
/**
* This function will remove the gatherblock from the global list, which is created by MemGatherInit function
* This function will remove the gatherblock from the global list, which is created by MemGatherInit function.
* All blocks must be returned via FreeBlockMemGather before calling this function.
*
* @param gm_handler the gatherblock to be removed
*
* @return EOK
* @return EOK on success; ERROR if blocks are still allocated
*/
x_err_t RemoveMemGather(struct MemGather *gm_handler)
{
@ -124,6 +132,10 @@ x_err_t RemoveMemGather(struct MemGather *gm_handler)
CHECK((gm_handler->m_kind & Cmpt_KindN_Static)!=0);
if (gm_handler->block_free_number != gm_handler->block_total_number) {
return ERROR;
}
/* resume all the suspend tasks on gatherblock object */
while (!IsDoubleLinkListEmpty(&(gm_handler->wait_task))) {
critical_value = CriticalAreaLock();
@ -238,10 +250,11 @@ GatherMemType CreateMemGather(const char *gm_name, x_size_t block_number, x_size
/**
* This function will delete a gatherblock object, which is created by MemGatherCreate function.
* All blocks must be returned via FreeBlockMemGather before calling this function.
*
* @param gm_handler the gatherblock object to be deleted
*
* @return EOK
* @return EOK on success; ERROR if blocks are still allocated
*/
x_err_t DeleteMemGather(GatherMemType gm_handler)
{
@ -254,6 +267,10 @@ x_err_t DeleteMemGather(GatherMemType gm_handler)
NULL_PARAM_CHECK(gm_handler);
CHECK(((gm_handler->m_kind & Cmpt_KindN_Static)==0));
if (gm_handler->block_free_number != gm_handler->block_total_number) {
return ERROR;
}
/* resume all the suspend tasks on gatherblock object */
while (!IsDoubleLinkListEmpty(&(gm_handler->wait_task))) {
critical_value = CriticalAreaLock();

View File

@ -29,14 +29,23 @@
* This function will return the node height of the avl tree
*
* @param avl_node avl tree node descriptor
* @return 0
* @return cached height, or 0 if node is NULL
*/
static uint32 AvlTreeGetNodeHeight(AvlNodeType avl_node)
{
return avl_node ? avl_node->height : 0;
}
/**
* This function will update the cached height of the avl tree node
*
* @param avl_node avl tree node descriptor
*/
static void AvlTreeUpdateNodeHeight(AvlNodeType avl_node)
{
if(avl_node) {
return AVL_MAX(AvlTreeGetNodeHeight(avl_node->left), AvlTreeGetNodeHeight(avl_node->right)) + 1;
} else {
return 0;
avl_node->height = AVL_MAX(AvlTreeGetNodeHeight(avl_node->left),
AvlTreeGetNodeHeight(avl_node->right)) + 1;
}
}
@ -69,8 +78,8 @@ static AvlNodeType AvlTreeSetRightRotate(AvlNodeType avl_node)
avl_node->left = new_node->right;
new_node->right = avl_node;
new_node->height = AVL_MAX(AvlTreeGetNodeHeight(new_node->left), AvlTreeGetNodeHeight(new_node->right)) + 1;
avl_node->height = AVL_MAX(AvlTreeGetNodeHeight(avl_node->left), AvlTreeGetNodeHeight(avl_node->right)) + 1;
AvlTreeUpdateNodeHeight(avl_node);
AvlTreeUpdateNodeHeight(new_node);
return new_node;
}
@ -90,8 +99,8 @@ static AvlNodeType AvlTreeSetLeftRotate(AvlNodeType avl_node)
avl_node->right = new_node->left;
new_node->left = avl_node;
new_node->height = AVL_MAX(AvlTreeGetNodeHeight(new_node->left), AvlTreeGetNodeHeight(new_node->right)) + 1;
avl_node->height = AVL_MAX(AvlTreeGetNodeHeight(avl_node->left), AvlTreeGetNodeHeight(avl_node->right)) + 1;
AvlTreeUpdateNodeHeight(avl_node);
AvlTreeUpdateNodeHeight(new_node);
return new_node;
}
@ -221,74 +230,10 @@ AvlNodeType AvlTreeInsertNode(AvlNodeType avl_node, int32 data)
}
}
AvlTreeUpdateNodeHeight(avl_node);
return AvlTreeBalance(avl_node);
}
/**
* This function will find the pre node of the avl_node
*
* @param avl_node avl tree node descriptor
* @return avl tree node
*/
static AvlNodeType AvlTreeFindPreNode(AvlNodeType avl_node)
{
NULL_PARAM_CHECK(avl_node);
AvlNodeType pre_node = NONE;
if(avl_node->left) {
if(avl_node->left->right) {
pre_node = avl_node->left->right;
while(pre_node->right) {
pre_node = pre_node->right;
}
} else {
pre_node = avl_node->left;
}
} else {
pre_node = avl_node;
}
return pre_node;
}
/**
* This function will delete a certain node, ultimate target is to find the leaf node
*
* @param avl_node avl tree node descriptor
* @param data delete data
* @return avl tree node
*/
static AvlNodeType AvlTreeDeleteLeafNode(AvlNodeType avl_node)
{
AvlNodeType pre_node = NONE;
if((NONE == avl_node->left) && (NONE == avl_node->right)) {
/*Leaf Node*/
avl_node = NONE;
x_free(avl_node);
} else if(NONE == avl_node->left) {
/*Right child is Leaf Node*/
avl_node->data = avl_node->right->data;
avl_node->right = NONE;
x_free(avl_node->right);
} else if(NONE == avl_node->right) {
/*Left child is Leaf Node*/
avl_node->data = avl_node->left->data;
avl_node->left = NONE;
x_free(avl_node->left);
} else {
/*Find the pre node to replace the avl node, then delete the pre node*/
pre_node = AvlTreeFindPreNode(avl_node);
if(pre_node) {
avl_node->data = pre_node->data;
avl_node->left = AvlTreeDeleteNode(avl_node->left, pre_node->data);
}
}
return avl_node;
}
/**
* This function will delete data from the avl tree
*
@ -297,17 +242,39 @@ static AvlNodeType AvlTreeDeleteLeafNode(AvlNodeType avl_node)
*/
AvlNodeType AvlTreeDeleteNode(AvlNodeType avl_node, int32 data)
{
AvlNodeType temp = NONE;
AvlNodeType pred = NONE;
if(avl_node) {
if(data == avl_node->data) {
avl_node = AvlTreeDeleteLeafNode(avl_node);
if(avl_node->data < data) {
avl_node->right = AvlTreeDeleteNode(avl_node->right, data);
} else if(avl_node->data > data) {
avl_node->left = AvlTreeDeleteNode(avl_node->left, data);
} else {
if(avl_node->data < data) {
avl_node->right = AvlTreeDeleteNode(avl_node->right, data);
if((NONE == avl_node->left) && (NONE == avl_node->right)) {
x_free(avl_node);
return NONE;
} else if(NONE == avl_node->left) {
temp = avl_node->right;
x_free(avl_node);
AvlTreeUpdateNodeHeight(temp);
return AvlTreeBalance(temp);
} else if(NONE == avl_node->right) {
temp = avl_node->left;
x_free(avl_node);
AvlTreeUpdateNodeHeight(temp);
return AvlTreeBalance(temp);
} else {
avl_node->left = AvlTreeDeleteNode(avl_node->left, data);
pred = avl_node->left;
while(pred->right) {
pred = pred->right;
}
avl_node->data = pred->data;
avl_node->left = AvlTreeDeleteNode(avl_node->left, pred->data);
}
}
AvlTreeUpdateNodeHeight(avl_node);
return AvlTreeBalance(avl_node);
} else {
KPrintf("AvlTreeDeleteNode cannot find the delete data\n");

View File

@ -180,11 +180,11 @@ static x_err_t _MsgQueueUrgentSend(struct MsgQueue *mq, const void *buffer, x_si
if (mq->index < 0)
mq->index += mq->max_msgs;
msg = mq->msg_buf + ( ( mq->index + mq->num_msgs ) % mq->max_msgs ) * mq->each_len ;
msg = mq->msg_buf + (mq->index % mq->max_msgs) * mq->each_len;
memcpy(msg , buffer, size);
mq->num_msgs ++;
if (!IsDoubleLinkListEmpty(&mq->send_pend_list)) {
LinklistResume(&(mq->send_pend_list));
if (!IsDoubleLinkListEmpty(&mq->recv_pend_list)) {
LinklistResume(&(mq->recv_pend_list));
CriticalAreaUnLock(lock);
DO_KTASK_ASSIGN;
return EOK;
@ -214,7 +214,7 @@ static x_err_t _MsgQueueRecv(struct MsgQueue* mq,
timeout = CalculateTickFromTimeMs(msec);
lock = CriticalAreaLock();
if (mq->index == 0 && timeout == 0) {
if (timeout == 0 && mq->num_msgs <= 0) {
CriticalAreaUnLock(lock);
return -ETIMEOUT;
}

View File

@ -61,15 +61,25 @@ static int32 _SemaphoreCreate(uint16 val)
return id;
}
static void _SemaphoreDelete(struct Semaphore *sem)
static void _SemaphoreDelete(int32 id)
{
int resched = 0;
x_base lock = 0;
struct Semaphore *sem = NONE;
struct IdNode *idnode = NONE;
NULL_PARAM_CHECK(sem);
if (id < 0)
return;
lock = CriticalAreaLock();
idnode = IdGetObj(&k_sem_id_manager, id);
if (idnode == NONE) {
CriticalAreaUnLock(lock);
return;
}
sem = CONTAINER_OF(idnode, struct Semaphore, id);
SYS_KDEBUG_LOG(KDBG_IPC, ("deleted semaphore: id %d\n", (int)sem->id.id));
lock = CriticalAreaLock();
if (!IsDoubleLinkListEmpty(&sem->pend_list)) {
resched = 1;
LinklistResumeAll(&sem->pend_list);
@ -84,21 +94,29 @@ static void _SemaphoreDelete(struct Semaphore *sem)
if (resched){
DO_KTASK_ASSIGN;
}
}
static int32 _SemaphoreObtain(struct Semaphore *sem, int32 msec)
static int32 _SemaphoreObtain(int32 id, int32 msec)
{
int lock = 0;
int32 wait_time = 0;
struct TaskDescriptor *task = NONE;
struct Semaphore *sem = NONE;
struct IdNode *idnode = NONE;
NULL_PARAM_CHECK(sem);
if (id < 0)
return -ERROR;
if(WAITING_FOREVER == msec)
wait_time = WAITING_FOREVER;
else
wait_time = CalculateTickFromTimeMs(msec);
lock = CriticalAreaLock();
idnode = IdGetObj(&k_sem_id_manager, id);
if (idnode == NONE) {
CriticalAreaUnLock(lock);
return -ERROR;
}
sem = CONTAINER_OF(idnode, struct Semaphore, id);
SYS_KDEBUG_LOG(KDBG_IPC, ("obtain semaphore: id %d, value %d, by task %s\n",
(int)sem->id.id, (int)sem->value, GetKTaskDescriptor()->task_base_info.name));
@ -134,14 +152,23 @@ static int32 _SemaphoreObtain(struct Semaphore *sem, int32 msec)
return task->exstatus;
}
static int32 _SemaphoreAbandon(struct Semaphore *sem)
static int32 _SemaphoreAbandon(int32 id)
{
int lock = 0;
int resched = 0;
struct Semaphore *sem = NONE;
struct IdNode *idnode = NONE;
NULL_PARAM_CHECK(sem);
if (id < 0)
return -ERROR;
lock = CriticalAreaLock();
idnode = IdGetObj(&k_sem_id_manager, id);
if (idnode == NONE) {
CriticalAreaUnLock(lock);
return -ERROR;
}
sem = CONTAINER_OF(idnode, struct Semaphore, id);
SYS_KDEBUG_LOG(KDBG_IPC, ("abandon semaphore: id %d, value %d, by task %s\n",
(int)sem->id.id, (int)sem->value, GetKTaskDescriptor()->task_base_info.name));
@ -162,14 +189,23 @@ static int32 _SemaphoreAbandon(struct Semaphore *sem)
return EOK;
}
static int32 _SemaphoreSetValue(struct Semaphore *sem, uint16 val)
static int32 _SemaphoreSetValue(int32 id, uint16 val)
{
int lock = 0;
int resched = 0;
struct Semaphore *sem = NONE;
struct IdNode *idnode = NONE;
NULL_PARAM_CHECK(sem);
if (id < 0)
return -ERROR;
lock = CriticalAreaLock();
idnode = IdGetObj(&k_sem_id_manager, id);
if (idnode == NONE) {
CriticalAreaUnLock(lock);
return -ERROR;
}
sem = CONTAINER_OF(idnode, struct Semaphore, id);
SYS_KDEBUG_LOG(KDBG_IPC, ("set semaphore value: id %d, old value %d, new value %d, by task %s\n",
(int)sem->id.id, (int)sem->value, (int)val, GetKTaskDescriptor()->task_base_info.name));
@ -221,24 +257,9 @@ int32 KSemaphoreCreate(uint16 val)
*/
void KSemaphoreDelete(int32 id)
{
x_base lock = 0;
struct Semaphore *sem = NONE;
struct IdNode *idnode = NONE;
KDEBUG_NOT_IN_INTERRUPT;
if (id < 0)
return;
lock = CriticalAreaLock();
idnode = IdGetObj(&k_sem_id_manager, id);
if (idnode == NONE){
CriticalAreaUnLock(lock);
return;
}
CriticalAreaUnLock(lock);
sem = CONTAINER_OF(idnode, struct Semaphore, id);
done.SemaphoreDelete(sem);
done.SemaphoreDelete(id);
}
/**
@ -252,22 +273,7 @@ int32 KSemaphoreObtain(int32 id, int32 msec)
{
KDEBUG_NOT_IN_INTERRUPT;
x_base lock = 0;
struct Semaphore *sem = NONE;
struct IdNode *idnode = NONE;
if (id < 0)
return -ERROR;
lock = CriticalAreaLock();
idnode = IdGetObj(&k_sem_id_manager, id);
if (idnode == NONE){
CriticalAreaUnLock(lock);
return -ERROR;
}
sem =CONTAINER_OF(idnode, struct Semaphore, id);
CriticalAreaUnLock(lock);
return done.SemaphoreObtain(sem, msec);
return done.SemaphoreObtain(id, msec);
}
/**
@ -280,23 +286,7 @@ int32 KSemaphoreAbandon(int32 id)
{
KDEBUG_NOT_IN_INTERRUPT;
x_base lock = 0;
struct Semaphore *sem = NONE;
struct IdNode *idnode = NONE;
if (id < 0)
return -ERROR;
lock = CriticalAreaLock();
idnode = IdGetObj(&k_sem_id_manager, id);
if (idnode == NONE) {
CriticalAreaUnLock(lock);
return -ERROR;
}
sem =CONTAINER_OF(idnode, struct Semaphore, id);
CriticalAreaUnLock(lock);
return done.SemaphoreAbandon(sem);
return done.SemaphoreAbandon(id);
}
/**
@ -310,20 +300,5 @@ int32 KSemaphoreSetValue(int32 id, uint16 val)
{
KDEBUG_NOT_IN_INTERRUPT;
x_base lock = 0;
struct Semaphore *sem = NONE;
struct IdNode *idnode = NONE;
if (id < 0)
return -ERROR;
lock = CriticalAreaLock();
idnode = IdGetObj(&k_sem_id_manager, id);
if (idnode == NONE) {
CriticalAreaUnLock(lock);
return -ERROR;
}
sem = CONTAINER_OF(idnode, struct Semaphore, id);
CriticalAreaUnLock(lock);
return done.SemaphoreSetValue(sem, val);
return done.SemaphoreSetValue(id, val);
}

View File

@ -1 +0,0 @@
##主要撰写和更新EAL6申请过程中的文档