forked from chos/crtos
Compare commits
13 Commits
prepare_fo
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
963da4a27a | |
|
|
b63d5b2b1f | |
|
|
37c97ce2eb | |
|
|
7008ab06b3 | |
|
|
0f8d53f367 | |
|
|
8af1e05656 | |
|
|
aa6318d60f | |
|
|
c39f55325f | |
|
|
4ebe448542 | |
|
|
cf60179805 | |
|
|
0b70e4f18f | |
|
|
fac4d80e9d | |
|
|
ed7f4012da |
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := core_riscv.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := debug.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue