forked from xuos/xiuos
modify XiUOS DIR : (1.add plc_demo in APP_Framework/control_app; 2.add industrial_network、industrial_fieldbus and industrial_wlan; 3.add XiZi_AIoT and modify XiZi as XiZi_IIoT.)
This commit is contained in:
Executable
+41
@@ -0,0 +1,41 @@
|
||||
ifeq ($(CONFIG_BOARD_CH32V307VCT6), )
|
||||
SRC_DIR := shared
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BOARD_FE310_EVB),y)
|
||||
SRC_DIR +=fe310
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BOARD_K210_EVB),y)
|
||||
SRC_DIR +=k210
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BOARD_MAIX_GO_EVB),y)
|
||||
SRC_DIR +=k210
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BOARD_AIIT_RISCV_EVB),y)
|
||||
SRC_DIR +=k210
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BOARD_XIDATONG_RISCV64_EVB),y)
|
||||
SRC_DIR +=k210
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BOARD_GAPUINO),y)
|
||||
SRC_DIR +=gap8
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BOARD_GD32VF103RVSTAR),y)
|
||||
SRC_DIR +=gd32vf103-rvstar
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BOARD_CH32V307VCT6), y)
|
||||
SRC_DIR +=ch32v307vct6
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BOARD_RV32M1_VEGA),y)
|
||||
SRC_DIR +=rv32m1-vega
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := core_riscv.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,558 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : core_riscv.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : RISC-V Core Peripheral Access Layer Source File
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*******************************************************************************/
|
||||
#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
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @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_MIE
|
||||
*
|
||||
* @brief Return the Machine Interrupt Enable Register
|
||||
*
|
||||
* @return mie value
|
||||
*/
|
||||
uint32_t __get_MIE(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mie" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MISA
|
||||
*
|
||||
* @brief Set the Machine ISA Register
|
||||
*
|
||||
* @param value - set mie value
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void __set_MIE(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mie, %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_MTVEC
|
||||
*
|
||||
* @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_MTVEC
|
||||
*
|
||||
* @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_MIP
|
||||
*
|
||||
* @brief Return the Machine Interrupt Pending Register
|
||||
*
|
||||
* @return mip value
|
||||
*/
|
||||
uint32_t __get_MIP(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mip" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MIP
|
||||
*
|
||||
* @brief Set the Machine Interrupt Pending Register
|
||||
*
|
||||
* @return mip value
|
||||
*/
|
||||
void __set_MIP(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mip, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MCYCLE
|
||||
*
|
||||
* @brief Return Lower 32 bits of Cycle counter
|
||||
*
|
||||
* @return mcycle value
|
||||
*/
|
||||
uint32_t __get_MCYCLE(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mcycle" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MCYCLE
|
||||
*
|
||||
* @brief Set Lower 32 bits of Cycle counter
|
||||
*
|
||||
* @return mcycle value
|
||||
*/
|
||||
void __set_MCYCLE(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mcycle, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MCYCLEH
|
||||
*
|
||||
* @brief Return Upper 32 bits of Cycle counter
|
||||
*
|
||||
* @return mcycleh value
|
||||
*/
|
||||
uint32_t __get_MCYCLEH(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mcycleh" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MCYCLEH
|
||||
*
|
||||
* @brief Set Upper 32 bits of Cycle counter
|
||||
*
|
||||
* @return mcycleh value
|
||||
*/
|
||||
void __set_MCYCLEH(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mcycleh, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MINSTRET
|
||||
*
|
||||
* @brief Return Lower 32 bits of Instructions-retired counter
|
||||
*
|
||||
* @return mcause value
|
||||
*/
|
||||
uint32_t __get_MINSTRET(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "minstret" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MINSTRET
|
||||
*
|
||||
* @brief Set Lower 32 bits of Instructions-retired counter
|
||||
*
|
||||
* @return minstret value
|
||||
*/
|
||||
void __set_MINSTRET(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw minstret, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MINSTRETH
|
||||
*
|
||||
* @brief Return Upper 32 bits of Instructions-retired counter
|
||||
*
|
||||
* @return minstreth value
|
||||
*/
|
||||
uint32_t __get_MINSTRETH(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "minstreth" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MINSTRETH
|
||||
*
|
||||
* @brief Set Upper 32 bits of Instructions-retired counter
|
||||
*
|
||||
* @return minstreth value
|
||||
*/
|
||||
void __set_MINSTRETH(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw minstreth, %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 none
|
||||
*
|
||||
* @return Return SP Register
|
||||
*/
|
||||
uint32_t __get_SP(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
asm volatile (
|
||||
"mv %0," "sp"
|
||||
: "=r"(result)
|
||||
:
|
||||
);
|
||||
return (result);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,375 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : core_riscv.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : RISC-V Core Peripheral Access Layer Header File for CH32V30x
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*******************************************************************************/
|
||||
#ifndef __CORE_RISCV_H__
|
||||
#define __CORE_RISCV_H__
|
||||
|
||||
/* IO definitions */
|
||||
#ifdef __cplusplus
|
||||
#define __I volatile /*!< defines 'read only' permissions */
|
||||
#else
|
||||
#define __I volatile const /*!< defines 'read only' permissions */
|
||||
#endif
|
||||
#define __O volatile /*!< defines 'write only' permissions */
|
||||
#define __IO volatile /*!< defines 'read / write' permissions */
|
||||
|
||||
/* 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 {StatERROR = 0, SUCCESS = !StatERROR} 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 Program Fast Interrupt Controller (PFIC) */
|
||||
typedef struct{
|
||||
__I uint32_t ISR[8];
|
||||
__I uint32_t IPR[8];
|
||||
__IO uint32_t ITHRESDR;
|
||||
__IO uint32_t RESERVED;
|
||||
__IO uint32_t CFGR;
|
||||
__I uint32_t GISR;
|
||||
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[0x810];
|
||||
__IO uint32_t SCTLR;
|
||||
}PFIC_Type;
|
||||
|
||||
/* memory mapped structure for SysTick */
|
||||
typedef struct
|
||||
{
|
||||
__IO u32 CTLR;
|
||||
__IO u32 SR;
|
||||
__IO u64 CNT;
|
||||
__IO u64 CMP;
|
||||
}SysTick_Type;
|
||||
|
||||
|
||||
#define PFIC ((PFIC_Type *) 0xE000E000 )
|
||||
#define NVIC PFIC
|
||||
#define NVIC_KEY1 ((uint32_t)0xFA050000)
|
||||
#define NVIC_KEY2 ((uint32_t)0xBCAF0000)
|
||||
#define NVIC_KEY3 ((uint32_t)0xBEEF0000)
|
||||
|
||||
#define SysTick ((SysTick_Type *) 0xE000F000)
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __enable_irq
|
||||
*
|
||||
* @brief Enable Global Interrupt
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
RV_STATIC_INLINE void __enable_irq() { __asm volatile ("csrw 0x800, %0" : : "r" (0x6088) ); }
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __disable_irq
|
||||
*
|
||||
* @brief Disable Global Interrupt
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
RV_STATIC_INLINE void __disable_irq() { __asm volatile ("csrw 0x800, %0" : : "r" (0x6000) ); }
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __NOP
|
||||
*
|
||||
* @brief nop
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
RV_STATIC_INLINE void __NOP() { __asm volatile ("nop"); }
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_EnableIRQ
|
||||
*
|
||||
* @brief Enable Interrupt
|
||||
*
|
||||
* @param IRQn: Interrupt Numbers
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
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
|
||||
*/
|
||||
RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_GetStatusIRQ
|
||||
*
|
||||
* @brief Get Interrupt Enable State
|
||||
*
|
||||
* @param IRQn: Interrupt Numbers
|
||||
*
|
||||
* @return 1 - Interrupt Enable
|
||||
* 0 - Interrupt Disable
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
* priority -
|
||||
* bit7 - pre-emption priority
|
||||
* bit6~bit4 - subpriority
|
||||
* @return None
|
||||
*/
|
||||
RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority)
|
||||
{
|
||||
NVIC->IPRIOR[(uint32_t)(IRQn)] = priority;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @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 __WFE
|
||||
*
|
||||
* @brief Wait for Events
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void)
|
||||
{
|
||||
uint32_t t;
|
||||
|
||||
t = NVIC->SCTLR;
|
||||
NVIC->SCTLR |= (1<<3)|(1<<5); // (wfi->wfe)+(__sev)
|
||||
NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5));
|
||||
asm volatile ("wfi");
|
||||
asm volatile ("wfi");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetVTFIRQ
|
||||
*
|
||||
* @brief Set VTF Interrupt
|
||||
*
|
||||
* @param add - VTF interrupt service function base address.
|
||||
* IRQn -Interrupt Numbers
|
||||
* num - VTF Interrupt Numbers
|
||||
* NewState - DISABLE or ENABLE
|
||||
* @return None
|
||||
*/
|
||||
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&0xF00FFFFE)|0x1);
|
||||
}
|
||||
else{
|
||||
NVIC->VTFIDR[num] = IRQn;
|
||||
NVIC->VTFADDR[num] = ((addr&0xF00FFFFE)&(~0x1));
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_SystemReset
|
||||
*
|
||||
* @brief Initiate a system reset request
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
RV_STATIC_INLINE void NVIC_SystemReset(void)
|
||||
{
|
||||
NVIC->CFGR = NVIC_KEY3|(1<<7);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 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_MIE(void);
|
||||
extern void __set_MIE(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_MIP(void);
|
||||
extern void __set_MIP(uint32_t value);
|
||||
extern uint32_t __get_MCYCLE(void);
|
||||
extern void __set_MCYCLE(uint32_t value);
|
||||
extern uint32_t __get_MCYCLEH(void);
|
||||
extern void __set_MCYCLEH(uint32_t value);
|
||||
extern uint32_t __get_MINSTRET(void);
|
||||
extern void __set_MINSTRET(uint32_t value);
|
||||
extern uint32_t __get_MINSTRETH(void);
|
||||
extern void __set_MINSTRETH(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);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := debug.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,201 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : debug.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : This file contains all the functions prototypes for UART
|
||||
* Printf , Delay functions.
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*******************************************************************************/
|
||||
/*************************************************
|
||||
File name: debug.c
|
||||
Description: support some basic functions for ch32v30x
|
||||
History:
|
||||
1. Date: 2022-08-09
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
*************************************************/
|
||||
#include "debug.h"
|
||||
|
||||
static uint8_t p_us = 0;
|
||||
static uint16_t p_ms = 0;
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Delay_Init
|
||||
*
|
||||
* @brief Initializes Delay Funcation.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void Delay_Init(void)
|
||||
{
|
||||
p_us = SystemCoreClock / 8000000;
|
||||
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;
|
||||
|
||||
SysTick->SR &= ~(1 << 0);
|
||||
i = (uint32_t)n * p_us;
|
||||
|
||||
SysTick->CMP = i;
|
||||
SysTick->CTLR |= (1 << 4) | (1 << 5) | (1 << 0);
|
||||
|
||||
while((SysTick->SR & (1 << 0)) != (1 << 0))
|
||||
;
|
||||
SysTick->CTLR &= ~(1 << 0);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Delay_Ms
|
||||
*
|
||||
* @brief Millisecond Delay Time.
|
||||
*
|
||||
* @param n - Millisecond number.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void Delay_Ms(uint32_t n)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
SysTick->SR &= ~(1 << 0);
|
||||
i = (uint32_t)n * p_ms;
|
||||
|
||||
SysTick->CMP = i;
|
||||
SysTick->CTLR |= (1 << 4) | (1 << 5) | (1 << 0);
|
||||
|
||||
while((SysTick->SR & (1 << 0)) != (1 << 0))
|
||||
;
|
||||
SysTick->CTLR &= ~(1 << 0);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @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;
|
||||
USART_InitTypeDef USART_InitStructure;
|
||||
|
||||
#if(DEBUG == DEBUG_UART1)
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
#elif(DEBUG == DEBUG_UART2)
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
#elif(DEBUG == DEBUG_UART3)
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
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_UART2)
|
||||
USART_Init(USART2, &USART_InitStructure);
|
||||
USART_Cmd(USART2, ENABLE);
|
||||
|
||||
#elif(DEBUG == DEBUG_UART3)
|
||||
USART_Init(USART3, &USART_InitStructure);
|
||||
USART_Cmd(USART3, 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;
|
||||
|
||||
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_UART2)
|
||||
while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
|
||||
USART_SendData(USART2, *buf++);
|
||||
#elif(DEBUG == DEBUG_UART3)
|
||||
while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
|
||||
USART_SendData(USART3, *buf++);
|
||||
#endif
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn _sbrk
|
||||
*
|
||||
* @brief Change the spatial position of data segment.
|
||||
*
|
||||
* @return size: Data length
|
||||
*/
|
||||
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,45 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : debug.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : This file contains all the functions prototypes for UART
|
||||
* Printf , Delay functions.
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*******************************************************************************/
|
||||
/*************************************************
|
||||
File name: debug.h
|
||||
Description: support some basic functions for ch32v30x
|
||||
History:
|
||||
1. Date: 2022-08-09
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
*************************************************/
|
||||
|
||||
#ifndef __DEBUG_H
|
||||
#define __DEBUG_H
|
||||
|
||||
#include "stdio.h"
|
||||
#include "ch32v30x.h"
|
||||
|
||||
/* UART Printf Definition */
|
||||
#define DEBUG_UART1 1
|
||||
#define DEBUG_UART2 2
|
||||
#define DEBUG_UART3 3
|
||||
|
||||
/* DEBUG UATR Definition */
|
||||
#define DEBUG DEBUG_UART1
|
||||
//#define DEBUG DEBUG_UART2
|
||||
//#define DEBUG DEBUG_UART3
|
||||
|
||||
|
||||
void Delay_Init(void);
|
||||
void Delay_Us (uint32_t n);
|
||||
void Delay_Ms (uint32_t n);
|
||||
void USART_Printf_Init(uint32_t baudrate);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
SRC_FILES := boot.S interrupt.c tick.c switch.S prepare_rhwstack.c interrupt_switch.S
|
||||
SRC_DIR := Core User Debug
|
||||
# interrupt_switch.S
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := ch32v30x_it.c system_ch32v30x.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,51 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v30x_conf.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : Library configuration file.
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*******************************************************************************/
|
||||
/*************************************************
|
||||
File name: ch32v30x_conf.h
|
||||
Description: include peripheral supports for ch32v30x
|
||||
History:
|
||||
1. Date: 2022-08-09
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
*************************************************/
|
||||
#ifndef __CH32V30x_CONF_H
|
||||
#define __CH32V30x_CONF_H
|
||||
|
||||
#include "ch32v30x_adc.h"
|
||||
#include "ch32v30x_bkp.h"
|
||||
#include "ch32v30x_can.h"
|
||||
#include "ch32v30x_crc.h"
|
||||
#include "ch32v30x_dac.h"
|
||||
#include "ch32v30x_dbgmcu.h"
|
||||
#include "ch32v30x_dma.h"
|
||||
#include "ch32v30x_exti.h"
|
||||
#include "ch32v30x_flash.h"
|
||||
#include "ch32v30x_fsmc.h"
|
||||
#include "ch32v30x_gpio.h"
|
||||
#include "ch32v30x_i2c.h"
|
||||
#include "ch32v30x_iwdg.h"
|
||||
#include "ch32v30x_pwr.h"
|
||||
#include "ch32v30x_rcc.h"
|
||||
#include "ch32v30x_rtc.h"
|
||||
#include "ch32v30x_sdio.h"
|
||||
#include "ch32v30x_spi.h"
|
||||
#include "ch32v30x_tim.h"
|
||||
#include "ch32v30x_usart.h"
|
||||
#include "ch32v30x_wwdg.h"
|
||||
#include "ch32v30x_it.h"
|
||||
#include "ch32v30x_misc.h"
|
||||
|
||||
|
||||
#endif /* __CH32V30x_CONF_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v10x_it.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2020/04/30
|
||||
* Description : Main Interrupt Service Routines.
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*******************************************************************************/
|
||||
/*************************************************
|
||||
File name: ch32v30x_it.c
|
||||
Description: include peripheral supports for ch32v30x
|
||||
History:
|
||||
1. Date: 2022-08-09
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. add HardFault interrupt implementation.
|
||||
*************************************************/
|
||||
#include "ch32v30x_it.h"
|
||||
#include "board.h"
|
||||
#include <xs_isr.h>
|
||||
|
||||
|
||||
|
||||
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NMI_Handler
|
||||
*
|
||||
* @brief This function handles NMI exception.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
GET_INT_SP();
|
||||
isrManager.done->incCounter();
|
||||
KPrintf("NMI_Handler.\n");
|
||||
isrManager.done->decCounter();
|
||||
FREE_INT_SP();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn HardFault_Handler
|
||||
*
|
||||
* @brief This function handles Hard Fault exception.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
GET_INT_SP();
|
||||
isrManager.done->incCounter();
|
||||
KPrintf("HardFault_Handler.\n");
|
||||
isrManager.done->decCounter();
|
||||
FREE_INT_SP();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v30x_it.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : This file contains the headers of the interrupt handlers.
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*******************************************************************************/
|
||||
#ifndef __CH32V30x_IT_H
|
||||
#define __CH32V30x_IT_H
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#define GET_INT_SP() asm("csrrw sp,mscratch,sp")
|
||||
#define FREE_INT_SP() asm("csrrw sp,mscratch,sp")
|
||||
|
||||
|
||||
#endif /* __CH32V30x_IT_H */
|
||||
|
||||
|
||||
@@ -0,0 +1,776 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v30x.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V30x Device Peripheral Access Layer System Source File.
|
||||
* For HSE = 8Mhz
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*********************************************************************************/
|
||||
#include "ch32v30x.h"
|
||||
|
||||
/*
|
||||
* Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after
|
||||
* reset the HSI is used as SYSCLK source).
|
||||
* If none of the define below is enabled, the HSI is used as System clock source.
|
||||
*/
|
||||
// #define SYSCLK_FREQ_HSE HSE_VALUE
|
||||
/* #define SYSCLK_FREQ_24MHz 24000000 */
|
||||
//#define SYSCLK_FREQ_48MHz 48000000
|
||||
/* #define SYSCLK_FREQ_56MHz 56000000 */
|
||||
//#define SYSCLK_FREQ_72MHz 72000000
|
||||
//#define SYSCLK_FREQ_96MHz 96000000
|
||||
//#define SYSCLK_FREQ_120MHz 120000000
|
||||
#define SYSCLK_FREQ_144MHz 144000000
|
||||
|
||||
/* Clock Definitions */
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_24MHz
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_48MHz
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_56MHz
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_72MHz
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_120MHz
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_144MHz
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
#else /* HSI Selected as System Clock source */
|
||||
uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */
|
||||
#endif
|
||||
|
||||
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
|
||||
|
||||
/* system_private_function_proto_types */
|
||||
static void SetSysClock(void);
|
||||
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
static void SetSysClockToHSE(void);
|
||||
#elif defined SYSCLK_FREQ_24MHz
|
||||
static void SetSysClockTo24(void);
|
||||
#elif defined SYSCLK_FREQ_48MHz
|
||||
static void SetSysClockTo48(void);
|
||||
#elif defined SYSCLK_FREQ_56MHz
|
||||
static void SetSysClockTo56(void);
|
||||
#elif defined SYSCLK_FREQ_72MHz
|
||||
static void SetSysClockTo72(void);
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz
|
||||
static void SetSysClockTo96(void);
|
||||
#elif defined SYSCLK_FREQ_120MHz
|
||||
static void SetSysClockTo120(void);
|
||||
#elif defined SYSCLK_FREQ_144MHz
|
||||
static void SetSysClockTo144(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SystemInit
|
||||
*
|
||||
* @brief Setup the microcontroller system Initialize the Embedded Flash Interface,
|
||||
* the PLL and update the SystemCoreClock variable.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
RCC->CTLR |= (uint32_t)0x00000001;
|
||||
|
||||
#ifdef CH32V30x_D8C
|
||||
RCC->CFGR0 &= (uint32_t)0xF8FF0000;
|
||||
#else
|
||||
RCC->CFGR0 &= (uint32_t)0xF0FF0000;
|
||||
#endif
|
||||
|
||||
RCC->CTLR &= (uint32_t)0xFEF6FFFF;
|
||||
RCC->CTLR &= (uint32_t)0xFFFBFFFF;
|
||||
RCC->CFGR0 &= (uint32_t)0xFF80FFFF;
|
||||
|
||||
#ifdef CH32V30x_D8C
|
||||
RCC->CTLR &= (uint32_t)0xEBFFFFFF;
|
||||
RCC->INTR = 0x00FF0000;
|
||||
RCC->CFGR2 = 0x00000000;
|
||||
#else
|
||||
RCC->INTR = 0x009F0000;
|
||||
#endif
|
||||
SetSysClock();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SystemCoreClockUpdate
|
||||
*
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
uint32_t tmp = 0, pllmull = 0, pllsource = 0, Pll_6_5 = 0;
|
||||
|
||||
tmp = RCC->CFGR0 & RCC_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case 0x00:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case 0x04:
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case 0x08:
|
||||
pllmull = RCC->CFGR0 & RCC_PLLMULL;
|
||||
pllsource = RCC->CFGR0 & RCC_PLLSRC;
|
||||
pllmull = ( pllmull >> 18) + 2;
|
||||
|
||||
#ifdef CH32V30x_D8
|
||||
if(pllmull == 17) pllmull = 18;
|
||||
#else
|
||||
if(pllmull == 2) pllmull = 18;
|
||||
if(pllmull == 15){
|
||||
pllmull = 13; /* *6.5 */
|
||||
Pll_6_5 = 1;
|
||||
}
|
||||
if(pllmull == 16) pllmull = 15;
|
||||
if(pllmull == 17) pllmull = 16;
|
||||
#endif
|
||||
|
||||
if (pllsource == 0x00)
|
||||
{
|
||||
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET)
|
||||
{
|
||||
SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemCoreClock = HSE_VALUE * pllmull;
|
||||
}
|
||||
}
|
||||
|
||||
if(Pll_6_5 == 1) SystemCoreClock = (SystemCoreClock / 2);
|
||||
|
||||
break;
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)];
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClock
|
||||
*
|
||||
* @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClock(void)
|
||||
{
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
SetSysClockToHSE();
|
||||
#elif defined SYSCLK_FREQ_24MHz
|
||||
SetSysClockTo24();
|
||||
#elif defined SYSCLK_FREQ_48MHz
|
||||
SetSysClockTo48();
|
||||
#elif defined SYSCLK_FREQ_56MHz
|
||||
SetSysClockTo56();
|
||||
#elif defined SYSCLK_FREQ_72MHz
|
||||
SetSysClockTo72();
|
||||
#elif defined SYSCLK_FREQ_96MHz
|
||||
SetSysClockTo96();
|
||||
#elif defined SYSCLK_FREQ_120MHz
|
||||
SetSysClockTo120();
|
||||
#elif defined SYSCLK_FREQ_144MHz
|
||||
SetSysClockTo144();
|
||||
|
||||
#endif
|
||||
|
||||
/* If none of the define above is enabled, the HSI is used as System clock
|
||||
* source (default after reset)
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockToHSE
|
||||
*
|
||||
* @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockToHSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
|
||||
|
||||
/* Select HSE as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_HSE;
|
||||
|
||||
/* Wait till HSE is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_24MHz
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo24
|
||||
*
|
||||
* @brief Sets System clock frequency to 24MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo24(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
|
||||
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
#ifdef CH32V30x_D8
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL3);
|
||||
#else
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL3_EXTEN);
|
||||
#endif
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_48MHz
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo48
|
||||
*
|
||||
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo48(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
#ifdef CH32V30x_D8
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6);
|
||||
#else
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6_EXTEN);
|
||||
#endif
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_56MHz
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo56
|
||||
*
|
||||
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo56(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
#ifdef CH32V30x_D8
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7);
|
||||
#else
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7_EXTEN);
|
||||
#endif
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_72MHz
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo72
|
||||
*
|
||||
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo72(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
#ifdef CH32V30x_D8
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9);
|
||||
#else
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9_EXTEN);
|
||||
#endif
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo96
|
||||
*
|
||||
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo96(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSE * 12 = 96 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
#ifdef CH32V30x_D8
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12);
|
||||
#else
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12_EXTEN);
|
||||
#endif
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_120MHz
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo120
|
||||
*
|
||||
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo120(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSE * 15 = 120 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
#ifdef CH32V30x_D8
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15);
|
||||
#else
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15_EXTEN);
|
||||
#endif
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_144MHz
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo144
|
||||
*
|
||||
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo144(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSE * 18 = 144 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
#ifdef CH32V30x_D8
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18);
|
||||
#else
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18_EXTEN);
|
||||
#endif
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v30x.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V30x Device Peripheral Access Layer System Header File.
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*******************************************************************************/
|
||||
#ifndef __SYSTEM_CH32V30x_H
|
||||
#define __SYSTEM_CH32V30x_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include<stdint.h>
|
||||
extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
/* System_Exported_Functions */
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__CH32V30x_SYSTEM_H */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef ARCH_INTERRUPT_H__
|
||||
#define ARCH_INTERRUPT_H__
|
||||
|
||||
#include "ch32v30x.h"
|
||||
#include "core_riscv.h"
|
||||
|
||||
#define ARCH_MAX_IRQ_NUM 128
|
||||
#define ARCH_IRQ_NUM_OFFSET 0
|
||||
|
||||
int ArchEnableHwIrq(uint32_t irq_num);
|
||||
int ArchDisableHwIrq(uint32_t irq_num);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,389 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : boot.S
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V30x vector table for eclipse toolchain.
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*******************************************************************************/
|
||||
|
||||
.section .init,"ax",@progbits
|
||||
.global _start
|
||||
.align 1
|
||||
_start:
|
||||
j handle_reset
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00100073
|
||||
.section .vector,"ax",@progbits
|
||||
.align 1
|
||||
_vector_base:
|
||||
.option norvc;
|
||||
.word _start
|
||||
.word 0
|
||||
.word NMI_Handler /* NMI */
|
||||
.word HardFault_Handler /* Hard Fault */
|
||||
.word 0
|
||||
.word Ecall_M_Mode_Handler /* Ecall M Mode */
|
||||
.word 0
|
||||
.word 0
|
||||
.word Ecall_U_Mode_Handler /* Ecall U Mode */
|
||||
.word Break_Point_Handler /* Break Point */
|
||||
.word 0
|
||||
.word 0
|
||||
.word SysTick_Handler /* SysTick */
|
||||
.word 0
|
||||
.word SW_handler /* SW */
|
||||
.word 0
|
||||
/* External Interrupts */
|
||||
.word WWDG_IRQHandler /* Window Watchdog */
|
||||
.word PVD_IRQHandler /* PVD through EXTI Line detect */
|
||||
.word TAMPER_IRQHandler /* TAMPER */
|
||||
.word RTC_IRQHandler /* RTC */
|
||||
.word FLASH_IRQHandler /* Flash */
|
||||
.word RCC_IRQHandler /* RCC */
|
||||
.word EXTI0_IRQHandler /* EXTI Line 0 */
|
||||
.word EXTI1_IRQHandler /* EXTI Line 1 */
|
||||
.word EXTI2_IRQHandler /* EXTI Line 2 */
|
||||
.word EXTI3_IRQHandler /* EXTI Line 3 */
|
||||
.word EXTI4_IRQHandler /* EXTI Line 4 */
|
||||
.word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
|
||||
.word DMA1_Channel2_IRQHandler /* DMA1 Channel 2 */
|
||||
.word DMA1_Channel3_IRQHandler /* DMA1 Channel 3 */
|
||||
.word DMA1_Channel4_IRQHandler /* DMA1 Channel 4 */
|
||||
.word DMA1_Channel5_IRQHandler /* DMA1 Channel 5 */
|
||||
.word DMA1_Channel6_IRQHandler /* DMA1 Channel 6 */
|
||||
.word DMA1_Channel7_IRQHandler /* DMA1 Channel 7 */
|
||||
.word ADC1_2_IRQHandler /* ADC1_2 */
|
||||
.word USB_HP_CAN1_TX_IRQHandler /* USB HP and CAN1 TX */
|
||||
.word USB_LP_CAN1_RX0_IRQHandler /* USB LP and CAN1RX0 */
|
||||
.word CAN1_RX1_IRQHandler /* CAN1 RX1 */
|
||||
.word CAN1_SCE_IRQHandler /* CAN1 SCE */
|
||||
.word EXTI9_5_IRQHandler /* EXTI Line 9..5 */
|
||||
.word TIM1_BRK_IRQHandler /* TIM1 Break */
|
||||
.word TIM1_UP_IRQHandler /* TIM1 Update */
|
||||
.word TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */
|
||||
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
|
||||
.word TIM2_IRQHandler /* TIM2 */
|
||||
.word TIM3_IRQHandler /* TIM3 */
|
||||
.word TIM4_IRQHandler /* TIM4 */
|
||||
.word I2C1_EV_IRQHandler /* I2C1 Event */
|
||||
.word I2C1_ER_IRQHandler /* I2C1 Error */
|
||||
.word I2C2_EV_IRQHandler /* I2C2 Event */
|
||||
.word I2C2_ER_IRQHandler /* I2C2 Error */
|
||||
.word SPI1_IRQHandler /* SPI1 */
|
||||
.word SPI2_IRQHandler /* SPI2 */
|
||||
.word USART1_IRQHandler /* USART1 */
|
||||
.word USART2_IRQHandler /* USART2 */
|
||||
.word USART3_IRQHandler /* USART3 */
|
||||
.word EXTI15_10_IRQHandler /* EXTI Line 15..10 */
|
||||
.word RTCAlarm_IRQHandler /* RTC Alarm through EXTI Line */
|
||||
.word USBWakeUp_IRQHandler /* USB Wakeup from suspend */
|
||||
.word TIM8_BRK_IRQHandler /* TIM8 Break */
|
||||
.word TIM8_UP_IRQHandler /* TIM8 Update */
|
||||
.word TIM8_TRG_COM_IRQHandler /* TIM8 Trigger and Commutation */
|
||||
.word TIM8_CC_IRQHandler /* TIM8 Capture Compare */
|
||||
.word RNG_IRQHandler /* RNG */
|
||||
.word FSMC_IRQHandler /* FSMC */
|
||||
.word SDIO_IRQHandler /* SDIO */
|
||||
.word TIM5_IRQHandler /* TIM5 */
|
||||
.word SPI3_IRQHandler /* SPI3 */
|
||||
.word UART4_IRQHandler /* UART4 */
|
||||
.word UART5_IRQHandler /* UART5 */
|
||||
.word TIM6_IRQHandler /* TIM6 */
|
||||
.word TIM7_IRQHandler /* TIM7 */
|
||||
.word DMA2_Channel1_IRQHandler /* DMA2 Channel 1 */
|
||||
.word DMA2_Channel2_IRQHandler /* DMA2 Channel 2 */
|
||||
.word DMA2_Channel3_IRQHandler /* DMA2 Channel 3 */
|
||||
.word DMA2_Channel4_IRQHandler /* DMA2 Channel 4 */
|
||||
.word DMA2_Channel5_IRQHandler /* DMA2 Channel 5 */
|
||||
.word ETH_IRQHandler /* ETH */
|
||||
.word ETH_WKUP_IRQHandler /* ETH WakeUp */
|
||||
.word CAN2_TX_IRQHandler /* CAN2 TX */
|
||||
.word CAN2_RX0_IRQHandler /* CAN2 RX0 */
|
||||
.word CAN2_RX1_IRQHandler /* CAN2 RX1 */
|
||||
.word CAN2_SCE_IRQHandler /* CAN2 SCE */
|
||||
.word OTG_FS_IRQHandler /* OTGFS */
|
||||
.word USBHSWakeup_IRQHandler /* USBHS Wakeup */
|
||||
.word USBHS_IRQHandler /* USBHS */
|
||||
.word DVP_IRQHandler /* DVP */
|
||||
.word UART6_IRQHandler /* UART6 */
|
||||
.word UART7_IRQHandler /* UART7 */
|
||||
.word UART8_IRQHandler /* UART8 */
|
||||
.word TIM9_BRK_IRQHandler /* TIM9 Break */
|
||||
.word TIM9_UP_IRQHandler /* TIM9 Update */
|
||||
.word TIM9_TRG_COM_IRQHandler /* TIM9 Trigger and Commutation */
|
||||
.word TIM9_CC_IRQHandler /* TIM9 Capture Compare */
|
||||
.word TIM10_BRK_IRQHandler /* TIM10 Break */
|
||||
.word TIM10_UP_IRQHandler /* TIM10 Update */
|
||||
.word TIM10_TRG_COM_IRQHandler /* TIM10 Trigger and Commutation */
|
||||
.word TIM10_CC_IRQHandler /* TIM10 Capture Compare */
|
||||
.word DMA2_Channel6_IRQHandler /* DMA2 Channel 6 */
|
||||
.word DMA2_Channel7_IRQHandler /* DMA2 Channel 7 */
|
||||
.word DMA2_Channel8_IRQHandler /* DMA2 Channel 8 */
|
||||
.word DMA2_Channel9_IRQHandler /* DMA2 Channel 9 */
|
||||
.word DMA2_Channel10_IRQHandler /* DMA2 Channel 10 */
|
||||
.word DMA2_Channel11_IRQHandler /* DMA2 Channel 11 */
|
||||
|
||||
.option rvc;
|
||||
|
||||
.section .text.vector_handler, "ax", @progbits
|
||||
.weak NMI_Handler /* NMI */
|
||||
.weak HardFault_Handler /* Hard Fault */
|
||||
.weak Ecall_M_Mode_Handler /* Ecall M Mode */
|
||||
.weak Ecall_U_Mode_Handler /* Ecall U Mode */
|
||||
.weak Break_Point_Handler /* Break Point */
|
||||
.weak SysTick_Handler /* SysTick */
|
||||
.weak SW_handler /* SW */
|
||||
.weak WWDG_IRQHandler /* Window Watchdog */
|
||||
.weak PVD_IRQHandler /* PVD through EXTI Line detect */
|
||||
.weak TAMPER_IRQHandler /* TAMPER */
|
||||
.weak RTC_IRQHandler /* RTC */
|
||||
.weak FLASH_IRQHandler /* Flash */
|
||||
.weak RCC_IRQHandler /* RCC */
|
||||
.weak EXTI0_IRQHandler /* EXTI Line 0 */
|
||||
.weak EXTI1_IRQHandler /* EXTI Line 1 */
|
||||
.weak EXTI2_IRQHandler /* EXTI Line 2 */
|
||||
.weak EXTI3_IRQHandler /* EXTI Line 3 */
|
||||
.weak EXTI4_IRQHandler /* EXTI Line 4 */
|
||||
.weak DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
|
||||
.weak DMA1_Channel2_IRQHandler /* DMA1 Channel 2 */
|
||||
.weak DMA1_Channel3_IRQHandler /* DMA1 Channel 3 */
|
||||
.weak DMA1_Channel4_IRQHandler /* DMA1 Channel 4 */
|
||||
.weak DMA1_Channel5_IRQHandler /* DMA1 Channel 5 */
|
||||
.weak DMA1_Channel6_IRQHandler /* DMA1 Channel 6 */
|
||||
.weak DMA1_Channel7_IRQHandler /* DMA1 Channel 7 */
|
||||
.weak ADC1_2_IRQHandler /* ADC1_2 */
|
||||
.weak USB_HP_CAN1_TX_IRQHandler /* USB HP and CAN1 TX */
|
||||
.weak USB_LP_CAN1_RX0_IRQHandler /* USB LP and CAN1RX0 */
|
||||
.weak CAN1_RX1_IRQHandler /* CAN1 RX1 */
|
||||
.weak CAN1_SCE_IRQHandler /* CAN1 SCE */
|
||||
.weak EXTI9_5_IRQHandler /* EXTI Line 9..5 */
|
||||
.weak TIM1_BRK_IRQHandler /* TIM1 Break */
|
||||
.weak TIM1_UP_IRQHandler /* TIM1 Update */
|
||||
.weak TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */
|
||||
.weak TIM1_CC_IRQHandler /* TIM1 Capture Compare */
|
||||
.weak TIM2_IRQHandler /* TIM2 */
|
||||
.weak TIM3_IRQHandler /* TIM3 */
|
||||
.weak TIM4_IRQHandler /* TIM4 */
|
||||
.weak I2C1_EV_IRQHandler /* I2C1 Event */
|
||||
.weak I2C1_ER_IRQHandler /* I2C1 Error */
|
||||
.weak I2C2_EV_IRQHandler /* I2C2 Event */
|
||||
.weak I2C2_ER_IRQHandler /* I2C2 Error */
|
||||
.weak SPI1_IRQHandler /* SPI1 */
|
||||
.weak SPI2_IRQHandler /* SPI2 */
|
||||
.weak USART1_IRQHandler /* USART1 */
|
||||
.weak USART2_IRQHandler /* USART2 */
|
||||
.weak USART3_IRQHandler /* USART3 */
|
||||
.weak EXTI15_10_IRQHandler /* EXTI Line 15..10 */
|
||||
.weak RTCAlarm_IRQHandler /* RTC Alarm through EXTI Line */
|
||||
.weak USBWakeUp_IRQHandler /* USB Wakeup from suspend */
|
||||
.weak TIM8_BRK_IRQHandler /* TIM8 Break */
|
||||
.weak TIM8_UP_IRQHandler /* TIM8 Update */
|
||||
.weak TIM8_TRG_COM_IRQHandler /* TIM8 Trigger and Commutation */
|
||||
.weak TIM8_CC_IRQHandler /* TIM8 Capture Compare */
|
||||
.weak RNG_IRQHandler /* RNG */
|
||||
.weak FSMC_IRQHandler /* FSMC */
|
||||
.weak SDIO_IRQHandler /* SDIO */
|
||||
.weak TIM5_IRQHandler /* TIM5 */
|
||||
.weak SPI3_IRQHandler /* SPI3 */
|
||||
.weak UART4_IRQHandler /* UART4 */
|
||||
.weak UART5_IRQHandler /* UART5 */
|
||||
.weak TIM6_IRQHandler /* TIM6 */
|
||||
.weak TIM7_IRQHandler /* TIM7 */
|
||||
.weak DMA2_Channel1_IRQHandler /* DMA2 Channel 1 */
|
||||
.weak DMA2_Channel2_IRQHandler /* DMA2 Channel 2 */
|
||||
.weak DMA2_Channel3_IRQHandler /* DMA2 Channel 3 */
|
||||
.weak DMA2_Channel4_IRQHandler /* DMA2 Channel 4 */
|
||||
.weak DMA2_Channel5_IRQHandler /* DMA2 Channel 5 */
|
||||
.weak ETH_IRQHandler /* ETH */
|
||||
.weak ETH_WKUP_IRQHandler /* ETH WakeUp */
|
||||
.weak CAN2_TX_IRQHandler /* CAN2 TX */
|
||||
.weak CAN2_RX0_IRQHandler /* CAN2 RX0 */
|
||||
.weak CAN2_RX1_IRQHandler /* CAN2 RX1 */
|
||||
.weak CAN2_SCE_IRQHandler /* CAN2 SCE */
|
||||
.weak OTG_FS_IRQHandler /* OTGFS */
|
||||
.weak USBHSWakeup_IRQHandler /* USBHS Wakeup */
|
||||
.weak USBHS_IRQHandler /* USBHS */
|
||||
.weak DVP_IRQHandler /* DVP */
|
||||
.weak UART6_IRQHandler /* UART6 */
|
||||
.weak UART7_IRQHandler /* UART7 */
|
||||
.weak UART8_IRQHandler /* UART8 */
|
||||
.weak TIM9_BRK_IRQHandler /* TIM9 Break */
|
||||
.weak TIM9_UP_IRQHandler /* TIM9 Update */
|
||||
.weak TIM9_TRG_COM_IRQHandler /* TIM9 Trigger and Commutation */
|
||||
.weak TIM9_CC_IRQHandler /* TIM9 Capture Compare */
|
||||
.weak TIM10_BRK_IRQHandler /* TIM10 Break */
|
||||
.weak TIM10_UP_IRQHandler /* TIM10 Update */
|
||||
.weak TIM10_TRG_COM_IRQHandler /* TIM10 Trigger and Commutation */
|
||||
.weak TIM10_CC_IRQHandler /* TIM10 Capture Compare */
|
||||
.weak DMA2_Channel6_IRQHandler /* DMA2 Channel 6 */
|
||||
.weak DMA2_Channel7_IRQHandler /* DMA2 Channel 7 */
|
||||
.weak DMA2_Channel8_IRQHandler /* DMA2 Channel 8 */
|
||||
.weak DMA2_Channel9_IRQHandler /* DMA2 Channel 9 */
|
||||
.weak DMA2_Channel10_IRQHandler /* DMA2 Channel 10 */
|
||||
.weak DMA2_Channel11_IRQHandler /* DMA2 Channel 11 */
|
||||
|
||||
NMI_Handler: 1: j 1b
|
||||
HardFault_Handler: 1: j 1b
|
||||
Ecall_M_Mode_Handler: 1: j 1b
|
||||
Ecall_U_Mode_Handler: 1: j 1b
|
||||
Break_Point_Handler: 1: j 1b
|
||||
SysTick_Handler: 1: j 1b
|
||||
SW_handler: 1: j 1b
|
||||
WWDG_IRQHandler: 1: j 1b
|
||||
PVD_IRQHandler: 1: j 1b
|
||||
TAMPER_IRQHandler: 1: j 1b
|
||||
RTC_IRQHandler: 1: j 1b
|
||||
FLASH_IRQHandler: 1: j 1b
|
||||
RCC_IRQHandler: 1: j 1b
|
||||
EXTI0_IRQHandler: 1: j 1b
|
||||
EXTI1_IRQHandler: 1: j 1b
|
||||
EXTI2_IRQHandler: 1: j 1b
|
||||
EXTI3_IRQHandler: 1: j 1b
|
||||
EXTI4_IRQHandler: 1: j 1b
|
||||
DMA1_Channel1_IRQHandler: 1: j 1b
|
||||
DMA1_Channel2_IRQHandler: 1: j 1b
|
||||
DMA1_Channel3_IRQHandler: 1: j 1b
|
||||
DMA1_Channel4_IRQHandler: 1: j 1b
|
||||
DMA1_Channel5_IRQHandler: 1: j 1b
|
||||
DMA1_Channel6_IRQHandler: 1: j 1b
|
||||
DMA1_Channel7_IRQHandler: 1: j 1b
|
||||
ADC1_2_IRQHandler: 1: j 1b
|
||||
USB_HP_CAN1_TX_IRQHandler: 1: j 1b
|
||||
USB_LP_CAN1_RX0_IRQHandler: 1: j 1b
|
||||
CAN1_RX1_IRQHandler: 1: j 1b
|
||||
CAN1_SCE_IRQHandler: 1: j 1b
|
||||
EXTI9_5_IRQHandler: 1: j 1b
|
||||
TIM1_BRK_IRQHandler: 1: j 1b
|
||||
TIM1_UP_IRQHandler: 1: j 1b
|
||||
TIM1_TRG_COM_IRQHandler: 1: j 1b
|
||||
TIM1_CC_IRQHandler: 1: j 1b
|
||||
TIM2_IRQHandler: 1: j 1b
|
||||
TIM3_IRQHandler: 1: j 1b
|
||||
TIM4_IRQHandler: 1: j 1b
|
||||
I2C1_EV_IRQHandler: 1: j 1b
|
||||
I2C1_ER_IRQHandler: 1: j 1b
|
||||
I2C2_EV_IRQHandler: 1: j 1b
|
||||
I2C2_ER_IRQHandler: 1: j 1b
|
||||
SPI1_IRQHandler: 1: j 1b
|
||||
SPI2_IRQHandler: 1: j 1b
|
||||
USART1_IRQHandler: 1: j 1b
|
||||
USART2_IRQHandler: 1: j 1b
|
||||
USART3_IRQHandler: 1: j 1b
|
||||
EXTI15_10_IRQHandler: 1: j 1b
|
||||
RTCAlarm_IRQHandler: 1: j 1b
|
||||
USBWakeUp_IRQHandler: 1: j 1b
|
||||
TIM8_BRK_IRQHandler: 1: j 1b
|
||||
TIM8_UP_IRQHandler: 1: j 1b
|
||||
TIM8_TRG_COM_IRQHandler: 1: j 1b
|
||||
TIM8_CC_IRQHandler: 1: j 1b
|
||||
RNG_IRQHandler: 1: j 1b
|
||||
FSMC_IRQHandler: 1: j 1b
|
||||
SDIO_IRQHandler: 1: j 1b
|
||||
TIM5_IRQHandler: 1: j 1b
|
||||
SPI3_IRQHandler: 1: j 1b
|
||||
UART4_IRQHandler: 1: j 1b
|
||||
UART5_IRQHandler: 1: j 1b
|
||||
TIM6_IRQHandler: 1: j 1b
|
||||
TIM7_IRQHandler: 1: j 1b
|
||||
DMA2_Channel1_IRQHandler: 1: j 1b
|
||||
DMA2_Channel2_IRQHandler: 1: j 1b
|
||||
DMA2_Channel3_IRQHandler: 1: j 1b
|
||||
DMA2_Channel4_IRQHandler: 1: j 1b
|
||||
DMA2_Channel5_IRQHandler: 1: j 1b
|
||||
ETH_IRQHandler: 1: j 1b
|
||||
ETH_WKUP_IRQHandler: 1: j 1b
|
||||
CAN2_TX_IRQHandler: 1: j 1b
|
||||
CAN2_RX0_IRQHandler: 1: j 1b
|
||||
CAN2_RX1_IRQHandler: 1: j 1b
|
||||
CAN2_SCE_IRQHandler: 1: j 1b
|
||||
OTG_FS_IRQHandler: 1: j 1b
|
||||
USBHSWakeup_IRQHandler: 1: j 1b
|
||||
USBHS_IRQHandler: 1: j 1b
|
||||
DVP_IRQHandler: 1: j 1b
|
||||
UART6_IRQHandler: 1: j 1b
|
||||
UART7_IRQHandler: 1: j 1b
|
||||
UART8_IRQHandler: 1: j 1b
|
||||
TIM9_BRK_IRQHandler: 1: j 1b
|
||||
TIM9_UP_IRQHandler: 1: j 1b
|
||||
TIM9_TRG_COM_IRQHandler: 1: j 1b
|
||||
TIM9_CC_IRQHandler: 1: j 1b
|
||||
TIM10_BRK_IRQHandler: 1: j 1b
|
||||
TIM10_UP_IRQHandler: 1: j 1b
|
||||
TIM10_TRG_COM_IRQHandler: 1: j 1b
|
||||
TIM10_CC_IRQHandler: 1: j 1b
|
||||
DMA2_Channel6_IRQHandler: 1: j 1b
|
||||
DMA2_Channel7_IRQHandler: 1: j 1b
|
||||
DMA2_Channel8_IRQHandler: 1: j 1b
|
||||
DMA2_Channel9_IRQHandler: 1: j 1b
|
||||
DMA2_Channel10_IRQHandler: 1: j 1b
|
||||
DMA2_Channel11_IRQHandler: 1: j 1b
|
||||
|
||||
|
||||
.section .text.handle_reset,"ax",@progbits
|
||||
.weak handle_reset
|
||||
.align 1
|
||||
handle_reset:
|
||||
.option push
|
||||
.option norelax
|
||||
csrw mepc, t0
|
||||
la gp, __global_pointer$
|
||||
.option pop
|
||||
1:
|
||||
la sp, _eusrstack
|
||||
2:
|
||||
/* Load data section from flash to RAM */
|
||||
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:
|
||||
li t0, 0x1f
|
||||
csrw 0xbc0, t0
|
||||
|
||||
/* Enable nested and hardware stack */
|
||||
li t0, 0x1f
|
||||
csrw 0x804, t0
|
||||
# csrw 0x804, zero
|
||||
|
||||
/* Enable floating point and interrupt */
|
||||
li t0, 0x7800
|
||||
csrs mstatus, t0
|
||||
|
||||
la t0, _vector_base
|
||||
ori t0, t0, 3
|
||||
csrw mtvec, t0
|
||||
|
||||
jal SystemInit
|
||||
la t0, entry
|
||||
csrw mepc, t0
|
||||
mret
|
||||
|
||||
|
||||
@@ -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,142 @@
|
||||
/*
|
||||
* 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 "ch32v30x.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;
|
||||
|
||||
void sw_setpend(void)
|
||||
{
|
||||
SysTick->CTLR |= (1<<31);
|
||||
}
|
||||
|
||||
/*
|
||||
* clear soft interrupt
|
||||
*/
|
||||
void sw_clearpend(void)
|
||||
{
|
||||
SysTick->CTLR &= ~(1<<31);
|
||||
}
|
||||
|
||||
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,115 @@
|
||||
#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,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 "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
|
||||
stack_contex->mstatus = 0x00007880;
|
||||
|
||||
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,200 @@
|
||||
/*
|
||||
* 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:
|
||||
/* first save interrupt stack */
|
||||
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,39 @@
|
||||
/*
|
||||
* 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 "ch32v30x.h"
|
||||
#include "ch32v30x_it.h"
|
||||
#include "core_riscv.h"
|
||||
|
||||
extern void KTaskOsAssignAfterIrq(void *);
|
||||
|
||||
void SysTick_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
GET_INT_SP();
|
||||
/* enter interrupt */
|
||||
x_base level;
|
||||
level = DisableLocalInterrupt();
|
||||
isrManager.done->incCounter();
|
||||
EnableLocalInterrupt(level);
|
||||
SysTick->SR = 0;
|
||||
TickAndTaskTimesliceUpdate();
|
||||
KTaskOsAssignAfterIrq(NONE);
|
||||
/* leave interrupt */
|
||||
level = DisableLocalInterrupt();
|
||||
isrManager.done->decCounter();
|
||||
EnableLocalInterrupt(level);
|
||||
FREE_INT_SP();
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
|
||||
This software, except as otherwise noted in subrepositories,
|
||||
is licensed under the Apache 2 license, quoted below.
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2016 SiFive, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := interrupt.c boot.S tick.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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 ARCH_INTERRUPT_H__
|
||||
#define ARCH_INTERRUPT_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <plic_driver.h>
|
||||
|
||||
#define ARCH_MAX_IRQ_NUM IRQN_MAX
|
||||
#define ARCH_IRQ_NUM_OFFSET 0
|
||||
|
||||
uint32_t GetInterruptNumber(void);
|
||||
void HwInterruptAck(uint32_t irq);
|
||||
|
||||
int32_t ArchEnableHwIrq(int irq_num);
|
||||
int32_t ArchDisableHwIrq(int irq_num);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,134 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
/**
|
||||
* @file boot.S
|
||||
* @brief hifive1-rev-B-board start function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-25
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: boot.S
|
||||
Description: hifive1-rev-B-board start function
|
||||
Others: take freedom-e-sdk v20180402/bsp/env/start.S for references
|
||||
https://github.com/sifive/freedom-e-sdk/releases/tag/v20180402
|
||||
History:
|
||||
1. Date: 2021-04-25
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. See LICENSE details in xiuos/arch/risc-v/fe310/LICENSE
|
||||
2. Modify entry function name
|
||||
3. Modify OS startup function
|
||||
4. Add interrupt entry function.
|
||||
*************************************************/
|
||||
|
||||
#include <sifive/smp.h>
|
||||
|
||||
/* This is defined in sifive/platform.h, but that can't be included from
|
||||
* assembly. */
|
||||
#define CLINT_CTRL_ADDR 0x02000000
|
||||
#include <encoding.h>
|
||||
#include "register_para.h"
|
||||
#include "boot.h"
|
||||
|
||||
.section .init
|
||||
.globl _begin
|
||||
.type _begin,@function
|
||||
|
||||
_begin:
|
||||
.cfi_startproc
|
||||
.cfi_undefined ra
|
||||
.option push
|
||||
.option norelax
|
||||
la gp, __global_pointer$
|
||||
.option pop
|
||||
la sp, _sp
|
||||
|
||||
|
||||
/* Load data section */
|
||||
la a0, _data_lma
|
||||
la a1, _data
|
||||
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, __bss_start
|
||||
la a1, _end
|
||||
bgeu a0, a1, 2f
|
||||
1:
|
||||
sw zero, (a0)
|
||||
addi a0, a0, 4
|
||||
bltu a0, a1, 1b
|
||||
2:
|
||||
|
||||
/* Call global constructors */
|
||||
//la a0, __libc_fini_array
|
||||
//call atexit
|
||||
//call __libc_init_array
|
||||
|
||||
#ifndef __riscv_float_abi_soft
|
||||
/* Enable FPU */
|
||||
li t0, MSTATUS_FS
|
||||
csrs mstatus, t0
|
||||
csrr t1, mstatus
|
||||
and t1, t1, t0
|
||||
beqz t1, 1f
|
||||
fssr x0
|
||||
1:
|
||||
#endif
|
||||
|
||||
auipc ra, 0
|
||||
addi sp, sp, -16
|
||||
sw ra, 8(sp)
|
||||
|
||||
/* argc = argv = 0 */
|
||||
li a0, 0
|
||||
li a1, 0
|
||||
call entry
|
||||
/* tail exit */
|
||||
|
||||
1:
|
||||
j 1b
|
||||
.cfi_endproc
|
||||
|
||||
|
||||
.section .text.entry
|
||||
.align 2
|
||||
.global save_hw_context
|
||||
save_hw_context:
|
||||
|
||||
/* save all from thread context */
|
||||
SAVE_X_REGISTERS
|
||||
|
||||
/* save break thread stack to s0 */
|
||||
move s0, sp
|
||||
|
||||
#ifdef TASK_ISOLATION
|
||||
csrr a0, mcause
|
||||
srli a0, a0, 31
|
||||
andi a0, a0, 0x1
|
||||
beqz a0, 1f
|
||||
#endif
|
||||
/* switch to interrupt stack */
|
||||
la sp, _sp
|
||||
|
||||
1:
|
||||
/* interrupt handle */
|
||||
csrr a0, mcause
|
||||
csrr a1, mepc
|
||||
mv a2, sp
|
||||
call HandleTrap
|
||||
|
||||
/* switch to from_thread stack */
|
||||
move sp, s0
|
||||
mv a0, fp
|
||||
call KTaskOsAssignAfterIrq
|
||||
j SwitchKTaskContextExit
|
||||
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* 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 <arch_interrupt.h>
|
||||
#include <board.h>
|
||||
#include <encoding.h>
|
||||
#include <platform.h>
|
||||
#include <plic_driver.h>
|
||||
#include <xs_assign.h>
|
||||
#include <xs_base.h>
|
||||
#include <xs_isr.h>
|
||||
#include <xs_ktask.h>
|
||||
#ifdef TASK_ISOLATION
|
||||
#include <xs_isolation.h>
|
||||
#include <xs_service.h>
|
||||
#endif
|
||||
|
||||
#define MAX_HANDLERS PLIC_NUM_INTERRUPTS
|
||||
extern plic_instance_t g_plic ;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function will mask a interrupt.
|
||||
* @param vector the interrupt number
|
||||
*/
|
||||
int32_t ArchDisableHwIrq(int irq)
|
||||
{
|
||||
PLIC_disable_interrupt(&g_plic, irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will un-mask a interrupt.
|
||||
* @param vector the interrupt number
|
||||
*/
|
||||
int32_t ArchEnableHwIrq(int irq)
|
||||
{
|
||||
PLIC_enable_interrupt(&g_plic, irq);
|
||||
PLIC_set_priority(&g_plic, irq, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t GetInterruptNumber(void)
|
||||
{
|
||||
return (uint32_t)PLIC_claim_interrupt(&g_plic);
|
||||
}
|
||||
|
||||
void HwInterruptAck(uint32_t irq)
|
||||
{
|
||||
PLIC_complete_interrupt(&g_plic, irq);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will be call when external machine-level
|
||||
* interrupt from PLIC occurred.
|
||||
*/
|
||||
uintptr_t HandleIrqMExt(uintptr_t cause, uintptr_t epc)
|
||||
{
|
||||
uint32_t irq;
|
||||
|
||||
/* get irq number */
|
||||
irq = GetInterruptNumber();
|
||||
/* get interrupt service routine */
|
||||
isrManager.done->handleIrq(irq);
|
||||
HwInterruptAck(irq);
|
||||
}
|
||||
|
||||
extern int TickIsr(void);
|
||||
|
||||
#ifdef TASK_ISOLATION
|
||||
uintptr_t HandleTrap(uintptr_t mcause, uintptr_t epc, uintptr_t * sp)
|
||||
{
|
||||
int cause = mcause & MCAUSE_CAUSE ;
|
||||
|
||||
if (mcause & MCAUSE_INT) {
|
||||
isrManager.done->incCounter();
|
||||
switch (cause) {
|
||||
case IRQ_M_EXT:
|
||||
HandleIrqMExt(mcause, epc);
|
||||
break;
|
||||
case IRQ_M_TIMER:
|
||||
CLINT_MTIMECMP_ADDR = CLINT_MTIME_ADDR + TICK;
|
||||
TickIsr();
|
||||
break;
|
||||
}
|
||||
isrManager.done->decCounter();
|
||||
}else {
|
||||
x_base temp;
|
||||
temp = DISABLE_INTERRUPT();
|
||||
KTaskDescriptorType tid;
|
||||
extern long ShowTask();
|
||||
tid = GetKTaskDescriptor();
|
||||
|
||||
if(cause == CAUSE_USER_ECALL) {
|
||||
tid->task_dync_sched_member.isolation_status = 1;
|
||||
sp[0] += 4;
|
||||
unsigned long service_num = (unsigned long)(sp[10]);
|
||||
//KPrintf("Environment call from U-mode,service_num: %ld\n",service_num);
|
||||
uint8_t param_num = g_service_table[service_num].param_num;
|
||||
uintptr_t *param = sp + 11;
|
||||
ENABLE_INTERRUPT(temp);
|
||||
sp[10] = g_service_table[service_num].fun(service_num,param,param_num) ;
|
||||
tid->task_dync_sched_member.isolation_status = 0;
|
||||
|
||||
} else if( cause == CAUSE_MACHINE_ECALL) {
|
||||
unsigned long service_num = (unsigned long)(sp[10]);
|
||||
KPrintf("Environment call from M-mode, task:%s, flag: %d,service_num: %d\n \n",tid->task_base_info.name,tid->task_dync_sched_member.isolation_flag, service_num);
|
||||
sp[0] += 4;
|
||||
ENABLE_INTERRUPT(temp);
|
||||
}
|
||||
else if (cause == CAUSE_FAULT_LOAD || cause == CAUSE_FAULT_STORE || cause == CAUSE_FAULT_FETCH ){
|
||||
if ( tid->task_dync_sched_member.isolation_flag == 1) {
|
||||
x_ubase fault_addr = READ_CSR(mtval);
|
||||
// KPrintf("access fault ,addr : 0x%08x\n",fault_addr);
|
||||
x_bool result ;
|
||||
result = mem_access.FaultHandle(tid->task_dync_sched_member.isolation , fault_addr);
|
||||
if(result)
|
||||
mem_access.Load(tid->task_dync_sched_member.isolation);
|
||||
else{
|
||||
KPrintf("\nSegmentation fault, task: %s\n",tid->task_base_info.name);
|
||||
KTaskQuit();
|
||||
}
|
||||
}else
|
||||
goto __print;
|
||||
}
|
||||
else
|
||||
{
|
||||
KPrintf("\nException:\n");
|
||||
tid = GetKTaskDescriptor();
|
||||
switch (cause)
|
||||
{
|
||||
case CAUSE_MISALIGNED_FETCH:
|
||||
KPrintf("Instruction address misaligned");
|
||||
break;
|
||||
case CAUSE_FAULT_FETCH:
|
||||
KPrintf("Instruction access fault");
|
||||
break;
|
||||
case CAUSE_ILLEGAL_INSTRUCTION:
|
||||
KPrintf("Illegal instruction");
|
||||
break;
|
||||
case CAUSE_BREAKPOINT:
|
||||
KPrintf("Breakpoint");
|
||||
break;
|
||||
case CAUSE_MISALIGNED_LOAD:
|
||||
KPrintf("Load address misaligned");
|
||||
break;
|
||||
case CAUSE_FAULT_LOAD:
|
||||
KPrintf("Load access fault");
|
||||
break;
|
||||
case CAUSE_MISALIGNED_STORE:
|
||||
KPrintf("Store address misaligned");
|
||||
break;
|
||||
case CAUSE_FAULT_STORE:
|
||||
KPrintf("Store access fault");
|
||||
break;
|
||||
case CAUSE_SUPERVISOR_ECALL:
|
||||
KPrintf("Environment call from S-mode");
|
||||
break;
|
||||
case CAUSE_HYPERVISOR_ECALL:
|
||||
KPrintf("Environment call from H-mode");
|
||||
break;
|
||||
default:
|
||||
KPrintf("Uknown exception : %08lX", cause);
|
||||
break;
|
||||
}
|
||||
__print:
|
||||
KPrintf("\n");
|
||||
//PrintStackFrame(sp);
|
||||
KPrintf("exception pc => 0x%08x\n", epc);
|
||||
KPrintf("current thread: %.*s\n", NAME_NUM_MAX, tid->task_base_info.name);
|
||||
#ifdef TOOL_SHELL
|
||||
ShowTask();
|
||||
#endif
|
||||
while(RET_TRUE);
|
||||
}
|
||||
}
|
||||
return epc;
|
||||
}
|
||||
#else
|
||||
uintptr_t HandleTrap(uintptr_t mcause, uintptr_t epc, uintptr_t * sp)
|
||||
{
|
||||
int cause = mcause & MCAUSE_CAUSE ;
|
||||
|
||||
if (mcause & MCAUSE_INT)
|
||||
{
|
||||
isrManager.done->incCounter();
|
||||
switch (cause)
|
||||
{
|
||||
case IRQ_M_EXT:
|
||||
HandleIrqMExt(mcause, epc);
|
||||
break;
|
||||
case IRQ_M_TIMER:
|
||||
CLINT_MTIMECMP_ADDR = CLINT_MTIME_ADDR + TICK;
|
||||
TickIsr();
|
||||
break;
|
||||
}
|
||||
isrManager.done->decCounter();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
KTaskDescriptorType tid;
|
||||
extern long ShowTask();
|
||||
|
||||
|
||||
DISABLE_INTERRUPT();
|
||||
|
||||
tid = GetKTaskDescriptor();
|
||||
KPrintf("\nException:\n");
|
||||
switch (cause)
|
||||
{
|
||||
case CAUSE_MISALIGNED_FETCH:
|
||||
KPrintf("Instruction address misaligned");
|
||||
break;
|
||||
case CAUSE_FAULT_FETCH:
|
||||
KPrintf("Instruction access fault");
|
||||
break;
|
||||
case CAUSE_ILLEGAL_INSTRUCTION:
|
||||
KPrintf("Illegal instruction");
|
||||
break;
|
||||
case CAUSE_BREAKPOINT:
|
||||
KPrintf("Breakpoint");
|
||||
break;
|
||||
case CAUSE_MISALIGNED_LOAD:
|
||||
KPrintf("Load address misaligned");
|
||||
break;
|
||||
case CAUSE_FAULT_LOAD:
|
||||
KPrintf("Load access fault");
|
||||
break;
|
||||
case CAUSE_MISALIGNED_STORE:
|
||||
KPrintf("Store address misaligned");
|
||||
break;
|
||||
case CAUSE_FAULT_STORE:
|
||||
KPrintf("Store access fault");
|
||||
break;
|
||||
case CAUSE_SUPERVISOR_ECALL:
|
||||
KPrintf("Environment call from S-mode");
|
||||
break;
|
||||
case CAUSE_HYPERVISOR_ECALL:
|
||||
KPrintf("Environment call from H-mode");
|
||||
break;
|
||||
default:
|
||||
KPrintf("Uknown exception : %08lX", cause);
|
||||
break;
|
||||
}
|
||||
KPrintf("\n");
|
||||
//PrintStackFrame(sp);
|
||||
KPrintf("exception pc => 0x%08x\n", epc);
|
||||
KPrintf("current thread: %.*s\n", NAME_NUM_MAX, tid->task_base_info.name);
|
||||
#ifdef TOOL_SHELL
|
||||
ShowTask();
|
||||
#endif
|
||||
while (RET_TRUE);
|
||||
}
|
||||
return epc;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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 <encoding.h>
|
||||
#include <clint.h>
|
||||
#include <xs_ktick.h>
|
||||
|
||||
static volatile unsigned long tick_cycles = 0;
|
||||
int TickIsr(void)
|
||||
{
|
||||
TickAndTaskTimesliceUpdate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := boot.S interrupt.c tick.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
+305
@@ -0,0 +1,305 @@
|
||||
/****************************************************************************
|
||||
* arch/risc-v/include/gap8/irq.h
|
||||
* GAP8 event system
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: hhuysqt <1020988872@qq.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* GAP8 features a FC controller and a 8-core cluster. IRQ from peripherals
|
||||
* have unique ID, which are dispatched to the FC or cluster by the SOC
|
||||
* event unit, and then by the FC event unit or cluster event unit, and
|
||||
* finally to FC or cluster. Peripherals share the same IRQ entry.
|
||||
****************************************************************************/
|
||||
/**
|
||||
* @file arch_interrupt.h
|
||||
* @brief support gap8 interrupt
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-09-02
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: arch_interrupt.h
|
||||
Description: support gap8 interrupt
|
||||
Others: take nuttx/arch/risc-v/include/gap8/irq.h for references
|
||||
https://github.com/apache/incubator-nuttx.git
|
||||
History:
|
||||
1. Date: 2021-09-02
|
||||
Author: AIIT XUOS Lab
|
||||
Modification: add interrupt function definition
|
||||
*************************************************/
|
||||
|
||||
#ifndef ARCH_INTERRUPT_H__
|
||||
#define ARCH_INTERRUPT_H__
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Unique ID in SOC domain */
|
||||
|
||||
/* uDMA data events.
|
||||
* Each peripheral has a uDMA_ID.
|
||||
* Each peripheral also has RX and TX event ID, which happen to be 2*uDMA_ID
|
||||
* and 2*uDMA_ID+1.
|
||||
*/
|
||||
|
||||
#define GAP8_EVENT_UDMA_LVDS_RX 0
|
||||
#define GAP8_EVENT_UDMA_LVDS_TX 1
|
||||
#define GAP8_EVENT_UDMA_SPIM0_RX 2
|
||||
#define GAP8_EVENT_UDMA_SPIM0_TX 3
|
||||
#define GAP8_EVENT_UDMA_SPIM1_RX 4
|
||||
#define GAP8_EVENT_UDMA_SPIM1_TX 5
|
||||
#define GAP8_EVENT_UDMA_HYPERBUS_RX 6
|
||||
#define GAP8_EVENT_UDMA_HYPERBUS_TX 7
|
||||
#define GAP8_EVENT_UDMA_UART_RX 8
|
||||
#define GAP8_EVENT_UDMA_UART_TX 9
|
||||
#define GAP8_EVENT_UDMA_I2C0_RX 10
|
||||
#define GAP8_EVENT_UDMA_I2C0_TX 11
|
||||
#define GAP8_EVENT_UDMA_I2C1_RX 12
|
||||
#define GAP8_EVENT_UDMA_I2C1_TX 13
|
||||
#define GAP8_EVENT_UDMA_TCDM_RX 14
|
||||
#define GAP8_EVENT_UDMA_TCDM_TX 15
|
||||
#define GAP8_EVENT_UDMA_SAI_CH0 16
|
||||
#define GAP8_EVENT_UDMA_SAI_CH1 17
|
||||
#define GAP8_EVENT_UDMA_CPI_RX 18
|
||||
|
||||
#define GAP8_UDMA_MAX_EVENT 18
|
||||
|
||||
/* Other events of uDMA peripherals */
|
||||
|
||||
#define GAP8_EVENT_LVDS_GEN0 20
|
||||
#define GAP8_EVENT_LVDS_GEN1 21
|
||||
#define GAP8_EVENT_SPIM0_EOT 22
|
||||
#define GAP8_EVENT_SPIM1_EOT 23
|
||||
#define GAP8_EVENT_HYPERBUS_RESERVED 24
|
||||
#define GAP8_EVENT_UART_RESERVED 25
|
||||
#define GAP8_EVENT_I2C0_ERROR 26
|
||||
#define GAP8_EVENT_I2C1_ERROR 27
|
||||
#define GAP8_EVENT_I2S_RESERVED 28
|
||||
#define GAP8_EVENT_CAM_RESERVED 29
|
||||
|
||||
/* PMU events */
|
||||
|
||||
#define GAP8_EVENT_PMU_CLUSTER_POWER_ON 31
|
||||
#define GAP8_EVENT_PMU_CLUSTER_RESERVED0 32
|
||||
#define GAP8_EVENT_PMU_CLUSTER_RESERVED1 33
|
||||
#define GAP8_EVENT_PMU_CLUSTER_RESERVED2 34
|
||||
#define GAP8_EVENT_PMU_CLUSTER_CLOCK_GATING 35
|
||||
#define GAP8_EVENT_PMU_DLC_BRIDGE_PICL_OK 36
|
||||
#define GAP8_EVENT_PMU_DLC_BRIDGE_SCU_OK 37
|
||||
|
||||
/* Other SOC domain peripheral events */
|
||||
|
||||
#define GAP8_EVENT_PWM0 38
|
||||
#define GAP8_EVENT_PWM1 39
|
||||
#define GAP8_EVENT_PWM2 40
|
||||
#define GAP8_EVENT_PWM3 41
|
||||
#define GAP8_EVENT_GPIO 42 /* GPIO group interrupt */
|
||||
#define GAP8_EVENT_RTC_APB 43
|
||||
#define GAP8_EVENT_RTC 44
|
||||
#define GAP8_EVENT_RESERVED0 45
|
||||
#define GAP8_EVENT_RESERVED1 46
|
||||
#define GAP8_EVENT_RESERVED2 47
|
||||
#define GAP8_EVENT_SOC_SW_0 48 /* GAP8 SOC SW Event0 */
|
||||
#define GAP8_EVENT_SOC_SW_1 49 /* GAP8 SOC SW Event1 */
|
||||
#define GAP8_EVENT_SOC_SW_2 50 /* GAP8 SOC SW Event2 */
|
||||
#define GAP8_EVENT_SOC_SW_3 51 /* GAP8 SOC SW Event3 */
|
||||
#define GAP8_EVENT_SOC_SW_4 52 /* GAP8 SOC SW Event4 */
|
||||
#define GAP8_EVENT_SOC_SW_5 53 /* GAP8 SOC SW Event5 */
|
||||
#define GAP8_EVENT_SOC_SW_6 54 /* GAP8 SOC SW Event6 */
|
||||
#define GAP8_EVENT_SOC_SW_7 55 /* GAP8 SOC SW Event7 */
|
||||
#define GAP8_EVENT_REF32K_CLK_RISE 56 /* Reference 32K Clock event */
|
||||
|
||||
/* FC domain IRQ ID */
|
||||
|
||||
#define GAP8_IRQ_FC_SW_0 0
|
||||
#define GAP8_IRQ_FC_SW_1 1
|
||||
#define GAP8_IRQ_FC_SW_2 2
|
||||
#define GAP8_IRQ_FC_SW_3 3
|
||||
#define GAP8_IRQ_FC_SW_4 4
|
||||
#define GAP8_IRQ_FC_SW_5 5
|
||||
#define GAP8_IRQ_FC_SW_6 6
|
||||
#define GAP8_IRQ_FC_SW_7 7
|
||||
#define GAP8_IRQ_FC_TIMER_LO 10
|
||||
#define GAP8_IRQ_FC_TIMER_HI 11
|
||||
#define GAP8_IRQ_FC_UDMA 27
|
||||
#define GAP8_IRQ_FC_MPU 28
|
||||
#define GAP8_IRQ_FC_UDMA_ERR 29
|
||||
#define GAP8_IRQ_FC_HP_0 30
|
||||
#define GAP8_IRQ_FC_HP_1 31
|
||||
|
||||
#define GAP8_IRQ_RESERVED 60
|
||||
|
||||
/* Cluster domain IRQ ID */
|
||||
|
||||
/* TODO */
|
||||
|
||||
/* RISCY core exception vectors */
|
||||
|
||||
#define GAP8_IRQ_RST 32
|
||||
#define GAP8_IRQ_ILLEGAL 33
|
||||
#define GAP8_IRQ_SYSCALL 34
|
||||
|
||||
/* Total number of IRQs.
|
||||
* 32 ISRs + reset-handler + illegal-instruction-handler +
|
||||
* system-call-handler
|
||||
*/
|
||||
|
||||
#define NR_IRQS 35
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* SOC_EU - SOC domain event unit */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
volatile uint32_t EVENT; /* event register */
|
||||
volatile uint32_t FC_MASK_MSB; /* fc mask MSB register */
|
||||
volatile uint32_t FC_MASK_LSB; /* fc mask LSB register */
|
||||
volatile uint32_t CL_MASK_MSB; /* cluster mask MSB register */
|
||||
volatile uint32_t CL_MASK_LSB; /* cluster mask LSB register */
|
||||
volatile uint32_t PR_MASK_MSB; /* propagate mask MSB register */
|
||||
volatile uint32_t PR_MASK_LSB; /* propagate mask LSB register */
|
||||
volatile uint32_t ERR_MASK_MSB; /* error mask MSB register */
|
||||
volatile uint32_t ERR_MASK_LSB; /* error mask LSB register */
|
||||
volatile uint32_t TIMER_SEL_HI; /* timer high register */
|
||||
volatile uint32_t TIMER_SEL_LO; /* timer low register */
|
||||
} soc_eu_reg_t;
|
||||
|
||||
#define SOC_EU ((soc_eu_reg_t *)0x1A106000U)
|
||||
|
||||
/* FCEU - FC domain event unit */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
volatile uint32_t MASK; /* mask register */
|
||||
volatile uint32_t MASK_AND; /* mask-and(clr) register */
|
||||
volatile uint32_t MASK_OR; /* mask-or(set) register */
|
||||
volatile uint32_t MASK_IRQ; /* irq mask register */
|
||||
volatile uint32_t MASK_IRQ_AND; /* irq mask-and(clr) register */
|
||||
volatile uint32_t MASK_IRQ_OR; /* irq mask-or(set) register */
|
||||
volatile uint32_t STATUS; /* clock Status register */
|
||||
volatile uint32_t BUFFER; /* irq pending register */
|
||||
volatile uint32_t BUFFER_MASKED; /* buffer masked register */
|
||||
volatile uint32_t BUFFER_IRQ_MASKED; /* buffer irq masked register */
|
||||
volatile uint32_t BUFFER_CLEAR; /* clear irq pending */
|
||||
volatile uint32_t SW_EVENTS_MASK; /* software event mask register */
|
||||
volatile uint32_t SW_EVENTS_MASK_AND; /* software event mask and register */
|
||||
volatile uint32_t SW_EVENTS_MASK_OR; /* software event mask or register */
|
||||
volatile uint32_t EVENT_WAIT; /* event wait register */
|
||||
volatile uint32_t EVENT_WAIT_CLEAR; /* event wait clear register */
|
||||
volatile uint32_t MASK_SEC_IRQ; /* mask sec irq register */
|
||||
} fceu_reg_t;
|
||||
|
||||
#define FCEU ((fceu_reg_t*)0x00204000U)
|
||||
|
||||
/* Current interrupt event ID */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
volatile uint32_t CURRENT_EVENT; /* current event register */
|
||||
} soc_event_reg_t;
|
||||
|
||||
#define SOC_EVENTS ((soc_event_reg_t*)0x00200F00UL)
|
||||
|
||||
/* event trigger and mask */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
volatile uint32_t TRIGGER_SET[8]; /* trigger set register */
|
||||
volatile uint32_t _reserved0[8]; /* Offset: 0x20 (R/W) Empty Registers */
|
||||
volatile uint32_t TRIGGER_WAIT[8]; /* trigger wait register */
|
||||
volatile uint32_t _reserved1[8]; /* Offset: 0x60 (R/W) Empty Registers */
|
||||
volatile uint32_t TRIGGER_CLR[8]; /* trigger clear register */
|
||||
} eu_sw_events_trigger_reg_t;
|
||||
|
||||
#define EU_SW_EVNT_TRIG ((eu_sw_events_trigger_reg_t*)0x00204100UL)
|
||||
|
||||
#define ARCH_MAX_IRQ_NUM NR_IRQS
|
||||
|
||||
int ArchEnableHwIrq(uint32_t irq_num);
|
||||
int ArchDisableHwIrq(uint32_t irq_num);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_disable_event
|
||||
*
|
||||
* Description:
|
||||
* Disable the specific event. Note that setting 1 means to disable an
|
||||
* event...
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void up_disable_event(int event)
|
||||
{
|
||||
if (event >= 32)
|
||||
{
|
||||
SOC_EU->FC_MASK_MSB |= (1 << (event - 32));
|
||||
}
|
||||
else
|
||||
{
|
||||
SOC_EU->FC_MASK_LSB |= (1 << event);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_enable_event
|
||||
*
|
||||
* Description:
|
||||
* Enable the specific event. Note that setting 0 means to enable an
|
||||
* event...
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void up_enable_event(int event)
|
||||
{
|
||||
if (event >= 32)
|
||||
{
|
||||
SOC_EU->FC_MASK_MSB &= ~(1 << (event - 32));
|
||||
}
|
||||
else
|
||||
{
|
||||
SOC_EU->FC_MASK_LSB &= ~(1 << event);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+381
@@ -0,0 +1,381 @@
|
||||
/****************************************************************************
|
||||
* arch/risc-v/src/gapuino/gap8_head.S
|
||||
* Startup file for FC of GAP8
|
||||
* Interrupt vector and reset handler
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: hhuysqt <1020988872@qq.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file boot.s
|
||||
* @brief support gap8 interrupt and startup
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-09-02
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: boot.s
|
||||
Description: support gap8 interrupt and startup
|
||||
Others: take nuttx/arch/risc-v/gap8/gap8_head.S for references
|
||||
https://github.com/apache/incubator-nuttx.git
|
||||
History:
|
||||
1. Date: 2021-09-02
|
||||
Author: AIIT XUOS Lab
|
||||
Modification: modify startup sequence and interrupt process
|
||||
*************************************************/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Exception context size: EPC + 31 common regs + 6 loop regs */
|
||||
#include "boot.h"
|
||||
#define EXCEPTION_STACK_SIZE 4*38
|
||||
|
||||
/****************************************************************************
|
||||
* Assembler Macro Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* save all the registers on interrupt entry */
|
||||
|
||||
.macro SAVE_REGS
|
||||
addi sp, sp, -EXCEPTION_STACK_SIZE
|
||||
sw x1, 1*4(sp) /* ra */
|
||||
sw x3, 3*4(sp) /* gp */
|
||||
sw x4, 4*4(sp) /* tp */
|
||||
sw x5, 5*4(sp) /* t0 */
|
||||
sw x6, 6*4(sp) /* t1 */
|
||||
sw x7, 7*4(sp) /* t2 */
|
||||
sw x8, 8*4(sp) /* s0 */
|
||||
sw x9, 9*4(sp) /* s1 */
|
||||
sw x10, 10*4(sp) /* a0 */
|
||||
sw x11, 11*4(sp) /* a1 */
|
||||
sw x12, 12*4(sp) /* a2 */
|
||||
sw x13, 13*4(sp) /* a3 */
|
||||
sw x14, 14*4(sp) /* a4 */
|
||||
sw x15, 15*4(sp) /* a5 */
|
||||
sw x16, 16*4(sp) /* a6 */
|
||||
sw x17, 17*4(sp) /* a7 */
|
||||
sw x18, 18*4(sp) /* s2 */
|
||||
sw x19, 19*4(sp) /* s3 */
|
||||
sw x20, 20*4(sp) /* s4 */
|
||||
sw x21, 21*4(sp) /* s5 */
|
||||
sw x22, 22*4(sp) /* s6 */
|
||||
sw x23, 23*4(sp) /* s7 */
|
||||
sw x24, 24*4(sp) /* s8 */
|
||||
sw x25, 25*4(sp) /* s9 */
|
||||
sw x26, 26*4(sp) /* s10 */
|
||||
sw x27, 27*4(sp) /* s11 */
|
||||
sw x28, 28*4(sp) /* t3 */
|
||||
sw x29, 29*4(sp) /* t4 */
|
||||
sw x30, 30*4(sp) /* t5 */
|
||||
sw x31, 31*4(sp) /* t6 */
|
||||
csrr x28, 0x7B0
|
||||
csrr x29, 0x7B1
|
||||
csrr x30, 0x7B2
|
||||
sw x28, 32*4(sp) /* lpstart[0] */
|
||||
sw x29, 33*4(sp) /* lpend[0] */
|
||||
sw x30, 34*4(sp) /* lpcount[0] */
|
||||
csrr x28, 0x7B4
|
||||
csrr x29, 0x7B5
|
||||
csrr x30, 0x7B6
|
||||
sw x28, 35*4(sp) /* lpstart[1] */
|
||||
sw x29, 36*4(sp) /* lpend[1] */
|
||||
sw x30, 37*4(sp) /* lpcount[1] */
|
||||
addi s0, sp, EXCEPTION_STACK_SIZE
|
||||
sw s0, 2*4(sp) /* original SP */
|
||||
.endm
|
||||
|
||||
/* restore regs and `mret` */
|
||||
|
||||
.macro RESTORE_REGS
|
||||
lw x28, 35*4(sp) /* lpstart[1] */
|
||||
lw x29, 36*4(sp) /* lpend[1] */
|
||||
lw x30, 37*4(sp) /* lpcount[1] */
|
||||
csrrw x0, 0x7B4, x28
|
||||
csrrw x0, 0x7B5, x29
|
||||
csrrw x0, 0x7B6, x30
|
||||
lw x28, 32*4(sp) /* lpstart[0] */
|
||||
lw x29, 33*4(sp) /* lpend[0] */
|
||||
lw x30, 34*4(sp) /* lpcount[0] */
|
||||
csrrw x0, 0x7B0, x28
|
||||
csrrw x0, 0x7B1, x29
|
||||
csrrw x0, 0x7B2, x30
|
||||
li s0, 0x1880 /* machine mode, UPIE & MPIE enabled */
|
||||
csrrw x0, mstatus, s0
|
||||
lw x3, 3*4(sp) /* gp */
|
||||
lw x4, 4*4(sp) /* tp */
|
||||
lw x5, 5*4(sp) /* t0 */
|
||||
lw x6, 6*4(sp) /* t1 */
|
||||
lw x7, 7*4(sp) /* t2 */
|
||||
lw x8, 8*4(sp) /* s0 */
|
||||
lw x9, 9*4(sp) /* s1 */
|
||||
lw x10, 10*4(sp) /* a0 */
|
||||
lw x11, 11*4(sp) /* a1 */
|
||||
lw x12, 12*4(sp) /* a2 */
|
||||
lw x13, 13*4(sp) /* a3 */
|
||||
lw x14, 14*4(sp) /* a4 */
|
||||
lw x15, 15*4(sp) /* a5 */
|
||||
lw x16, 16*4(sp) /* a6 */
|
||||
lw x17, 17*4(sp) /* a7 */
|
||||
lw x18, 18*4(sp) /* s2 */
|
||||
lw x19, 19*4(sp) /* s3 */
|
||||
lw x20, 20*4(sp) /* s4 */
|
||||
lw x21, 21*4(sp) /* s5 */
|
||||
lw x22, 22*4(sp) /* s6 */
|
||||
lw x23, 23*4(sp) /* s7 */
|
||||
lw x24, 24*4(sp) /* s8 */
|
||||
lw x25, 25*4(sp) /* s9 */
|
||||
lw x26, 26*4(sp) /* s10 */
|
||||
lw x27, 27*4(sp) /* s11 */
|
||||
lw x28, 28*4(sp) /* t3 */
|
||||
lw x29, 29*4(sp) /* t4 */
|
||||
lw x30, 30*4(sp) /* t5 */
|
||||
lw x31, 31*4(sp) /* t6 */
|
||||
|
||||
lw x1, 1*4(sp) /* ra */
|
||||
|
||||
lw sp, 2*4(sp) /* restore original sp */
|
||||
.endm
|
||||
|
||||
.macro WRAP_IRQ Routine, IRQn
|
||||
wrap_irq_\Routine :
|
||||
|
||||
SAVE_X_REGISTERS
|
||||
|
||||
mv fp, sp
|
||||
|
||||
li a0, \IRQn /* irq = IRQn */
|
||||
mv a1, sp /* context = sp */
|
||||
call gap8_dispatch_irq
|
||||
|
||||
mv sp, fp
|
||||
mv a0, fp
|
||||
call KTaskOsAssignAfterIrq
|
||||
j SwitchKTaskContextExit
|
||||
|
||||
.endm
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* External Variables and Functions
|
||||
*******************************************************************************/
|
||||
|
||||
.extern __bss_start
|
||||
.extern __bss_end
|
||||
.extern _idle_stack_end
|
||||
.extern __data_start__
|
||||
|
||||
.extern gap8_dispatch_irq
|
||||
.extern entry
|
||||
.extern gapuino_sysinit
|
||||
.extern GapuinoStart
|
||||
|
||||
.globl reset_handler
|
||||
/*******************************************************************************
|
||||
* Reset handler
|
||||
*******************************************************************************/
|
||||
reset_handler:
|
||||
#if 0
|
||||
csrr a0, 0xf14 /* Cluster ID */
|
||||
andi a1, a0, 0x1f /* Core ID */
|
||||
srli a0, a0, 5
|
||||
#endif
|
||||
# la gp, __data_start__
|
||||
li a0, 0x1800 /* Set MSTATUS : Machine Mode */
|
||||
csrw mstatus, a0
|
||||
|
||||
li a0, 0x1C000000 /* Set MTVEC */
|
||||
csrw mtvec, a0
|
||||
|
||||
/* Stack initialization */
|
||||
|
||||
la x2, _idle_stack_end
|
||||
|
||||
/* Clear BSS */
|
||||
|
||||
la x26, __bss_start
|
||||
la x27, __bss_end
|
||||
|
||||
bge x26, x27, zero_loop_end
|
||||
|
||||
zero_loop:
|
||||
sw x0, 0(x26)
|
||||
addi x26, x26, 4
|
||||
ble x26, x27, zero_loop
|
||||
|
||||
zero_loop_end:
|
||||
|
||||
csrr a0, 0xf14 /* Cluster ID */
|
||||
andi a1, a0, 0x1f /* Core ID */
|
||||
|
||||
j GapuinoStart
|
||||
|
||||
dead_loop:
|
||||
jal x0, dead_loop
|
||||
|
||||
|
||||
/* IRQ wrappers
|
||||
* IRQn are identical to gap8_interrupt.h
|
||||
*/
|
||||
|
||||
WRAP_IRQ sw_evt0, 0
|
||||
WRAP_IRQ sw_evt1, 1
|
||||
WRAP_IRQ sw_evt2, 2
|
||||
WRAP_IRQ sw_evt3, 3
|
||||
WRAP_IRQ sw_evt4, 4
|
||||
WRAP_IRQ sw_evt5, 5
|
||||
WRAP_IRQ sw_evt6, 6
|
||||
WRAP_IRQ sw_evt7, 7
|
||||
|
||||
WRAP_IRQ timer_lo, 10
|
||||
WRAP_IRQ timer_hi, 11
|
||||
|
||||
WRAP_IRQ udma, 27
|
||||
WRAP_IRQ mpu, 28
|
||||
WRAP_IRQ udma_err, 29
|
||||
WRAP_IRQ fc_hp0, 30
|
||||
WRAP_IRQ fc_hp1, 31
|
||||
|
||||
WRAP_IRQ reserved, 60
|
||||
|
||||
/* RISCV exceptions */
|
||||
|
||||
illegal_insn_handler:
|
||||
csrr s0, mepc
|
||||
sw s0, 0*4(sp) /* exception PC */
|
||||
|
||||
/* Spin here so that debugger would read `s0` */
|
||||
|
||||
1:
|
||||
j 1b
|
||||
|
||||
/* Systemcall handler */
|
||||
|
||||
ecall_insn_handler:
|
||||
SAVE_REGS
|
||||
|
||||
/* Point to the next instruction of `ecall` */
|
||||
|
||||
csrr s0, mepc
|
||||
addi s0, s0, 4
|
||||
sw s0, 0(sp) /* exception PC */
|
||||
|
||||
li a0, 34 /* irq = 34 */
|
||||
mv a1, sp /* context = sp */
|
||||
jal x1, gap8_dispatch_irq
|
||||
|
||||
/* If context switch is needed, return
|
||||
* a new sp
|
||||
*/
|
||||
|
||||
mv sp, a0
|
||||
|
||||
lw s0, 0(sp) /* restore ePC */
|
||||
csrw mepc, s0
|
||||
|
||||
RESTORE_REGS
|
||||
|
||||
mret
|
||||
|
||||
/*******************************************************************************
|
||||
* INTERRUPT VECTOR TABLE
|
||||
*******************************************************************************/
|
||||
/* This section has to be down here, since we have to disable rvc for it */
|
||||
|
||||
.section .vectors_M, "ax"
|
||||
.option norvc;
|
||||
|
||||
j wrap_irq_sw_evt0 /* 0 */
|
||||
j wrap_irq_sw_evt1 /* 1 */
|
||||
j wrap_irq_sw_evt2 /* 2 */
|
||||
j wrap_irq_sw_evt3 /* 3 */
|
||||
j wrap_irq_sw_evt4 /* 4 */
|
||||
j wrap_irq_sw_evt5 /* 5 */
|
||||
j wrap_irq_sw_evt6 /* 6 */
|
||||
j wrap_irq_sw_evt7 /* 7 */
|
||||
j wrap_irq_reserved /* 8 */
|
||||
j wrap_irq_reserved /* 9 */
|
||||
j wrap_irq_timer_lo /* 10 */
|
||||
j wrap_irq_timer_hi /* 11 */
|
||||
j wrap_irq_reserved /* 12 */
|
||||
j wrap_irq_reserved /* 13 */
|
||||
j wrap_irq_reserved /* 14 */
|
||||
j wrap_irq_reserved /* 15 */
|
||||
j wrap_irq_reserved /* 16 */
|
||||
j wrap_irq_reserved /* 17 */
|
||||
j wrap_irq_reserved /* 18 */
|
||||
j wrap_irq_reserved /* 19 */
|
||||
j wrap_irq_reserved /* 20 */
|
||||
j wrap_irq_reserved /* 21 */
|
||||
j wrap_irq_reserved /* 22 */
|
||||
j wrap_irq_reserved /* 23 */
|
||||
j wrap_irq_reserved /* 24 */
|
||||
j wrap_irq_reserved /* 25 */
|
||||
j wrap_irq_reserved /* 26 */
|
||||
j wrap_irq_udma /* 27 */
|
||||
j wrap_irq_mpu /* 28 */
|
||||
j wrap_irq_udma_err /* 29 */
|
||||
j wrap_irq_fc_hp0 /* 30 */
|
||||
j wrap_irq_fc_hp1 /* 31 */
|
||||
|
||||
j reset_handler /* 32 */
|
||||
j illegal_insn_handler/* 33 */
|
||||
j ecall_insn_handler /* 34 */
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* This variable is pointed to the structure containing all information
|
||||
* exchanged with the platform loader. It is using a fixed address so that
|
||||
* the loader can also find it and then knows the address of the debug
|
||||
* structure.
|
||||
****************************************************************************/
|
||||
|
||||
.section .dbg_struct, "ax"
|
||||
.option norvc;
|
||||
.org 0x90
|
||||
.global __rt_debug_struct_ptr
|
||||
__rt_debug_struct_ptr:
|
||||
.word Debug_Struct
|
||||
|
||||
/****************************************************************************
|
||||
* This global variable is unsigned int g_idle_topstack and is exported here
|
||||
* only because of its coupling to idle thread stack.
|
||||
****************************************************************************/
|
||||
|
||||
.section .data
|
||||
.global g_idle_topstack
|
||||
g_idle_topstack:
|
||||
.word _idle_stack_end
|
||||
Executable
+2064
File diff suppressed because it is too large
Load Diff
+209
@@ -0,0 +1,209 @@
|
||||
/****************************************************************************
|
||||
* arch/risc-v/src/gap8/gap8_interrupt.c
|
||||
* GAP8 event system
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: hhuysqt <1020988872@qq.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* GAP8 features a FC controller and a 8-core cluster. IRQ from peripherals
|
||||
* have unique ID, which are dispatched to the FC or cluster by the SOC
|
||||
* event unit, and then by the FC event unit or cluster event unit, and
|
||||
* finally to FC or cluster. Peripherals share the same IRQ entry.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file interrupt.c
|
||||
* @brief support gap8 interrupt enable and disable
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-09-02
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: interrupt.c
|
||||
Description: support gap8 interrupt enable and disable
|
||||
Others: take nuttx/arch/risc-v/gap8/gap8_interrupt.c for references
|
||||
https://github.com/apache/incubator-nuttx.git
|
||||
History:
|
||||
1. Date: 2021-09-02
|
||||
Author: AIIT XUOS Lab
|
||||
Modification: modify interrupt enable/disable function and add interrupt process function
|
||||
*************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <arch_interrupt.h>
|
||||
#include <xs_base.h>
|
||||
#include <xs_isr.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
volatile uint32_t *g_current_regs;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Function exported to the NuttX kernel */
|
||||
|
||||
void up_mdelay(unsigned int time)
|
||||
{
|
||||
while (time--)
|
||||
{
|
||||
volatile int dummy = 200000;
|
||||
while (dummy--)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ArchDisableHwIrq
|
||||
*
|
||||
* Description:
|
||||
* Disable the IRQ specified by 'irq'. Mind the Machine privilege.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ArchDisableHwIrq(uint32_t irq_num)
|
||||
{
|
||||
FCEU->MASK_IRQ_AND = (1UL << irq_num);
|
||||
}
|
||||
/****************************************************************************
|
||||
* Name: ArchEnableHwIrq
|
||||
*
|
||||
* Description:
|
||||
* Enable the IRQ specified by 'irq'. Mind the Machine privilege.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ArchEnableHwIrq(uint32_t irq_num)
|
||||
{
|
||||
FCEU->MASK_IRQ_OR = (1 << irq_num);
|
||||
}
|
||||
|
||||
|
||||
x_base DisableLocalInterrupt(void)
|
||||
{
|
||||
x_base level;
|
||||
asm volatile("nop");
|
||||
asm volatile ("csrrci %0, mstatus, 8" : "=r"(level));
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Name: EnableLocalInterrupt
|
||||
*
|
||||
* Description:
|
||||
* Return the current interrupt state and enable interrupts
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void EnableLocalInterrupt(x_base oldstat)
|
||||
{
|
||||
x_base newstat;
|
||||
|
||||
asm volatile ("csrw mstatus, %0" :: "r"(oldstat));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gap8_sleep_wait_sw_evnt
|
||||
*
|
||||
* Description:
|
||||
* Sleep on specific event.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void gap8_sleep_wait_sw_evnt(uint32_t event_mask)
|
||||
{
|
||||
FCEU->MASK_OR = event_mask;
|
||||
// __builtin_pulp_event_unit_read((void *)&FCEU->EVENT_WAIT_CLEAR, 0);
|
||||
FCEU->MASK_AND = event_mask;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: irqinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the IRQ on FC.
|
||||
*
|
||||
****************************************************************************/
|
||||
extern void gap8_udma_doirq(int irq, void *arg);
|
||||
void irqinitialize(void)
|
||||
{
|
||||
/* Deactivate all the soc events */
|
||||
|
||||
SOC_EU->FC_MASK_MSB = 0xffffffff;
|
||||
SOC_EU->FC_MASK_LSB = 0xffffffff;
|
||||
|
||||
/* enable soc peripheral interrupt */
|
||||
|
||||
isrManager.done->registerIrq(GAP8_IRQ_FC_UDMA, gap8_udma_doirq, NONE);
|
||||
isrManager.done->enableIrq(GAP8_IRQ_FC_UDMA);
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gap8_dispatch_irq
|
||||
*
|
||||
* Description:
|
||||
* Called from IRQ vectors. Input vector id. Return SP pointer, modified
|
||||
* or not.
|
||||
*
|
||||
****************************************************************************/
|
||||
void *gap8_dispatch_irq(uint32_t vector, void *current_regs)
|
||||
{
|
||||
/* Clear pending bit and trigger a software event.
|
||||
* GAP8 would sleep on sw event 3 on up_idle().
|
||||
*/
|
||||
|
||||
FCEU->BUFFER_CLEAR = (1 << vector);
|
||||
EU_SW_EVNT_TRIG->TRIGGER_SET[3] = 0;
|
||||
|
||||
g_current_regs = current_regs;
|
||||
|
||||
|
||||
isrManager.done->incCounter();
|
||||
isrManager.done->handleIrq(vector);
|
||||
|
||||
isrManager.done->decCounter();
|
||||
}
|
||||
|
||||
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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>
|
||||
static volatile unsigned long tick_cycles = 0;
|
||||
int TickIsr(void)
|
||||
{
|
||||
TickAndTaskTimesliceUpdate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := boot.S intexc_gd32vf103.S interrupt.c tick.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef ARCH_INTERRUPT_H__
|
||||
#define ARCH_INTERRUPT_H__
|
||||
|
||||
#include <nuclei_sdk_soc.h>
|
||||
|
||||
#define ARCH_MAX_IRQ_NUM 128
|
||||
#define ARCH_IRQ_NUM_OFFSET 0
|
||||
|
||||
int ArchEnableHwIrq(uint32_t irq_num);
|
||||
int ArchDisableHwIrq(uint32_t irq_num);
|
||||
|
||||
#endif
|
||||
+486
@@ -0,0 +1,486 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/******************************************************************************
|
||||
* \file startup_gd32vf103.S
|
||||
* \brief NMSIS Nuclei N/NX Class Core based Core Device Startup File for
|
||||
* Device gd32vf103
|
||||
* \version V1.00
|
||||
* \date 21 Nov 2019
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "boot.h"
|
||||
#include "riscv_encoding.h"
|
||||
|
||||
#ifndef __riscv_32e
|
||||
#define portRegNum 30
|
||||
#else
|
||||
#define portRegNum 14
|
||||
#endif
|
||||
|
||||
#define portCONTEXT_SIZE ( portRegNum * REGBYTES )
|
||||
|
||||
# .align 2
|
||||
# .global eclic_msip_handler
|
||||
# eclic_msip_handler:
|
||||
# addi sp, sp, -portCONTEXT_SIZE
|
||||
# STORE x1, 1 * REGBYTES(sp) /* RA */
|
||||
# STORE x5, 2 * REGBYTES(sp)
|
||||
# STORE x6, 3 * REGBYTES(sp)
|
||||
# STORE x7, 4 * REGBYTES(sp)
|
||||
# STORE x8, 5 * REGBYTES(sp)
|
||||
# STORE x9, 6 * REGBYTES(sp)
|
||||
# STORE x10, 7 * REGBYTES(sp)
|
||||
# STORE x11, 8 * REGBYTES(sp)
|
||||
# STORE x12, 9 * REGBYTES(sp)
|
||||
# STORE x13, 10 * REGBYTES(sp)
|
||||
# STORE x14, 11 * REGBYTES(sp)
|
||||
# STORE x15, 12 * REGBYTES(sp)
|
||||
# #ifndef __riscv_32e
|
||||
# STORE x16, 13 * REGBYTES(sp)
|
||||
# STORE x17, 14 * REGBYTES(sp)
|
||||
# STORE x18, 15 * REGBYTES(sp)
|
||||
# STORE x19, 16 * REGBYTES(sp)
|
||||
# STORE x20, 17 * REGBYTES(sp)
|
||||
# STORE x21, 18 * REGBYTES(sp)
|
||||
# STORE x22, 19 * REGBYTES(sp)
|
||||
# STORE x23, 20 * REGBYTES(sp)
|
||||
# STORE x24, 21 * REGBYTES(sp)
|
||||
# STORE x25, 22 * REGBYTES(sp)
|
||||
# STORE x26, 23 * REGBYTES(sp)
|
||||
# STORE x27, 24 * REGBYTES(sp)
|
||||
# STORE x28, 25 * REGBYTES(sp)
|
||||
# STORE x29, 26 * REGBYTES(sp)
|
||||
# STORE x30, 27 * REGBYTES(sp)
|
||||
# STORE x31, 28 * REGBYTES(sp)
|
||||
# #endif
|
||||
# /* Push mstatus to stack */
|
||||
# csrr t0, CSR_MSTATUS
|
||||
# STORE t0, (portRegNum - 1) * REGBYTES(sp)
|
||||
|
||||
# /* Push additional registers */
|
||||
|
||||
# /* Store sp to task stack */
|
||||
# LOAD t0, rt_interrupt_from_thread
|
||||
# STORE sp, 0(t0)
|
||||
|
||||
# csrr t0, CSR_MEPC
|
||||
# STORE t0, 0(sp)
|
||||
|
||||
# jal xPortTaskSwitch
|
||||
|
||||
# /* Switch task context */
|
||||
# LOAD t0, rt_interrupt_to_thread
|
||||
# LOAD sp, 0x0(t0)
|
||||
|
||||
# /* Pop PC from stack and set MEPC */
|
||||
# LOAD t0, 0 * REGBYTES(sp)
|
||||
# csrw CSR_MEPC, t0
|
||||
# /* Pop additional registers */
|
||||
|
||||
# /* Pop mstatus from stack and set it */
|
||||
# LOAD t0, (portRegNum - 1) * REGBYTES(sp)
|
||||
# csrw CSR_MSTATUS, t0
|
||||
# /* Interrupt still disable here */
|
||||
# /* Restore Registers from Stack */
|
||||
# LOAD x1, 1 * REGBYTES(sp) /* RA */
|
||||
# LOAD x5, 2 * REGBYTES(sp)
|
||||
# LOAD x6, 3 * REGBYTES(sp)
|
||||
# LOAD x7, 4 * REGBYTES(sp)
|
||||
# LOAD x8, 5 * REGBYTES(sp)
|
||||
# LOAD x9, 6 * REGBYTES(sp)
|
||||
# LOAD x10, 7 * REGBYTES(sp)
|
||||
# LOAD x11, 8 * REGBYTES(sp)
|
||||
# LOAD x12, 9 * REGBYTES(sp)
|
||||
# LOAD x13, 10 * REGBYTES(sp)
|
||||
# LOAD x14, 11 * REGBYTES(sp)
|
||||
# LOAD x15, 12 * REGBYTES(sp)
|
||||
# #ifndef __riscv_32e
|
||||
# LOAD x16, 13 * REGBYTES(sp)
|
||||
# LOAD x17, 14 * REGBYTES(sp)
|
||||
# LOAD x18, 15 * REGBYTES(sp)
|
||||
# LOAD x19, 16 * REGBYTES(sp)
|
||||
# LOAD x20, 17 * REGBYTES(sp)
|
||||
# LOAD x21, 18 * REGBYTES(sp)
|
||||
# LOAD x22, 19 * REGBYTES(sp)
|
||||
# LOAD x23, 20 * REGBYTES(sp)
|
||||
# LOAD x24, 21 * REGBYTES(sp)
|
||||
# LOAD x25, 22 * REGBYTES(sp)
|
||||
# LOAD x26, 23 * REGBYTES(sp)
|
||||
# LOAD x27, 24 * REGBYTES(sp)
|
||||
# LOAD x28, 25 * REGBYTES(sp)
|
||||
# LOAD x29, 26 * REGBYTES(sp)
|
||||
# LOAD x30, 27 * REGBYTES(sp)
|
||||
# LOAD x31, 28 * REGBYTES(sp)
|
||||
# #endif
|
||||
|
||||
# addi sp, sp, portCONTEXT_SIZE
|
||||
# mret
|
||||
.extern xPortTaskSwitch
|
||||
|
||||
.align 2
|
||||
.global eclic_msip_handler
|
||||
eclic_msip_handler:
|
||||
|
||||
SAVE_X_REGISTERS
|
||||
|
||||
jal xPortTaskSwitch
|
||||
|
||||
call KTaskOsAssignAfterIrq
|
||||
j SwitchKTaskContextExit
|
||||
|
||||
|
||||
.macro DECLARE_INT_HANDLER INT_HDL_NAME
|
||||
#if defined(__riscv_xlen) && (__riscv_xlen == 32)
|
||||
.word \INT_HDL_NAME
|
||||
#else
|
||||
.dword \INT_HDL_NAME
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Put the interrupt vectors in this section according to vector remapped or not:
|
||||
* .vtable: vector table's LMA and VMA are the same, it is not remapped
|
||||
* .vtable_ilm: vector table's LMA and VMA are different, it is remapped, and
|
||||
* VECTOR_TABLE_REMAPPED need to be defined
|
||||
*/
|
||||
#if defined(VECTOR_TABLE_REMAPPED)
|
||||
.section .vtable_ilm
|
||||
#else
|
||||
.section .vtable
|
||||
#endif
|
||||
|
||||
.weak eclic_msip_handler
|
||||
.weak eclic_mtip_handler
|
||||
.weak eclic_bwei_handler
|
||||
.weak eclic_pmovi_handler
|
||||
.weak WWDGT_IRQHandler
|
||||
.weak LVD_IRQHandler
|
||||
.weak TAMPER_IRQHandler
|
||||
.weak RTC_IRQHandler
|
||||
.weak FMC_IRQHandler
|
||||
.weak RCU_IRQHandler
|
||||
.weak EXTI0_IRQHandler
|
||||
.weak EXTI1_IRQHandler
|
||||
.weak EXTI2_IRQHandler
|
||||
.weak EXTI3_IRQHandler
|
||||
.weak EXTI4_IRQHandler
|
||||
.weak DMA0_Channel0_IRQHandler
|
||||
.weak DMA0_Channel1_IRQHandler
|
||||
.weak DMA0_Channel2_IRQHandler
|
||||
.weak DMA0_Channel3_IRQHandler
|
||||
.weak DMA0_Channel4_IRQHandler
|
||||
.weak DMA0_Channel5_IRQHandler
|
||||
.weak DMA0_Channel6_IRQHandler
|
||||
.weak ADC0_1_IRQHandler
|
||||
.weak CAN0_TX_IRQHandler
|
||||
.weak CAN0_RX0_IRQHandler
|
||||
.weak CAN0_RX1_IRQHandler
|
||||
.weak CAN0_EWMC_IRQHandler
|
||||
.weak EXTI5_9_IRQHandler
|
||||
.weak TIMER0_BRK_IRQHandler
|
||||
.weak TIMER0_UP_IRQHandler
|
||||
.weak TIMER0_TRG_CMT_IRQHandler
|
||||
.weak TIMER0_Channel_IRQHandler
|
||||
.weak TIMER1_IRQHandler
|
||||
.weak TIMER2_IRQHandler
|
||||
.weak TIMER3_IRQHandler
|
||||
.weak I2C0_EV_IRQHandler
|
||||
.weak I2C0_ER_IRQHandler
|
||||
.weak I2C1_EV_IRQHandler
|
||||
.weak I2C1_ER_IRQHandler
|
||||
.weak SPI0_IRQHandler
|
||||
.weak SPI1_IRQHandler
|
||||
.weak USART0_IRQHandler
|
||||
.weak USART1_IRQHandler
|
||||
.weak USART2_IRQHandler
|
||||
.weak EXTI10_15_IRQHandler
|
||||
.weak RTC_Alarm_IRQHandler
|
||||
.weak USBFS_WKUP_IRQHandler
|
||||
.weak EXMC_IRQHandler
|
||||
.weak TIMER4_IRQHandler
|
||||
.weak SPI2_IRQHandler
|
||||
.weak UART3_IRQHandler
|
||||
.weak UART4_IRQHandler
|
||||
.weak TIMER5_IRQHandler
|
||||
.weak TIMER6_IRQHandler
|
||||
.weak DMA1_Channel0_IRQHandler
|
||||
.weak DMA1_Channel1_IRQHandler
|
||||
.weak DMA1_Channel2_IRQHandler
|
||||
.weak DMA1_Channel3_IRQHandler
|
||||
.weak DMA1_Channel4_IRQHandler
|
||||
.weak CAN1_TX_IRQHandler
|
||||
.weak CAN1_RX0_IRQHandler
|
||||
.weak CAN1_RX1_IRQHandler
|
||||
.weak CAN1_EWMC_IRQHandler
|
||||
.weak USBFS_IRQHandler
|
||||
|
||||
|
||||
.globl vector_base
|
||||
.type vector_base, @object
|
||||
vector_base:
|
||||
#ifndef VECTOR_TABLE_REMAPPED
|
||||
j _start /* 0: Reserved, Jump to _start when reset for vector table not remapped cases.*/
|
||||
.align LOG_REGBYTES /* Need to align 4 byte for RV32, 8 Byte for RV64 */
|
||||
#else
|
||||
DECLARE_INT_HANDLER default_intexc_handler /* 0: Reserved, default handler for vector table remapped cases */
|
||||
#endif
|
||||
DECLARE_INT_HANDLER default_intexc_handler /* 1: Reserved */
|
||||
DECLARE_INT_HANDLER default_intexc_handler /* 2: Reserved */
|
||||
DECLARE_INT_HANDLER eclic_msip_handler /* 3: Machine software interrupt */
|
||||
|
||||
DECLARE_INT_HANDLER default_intexc_handler /* 4: Reserved */
|
||||
DECLARE_INT_HANDLER default_intexc_handler /* 5: Reserved */
|
||||
DECLARE_INT_HANDLER default_intexc_handler /* 6: Reserved */
|
||||
DECLARE_INT_HANDLER eclic_mtip_handler /* 7: Machine timer interrupt */
|
||||
|
||||
DECLARE_INT_HANDLER default_intexc_handler /* 8: Reserved */
|
||||
DECLARE_INT_HANDLER default_intexc_handler /* 9: Reserved */
|
||||
DECLARE_INT_HANDLER default_intexc_handler /* 10: Reserved */
|
||||
DECLARE_INT_HANDLER default_intexc_handler /* 11: Reserved */
|
||||
|
||||
DECLARE_INT_HANDLER default_intexc_handler /* 12: Reserved */
|
||||
DECLARE_INT_HANDLER default_intexc_handler /* 13: Reserved */
|
||||
DECLARE_INT_HANDLER default_intexc_handler /* 14: Reserved */
|
||||
DECLARE_INT_HANDLER default_intexc_handler /* 15: Reserved */
|
||||
|
||||
DECLARE_INT_HANDLER default_intexc_handler /* 16: Reserved */
|
||||
DECLARE_INT_HANDLER eclic_bwei_handler /* 17: Bus Error interrupt */
|
||||
DECLARE_INT_HANDLER eclic_pmovi_handler /* 18: Performance Monitor */
|
||||
|
||||
DECLARE_INT_HANDLER WWDGT_IRQHandler
|
||||
DECLARE_INT_HANDLER LVD_IRQHandler
|
||||
DECLARE_INT_HANDLER TAMPER_IRQHandler
|
||||
DECLARE_INT_HANDLER RTC_IRQHandler
|
||||
DECLARE_INT_HANDLER FMC_IRQHandler
|
||||
DECLARE_INT_HANDLER RCU_IRQHandler
|
||||
DECLARE_INT_HANDLER EXTI0_IRQHandler
|
||||
DECLARE_INT_HANDLER EXTI1_IRQHandler
|
||||
DECLARE_INT_HANDLER EXTI2_IRQHandler
|
||||
DECLARE_INT_HANDLER EXTI3_IRQHandler
|
||||
DECLARE_INT_HANDLER EXTI4_IRQHandler
|
||||
DECLARE_INT_HANDLER DMA0_Channel0_IRQHandler
|
||||
DECLARE_INT_HANDLER DMA0_Channel1_IRQHandler
|
||||
DECLARE_INT_HANDLER DMA0_Channel2_IRQHandler
|
||||
DECLARE_INT_HANDLER DMA0_Channel3_IRQHandler
|
||||
DECLARE_INT_HANDLER DMA0_Channel4_IRQHandler
|
||||
DECLARE_INT_HANDLER DMA0_Channel5_IRQHandler
|
||||
DECLARE_INT_HANDLER DMA0_Channel6_IRQHandler
|
||||
DECLARE_INT_HANDLER ADC0_1_IRQHandler
|
||||
DECLARE_INT_HANDLER CAN0_TX_IRQHandler
|
||||
DECLARE_INT_HANDLER CAN0_RX0_IRQHandler
|
||||
DECLARE_INT_HANDLER CAN0_RX1_IRQHandler
|
||||
DECLARE_INT_HANDLER CAN0_EWMC_IRQHandler
|
||||
DECLARE_INT_HANDLER EXTI5_9_IRQHandler
|
||||
DECLARE_INT_HANDLER TIMER0_BRK_IRQHandler
|
||||
DECLARE_INT_HANDLER TIMER0_UP_IRQHandler
|
||||
DECLARE_INT_HANDLER TIMER0_TRG_CMT_IRQHandler
|
||||
DECLARE_INT_HANDLER TIMER0_Channel_IRQHandler
|
||||
DECLARE_INT_HANDLER TIMER1_IRQHandler
|
||||
DECLARE_INT_HANDLER TIMER2_IRQHandler
|
||||
DECLARE_INT_HANDLER TIMER3_IRQHandler
|
||||
DECLARE_INT_HANDLER I2C0_EV_IRQHandler
|
||||
DECLARE_INT_HANDLER I2C0_ER_IRQHandler
|
||||
DECLARE_INT_HANDLER I2C1_EV_IRQHandler
|
||||
DECLARE_INT_HANDLER I2C1_ER_IRQHandler
|
||||
DECLARE_INT_HANDLER SPI0_IRQHandler
|
||||
DECLARE_INT_HANDLER SPI1_IRQHandler
|
||||
DECLARE_INT_HANDLER USART0_IRQHandler
|
||||
DECLARE_INT_HANDLER USART1_IRQHandler
|
||||
DECLARE_INT_HANDLER USART2_IRQHandler
|
||||
DECLARE_INT_HANDLER EXTI10_15_IRQHandler
|
||||
DECLARE_INT_HANDLER RTC_Alarm_IRQHandler
|
||||
DECLARE_INT_HANDLER USBFS_WKUP_IRQHandler
|
||||
DECLARE_INT_HANDLER default_intexc_handler
|
||||
DECLARE_INT_HANDLER default_intexc_handler
|
||||
DECLARE_INT_HANDLER default_intexc_handler
|
||||
DECLARE_INT_HANDLER default_intexc_handler
|
||||
DECLARE_INT_HANDLER default_intexc_handler
|
||||
DECLARE_INT_HANDLER EXMC_IRQHandler
|
||||
DECLARE_INT_HANDLER default_intexc_handler
|
||||
DECLARE_INT_HANDLER TIMER4_IRQHandler
|
||||
DECLARE_INT_HANDLER SPI2_IRQHandler
|
||||
DECLARE_INT_HANDLER UART3_IRQHandler
|
||||
DECLARE_INT_HANDLER UART4_IRQHandler
|
||||
DECLARE_INT_HANDLER TIMER5_IRQHandler
|
||||
DECLARE_INT_HANDLER TIMER6_IRQHandler
|
||||
DECLARE_INT_HANDLER DMA1_Channel0_IRQHandler
|
||||
DECLARE_INT_HANDLER DMA1_Channel1_IRQHandler
|
||||
DECLARE_INT_HANDLER DMA1_Channel2_IRQHandler
|
||||
DECLARE_INT_HANDLER DMA1_Channel3_IRQHandler
|
||||
DECLARE_INT_HANDLER DMA1_Channel4_IRQHandler
|
||||
DECLARE_INT_HANDLER default_intexc_handler
|
||||
DECLARE_INT_HANDLER default_intexc_handler
|
||||
DECLARE_INT_HANDLER CAN1_TX_IRQHandler
|
||||
DECLARE_INT_HANDLER CAN1_RX0_IRQHandler
|
||||
DECLARE_INT_HANDLER CAN1_RX1_IRQHandler
|
||||
DECLARE_INT_HANDLER CAN1_EWMC_IRQHandler
|
||||
DECLARE_INT_HANDLER USBFS_IRQHandler
|
||||
|
||||
.extern Gd32vf103Start
|
||||
.extern SystemInit
|
||||
.extern _premain_init
|
||||
|
||||
|
||||
.section .init
|
||||
|
||||
.globl _start
|
||||
.type _start, @function
|
||||
|
||||
/**
|
||||
* Reset Handler called on controller reset
|
||||
*/
|
||||
_start:
|
||||
/* ===== Startup Stage 1 ===== */
|
||||
/* Disable Global Interrupt */
|
||||
csrc CSR_MSTATUS, MSTATUS_MIE
|
||||
/* Jump to logical address first to ensure correct operation of RAM region */
|
||||
la a0, _start
|
||||
li a1, 1
|
||||
slli a1, a1, 29
|
||||
bleu a1, a0, _start0800
|
||||
srli a1, a1, 2
|
||||
bleu a1, a0, _start0800
|
||||
la a0, _start0800
|
||||
add a0, a0, a1
|
||||
jr a0
|
||||
|
||||
_start0800:
|
||||
/* Initialize GP and Stack Pointer SP */
|
||||
.option push
|
||||
.option norelax
|
||||
la gp, __global_pointer$
|
||||
|
||||
.option pop
|
||||
la sp, _sp
|
||||
|
||||
/*
|
||||
* Set the the NMI base mnvec to share
|
||||
* with mtvec by setting CSR_MMISC_CTL
|
||||
* bit 9 NMI_CAUSE_FFF to 1
|
||||
*/
|
||||
li t0, MMISC_CTL_NMI_CAUSE_FFF
|
||||
csrs CSR_MMISC_CTL, t0
|
||||
|
||||
/*
|
||||
* Intialize ECLIC vector interrupt
|
||||
* base address mtvt to vector_base
|
||||
*/
|
||||
la t0, vector_base
|
||||
csrw CSR_MTVT, t0
|
||||
|
||||
/*
|
||||
* Set ECLIC non-vector entry to be controlled
|
||||
* by mtvt2 CSR register.
|
||||
* Intialize ECLIC non-vector interrupt
|
||||
* base address mtvt2 to irq_entry.
|
||||
*/
|
||||
la t0, irq_entry
|
||||
csrw CSR_MTVT2, t0
|
||||
csrs CSR_MTVT2, 0x1
|
||||
|
||||
/*
|
||||
* Set Exception Entry MTVEC to exc_entry
|
||||
* Due to settings above, Exception and NMI
|
||||
* will share common entry.
|
||||
*/
|
||||
la t0, exc_entry
|
||||
csrw CSR_MTVEC, t0
|
||||
|
||||
/* Set the interrupt processing mode to ECLIC mode */
|
||||
li t0, 0x3f
|
||||
csrc CSR_MTVEC, t0
|
||||
csrs CSR_MTVEC, 0x3
|
||||
|
||||
/* ===== Startup Stage 2 ===== */
|
||||
|
||||
#if defined(__riscv_flen) && __riscv_flen > 0
|
||||
/* Enable FPU */
|
||||
li t0, MSTATUS_FS
|
||||
csrs mstatus, t0
|
||||
csrw fcsr, x0
|
||||
#endif
|
||||
|
||||
/* Enable mcycle and minstret counter */
|
||||
csrci CSR_MCOUNTINHIBIT, 0x5
|
||||
|
||||
/* ===== Startup Stage 3 ===== */
|
||||
/*
|
||||
* Load code section from FLASH to ILM
|
||||
* when code LMA is different with VMA
|
||||
*/
|
||||
la a0, _ilm_lma
|
||||
la a1, _ilm
|
||||
/* If the ILM phy-address same as the logic-address, then quit */
|
||||
beq a0, a1, 2f
|
||||
la a2, _eilm
|
||||
bgeu a1, a2, 2f
|
||||
|
||||
1:
|
||||
/* Load code section if necessary */
|
||||
lw t0, (a0)
|
||||
sw t0, (a1)
|
||||
addi a0, a0, 4
|
||||
addi a1, a1, 4
|
||||
bltu a1, a2, 1b
|
||||
2:
|
||||
/* Load data section */
|
||||
la a0, _data_lma
|
||||
la a1, _data
|
||||
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, __bss_start
|
||||
la a1, _end
|
||||
bgeu a0, a1, 2f
|
||||
1:
|
||||
sw zero, (a0)
|
||||
addi a0, a0, 4
|
||||
bltu a0, a1, 1b
|
||||
2:
|
||||
/*
|
||||
* Call vendor defined SystemInit to
|
||||
* initialize the micro-controller system
|
||||
*/
|
||||
call SystemInit
|
||||
|
||||
/* Call global constructors */
|
||||
la a0, __libc_fini_array
|
||||
call atexit
|
||||
/* Call C/C++ constructor start up code */
|
||||
call __libc_init_array
|
||||
|
||||
/* do pre-init steps before main */
|
||||
call _premain_init
|
||||
|
||||
/* ===== Call entry Function ===== */
|
||||
/* argc = argv = 0 */
|
||||
li a0, 0
|
||||
li a1, 0
|
||||
|
||||
j Gd32vf103Start
|
||||
|
||||
1:
|
||||
j 1b
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @file interrupt.c
|
||||
* @brief support gap8 interrupt enable and disable
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-09-02
|
||||
*/
|
||||
|
||||
|
||||
#include <arch_interrupt.h>
|
||||
#include <xs_base.h>
|
||||
#include <xs_isr.h>
|
||||
#include <core_feature_base.h>
|
||||
|
||||
int ArchDisableHwIrq(uint32_t irq_num)
|
||||
{
|
||||
ECLIC_DisableIRQ(irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ArchEnableHwIrq(uint32_t irq_num)
|
||||
{
|
||||
ECLIC_EnableIRQ(irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
x_base DisableLocalInterrupt(void)
|
||||
{
|
||||
return __RV_CSR_READ_CLEAR(CSR_MSTATUS, MSTATUS_MIE);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: EnableLocalInterrupt
|
||||
*
|
||||
* Description:
|
||||
* Return the current interrupt state and enable interrupts
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void EnableLocalInterrupt(x_base oldstat)
|
||||
{
|
||||
__RV_CSR_WRITE(CSR_MSTATUS, oldstat);
|
||||
}
|
||||
|
||||
|
||||
// extern void KTaskOsAssignAfterIrq(void *context);
|
||||
|
||||
// void IsrEntry()
|
||||
// {
|
||||
// uint32 ipsr;
|
||||
|
||||
// isrManager.done->incCounter();
|
||||
// isrManager.done->handleIrq(ipsr);
|
||||
// KTaskOsAssignAfterIrq(NONE);
|
||||
// isrManager.done->decCounter();
|
||||
|
||||
// }
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/******************************************************************************
|
||||
* \file intexc_gd32vf103.S
|
||||
* \brief NMSIS Interrupt and Exception Handling Template File
|
||||
* for Device gd32vf103
|
||||
* \version V1.00
|
||||
* \date 7 Jan 2020
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "riscv_encoding.h"
|
||||
|
||||
/**
|
||||
* \brief Global interrupt disabled
|
||||
* \details
|
||||
* This function disable global interrupt.
|
||||
* \remarks
|
||||
* - All the interrupt requests will be ignored by CPU.
|
||||
*/
|
||||
.macro DISABLE_MIE
|
||||
csrc CSR_MSTATUS, MSTATUS_MIE
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Macro for context save
|
||||
* \details
|
||||
* This macro save ABI defined caller saved registers in the stack.
|
||||
* \remarks
|
||||
* - This Macro could use to save context when you enter to interrupt
|
||||
* or exception
|
||||
*/
|
||||
/* Save caller registers */
|
||||
.macro SAVE_CONTEXT
|
||||
/* Allocate stack space for context saving */
|
||||
#ifndef __riscv_32e
|
||||
addi sp, sp, -20*REGBYTES
|
||||
#else
|
||||
addi sp, sp, -14*REGBYTES
|
||||
#endif /* __riscv_32e */
|
||||
|
||||
STORE x1, 0*REGBYTES(sp)
|
||||
STORE x4, 1*REGBYTES(sp)
|
||||
STORE x5, 2*REGBYTES(sp)
|
||||
STORE x6, 3*REGBYTES(sp)
|
||||
STORE x7, 4*REGBYTES(sp)
|
||||
STORE x10, 5*REGBYTES(sp)
|
||||
STORE x11, 6*REGBYTES(sp)
|
||||
STORE x12, 7*REGBYTES(sp)
|
||||
STORE x13, 8*REGBYTES(sp)
|
||||
STORE x14, 9*REGBYTES(sp)
|
||||
STORE x15, 10*REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
STORE x16, 14*REGBYTES(sp)
|
||||
STORE x17, 15*REGBYTES(sp)
|
||||
STORE x28, 16*REGBYTES(sp)
|
||||
STORE x29, 17*REGBYTES(sp)
|
||||
STORE x30, 18*REGBYTES(sp)
|
||||
STORE x31, 19*REGBYTES(sp)
|
||||
#endif /* __riscv_32e */
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Macro for restore caller registers
|
||||
* \details
|
||||
* This macro restore ABI defined caller saved registers from stack.
|
||||
* \remarks
|
||||
* - You could use this macro to restore context before you want return
|
||||
* from interrupt or exeception
|
||||
*/
|
||||
/* Restore caller registers */
|
||||
.macro RESTORE_CONTEXT
|
||||
LOAD x1, 0*REGBYTES(sp)
|
||||
LOAD x4, 1*REGBYTES(sp)
|
||||
LOAD x5, 2*REGBYTES(sp)
|
||||
LOAD x6, 3*REGBYTES(sp)
|
||||
LOAD x7, 4*REGBYTES(sp)
|
||||
LOAD x10, 5*REGBYTES(sp)
|
||||
LOAD x11, 6*REGBYTES(sp)
|
||||
LOAD x12, 7*REGBYTES(sp)
|
||||
LOAD x13, 8*REGBYTES(sp)
|
||||
LOAD x14, 9*REGBYTES(sp)
|
||||
LOAD x15, 10*REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
LOAD x16, 14*REGBYTES(sp)
|
||||
LOAD x17, 15*REGBYTES(sp)
|
||||
LOAD x28, 16*REGBYTES(sp)
|
||||
LOAD x29, 17*REGBYTES(sp)
|
||||
LOAD x30, 18*REGBYTES(sp)
|
||||
LOAD x31, 19*REGBYTES(sp)
|
||||
|
||||
/* De-allocate the stack space */
|
||||
addi sp, sp, 20*REGBYTES
|
||||
#else
|
||||
/* De-allocate the stack space */
|
||||
addi sp, sp, 14*REGBYTES
|
||||
#endif /* __riscv_32e */
|
||||
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Macro for save necessary CSRs to stack
|
||||
* \details
|
||||
* This macro store MCAUSE, MEPC, MSUBM to stack.
|
||||
*/
|
||||
.macro SAVE_CSR_CONTEXT
|
||||
/* Store CSR mcause to stack using pushmcause */
|
||||
csrrwi x0, CSR_PUSHMCAUSE, 11
|
||||
/* Store CSR mepc to stack using pushmepc */
|
||||
csrrwi x0, CSR_PUSHMEPC, 12
|
||||
/* Store CSR msub to stack using pushmsub */
|
||||
csrrwi x0, CSR_PUSHMSUBM, 13
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Macro for restore necessary CSRs from stack
|
||||
* \details
|
||||
* This macro restore MSUBM, MEPC, MCAUSE from stack.
|
||||
*/
|
||||
.macro RESTORE_CSR_CONTEXT
|
||||
LOAD x5, 13*REGBYTES(sp)
|
||||
csrw CSR_MSUBM, x5
|
||||
LOAD x5, 12*REGBYTES(sp)
|
||||
csrw CSR_MEPC, x5
|
||||
LOAD x5, 11*REGBYTES(sp)
|
||||
csrw CSR_MCAUSE, x5
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Exception/NMI Entry
|
||||
* \details
|
||||
* This function provide common entry functions for exception/nmi.
|
||||
* \remarks
|
||||
* This function provide a default exception/nmi entry.
|
||||
* ABI defined caller save register and some CSR registers
|
||||
* to be saved before enter interrupt handler and be restored before return.
|
||||
*/
|
||||
.section .text.trap
|
||||
/* In CLIC mode, the exeception entry must be 64bytes aligned */
|
||||
.align 6
|
||||
.global exc_entry
|
||||
.weak exc_entry
|
||||
exc_entry:
|
||||
/* Save the caller saving registers (context) */
|
||||
SAVE_CONTEXT
|
||||
/* Save the necessary CSR registers */
|
||||
SAVE_CSR_CONTEXT
|
||||
|
||||
/*
|
||||
* Set the exception handler function arguments
|
||||
* argument 1: mcause value
|
||||
* argument 2: current stack point(SP) value
|
||||
*/
|
||||
csrr a0, mcause
|
||||
mv a1, sp
|
||||
/*
|
||||
* TODO: Call the exception handler function
|
||||
* By default, the function template is provided in
|
||||
* system_Device.c, you can adjust it as you want
|
||||
*/
|
||||
call core_exception_handler
|
||||
|
||||
/* Restore the necessary CSR registers */
|
||||
RESTORE_CSR_CONTEXT
|
||||
/* Restore the caller saving registers (context) */
|
||||
RESTORE_CONTEXT
|
||||
|
||||
/* Return to regular code */
|
||||
mret
|
||||
|
||||
/**
|
||||
* \brief Non-Vector Interrupt Entry
|
||||
* \details
|
||||
* This function provide common entry functions for handling
|
||||
* non-vector interrupts
|
||||
* \remarks
|
||||
* This function provide a default non-vector interrupt entry.
|
||||
* ABI defined caller save register and some CSR registers need
|
||||
* to be saved before enter interrupt handler and be restored before return.
|
||||
*/
|
||||
.section .text.irq
|
||||
/* In CLIC mode, the interrupt entry must be 4bytes aligned */
|
||||
.align 2
|
||||
.global irq_entry
|
||||
.weak irq_entry
|
||||
/* This label will be set to MTVT2 register */
|
||||
irq_entry:
|
||||
/* Save the caller saving registers (context) */
|
||||
SAVE_CONTEXT
|
||||
/* Save the necessary CSR registers */
|
||||
SAVE_CSR_CONTEXT
|
||||
|
||||
/* This special CSR read/write operation, which is actually
|
||||
* claim the CLIC to find its pending highest ID, if the ID
|
||||
* is not 0, then automatically enable the mstatus.MIE, and
|
||||
* jump to its vector-entry-label, and update the link register
|
||||
*/
|
||||
csrrw ra, CSR_JALMNXTI, ra
|
||||
|
||||
/* Critical section with interrupts disabled */
|
||||
DISABLE_MIE
|
||||
|
||||
/* Restore the necessary CSR registers */
|
||||
RESTORE_CSR_CONTEXT
|
||||
/* Restore the caller saving registers (context) */
|
||||
RESTORE_CONTEXT
|
||||
|
||||
/* Return to regular code */
|
||||
mret
|
||||
|
||||
/* Default Handler for Exceptions / Interrupts */
|
||||
.global default_intexc_handler
|
||||
.weak default_intexc_handler
|
||||
Undef_Handler:
|
||||
default_intexc_handler:
|
||||
1:
|
||||
j 1b
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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 <gd32vf103.h>
|
||||
#include <core_feature_timer.h>
|
||||
|
||||
#define SysTick_Handler eclic_mtip_handler
|
||||
|
||||
/* This is the timer interrupt service routine. */
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
SysTick_Reload(SYSTICK_TICK_CONST);
|
||||
|
||||
// isrManager.done->incCounter();
|
||||
|
||||
TickAndTaskTimesliceUpdate();
|
||||
|
||||
// isrManager.done->decCounter();
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
SRC_FILES := interrupt.c boot.S tick.c
|
||||
|
||||
ifeq ($(CONFIG_ARCH_SMP),y)
|
||||
SRC_FILES += smp_support.c
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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 ARCH_INTERRUPT_H__
|
||||
#define ARCH_INTERRUPT_H__
|
||||
|
||||
#include <plic.h>
|
||||
|
||||
#define ARCH_MAX_IRQ_NUM IRQN_MAX
|
||||
|
||||
#define ARCH_IRQ_NUM_OFFSET 0
|
||||
|
||||
int32 ArchEnableHwIrq(uint32 irq_num);
|
||||
int32 ArchDisableHwIrq(uint32 irq_num);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018/10/01 Bernard The first version
|
||||
* 2018/12/27 Jesven Add SMP support
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: boot.S
|
||||
Description: K210 boot code
|
||||
Others: take RT-Thread v4.0.2/libcpu/risc-v/k210/startup_gcc.S
|
||||
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
|
||||
History:
|
||||
1. Date: 2021-04-25
|
||||
Author: AIIT XUOS Lab
|
||||
*************************************************/
|
||||
|
||||
#include "boot.h"
|
||||
|
||||
#define MSTATUS_FS 0x00006000U
|
||||
#define __STACKSIZE__ 4096
|
||||
#define K210_CPU0_STACKTOP (__stack_tp0)
|
||||
#define K210_CPU1_STACKTOP (__stack_tp1)
|
||||
|
||||
.globl _begin
|
||||
.section ".start", "ax"
|
||||
_begin:
|
||||
j 1f
|
||||
.word 0xdeadbeef
|
||||
.align 3
|
||||
.globl g_wake_up
|
||||
g_wake_up:
|
||||
.dword 1
|
||||
.dword 0
|
||||
1:
|
||||
csrw mideleg, 0
|
||||
csrw medeleg, 0
|
||||
csrw mie, 0
|
||||
csrw mip, 0
|
||||
la t0, save_hw_context
|
||||
csrw mtvec, t0
|
||||
|
||||
ZERO_X_REGISTERS
|
||||
|
||||
li t0, MSTATUS_FS
|
||||
csrs mstatus, t0
|
||||
|
||||
#ifndef BSP_USING_QEMU
|
||||
ZERO_F_REGISTERS
|
||||
#endif
|
||||
|
||||
.option push
|
||||
.option norelax
|
||||
la gp, __global_pointer$
|
||||
.option pop
|
||||
|
||||
csrr a0, mhartid
|
||||
|
||||
bnez a0, 1f
|
||||
la sp, K210_CPU0_STACKTOP
|
||||
j 2f
|
||||
1:
|
||||
la sp, K210_CPU1_STACKTOP
|
||||
2:
|
||||
|
||||
j Kd233Start
|
||||
|
||||
|
||||
|
||||
.data
|
||||
.globl cpu2_boot_flag
|
||||
.align 3
|
||||
cpu2_boot_flag:
|
||||
.8byte 0
|
||||
|
||||
|
||||
.section .text.entry
|
||||
.align 2
|
||||
.globl save_hw_context
|
||||
save_hw_context:
|
||||
|
||||
SAVE_X_REGISTERS
|
||||
|
||||
mv fp, sp
|
||||
|
||||
csrr t0, mhartid
|
||||
|
||||
#ifdef TASK_ISOLATION
|
||||
csrr a0, mcause
|
||||
srli a0, a0, 63
|
||||
andi a0, a0, 0x1
|
||||
beqz a0, 1f
|
||||
#endif
|
||||
la sp, __stack_start__
|
||||
addi t1, t0, 1
|
||||
li t2, __STACKSIZE__
|
||||
mul t1, t1, t2
|
||||
add sp, sp, t1 /* sp = (cpuid + 1) * __STACKSIZE__ + __stack_start__ */
|
||||
|
||||
1:
|
||||
csrr a0, mcause
|
||||
csrr a1, mepc
|
||||
mv a2, fp
|
||||
call HandleTrap
|
||||
|
||||
mv sp, fp
|
||||
mv a0, fp
|
||||
call KTaskOsAssignAfterIrq
|
||||
j SwitchKTaskContextExit
|
||||
@@ -0,0 +1,423 @@
|
||||
/* Copyright 2018 Canaan Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file interrupt.c
|
||||
* @brief support k210 interrupt configure
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-29
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: interrupt.c
|
||||
Description: support k210 interrupt configure
|
||||
Others: take plic.c for references from Canaan k210 SDK
|
||||
* https://canaan-creative.com/developer
|
||||
History:
|
||||
1. Date: 2021-04-29
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. support K210 interrupt configure
|
||||
*************************************************/
|
||||
|
||||
#include "tick.h"
|
||||
#include <clint.h>
|
||||
#include <interrupt.h>
|
||||
#include <plic.h>
|
||||
#include <xs_assign.h>
|
||||
#include <xs_base.h>
|
||||
#include <xs_isr.h>
|
||||
#include <xs_ktask.h>
|
||||
#ifdef TASK_ISOLATION
|
||||
#include <xs_service.h>
|
||||
#endif
|
||||
|
||||
#define CPU_NUM 2
|
||||
|
||||
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 EnableHwclintIpi(void)
|
||||
{
|
||||
SET_CSR(mie, MIP_MSIP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DisableHwclintIpi(void)
|
||||
{
|
||||
CLEAR_CSR(mie, MIP_MSIP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EnableHwplicIrq(plic_irq_t irq_number)
|
||||
{
|
||||
unsigned long core_id = 0;
|
||||
|
||||
if (PLIC_NUM_SOURCES < irq_number || 0 > irq_number)
|
||||
return -1;
|
||||
uint32_t current = plic->target_enables.target[core_id].enable[irq_number / 32];
|
||||
current |= (uint32_t)1 << (irq_number % 32);
|
||||
plic->target_enables.target[core_id].enable[irq_number / 32] = current;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DisableHwplicIrq(plic_irq_t irq_number)
|
||||
{
|
||||
unsigned long core_id = 0;
|
||||
|
||||
if (PLIC_NUM_SOURCES < irq_number || 0 > irq_number)
|
||||
return -1;
|
||||
uint32_t current = plic->target_enables.target[core_id].enable[irq_number / 32];
|
||||
current &= ~((uint32_t)1 << (irq_number % 32));
|
||||
plic->target_enables.target[core_id].enable[irq_number / 32] = current;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InitHwinterrupt(void)
|
||||
{
|
||||
int idx;
|
||||
int cpuid;
|
||||
|
||||
cpuid = current_coreid();
|
||||
|
||||
for (idx = 0; idx < ((PLIC_NUM_SOURCES + 32u) / 32u); idx ++)
|
||||
plic->target_enables.target[cpuid].enable[idx] = 0;
|
||||
|
||||
for (idx = 0; idx < PLIC_NUM_SOURCES; idx++)
|
||||
plic->source_priorities.priority[idx] = 0;
|
||||
|
||||
plic->targets.target[cpuid].priority_threshold = 0;
|
||||
|
||||
SET_CSR(mie, MIP_MEIP);
|
||||
}
|
||||
|
||||
void InitHwSecondaryInterrupt(void)
|
||||
{
|
||||
int idx;
|
||||
int cpuid;
|
||||
|
||||
cpuid = current_coreid();
|
||||
|
||||
for (idx = 0; idx < ((PLIC_NUM_SOURCES + 32u) / 32u); idx ++)
|
||||
plic->target_enables.target[cpuid].enable[idx] = 0;
|
||||
|
||||
plic->targets.target[cpuid].priority_threshold = 0;
|
||||
|
||||
SET_CSR(mie, MIP_MEIP);
|
||||
}
|
||||
|
||||
int32 ArchEnableHwIrq(uint32 irq_num)
|
||||
{
|
||||
plic_set_priority(irq_num, 1);
|
||||
EnableHwplicIrq(irq_num);
|
||||
}
|
||||
|
||||
int32 ArchDisableHwIrq(uint32 irq_num)
|
||||
{
|
||||
DisableHwplicIrq(irq_num);
|
||||
}
|
||||
|
||||
__attribute__((weak))
|
||||
void PlicIrqHandle(plic_irq_t irq)
|
||||
{
|
||||
KPrintf("UN-handled interrupt %d occurred!!!\n", irq);
|
||||
return ;
|
||||
}
|
||||
|
||||
uintptr_t HandleIrqMExt(uintptr_t cause, uintptr_t epc)
|
||||
{
|
||||
if (READ_CSR(mip) & MIP_MEIP) {
|
||||
uint64_t core_id = current_coreid();
|
||||
uint64_t ie_flag = READ_CSR(mie);
|
||||
uint32_t int_num = plic->targets.target[core_id].claim_complete;
|
||||
uint32_t int_threshold = plic->targets.target[core_id].priority_threshold;
|
||||
plic->targets.target[core_id].priority_threshold = plic->source_priorities.priority[int_num];
|
||||
|
||||
CLEAR_CSR(mie, MIP_MTIP | MIP_MSIP);
|
||||
|
||||
isrManager.done->handleIrq(int_num);
|
||||
|
||||
plic->targets.target[core_id].claim_complete = int_num;
|
||||
SET_CSR(mstatus, MSTATUS_MPIE | MSTATUS_MPP);
|
||||
WRITE_CSR(mie, ie_flag);
|
||||
plic->targets.target[core_id].priority_threshold = int_threshold;
|
||||
}
|
||||
|
||||
return epc;
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
||||
#ifdef TASK_ISOLATION
|
||||
uintptr_t HandleTrap(uintptr_t mcause, uintptr_t epc, uintptr_t * sp)
|
||||
{
|
||||
int cause = mcause & CAUSE_MACHINE_IRQ_REASON_MASK;
|
||||
|
||||
if (mcause & (1UL << 63)) {
|
||||
isrManager.done->incCounter();
|
||||
switch (cause) {
|
||||
case IRQ_M_SOFT: {
|
||||
uint64_t core_id = current_coreid();
|
||||
clint_ipi_clear(core_id);
|
||||
|
||||
DO_KTASK_ASSIGN;
|
||||
}
|
||||
break;
|
||||
case IRQ_M_EXT:
|
||||
HandleIrqMExt(mcause, epc);
|
||||
break;
|
||||
case IRQ_M_TIMER:
|
||||
TickIsr();
|
||||
break;
|
||||
}
|
||||
isrManager.done->decCounter();
|
||||
} else {
|
||||
x_base temp;
|
||||
temp = DISABLE_INTERRUPT();
|
||||
KTaskDescriptorType tid;
|
||||
extern long ShowTask();
|
||||
tid = GetKTaskDescriptor();
|
||||
|
||||
if(cause == CAUSE_USER_ECALL) {
|
||||
tid->task_dync_sched_member.isolation_status = 1;
|
||||
sp[0] += 4;
|
||||
unsigned long service_num = (unsigned long)(sp[10]);
|
||||
//KPrintf("Environment call from U-mode,service_num: %ld\n",service_num);
|
||||
uint8_t param_num = g_service_table[service_num].param_num;
|
||||
uintptr_t *param = sp + 11;
|
||||
ENABLE_INTERRUPT(temp);
|
||||
sp[10] = g_service_table[service_num].fun(service_num,param,param_num) ;
|
||||
tid->task_dync_sched_member.isolation_status = 0;
|
||||
|
||||
} else if (cause == CAUSE_MACHINE_ECALL) {
|
||||
unsigned long service_num = (unsigned long)(sp[10]);
|
||||
KPrintf("Environment call from M-mode, task:%s, flag: %d,service_num: %d\n \n",tid->task_base_info.name,tid->task_dync_sched_member.isolation_flag, service_num);
|
||||
sp[0] += 4;
|
||||
ENABLE_INTERRUPT(temp);
|
||||
} else {
|
||||
KPrintf("\nException:\n");
|
||||
tid = GetKTaskDescriptor();
|
||||
switch (cause) {
|
||||
case CAUSE_MISALIGNED_FETCH:
|
||||
KPrintf("Instruction address misaligned");
|
||||
break;
|
||||
case CAUSE_FAULT_FETCH:
|
||||
KPrintf("Instruction access fault");
|
||||
break;
|
||||
case CAUSE_ILLEGAL_INSTRUCTION:
|
||||
KPrintf("Illegal instruction");
|
||||
break;
|
||||
case CAUSE_BREAKPOINT:
|
||||
KPrintf("Breakpoint");
|
||||
break;
|
||||
case CAUSE_MISALIGNED_LOAD:
|
||||
KPrintf("Load address misaligned");
|
||||
break;
|
||||
case CAUSE_FAULT_LOAD:
|
||||
KPrintf("Load access fault");
|
||||
break;
|
||||
case CAUSE_MISALIGNED_STORE:
|
||||
KPrintf("Store address misaligned");
|
||||
break;
|
||||
case CAUSE_FAULT_STORE:
|
||||
KPrintf("Store access fault");
|
||||
break;
|
||||
case CAUSE_SUPERVISOR_ECALL:
|
||||
KPrintf("Environment call from S-mode");
|
||||
break;
|
||||
case CAUSE_HYPERVISOR_ECALL:
|
||||
KPrintf("Environment call from H-mode");
|
||||
break;
|
||||
default:
|
||||
KPrintf("Uknown exception : %08lX", cause);
|
||||
break;
|
||||
}
|
||||
KPrintf("\n");
|
||||
PrintStackFrame(sp);
|
||||
KPrintf("exception pc => 0x%08x\n", epc);
|
||||
KPrintf("current thread: %.*s\n", NAME_NUM_MAX, tid->task_base_info.name);
|
||||
#ifdef TOOL_SHELL
|
||||
ShowTask();
|
||||
#endif
|
||||
while (RET_TRUE);
|
||||
}
|
||||
|
||||
}
|
||||
return epc;
|
||||
}
|
||||
#else
|
||||
uintptr_t HandleTrap(uintptr_t mcause, uintptr_t epc, uintptr_t * sp)
|
||||
{
|
||||
int cause = mcause & CAUSE_MACHINE_IRQ_REASON_MASK;
|
||||
if (mcause & (1UL << 63)) {
|
||||
isrManager.done->incCounter();
|
||||
switch (cause) {
|
||||
case IRQ_M_SOFT: {
|
||||
uint64_t core_id = current_coreid();
|
||||
clint_ipi_clear(core_id);
|
||||
DO_KTASK_ASSIGN;
|
||||
}
|
||||
break;
|
||||
case IRQ_M_EXT:
|
||||
HandleIrqMExt(mcause, epc);
|
||||
break;
|
||||
case IRQ_M_TIMER:
|
||||
TickIsr();
|
||||
break;
|
||||
}
|
||||
isrManager.done->decCounter();
|
||||
} else {
|
||||
KTaskDescriptorType tid;
|
||||
extern long ShowTask();
|
||||
|
||||
DISABLE_INTERRUPT();
|
||||
tid = GetKTaskDescriptor();
|
||||
KPrintf("\nException:\n");
|
||||
switch (cause) {
|
||||
case CAUSE_MISALIGNED_FETCH:
|
||||
KPrintf("Instruction address misaligned");
|
||||
break;
|
||||
case CAUSE_FAULT_FETCH:
|
||||
KPrintf("Instruction access fault");
|
||||
break;
|
||||
case CAUSE_ILLEGAL_INSTRUCTION:
|
||||
KPrintf("Illegal instruction");
|
||||
break;
|
||||
case CAUSE_BREAKPOINT:
|
||||
KPrintf("Breakpoint");
|
||||
break;
|
||||
case CAUSE_MISALIGNED_LOAD:
|
||||
KPrintf("Load address misaligned");
|
||||
break;
|
||||
case CAUSE_FAULT_LOAD:
|
||||
KPrintf("Load access fault");
|
||||
break;
|
||||
case CAUSE_MISALIGNED_STORE:
|
||||
KPrintf("Store address misaligned");
|
||||
break;
|
||||
case CAUSE_FAULT_STORE:
|
||||
KPrintf("Store access fault");
|
||||
break;
|
||||
case CAUSE_USER_ECALL:
|
||||
KPrintf("Environment call from U-mode");
|
||||
break;
|
||||
case CAUSE_SUPERVISOR_ECALL:
|
||||
KPrintf("Environment call from S-mode");
|
||||
break;
|
||||
case CAUSE_HYPERVISOR_ECALL:
|
||||
KPrintf("Environment call from H-mode");
|
||||
break;
|
||||
case CAUSE_MACHINE_ECALL:
|
||||
KPrintf("Environment call from M-mode");
|
||||
break;
|
||||
default:
|
||||
KPrintf("Uknown exception : %08lX", cause);
|
||||
break;
|
||||
}
|
||||
KPrintf("\n");
|
||||
PrintStackFrame(sp);
|
||||
KPrintf("exception pc => 0x%08x\n", epc);
|
||||
KPrintf("current task: %.*s\n", NAME_NUM_MAX, tid->task_base_info.name);
|
||||
#ifdef TOOL_SHELL
|
||||
ShowTask();
|
||||
#endif
|
||||
while (RET_TRUE);
|
||||
}
|
||||
return epc;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018/12/23 Bernard The first version
|
||||
* 2018/12/27 Jesven Add secondary cpu boot
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: smp_support.c
|
||||
Description: SMP support routines
|
||||
Others: take RT-Thread v4.0.2/libcpu/risc-v/k210/cpuport_smp.c
|
||||
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
|
||||
History:
|
||||
1. Date: 2021-04-25
|
||||
Author: AIIT XUOS Lab
|
||||
*************************************************/
|
||||
|
||||
#include "board.h"
|
||||
#include <bsp_atomic.h>
|
||||
#include <clint.h>
|
||||
#include <encoding.h>
|
||||
#include <xs_spinlock.h>
|
||||
#include <stdint.h>
|
||||
#include <xs_assign.h>
|
||||
|
||||
|
||||
|
||||
void HwSendIpi(int ipi_vector, unsigned int cpu_mask)
|
||||
{
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < CPU_NUMBERS; idx ++)
|
||||
if (cpu_mask & (1 << idx))
|
||||
clint_ipi_send(idx);
|
||||
}
|
||||
|
||||
int GetCpuId(void)
|
||||
{
|
||||
return READ_CSR(mhartid);
|
||||
}
|
||||
|
||||
void InitHwSpinlock(HwSpinlock *lock)
|
||||
{
|
||||
((spinlock_t *)lock)->lock = 0;
|
||||
}
|
||||
|
||||
void HwLockSpinlock(HwSpinlock *lock)
|
||||
{
|
||||
spinlock_lock((spinlock_t *)lock);
|
||||
}
|
||||
|
||||
void HwUnlockSpinlock(HwSpinlock *lock)
|
||||
{
|
||||
spinlock_unlock((spinlock_t *)lock);
|
||||
}
|
||||
|
||||
extern uint64 cpu2_boot_flag;
|
||||
void StartupSecondaryCpu(void)
|
||||
{
|
||||
mb();
|
||||
cpu2_boot_flag = 0x2018050420191010;
|
||||
}
|
||||
|
||||
extern void InitHwSecondaryInterrupt(void);
|
||||
extern int InitHwTick(void);
|
||||
extern int EnableHwclintIpi(void);
|
||||
|
||||
void SecondaryCpuCStart(void)
|
||||
{
|
||||
HwLockSpinlock(&AssignSpinLock);
|
||||
InitHwSecondaryInterrupt();
|
||||
|
||||
InitHwTick();
|
||||
|
||||
EnableHwclintIpi();
|
||||
|
||||
StartupOsAssign();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018/10/28 Bernard The unify RISC-V porting code.
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: tick.c
|
||||
Description: system tick interrupt related routines
|
||||
Others: take RT-Thread v4.0.2/libcpu/risc-v/k210/tick.c
|
||||
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
|
||||
History:
|
||||
1. Date: 2021-04-25
|
||||
Author: AIIT XUOS Lab
|
||||
*************************************************/
|
||||
|
||||
#include <clint.h>
|
||||
#include <encoding.h>
|
||||
#include <sysctl.h>
|
||||
#include <xs_ktick.h>
|
||||
|
||||
static volatile unsigned long tick_cycles = 0;
|
||||
|
||||
int TickIsr(void)
|
||||
{
|
||||
uint64_t core_id = current_coreid();
|
||||
|
||||
clint->mtimecmp[core_id] += tick_cycles;
|
||||
TickAndTaskTimesliceUpdate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int InitHwTick(void)
|
||||
{
|
||||
unsigned long core_id = current_coreid();
|
||||
unsigned long interval = 1000 / TICK_PER_SECOND;
|
||||
|
||||
CLEAR_CSR(mie, MIP_MTIP);
|
||||
|
||||
#ifdef BSP_USING_QEMU
|
||||
tick_cycles = (10000000 / TICK_PER_SECOND);
|
||||
#else
|
||||
tick_cycles = interval * SysctlClockGetFreq(SYSCTL_CLOCK_CPU) / CLINT_CLOCK_DIV / 1000ULL - 1;
|
||||
#endif
|
||||
|
||||
clint->mtimecmp[core_id] = clint->mtime + tick_cycles;
|
||||
|
||||
SET_CSR(mie, MIP_MTIP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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 TICK_H__
|
||||
#define TICK_H__
|
||||
|
||||
int TickIsr(void);
|
||||
int InitHwTick(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := startup_RV32M1_ri5cy.S interrupt_gcc.S system_RV32M1_ri5cy.c interrupt.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @file arch_interrupt.h
|
||||
* @brief support rv32m1-vega interrupt
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-02-16
|
||||
*/
|
||||
|
||||
#ifndef ARCH_INTERRUPT_H__
|
||||
#define ARCH_INTERRUPT_H__
|
||||
|
||||
#include <RV32M1_ri5cy.h>
|
||||
|
||||
#define ARCH_MAX_IRQ_NUM NUMBER_OF_INT_VECTORS
|
||||
#define ARCH_IRQ_NUM_OFFSET 0
|
||||
|
||||
int ArchEnableHwIrq(uint32_t irq_num);
|
||||
int ArchDisableHwIrq(uint32_t irq_num);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright 2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
/* Copyright (c) 2009 - 2015 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @file core_riscv32.h
|
||||
* @brief support interrupt
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-02-16
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: core_riscv32.h
|
||||
Description: support gap8 interrupt and startup
|
||||
Others: take for references
|
||||
https://github.com/open-isa-org/open-isa.org
|
||||
History:
|
||||
1. Date: 2022-02-16
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
*************************************************/
|
||||
|
||||
#ifndef __CORE_RISCV32_H__
|
||||
#define __CORE_RISCV32_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RISCV32
|
||||
|
||||
#if defined ( __GNUC__ )
|
||||
#define __ASM __asm /*!< asm keyword for GNU Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for GNU Compiler */
|
||||
#define __STATIC_INLINE static inline
|
||||
|
||||
#else
|
||||
#error Unknown compiler
|
||||
#endif
|
||||
|
||||
#if defined ( __GNUC__ )
|
||||
|
||||
#define __BKPT(x) __ASM("ebreak")
|
||||
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __NOP(void)
|
||||
{
|
||||
__ASM volatile ("nop");
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __DSB(void)
|
||||
{
|
||||
__ASM volatile ("nop");
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __ISB(void)
|
||||
{
|
||||
__ASM volatile ("nop");
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __WFI(void)
|
||||
{
|
||||
__ASM volatile ("wfi");
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __WFE(void)
|
||||
{
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
|
||||
{
|
||||
__ASM volatile ("csrsi mstatus, 8");
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
|
||||
{
|
||||
__ASM volatile ("csrci mstatus, 8");
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)
|
||||
{
|
||||
return __builtin_bswap32(value);
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
return __builtin_bswap16(value);
|
||||
}
|
||||
|
||||
#else
|
||||
#error Unknown compiler
|
||||
#endif
|
||||
|
||||
#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 */
|
||||
|
||||
/* following defines should be used for structure members */
|
||||
#define __IM volatile const /*! Defines 'read only' structure member permissions */
|
||||
#define __OM volatile /*! Defines 'write only' structure member permissions */
|
||||
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_RISCV32_H__ */
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2014-2016 Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_device_registers.h
|
||||
* @brief support fsl device
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-02-16
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: fsl_device_registers.h
|
||||
Description: support fsl device
|
||||
Others: take for references
|
||||
https://github.com/open-isa-org/open-isa.org
|
||||
History:
|
||||
1. Date: 2022-02-16
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
*************************************************/
|
||||
|
||||
#ifndef __FSL_DEVICE_REGISTERS_H__
|
||||
#define __FSL_DEVICE_REGISTERS_H__
|
||||
|
||||
#define CPU_RV32M1_ri5cy
|
||||
/*
|
||||
* Include the cpu specific register header files.
|
||||
*
|
||||
* The CPU macro should be declared in the project or makefile.
|
||||
*/
|
||||
#if defined(CPU_RV32M1_cm0plus)
|
||||
|
||||
#define RV32M1_cm0plus_SERIES
|
||||
|
||||
/* CMSIS-style register definitions */
|
||||
#include "RV32M1_cm0plus.h"
|
||||
/* CPU specific feature definitions */
|
||||
#include "RV32M1_cm0plus_features.h"
|
||||
|
||||
#elif defined(CPU_RV32M1_cm4)
|
||||
|
||||
#define RV32M1_cm4_SERIES
|
||||
|
||||
/* CMSIS-style register definitions */
|
||||
#include "RV32M1_cm4.h"
|
||||
/* CPU specific feature definitions */
|
||||
#include "RV32M1_cm4_features.h"
|
||||
|
||||
#elif defined(CPU_RV32M1_zero_riscy)
|
||||
|
||||
#define RV32M1_zero_riscy_SERIES
|
||||
|
||||
/* CMSIS-style register definitions */
|
||||
#include "RV32M1_zero_riscy.h"
|
||||
/* CPU specific feature definitions */
|
||||
#include "RV32M1_zero_riscy_features.h"
|
||||
|
||||
#elif defined(CPU_RV32M1_ri5cy)
|
||||
|
||||
#define RV32M1_ri5cy_SERIES
|
||||
|
||||
/* CMSIS-style register definitions */
|
||||
#include "RV32M1_ri5cy.h"
|
||||
/* CPU specific feature definitions */
|
||||
#include "RV32M1_ri5cy_features.h"
|
||||
|
||||
#else
|
||||
#error "No valid CPU defined!"
|
||||
#endif
|
||||
|
||||
#endif /* __FSL_DEVICE_REGISTERS_H__ */
|
||||
|
||||
/*******************************************************************************
|
||||
* EOF
|
||||
******************************************************************************/
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @file interrupt.c
|
||||
* @brief support interrupt
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-09-02
|
||||
*/
|
||||
|
||||
|
||||
#include <arch_interrupt.h>
|
||||
#include <xs_base.h>
|
||||
#include <xs_isr.h>
|
||||
#include "fsl_common.h"
|
||||
#include <RV32M1_ri5cy.h>
|
||||
|
||||
int ArchDisableHwIrq(uint32_t irq_num)
|
||||
{
|
||||
DisableIRQ(irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ArchEnableHwIrq(uint32_t irq_num)
|
||||
{
|
||||
EnableIRQ(irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
x_base DisableLocalInterrupt(void)
|
||||
{
|
||||
__disable_irq();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: EnableLocalInterrupt
|
||||
*
|
||||
* Description:
|
||||
* Return the current interrupt state and enable interrupts
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void EnableLocalInterrupt(x_base oldstat)
|
||||
{
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
typedef void (*irq_handler_t)(void);
|
||||
extern const irq_handler_t isrTable[];
|
||||
|
||||
void SystemIrqHandler(uint32_t mcause)
|
||||
{
|
||||
uint32_t intNum;
|
||||
|
||||
if (mcause & 0x80000000) /* For external interrupt. */
|
||||
{
|
||||
intNum = mcause & 0x1FUL;
|
||||
|
||||
/* Clear pending flag in EVENT unit .*/
|
||||
EVENT_UNIT->INTPTPENDCLEAR = (1U << intNum);
|
||||
|
||||
/* Now call the real irq handler for intNum */
|
||||
isrManager.done->incCounter();
|
||||
isrTable[intNum]();
|
||||
isrManager.done->decCounter();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @file interrupt_gcc.S
|
||||
* @brief support vega interrupt
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-02-16
|
||||
*/
|
||||
|
||||
#include "boot.h"
|
||||
|
||||
.section .text.entry
|
||||
.align 2
|
||||
.global IRQ_Handler
|
||||
IRQ_Handler:
|
||||
|
||||
SAVE_X_REGISTERS
|
||||
|
||||
mv fp, sp
|
||||
|
||||
/* switch to interrupt stack */
|
||||
# la sp, __stack
|
||||
|
||||
/* interrupt handle */
|
||||
|
||||
csrr a0, mcause
|
||||
csrr a1, mepc
|
||||
mv a2, sp
|
||||
call SystemIrqHandler
|
||||
|
||||
/* switch to from thread stack */
|
||||
|
||||
mv sp, fp
|
||||
mv a0, fp
|
||||
call KTaskOsAssignAfterIrq
|
||||
j SwitchKTaskContextExit
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* @file: startup_RV32M1_ri5cy.s */
|
||||
/* @purpose: RI5CY Core Device Startup File */
|
||||
/* RV32M1_ri5cy */
|
||||
/* @version: 1.0 */
|
||||
/* @date: 2018-10-2 */
|
||||
/* @build: b180926 */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* */
|
||||
/* Copyright 1997-2016 Freescale Semiconductor, Inc. */
|
||||
/* Copyright 2016-2018 NXP */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
|
||||
|
||||
// Copyright 2017 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
/*************************************************
|
||||
File name: startup_RV32M1_ri5cy.s
|
||||
Description:
|
||||
Others: take for references
|
||||
https://github.com/open-isa-org/open-isa.org
|
||||
History:
|
||||
1. Date: 2022-02-16
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
*************************************************/
|
||||
|
||||
.extern Rv32m1VgeaStart
|
||||
#define EXCEPTION_STACK_SIZE 0x58
|
||||
|
||||
.text
|
||||
.section .vectors, "ax"
|
||||
.option norvc;
|
||||
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
|
||||
// reset vector
|
||||
jal x0, Reset_Handler
|
||||
|
||||
// Illegal instrution exception
|
||||
jal x0, IllegalInstruction_Handler
|
||||
|
||||
// ecall handler
|
||||
jal x0, Ecall_Handler
|
||||
|
||||
// LSU error
|
||||
jal x0, LSU_Handler
|
||||
|
||||
.section .startup
|
||||
|
||||
/* Reset Handler */
|
||||
Reset_Handler:
|
||||
|
||||
# Disable global interrupt. */
|
||||
csrci mstatus, 8
|
||||
|
||||
# initialize stack pointer
|
||||
la sp, __StackTop
|
||||
|
||||
# initialize global pointer
|
||||
la gp, __global_pointer
|
||||
|
||||
#ifndef __NO_SYSTEM_INIT
|
||||
jal SystemInit
|
||||
#endif
|
||||
|
||||
# call __libc_init_array
|
||||
|
||||
# Enable global interrupt. */
|
||||
# csrsi mstatus, 8
|
||||
|
||||
jal Rv32m1VgeaStart
|
||||
ebreak
|
||||
|
||||
.size Reset_Handler, . - Reset_Handler
|
||||
|
||||
.global _init
|
||||
.global _fini
|
||||
_init:
|
||||
_fini:
|
||||
ret
|
||||
|
||||
// saves all caller-saved registers (except return address)
|
||||
store_regs:
|
||||
sw x3, 0x00(x2) // gp
|
||||
sw x4, 0x04(x2) // tp
|
||||
sw x5, 0x08(x2) // t0
|
||||
sw x6, 0x0c(x2) // t1
|
||||
sw x7, 0x10(x2) // t2
|
||||
sw x10, 0x14(x2) // a0
|
||||
sw x11, 0x18(x2) // a1
|
||||
sw x12, 0x1c(x2) // a2
|
||||
sw x13, 0x20(x2) // a3
|
||||
sw x14, 0x24(x2) // a4
|
||||
sw x15, 0x28(x2) // a5
|
||||
sw x16, 0x2c(x2) // a6
|
||||
sw x17, 0x30(x2) // a7
|
||||
|
||||
csrr a0, 0x7B0
|
||||
csrr a1, 0x7B1
|
||||
csrr a2, 0x7B2
|
||||
sw a0, 0x34(x2) // lpstart[0]
|
||||
sw a1, 0x38(x2) // lpend[0]
|
||||
sw a2, 0x3c(x2) // lpcount[0]
|
||||
csrr a0, 0x7B4
|
||||
csrr a1, 0x7B5
|
||||
csrr a2, 0x7B6
|
||||
sw a0, 0x40(x2) // lpstart[1]
|
||||
sw a1, 0x44(x2) // lpend[1]
|
||||
sw a2, 0x48(x2) // lpcount[1]
|
||||
|
||||
csrr a0, 0x341
|
||||
sw a0, 0x4c(x2) // mepc
|
||||
csrr a1, 0x300
|
||||
sw a1, 0x50(x2) // mstatus
|
||||
jalr x0, x1
|
||||
|
||||
// load back registers from stack
|
||||
end_except:
|
||||
lw a1, 0x50(x2) // mstatus
|
||||
csrrw x0, 0x300, a1
|
||||
lw a0, 0x4c(x2) // mepc
|
||||
csrrw x0, 0x341, a0
|
||||
|
||||
lw a0, 0x40(x2) // lpstart[1]
|
||||
lw a1, 0x44(x2) // lpend[1]
|
||||
lw a2, 0x48(x2) // lpcount[1]
|
||||
csrrw x0, 0x7B4, a0
|
||||
csrrw x0, 0x7B5, a1
|
||||
csrrw x0, 0x7B6, a2
|
||||
lw a0, 0x34(x2) // lpstart[0]
|
||||
lw a1, 0x38(x2) // lpend[0]
|
||||
lw a2, 0x3c(x2) // lpcount[0]
|
||||
csrrw x0, 0x7B0, a0
|
||||
csrrw x0, 0x7B1, a1
|
||||
csrrw x0, 0x7B2, a2
|
||||
|
||||
lw x3, 0x00(x2) // gp
|
||||
lw x4, 0x04(x2) // tp
|
||||
lw x5, 0x08(x2) // t0
|
||||
lw x6, 0x0c(x2) // t1
|
||||
lw x7, 0x10(x2) // t2
|
||||
lw x10, 0x14(x2) // a0
|
||||
lw x11, 0x18(x2) // a1
|
||||
lw x12, 0x1c(x2) // a2
|
||||
lw x13, 0x20(x2) // a3
|
||||
lw x14, 0x24(x2) // a4
|
||||
lw x15, 0x28(x2) // a5
|
||||
lw x16, 0x2c(x2) // a6
|
||||
lw x17, 0x30(x2) // a7
|
||||
|
||||
lw x1, 0x54(x2)
|
||||
addi x2, x2, EXCEPTION_STACK_SIZE
|
||||
mret
|
||||
|
||||
.weak IRQ_Handler
|
||||
.type IRQ_Handler, %function
|
||||
IRQ_Handler:
|
||||
addi x2, x2, -EXCEPTION_STACK_SIZE
|
||||
sw x1, 0x54(x2)
|
||||
jal x1, store_regs
|
||||
la x1, end_except
|
||||
csrr a0, mcause
|
||||
jal x0, SystemIrqHandler
|
||||
.size IRQ_Handler, . - IRQ_Handler
|
||||
|
||||
.macro define_exception_entry entry_name handler_name
|
||||
.weak \entry_name
|
||||
\entry_name:
|
||||
addi x2, x2, -EXCEPTION_STACK_SIZE
|
||||
sw x1, 0x54(x2)
|
||||
jal x1, store_regs
|
||||
la x1, end_except
|
||||
jal x0, \handler_name
|
||||
.endm
|
||||
|
||||
define_exception_entry IllegalInstruction_Handler IllegalInstruction_HandlerFunc
|
||||
define_exception_entry Ecall_Handler Ecall_HandlerFunc
|
||||
define_exception_entry LSU_Handler LSU_HandlerFunc
|
||||
|
||||
.weak IllegalInstruction_HandlerFunc
|
||||
.type IllegalInstruction_HandlerFunc, %function
|
||||
IllegalInstruction_HandlerFunc:
|
||||
j .
|
||||
.size IllegalInstruction_HandlerFunc, . - IllegalInstruction_HandlerFunc
|
||||
|
||||
.weak Ecall_HandlerFunc
|
||||
.type Ecall_HandlerFunc, %function
|
||||
Ecall_HandlerFunc:
|
||||
j .
|
||||
.size Ecall_HandlerFunc, . - Ecall_HandlerFunc
|
||||
|
||||
.weak LSU_HandlerFunc
|
||||
.type LSU_HandlerFunc, %function
|
||||
LSU_HandlerFunc:
|
||||
j .
|
||||
.size LSU_HandlerFunc, . - LSU_HandlerFunc
|
||||
@@ -0,0 +1,236 @@
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* @file: startup_RV32M1_zero_riscy.s */
|
||||
/* @purpose: ZERO_RISCY Core Device Startup File */
|
||||
/* RV32M1_zero_riscy */
|
||||
/* @version: 1.0 */
|
||||
/* @date: 2018-10-2 */
|
||||
/* @build: b180926 */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* */
|
||||
/* Copyright 1997-2016 Freescale Semiconductor, Inc. */
|
||||
/* Copyright 2016-2018 NXP */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
|
||||
// Copyright 2017 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
/*************************************************
|
||||
File name: startup_RV32M1_zero_ri5cy.s
|
||||
Description:
|
||||
Others: take for references
|
||||
https://github.com/open-isa-org/open-isa.org
|
||||
History:
|
||||
1. Date: 2022-02-16
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
*************************************************/
|
||||
.extern Rv32m1VgeaStart
|
||||
#define EXCEPTION_STACK_SIZE 0x58
|
||||
|
||||
.text
|
||||
.section .vectors, "ax"
|
||||
.option norvc;
|
||||
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
jal x0, IRQ_Handler
|
||||
|
||||
// reset vector
|
||||
jal x0, Reset_Handler
|
||||
|
||||
// Illegal instrution exception
|
||||
jal x0, IllegalInstruction_Handler
|
||||
|
||||
// ecall handler
|
||||
jal x0, Ecall_Handler
|
||||
|
||||
// LSU error
|
||||
jal x0, LSU_Handler
|
||||
|
||||
.section .startup
|
||||
|
||||
/* Reset Handler */
|
||||
Reset_Handler:
|
||||
|
||||
# Disable global interrupt. */
|
||||
csrci mstatus, 8
|
||||
|
||||
# initialize stack pointer
|
||||
la sp, __StackTop
|
||||
|
||||
# initialize global pointer
|
||||
la gp, __global_pointer
|
||||
|
||||
#ifndef __NO_SYSTEM_INIT
|
||||
jal SystemInit
|
||||
#endif
|
||||
|
||||
call __libc_init_array
|
||||
|
||||
# Enable global interrupt. */
|
||||
csrsi mstatus, 8
|
||||
|
||||
jal Rv32m1VgeaStart
|
||||
ebreak
|
||||
|
||||
.size Reset_Handler, . - Reset_Handler
|
||||
|
||||
.global _init
|
||||
.global _fini
|
||||
_init:
|
||||
_fini:
|
||||
ret
|
||||
|
||||
// saves all caller-saved registers (except return address)
|
||||
store_regs:
|
||||
sw x3, 0x00(x2) // gp
|
||||
sw x4, 0x04(x2) // tp
|
||||
sw x5, 0x08(x2) // t0
|
||||
sw x6, 0x0c(x2) // t1
|
||||
sw x7, 0x10(x2) // t2
|
||||
sw x10, 0x14(x2) // a0
|
||||
sw x11, 0x18(x2) // a1
|
||||
sw x12, 0x1c(x2) // a2
|
||||
sw x13, 0x20(x2) // a3
|
||||
sw x14, 0x24(x2) // a4
|
||||
sw x15, 0x28(x2) // a5
|
||||
sw x16, 0x2c(x2) // a6
|
||||
sw x17, 0x30(x2) // a7
|
||||
|
||||
csrr a0, 0x7B0
|
||||
csrr a1, 0x7B1
|
||||
csrr a2, 0x7B2
|
||||
sw a0, 0x34(x2) // lpstart[0]
|
||||
sw a1, 0x38(x2) // lpend[0]
|
||||
sw a2, 0x3c(x2) // lpcount[0]
|
||||
csrr a0, 0x7B4
|
||||
csrr a1, 0x7B5
|
||||
csrr a2, 0x7B6
|
||||
sw a0, 0x40(x2) // lpstart[1]
|
||||
sw a1, 0x44(x2) // lpend[1]
|
||||
sw a2, 0x48(x2) // lpcount[1]
|
||||
|
||||
csrr a0, 0x341
|
||||
sw a0, 0x4c(x2) // mepc
|
||||
csrr a1, 0x300
|
||||
sw a1, 0x50(x2) // mstatus
|
||||
jalr x0, x1
|
||||
|
||||
// load back registers from stack
|
||||
end_except:
|
||||
lw a1, 0x50(x2) // mstatus
|
||||
csrrw x0, 0x300, a1
|
||||
lw a0, 0x4c(x2) // mepc
|
||||
csrrw x0, 0x341, a0
|
||||
|
||||
lw a0, 0x40(x2) // lpstart[1]
|
||||
lw a1, 0x44(x2) // lpend[1]
|
||||
lw a2, 0x48(x2) // lpcount[1]
|
||||
csrrw x0, 0x7B4, a0
|
||||
csrrw x0, 0x7B5, a1
|
||||
csrrw x0, 0x7B6, a2
|
||||
lw a0, 0x34(x2) // lpstart[0]
|
||||
lw a1, 0x38(x2) // lpend[0]
|
||||
lw a2, 0x3c(x2) // lpcount[0]
|
||||
csrrw x0, 0x7B0, a0
|
||||
csrrw x0, 0x7B1, a1
|
||||
csrrw x0, 0x7B2, a2
|
||||
|
||||
lw x3, 0x00(x2) // gp
|
||||
lw x4, 0x04(x2) // tp
|
||||
lw x5, 0x08(x2) // t0
|
||||
lw x6, 0x0c(x2) // t1
|
||||
lw x7, 0x10(x2) // t2
|
||||
lw x10, 0x14(x2) // a0
|
||||
lw x11, 0x18(x2) // a1
|
||||
lw x12, 0x1c(x2) // a2
|
||||
lw x13, 0x20(x2) // a3
|
||||
lw x14, 0x24(x2) // a4
|
||||
lw x15, 0x28(x2) // a5
|
||||
lw x16, 0x2c(x2) // a6
|
||||
lw x17, 0x30(x2) // a7
|
||||
|
||||
lw x1, 0x54(x2)
|
||||
addi x2, x2, EXCEPTION_STACK_SIZE
|
||||
mret
|
||||
|
||||
.weak IRQ_Handler
|
||||
.type IRQ_Handler, %function
|
||||
IRQ_Handler:
|
||||
addi x2, x2, -EXCEPTION_STACK_SIZE
|
||||
sw x1, 0x54(x2)
|
||||
jal x1, store_regs
|
||||
la x1, end_except
|
||||
csrr a0, mcause
|
||||
jal x0, SystemIrqHandler
|
||||
.size IRQ_Handler, . - IRQ_Handler
|
||||
|
||||
.macro define_exception_entry entry_name handler_name
|
||||
.weak \entry_name
|
||||
\entry_name:
|
||||
addi x2, x2, -EXCEPTION_STACK_SIZE
|
||||
sw x1, 0x54(x2)
|
||||
jal x1, store_regs
|
||||
la x1, end_except
|
||||
jal x0, \handler_name
|
||||
.endm
|
||||
|
||||
define_exception_entry IllegalInstruction_Handler IllegalInstruction_HandlerFunc
|
||||
define_exception_entry Ecall_Handler Ecall_HandlerFunc
|
||||
define_exception_entry LSU_Handler LSU_HandlerFunc
|
||||
|
||||
.weak IllegalInstruction_HandlerFunc
|
||||
.type IllegalInstruction_HandlerFunc, %function
|
||||
IllegalInstruction_HandlerFunc:
|
||||
j .
|
||||
.size IllegalInstruction_HandlerFunc, . - IllegalInstruction_HandlerFunc
|
||||
|
||||
.weak Ecall_HandlerFunc
|
||||
.type Ecall_HandlerFunc, %function
|
||||
Ecall_HandlerFunc:
|
||||
j .
|
||||
.size Ecall_HandlerFunc, . - Ecall_HandlerFunc
|
||||
|
||||
.weak LSU_HandlerFunc
|
||||
.type LSU_HandlerFunc, %function
|
||||
LSU_HandlerFunc:
|
||||
j .
|
||||
.size LSU_HandlerFunc, . - LSU_HandlerFunc
|
||||
@@ -0,0 +1,567 @@
|
||||
/*
|
||||
** ###################################################################
|
||||
** Processors: RV32M1_ri5cy
|
||||
** RV32M1_ri5cy
|
||||
**
|
||||
** Compilers: Keil ARM C/C++ Compiler
|
||||
** GNU C Compiler
|
||||
** IAR ANSI C/C++ Compiler for ARM
|
||||
** MCUXpresso Compiler
|
||||
**
|
||||
** Reference manual: RV32M1 Series Reference Manual, Rev. 1 , 8/10/2018
|
||||
** Version: rev. 1.0, 2018-10-02
|
||||
** Build: b180926
|
||||
**
|
||||
** Abstract:
|
||||
** Provides a system configuration function and a global variable that
|
||||
** contains the system frequency. It configures the device and initializes
|
||||
** the oscillator (PLL) that is part of the microcontroller device.
|
||||
**
|
||||
** Copyright 2016 Freescale Semiconductor, Inc.
|
||||
** Copyright 2016-2018 NXP
|
||||
** All rights reserved.
|
||||
**
|
||||
** SPDX-License-Identifier: BSD-3-Clause
|
||||
**
|
||||
** http: www.nxp.com
|
||||
** mail: support@nxp.com
|
||||
**
|
||||
** Revisions:
|
||||
** - rev. 1.0 (2018-10-02)
|
||||
** Initial version.
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file RV32M1_ri5cy
|
||||
* @version 1.0
|
||||
* @date 2018-10-02
|
||||
* @brief Device specific configuration file for RV32M1_ri5cy
|
||||
* (implementation file)
|
||||
*
|
||||
* Provides a system configuration function and a global variable that contains
|
||||
* the system frequency. It configures the device and initializes the oscillator
|
||||
* (PLL) that is part of the microcontroller device.
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: RV32M1_ri5cy
|
||||
Description:
|
||||
Others: take for references
|
||||
https://github.com/open-isa-org/open-isa.org
|
||||
History:
|
||||
1. Date: 2022-02-16
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
*************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "fsl_device_registers.h"
|
||||
#include "fsl_common.h"
|
||||
|
||||
typedef void (*irq_handler_t)(void);
|
||||
|
||||
extern void DMA0_0_4_8_12_DriverIRQHandler(void);
|
||||
extern void DMA0_1_5_9_13_DriverIRQHandler(void);
|
||||
extern void DMA0_2_6_10_14_DriverIRQHandler(void);
|
||||
extern void DMA0_3_7_11_15_DriverIRQHandler(void);
|
||||
extern void DMA0_Error_IRQHandler(void);
|
||||
extern void CMC0_IRQHandler(void);
|
||||
extern void EWM_IRQHandler(void);
|
||||
extern void FTFE_Command_Complete_IRQHandler(void);
|
||||
extern void FTFE_Read_Collision_IRQHandler(void);
|
||||
extern void LLWU0_IRQHandler(void);
|
||||
extern void MUA_IRQHandler(void);
|
||||
extern void SPM_IRQHandler(void);
|
||||
extern void WDOG0_IRQHandler(void);
|
||||
extern void SCG_IRQHandler(void);
|
||||
extern void LPIT0_IRQHandler(void);
|
||||
extern void RTC_IRQHandler(void);
|
||||
extern void LPTMR0_IRQHandler(void);
|
||||
extern void LPTMR1_IRQHandler(void);
|
||||
extern void TPM0_IRQHandler(void);
|
||||
extern void TPM1_IRQHandler(void);
|
||||
extern void TPM2_IRQHandler(void);
|
||||
extern void EMVSIM0_IRQHandler(void);
|
||||
extern void FLEXIO0_DriverIRQHandler(void);
|
||||
extern void LPI2C0_DriverIRQHandler(void);
|
||||
extern void LPI2C1_DriverIRQHandler(void);
|
||||
extern void LPI2C2_DriverIRQHandler(void);
|
||||
extern void I2S0_DriverIRQHandler(void);
|
||||
extern void USDHC0_DriverIRQHandler(void);
|
||||
extern void LPSPI0_DriverIRQHandler(void);
|
||||
extern void LPSPI1_DriverIRQHandler(void);
|
||||
extern void LPSPI2_DriverIRQHandler(void);
|
||||
extern void LPUART0_DriverIRQHandler(void);
|
||||
extern void LPUART1_DriverIRQHandler(void);
|
||||
extern void LPUART2_DriverIRQHandler(void);
|
||||
extern void USB0_IRQHandler(void);
|
||||
extern void PORTA_IRQHandler(void);
|
||||
extern void PORTB_IRQHandler(void);
|
||||
extern void PORTC_IRQHandler(void);
|
||||
extern void PORTD_IRQHandler(void);
|
||||
extern void ADC0_IRQHandler(void);
|
||||
extern void LPCMP0_IRQHandler(void);
|
||||
extern void LPDAC0_IRQHandler(void);
|
||||
extern void CAU3_Task_Complete_IRQHandler(void);
|
||||
extern void CAU3_Security_Violation_IRQHandler(void);
|
||||
extern void TRNG_IRQHandler(void);
|
||||
extern void LPIT1_IRQHandler(void);
|
||||
extern void LPTMR2_IRQHandler(void);
|
||||
extern void TPM3_IRQHandler(void);
|
||||
extern void LPI2C3_DriverIRQHandler(void);
|
||||
extern void LPSPI3_DriverIRQHandler(void);
|
||||
extern void LPUART3_DriverIRQHandler(void);
|
||||
extern void PORTE_IRQHandler(void);
|
||||
extern void LPCMP1_IRQHandler(void);
|
||||
extern void RF0_0_IRQHandler(void);
|
||||
extern void RF0_1_IRQHandler(void);
|
||||
extern void INTMUX0_0_DriverIRQHandler(void);
|
||||
extern void INTMUX0_1_DriverIRQHandler(void);
|
||||
extern void INTMUX0_2_DriverIRQHandler(void);
|
||||
extern void INTMUX0_3_DriverIRQHandler(void);
|
||||
extern void INTMUX0_4_DriverIRQHandler(void);
|
||||
extern void INTMUX0_5_DriverIRQHandler(void);
|
||||
extern void INTMUX0_6_DriverIRQHandler(void);
|
||||
extern void INTMUX0_7_DriverIRQHandler(void);
|
||||
extern void INTMUX0_8_DriverIRQHandler(void);
|
||||
extern void DMA0_0_4_8_12_IRQHandler(void);
|
||||
extern void DMA0_1_5_9_13_IRQHandler(void);
|
||||
extern void DMA0_2_6_10_14_IRQHandler(void);
|
||||
extern void DMA0_3_7_11_15_IRQHandler(void);
|
||||
extern void FLEXIO0_IRQHandler(void);
|
||||
extern void LPI2C0_IRQHandler(void);
|
||||
extern void LPI2C1_IRQHandler(void);
|
||||
extern void LPI2C2_IRQHandler(void);
|
||||
extern void I2S0_IRQHandler(void);
|
||||
extern void USDHC0_IRQHandler(void);
|
||||
extern void LPSPI0_IRQHandler(void);
|
||||
extern void LPSPI1_IRQHandler(void);
|
||||
extern void LPSPI2_IRQHandler(void);
|
||||
extern void LPUART0_IRQHandler(void);
|
||||
extern void LPUART1_IRQHandler(void);
|
||||
extern void LPUART2_IRQHandler(void);
|
||||
extern void LPI2C3_IRQHandler(void);
|
||||
extern void LPSPI3_IRQHandler(void);
|
||||
extern void LPUART3_IRQHandler(void);
|
||||
extern void INTMUX0_0_IRQHandler(void);
|
||||
extern void INTMUX0_1_IRQHandler(void);
|
||||
extern void INTMUX0_2_IRQHandler(void);
|
||||
extern void INTMUX0_3_IRQHandler(void);
|
||||
extern void INTMUX0_4_IRQHandler(void);
|
||||
extern void INTMUX0_5_IRQHandler(void);
|
||||
extern void INTMUX0_6_IRQHandler(void);
|
||||
extern void INTMUX0_7_IRQHandler(void);
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- Core clock
|
||||
---------------------------------------------------------------------------- */
|
||||
uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
|
||||
|
||||
extern uint32_t __etext;
|
||||
extern uint32_t __data_start__;
|
||||
extern uint32_t __data_end__;
|
||||
|
||||
extern uint32_t __bss_start__;
|
||||
extern uint32_t __bss_end__;
|
||||
|
||||
static void copy_section(uint32_t * p_load, uint32_t * p_vma, uint32_t * p_vma_end)
|
||||
{
|
||||
while(p_vma <= p_vma_end)
|
||||
{
|
||||
*p_vma = *p_load;
|
||||
++p_load;
|
||||
++p_vma;
|
||||
}
|
||||
}
|
||||
|
||||
static void zero_section(uint32_t * start, uint32_t * end)
|
||||
{
|
||||
uint32_t * p_zero = start;
|
||||
|
||||
while(p_zero <= end)
|
||||
{
|
||||
*p_zero = 0;
|
||||
++p_zero;
|
||||
}
|
||||
}
|
||||
|
||||
#define DEFINE_IRQ_HANDLER(irq_handler, driver_irq_handler) \
|
||||
void __attribute__((weak)) irq_handler(void) { driver_irq_handler();}
|
||||
|
||||
#define DEFINE_DEFAULT_IRQ_HANDLER(irq_handler) void irq_handler() __attribute__((weak, alias("DefaultIRQHandler")))
|
||||
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(DMA0_0_4_8_12_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(DMA0_1_5_9_13_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(DMA0_2_6_10_14_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(DMA0_3_7_11_15_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(DMA0_Error_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(CMC0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(EWM_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(FTFE_Command_Complete_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(FTFE_Read_Collision_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LLWU0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(MUA_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(SPM_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(WDOG0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(SCG_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPIT0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(RTC_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPTMR0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPTMR1_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(TPM0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(TPM1_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(TPM2_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(EMVSIM0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(FLEXIO0_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPI2C0_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPI2C1_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPI2C2_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(I2S0_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(USDHC0_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPSPI0_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPSPI1_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPSPI2_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPUART0_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPUART1_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPUART2_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(USB0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(PORTA_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(PORTB_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(PORTC_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(PORTD_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(ADC0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPCMP0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPDAC0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(CAU3_Task_Complete_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(CAU3_Security_Violation_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(TRNG_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPIT1_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPTMR2_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(TPM3_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPI2C3_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPSPI3_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPUART3_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(PORTE_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPCMP1_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(RF0_0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(RF0_1_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX0_0_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX0_1_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX0_2_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX0_3_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX0_4_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX0_5_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX0_6_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX0_7_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX0_8_DriverIRQHandler);
|
||||
|
||||
DEFINE_IRQ_HANDLER(DMA0_0_4_8_12_IRQHandler, DMA0_0_4_8_12_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(DMA0_1_5_9_13_IRQHandler, DMA0_1_5_9_13_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(DMA0_2_6_10_14_IRQHandler, DMA0_2_6_10_14_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(DMA0_3_7_11_15_IRQHandler, DMA0_3_7_11_15_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(FLEXIO0_IRQHandler, FLEXIO0_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPI2C0_IRQHandler, LPI2C0_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPI2C1_IRQHandler, LPI2C1_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPI2C2_IRQHandler, LPI2C2_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(I2S0_IRQHandler, I2S0_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(USDHC0_IRQHandler, USDHC0_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPSPI0_IRQHandler, LPSPI0_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPSPI1_IRQHandler, LPSPI1_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPSPI2_IRQHandler, LPSPI2_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPUART0_IRQHandler, LPUART0_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPUART1_IRQHandler, LPUART1_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPUART2_IRQHandler, LPUART2_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPI2C3_IRQHandler, LPI2C3_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPSPI3_IRQHandler, LPSPI3_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPUART3_IRQHandler, LPUART3_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX0_0_IRQHandler, INTMUX0_0_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX0_1_IRQHandler, INTMUX0_1_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX0_2_IRQHandler, INTMUX0_2_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX0_3_IRQHandler, INTMUX0_3_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX0_4_IRQHandler, INTMUX0_4_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX0_5_IRQHandler, INTMUX0_5_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX0_6_IRQHandler, INTMUX0_6_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX0_7_IRQHandler, INTMUX0_7_DriverIRQHandler);
|
||||
|
||||
__attribute__((section("user_vectors"))) const irq_handler_t isrTable[] =
|
||||
{
|
||||
DMA0_0_4_8_12_IRQHandler,
|
||||
DMA0_1_5_9_13_IRQHandler,
|
||||
DMA0_2_6_10_14_IRQHandler,
|
||||
DMA0_3_7_11_15_IRQHandler,
|
||||
DMA0_Error_IRQHandler,
|
||||
CMC0_IRQHandler,
|
||||
MUA_IRQHandler,
|
||||
USB0_IRQHandler,
|
||||
USDHC0_IRQHandler,
|
||||
I2S0_IRQHandler,
|
||||
FLEXIO0_IRQHandler,
|
||||
EMVSIM0_IRQHandler,
|
||||
LPIT0_IRQHandler,
|
||||
LPSPI0_IRQHandler,
|
||||
LPSPI1_IRQHandler,
|
||||
LPI2C0_IRQHandler,
|
||||
LPI2C1_IRQHandler,
|
||||
LPUART0_IRQHandler,
|
||||
PORTA_IRQHandler,
|
||||
TPM0_IRQHandler,
|
||||
LPDAC0_IRQHandler,
|
||||
ADC0_IRQHandler,
|
||||
LPCMP0_IRQHandler,
|
||||
RTC_IRQHandler,
|
||||
INTMUX0_0_IRQHandler,
|
||||
INTMUX0_1_IRQHandler,
|
||||
INTMUX0_2_IRQHandler,
|
||||
INTMUX0_3_IRQHandler,
|
||||
INTMUX0_4_IRQHandler,
|
||||
INTMUX0_5_IRQHandler,
|
||||
INTMUX0_6_IRQHandler,
|
||||
INTMUX0_7_IRQHandler,
|
||||
EWM_IRQHandler,
|
||||
FTFE_Command_Complete_IRQHandler,
|
||||
FTFE_Read_Collision_IRQHandler,
|
||||
LLWU0_IRQHandler,
|
||||
SPM_IRQHandler,
|
||||
WDOG0_IRQHandler,
|
||||
SCG_IRQHandler,
|
||||
LPTMR0_IRQHandler,
|
||||
LPTMR1_IRQHandler,
|
||||
TPM1_IRQHandler,
|
||||
TPM2_IRQHandler,
|
||||
LPI2C2_IRQHandler,
|
||||
LPSPI2_IRQHandler,
|
||||
LPUART1_IRQHandler,
|
||||
LPUART2_IRQHandler,
|
||||
PORTB_IRQHandler,
|
||||
PORTC_IRQHandler,
|
||||
PORTD_IRQHandler,
|
||||
CAU3_Task_Complete_IRQHandler,
|
||||
CAU3_Security_Violation_IRQHandler,
|
||||
TRNG_IRQHandler,
|
||||
LPIT1_IRQHandler,
|
||||
LPTMR2_IRQHandler,
|
||||
TPM3_IRQHandler,
|
||||
LPI2C3_IRQHandler,
|
||||
LPSPI3_IRQHandler,
|
||||
LPUART3_IRQHandler,
|
||||
PORTE_IRQHandler,
|
||||
LPCMP1_IRQHandler,
|
||||
RF0_0_IRQHandler,
|
||||
RF0_1_IRQHandler,
|
||||
};
|
||||
|
||||
extern uint32_t __VECTOR_TABLE[];
|
||||
|
||||
static uint32_t irqNesting = 0;
|
||||
|
||||
static void DefaultIRQHandler(void)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- SystemInit()
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
void SystemInit (void) {
|
||||
#if (DISABLE_WDOG)
|
||||
WDOG0->CNT = 0xD928C520U;
|
||||
WDOG0->TOVAL = 0xFFFF;
|
||||
WDOG0->CS = (uint32_t) ((WDOG0->CS) & ~WDOG_CS_EN_MASK) | WDOG_CS_UPDATE_MASK;
|
||||
#endif /* (DISABLE_WDOG) */
|
||||
|
||||
SystemInitHook();
|
||||
|
||||
copy_section(&__etext, &__data_start__, &__data_end__);
|
||||
zero_section(&__bss_start__, &__bss_end__);
|
||||
|
||||
/* Setup the vector table address. */
|
||||
irqNesting = 0;
|
||||
|
||||
__ASM volatile("csrw 0x305, %0" :: "r"((uint32_t)__VECTOR_TABLE)); /* MTVEC */
|
||||
__ASM volatile("csrw 0x005, %0" :: "r"((uint32_t)__VECTOR_TABLE)); /* UTVEC */
|
||||
|
||||
/* Clear all pending flags. */
|
||||
EVENT_UNIT->INTPTPENDCLEAR = 0xFFFFFFFF;
|
||||
EVENT_UNIT->EVTPENDCLEAR = 0xFFFFFFFF;
|
||||
/* Set all interrupt as secure interrupt. */
|
||||
EVENT_UNIT->INTPTSECURE = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- SystemCoreClockUpdate()
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
void SystemCoreClockUpdate (void) {
|
||||
|
||||
uint32_t SCGOUTClock; /* Variable to store output clock frequency of the SCG module */
|
||||
uint16_t Divider;
|
||||
Divider = ((SCG->CSR & SCG_CSR_DIVCORE_MASK) >> SCG_CSR_DIVCORE_SHIFT) + 1;
|
||||
|
||||
switch ((SCG->CSR & SCG_CSR_SCS_MASK) >> SCG_CSR_SCS_SHIFT) {
|
||||
case 0x1:
|
||||
/* System OSC */
|
||||
SCGOUTClock = CPU_XTAL_CLK_HZ;
|
||||
break;
|
||||
case 0x2:
|
||||
/* Slow IRC */
|
||||
SCGOUTClock = (((SCG->SIRCCFG & SCG_SIRCCFG_RANGE_MASK) >> SCG_SIRCCFG_RANGE_SHIFT) ? 8000000 : 2000000);
|
||||
break;
|
||||
case 0x3:
|
||||
/* Fast IRC */
|
||||
SCGOUTClock = 48000000 + ((SCG->FIRCCFG & SCG_FIRCCFG_RANGE_MASK) >> SCG_FIRCCFG_RANGE_SHIFT) * 4000000;
|
||||
break;
|
||||
case 0x5:
|
||||
/* Low Power FLL */
|
||||
SCGOUTClock = 48000000 + ((SCG->LPFLLCFG & SCG_LPFLLCFG_FSEL_MASK) >> SCG_LPFLLCFG_FSEL_SHIFT) * 24000000;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
SystemCoreClock = (SCGOUTClock / Divider);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- SystemInitHook()
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
__attribute__ ((weak)) void SystemInitHook (void) {
|
||||
/* Void implementation of the weak function. */
|
||||
}
|
||||
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma weak SystemIrqHandler
|
||||
void SystemIrqHandler(uint32_t mcause) {
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((weak)) void SystemIrqHandler(uint32_t mcause) {
|
||||
#else
|
||||
#error Not supported compiler type
|
||||
#endif
|
||||
uint32_t intNum;
|
||||
|
||||
if (mcause & 0x80000000) /* For external interrupt. */
|
||||
{
|
||||
intNum = mcause & 0x1FUL;
|
||||
|
||||
irqNesting++;
|
||||
|
||||
/* Clear pending flag in EVENT unit .*/
|
||||
EVENT_UNIT->INTPTPENDCLEAR = (1U << intNum);
|
||||
|
||||
/* Read back to make sure write finished. */
|
||||
(void)(EVENT_UNIT->INTPTPENDCLEAR);
|
||||
|
||||
__enable_irq(); /* Support nesting interrupt */
|
||||
|
||||
/* Now call the real irq handler for intNum */
|
||||
isrTable[intNum]();
|
||||
|
||||
__disable_irq();
|
||||
|
||||
irqNesting--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use LIPT0 channel 0 for systick. */
|
||||
#define SYSTICK_LPIT LPIT0
|
||||
#define SYSTICK_LPIT_CH 0
|
||||
#define SYSTICK_LPIT_IRQn LPIT0_IRQn
|
||||
|
||||
/* Leverage LPIT0 to provide Systick */
|
||||
void SystemSetupSystick(uint32_t tickRateHz, uint32_t intPriority)
|
||||
{
|
||||
/* Init pit module */
|
||||
CLOCK_EnableClock(kCLOCK_Lpit0);
|
||||
|
||||
/* Reset the timer channels and registers except the MCR register */
|
||||
SYSTICK_LPIT->MCR |= LPIT_MCR_SW_RST_MASK;
|
||||
SYSTICK_LPIT->MCR &= ~LPIT_MCR_SW_RST_MASK;
|
||||
|
||||
/* Setup timer operation in debug and doze modes and enable the module */
|
||||
SYSTICK_LPIT->MCR = LPIT_MCR_DBG_EN_MASK | LPIT_MCR_DOZE_EN_MASK | LPIT_MCR_M_CEN_MASK;
|
||||
|
||||
/* Set timer period for channel 0 */
|
||||
SYSTICK_LPIT->CHANNEL[SYSTICK_LPIT_CH].TVAL = (CLOCK_GetIpFreq(kCLOCK_Lpit0) / tickRateHz) - 1;
|
||||
|
||||
/* Enable timer interrupts for channel 0 */
|
||||
SYSTICK_LPIT->MIER |= (1U << SYSTICK_LPIT_CH);
|
||||
|
||||
/* Set interrupt priority. */
|
||||
EVENT_SetIRQPriority(SYSTICK_LPIT_IRQn, intPriority);
|
||||
|
||||
/* Enable interrupt at the EVENT unit */
|
||||
EnableIRQ(SYSTICK_LPIT_IRQn);
|
||||
|
||||
/* Start channel 0 */
|
||||
SYSTICK_LPIT->SETTEN |= (LPIT_SETTEN_SET_T_EN_0_MASK << SYSTICK_LPIT_CH);
|
||||
}
|
||||
|
||||
uint32_t SystemGetIRQNestingLevel(void)
|
||||
{
|
||||
return irqNesting;
|
||||
}
|
||||
|
||||
void SystemClearSystickFlag(void)
|
||||
{
|
||||
/* Channel 0. */
|
||||
SYSTICK_LPIT->MSR = (1U << SYSTICK_LPIT_CH);
|
||||
}
|
||||
|
||||
void EVENT_SetIRQPriority(IRQn_Type IRQn, uint8_t intPriority)
|
||||
{
|
||||
uint8_t regIdx;
|
||||
uint8_t regOffset;
|
||||
|
||||
if ((IRQn < 32) && (intPriority < 8))
|
||||
{
|
||||
/*
|
||||
* 4 priority control registers, each register controls 8 interrupts.
|
||||
* Bit 0-2: interrupt 0
|
||||
* Bit 4-7: interrupt 1
|
||||
* ...
|
||||
* Bit 28-30: interrupt 7
|
||||
*/
|
||||
regIdx = IRQn >> 3U;
|
||||
regOffset = (IRQn & 0x07U) * 4U;
|
||||
|
||||
EVENT_UNIT->INTPTPRI[regIdx] = (EVENT_UNIT->INTPTPRI[regIdx] & ~(0x0F << regOffset)) | (intPriority << regOffset);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t EVENT_GetIRQPriority(IRQn_Type IRQn)
|
||||
{
|
||||
uint8_t regIdx;
|
||||
uint8_t regOffset;
|
||||
int32_t intPriority;
|
||||
|
||||
if ((IRQn < 32))
|
||||
{
|
||||
/*
|
||||
* 4 priority control registers, each register controls 8 interrupts.
|
||||
* Bit 0-2: interrupt 0
|
||||
* Bit 4-7: interrupt 1
|
||||
* ...
|
||||
* Bit 28-30: interrupt 7
|
||||
*/
|
||||
regIdx = IRQn >> 3U;
|
||||
regOffset = (IRQn & 0x07U) << 2U;
|
||||
|
||||
intPriority = (EVENT_UNIT->INTPTPRI[regIdx] >> regOffset) & 0xF;
|
||||
return (uint8_t)intPriority;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SystemInISR(void)
|
||||
{
|
||||
return ((EVENT_UNIT->INTPTENACTIVE) != 0);;
|
||||
}
|
||||
|
||||
void EVENT_SystemReset(void)
|
||||
{
|
||||
EVENT_UNIT->SLPCTRL |= EVENT_SLPCTRL_SYSRSTREQST_MASK;
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
** ###################################################################
|
||||
** Processors: RV32M1_ri5cy
|
||||
** RV32M1_ri5cy
|
||||
**
|
||||
** Compilers: Keil ARM C/C++ Compiler
|
||||
** GNU C Compiler
|
||||
** IAR ANSI C/C++ Compiler for ARM
|
||||
** MCUXpresso Compiler
|
||||
**
|
||||
** Reference manual: RV32M1 Series Reference Manual, Rev. 1 , 8/10/2018
|
||||
** Version: rev. 1.0, 2018-10-02
|
||||
** Build: b180926
|
||||
**
|
||||
** Abstract:
|
||||
** Provides a system configuration function and a global variable that
|
||||
** contains the system frequency. It configures the device and initializes
|
||||
** the oscillator (PLL) that is part of the microcontroller device.
|
||||
**
|
||||
** Copyright 2016 Freescale Semiconductor, Inc.
|
||||
** Copyright 2016-2018 NXP
|
||||
** All rights reserved.
|
||||
**
|
||||
** SPDX-License-Identifier: BSD-3-Clause
|
||||
**
|
||||
** http: www.nxp.com
|
||||
** mail: support@nxp.com
|
||||
**
|
||||
** Revisions:
|
||||
** - rev. 1.0 (2018-10-02)
|
||||
** Initial version.
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file RV32M1_ri5cy
|
||||
* @version 1.0
|
||||
* @date 2018-10-02
|
||||
* @brief Device specific configuration file for RV32M1_ri5cy (header file)
|
||||
*
|
||||
* Provides a system configuration function and a global variable that contains
|
||||
* the system frequency. It configures the device and initializes the oscillator
|
||||
* (PLL) that is part of the microcontroller device.
|
||||
*/
|
||||
/*************************************************
|
||||
File name: RV32M1_ri5cy
|
||||
Description:
|
||||
Others: take for references
|
||||
https://github.com/open-isa-org/open-isa.org
|
||||
History:
|
||||
1. Date: 2022-02-16
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
*************************************************/
|
||||
#ifndef _SYSTEM_RV32M1_ri5cy_H_
|
||||
#define _SYSTEM_RV32M1_ri5cy_H_ /**< Symbol preventing repeated inclusion */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
#ifndef DISABLE_WDOG
|
||||
#define DISABLE_WDOG 1
|
||||
#endif
|
||||
|
||||
/* Define clock source values */
|
||||
#define CPU_XTAL_CLK_HZ 8000000u /* Value of the external crystal or oscillator clock frequency in Hz */
|
||||
|
||||
/* Low power mode enable */
|
||||
/* SMC_PMPROT: AHSRUN=1, AVLP=1,ALLS=1,AVLLS=0x3 */
|
||||
#define SYSTEM_SMC_PMPROT_VALUE 0xABu /* SMC_PMPROT */
|
||||
#define SYSTEM_SMC_PMCTRL_VALUE 0x0u /* SMC_PMCTRL */
|
||||
|
||||
#define DEFAULT_SYSTEM_CLOCK 48000000u /* Default System clock value */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief System clock frequency (core clock)
|
||||
*
|
||||
* The system clock frequency supplied to the SysTick timer and the processor
|
||||
* core clock. This variable can be used by the user application to setup the
|
||||
* SysTick timer or configure other parameters. It may also be used by debugger to
|
||||
* query the frequency of the debug timer or configure the trace clock speed
|
||||
* SystemCoreClock is initialized with a correct predefined value.
|
||||
*/
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system.
|
||||
*
|
||||
* Typically this function configures the oscillator (PLL) that is part of the
|
||||
* microcontroller device. For systems with variable clock speed it also updates
|
||||
* the variable SystemCoreClock. SystemInit is called from startup_device file.
|
||||
*/
|
||||
void SystemInit (void);
|
||||
|
||||
/**
|
||||
* @brief Updates the SystemCoreClock variable.
|
||||
*
|
||||
* It must be called whenever the core clock is changed during program
|
||||
* execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
|
||||
* the current core clock.
|
||||
*/
|
||||
void SystemCoreClockUpdate (void);
|
||||
|
||||
/**
|
||||
* @brief SystemInit function hook.
|
||||
*
|
||||
* This weak function allows to call specific initialization code during the
|
||||
* SystemInit() execution.This can be used when an application specific code needs
|
||||
* to be called as close to the reset entry as possible (for example the Multicore
|
||||
* Manager MCMGR_EarlyInit() function call).
|
||||
* NOTE: No global r/w variables can be used in this hook function because the
|
||||
* initialization of these variables happens after this function.
|
||||
*/
|
||||
void SystemInitHook (void);
|
||||
|
||||
/**
|
||||
* @brief System IRQ handler which dispatches specific IRQ to corresponding registered handler.
|
||||
*
|
||||
* It is called from IRQ exception context and dispatches to registered handler according to
|
||||
* MCAUSE interrupt number.
|
||||
*
|
||||
* @param mcause IRQ acknowledge value read from MCAUSE
|
||||
*/
|
||||
void SystemIrqHandler(uint32_t mcause);
|
||||
|
||||
/**
|
||||
* @brief Get IRQ nesting level of current context.
|
||||
*
|
||||
* If the return value is 0, then the context is not ISR, otherwise the context is ISR.
|
||||
*
|
||||
* @return IRQ nesting level
|
||||
*/
|
||||
uint32_t SystemGetIRQNestingLevel (void);
|
||||
|
||||
/**
|
||||
* @brief Setup systick for RTOS system.
|
||||
*
|
||||
* @param tickRateHz Tick number per second
|
||||
* @param intPriority IRQ interrupt priority (the smaller, the higher priority)
|
||||
*/
|
||||
void SystemSetupSystick (uint32_t tickRateHz, uint32_t intPriority);
|
||||
|
||||
/**
|
||||
* @brief Clear systick flag status so that next tick interrupt may occur.
|
||||
*/
|
||||
void SystemClearSystickFlag (void);
|
||||
|
||||
/**
|
||||
* @brief Sysem is in ISR or not.
|
||||
*/
|
||||
bool SystemInISR(void);
|
||||
|
||||
#define SysTick_Handler LPIT0_IRQHandler
|
||||
|
||||
/**
|
||||
* @brief Set interrupt priority in Event unit.
|
||||
*/
|
||||
void EVENT_SetIRQPriority(IRQn_Type IRQn, uint8_t intPriority);
|
||||
|
||||
/**
|
||||
* @brief Get interrupt priority in Event unit.
|
||||
*/
|
||||
uint8_t EVENT_GetIRQPriority(IRQn_Type IRQn);
|
||||
|
||||
/**
|
||||
* @brief Reset the system.
|
||||
*/
|
||||
void EVENT_SystemReset(void);
|
||||
|
||||
#define NVIC_SystemReset EVENT_SystemReset
|
||||
|
||||
/* Priority setting macro remap. */
|
||||
#define NVIC_SetPriority EVENT_SetIRQPriority
|
||||
|
||||
/* Priority getting macro remap. */
|
||||
#define NVIC_GetPriority EVENT_GetIRQPriority
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYSTEM_RV32M1_ri5cy_H_ */
|
||||
@@ -0,0 +1,546 @@
|
||||
/*
|
||||
** ###################################################################
|
||||
** Processors: RV32M1_zero_riscy
|
||||
** RV32M1_zero_riscy
|
||||
**
|
||||
** Compilers: Keil ARM C/C++ Compiler
|
||||
** GNU C Compiler
|
||||
** IAR ANSI C/C++ Compiler for ARM
|
||||
** MCUXpresso Compiler
|
||||
**
|
||||
** Reference manual: RV32M1 Series Reference Manual, Rev. 1 , 8/10/2018
|
||||
** Version: rev. 1.0, 2018-10-02
|
||||
** Build: b180926
|
||||
**
|
||||
** Abstract:
|
||||
** Provides a system configuration function and a global variable that
|
||||
** contains the system frequency. It configures the device and initializes
|
||||
** the oscillator (PLL) that is part of the microcontroller device.
|
||||
**
|
||||
** Copyright 2016 Freescale Semiconductor, Inc.
|
||||
** Copyright 2016-2018 NXP
|
||||
** All rights reserved.
|
||||
**
|
||||
** SPDX-License-Identifier: BSD-3-Clause
|
||||
**
|
||||
** http: www.nxp.com
|
||||
** mail: support@nxp.com
|
||||
**
|
||||
** Revisions:
|
||||
** - rev. 1.0 (2018-10-02)
|
||||
** Initial version.
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file RV32M1_zero_riscy
|
||||
* @version 1.0
|
||||
* @date 2018-10-02
|
||||
* @brief Device specific configuration file for RV32M1_zero_riscy
|
||||
* (implementation file)
|
||||
*
|
||||
* Provides a system configuration function and a global variable that contains
|
||||
* the system frequency. It configures the device and initializes the oscillator
|
||||
* (PLL) that is part of the microcontroller device.
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: RV32M1_zero_riscy
|
||||
Description:
|
||||
Others: take for references
|
||||
https://github.com/open-isa-org/open-isa.org
|
||||
History:
|
||||
1. Date: 2022-02-16
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
*************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "fsl_device_registers.h"
|
||||
#include "fsl_common.h"
|
||||
|
||||
typedef void (*irq_handler_t)(void);
|
||||
|
||||
extern void CTI1_IRQHandler(void);
|
||||
extern void DMA1_04_DriverIRQHandler(void);
|
||||
extern void DMA1_15_DriverIRQHandler(void);
|
||||
extern void DMA1_26_DriverIRQHandler(void);
|
||||
extern void DMA1_37_DriverIRQHandler(void);
|
||||
extern void DMA1_Error_DriverIRQHandler(void);
|
||||
extern void CMC1_IRQHandler(void);
|
||||
extern void LLWU1_IRQHandler(void);
|
||||
extern void MUB_IRQHandler(void);
|
||||
extern void WDOG1_IRQHandler(void);
|
||||
extern void CAU3_Task_Complete_IRQHandler(void);
|
||||
extern void CAU3_Security_Violation_IRQHandler(void);
|
||||
extern void TRNG_IRQHandler(void);
|
||||
extern void LPIT1_IRQHandler(void);
|
||||
extern void LPTMR2_IRQHandler(void);
|
||||
extern void TPM3_IRQHandler(void);
|
||||
extern void LPI2C3_DriverIRQHandler(void);
|
||||
extern void RF0_0_IRQHandler(void);
|
||||
extern void RF0_1_IRQHandler(void);
|
||||
extern void LPSPI3_DriverIRQHandler(void);
|
||||
extern void LPUART3_DriverIRQHandler(void);
|
||||
extern void PORTE_IRQHandler(void);
|
||||
extern void LPCMP1_IRQHandler(void);
|
||||
extern void RTC_IRQHandler(void);
|
||||
extern void INTMUX1_0_DriverIRQHandler(void);
|
||||
extern void INTMUX1_1_DriverIRQHandler(void);
|
||||
extern void INTMUX1_2_DriverIRQHandler(void);
|
||||
extern void INTMUX1_3_DriverIRQHandler(void);
|
||||
extern void INTMUX1_4_DriverIRQHandler(void);
|
||||
extern void INTMUX1_5_DriverIRQHandler(void);
|
||||
extern void INTMUX1_6_DriverIRQHandler(void);
|
||||
extern void INTMUX1_7_DriverIRQHandler(void);
|
||||
extern void EWM_IRQHandler(void);
|
||||
extern void FTFE_Command_Complete_IRQHandler(void);
|
||||
extern void FTFE_Read_Collision_IRQHandler(void);
|
||||
extern void SPM_IRQHandler(void);
|
||||
extern void SCG_IRQHandler(void);
|
||||
extern void LPIT0_IRQHandler(void);
|
||||
extern void LPTMR0_IRQHandler(void);
|
||||
extern void LPTMR1_IRQHandler(void);
|
||||
extern void TPM0_IRQHandler(void);
|
||||
extern void TPM1_IRQHandler(void);
|
||||
extern void TPM2_IRQHandler(void);
|
||||
extern void EMVSIM0_IRQHandler(void);
|
||||
extern void FLEXIO0_DriverIRQHandler(void);
|
||||
extern void LPI2C0_DriverIRQHandler(void);
|
||||
extern void LPI2C1_DriverIRQHandler(void);
|
||||
extern void LPI2C2_DriverIRQHandler(void);
|
||||
extern void I2S0_DriverIRQHandler(void);
|
||||
extern void USDHC0_DriverIRQHandler(void);
|
||||
extern void LPSPI0_DriverIRQHandler(void);
|
||||
extern void LPSPI1_DriverIRQHandler(void);
|
||||
extern void LPSPI2_DriverIRQHandler(void);
|
||||
extern void LPUART0_DriverIRQHandler(void);
|
||||
extern void LPUART1_DriverIRQHandler(void);
|
||||
extern void LPUART2_DriverIRQHandler(void);
|
||||
extern void USB0_IRQHandler(void);
|
||||
extern void PORTA_IRQHandler(void);
|
||||
extern void PORTB_IRQHandler(void);
|
||||
extern void PORTC_IRQHandler(void);
|
||||
extern void PORTD_IRQHandler(void);
|
||||
extern void ADC0_IRQHandler(void);
|
||||
extern void LPCMP0_IRQHandler(void);
|
||||
extern void LPDAC0_IRQHandler(void);
|
||||
extern void DMA1_15_IRQHandler(void);
|
||||
extern void DMA1_26_IRQHandler(void);
|
||||
extern void DMA1_37_IRQHandler(void);
|
||||
extern void DMA1_Error_IRQHandler(void);
|
||||
extern void LPI2C3_IRQHandler(void);
|
||||
extern void LPSPI3_IRQHandler(void);
|
||||
extern void LPUART3_IRQHandler(void);
|
||||
extern void INTMUX1_0_IRQHandler(void);
|
||||
extern void INTMUX1_1_IRQHandler(void);
|
||||
extern void INTMUX1_2_IRQHandler(void);
|
||||
extern void INTMUX1_3_IRQHandler(void);
|
||||
extern void INTMUX1_4_IRQHandler(void);
|
||||
extern void INTMUX1_5_IRQHandler(void);
|
||||
extern void INTMUX1_6_IRQHandler(void);
|
||||
extern void INTMUX1_7_IRQHandler(void);
|
||||
extern void FLEXIO0_IRQHandler(void);
|
||||
extern void LPI2C0_IRQHandler(void);
|
||||
extern void LPI2C1_IRQHandler(void);
|
||||
extern void LPI2C2_IRQHandler(void);
|
||||
extern void I2S0_IRQHandler(void);
|
||||
extern void USDHC0_IRQHandler(void);
|
||||
extern void LPSPI0_IRQHandler(void);
|
||||
extern void LPSPI1_IRQHandler(void);
|
||||
extern void LPSPI2_IRQHandler(void);
|
||||
extern void LPUART0_IRQHandler(void);
|
||||
extern void LPUART1_IRQHandler(void);
|
||||
extern void LPUART2_IRQHandler(void);
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- Core clock
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
|
||||
|
||||
extern uint32_t __etext;
|
||||
extern uint32_t __data_start__;
|
||||
extern uint32_t __data_end__;
|
||||
|
||||
extern uint32_t __bss_start__;
|
||||
extern uint32_t __bss_end__;
|
||||
|
||||
static void copy_section(uint32_t * p_load, uint32_t * p_vma, uint32_t * p_vma_end)
|
||||
{
|
||||
while(p_vma <= p_vma_end)
|
||||
{
|
||||
*p_vma = *p_load;
|
||||
++p_load;
|
||||
++p_vma;
|
||||
}
|
||||
}
|
||||
|
||||
static void zero_section(uint32_t * start, uint32_t * end)
|
||||
{
|
||||
uint32_t * p_zero = start;
|
||||
|
||||
while(p_zero <= end)
|
||||
{
|
||||
*p_zero = 0;
|
||||
++p_zero;
|
||||
}
|
||||
}
|
||||
|
||||
#define DEFINE_IRQ_HANDLER(irq_handler, driver_irq_handler) \
|
||||
void __attribute__((weak)) irq_handler(void) { driver_irq_handler();}
|
||||
|
||||
#define DEFINE_DEFAULT_IRQ_HANDLER(irq_handler) void irq_handler() __attribute__((weak, alias("DefaultIRQHandler")))
|
||||
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(CTI1_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(DMA1_04_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(DMA1_15_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(DMA1_26_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(DMA1_37_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(DMA1_Error_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(CMC1_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LLWU1_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(MUB_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(WDOG1_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(CAU3_Task_Complete_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(CAU3_Security_Violation_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(TRNG_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPIT1_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPTMR2_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(TPM3_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPI2C3_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(RF0_0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(RF0_1_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPSPI3_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPUART3_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(PORTE_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPCMP1_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(RTC_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX1_0_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX1_1_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX1_2_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX1_3_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX1_4_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX1_5_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX1_6_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(INTMUX1_7_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(EWM_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(FTFE_Command_Complete_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(FTFE_Read_Collision_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(SPM_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(SCG_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPIT0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPTMR0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPTMR1_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(TPM0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(TPM1_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(TPM2_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(EMVSIM0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(FLEXIO0_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPI2C0_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPI2C1_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPI2C2_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(I2S0_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(USDHC0_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPSPI0_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPSPI1_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPSPI2_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPUART0_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPUART1_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPUART2_DriverIRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(USB0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(PORTA_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(PORTB_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(PORTC_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(PORTD_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(ADC0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPCMP0_IRQHandler);
|
||||
DEFINE_DEFAULT_IRQ_HANDLER(LPDAC0_IRQHandler);
|
||||
|
||||
DEFINE_IRQ_HANDLER(DMA1_04_IRQHandler, DMA1_04_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(DMA1_15_IRQHandler, DMA1_15_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(DMA1_26_IRQHandler, DMA1_26_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(DMA1_37_IRQHandler, DMA1_37_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(DMA1_Error_IRQHandler, DMA1_Error_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPI2C3_IRQHandler, LPI2C3_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPSPI3_IRQHandler, LPSPI3_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPUART3_IRQHandler, LPUART3_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX1_0_IRQHandler, INTMUX1_0_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX1_1_IRQHandler, INTMUX1_1_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX1_2_IRQHandler, INTMUX1_2_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX1_3_IRQHandler, INTMUX1_3_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX1_4_IRQHandler, INTMUX1_4_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX1_5_IRQHandler, INTMUX1_5_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX1_6_IRQHandler, INTMUX1_6_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(INTMUX1_7_IRQHandler, INTMUX1_7_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(FLEXIO0_IRQHandler, FLEXIO0_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPI2C0_IRQHandler, LPI2C0_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPI2C1_IRQHandler, LPI2C1_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPI2C2_IRQHandler, LPI2C2_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(I2S0_IRQHandler, I2S0_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(USDHC0_IRQHandler, USDHC0_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPSPI0_IRQHandler, LPSPI0_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPSPI1_IRQHandler, LPSPI1_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPSPI2_IRQHandler, LPSPI2_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPUART0_IRQHandler, LPUART0_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPUART1_IRQHandler, LPUART1_DriverIRQHandler);
|
||||
DEFINE_IRQ_HANDLER(LPUART2_IRQHandler, LPUART2_DriverIRQHandler);
|
||||
|
||||
__attribute__((section("user_vectors"))) const irq_handler_t isrTable[] =
|
||||
{
|
||||
CTI1_IRQHandler,
|
||||
DMA1_04_IRQHandler,
|
||||
DMA1_15_IRQHandler,
|
||||
DMA1_26_IRQHandler,
|
||||
DMA1_37_IRQHandler,
|
||||
DMA1_Error_IRQHandler,
|
||||
CMC1_IRQHandler,
|
||||
LLWU1_IRQHandler,
|
||||
MUB_IRQHandler,
|
||||
WDOG1_IRQHandler,
|
||||
CAU3_Task_Complete_IRQHandler,
|
||||
CAU3_Security_Violation_IRQHandler,
|
||||
TRNG_IRQHandler,
|
||||
LPIT1_IRQHandler,
|
||||
LPTMR2_IRQHandler,
|
||||
TPM3_IRQHandler,
|
||||
LPI2C3_IRQHandler,
|
||||
RF0_0_IRQHandler,
|
||||
RF0_1_IRQHandler,
|
||||
LPSPI3_IRQHandler,
|
||||
LPUART3_IRQHandler,
|
||||
PORTE_IRQHandler,
|
||||
LPCMP1_IRQHandler,
|
||||
RTC_IRQHandler,
|
||||
INTMUX1_0_IRQHandler,
|
||||
INTMUX1_1_IRQHandler,
|
||||
INTMUX1_2_IRQHandler,
|
||||
INTMUX1_3_IRQHandler,
|
||||
INTMUX1_4_IRQHandler,
|
||||
INTMUX1_5_IRQHandler,
|
||||
INTMUX1_6_IRQHandler,
|
||||
INTMUX1_7_IRQHandler,
|
||||
EWM_IRQHandler,
|
||||
FTFE_Command_Complete_IRQHandler,
|
||||
FTFE_Read_Collision_IRQHandler,
|
||||
SPM_IRQHandler,
|
||||
SCG_IRQHandler,
|
||||
LPIT0_IRQHandler,
|
||||
LPTMR0_IRQHandler,
|
||||
LPTMR1_IRQHandler,
|
||||
TPM0_IRQHandler,
|
||||
TPM1_IRQHandler,
|
||||
TPM2_IRQHandler,
|
||||
EMVSIM0_IRQHandler,
|
||||
FLEXIO0_IRQHandler,
|
||||
LPI2C0_IRQHandler,
|
||||
LPI2C1_IRQHandler,
|
||||
LPI2C2_IRQHandler,
|
||||
I2S0_IRQHandler,
|
||||
USDHC0_IRQHandler,
|
||||
LPSPI0_IRQHandler,
|
||||
LPSPI1_IRQHandler,
|
||||
LPSPI2_IRQHandler,
|
||||
LPUART0_IRQHandler,
|
||||
LPUART1_IRQHandler,
|
||||
LPUART2_IRQHandler,
|
||||
USB0_IRQHandler,
|
||||
PORTA_IRQHandler,
|
||||
PORTB_IRQHandler,
|
||||
PORTC_IRQHandler,
|
||||
PORTD_IRQHandler,
|
||||
ADC0_IRQHandler,
|
||||
LPCMP0_IRQHandler,
|
||||
LPDAC0_IRQHandler,
|
||||
};
|
||||
|
||||
extern uint32_t __VECTOR_TABLE[];
|
||||
|
||||
static uint32_t irqNesting = 0;
|
||||
|
||||
static void DefaultIRQHandler(void)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- SystemInit()
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
void SystemInit (void) {
|
||||
#if (DISABLE_WDOG)
|
||||
WDOG1->CNT = 0xD928C520U;
|
||||
WDOG1->TOVAL = 0xFFFF;
|
||||
WDOG1->CS = (uint32_t) ((WDOG1->CS) & ~WDOG_CS_EN_MASK) | WDOG_CS_UPDATE_MASK;
|
||||
#endif /* (DISABLE_WDOG) */
|
||||
|
||||
SystemInitHook();
|
||||
|
||||
copy_section(&__etext, &__data_start__, &__data_end__);
|
||||
zero_section(&__bss_start__, &__bss_end__);
|
||||
|
||||
/* Setup the vector table address. */
|
||||
irqNesting = 0;
|
||||
|
||||
__ASM volatile("csrw 0x305, %0" :: "r"((uint32_t)__VECTOR_TABLE)); /* MTVEC */
|
||||
__ASM volatile("csrw 0x005, %0" :: "r"((uint32_t)__VECTOR_TABLE)); /* UTVEC */
|
||||
|
||||
/* Clear all pending flags. */
|
||||
EVENT_UNIT->INTPTPENDCLEAR = 0xFFFFFFFF;
|
||||
EVENT_UNIT->EVTPENDCLEAR = 0xFFFFFFFF;
|
||||
/* Set all interrupt as secure interrupt. */
|
||||
EVENT_UNIT->INTPTSECURE = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- SystemCoreClockUpdate()
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
void SystemCoreClockUpdate (void) {
|
||||
|
||||
uint32_t SCGOUTClock; /* Variable to store output clock frequency of the SCG module */
|
||||
uint16_t Divider;
|
||||
Divider = ((SCG->CSR & SCG_CSR_DIVCORE_MASK) >> SCG_CSR_DIVCORE_SHIFT) + 1;
|
||||
|
||||
switch ((SCG->CSR & SCG_CSR_SCS_MASK) >> SCG_CSR_SCS_SHIFT) {
|
||||
case 0x1:
|
||||
/* System OSC */
|
||||
SCGOUTClock = CPU_XTAL_CLK_HZ;
|
||||
break;
|
||||
case 0x2:
|
||||
/* Slow IRC */
|
||||
SCGOUTClock = (((SCG->SIRCCFG & SCG_SIRCCFG_RANGE_MASK) >> SCG_SIRCCFG_RANGE_SHIFT) ? 8000000 : 2000000);
|
||||
break;
|
||||
case 0x3:
|
||||
/* Fast IRC */
|
||||
SCGOUTClock = 48000000 + ((SCG->FIRCCFG & SCG_FIRCCFG_RANGE_MASK) >> SCG_FIRCCFG_RANGE_SHIFT) * 4000000;
|
||||
break;
|
||||
case 0x5:
|
||||
/* Low Power FLL */
|
||||
SCGOUTClock = 48000000 + ((SCG->LPFLLCFG & SCG_LPFLLCFG_FSEL_MASK) >> SCG_LPFLLCFG_FSEL_SHIFT) * 24000000;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
SystemCoreClock = (SCGOUTClock / Divider);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
-- SystemInitHook()
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
__attribute__ ((weak)) void SystemInitHook (void) {
|
||||
/* Void implementation of the weak function. */
|
||||
}
|
||||
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma weak SystemIrqHandler
|
||||
void SystemIrqHandler(uint32_t mcause) {
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((weak)) void SystemIrqHandler(uint32_t mcause) {
|
||||
#else
|
||||
#error Not supported compiler type
|
||||
#endif
|
||||
uint32_t intNum;
|
||||
|
||||
if (mcause & 0x80000000) /* For external interrupt. */
|
||||
{
|
||||
intNum = mcause & 0x1FUL;
|
||||
|
||||
irqNesting++;
|
||||
|
||||
/* Clear pending flag in EVENT unit .*/
|
||||
EVENT_UNIT->INTPTPENDCLEAR = (1U << intNum);
|
||||
|
||||
/* Read back to make sure write finished. */
|
||||
(void)(EVENT_UNIT->INTPTPENDCLEAR);
|
||||
|
||||
__enable_irq(); /* Support nesting interrupt */
|
||||
|
||||
/* Now call the real irq handler for intNum */
|
||||
isrTable[intNum]();
|
||||
|
||||
__disable_irq();
|
||||
|
||||
irqNesting--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use LIPT1 channel 0 for systick. */
|
||||
#define SYSTICK_LPIT LPIT1
|
||||
#define SYSTICK_LPIT_CH 0
|
||||
#define SYSTICK_LPIT_IRQn LPIT1_IRQn
|
||||
|
||||
/* Leverage LPIT0 to provide Systick */
|
||||
void SystemSetupSystick(uint32_t tickRateHz, uint32_t intPriority)
|
||||
{
|
||||
/* Init pit module */
|
||||
CLOCK_EnableClock(kCLOCK_Lpit1);
|
||||
|
||||
/* Reset the timer channels and registers except the MCR register */
|
||||
SYSTICK_LPIT->MCR |= LPIT_MCR_SW_RST_MASK;
|
||||
SYSTICK_LPIT->MCR &= ~LPIT_MCR_SW_RST_MASK;
|
||||
|
||||
/* Setup timer operation in debug and doze modes and enable the module */
|
||||
SYSTICK_LPIT->MCR = LPIT_MCR_DBG_EN_MASK | LPIT_MCR_DOZE_EN_MASK | LPIT_MCR_M_CEN_MASK;
|
||||
|
||||
/* Set timer period for channel 0 */
|
||||
SYSTICK_LPIT->CHANNEL[SYSTICK_LPIT_CH].TVAL = (CLOCK_GetIpFreq(kCLOCK_Lpit1) / tickRateHz) - 1;
|
||||
|
||||
/* Enable timer interrupts for channel 0 */
|
||||
SYSTICK_LPIT->MIER |= (1U << SYSTICK_LPIT_CH);
|
||||
|
||||
/* Set interrupt priority. */
|
||||
EVENT_SetIRQPriority(SYSTICK_LPIT_IRQn, intPriority);
|
||||
|
||||
/* Enable interrupt at the EVENT unit */
|
||||
EnableIRQ(SYSTICK_LPIT_IRQn);
|
||||
|
||||
/* Start channel 0 */
|
||||
SYSTICK_LPIT->SETTEN |= (LPIT_SETTEN_SET_T_EN_0_MASK << SYSTICK_LPIT_CH);
|
||||
}
|
||||
|
||||
uint32_t SystemGetIRQNestingLevel(void)
|
||||
{
|
||||
return irqNesting;
|
||||
}
|
||||
|
||||
void SystemClearSystickFlag(void)
|
||||
{
|
||||
/* Channel 0. */
|
||||
SYSTICK_LPIT->MSR = (1U << SYSTICK_LPIT_CH);
|
||||
}
|
||||
|
||||
void EVENT_SetIRQPriority(IRQn_Type IRQn, uint8_t intPriority)
|
||||
{
|
||||
uint8_t regIdx;
|
||||
uint8_t regOffset;
|
||||
|
||||
if ((IRQn < 32) && (intPriority < 8))
|
||||
{
|
||||
/*
|
||||
* 4 priority control registers, each register controls 8 interrupts.
|
||||
* Bit 0-2: interrupt 0
|
||||
* Bit 4-7: interrupt 1
|
||||
* ...
|
||||
* Bit 28-30: interrupt 7
|
||||
*/
|
||||
regIdx = IRQn >> 3U;
|
||||
regOffset = (IRQn & 0x07U) * 4U;
|
||||
|
||||
EVENT_UNIT->INTPTPRI[regIdx] = (EVENT_UNIT->INTPTPRI[regIdx] & ~(0x0F << regOffset)) | (intPriority << regOffset);
|
||||
}
|
||||
}
|
||||
|
||||
bool SystemInISR(void)
|
||||
{
|
||||
return ((EVENT_UNIT->INTPTENACTIVE) != 0);;
|
||||
}
|
||||
|
||||
void EVENT_SystemReset(void)
|
||||
{
|
||||
EVENT_UNIT->SLPCTRL |= EVENT_SLPCTRL_SYSRSTREQST_MASK;
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
** ###################################################################
|
||||
** Processors: RV32M1_zero_riscy
|
||||
** RV32M1_zero_riscy
|
||||
**
|
||||
** Compilers: Keil ARM C/C++ Compiler
|
||||
** GNU C Compiler
|
||||
** IAR ANSI C/C++ Compiler for ARM
|
||||
** MCUXpresso Compiler
|
||||
**
|
||||
** Reference manual: RV32M1 Series Reference Manual, Rev. 1 , 8/10/2018
|
||||
** Version: rev. 1.0, 2018-10-02
|
||||
** Build: b180926
|
||||
**
|
||||
** Abstract:
|
||||
** Provides a system configuration function and a global variable that
|
||||
** contains the system frequency. It configures the device and initializes
|
||||
** the oscillator (PLL) that is part of the microcontroller device.
|
||||
**
|
||||
** Copyright 2016 Freescale Semiconductor, Inc.
|
||||
** Copyright 2016-2018 NXP
|
||||
** All rights reserved.
|
||||
**
|
||||
** SPDX-License-Identifier: BSD-3-Clause
|
||||
**
|
||||
** http: www.nxp.com
|
||||
** mail: support@nxp.com
|
||||
**
|
||||
** Revisions:
|
||||
** - rev. 1.0 (2018-10-02)
|
||||
** Initial version.
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file RV32M1_zero_riscy
|
||||
* @version 1.0
|
||||
* @date 2018-10-02
|
||||
* @brief Device specific configuration file for RV32M1_zero_riscy (header
|
||||
* file)
|
||||
*
|
||||
* Provides a system configuration function and a global variable that contains
|
||||
* the system frequency. It configures the device and initializes the oscillator
|
||||
* (PLL) that is part of the microcontroller device.
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: RV32M1_zero_riscy
|
||||
Description:
|
||||
Others: take for references
|
||||
https://github.com/open-isa-org/open-isa.org
|
||||
History:
|
||||
1. Date: 2022-02-16
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
*************************************************/
|
||||
|
||||
#ifndef _SYSTEM_RV32M1_zero_riscy_H_
|
||||
#define _SYSTEM_RV32M1_zero_riscy_H_ /**< Symbol preventing repeated inclusion */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
#ifndef DISABLE_WDOG
|
||||
#define DISABLE_WDOG 1
|
||||
#endif
|
||||
|
||||
/* Define clock source values */
|
||||
#define CPU_XTAL_CLK_HZ 8000000u /* Value of the external crystal or oscillator clock frequency in Hz */
|
||||
|
||||
/* Low power mode enable */
|
||||
/* SMC_PMPROT: AHSRUN=1, AVLP=1,ALLS=1,AVLLS=0x3 */
|
||||
#define SYSTEM_SMC_PMPROT_VALUE 0xABu /* SMC_PMPROT */
|
||||
#define SYSTEM_SMC_PMCTRL_VALUE 0x0u /* SMC_PMCTRL */
|
||||
|
||||
#define DEFAULT_SYSTEM_CLOCK 48000000u /* Default System clock value */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief System clock frequency (core clock)
|
||||
*
|
||||
* The system clock frequency supplied to the SysTick timer and the processor
|
||||
* core clock. This variable can be used by the user application to setup the
|
||||
* SysTick timer or configure other parameters. It may also be used by debugger to
|
||||
* query the frequency of the debug timer or configure the trace clock speed
|
||||
* SystemCoreClock is initialized with a correct predefined value.
|
||||
*/
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system.
|
||||
*
|
||||
* Typically this function configures the oscillator (PLL) that is part of the
|
||||
* microcontroller device. For systems with variable clock speed it also updates
|
||||
* the variable SystemCoreClock. SystemInit is called from startup_device file.
|
||||
*/
|
||||
void SystemInit (void);
|
||||
|
||||
/**
|
||||
* @brief Updates the SystemCoreClock variable.
|
||||
*
|
||||
* It must be called whenever the core clock is changed during program
|
||||
* execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
|
||||
* the current core clock.
|
||||
*/
|
||||
void SystemCoreClockUpdate (void);
|
||||
|
||||
/**
|
||||
* @brief SystemInit function hook.
|
||||
*
|
||||
* This weak function allows to call specific initialization code during the
|
||||
* SystemInit() execution.This can be used when an application specific code needs
|
||||
* to be called as close to the reset entry as possible (for example the Multicore
|
||||
* Manager MCMGR_EarlyInit() function call).
|
||||
* NOTE: No global r/w variables can be used in this hook function because the
|
||||
* initialization of these variables happens after this function.
|
||||
*/
|
||||
void SystemInitHook (void);
|
||||
|
||||
/**
|
||||
* @brief System IRQ handler which dispatches specific IRQ to corresponding registered handler.
|
||||
*
|
||||
* It is called from IRQ exception context and dispatches to registered handler according to
|
||||
* MCAUSE interrupt number.
|
||||
*
|
||||
* @param mcause IRQ acknowledge value read from MCAUSE
|
||||
*/
|
||||
void SystemIrqHandler(uint32_t mcause);
|
||||
|
||||
/**
|
||||
* @brief Get IRQ nesting level of current context.
|
||||
*
|
||||
* If the return value is 0, then the context is not ISR, otherwise the context is ISR.
|
||||
*
|
||||
* @return IRQ nesting level
|
||||
*/
|
||||
uint32_t SystemGetIRQNestingLevel (void);
|
||||
|
||||
/**
|
||||
* @brief Setup systick for RTOS system.
|
||||
*
|
||||
* @param tickRateHz Tick number per second
|
||||
* @param intPriority IRQ interrupt priority (the smaller, the higher priority)
|
||||
*/
|
||||
void SystemSetupSystick (uint32_t tickRateHz, uint32_t intPriority);
|
||||
|
||||
/**
|
||||
* @brief Clear systick flag status so that next tick interrupt may occur.
|
||||
*/
|
||||
void SystemClearSystickFlag (void);
|
||||
|
||||
#define SysTick_Handler LPIT1_IRQHandler
|
||||
|
||||
/**
|
||||
* @brief Sysem is in ISR or not.
|
||||
*/
|
||||
bool SystemInISR(void);
|
||||
|
||||
/**
|
||||
* @brief Set interrupt priority in Event unit.
|
||||
*/
|
||||
void EVENT_SetIRQPriority(IRQn_Type IRQn, uint8_t intPriority);
|
||||
|
||||
/* Priority setting macro remap. */
|
||||
#define NVIC_SetPriority EVENT_SetIRQPriority
|
||||
|
||||
/**
|
||||
* @brief Reset the system.
|
||||
*/
|
||||
void EVENT_SystemReset(void);
|
||||
|
||||
#define NVIC_SystemReset EVENT_SystemReset
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYSTEM_RV32M1_zero_riscy_H_ */
|
||||
@@ -0,0 +1,9 @@
|
||||
SRC_FILES +=riscv64_switch.c
|
||||
SRC_FILES +=prepare_rhwstack.c
|
||||
|
||||
ifeq ($(CONFIG_TASK_ISOLATION),y)
|
||||
SRC_FILES += pmp.c
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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 "register_para.h"
|
||||
|
||||
.macro ZERO_X_REGISTERS
|
||||
xor zero, zero, zero
|
||||
xor ra, ra, ra
|
||||
xor sp, sp, sp
|
||||
xor gp, gp, gp
|
||||
xor tp, tp, tp
|
||||
xor t0, t0, t0
|
||||
xor t1, t1, t1
|
||||
xor t2, t2, t2
|
||||
xor s0, s0, s0
|
||||
xor s1, s1, s1
|
||||
xor a0, a0, a0
|
||||
xor a1, a1, a1
|
||||
xor a2, a2, a2
|
||||
xor a3, a3, a3
|
||||
xor a4, a4, a4
|
||||
xor a5, a5, a5
|
||||
xor a6, a6, a6
|
||||
xor a7, a7, a7
|
||||
xor s2, s2, s2
|
||||
xor s3, s3, s3
|
||||
xor s4, s4, s4
|
||||
xor s5, s5, s5
|
||||
xor s6, s6, s6
|
||||
xor s7, s7, s7
|
||||
xor s8, s8, s8
|
||||
xor s9, s9, s9
|
||||
xor s10, s10, s10
|
||||
xor s11, s11, s11
|
||||
xor t3, t3, t3
|
||||
xor t4, t4, t4
|
||||
xor t5, t5, t5
|
||||
xor t6, t6, t6
|
||||
.endm
|
||||
|
||||
.macro ZERO_F_REGISTERS
|
||||
FSubDS f0, f0, f0
|
||||
FSubDS f1, f1, f1
|
||||
FSubDS f2, f2, f2
|
||||
FSubDS f3, f3, f3
|
||||
FSubDS f4, f4, f4
|
||||
FSubDS f5, f5, f5
|
||||
FSubDS f6, f6, f6
|
||||
FSubDS f7, f7, f7
|
||||
FSubDS f8, f8, f8
|
||||
FSubDS f9, f9, f9
|
||||
FSubDS f10,f10,f10
|
||||
FSubDS f11,f11,f11
|
||||
FSubDS f12,f12,f12
|
||||
FSubDS f13,f13,f13
|
||||
FSubDS f14,f14,f14
|
||||
FSubDS f15,f15,f15
|
||||
FSubDS f16,f16,f16
|
||||
FSubDS f17,f17,f17
|
||||
FSubDS f18,f18,f18
|
||||
FSubDS f19,f19,f19
|
||||
FSubDS f20,f20,f20
|
||||
FSubDS f21,f21,f21
|
||||
FSubDS f22,f22,f22
|
||||
FSubDS f23,f23,f23
|
||||
FSubDS f24,f24,f24
|
||||
FSubDS f25,f25,f25
|
||||
FSubDS f26,f26,f26
|
||||
FSubDS f27,f27,f27
|
||||
FSubDS f28,f28,f28
|
||||
FSubDS f29,f29,f29
|
||||
FSubDS f30,f30,f30
|
||||
FSubDS f31,f31,f31
|
||||
.endm
|
||||
|
||||
.macro SAVE_X_REGISTERS
|
||||
|
||||
addi sp, sp, -32 * RegLength
|
||||
|
||||
StoreD ra, 1 * RegLength(sp)
|
||||
|
||||
csrr ra, mstatus
|
||||
StoreD ra, 2 * RegLength(sp)
|
||||
|
||||
csrr ra, mepc
|
||||
StoreD ra, 0 * RegLength(sp)
|
||||
|
||||
StoreD tp, 4 * RegLength(sp)
|
||||
StoreD t0, 5 * RegLength(sp)
|
||||
StoreD t1, 6 * RegLength(sp)
|
||||
StoreD t2, 7 * RegLength(sp)
|
||||
StoreD s0, 8 * RegLength(sp)
|
||||
StoreD s1, 9 * RegLength(sp)
|
||||
StoreD a0, 10 * RegLength(sp)
|
||||
StoreD a1, 11 * RegLength(sp)
|
||||
StoreD a2, 12 * RegLength(sp)
|
||||
StoreD a3, 13 * RegLength(sp)
|
||||
StoreD a4, 14 * RegLength(sp)
|
||||
StoreD a5, 15 * RegLength(sp)
|
||||
StoreD a6, 16 * RegLength(sp)
|
||||
StoreD a7, 17 * RegLength(sp)
|
||||
StoreD s2, 18 * RegLength(sp)
|
||||
StoreD s3, 19 * RegLength(sp)
|
||||
StoreD s4, 20 * RegLength(sp)
|
||||
StoreD s5, 21 * RegLength(sp)
|
||||
StoreD s6, 22 * RegLength(sp)
|
||||
StoreD s7, 23 * RegLength(sp)
|
||||
StoreD s8, 24 * RegLength(sp)
|
||||
StoreD s9, 25 * RegLength(sp)
|
||||
StoreD s10, 26 * RegLength(sp)
|
||||
StoreD s11, 27 * RegLength(sp)
|
||||
StoreD t3, 28 * RegLength(sp)
|
||||
StoreD t4, 29 * RegLength(sp)
|
||||
StoreD t5, 30 * RegLength(sp)
|
||||
StoreD t6, 31 * RegLength(sp)
|
||||
.endm
|
||||
|
||||
|
||||
@@ -0,0 +1,324 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file kswitch.h
|
||||
* @brief risc-v ecall function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-25
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: kswitch.h
|
||||
Description: risc-v ecall function
|
||||
Others: take incubator-nuttx arch/risc-v/include/rv64gc/syscall.h for references
|
||||
https://github.com/apache/incubator-nuttx/tree/master/arch/risc-v/include/rv64gc
|
||||
History:
|
||||
1. Date: 2021-04-25
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. Modify function name for a unified
|
||||
2. Add some functions when there is no system call
|
||||
*************************************************/
|
||||
|
||||
#ifndef __XS_RISC_V_KSWITCH_H__
|
||||
#define __XS_RISC_V_KSWITCH_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../../../kernel/include/xs_service.h"
|
||||
|
||||
#ifdef TASK_ISOLATION
|
||||
|
||||
/****************************************************************************
|
||||
* Name: KSwitch0
|
||||
*
|
||||
* Description:
|
||||
* ecall with zero parameters.
|
||||
*
|
||||
****************************************************************************/
|
||||
static inline uintptr_t KSwitch0(unsigned int nbr)
|
||||
{
|
||||
register long r0 asm("a0") = (long)(nbr);
|
||||
|
||||
asm volatile
|
||||
(
|
||||
"ecall"
|
||||
:: "r"(r0)
|
||||
);
|
||||
|
||||
asm volatile("nop" : "=r"(r0));
|
||||
|
||||
return r0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: KSwitch1
|
||||
*
|
||||
* Description:
|
||||
* ecall with one parameters.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uintptr_t KSwitch1(unsigned int nbr, uintptr_t parm1)
|
||||
{
|
||||
register long r0 asm("a0") = (long)(nbr);
|
||||
register long r1 asm("a1") = (long)(parm1);
|
||||
|
||||
asm volatile
|
||||
(
|
||||
"ecall"
|
||||
:: "r"(r0), "r"(r1)
|
||||
);
|
||||
|
||||
asm volatile("nop" : "=r"(r0));
|
||||
|
||||
return r0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: KSwitch2
|
||||
*
|
||||
* Description:
|
||||
* ecall with two parameters.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uintptr_t KSwitch2(unsigned int nbr, uintptr_t parm1,
|
||||
uintptr_t parm2)
|
||||
{
|
||||
register long r0 asm("a0") = (long)(nbr);
|
||||
register long r1 asm("a1") = (long)(parm1);
|
||||
register long r2 asm("a2") = (long)(parm2);
|
||||
|
||||
asm volatile
|
||||
(
|
||||
"ecall"
|
||||
:: "r"(r0), "r"(r1), "r"(r2)
|
||||
);
|
||||
|
||||
asm volatile("nop" : "=r"(r0));
|
||||
|
||||
return r0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: KSwitch3
|
||||
*
|
||||
* Description:
|
||||
* ecall with three parameters.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uintptr_t KSwitch3(unsigned int knum, uintptr_t arg1,
|
||||
uintptr_t arg2, uintptr_t arg3)
|
||||
{
|
||||
register long reg0 asm("a0") = (long)(knum);
|
||||
register long reg1 asm("a1") = (long)(arg1);
|
||||
register long reg2 asm("a2") = (long)(arg2);
|
||||
register long reg3 asm("a3") = (long)(arg3);
|
||||
|
||||
asm volatile
|
||||
(
|
||||
"ecall"
|
||||
:: "r"(reg0), "r"(reg1), "r"(reg2), "r"(reg3)
|
||||
);
|
||||
|
||||
asm volatile("nop" : "=r"(reg0));
|
||||
|
||||
return reg0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Name: KSwitch4
|
||||
*
|
||||
* Description:
|
||||
* ecall with four parameters.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uintptr_t KSwitch4(unsigned int nbr, uintptr_t parm1,
|
||||
uintptr_t parm2, uintptr_t parm3,
|
||||
uintptr_t parm4)
|
||||
{
|
||||
register long r0 asm("a0") = (long)(nbr);
|
||||
register long r1 asm("a1") = (long)(parm1);
|
||||
register long r2 asm("a2") = (long)(parm2);
|
||||
register long r3 asm("a3") = (long)(parm3);
|
||||
register long r4 asm("a4") = (long)(parm4);
|
||||
|
||||
asm volatile
|
||||
(
|
||||
"ecall"
|
||||
:: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)
|
||||
);
|
||||
|
||||
asm volatile("nop" : "=r"(r0));
|
||||
|
||||
return r0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: KSwitch5
|
||||
*
|
||||
* Description:
|
||||
* ecall with five parameters.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uintptr_t KSwitch5(unsigned int nbr, uintptr_t parm1,
|
||||
uintptr_t parm2, uintptr_t parm3,
|
||||
uintptr_t parm4, uintptr_t parm5)
|
||||
{
|
||||
register long r0 asm("a0") = (long)(nbr);
|
||||
register long r1 asm("a1") = (long)(parm1);
|
||||
register long r2 asm("a2") = (long)(parm2);
|
||||
register long r3 asm("a3") = (long)(parm3);
|
||||
register long r4 asm("a4") = (long)(parm4);
|
||||
register long r5 asm("a5") = (long)(parm5);
|
||||
|
||||
asm volatile
|
||||
(
|
||||
"ecall"
|
||||
:: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)
|
||||
);
|
||||
|
||||
asm volatile("nop" : "=r"(r0));
|
||||
|
||||
return r0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: KSwitch6
|
||||
*
|
||||
* Description:
|
||||
* ecall with six parameters.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uintptr_t KSwitch6(unsigned int nbr, uintptr_t parm1,
|
||||
uintptr_t parm2, uintptr_t parm3,
|
||||
uintptr_t parm4, uintptr_t parm5,
|
||||
uintptr_t parm6)
|
||||
{
|
||||
register long r0 asm("a0") = (long)(nbr);
|
||||
register long r1 asm("a1") = (long)(parm1);
|
||||
register long r2 asm("a2") = (long)(parm2);
|
||||
register long r3 asm("a3") = (long)(parm3);
|
||||
register long r4 asm("a4") = (long)(parm4);
|
||||
register long r5 asm("a5") = (long)(parm5);
|
||||
register long r6 asm("a6") = (long)(parm6);
|
||||
|
||||
asm volatile
|
||||
(
|
||||
"ecall"
|
||||
:: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5), "r"(r6)
|
||||
);
|
||||
|
||||
asm volatile("nop" : "=r"(r0));
|
||||
|
||||
return r0;
|
||||
}
|
||||
#else
|
||||
static inline unsigned long KSwitch0(unsigned int knum)
|
||||
{
|
||||
uintptr_t param[1] = {0};
|
||||
uint8_t num = 0;
|
||||
return SERVICETABLE[knum].fun(knum, param, num);
|
||||
}
|
||||
|
||||
static inline unsigned long KSwitch1(unsigned int knum, unsigned long arg1)
|
||||
{
|
||||
uintptr_t param[1] = {0};
|
||||
uint8_t num = 0;
|
||||
param[0] = arg1;
|
||||
return SERVICETABLE[knum].fun(knum, param, num );
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned long KSwitch2(unsigned int knum, unsigned long arg1,
|
||||
unsigned long arg2)
|
||||
{
|
||||
uintptr_t param[2] = {0};
|
||||
uint8_t num = 0;
|
||||
param[0] = arg1;
|
||||
param[1] = arg2;
|
||||
return SERVICETABLE[knum].fun(knum, param, num );
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned long KSwitch3(unsigned int knum, unsigned long arg1,
|
||||
unsigned long arg2, unsigned long arg3)
|
||||
{
|
||||
uintptr_t param[3] = {0};
|
||||
uint8_t num = 0;
|
||||
param[0] = arg1;
|
||||
param[1] = arg2;
|
||||
param[2] = arg3;
|
||||
|
||||
return SERVICETABLE[knum].fun(knum, param, num );
|
||||
}
|
||||
|
||||
static inline unsigned long KSwitch4(unsigned int knum, unsigned long arg1,
|
||||
unsigned long arg2, unsigned long arg3,
|
||||
unsigned long arg4)
|
||||
{
|
||||
uintptr_t param[4] = {0};
|
||||
uint8_t num = 0;
|
||||
param[0] = arg1;
|
||||
param[1] = arg2;
|
||||
param[2] = arg3;
|
||||
param[3] = arg4;
|
||||
return SERVICETABLE[knum].fun(knum, param, num );
|
||||
}
|
||||
|
||||
static inline unsigned long KSwitch5(unsigned int knum, unsigned long arg1,
|
||||
unsigned long arg2, unsigned long arg3,
|
||||
unsigned long arg4, unsigned long arg5)
|
||||
{
|
||||
uintptr_t param[5] = {0};
|
||||
uint8_t num = 0;
|
||||
param[0] = arg1;
|
||||
param[1] = arg2;
|
||||
param[2] = arg3;
|
||||
param[3] = arg4;
|
||||
param[4] = arg5;
|
||||
return SERVICETABLE[knum].fun(knum, param, num );
|
||||
}
|
||||
|
||||
static inline unsigned long KSwitch6(unsigned int knum, unsigned long arg1,
|
||||
unsigned long arg2, unsigned long arg3,
|
||||
unsigned long arg4, unsigned long arg5,
|
||||
unsigned long arg6)
|
||||
{
|
||||
uintptr_t param[6] = {0};
|
||||
uint8_t num = 0;
|
||||
param[0] = arg1;
|
||||
param[1] = arg2;
|
||||
param[2] = arg3;
|
||||
param[3] = arg4;
|
||||
param[4] = arg5;
|
||||
param[5] = arg6;
|
||||
return SERVICETABLE[knum].fun(knum, param, num );
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,517 @@
|
||||
/*
|
||||
* 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 "pmp.h"
|
||||
#include <board.h>
|
||||
#include <encoding.h>
|
||||
#include <xs_isolation.h>
|
||||
|
||||
#define USER_TEXT_START (uintptr_t)( USERSPACE )
|
||||
#define USER_TEXT_END (uintptr_t)( USERSPACE->us_textend )
|
||||
#define USER_SRAM_START (uintptr_t)( USERSPACE->us_datastart )
|
||||
#define USER_SRAM_END (uintptr_t)( USERSPACE->us_bssend )
|
||||
|
||||
|
||||
/**
|
||||
* This function add a pmp tor region to task pmp config
|
||||
*
|
||||
* @param task_pmp the task pmp config structure
|
||||
* @param start the memory start address
|
||||
* @param size the memory address size
|
||||
* @param type the memory type
|
||||
*
|
||||
* @return EOK
|
||||
*/
|
||||
x_err_t PmpAddTorRegion(void *task_pmp, x_ubase start , size_t size , uint8_t type )
|
||||
{
|
||||
if( task_pmp == NONE)
|
||||
return -ERROR;
|
||||
if (size == 0)
|
||||
return EOK;
|
||||
|
||||
struct Pmp *pmp;
|
||||
pmp = (struct Pmp *)task_pmp ;
|
||||
struct PmpRegionTor *region ;
|
||||
region = (struct PmpRegionTor *)x_malloc(sizeof(struct PmpRegionTor ));
|
||||
if (region == NONE)
|
||||
return -ENOMEM;
|
||||
|
||||
uint8_t flag = 0;
|
||||
switch (type)
|
||||
{
|
||||
case REGION_TYPE_CODE:
|
||||
flag = PMP_R | PMP_X ;
|
||||
break;
|
||||
case REGION_TYPE_DATA :
|
||||
flag = PMP_R | PMP_W ;
|
||||
break;
|
||||
case REGION_TYPE_BSS :
|
||||
flag = PMP_R | PMP_W ;
|
||||
break;
|
||||
case REGION_TYPE_HEAP :
|
||||
flag = PMP_R | PMP_W ;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
memset(region,0,sizeof(struct PmpRegionTor ));
|
||||
InitDoubleLinkList(&(region->link));
|
||||
region->region_type = PMP_TOR_TYPE;
|
||||
region->start = start;
|
||||
region->end = start + size ;
|
||||
region->entry[0].pmpcfg = PMP_NA4 | flag;
|
||||
region->entry[0].pmpaddr = TO_PMP_ADDR(start);
|
||||
|
||||
region->entry[1].pmpcfg = PMP_TOR | flag;
|
||||
region->entry[1].pmpaddr = TO_PMP_ADDR(ALIGN_MEN_UP(region->end,4));
|
||||
|
||||
|
||||
if (pmp->count <= PMP_MAX_ENTRY_NUMBER - 2 )
|
||||
{
|
||||
DoubleLinkListInsertNodeAfter(&pmp->tor_list, ®ion->link);
|
||||
pmp->count = pmp->count + 2 ;
|
||||
}else
|
||||
{
|
||||
struct PmpRegionTor *node ;
|
||||
node = (struct PmpRegionTor *)pmp->tor_list.node_next ;
|
||||
DoubleLinkListRmNode(&(node->link));
|
||||
DoubleLinkListInsertNodeAfter(&pmp->tor_list, ®ion->link);
|
||||
DoubleLinkListInsertNodeAfter(&pmp->tor_swap_list, &node->link);
|
||||
node->swap_count ++;
|
||||
}
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function free a pmp region
|
||||
*
|
||||
* @param task_pmp the task pmp config structure
|
||||
* @param addr the memory address
|
||||
*
|
||||
* @return EOK
|
||||
*/
|
||||
x_err_t PmpClearRegion(void *task_pmp, x_ubase addr)
|
||||
{
|
||||
// KPrintf("PmpClearRegion\n");
|
||||
if( task_pmp == NONE)
|
||||
return -ERROR;
|
||||
struct Pmp *pmp;
|
||||
pmp = (struct Pmp *)task_pmp ;
|
||||
|
||||
struct PmpRegionTor *tor_node = NONE;
|
||||
DoubleLinklistType *link = NONE;
|
||||
|
||||
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 ){
|
||||
pmp->count = pmp->count -2;
|
||||
goto __free ;
|
||||
}
|
||||
}
|
||||
}
|
||||
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 ) {
|
||||
goto __free;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__free:
|
||||
DoubleLinkListRmNode(&(tor_node->link));
|
||||
x_free(tor_node);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function init a task pmp config structure and add some pmp region
|
||||
*
|
||||
* @param task_pmp the task pmp config structure
|
||||
* @param stack_start the task stack address
|
||||
* @param stack_size the task stack size
|
||||
*
|
||||
* @return EOK
|
||||
*/
|
||||
x_err_t PmpInitIsolation(void **task_pmp, x_ubase stack_start , size_t stack_size)
|
||||
{
|
||||
|
||||
struct Pmp *pmp ;
|
||||
pmp = (struct Pmp *)x_malloc(sizeof(struct Pmp));
|
||||
if(pmp == NONE)
|
||||
return -ENOMEMORY;
|
||||
memset(pmp,0,sizeof(struct Pmp));
|
||||
InitDoubleLinkList(&(pmp->tor_list));
|
||||
InitDoubleLinkList(&(pmp->tor_swap_list));
|
||||
uint8_t index = 0;
|
||||
|
||||
// text
|
||||
if (USER_TEXT_END - USER_TEXT_START > 0 ) {
|
||||
pmp->pmp_entry_reserve[index].pmpcfg = PMP_NA4 | PMP_R | PMP_X ;
|
||||
pmp->pmp_entry_reserve[index].pmpaddr = TO_PMP_ADDR(USER_TEXT_START);
|
||||
pmp->pmp_entry_reserve[index + 1].pmpcfg = PMP_TOR | PMP_R | PMP_X ;
|
||||
pmp->pmp_entry_reserve[index + 1].pmpaddr = TO_PMP_ADDR(ALIGN_MEN_UP(USER_TEXT_END,4));
|
||||
index = index + 2 ;
|
||||
pmp->count = pmp->count + 2;
|
||||
pmp->reserve = pmp->reserve + 2;
|
||||
}
|
||||
|
||||
// data & bss
|
||||
if (USER_SRAM_END - USER_SRAM_START > 0 ) {
|
||||
pmp->pmp_entry_reserve[index].pmpcfg = PMP_NA4 | PMP_R | PMP_W ;
|
||||
pmp->pmp_entry_reserve[index].pmpaddr = TO_PMP_ADDR(USER_SRAM_START);
|
||||
pmp->pmp_entry_reserve[index + 1].pmpcfg = PMP_TOR | PMP_R | PMP_W ;
|
||||
pmp->pmp_entry_reserve[index + 1].pmpaddr = TO_PMP_ADDR(ALIGN_MEN_UP(USER_SRAM_END,4));
|
||||
index = index + 2 ;
|
||||
pmp->count = pmp->count + 2;
|
||||
pmp->reserve = pmp->reserve + 2;
|
||||
}
|
||||
|
||||
if (stack_size > 0 ) {
|
||||
pmp->pmp_entry_reserve[index].pmpcfg = PMP_NA4 | PMP_R | PMP_W | PMP_X ;
|
||||
pmp->pmp_entry_reserve[index].pmpaddr = TO_PMP_ADDR(stack_start);
|
||||
pmp->pmp_entry_reserve[index + 1].pmpcfg = PMP_TOR | PMP_R | PMP_W | PMP_X ;
|
||||
pmp->pmp_entry_reserve[index + 1].pmpaddr = TO_PMP_ADDR(ALIGN_MEN_UP((stack_start + stack_size),4));
|
||||
pmp->count = pmp->count + 2;
|
||||
pmp->reserve = pmp->reserve + 2;
|
||||
}
|
||||
|
||||
*task_pmp = (void *)pmp;
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function free task pmp config structure
|
||||
*
|
||||
* @param task_pmp the task pmp config structure
|
||||
*
|
||||
*/
|
||||
void PmpFree(void *task_pmp){
|
||||
// KPrintf("pmp free \n");
|
||||
|
||||
if( task_pmp == NONE)
|
||||
return ;
|
||||
struct Pmp *pmp;
|
||||
pmp = (struct Pmp *)task_pmp ;
|
||||
|
||||
struct PmpRegionTor *tor_node = NONE;
|
||||
DoubleLinklistType *link = NONE;
|
||||
|
||||
if (!IsDoubleLinkListEmpty(&(pmp->tor_list)) ){
|
||||
DOUBLE_LINKLIST_FOR_EACH(link, &pmp->tor_list)
|
||||
{
|
||||
tor_node = CONTAINER_OF(link, struct PmpRegionTor, link);
|
||||
DoubleLinkListRmNode(&(tor_node->link));
|
||||
x_free(tor_node);
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsDoubleLinkListEmpty(&pmp->tor_swap_list)) {
|
||||
DOUBLE_LINKLIST_FOR_EACH(link, &pmp->tor_swap_list) {
|
||||
tor_node = CONTAINER_OF(link, struct PmpRegionTor, link);
|
||||
DoubleLinkListRmNode(&(tor_node->link));
|
||||
x_free(tor_node);
|
||||
}
|
||||
}
|
||||
|
||||
x_free(pmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function write value to pmp config register
|
||||
* @param index pmpcfg register index
|
||||
* @param value pmpcfg register value
|
||||
*
|
||||
*/
|
||||
void WritePmpcfg(uint8_t index , x_ubase value)
|
||||
{
|
||||
if ( index == 0 ) {
|
||||
WRITE_CSR(pmpcfg0, value);
|
||||
}else if ( index == 1 ) {
|
||||
WRITE_CSR(pmpcfg1, value);
|
||||
}else if ( index == 2 ) {
|
||||
WRITE_CSR(pmpcfg2, value);
|
||||
}else if ( index == 3 ) {
|
||||
WRITE_CSR(pmpcfg3, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function write value to pmp addr register
|
||||
* @param index pmpaddr register index
|
||||
* @param value pmpaddr register value
|
||||
*
|
||||
*/
|
||||
void WritePmpaddr(uint8_t index, x_ubase value)
|
||||
{
|
||||
|
||||
if ( index == 0 ) {
|
||||
WRITE_CSR(pmpaddr0, value);
|
||||
}else if ( index == 1 ) {
|
||||
WRITE_CSR(pmpaddr1, value);
|
||||
}else if ( index == 2 ) {
|
||||
WRITE_CSR(pmpaddr2, value);
|
||||
}else if ( index == 3 ) {
|
||||
WRITE_CSR(pmpaddr3, value);
|
||||
}else if ( index == 4 ) {
|
||||
WRITE_CSR(pmpaddr4, value);
|
||||
}else if ( index == 5 ) {
|
||||
WRITE_CSR(pmpaddr5, value);
|
||||
}else if ( index == 6 ) {
|
||||
WRITE_CSR(pmpaddr6, value);
|
||||
}else if ( index == 7 ) {
|
||||
WRITE_CSR(pmpaddr7, value);
|
||||
}else if ( index == 8 ) {
|
||||
WRITE_CSR(pmpaddr8, value);
|
||||
}else if ( index == 9 ) {
|
||||
WRITE_CSR(pmpaddr9, value);
|
||||
}else if ( index == 10 ) {
|
||||
WRITE_CSR(pmpaddr10, value);
|
||||
}else if ( index == 11 ) {
|
||||
WRITE_CSR(pmpaddr11, value);
|
||||
}else if ( index == 12 ) {
|
||||
WRITE_CSR(pmpaddr12, value);
|
||||
}else if ( index == 13 ) {
|
||||
WRITE_CSR(pmpaddr13, value);
|
||||
}else if ( index == 14 ) {
|
||||
WRITE_CSR(pmpaddr14, value);
|
||||
}else if ( index == 15 ) {
|
||||
WRITE_CSR(pmpaddr15, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function handle user task access memory fault, check addr in pmp swap list or not ,if addr is in
|
||||
* pmp swap list, swap in to pmp list.
|
||||
*
|
||||
* @param task_pmp the task pmp config structure
|
||||
* @param addr access addr when fault
|
||||
*
|
||||
* @return EOK
|
||||
*/
|
||||
x_bool PmpAccessFaultHandle(void *task_pmp, x_ubase addr)
|
||||
{
|
||||
if( task_pmp == NONE)
|
||||
return RET_FALSE;
|
||||
struct Pmp *pmp;
|
||||
pmp = (struct Pmp *)task_pmp ;
|
||||
|
||||
x_bool ret = RET_FALSE;
|
||||
uint8_t region_type;
|
||||
DoubleLinklistType *link = NONE;
|
||||
struct PmpRegionTor *tor_node = NONE;
|
||||
|
||||
|
||||
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 && addr <= (tor_node->end) ) {
|
||||
region_type = PMP_TOR;
|
||||
goto __swap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
goto __exit;
|
||||
|
||||
__swap:
|
||||
|
||||
if ( region_type = PMP_TOR ) {
|
||||
if( pmp->count < PMP_MAX_ENTRY_NUMBER - 2) {
|
||||
DoubleLinkListRmNode(&(tor_node->link));
|
||||
DoubleLinkListInsertNodeBefore(&pmp->tor_list, &tor_node->link);
|
||||
pmp->count = pmp->count + 2;
|
||||
} else {
|
||||
struct PmpRegionTor *swap_node;
|
||||
swap_node = (struct PmpRegionTor *)pmp->tor_list.node_next;
|
||||
DoubleLinkListRmNode(&(swap_node->link));
|
||||
DoubleLinkListRmNode(&(tor_node->link));
|
||||
DoubleLinkListInsertNodeBefore(&pmp->tor_list, &tor_node->link);
|
||||
DoubleLinkListInsertNodeBefore(&pmp->tor_swap_list, &swap_node->link);
|
||||
swap_node->swap_count ++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
ret = RET_TRUE;
|
||||
|
||||
__exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(ARCH_RISCV64)
|
||||
/**
|
||||
* This function clear pmp registers.
|
||||
*/
|
||||
void PmpClear(void)
|
||||
{
|
||||
WRITE_CSR(pmpcfg0, 0);
|
||||
WRITE_CSR(pmpcfg2, 0);
|
||||
|
||||
WRITE_CSR(pmpaddr0, 0);
|
||||
WRITE_CSR(pmpaddr1, 0);
|
||||
WRITE_CSR(pmpaddr2, 0);
|
||||
WRITE_CSR(pmpaddr3, 0);
|
||||
WRITE_CSR(pmpaddr4, 0);
|
||||
WRITE_CSR(pmpaddr5, 0);
|
||||
WRITE_CSR(pmpaddr6, 0);
|
||||
WRITE_CSR(pmpaddr7, 0);
|
||||
WRITE_CSR(pmpaddr8, 0);
|
||||
WRITE_CSR(pmpaddr9, 0);
|
||||
WRITE_CSR(pmpaddr10, 0);
|
||||
WRITE_CSR(pmpaddr11, 0);
|
||||
WRITE_CSR(pmpaddr12, 0);
|
||||
WRITE_CSR(pmpaddr13, 0);
|
||||
WRITE_CSR(pmpaddr14, 0);
|
||||
WRITE_CSR(pmpaddr15, 0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This function load task pmp config to pmp register.
|
||||
* @param task_pmp the task pmp config structure
|
||||
*
|
||||
*/
|
||||
void PmpLoad(void *task_pmp)
|
||||
{
|
||||
// KPrintf("pmpLoad \n");
|
||||
if( task_pmp == NONE)
|
||||
return ;
|
||||
struct Pmp *pmp;
|
||||
pmp = (struct Pmp *)task_pmp ;
|
||||
|
||||
PmpClear();
|
||||
uint8_t index = 0;
|
||||
x_ubase pmpcfg0 = 0 ;
|
||||
x_ubase pmpcfg2 = 0 ;
|
||||
|
||||
|
||||
for( int i = 0 ; i < pmp->reserve; i++){
|
||||
pmpcfg0 |= pmp->pmp_entry_reserve[i].pmpcfg << ( index * 8) ;
|
||||
WritePmpaddr(index , pmp->pmp_entry_reserve[i].pmpaddr );
|
||||
index ++ ;
|
||||
}
|
||||
|
||||
DoubleLinklistType *link = NONE;
|
||||
struct PmpRegionTor *node2 = NONE;
|
||||
|
||||
if (!IsDoubleLinkListEmpty(&pmp->tor_list) ){
|
||||
DOUBLE_LINKLIST_FOR_EACH(link, &pmp->tor_list)
|
||||
{
|
||||
node2 = CONTAINER_OF(link, struct PmpRegionTor, link);
|
||||
WritePmpaddr(index ,node2->entry[0].pmpaddr );
|
||||
if (index < 8)
|
||||
pmpcfg0 |= node2->entry[0].pmpcfg << ( index * 8);
|
||||
else
|
||||
pmpcfg2 |= node2->entry[0].pmpcfg << ( (index - 8) * 8);
|
||||
index ++;
|
||||
|
||||
WritePmpaddr(index ,node2->entry[1].pmpaddr );
|
||||
if (index < 8)
|
||||
pmpcfg0 |= node2->entry[1].pmpcfg << ( index * 8);
|
||||
else
|
||||
pmpcfg2 |= node2->entry[1].pmpcfg << ( (index - 8) * 8);
|
||||
index ++;
|
||||
}
|
||||
}
|
||||
WritePmpcfg(0, pmpcfg0 );
|
||||
WritePmpcfg(2, pmpcfg2 );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
* This function clear pmp registers.
|
||||
*/
|
||||
void PmpClear(void)
|
||||
{
|
||||
WRITE_CSR(pmpcfg0, 0);
|
||||
WRITE_CSR(pmpcfg1, 0);
|
||||
WRITE_CSR(pmpcfg2, 0);
|
||||
WRITE_CSR(pmpcfg3, 0);
|
||||
|
||||
WRITE_CSR(pmpaddr0, 0);
|
||||
WRITE_CSR(pmpaddr1, 0);
|
||||
WRITE_CSR(pmpaddr2, 0);
|
||||
WRITE_CSR(pmpaddr3, 0);
|
||||
WRITE_CSR(pmpaddr4, 0);
|
||||
WRITE_CSR(pmpaddr5, 0);
|
||||
WRITE_CSR(pmpaddr6, 0);
|
||||
WRITE_CSR(pmpaddr7, 0);
|
||||
WRITE_CSR(pmpaddr8, 0);
|
||||
WRITE_CSR(pmpaddr9, 0);
|
||||
WRITE_CSR(pmpaddr10, 0);
|
||||
WRITE_CSR(pmpaddr11, 0);
|
||||
WRITE_CSR(pmpaddr12, 0);
|
||||
WRITE_CSR(pmpaddr13, 0);
|
||||
WRITE_CSR(pmpaddr14, 0);
|
||||
WRITE_CSR(pmpaddr15, 0);
|
||||
}
|
||||
#define PMP_CFG_CONVERSE(a,b,c,d) ( ((uint32_t)(d) << 24) | ((uint32_t)(c) << 16) | ((uint32_t)(b) << 8) | (uint32_t)(a) )
|
||||
|
||||
/**
|
||||
* This function load task pmp config to pmp register.
|
||||
* @param task_pmp the task pmp config structure
|
||||
*
|
||||
*/
|
||||
void PmpLoad(void *task_pmp)
|
||||
{
|
||||
// KPrintf("pmpLoad \n");
|
||||
if( task_pmp == NONE)
|
||||
return ;
|
||||
struct Pmp *pmp;
|
||||
pmp = (struct Pmp *)task_pmp ;
|
||||
|
||||
PmpClear();
|
||||
uint8_t index = 0;
|
||||
|
||||
uint8_t pmpcfg[16] = { 0 } ;
|
||||
uint32_t pmpcfg0 = 0 ;
|
||||
uint32_t pmpcfg1 = 0 ;
|
||||
uint32_t pmpcfg2 = 0 ;
|
||||
uint32_t pmpcfg3 = 0 ;
|
||||
|
||||
for( int i = 0 ; i < pmp->reserve; i++){
|
||||
pmpcfg[index] = pmp->pmp_entry_reserve[i].pmpcfg ;
|
||||
WritePmpaddr(index , pmp->pmp_entry_reserve[i].pmpaddr );
|
||||
index ++ ;
|
||||
}
|
||||
|
||||
DoubleLinklistType *node = NONE;
|
||||
struct PmpRegionTor *tor_node = NONE;
|
||||
if (!IsDoubleLinkListEmpty(&(pmp->tor_list)) ){
|
||||
DOUBLE_LINKLIST_FOR_EACH(node, &(pmp->tor_list))
|
||||
{
|
||||
tor_node = CONTAINER_OF(node, struct PmpRegionTor, link);
|
||||
WritePmpaddr(index ,tor_node->entry[0].pmpaddr );
|
||||
pmpcfg[index] = tor_node->entry[0].pmpcfg;
|
||||
index ++;
|
||||
|
||||
WritePmpaddr(index ,tor_node->entry[1].pmpaddr );
|
||||
pmpcfg[index] = tor_node->entry[1].pmpcfg;
|
||||
index ++;
|
||||
}
|
||||
}
|
||||
|
||||
pmpcfg0 = PMP_CFG_CONVERSE(pmpcfg[0], pmpcfg[1], pmpcfg[2], pmpcfg[3]);
|
||||
pmpcfg1 = PMP_CFG_CONVERSE(pmpcfg[4], pmpcfg[5], pmpcfg[6], pmpcfg[7]);
|
||||
pmpcfg2 = PMP_CFG_CONVERSE(pmpcfg[8], pmpcfg[9], pmpcfg[10], pmpcfg[11]);
|
||||
pmpcfg3 = PMP_CFG_CONVERSE(pmpcfg[12], pmpcfg[13], pmpcfg[14], pmpcfg[15]);
|
||||
WritePmpcfg(0, pmpcfg0);
|
||||
WritePmpcfg(1, pmpcfg1);
|
||||
WritePmpcfg(2, pmpcfg2);
|
||||
WritePmpcfg(3, pmpcfg3);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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 PMP_H
|
||||
#define PMP_H
|
||||
|
||||
#include <xs_klist.h>
|
||||
|
||||
#define PMP_MAX_ENTRY_NUMBER 16
|
||||
#define PMP_ENTRY_RESERVE 6
|
||||
#define PMP_ENTRY_MAX 255
|
||||
|
||||
#define PMP_R 0x01 /* Allow read */
|
||||
#define PMP_W 0x02 /* Allow write */
|
||||
#define PMP_X 0x04 /* Allow execute */
|
||||
#define PMP_L 0x80 /* PMP entry is locked */
|
||||
#define PMP_OFF 0x00 /* Null region */
|
||||
#define PMP_TOR 0x08 /* Top of range */
|
||||
#define PMP_NA4 0x10 /* Naturally aligned four-byte region */
|
||||
#define PMP_NAPOT 0x18 /* Naturally aligned power-of-two region */
|
||||
|
||||
#define PMP_TOR_TYPE 0 /* Top of range */
|
||||
#define PMP_NAPOT_TYPE 1 /* Naturally aligned power-of-two region */
|
||||
|
||||
#define PMP_SHIFT_ADDR 2
|
||||
#define PMP_TYPE_MASK 0x18
|
||||
#define TO_PMP_ADDR(addr) ((addr) >> PMP_SHIFT_ADDR)
|
||||
#define FROM_PMP_ADDR(addr) ((addr) << PMP_SHIFT_ADDR)
|
||||
#define TO_NAPOT_RANGE(size) (((size) - 1) >> 1)
|
||||
#define TO_PMP_NAPOT(addr, size) TO_PMP_ADDR(addr | TO_NAPOT_RANGE(size))
|
||||
|
||||
struct PmpEntry
|
||||
{
|
||||
uint8_t pmpcfg;
|
||||
#if defined(ARCH_RISCV64)
|
||||
uint64_t pmpaddr;
|
||||
#else
|
||||
uint32_t pmpaddr;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
struct PmpRegionNapot
|
||||
{
|
||||
x_ubase start ;
|
||||
x_ubase end;
|
||||
uint16_t swap_count;
|
||||
uint8_t region_type;
|
||||
struct PmpEntry entry;
|
||||
|
||||
DoubleLinklistType link;
|
||||
};
|
||||
|
||||
struct PmpRegionTor
|
||||
{
|
||||
x_ubase start ;
|
||||
x_ubase end;
|
||||
uint16_t swap_count;
|
||||
uint8_t region_type;
|
||||
struct PmpEntry entry[2];
|
||||
|
||||
DoubleLinklistType link;
|
||||
};
|
||||
|
||||
struct Pmp
|
||||
{
|
||||
uint8_t count;
|
||||
uint8_t reserve;
|
||||
struct PmpEntry pmp_entry_reserve[PMP_ENTRY_RESERVE];
|
||||
DoubleLinklistType tor_list;
|
||||
|
||||
DoubleLinklistType tor_swap_list;
|
||||
};
|
||||
|
||||
|
||||
x_err_t PmpAddTorRegion(void *task_pmp, x_ubase start , size_t size , uint8_t flag );
|
||||
x_err_t PmpInitIsolation(void **task_pmp, x_ubase stack_start , size_t stack_size);
|
||||
void PmpFree(void *task_pmp);
|
||||
void PmpClear(void);
|
||||
x_err_t PmpClearRegion(void *task_pmp, x_ubase addr);
|
||||
void PmpLoad(void *task_pmp);
|
||||
x_bool PmpAccessFaultHandle(void *task_pmp, x_ubase addr);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* 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 "register_para.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
|
||||
|
||||
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
|
||||
stack_contex->mstatus = 0x00007880;
|
||||
|
||||
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,109 @@
|
||||
/*
|
||||
* 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 RISCV_PLIC_H__
|
||||
#define RISCV_PLIC_H__
|
||||
|
||||
#ifndef PLIC_BASE_ADDR
|
||||
#define PLIC_BASE_ADDR 0x0
|
||||
#endif
|
||||
|
||||
#define PLIC_PRIORITY_OFFSET (0x00000000UL)
|
||||
#define PLIC_PRIORITY_SHIFT_PER_SOURCE 2
|
||||
|
||||
#define PLIC_PENDING_OFFSET (0x00001000UL)
|
||||
#define PLIC_PENDING_SHIFT_PER_SOURCE 0
|
||||
|
||||
#define PLIC_ENABLE_OFFSET (0x00002000UL)
|
||||
#define PLIC_ENABLE_SHIFT_PER_TARGET 7
|
||||
|
||||
#define PLIC_THRESHOLD_OFFSET (0x00200000UL)
|
||||
#define PLIC_THRESHOLD_SHIFT_PER_TARGET 12
|
||||
|
||||
#define PLIC_CLAIM_OFFSET (0x00200004UL)
|
||||
#define PLIC_CLAIM_SHIFT_PER_TARGET 12
|
||||
|
||||
#if defined(__GNUC__) && !defined(__ASSEMBLER__)
|
||||
__attribute__((always_inline)) static inline void PlicSetFeature(unsigned int feature)
|
||||
{
|
||||
volatile unsigned int *feature_ptr = (volatile unsigned int *)PLIC_BASE_ADDR;
|
||||
*feature_ptr = feature;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void PlicSetThreshold(unsigned int threshold)
|
||||
{
|
||||
unsigned int hart_id = READ_CSR(mhartid);
|
||||
volatile unsigned int *threshold_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR +
|
||||
PLIC_THRESHOLD_OFFSET +
|
||||
(hart_id << PLIC_THRESHOLD_SHIFT_PER_TARGET));
|
||||
*threshold_ptr = threshold;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void PlicSetPriority(unsigned int source, unsigned int priority)
|
||||
{
|
||||
volatile unsigned int *priority_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR +
|
||||
PLIC_PRIORITY_OFFSET +
|
||||
(source << PLIC_PRIORITY_SHIFT_PER_SOURCE));
|
||||
*priority_ptr = priority;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void PlicSetPending(unsigned int source)
|
||||
{
|
||||
volatile unsigned int *current_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR +
|
||||
PLIC_PENDING_OFFSET +
|
||||
((source >> 5) << 2));
|
||||
*current_ptr = (1 << (source & 0x1F));
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void PlicIrqEnable(unsigned int source)
|
||||
{
|
||||
unsigned int hart_id = READ_CSR(mhartid);
|
||||
volatile unsigned int *current_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR +
|
||||
PLIC_ENABLE_OFFSET +
|
||||
(hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) +
|
||||
((source >> 5) << 2));
|
||||
unsigned int current = *current_ptr;
|
||||
current = current | (1 << (source & 0x1F));
|
||||
*current_ptr = current;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void PlicIrqDisable(unsigned int source)
|
||||
{
|
||||
unsigned int hart_id = READ_CSR(mhartid);
|
||||
volatile unsigned int *current_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR +
|
||||
PLIC_ENABLE_OFFSET +
|
||||
(hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) +
|
||||
((source >> 5) << 2));
|
||||
unsigned int current = *current_ptr;
|
||||
current = current & ~((1 << (source & 0x1F)));
|
||||
*current_ptr = current;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline unsigned int PlicIrqClaim(void)
|
||||
{
|
||||
unsigned int hart_id = READ_CSR(mhartid);
|
||||
volatile unsigned int *claim_addr = (volatile unsigned int *)(PLIC_BASE_ADDR +
|
||||
PLIC_CLAIM_OFFSET +
|
||||
(hart_id << PLIC_CLAIM_SHIFT_PER_TARGET));
|
||||
return *claim_addr;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void PlicIrqComplete(unsigned int source)
|
||||
{
|
||||
unsigned int hart_id = READ_CSR(mhartid);
|
||||
volatile unsigned int *claim_addr = (volatile unsigned int *)(PLIC_BASE_ADDR +
|
||||
PLIC_CLAIM_OFFSET +
|
||||
(hart_id << PLIC_CLAIM_SHIFT_PER_TARGET));
|
||||
*claim_addr = source;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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 RISCV_OPS_H__
|
||||
#define RISCV_OPS_H__
|
||||
|
||||
#if defined(__GNUC__) && !defined(__ASSEMBLER__)
|
||||
|
||||
#define READ_CSR(reg) ({ unsigned long __tmp; \
|
||||
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
|
||||
__tmp; })
|
||||
|
||||
#define WRITE_CSR(reg, val) ({ \
|
||||
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
|
||||
asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
|
||||
else \
|
||||
asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
|
||||
|
||||
#define SET_CSR(reg, bit) ({ unsigned long __tmp; \
|
||||
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
|
||||
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
|
||||
else \
|
||||
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
|
||||
__tmp; })
|
||||
|
||||
#define CLEAR_CSR(reg, bit) ({ unsigned long __tmp; \
|
||||
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
|
||||
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
|
||||
else \
|
||||
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
|
||||
__tmp; })
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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__
|
||||
|
||||
#include <xsconfig.h>
|
||||
|
||||
#ifdef ARCH_CPU_64BIT
|
||||
#define StoreD sd
|
||||
#define LoadD ld
|
||||
#define FSubDS fsub.d
|
||||
#define RegLength 8
|
||||
#define StoreDS "sd"
|
||||
#define LoadDS "ld"
|
||||
#define RegLengthS "8"
|
||||
#else
|
||||
#define StoreD sw
|
||||
#define LoadD lw
|
||||
#define FSubDS fsub.s
|
||||
#define RegLength 4
|
||||
#define StoreDS "sw"
|
||||
#define LoadDS "lw"
|
||||
#define RegLengthS "4"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* 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 "register_para.h"
|
||||
#include <xs_base.h>
|
||||
#include <xs_ktask.h>
|
||||
|
||||
void __attribute__((naked)) SwitchKTaskContextExit()
|
||||
{
|
||||
asm volatile (LoadDS " a0, 0 * " RegLengthS "(sp)");
|
||||
asm volatile ("csrw mepc, a0");
|
||||
#ifdef TASK_ISOLATION
|
||||
asm volatile (LoadDS " a0, 2 * " RegLengthS "(sp)");
|
||||
asm volatile ("csrw mstatus, a0");
|
||||
asm volatile ("mv a0, sp");
|
||||
asm volatile ("jal RestoreMstatus");
|
||||
#else
|
||||
asm volatile ("li t0, 0x00007800");
|
||||
asm volatile ("csrw mstatus, t0");
|
||||
asm volatile (LoadDS " a0, 2 * " RegLengthS "(sp)");
|
||||
asm volatile ("csrs mstatus, a0");
|
||||
#endif
|
||||
asm volatile (LoadDS " ra, 1 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " tp, 4 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " t0, 5 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " t1, 6 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " t2, 7 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " s0, 8 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " s1, 9 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " a0, 10 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " a1, 11 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " a2, 12 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " a3, 13 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " a4, 14 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " a5, 15 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " a6, 16 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " a7, 17 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " s2, 18 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " s3, 19 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " s4, 20 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " s5, 21 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " s6, 22 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " s7, 23 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " s8, 24 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " s9, 25 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " s10, 26 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " s11, 27 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " t3, 28 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " t4, 29 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " t5, 30 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " t6, 31 * " RegLengthS "(sp)");
|
||||
asm volatile ("addi sp, sp, 32 * " RegLengthS "");
|
||||
|
||||
#ifdef ARCH_RISCV_FPU
|
||||
asm volatile (FLOAD " f0, 0 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f1, 1 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f2, 2 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f3, 3 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f4, 4 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f5, 5 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f6, 6 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f7, 7 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f8, 8 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f9, 9 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f10, 10 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f11, 11 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f12, 12 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f13, 13 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f14, 14 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f15, 15 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f16, 16 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f17, 17 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f18, 18 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f19, 19 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f20, 20 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f21, 21 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f22, 22 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f23, 23 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f24, 24 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f25, 25 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f26, 26 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f27, 27 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f28, 28 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f29, 29 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f30, 30 *" FREGBYTES "(sp)");
|
||||
asm volatile (FLOAD " f31, 31 *" FREGBYTES "(sp)");
|
||||
asm volatile ("addi sp, sp, 32 *" FREGBYTES);
|
||||
#endif
|
||||
|
||||
asm volatile ("mret");
|
||||
}
|
||||
|
||||
void __attribute__((naked)) SaveMpie()
|
||||
{
|
||||
|
||||
#ifdef ARCH_RISCV_FPV
|
||||
asm volatile ("addi sp, sp, -32 *" FREGBYTES);
|
||||
|
||||
asm volatile (FSTORE " f0, 0 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f1, 1 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f2, 2 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f3, 3 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f4, 4 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f5, 5 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f6, 6 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f7, 7 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f8, 8 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f9, 9 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f10, 10 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f11, 11 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f12, 12 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f13, 13 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f14, 14 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f15, 15 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f16, 16 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f17, 17 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f18, 18 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f19, 19 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f20, 20 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f21, 21 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f22, 22 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f23, 23 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f24, 24 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f25, 25 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f26, 26 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f27, 27 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f28, 28 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f29, 29 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f30, 30 *" FREGBYTES "(sp)");
|
||||
asm volatile (FSTORE " f31, 31 *" FREGBYTES "(sp)");
|
||||
#endif
|
||||
|
||||
asm volatile (StoreDS " a0, 2 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " tp, 4 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " t0, 5 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " t1, 6 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " t2, 7 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " s0, 8 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " s1, 9 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " a0, 10 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " a1, 11 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " a2, 12 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " a3, 13 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " a4, 14 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " a5, 15 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " a6, 16 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " a7, 17 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " s2, 18 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " s3, 19 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " s4, 20 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " s5, 21 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " s6, 22 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " s7, 23 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " s8, 24 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " s9, 25 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " s10, 26 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " s11, 27 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " t3, 28 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " t4, 29 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " t5, 30 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " t6, 31 * " RegLengthS "(sp)");
|
||||
asm volatile (LoadDS " sp, (a1)");
|
||||
asm volatile ("mv a0, a2");
|
||||
asm volatile ("jal RestoreCpusLockStatus");
|
||||
asm volatile ("j SwitchKTaskContextExit");
|
||||
}
|
||||
|
||||
void __attribute__((naked)) SwitchKtaskContextTo(x_ubase to, struct TaskDescriptor *to_task)
|
||||
{
|
||||
asm volatile (LoadDS " sp, (a0)\n");
|
||||
asm volatile ("mv a0, a1");
|
||||
asm volatile ("jal RestoreCpusLockStatus");
|
||||
asm volatile (LoadDS " a7, 2 * " RegLengthS "(sp)");
|
||||
asm volatile ("csrw mstatus, a7");
|
||||
asm volatile ("j SwitchKTaskContextExit");
|
||||
}
|
||||
|
||||
void __attribute__((naked)) SwitchKtaskContext(x_ubase from, x_ubase to, struct TaskDescriptor *to_task)
|
||||
{
|
||||
asm volatile ("addi sp, sp, -32 * " RegLengthS);
|
||||
asm volatile (StoreDS " sp, (a0)");
|
||||
asm volatile (StoreDS " x1, 0 * " RegLengthS "(sp)");
|
||||
asm volatile (StoreDS " x1, 1 * " RegLengthS "(sp)");
|
||||
asm volatile ("csrr a0, mstatus");
|
||||
#ifndef TASK_ISOLATION
|
||||
asm volatile ("andi a0, a0, 8");
|
||||
asm volatile ("beqz a0, SaveMpie");
|
||||
asm volatile ("li a0, 0x80");
|
||||
#endif
|
||||
asm volatile ("j SaveMpie");
|
||||
}
|
||||
|
||||
void __attribute__((naked)) HwInterruptcontextSwitch(x_ubase from, x_ubase to, struct TaskDescriptor *to_task, void *context)
|
||||
{
|
||||
asm volatile (StoreDS " a3, 0(a0)");
|
||||
asm volatile (LoadDS " sp, 0(a1)");
|
||||
asm volatile ("move a0, a2");
|
||||
asm volatile ("call RestoreCpusLockStatus");
|
||||
asm volatile ("j SwitchKTaskContextExit");
|
||||
}
|
||||
Reference in New Issue
Block a user