summaryrefslogtreecommitdiff
path: root/libcpu
diff options
context:
space:
mode:
authorguochuangjian <[email protected]>2018-08-05 15:08:50 +0800
committerguochuangjian <[email protected]>2018-08-05 15:08:50 +0800
commit3de51fe25688f0b6c7cb9f9d424861654fb09e49 (patch)
treedcf4a170b00deace7860187e3ff9c2e6495e0923 /libcpu
parent650f06aa1943d439ac049f6bc276b216999e6a56 (diff)
parent03bf99a56de255d41655bc8486d50cadbcae22f0 (diff)
fix usRcvBufferPos == MB_SER_PDU_SIZE_MAX bug
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/SConscript6
-rw-r--r--libcpu/arm/arm926/start_gcc.S7
-rw-r--r--libcpu/arm/arm926/start_iar.S7
-rw-r--r--libcpu/arm/arm926/start_rvds.S5
-rw-r--r--libcpu/arm/cortex-m3/context_gcc.S2
-rw-r--r--libcpu/arm/cortex-m3/context_rvds.S13
-rw-r--r--libcpu/arm/cortex-m3/cpuport.c10
-rw-r--r--libcpu/arm/cortex-m4/context_gcc.S28
-rw-r--r--libcpu/arm/cortex-m4/context_iar.S27
-rw-r--r--libcpu/arm/cortex-m4/context_rvds.S20
-rw-r--r--libcpu/arm/cortex-m4/cpuport.c245
-rw-r--r--libcpu/arm/cortex-m7/context_gcc.S28
-rw-r--r--libcpu/arm/cortex-m7/context_iar.S27
-rw-r--r--libcpu/arm/cortex-m7/context_rvds.S20
-rw-r--r--libcpu/arm/cortex-m7/cpuport.c245
-rw-r--r--libcpu/c-sky/ck802/contex_ck802_gcc.S152
-rw-r--r--libcpu/c-sky/ck802/core_ck802.c337
-rw-r--r--libcpu/c-sky/ck802/core_ck802.h552
-rw-r--r--libcpu/c-sky/ck802/stack_ck802.c55
-rw-r--r--libcpu/c-sky/common/csi_core.h248
-rw-r--r--libcpu/c-sky/common/csi_gcc.h36
-rw-r--r--libcpu/c-sky/common/csi_instr.h447
-rw-r--r--libcpu/c-sky/common/csi_reg.h366
-rw-r--r--libcpu/c-sky/common/csi_simd.h1483
-rw-r--r--libcpu/mips/loongson_1c/cpuport.c7
-rw-r--r--libcpu/mips/loongson_1c/sdram_cfg.h85
-rw-r--r--libcpu/mips/loongson_1c/start_gcc.S392
-rw-r--r--libcpu/nds32/context_gcc.S188
-rw-r--r--libcpu/nds32/cpuport.c202
-rw-r--r--libcpu/risc-v/e310/SConscript13
-rw-r--r--libcpu/risc-v/e310/context_gcc.S337
-rw-r--r--libcpu/risc-v/e310/encoding.h1313
-rw-r--r--libcpu/risc-v/e310/entry_gcc.S145
-rw-r--r--libcpu/risc-v/e310/hifive1.h81
-rw-r--r--libcpu/risc-v/e310/init.c210
-rw-r--r--libcpu/risc-v/e310/platform.h133
-rw-r--r--libcpu/risc-v/e310/sifive/bits.h36
-rw-r--r--libcpu/risc-v/e310/sifive/const.h18
-rw-r--r--libcpu/risc-v/e310/sifive/devices/aon.h88
-rw-r--r--libcpu/risc-v/e310/sifive/devices/clint.h14
-rw-r--r--libcpu/risc-v/e310/sifive/devices/gpio.h24
-rw-r--r--libcpu/risc-v/e310/sifive/devices/otp.h23
-rw-r--r--libcpu/risc-v/e310/sifive/devices/plic.h31
-rw-r--r--libcpu/risc-v/e310/sifive/devices/prci.h56
-rw-r--r--libcpu/risc-v/e310/sifive/devices/pwm.h37
-rw-r--r--libcpu/risc-v/e310/sifive/devices/spi.h80
-rw-r--r--libcpu/risc-v/e310/sifive/devices/uart.h27
-rw-r--r--libcpu/risc-v/e310/sifive/sections.h17
-rw-r--r--libcpu/risc-v/e310/sifive/smp.h65
-rw-r--r--libcpu/risc-v/e310/stack.c105
-rw-r--r--libcpu/risc-v/e310/start_gcc.S297
-rw-r--r--libcpu/risc-v/e310/trap.c55
52 files changed, 5177 insertions, 3268 deletions
diff --git a/libcpu/SConscript b/libcpu/SConscript
index 0d00976092..a42909e64c 100644
--- a/libcpu/SConscript
+++ b/libcpu/SConscript
@@ -4,6 +4,7 @@ from building import *
comm = rtconfig.ARCH + '/common'
path = rtconfig.ARCH + '/' + rtconfig.CPU
+ASFLAGS = ''
# The set of source files associated with this SConscript file.
if rtconfig.PLATFORM == 'armcc':
@@ -21,7 +22,10 @@ if rtconfig.PLATFORM == 'cl':
if rtconfig.PLATFORM == 'mingw':
src = Glob(path + '/*.c')
+if rtconfig.PLATFORM == 'armcc' and rtconfig.ARCH == 'arm' and rtconfig.CPU == 'arm926':
+ ASFLAGS = ' --cpreproc'
+
CPPPATH = [RTT_ROOT + '/libcpu/' + rtconfig.ARCH + '/' + rtconfig.CPU, RTT_ROOT + '/libcpu/' + rtconfig.ARCH + '/common']
-group = DefineGroup(rtconfig.CPU.upper(), src, depend = [''], CPPPATH = CPPPATH)
+group = DefineGroup(rtconfig.CPU.upper(), src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS)
Return('group')
diff --git a/libcpu/arm/arm926/start_gcc.S b/libcpu/arm/arm926/start_gcc.S
index 1ccff156b0..130bc041f8 100644
--- a/libcpu/arm/arm926/start_gcc.S
+++ b/libcpu/arm/arm926/start_gcc.S
@@ -24,7 +24,9 @@
* 2015-04-21 ArdaFu Remove remap code. Using mmu to map vector table
* 2015-06-04 aozima Align stack address to 8 byte.
*/
-
+
+#include "rt_low_level_init.h"
+
#define S_FRAME_SIZE (18*4) //72
@#define S_SPSR (17*4) //SPSR
@@ -54,9 +56,8 @@
#define MODE_ABT 0x17
#define MODE_UND 0x1B
#define MODEMASK 0x1F
-#define NOINT 0xC0
-.include "rt_low_level_gcc.inc"
+#define NOINT 0xC0
@;----------------------- Stack and Heap Definitions ---------------------------
.section .nobss, "w"
diff --git a/libcpu/arm/arm926/start_iar.S b/libcpu/arm/arm926/start_iar.S
index 3494b108d7..880f2d9706 100644
--- a/libcpu/arm/arm926/start_iar.S
+++ b/libcpu/arm/arm926/start_iar.S
@@ -24,7 +24,9 @@
; * 2015-04-21 ArdaFu Remove remap code. Using mmu to map vector table
; * 2015-06-04 aozima Align stack address to 8 byte.
; */
-
+
+#include "rt_low_level_init.h"
+
#define S_FRAME_SIZE (18*4) ;72
;#define S_SPSR (17*4) ;SPSR
@@ -54,9 +56,8 @@
#define MODE_ABT 0x17
#define MODE_UND 0x1B
#define MODEMASK 0x1F
-#define NOINT 0xC0
-#include "rt_low_level_iar.inc"
+#define NOINT 0xC0
;----------------------- Stack and Heap Definitions ----------------------------
MODULE ?cstartup
diff --git a/libcpu/arm/arm926/start_rvds.S b/libcpu/arm/arm926/start_rvds.S
index 1c1e48c07e..9f789b97f7 100644
--- a/libcpu/arm/arm926/start_rvds.S
+++ b/libcpu/arm/arm926/start_rvds.S
@@ -25,6 +25,8 @@
; * 2015-06-04 aozima Align stack address to 8 byte.
; */
+#include "rt_low_level_init.h"
+
S_FRAME_SIZE EQU (18*4) ;72
;S_SPSR EQU (17*4) ;SPSR
;S_CPSR EQU (16*4) ;CPSR
@@ -46,7 +48,6 @@ S_PC EQU (15*4) ;R15
;S_R1 EQU (1*4)
;S_R0 EQU (0*4)
-
MODE_USR EQU 0X10
MODE_FIQ EQU 0X11
MODE_IRQ EQU 0X12
@@ -57,8 +58,6 @@ MODE_SYS EQU 0X1F
MODEMASK EQU 0X1F
NOINT EQU 0xC0
-
- GET rt_low_level_keil.inc
;----------------------- Stack and Heap Definitions ----------------------------
AREA STACK, NOINIT, READWRITE, ALIGN=3
diff --git a/libcpu/arm/cortex-m3/context_gcc.S b/libcpu/arm/cortex-m3/context_gcc.S
index 5181cb2712..2e279c4be9 100644
--- a/libcpu/arm/cortex-m3/context_gcc.S
+++ b/libcpu/arm/cortex-m3/context_gcc.S
@@ -188,7 +188,7 @@ _get_sp_done:
STMFD r0!, {r4 - r11} /* push r4 - r11 register */
STMFD r0!, {lr} /* push exec_return register */
- TST lr, #0x04 /* if(!EXC_RETURN[2])
+ TST lr, #0x04 /* if(!EXC_RETURN[2]) */
BEQ _update_msp
MSR psp, r0 /* update stack pointer to PSP. */
B _update_done
diff --git a/libcpu/arm/cortex-m3/context_rvds.S b/libcpu/arm/cortex-m3/context_rvds.S
index a4191203be..9a7ff10abe 100644
--- a/libcpu/arm/cortex-m3/context_rvds.S
+++ b/libcpu/arm/cortex-m3/context_rvds.S
@@ -1,7 +1,7 @@
;/*
; * File : context_rvds.S
; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team
+; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
; *
; * The license and distribution terms for this file may be
; * found in the file LICENSE in this distribution or at
@@ -186,14 +186,17 @@ HardFault_Handler PROC
; get current context
TST lr, #0x04 ; if(!EXC_RETURN[2])
- MRSNE r0, msp ; get fault context from handler.
- MRSEQ r0, psp ; get fault context from thread.
+ ITE EQ
+ MRSEQ r0, msp ; [2]=0 ==> Z=1, get fault context from handler.
+ MRSNE r0, psp ; [2]=1 ==> Z=0, get fault context from thread.
STMFD r0!, {r4 - r11} ; push r4 - r11 register
STMFD r0!, {lr} ; push exec_return register
- MSRNE msp, r0 ; update stack pointer to MSP.
- MSREQ psp, r0 ; update stack pointer to PSP.
+ TST lr, #0x04 ; if(!EXC_RETURN[2])
+ ITE EQ
+ MSREQ msp, r0 ; [2]=0 ==> Z=1, update stack pointer to MSP.
+ MSRNE psp, r0 ; [2]=1 ==> Z=0, update stack pointer to PSP.
PUSH {lr}
BL rt_hw_hard_fault_exception
diff --git a/libcpu/arm/cortex-m3/cpuport.c b/libcpu/arm/cortex-m3/cpuport.c
index 10989ffc5b..3c7e0ee857 100644
--- a/libcpu/arm/cortex-m3/cpuport.c
+++ b/libcpu/arm/cortex-m3/cpuport.c
@@ -110,6 +110,8 @@ void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context))
#define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C) /* HardFault Status Register */
#define SCB_MMAR (*(volatile const unsigned *)0xE000ED34) /* MemManage Fault Address register */
#define SCB_BFAR (*(volatile const unsigned *)0xE000ED38) /* Bus Fault Address Register */
+#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED0C) /* Reset control Address Register */
+#define SCB_RESET_VALUE 0x05FA0004 /* Reset value, write to SCB_AIRCR can reset cpu */
#define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28) /* Memory-management Fault Status Register */
#define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29) /* Bus Fault Status Register */
@@ -352,6 +354,14 @@ void rt_hw_cpu_shutdown(void)
RT_ASSERT(0);
}
+/**
+ * reset CPU
+ */
+RT_WEAK void rt_hw_cpu_reset(void)
+{
+ SCB_AIRCR = SCB_RESET_VALUE;
+}
+
#ifdef RT_USING_CPU_FFS
/**
* This function finds the first bit set (beginning with the least significant bit)
diff --git a/libcpu/arm/cortex-m4/context_gcc.S b/libcpu/arm/cortex-m4/context_gcc.S
index 5985d54fb3..d003ce0ea0 100644
--- a/libcpu/arm/cortex-m4/context_gcc.S
+++ b/libcpu/arm/cortex-m4/context_gcc.S
@@ -1,7 +1,7 @@
/*
* File : context_gcc.S
* This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2009, RT-Thread Development Team
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
@@ -13,6 +13,7 @@
* 2012-01-01 aozima support context switch load/store FPU register.
* 2013-06-18 aozima add restore MSP feature.
* 2013-06-23 aozima support lazy stack optimized.
+ * 2018-07-24 aozima enhancement hard fault exception handler.
*/
/**
@@ -220,10 +221,29 @@ rt_hw_interrupt_thread_switch:
.type HardFault_Handler, %function
HardFault_Handler:
/* get current context */
- MRS r0, psp /* get fault thread stack pointer */
- PUSH {lr}
+ MRS r0, msp /* get fault context from handler. */
+ TST lr, #0x04 /* if(!EXC_RETURN[2]) */
+ BEQ _get_sp_done
+ MRS r0, psp /* get fault context from thread. */
+_get_sp_done:
+
+ STMFD r0!, {r4 - r11} /* push r4 - r11 register */
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ STMFD r0!, {lr} /* push dummy for flag */
+#endif
+ STMFD r0!, {lr} /* push exec_return register */
+
+ TST lr, #0x04 /* if(!EXC_RETURN[2]) */
+ BEQ _update_msp
+ MSR psp, r0 /* update stack pointer to PSP. */
+ B _update_done
+_update_msp:
+ MSR msp, r0 /* update stack pointer to MSP. */
+_update_done:
+
+ PUSH {LR}
BL rt_hw_hard_fault_exception
- POP {lr}
+ POP {LR}
ORR lr, lr, #0x04
BX lr
diff --git a/libcpu/arm/cortex-m4/context_iar.S b/libcpu/arm/cortex-m4/context_iar.S
index c34600ea4c..bf707d0d53 100644
--- a/libcpu/arm/cortex-m4/context_iar.S
+++ b/libcpu/arm/cortex-m4/context_iar.S
@@ -1,7 +1,7 @@
;/*
; * File : context_iar.S
; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2009, RT-Thread Development Team
+; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
; *
; * The license and distribution terms for this file may be
; * found in the file LICENSE in this distribution or at
@@ -14,6 +14,7 @@
; * 2012-01-01 aozima support context switch load/store FPU register.
; * 2013-06-18 aozima add restore MSP feature.
; * 2013-06-23 aozima support lazy stack optimized.
+; * 2018-07-24 aozima enhancement hard fault exception handler.
; */
;/**
@@ -223,7 +224,29 @@ rt_hw_interrupt_thread_switch:
HardFault_Handler:
; get current context
- MRS r0, psp ; get fault thread stack pointer
+ MRS r0, msp ; get fault context from handler.
+ TST lr, #0x04 ; if(!EXC_RETURN[2])
+ BEQ _get_sp_done
+ MRS r0, psp ; get fault context from thread.
+_get_sp_done
+
+ STMFD r0!, {r4 - r11} ; push r4 - r11 register
+ ;STMFD r0!, {lr} ; push exec_return register
+#if defined ( __ARMVFP__ )
+ SUB r0, r0, #0x04 ; push dummy for flag
+ STR lr, [r0]
+#endif
+ SUB r0, r0, #0x04
+ STR lr, [r0]
+
+ TST lr, #0x04 ; if(!EXC_RETURN[2])
+ BEQ _update_msp
+ MSR psp, r0 ; update stack pointer to PSP.
+ B _update_done
+_update_msp
+ MSR msp, r0 ; update stack pointer to MSP.
+_update_done
+
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {lr}
diff --git a/libcpu/arm/cortex-m4/context_rvds.S b/libcpu/arm/cortex-m4/context_rvds.S
index 5cae619287..6d20ab8e3e 100644
--- a/libcpu/arm/cortex-m4/context_rvds.S
+++ b/libcpu/arm/cortex-m4/context_rvds.S
@@ -1,7 +1,7 @@
;/*
; * File : context_rvds.S
; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2009, RT-Thread Development Team
+; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
; *
; * The license and distribution terms for this file may be
; * found in the file LICENSE in this distribution or at
@@ -13,6 +13,7 @@
; * 2012-01-01 aozima support context switch load/store FPU register.
; * 2013-06-18 aozima add restore MSP feature.
; * 2013-06-23 aozima support lazy stack optimized.
+; * 2018-07-24 aozima enhancement hard fault exception handler.
; */
;/**
@@ -225,7 +226,22 @@ rt_hw_interrupt_thread_switch PROC
HardFault_Handler PROC
; get current context
- MRS r0, psp ; get fault thread stack pointer
+ TST lr, #0x04 ; if(!EXC_RETURN[2])
+ ITE EQ
+ MRSEQ r0, msp ; [2]=0 ==> Z=1, get fault context from handler.
+ MRSNE r0, psp ; [2]=1 ==> Z=0, get fault context from thread.
+
+ STMFD r0!, {r4 - r11} ; push r4 - r11 register
+ IF {FPU} != "SoftVFP"
+ STMFD r0!, {lr} ; push dummy for flag
+ ENDIF
+ STMFD r0!, {lr} ; push exec_return register
+
+ TST lr, #0x04 ; if(!EXC_RETURN[2])
+ ITE EQ
+ MSREQ msp, r0 ; [2]=0 ==> Z=1, update stack pointer to MSP.
+ MSRNE psp, r0 ; [2]=1 ==> Z=0, update stack pointer to PSP.
+
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {lr}
diff --git a/libcpu/arm/cortex-m4/cpuport.c b/libcpu/arm/cortex-m4/cpuport.c
index e74c337c60..ed7102f844 100644
--- a/libcpu/arm/cortex-m4/cpuport.c
+++ b/libcpu/arm/cortex-m4/cpuport.c
@@ -1,7 +1,7 @@
/*
* File : cpuport.c
* This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2014, RT-Thread Development Team
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
@@ -17,6 +17,7 @@
* 2012-12-23 aozima stack addr align to 8byte.
* 2012-12-29 Bernard Add exception hook.
* 2013-06-23 aozima support lazy stack optimized.
+ * 2018-07-24 aozima enhancement hard fault exception handler.
*/
#include <rtthread.h>
@@ -177,14 +178,199 @@ rt_uint8_t *rt_hw_stack_init(void *tentry,
*
* @param exception_handle the exception handling hook function.
*/
-void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context))
+void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context))
{
rt_exception_hook = exception_handle;
}
-void rt_hw_hard_fault_exception(struct exception_stack_frame *exception_stack)
+#define SCB_CFSR (*(volatile const unsigned *)0xE000ED28) /* Configurable Fault Status Register */
+#define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C) /* HardFault Status Register */
+#define SCB_MMAR (*(volatile const unsigned *)0xE000ED34) /* MemManage Fault Address register */
+#define SCB_BFAR (*(volatile const unsigned *)0xE000ED38) /* Bus Fault Address Register */
+#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED0C) /* Reset control Address Register */
+#define SCB_RESET_VALUE 0x05FA0004 /* Reset value, write to SCB_AIRCR can reset cpu */
+
+#define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28) /* Memory-management Fault Status Register */
+#define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29) /* Bus Fault Status Register */
+#define SCB_CFSR_UFSR (*(volatile const unsigned short*)0xE000ED2A) /* Usage Fault Status Register */
+
+#ifdef RT_USING_FINSH
+static void usage_fault_track(void)
+{
+ rt_kprintf("usage fault:\n");
+ rt_kprintf("SCB_CFSR_UFSR:0x%02X ", SCB_CFSR_UFSR);
+
+ if(SCB_CFSR_UFSR & (1<<0))
+ {
+ /* [0]:UNDEFINSTR */
+ rt_kprintf("UNDEFINSTR ");
+ }
+
+ if(SCB_CFSR_UFSR & (1<<1))
+ {
+ /* [1]:INVSTATE */
+ rt_kprintf("INVSTATE ");
+ }
+
+ if(SCB_CFSR_UFSR & (1<<2))
+ {
+ /* [2]:INVPC */
+ rt_kprintf("INVPC ");
+ }
+
+ if(SCB_CFSR_UFSR & (1<<3))
+ {
+ /* [3]:NOCP */
+ rt_kprintf("NOCP ");
+ }
+
+ if(SCB_CFSR_UFSR & (1<<8))
+ {
+ /* [8]:UNALIGNED */
+ rt_kprintf("UNALIGNED ");
+ }
+
+ if(SCB_CFSR_UFSR & (1<<9))
+ {
+ /* [9]:DIVBYZERO */
+ rt_kprintf("DIVBYZERO ");
+ }
+
+ rt_kprintf("\n");
+}
+
+static void bus_fault_track(void)
+{
+ rt_kprintf("bus fault:\n");
+ rt_kprintf("SCB_CFSR_BFSR:0x%02X ", SCB_CFSR_BFSR);
+
+ if(SCB_CFSR_BFSR & (1<<0))
+ {
+ /* [0]:IBUSERR */
+ rt_kprintf("IBUSERR ");
+ }
+
+ if(SCB_CFSR_BFSR & (1<<1))
+ {
+ /* [1]:PRECISERR */
+ rt_kprintf("PRECISERR ");
+ }
+
+ if(SCB_CFSR_BFSR & (1<<2))
+ {
+ /* [2]:IMPRECISERR */
+ rt_kprintf("IMPRECISERR ");
+ }
+
+ if(SCB_CFSR_BFSR & (1<<3))
+ {
+ /* [3]:UNSTKERR */
+ rt_kprintf("UNSTKERR ");
+ }
+
+ if(SCB_CFSR_BFSR & (1<<4))
+ {
+ /* [4]:STKERR */
+ rt_kprintf("STKERR ");
+ }
+
+ if(SCB_CFSR_BFSR & (1<<7))
+ {
+ rt_kprintf("SCB->BFAR:%08X\n", SCB_BFAR);
+ }
+ else
+ {
+ rt_kprintf("\n");
+ }
+}
+
+static void mem_manage_fault_track(void)
+{
+ rt_kprintf("mem manage fault:\n");
+ rt_kprintf("SCB_CFSR_MFSR:0x%02X ", SCB_CFSR_MFSR);
+
+ if(SCB_CFSR_MFSR & (1<<0))
+ {
+ /* [0]:IACCVIOL */
+ rt_kprintf("IACCVIOL ");
+ }
+
+ if(SCB_CFSR_MFSR & (1<<1))
+ {
+ /* [1]:DACCVIOL */
+ rt_kprintf("DACCVIOL ");
+ }
+
+ if(SCB_CFSR_MFSR & (1<<3))
+ {
+ /* [3]:MUNSTKERR */
+ rt_kprintf("MUNSTKERR ");
+ }
+
+ if(SCB_CFSR_MFSR & (1<<4))
+ {
+ /* [4]:MSTKERR */
+ rt_kprintf("MSTKERR ");
+ }
+
+ if(SCB_CFSR_MFSR & (1<<7))
+ {
+ /* [7]:MMARVALID */
+ rt_kprintf("SCB->MMAR:%08X\n", SCB_MMAR);
+ }
+ else
+ {
+ rt_kprintf("\n");
+ }
+}
+
+static void hard_fault_track(void)
+{
+ if(SCB_HFSR & (1UL<<1))
+ {
+ /* [1]:VECTBL, Indicates hard fault is caused by failed vector fetch. */
+ rt_kprintf("failed vector fetch\n");
+ }
+
+ if(SCB_HFSR & (1UL<<30))
+ {
+ /* [30]:FORCED, Indicates hard fault is taken because of bus fault,
+ memory management fault, or usage fault. */
+ if(SCB_CFSR_BFSR)
+ {
+ bus_fault_track();
+ }
+
+ if(SCB_CFSR_MFSR)
+ {
+ mem_manage_fault_track();
+ }
+
+ if(SCB_CFSR_UFSR)
+ {
+ usage_fault_track();
+ }
+ }
+
+ if(SCB_HFSR & (1UL<<31))
+ {
+ /* [31]:DEBUGEVT, Indicates hard fault is triggered by debug event. */
+ rt_kprintf("debug event\n");
+ }
+}
+#endif /* RT_USING_FINSH */
+
+struct exception_info
+{
+ rt_uint32_t exc_return;
+ struct stack_frame stack_frame;
+};
+
+void rt_hw_hard_fault_exception(struct exception_info *exception_info)
{
extern long list_thread(void);
+ struct exception_stack_frame *exception_stack = &exception_info->stack_frame.exception_stack_frame;
+ struct stack_frame *context = &exception_info->stack_frame;
if (rt_exception_hook != RT_NULL)
{
@@ -194,20 +380,45 @@ void rt_hw_hard_fault_exception(struct exception_stack_frame *exception_stack)
if (result == RT_EOK) return;
}
- rt_kprintf("psr: 0x%08x\n", exception_stack->psr);
- rt_kprintf(" pc: 0x%08x\n", exception_stack->pc);
- rt_kprintf(" lr: 0x%08x\n", exception_stack->lr);
- rt_kprintf("r12: 0x%08x\n", exception_stack->r12);
- rt_kprintf("r03: 0x%08x\n", exception_stack->r3);
- rt_kprintf("r02: 0x%08x\n", exception_stack->r2);
- rt_kprintf("r01: 0x%08x\n", exception_stack->r1);
- rt_kprintf("r00: 0x%08x\n", exception_stack->r0);
+ rt_kprintf("psr: 0x%08x\n", context->exception_stack_frame.psr);
- rt_kprintf("hard fault on thread: %s\n", rt_thread_self()->name);
+ rt_kprintf("r00: 0x%08x\n", context->exception_stack_frame.r0);
+ rt_kprintf("r01: 0x%08x\n", context->exception_stack_frame.r1);
+ rt_kprintf("r02: 0x%08x\n", context->exception_stack_frame.r2);
+ rt_kprintf("r03: 0x%08x\n", context->exception_stack_frame.r3);
+ rt_kprintf("r04: 0x%08x\n", context->r4);
+ rt_kprintf("r05: 0x%08x\n", context->r5);
+ rt_kprintf("r06: 0x%08x\n", context->r6);
+ rt_kprintf("r07: 0x%08x\n", context->r7);
+ rt_kprintf("r08: 0x%08x\n", context->r8);
+ rt_kprintf("r09: 0x%08x\n", context->r9);
+ rt_kprintf("r10: 0x%08x\n", context->r10);
+ rt_kprintf("r11: 0x%08x\n", context->r11);
+ rt_kprintf("r12: 0x%08x\n", context->exception_stack_frame.r12);
+ rt_kprintf(" lr: 0x%08x\n", context->exception_stack_frame.lr);
+ rt_kprintf(" pc: 0x%08x\n", context->exception_stack_frame.pc);
+
+ if (exception_info->exc_return & (1 << 2))
+ {
+ rt_kprintf("hard fault on thread: %s\r\n\r\n", rt_thread_self()->name);
#ifdef RT_USING_FINSH
- list_thread();
+ list_thread();
#endif
+ }
+ else
+ {
+ rt_kprintf("hard fault on handler\r\n\r\n");
+ }
+
+ if ( (exception_info->exc_return & 0x10) == 0)
+ {
+ rt_kprintf("FPU active!\r\n");
+ }
+
+#ifdef RT_USING_FINSH
+ hard_fault_track();
+#endif /* RT_USING_FINSH */
while (1);
}
@@ -222,6 +433,14 @@ void rt_hw_cpu_shutdown(void)
RT_ASSERT(0);
}
+/**
+ * reset CPU
+ */
+RT_WEAK void rt_hw_cpu_reset(void)
+{
+ SCB_AIRCR = SCB_RESET_VALUE;
+}
+
#ifdef RT_USING_CPU_FFS
/**
* This function finds the first bit set (beginning with the least significant bit)
diff --git a/libcpu/arm/cortex-m7/context_gcc.S b/libcpu/arm/cortex-m7/context_gcc.S
index 5985d54fb3..d003ce0ea0 100644
--- a/libcpu/arm/cortex-m7/context_gcc.S
+++ b/libcpu/arm/cortex-m7/context_gcc.S
@@ -1,7 +1,7 @@
/*
* File : context_gcc.S
* This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2009, RT-Thread Development Team
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
@@ -13,6 +13,7 @@
* 2012-01-01 aozima support context switch load/store FPU register.
* 2013-06-18 aozima add restore MSP feature.
* 2013-06-23 aozima support lazy stack optimized.
+ * 2018-07-24 aozima enhancement hard fault exception handler.
*/
/**
@@ -220,10 +221,29 @@ rt_hw_interrupt_thread_switch:
.type HardFault_Handler, %function
HardFault_Handler:
/* get current context */
- MRS r0, psp /* get fault thread stack pointer */
- PUSH {lr}
+ MRS r0, msp /* get fault context from handler. */
+ TST lr, #0x04 /* if(!EXC_RETURN[2]) */
+ BEQ _get_sp_done
+ MRS r0, psp /* get fault context from thread. */
+_get_sp_done:
+
+ STMFD r0!, {r4 - r11} /* push r4 - r11 register */
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ STMFD r0!, {lr} /* push dummy for flag */
+#endif
+ STMFD r0!, {lr} /* push exec_return register */
+
+ TST lr, #0x04 /* if(!EXC_RETURN[2]) */
+ BEQ _update_msp
+ MSR psp, r0 /* update stack pointer to PSP. */
+ B _update_done
+_update_msp:
+ MSR msp, r0 /* update stack pointer to MSP. */
+_update_done:
+
+ PUSH {LR}
BL rt_hw_hard_fault_exception
- POP {lr}
+ POP {LR}
ORR lr, lr, #0x04
BX lr
diff --git a/libcpu/arm/cortex-m7/context_iar.S b/libcpu/arm/cortex-m7/context_iar.S
index c34600ea4c..bf707d0d53 100644
--- a/libcpu/arm/cortex-m7/context_iar.S
+++ b/libcpu/arm/cortex-m7/context_iar.S
@@ -1,7 +1,7 @@
;/*
; * File : context_iar.S
; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2009, RT-Thread Development Team
+; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
; *
; * The license and distribution terms for this file may be
; * found in the file LICENSE in this distribution or at
@@ -14,6 +14,7 @@
; * 2012-01-01 aozima support context switch load/store FPU register.
; * 2013-06-18 aozima add restore MSP feature.
; * 2013-06-23 aozima support lazy stack optimized.
+; * 2018-07-24 aozima enhancement hard fault exception handler.
; */
;/**
@@ -223,7 +224,29 @@ rt_hw_interrupt_thread_switch:
HardFault_Handler:
; get current context
- MRS r0, psp ; get fault thread stack pointer
+ MRS r0, msp ; get fault context from handler.
+ TST lr, #0x04 ; if(!EXC_RETURN[2])
+ BEQ _get_sp_done
+ MRS r0, psp ; get fault context from thread.
+_get_sp_done
+
+ STMFD r0!, {r4 - r11} ; push r4 - r11 register
+ ;STMFD r0!, {lr} ; push exec_return register
+#if defined ( __ARMVFP__ )
+ SUB r0, r0, #0x04 ; push dummy for flag
+ STR lr, [r0]
+#endif
+ SUB r0, r0, #0x04
+ STR lr, [r0]
+
+ TST lr, #0x04 ; if(!EXC_RETURN[2])
+ BEQ _update_msp
+ MSR psp, r0 ; update stack pointer to PSP.
+ B _update_done
+_update_msp
+ MSR msp, r0 ; update stack pointer to MSP.
+_update_done
+
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {lr}
diff --git a/libcpu/arm/cortex-m7/context_rvds.S b/libcpu/arm/cortex-m7/context_rvds.S
index dc9a958646..1abe477eab 100644
--- a/libcpu/arm/cortex-m7/context_rvds.S
+++ b/libcpu/arm/cortex-m7/context_rvds.S
@@ -1,7 +1,7 @@
;/*
; * File : context_rvds.S
; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2009, RT-Thread Development Team
+; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
; *
; * The license and distribution terms for this file may be
; * found in the file LICENSE in this distribution or at
@@ -13,6 +13,7 @@
; * 2012-01-01 aozima support context switch load/store FPU register.
; * 2013-06-18 aozima add restore MSP feature.
; * 2013-06-23 aozima support lazy stack optimized.
+; * 2018-07-24 aozima enhancement hard fault exception handler.
; */
;/**
@@ -227,7 +228,22 @@ HardFault_Handler PROC
MemManage_Handler
; get current context
- MRS r0, psp ; get fault thread stack pointer
+ TST lr, #0x04 ; if(!EXC_RETURN[2])
+ ITE EQ
+ MRSEQ r0, msp ; [2]=0 ==> Z=1, get fault context from handler.
+ MRSNE r0, psp ; [2]=1 ==> Z=0, get fault context from thread.
+
+ STMFD r0!, {r4 - r11} ; push r4 - r11 register
+ IF {FPU} != "SoftVFP"
+ STMFD r0!, {lr} ; push dummy for flag
+ ENDIF
+ STMFD r0!, {lr} ; push exec_return register
+
+ TST lr, #0x04 ; if(!EXC_RETURN[2])
+ ITE EQ
+ MSREQ msp, r0 ; [2]=0 ==> Z=1, update stack pointer to MSP.
+ MSRNE psp, r0 ; [2]=1 ==> Z=0, update stack pointer to PSP.
+
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {lr}
diff --git a/libcpu/arm/cortex-m7/cpuport.c b/libcpu/arm/cortex-m7/cpuport.c
index e74c337c60..ed7102f844 100644
--- a/libcpu/arm/cortex-m7/cpuport.c
+++ b/libcpu/arm/cortex-m7/cpuport.c
@@ -1,7 +1,7 @@
/*
* File : cpuport.c
* This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2014, RT-Thread Development Team
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
@@ -17,6 +17,7 @@
* 2012-12-23 aozima stack addr align to 8byte.
* 2012-12-29 Bernard Add exception hook.
* 2013-06-23 aozima support lazy stack optimized.
+ * 2018-07-24 aozima enhancement hard fault exception handler.
*/
#include <rtthread.h>
@@ -177,14 +178,199 @@ rt_uint8_t *rt_hw_stack_init(void *tentry,
*
* @param exception_handle the exception handling hook function.
*/
-void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context))
+void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context))
{
rt_exception_hook = exception_handle;
}
-void rt_hw_hard_fault_exception(struct exception_stack_frame *exception_stack)
+#define SCB_CFSR (*(volatile const unsigned *)0xE000ED28) /* Configurable Fault Status Register */
+#define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C) /* HardFault Status Register */
+#define SCB_MMAR (*(volatile const unsigned *)0xE000ED34) /* MemManage Fault Address register */
+#define SCB_BFAR (*(volatile const unsigned *)0xE000ED38) /* Bus Fault Address Register */
+#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED0C) /* Reset control Address Register */
+#define SCB_RESET_VALUE 0x05FA0004 /* Reset value, write to SCB_AIRCR can reset cpu */
+
+#define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28) /* Memory-management Fault Status Register */
+#define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29) /* Bus Fault Status Register */
+#define SCB_CFSR_UFSR (*(volatile const unsigned short*)0xE000ED2A) /* Usage Fault Status Register */
+
+#ifdef RT_USING_FINSH
+static void usage_fault_track(void)
+{
+ rt_kprintf("usage fault:\n");
+ rt_kprintf("SCB_CFSR_UFSR:0x%02X ", SCB_CFSR_UFSR);
+
+ if(SCB_CFSR_UFSR & (1<<0))
+ {
+ /* [0]:UNDEFINSTR */
+ rt_kprintf("UNDEFINSTR ");
+ }
+
+ if(SCB_CFSR_UFSR & (1<<1))
+ {
+ /* [1]:INVSTATE */
+ rt_kprintf("INVSTATE ");
+ }
+
+ if(SCB_CFSR_UFSR & (1<<2))
+ {
+ /* [2]:INVPC */
+ rt_kprintf("INVPC ");
+ }
+
+ if(SCB_CFSR_UFSR & (1<<3))
+ {
+ /* [3]:NOCP */
+ rt_kprintf("NOCP ");
+ }
+
+ if(SCB_CFSR_UFSR & (1<<8))
+ {
+ /* [8]:UNALIGNED */
+ rt_kprintf("UNALIGNED ");
+ }
+
+ if(SCB_CFSR_UFSR & (1<<9))
+ {
+ /* [9]:DIVBYZERO */
+ rt_kprintf("DIVBYZERO ");
+ }
+
+ rt_kprintf("\n");
+}
+
+static void bus_fault_track(void)
+{
+ rt_kprintf("bus fault:\n");
+ rt_kprintf("SCB_CFSR_BFSR:0x%02X ", SCB_CFSR_BFSR);
+
+ if(SCB_CFSR_BFSR & (1<<0))
+ {
+ /* [0]:IBUSERR */
+ rt_kprintf("IBUSERR ");
+ }
+
+ if(SCB_CFSR_BFSR & (1<<1))
+ {
+ /* [1]:PRECISERR */
+ rt_kprintf("PRECISERR ");
+ }
+
+ if(SCB_CFSR_BFSR & (1<<2))
+ {
+ /* [2]:IMPRECISERR */
+ rt_kprintf("IMPRECISERR ");
+ }
+
+ if(SCB_CFSR_BFSR & (1<<3))
+ {
+ /* [3]:UNSTKERR */
+ rt_kprintf("UNSTKERR ");
+ }
+
+ if(SCB_CFSR_BFSR & (1<<4))
+ {
+ /* [4]:STKERR */
+ rt_kprintf("STKERR ");
+ }
+
+ if(SCB_CFSR_BFSR & (1<<7))
+ {
+ rt_kprintf("SCB->BFAR:%08X\n", SCB_BFAR);
+ }
+ else
+ {
+ rt_kprintf("\n");
+ }
+}
+
+static void mem_manage_fault_track(void)
+{
+ rt_kprintf("mem manage fault:\n");
+ rt_kprintf("SCB_CFSR_MFSR:0x%02X ", SCB_CFSR_MFSR);
+
+ if(SCB_CFSR_MFSR & (1<<0))
+ {
+ /* [0]:IACCVIOL */
+ rt_kprintf("IACCVIOL ");
+ }
+
+ if(SCB_CFSR_MFSR & (1<<1))
+ {
+ /* [1]:DACCVIOL */
+ rt_kprintf("DACCVIOL ");
+ }
+
+ if(SCB_CFSR_MFSR & (1<<3))
+ {
+ /* [3]:MUNSTKERR */
+ rt_kprintf("MUNSTKERR ");
+ }
+
+ if(SCB_CFSR_MFSR & (1<<4))
+ {
+ /* [4]:MSTKERR */
+ rt_kprintf("MSTKERR ");
+ }
+
+ if(SCB_CFSR_MFSR & (1<<7))
+ {
+ /* [7]:MMARVALID */
+ rt_kprintf("SCB->MMAR:%08X\n", SCB_MMAR);
+ }
+ else
+ {
+ rt_kprintf("\n");
+ }
+}
+
+static void hard_fault_track(void)
+{
+ if(SCB_HFSR & (1UL<<1))
+ {
+ /* [1]:VECTBL, Indicates hard fault is caused by failed vector fetch. */
+ rt_kprintf("failed vector fetch\n");
+ }
+
+ if(SCB_HFSR & (1UL<<30))
+ {
+ /* [30]:FORCED, Indicates hard fault is taken because of bus fault,
+ memory management fault, or usage fault. */
+ if(SCB_CFSR_BFSR)
+ {
+ bus_fault_track();
+ }
+
+ if(SCB_CFSR_MFSR)
+ {
+ mem_manage_fault_track();
+ }
+
+ if(SCB_CFSR_UFSR)
+ {
+ usage_fault_track();
+ }
+ }
+
+ if(SCB_HFSR & (1UL<<31))
+ {
+ /* [31]:DEBUGEVT, Indicates hard fault is triggered by debug event. */
+ rt_kprintf("debug event\n");
+ }
+}
+#endif /* RT_USING_FINSH */
+
+struct exception_info
+{
+ rt_uint32_t exc_return;
+ struct stack_frame stack_frame;
+};
+
+void rt_hw_hard_fault_exception(struct exception_info *exception_info)
{
extern long list_thread(void);
+ struct exception_stack_frame *exception_stack = &exception_info->stack_frame.exception_stack_frame;
+ struct stack_frame *context = &exception_info->stack_frame;
if (rt_exception_hook != RT_NULL)
{
@@ -194,20 +380,45 @@ void rt_hw_hard_fault_exception(struct exception_stack_frame *exception_stack)
if (result == RT_EOK) return;
}
- rt_kprintf("psr: 0x%08x\n", exception_stack->psr);
- rt_kprintf(" pc: 0x%08x\n", exception_stack->pc);
- rt_kprintf(" lr: 0x%08x\n", exception_stack->lr);
- rt_kprintf("r12: 0x%08x\n", exception_stack->r12);
- rt_kprintf("r03: 0x%08x\n", exception_stack->r3);
- rt_kprintf("r02: 0x%08x\n", exception_stack->r2);
- rt_kprintf("r01: 0x%08x\n", exception_stack->r1);
- rt_kprintf("r00: 0x%08x\n", exception_stack->r0);
+ rt_kprintf("psr: 0x%08x\n", context->exception_stack_frame.psr);
- rt_kprintf("hard fault on thread: %s\n", rt_thread_self()->name);
+ rt_kprintf("r00: 0x%08x\n", context->exception_stack_frame.r0);
+ rt_kprintf("r01: 0x%08x\n", context->exception_stack_frame.r1);
+ rt_kprintf("r02: 0x%08x\n", context->exception_stack_frame.r2);
+ rt_kprintf("r03: 0x%08x\n", context->exception_stack_frame.r3);
+ rt_kprintf("r04: 0x%08x\n", context->r4);
+ rt_kprintf("r05: 0x%08x\n", context->r5);
+ rt_kprintf("r06: 0x%08x\n", context->r6);
+ rt_kprintf("r07: 0x%08x\n", context->r7);
+ rt_kprintf("r08: 0x%08x\n", context->r8);
+ rt_kprintf("r09: 0x%08x\n", context->r9);
+ rt_kprintf("r10: 0x%08x\n", context->r10);
+ rt_kprintf("r11: 0x%08x\n", context->r11);
+ rt_kprintf("r12: 0x%08x\n", context->exception_stack_frame.r12);
+ rt_kprintf(" lr: 0x%08x\n", context->exception_stack_frame.lr);
+ rt_kprintf(" pc: 0x%08x\n", context->exception_stack_frame.pc);
+
+ if (exception_info->exc_return & (1 << 2))
+ {
+ rt_kprintf("hard fault on thread: %s\r\n\r\n", rt_thread_self()->name);
#ifdef RT_USING_FINSH
- list_thread();
+ list_thread();
#endif
+ }
+ else
+ {
+ rt_kprintf("hard fault on handler\r\n\r\n");
+ }
+
+ if ( (exception_info->exc_return & 0x10) == 0)
+ {
+ rt_kprintf("FPU active!\r\n");
+ }
+
+#ifdef RT_USING_FINSH
+ hard_fault_track();
+#endif /* RT_USING_FINSH */
while (1);
}
@@ -222,6 +433,14 @@ void rt_hw_cpu_shutdown(void)
RT_ASSERT(0);
}
+/**
+ * reset CPU
+ */
+RT_WEAK void rt_hw_cpu_reset(void)
+{
+ SCB_AIRCR = SCB_RESET_VALUE;
+}
+
#ifdef RT_USING_CPU_FFS
/**
* This function finds the first bit set (beginning with the least significant bit)
diff --git a/libcpu/c-sky/ck802/contex_ck802_gcc.S b/libcpu/c-sky/ck802/contex_ck802_gcc.S
new file mode 100644
index 0000000000..44f2c331dd
--- /dev/null
+++ b/libcpu/c-sky/ck802/contex_ck802_gcc.S
@@ -0,0 +1,152 @@
+/*
+ * File : contex_ck802.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-01-01 Urey first version
+ * 2018-06-05 tanek clean code
+ */
+
+.file "contex_ck802.S"
+
+#undef VIC_TSPDR
+#define VIC_TSPDR 0XE000EC08
+
+.global rt_thread_switch_interrupt_flag
+.global rt_interrupt_from_thread
+.global rt_interrupt_to_thread
+
+.text
+.align 2
+
+/*
+ * rt_base_t rt_hw_interrupt_disable(void);
+ */
+.global rt_hw_interrupt_disable
+.type rt_hw_interrupt_disable, %function
+rt_hw_interrupt_disable:
+mfcr r0, psr
+psrclr ie
+rts
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t psr);
+ */
+.global rt_hw_interrupt_enable
+.type rt_hw_interrupt_enable, %function
+rt_hw_interrupt_enable:
+mtcr r0, psr
+rts
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * R0 --> to
+ */
+.global rt_hw_context_switch_to
+.type rt_hw_context_switch_to, %function
+rt_hw_context_switch_to:
+lrw r2, rt_interrupt_to_thread
+stw r0, (r2)
+
+/* set form thread = 0 */
+lrw r2, rt_interrupt_from_thread
+movi r0, 0
+stw r0, (r2)
+
+psrclr ie
+jbr __tspend_handler_nosave
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+ * r0 --> from
+ * r1 --> to
+ */
+.global rt_hw_context_switch_interrupt
+.type rt_hw_context_switch_interrupt, %function
+rt_hw_context_switch_interrupt:
+lrw r2, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
+stw r0, (r2)
+
+lrw r2, rt_interrupt_to_thread /* set rt_interrupt_to_thread */
+stw r1, (r2)
+
+lrw r0, VIC_TSPDR
+bgeni r1, 0
+stw r1, (r0)
+rts
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
+ * r0 --> from
+ * r1 --> to
+ */
+.global rt_hw_context_switch
+.type rt_hw_context_switch, %function
+rt_hw_context_switch:
+lrw r2, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
+stw r0, (r2)
+
+lrw r2, rt_interrupt_to_thread /* set rt_interrupt_to_thread */
+stw r1, (r2)
+
+lrw r0, VIC_TSPDR
+bgeni r1, 0
+stw r1, (r0)
+rts
+
+.global PendSV_Handler
+.type PendSV_Handler, %function
+PendSV_Handler:
+subi sp, 68
+stm r0-r13, (sp)
+stw r15, (sp, 56)
+mfcr r0, epsr
+stw r0, (sp, 60)
+mfcr r0, epc
+stw r0, (sp, 64)
+
+lrw r0, rt_interrupt_from_thread
+ldw r1, (r0)
+stw sp, (r1)
+
+__tspend_handler_nosave:
+lrw r6, rt_interrupt_to_thread
+lrw r7, rt_interrupt_from_thread
+ldw r8, (r6)
+stw r8, (r7)
+
+ldw sp, (r8)
+
+#ifdef CONFIG_STACK_GUARD
+mfcr r3, cr<0, 4>
+bseti r3, 0
+bseti r3, 1
+mtcr r3, cr<0, 4>
+#endif
+
+ldw r0, (sp, 64)
+mtcr r0, epc
+ldw r0, (sp, 60)
+bseti r0, 6
+mtcr r0, epsr
+ldw r15, (sp, 56)
+ldm r0-r13, (sp)
+addi sp, 68
+rte
+
diff --git a/libcpu/c-sky/ck802/core_ck802.c b/libcpu/c-sky/ck802/core_ck802.c
new file mode 100644
index 0000000000..047c417267
--- /dev/null
+++ b/libcpu/c-sky/ck802/core_ck802.c
@@ -0,0 +1,337 @@
+/*
+ * File : core_ck802.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-01-01 Urey first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include <stdint.h>
+#include <core_ck802.h>
+
+/* flag in interrupt handling */
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrupt_flag;
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ Core Function Interface contains:
+ - Core VIC Functions
+ - Core CORET Functions
+ - Core Register Access Functions
+ ******************************************************************************/
+/**
+ \defgroup CSI_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+/* ########################## NVIC functions #################################### */
+/**
+ \ingroup CSI_Core_FunctionInterface
+ \defgroup CSI_Core_NVICFunctions NVIC Functions
+ \brief Functions that manage interrupts and exceptions via the NVIC.
+ @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under CSKYv6M */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
+#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
+
+static uint32_t s_nvic_prio_bits = __NVIC_PRIO_BITS;
+
+/**
+ \brief initialize the NVIC interrupt controller
+ \param [in] prio_bits the priority bits of NVIC interrupt controller.
+ */
+void drv_nvic_init(uint32_t prio_bits)
+{
+ if (s_nvic_prio_bits >= 8U)
+ {
+ return;
+ }
+
+ s_nvic_prio_bits = prio_bits;
+}
+
+/**
+ \brief Enable External Interrupt
+ \details Enables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+void drv_nvic_enable_irq(int32_t IRQn)
+{
+ NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+#ifdef CONFIG_SYSTEM_SECURE
+ NVIC->ISSR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+#endif
+}
+
+/**
+ \brief Disable External Interrupt
+ \details Disables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+void drv_nvic_disable_irq(int32_t IRQn)
+{
+ NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+/**
+ \brief Enable External Secure Interrupt
+ \details Enables a secure device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+void drv_nvic_enable_sirq(int32_t IRQn)
+{
+ NVIC->ISSR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+/**
+ \brief Get Pending Interrupt
+ \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not pending.
+ \return 1 Interrupt status is pending.
+ */
+uint32_t drv_nvic_get_pending_irq(int32_t IRQn)
+{
+ return ((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+/**
+ \brief Set Pending Interrupt
+ \details Sets the pending bit of an external interrupt.
+ \param [in] IRQn Interrupt number. Value cannot be negative.
+ */
+void drv_nvic_set_pending_irq(int32_t IRQn)
+{
+ NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+/**
+ \brief Clear Pending Interrupt
+ \details Clears the pending bit of an external interrupt.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+void drv_nvic_clear_pending_irq(int32_t IRQn)
+{
+ NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+/**
+ \brief Get Wake up Interrupt
+ \details Reads the wake up register in the NVIC and returns the pending bit for the specified interrupt.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt is not set as wake up interrupt.
+ \return 1 Interrupt is set as wake up interrupt.
+ */
+uint32_t drv_nvic_get_wakeup_irq(int32_t IRQn)
+{
+ return ((uint32_t)(((NVIC->IWER[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+/**
+ \brief Set Wake up Interrupt
+ \details Sets the wake up bit of an external interrupt.
+ \param [in] IRQn Interrupt number. Value cannot be negative.
+ */
+void drv_nvic_set_wakeup_irq(int32_t IRQn)
+{
+ NVIC->IWER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+/**
+ \brief Clear Wake up Interrupt
+ \details Clears the wake up bit of an external interrupt.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+void drv_nvic_clear_wakeup_irq(int32_t IRQn)
+{
+ NVIC->IWDR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+/**
+ \brief Get Active Interrupt
+ \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt.
+ \param [in] IRQn Device specific interrupt number.
+ \return 0 Interrupt status is not active.
+ \return 1 Interrupt status is active.
+ \note IRQn must not be negative.
+ */
+uint32_t drv_nvic_get_active(int32_t IRQn)
+{
+ return ((uint32_t)(((NVIC->IABR[0] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+/**
+ \brief Set Threshold register
+ \details set the threshold register in the NVIC.
+ \param [in] VectThreshold specific vecter threshold.
+ \param [in] PrioThreshold specific priority threshold.
+ */
+void drv_nvic_set_threshold(uint32_t VectThreshold, uint32_t PrioThreshold)
+{
+ NVIC->IPTR = 0x80000000 | (((VectThreshold + 32) & 0xFF) << 8) | ((PrioThreshold & 0x3) << 6);
+}
+
+/**
+ \brief Set Interrupt Priority
+ \details Sets the priority of an interrupt.
+ \note The priority cannot be set for every core interrupt.
+ \param [in] IRQn Interrupt number.
+ \param [in] priority Priority to set.
+ */
+void drv_nvic_set_prio(int32_t IRQn, uint32_t priority)
+{
+ NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - s_nvic_prio_bits)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+}
+
+/**
+ \brief Get Interrupt Priority
+ \details Reads the priority of an interrupt.
+ The interrupt number can be positive to specify an external (device specific) interrupt,
+ or negative to specify an internal (core) interrupt.
+ \param [in] IRQn Interrupt number.
+ \return Interrupt Priority.
+ Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+uint32_t drv_nvic_get_prio(int32_t IRQn)
+{
+ return ((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn)) & (uint32_t)0xFFUL) >> (8U - s_nvic_prio_bits)));
+}
+
+
+/*@} end of CSI_Core_NVICFunctions */
+
+/* ################################## SysTick function ############################################ */
+/**
+ \ingroup CSI_Core_FunctionInterface
+ \defgroup CSI_Core_SysTickFunctions SysTick Functions
+ \brief Functions that configure the System.
+ @{
+ */
+
+
+/**
+ \brief CORE timer Configuration
+ \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ Counter is in free running mode to generate periodic interrupts.
+ \param [in] ticks Number of ticks between two interrupts.
+ \param [in] IRQn core timer Interrupt number.
+ \return 0 Function succeeded.
+ \return 1 Function failed.
+ \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+ function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+ must contain a vendor-specific implementation of this function.
+ */
+uint32_t drv_coret_config(uint32_t ticks, int32_t IRQn)
+{
+ if ((ticks - 1UL) > CORET_LOAD_RELOAD_Msk)
+ {
+ return (1UL); /* Reload value impossible */
+ }
+
+ CORET->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
+ drv_nvic_set_prio(IRQn, (1UL << s_nvic_prio_bits) - 1UL); /* set Priority for Systick Interrupt */
+ CORET->VAL = 0UL; /* Load the CORET Counter Value */
+ CORET->CTRL = CORET_CTRL_CLKSOURCE_Msk |
+ CORET_CTRL_TICKINT_Msk |
+ CORET_CTRL_ENABLE_Msk; /* Enable CORET IRQ and CORET Timer */
+ return (0UL); /* Function successful */
+}
+
+/**
+ \brief get CORE timer reload value
+ \return CORE timer counter value.
+ */
+uint32_t drv_coret_get_load(void)
+{
+ return CORET->LOAD;
+}
+
+/**
+ \brief get CORE timer counter value
+ \return CORE timer counter value.
+ */
+uint32_t drv_coret_get_value(void)
+{
+ return CORET->VAL;
+}
+
+/*@} end of CSI_Core_SysTickFunctions */
+
+#if 0
+/* ##################################### DCC function ########################################### */
+/**
+ \ingroup CSI_Core_FunctionInterface
+ \defgroup CSI_core_DebugFunctions HAD Functions
+ \brief Functions that access the HAD debug interface.
+ @{
+ */
+
+/**
+ \brief HAD Send Character
+ \details Transmits a character via the HAD channel 0, and
+ \li Just returns when no debugger is connected that has booked the output.
+ \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+ \param [in] ch Character to transmit.
+ \returns Character to transmit.
+ */
+uint32_t HAD_SendChar(uint32_t ch)
+{
+ DCC->DERJR = (uint8_t)ch;
+
+ return (ch);
+}
+
+
+/**
+ \brief HAD Receive Character
+ \details Inputs a character via the external variable \ref HAD_RxBuffer.
+ \return Received character.
+ \return -1 No character pending.
+ */
+int32_t HAD_ReceiveChar(void)
+{
+ int32_t ch = -1; /* no character available */
+
+ if (_FLD2VAL(DCC_EHSR_JW, DCC->EHSR))
+ {
+ ch = DCC->DERJW;
+ }
+
+ return (ch);
+}
+
+/**
+ \brief HAD Check Character
+ \details Checks whether a character is pending for reading in the variable \ref HAD_RxBuffer.
+ \return 0 No character available.
+ \return 1 Character available.
+ */
+int32_t HAD_CheckChar(void)
+{
+ return _FLD2VAL(DCC_EHSR_JW, DCC->EHSR); /* no character available */
+}
+
+#endif
diff --git a/libcpu/c-sky/ck802/core_ck802.h b/libcpu/c-sky/ck802/core_ck802.h
new file mode 100644
index 0000000000..6c335f8178
--- /dev/null
+++ b/libcpu/c-sky/ck802/core_ck802.h
@@ -0,0 +1,552 @@
+/*
+ * File : core_ck802.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-01-01 Urey first version
+ */
+
+#ifndef __CORE_CK802_H_GENERIC
+#define __CORE_CK802_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+ * CSI definitions
+ ******************************************************************************/
+/**
+ \ingroup Ck802
+ @{
+ */
+
+/* CSI CK802 definitions */
+#define __CK802_CSI_VERSION_MAIN (0x04U) /*!< [31:16] CSI HAL main version */
+#define __CK802_CSI_VERSION_SUB (0x1EU) /*!< [15:0] CSI HAL sub version */
+#define __CK802_CSI_VERSION ((__CK802_CSI_VERSION_MAIN << 16U) | \
+ __CK802_CSI_VERSION_SUB ) /*!< CSI HAL version number */
+
+#define __CK80X (0x02U) /*!< CK80X Core */
+
+/** __FPU_USED indicates whether an FPU is used or not.
+ This core does not support an FPU at all
+*/
+#define __FPU_USED 0U
+
+#if defined ( __GNUC__ )
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+#endif
+#endif
+
+#include "csi_gcc.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CK802_H_GENERIC */
+
+#ifndef __CSI_GENERIC
+
+#ifndef __CORE_CK802_H_DEPENDANT
+#define __CORE_CK802_H_DEPENDANT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* check device defines and use defaults */
+//#if defined __CHECK_DEVICE_DEFINES
+#ifndef __CK802_REV
+#define __CK802_REV 0x0000U
+//#warning "__CK802_REV not defined in device header file; using default!"
+#endif
+
+#ifndef __NVIC_PRIO_BITS
+#define __NVIC_PRIO_BITS 2U
+//#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+#endif
+
+#ifndef __Vendor_SysTickConfig
+#define __Vendor_SysTickConfig 0U
+//#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+#endif
+
+#ifndef __GSR_GCR_PRESENT
+#define __GSR_GCR_PRESENT 0U
+//#warning "__GSR_GCR_PRESENT not defined in device header file; using default!"
+#endif
+
+#ifndef __MGU_PRESENT
+#define __MGU_PRESENT 0U
+//#warning "__MGU_PRESENT not defined in device header file; using default!"
+#endif
+//#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ \defgroup CSI_glob_defs CSI Global Defines
+
+ <strong>IO Type Qualifiers</strong> are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+*/
+#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 */
+
+/*@} end of group CK802 */
+
+/*******************************************************************************
+ * Register Abstraction
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ ******************************************************************************/
+/**
+ \defgroup CSI_core_register Defines and Type Definitions
+ \brief Type definitions and defines for CK80X processor based devices.
+*/
+
+/**
+ \ingroup CSI_core_register
+ \defgroup CSI_CORE Status and Control Registers
+ \brief Core Register type definitions.
+ @{
+ */
+
+/**
+ \brief ���ʴ�����״̬�Ĵ���(PSR)�������嶨��.
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t C: 1; /*!< bit: 0 �����룯��λλ */
+ uint32_t _reserved0: 5; /*!< bit: 2.. 5 ���� */
+ uint32_t IE: 1; /*!< bit: 6 �ж���Ч����λ */
+ uint32_t IC: 1; /*!< bit: 7 �жϿ���λ */
+ uint32_t EE: 1; /*!< bit: 8 �쳣��Ч����λ */
+ uint32_t MM: 1; /*!< bit: 9 �������쳣�ڸ�λ */
+ uint32_t _reserved1: 6; /*!< bit: 10..15 ���� */
+ uint32_t VEC: 8; /*!< bit: 16..23 �쳣�¼�����ֵ */
+ uint32_t _reserved2: 7; /*!< bit: 24..30 ���� */
+ uint32_t S: 1; /*!< bit: 31 �����û�ģʽ����λ */
+ } b; /*!< Structure ��������� */
+ uint32_t w; /*!< Type �����Ĵ������� */
+} PSR_Type;
+
+/* PSR Register Definitions */
+#define PSR_S_Pos 31U /*!< PSR: S Position */
+#define PSR_S_Msk (1UL << PSR_S_Pos) /*!< PSR: S Mask */
+
+#define PSR_VEC_Pos 16U /*!< PSR: VEC Position */
+#define PSR_VEC_Msk (0x7FUL << PSR_VEC_Pos) /*!< PSR: VEC Mask */
+
+#define PSR_MM_Pos 9U /*!< PSR: MM Position */
+#define PSR_MM_Msk (1UL << PSR_MM_Pos) /*!< PSR: MM Mask */
+
+#define PSR_EE_Pos 8U /*!< PSR: EE Position */
+#define PSR_EE_Msk (1UL << PSR_EE_Pos) /*!< PSR: EE Mask */
+
+#define PSR_IC_Pos 7U /*!< PSR: IC Position */
+#define PSR_IC_Msk (1UL << PSR_IC_Pos) /*!< PSR: IC Mask */
+
+#define PSR_IE_Pos 6U /*!< PSR: IE Position */
+#define PSR_IE_Msk (1UL << PSR_IE_Pos) /*!< PSR: IE Mask */
+
+#define PSR_C_Pos 0U /*!< PSR: C Position */
+#define PSR_C_Msk (1UL << PSR_C_Pos) /*!< PSR: C Mask */
+
+/**
+ \brief ���ʸ��ٻ������üĴ���(CCR, CR<18, 0>)�������嶨��.
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t MP: 1; /*!< bit: 0 �ڴ汣������λ */
+ uint32_t _reserved0: 6; /*!< bit: 1.. 6 ���� */
+ uint32_t BE: 1; /*!< bit: 7 Endianģʽ */
+ uint32_t SCK: 3; /*!< bit: 8..10 ϵͳ�ʹ�������ʱ�ӱ� */
+ uint32_t _reserved1: 2; /*!< bit: 11..12 ���� */
+ uint32_t BE_V2: 1; /*!< bit: 13 V2�汾��С�� */
+ uint32_t _reserved2: 18; /*!< bit: 14..31 ���� */
+ } b; /*!< Structure ��������� */
+ uint32_t w; /*!< Type �����Ĵ������� */
+} CCR_Type;
+
+/* CCR Register Definitions */
+#define CCR_BE_V2_Pos 13U /*!< CCR: BE_V2 Position */
+#define CCR_BE_V2_Msk (0x1UL << CCR_ISR_Pos) /*!< CCR: BE_V2 Mask */
+
+#define CCR_SCK_Pos 8U /*!< CCR: SCK Position */
+#define CCR_SCK_Msk (0x3UL << CCR_SCK_Pos) /*!< CCR: SCK Mask */
+
+#define CCR_BE_Pos 7U /*!< CCR: BE Position */
+#define CCR_BE_Msk (0x1UL << CCR_BE_Pos) /*!< CCR: BE Mask */
+
+#define CCR_MP_Pos 0U /*!< CCR: MP Position */
+#define CCR_MP_Msk (0x1UL << CCR_MP_Pos) /*!< CCR: MP Mask */
+
+/**
+ \brief ���ʿɸ߻��ͷ���Ȩ�����üĴ���(CAPR, CR<19,0>)�������嶨��..
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t X0: 1; /*!< bit: 0 ����ִ����������λ */
+ uint32_t X1: 1; /*!< bit: 1 ����ִ����������λ */
+ uint32_t X2: 1; /*!< bit: 2 ����ִ����������λ */
+ uint32_t X3: 1; /*!< bit: 3 ����ִ����������λ */
+ uint32_t X4: 1; /*!< bit: 4 ����ִ����������λ */
+ uint32_t X5: 1; /*!< bit: 5 ����ִ����������λ */
+ uint32_t X6: 1; /*!< bit: 6 ����ִ����������λ */
+ uint32_t X7: 1; /*!< bit: 7 ����ִ����������λ */
+ uint32_t AP0: 2; /*!< bit: 8.. 9 ����Ȩ������λ */
+ uint32_t AP1: 2; /*!< bit: 10..11 ����Ȩ������λ */
+ uint32_t AP2: 2; /*!< bit: 12..13 ����Ȩ������λ */
+ uint32_t AP3: 2; /*!< bit: 14..15 ����Ȩ������λ */
+ uint32_t AP4: 2; /*!< bit: 16..17 ����Ȩ������λ */
+ uint32_t AP5: 2; /*!< bit: 18..19 ����Ȩ������λ */
+ uint32_t AP6: 2; /*!< bit: 20..21 ����Ȩ������λ */
+ uint32_t AP7: 2; /*!< bit: 22..23 ����Ȩ������λ */
+ uint32_t S0: 1; /*!< bit: 24 ��ȫ��������λ */
+ uint32_t S1: 1; /*!< bit: 25 ��ȫ��������λ */
+ uint32_t S2: 1; /*!< bit: 26 ��ȫ��������λ */
+ uint32_t S3: 1; /*!< bit: 27 ��ȫ��������λ */
+ uint32_t S4: 1; /*!< bit: 28 ��ȫ��������λ */
+ uint32_t S5: 1; /*!< bit: 29 ��ȫ��������λ */
+ uint32_t S6: 1; /*!< bit: 30 ��ȫ��������λ */
+ uint32_t S7: 1; /*!< bit: 31 ��ȫ��������λ */
+ } b; /*!< Structure ��������� */
+ uint32_t w; /*!< Type �����Ĵ������� */
+} CAPR_Type;
+
+/* CAPR Register Definitions */
+#define CAPR_S7_Pos 31U /*!< CAPR: S7 Position */
+#define CAPR_S7_Msk (1UL << CAPR_S7_Pos) /*!< CAPR: S7 Mask */
+
+#define CAPR_S6_Pos 30U /*!< CAPR: S6 Position */
+#define CAPR_S6_Msk (1UL << CAPR_S6_Pos) /*!< CAPR: S6 Mask */
+
+#define CAPR_S5_Pos 29U /*!< CAPR: S5 Position */
+#define CAPR_S5_Msk (1UL << CAPR_S5_Pos) /*!< CAPR: S5 Mask */
+
+#define CAPR_S4_Pos 28U /*!< CAPR: S4 Position */
+#define CAPR_S4_Msk (1UL << CAPR_S4_Pos) /*!< CAPR: S4 Mask */
+
+#define CAPR_S3_Pos 27U /*!< CAPR: S3 Position */
+#define CAPR_S3_Msk (1UL << CAPR_S3_Pos) /*!< CAPR: S3 Mask */
+
+#define CAPR_S2_Pos 26U /*!< CAPR: S2 Position */
+#define CAPR_S2_Msk (1UL << CAPR_S2_Pos) /*!< CAPR: S2 Mask */
+
+#define CAPR_S1_Pos 25U /*!< CAPR: S1 Position */
+#define CAPR_S1_Msk (1UL << CAPR_S1_Pos) /*!< CAPR: S1 Mask */
+
+#define CAPR_S0_Pos 24U /*!< CAPR: S0 Position */
+#define CAPR_S0_Msk (1UL << CAPR_S0_Pos) /*!< CAPR: S0 Mask */
+
+#define CAPR_AP7_Pos 22U /*!< CAPR: AP7 Position */
+#define CAPR_AP7_Msk (0x3UL << CAPR_AP7_Pos) /*!< CAPR: AP7 Mask */
+
+#define CAPR_AP6_Pos 20U /*!< CAPR: AP6 Position */
+#define CAPR_AP6_Msk (0x3UL << CAPR_AP6_Pos) /*!< CAPR: AP6 Mask */
+
+#define CAPR_AP5_Pos 18U /*!< CAPR: AP5 Position */
+#define CAPR_AP5_Msk (0x3UL << CAPR_AP5_Pos) /*!< CAPR: AP5 Mask */
+
+#define CAPR_AP4_Pos 16U /*!< CAPR: AP4 Position */
+#define CAPR_AP4_Msk (0x3UL << CAPR_AP4_Pos) /*!< CAPR: AP4 Mask */
+
+#define CAPR_AP3_Pos 14U /*!< CAPR: AP3 Position */
+#define CAPR_AP3_Msk (0x3UL << CAPR_AP3_Pos) /*!< CAPR: AP3 Mask */
+
+#define CAPR_AP2_Pos 12U /*!< CAPR: AP2 Position */
+#define CAPR_AP2_Msk (0x3UL << CAPR_AP2_Pos) /*!< CAPR: AP2 Mask */
+
+#define CAPR_AP1_Pos 10U /*!< CAPR: AP1 Position */
+#define CAPR_AP1_Msk (0x3UL << CAPR_AP1_Pos) /*!< CAPR: AP1 Mask */
+
+#define CAPR_AP0_Pos 8U /*!< CAPR: AP0 Position */
+#define CAPR_AP0_Msk (0x3UL << CAPR_AP0_Pos) /*!< CAPR: AP0 Mask */
+
+#define CAPR_X7_Pos 7U /*!< CAPR: X7 Position */
+#define CAPR_X7_Msk (0x1UL << CAPR_X7_Pos) /*!< CAPR: X7 Mask */
+
+#define CAPR_X6_Pos 6U /*!< CAPR: X6 Position */
+#define CAPR_X6_Msk (0x1UL << CAPR_X6_Pos) /*!< CAPR: X6 Mask */
+
+#define CAPR_X5_Pos 5U /*!< CAPR: X5 Position */
+#define CAPR_X5_Msk (0x1UL << CAPR_X5_Pos) /*!< CAPR: X5 Mask */
+
+#define CAPR_X4_Pos 4U /*!< CAPR: X4 Position */
+#define CAPR_X4_Msk (0x1UL << CAPR_X4_Pos) /*!< CAPR: X4 Mask */
+
+#define CAPR_X3_Pos 3U /*!< CAPR: X3 Position */
+#define CAPR_X3_Msk (0x1UL << CAPR_X3_Pos) /*!< CAPR: X3 Mask */
+
+#define CAPR_X2_Pos 2U /*!< CAPR: X2 Position */
+#define CAPR_X2_Msk (0x1UL << CAPR_X2_Pos) /*!< CAPR: X2 Mask */
+
+#define CAPR_X1_Pos 1U /*!< CAPR: X1 Position */
+#define CAPR_X1_Msk (0x1UL << CAPR_X1_Pos) /*!< CAPR: X1 Mask */
+
+#define CAPR_X0_Pos 0U /*!< CAPR: X0 Position */
+#define CAPR_X0_Msk (0x1UL << CAPR_X0_Pos) /*!< CAPR: X0 Mask */
+
+/**
+ \brief ���ʱ��������ƼĴ���(PACR, CR<20,0>)�������嶨��.
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t E: 1; /*!< bit: 0 ������������ */
+ uint32_t Size: 5; /*!< bit: 1.. 5 ��������С */
+ uint32_t _reserved0: 4; /*!< bit: 6.. 9 ���� */
+ uint32_t base_addr: 22; /*!< bit: 10..31 ��������ַ�ĸ�λ */
+ } b; /*!< Structure ��������� */
+ uint32_t w; /*!< Type �����Ĵ������� */
+} PACR_Type;
+
+/* PACR Register Definitions */
+#define PACR_BASE_ADDR_Pos 10U /*!< PACR: base_addr Position */
+#define PACK_BASE_ADDR_Msk (0x3FFFFFUL << PACR_BASE_ADDR_Pos) /*!< PACR: base_addr Mask */
+
+#define PACR_SIZE_Pos 1U /*!< PACR: Size Position */
+#define PACK_SIZE_Msk (0x1FUL << PACR_SIZE_Pos) /*!< PACR: Size Mask */
+
+#define PACR_E_Pos 0U /*!< PACR: E Position */
+#define PACK_E_Msk (0x1UL << PACR_E_Pos) /*!< PACR: E Mask */
+
+/**
+ \brief ���ʱ�����ѡ��Ĵ���(PRSR,CR<21,0>)�������嶨��.
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t RID: 3; /*!< bit: 0.. 2 ����������ֵ */
+ uint32_t _reserved0: 30; /*!< bit: 3..31 ���� */
+ } b; /*!< Structure ��������� */
+ uint32_t w; /*!< Type �����Ĵ������� */
+} PRSR_Type;
+
+/* PRSR Register Definitions */
+#define PRSR_RID_Pos 0U /*!< PRSR: RID Position */
+#define PRSR_RID_Msk (0x7UL << PRSR_RID_Pos) /*!< PRSR: RID Mask */
+
+/*@} end of group CSI_CORE */
+
+
+/**
+ \ingroup CSI_core_register
+ \defgroup CSI_NVIC Vectored Interrupt Controller (NVIC)
+ \brief Type definitions for the NVIC Registers
+ @{
+ */
+
+/**
+ \brief ����ʸ���жϿ������Ľṹ��.
+ */
+typedef struct
+{
+ __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) �ж�ʹ�����üĴ��� */
+ uint32_t RESERVED0[15U];
+ __IOM uint32_t IWER[1U]; /*!< Offset: 0x040 (R/W) �жϵ͹��Ļ������üĴ��� */
+ uint32_t RESERVED1[15U];
+ __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) �ж�ʹ������Ĵ��� */
+ uint32_t RESERVED2[15U];
+ __IOM uint32_t IWDR[1U]; /*!< Offset: 0x0c0 (R/W) �жϵ͹��Ļ�������Ĵ��� */
+ uint32_t RESERVED3[15U];
+ __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) �жϵȴ����üĴ��� */
+ uint32_t RESERVED4[15U];
+ __IOM uint32_t ISSR[1U]; /*!< Offset: 0x140 (R/W) ��ȫ�ж�ʹ�����üĴ��� */
+ uint32_t RESERVED5[15U];
+ __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) �жϵȴ�����Ĵ��� */
+ uint32_t RESERVED6[31U];
+ __IOM uint32_t IABR[1U]; /*!< Offset: 0x200 (R/W) �ж���Ӧ״̬�Ĵ��� */
+ uint32_t RESERVED7[63U];
+ __IOM uint32_t IPR[8U]; /*!< Offset: 0x300 (R/W) �ж����ȼ����üĴ��� */
+ uint32_t RESERVED8[504U];
+ __IM uint32_t ISR; /*!< Offset: 0xB00 (R/ ) �ж�״̬�Ĵ��� */
+ __IOM uint32_t IPTR; /*!< Offset: 0xB04 (R/W) �ж����ȼ���ֵ�Ĵ��� */
+} NVIC_Type;
+
+/*@} end of group CSI_NVIC */
+
+/**
+ \ingroup CSI_core_register
+ \defgroup CSI_SysTick System Tick Timer (CORET)
+ \brief Type definitions for the System Timer Registers.
+ @{
+ */
+
+/**
+ \brief ����ϵͳ��ʱ�������ݽṹ.
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) ����״̬�Ĵ��� */
+ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) ����ֵ�Ĵ��� */
+ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) ��ǰֵ�Ĵ��� */
+ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) У׼�Ĵ��� */
+} CORET_Type;
+
+/* CORET Control / Status Register Definitions */
+#define CORET_CTRL_COUNTFLAG_Pos 16U /*!< CORET CTRL: COUNTFLAG Position */
+#define CORET_CTRL_COUNTFLAG_Msk (1UL << CORET_CTRL_COUNTFLAG_Pos) /*!< CORET CTRL: COUNTFLAG Mask */
+
+#define CORET_CTRL_CLKSOURCE_Pos 2U /*!< CORET CTRL: CLKSOURCE Position */
+#define CORET_CTRL_CLKSOURCE_Msk (1UL << CORET_CTRL_CLKSOURCE_Pos) /*!< CORET CTRL: CLKSOURCE Mask */
+
+#define CORET_CTRL_TICKINT_Pos 1U /*!< CORET CTRL: TICKINT Position */
+#define CORET_CTRL_TICKINT_Msk (1UL << CORET_CTRL_TICKINT_Pos) /*!< CORET CTRL: TICKINT Mask */
+
+#define CORET_CTRL_ENABLE_Pos 0U /*!< CORET CTRL: ENABLE Position */
+#define CORET_CTRL_ENABLE_Msk (1UL /*<< CORET_CTRL_ENABLE_Pos*/) /*!< CORET CTRL: ENABLE Mask */
+
+/* CORET Reload Register Definitions */
+#define CORET_LOAD_RELOAD_Pos 0U /*!< CORET LOAD: RELOAD Position */
+#define CORET_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< CORET_LOAD_RELOAD_Pos*/) /*!< CORET LOAD: RELOAD Mask */
+
+/* CORET Current Register Definitions */
+#define CORET_VAL_CURRENT_Pos 0U /*!< CORET VAL: CURRENT Position */
+#define CORET_VAL_CURRENT_Msk (0xFFFFFFUL /*<< CORET_VAL_CURRENT_Pos*/) /*!< CORET VAL: CURRENT Mask */
+
+/* CORET Calibration Register Definitions */
+#define CORET_CALIB_NOREF_Pos 31U /*!< CORET CALIB: NOREF Position */
+#define CORET_CALIB_NOREF_Msk (1UL << CORET_CALIB_NOREF_Pos) /*!< CORET CALIB: NOREF Mask */
+
+#define CORET_CALIB_SKEW_Pos 30U /*!< CORET CALIB: SKEW Position */
+#define CORET_CALIB_SKEW_Msk (1UL << CORET_CALIB_SKEW_Pos) /*!< CORET CALIB: SKEW Mask */
+
+#define CORET_CALIB_TENMS_Pos 0U /*!< CORET CALIB: TENMS Position */
+#define CORET_CALIB_TENMS_Msk (0xFFFFFFUL /*<< CORET_CALIB_TENMS_Pos*/) /*!< CORET CALIB: TENMS Mask */
+
+/*@} end of group CSI_SysTick */
+
+/**
+ \ingroup CSI_core_register
+ \defgroup CSI_DCC
+ \brief Type definitions for the DCC.
+ @{
+ */
+
+/**
+ \brief ����DCC�����ݽṹ.
+ */
+typedef struct
+{
+ uint32_t RESERVED0[13U];
+ __IOM uint32_t HCR; /*!< Offset: 0x034 (R/W) */
+ __IM uint32_t EHSR; /*!< Offset: 0x03C (R/ ) */
+ uint32_t RESERVED1[6U];
+ union
+ {
+ __IM uint32_t DERJW; /*!< Offset: 0x058 (R/ ) ���ݽ����Ĵ��� CPU��*/
+ __OM uint32_t DERJR; /*!< Offset: 0x058 ( /W) ���ݽ����Ĵ��� CPUд*/
+ };
+
+} DCC_Type;
+
+#define DCC_HCR_JW_Pos 18U /*!< DCC HCR: jw_int_en Position */
+#define DCC_HCR_JW_Msk (1UL << DCC_HCR_JW_Pos) /*!< DCC HCR: jw_int_en Mask */
+
+#define DCC_HCR_JR_Pos 19U /*!< DCC HCR: jr_int_en Position */
+#define DCC_HCR_JR_Msk (1UL << DCC_HCR_JR_Pos) /*!< DCC HCR: jr_int_en Mask */
+
+#define DCC_EHSR_JW_Pos 1U /*!< DCC EHSR: jw_vld Position */
+#define DCC_EHSR_JW_Msk (1UL << DCC_EHSR_JW_Pos) /*!< DCC EHSR: jw_vld Mask */
+
+#define DCC_EHSR_JR_Pos 2U /*!< DCC EHSR: jr_vld Position */
+#define DCC_EHSR_JR_Msk (1UL << DCC_EHSR_JR_Pos) /*!< DCC EHSR: jr_vld Mask */
+
+/*@} end of group CSI_DCC */
+
+
+/**
+ \ingroup CSI_core_register
+ \defgroup CSI_core_bitfield Core register bit field macros
+ \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+ @{
+ */
+
+/**
+ \brief Mask and shift a bit field value for use in a register bit range.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of the bit field.
+ \return Masked and shifted value.
+*/
+#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
+
+/**
+ \brief Mask and shift a register value to extract a bit filed value.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of register.
+ \return Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CSI_core_bitfield */
+
+/**
+ \ingroup CSI_core_register
+ \defgroup CSI_core_base Core Definitions
+ \brief Definitions for base addresses, unions, and structures.
+ @{
+ */
+
+/* Memory mapping of CK802 Hardware */
+#define TCIP_BASE (0xE000E000UL) /*!< Titly Coupled IP Base Address */
+#define CORET_BASE (TCIP_BASE + 0x0010UL) /*!< CORET Base Address */
+#define NVIC_BASE (TCIP_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define DCC_BASE (0xE0011000UL) /*!< DCC Base Address */
+
+#define CORET ((CORET_Type *) CORET_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+#define DCC ((DCC_Type *) DCC_BASE ) /*!< DCC configuration struct */
+
+/*@} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CK802_H_DEPENDANT */
+
+#endif /* __CSI_GENERIC */
diff --git a/libcpu/c-sky/ck802/stack_ck802.c b/libcpu/c-sky/ck802/stack_ck802.c
new file mode 100644
index 0000000000..01fed9ad34
--- /dev/null
+++ b/libcpu/c-sky/ck802/stack_ck802.c
@@ -0,0 +1,55 @@
+/*
+ * File : stack_ck802.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2017-01-01 Urey first version
+ */
+
+#include <rtthread.h>
+
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit)
+{
+ rt_uint32_t *stk = (rt_uint32_t *)stack_addr;
+
+ stk = (rt_uint32_t *)(stack_addr + sizeof(rt_uint32_t));
+ stk = (rt_uint32_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8);
+
+ *(--stk) = (rt_uint32_t)tentry; /* Entry Point */
+ *(--stk) = (rt_uint32_t)0x80000150L; /* PSR */
+ *(--stk) = (rt_uint32_t)texit; /* R15 (LR) (init value will cause fault if ever used) */
+ *(--stk) = (rt_uint32_t)0x13131313L; /* R13 */
+ *(--stk) = (rt_uint32_t)0x12121212L; /* R12 */
+ *(--stk) = (rt_uint32_t)0x11111111L; /* R11 */
+ *(--stk) = (rt_uint32_t)0x10101010L; /* R10 */
+ *(--stk) = (rt_uint32_t)0x09090909L; /* R9 */
+ *(--stk) = (rt_uint32_t)0x08080808L; /* R8 */
+ *(--stk) = (rt_uint32_t)0x07070707L; /* R7 */
+ *(--stk) = (rt_uint32_t)0x06060606L; /* R6 */
+ *(--stk) = (rt_uint32_t)0x05050505L; /* R5 */
+ *(--stk) = (rt_uint32_t)0x04040404L; /* R4 */
+ *(--stk) = (rt_uint32_t)0x03030303L; /* R3 */
+ *(--stk) = (rt_uint32_t)0x02020202L; /* R2 */
+ *(--stk) = (rt_uint32_t)0x01010101L; /* R1 */
+ *(--stk) = (rt_uint32_t)parameter; /* R0 : argument */
+
+ /* return task's current stack address */
+ return (rt_uint8_t *)stk;
+}
+
diff --git a/libcpu/c-sky/common/csi_core.h b/libcpu/c-sky/common/csi_core.h
new file mode 100644
index 0000000000..de44ad6d69
--- /dev/null
+++ b/libcpu/c-sky/common/csi_core.h
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
+ *
+ * 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 csi_core.h
+ * @brief CSI Core Layer Header File
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+#ifndef _CORE_H_
+#define _CORE_H_
+
+#include <stdint.h>
+#include "csi_gcc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* ################################## NVIC function ############################################ */
+
+/**
+ \brief initialize the NVIC interrupt controller
+ \param [in] prio_bits the priority bits of NVIC interrupt controller.
+ */
+void drv_nvic_init(uint32_t prio_bits);
+
+/**
+ \brief Enable External Interrupt
+ \details Enables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] irq_num External interrupt number. Value cannot be negative.
+ */
+void drv_nvic_enable_irq(int32_t irq_num);
+/**
+ \brief Disable External Interrupt
+ \details Disables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] irq_num External interrupt number. Value cannot be negative.
+ */
+void drv_nvic_disable_irq(int32_t irq_num);
+
+/**
+ \brief Get Pending Interrupt
+ \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+ \param [in] irq_num Interrupt number.
+ \return 0 Interrupt status is not pending.
+ \return 1 Interrupt status is pending.
+ */
+uint32_t drv_nvic_get_pending_irq(int32_t irq_num);
+
+/**
+ \brief Set Pending Interrupt
+ \details Sets the pending bit of an external interrupt.
+ \param [in] irq_num Interrupt number. Value cannot be negative.
+ */
+void drv_nvic_set_pending_irq(int32_t irq_num);
+
+/**
+ \brief Clear Pending Interrupt
+ \details Clears the pending bit of an external interrupt.
+ \param [in] irq_num External interrupt number. Value cannot be negative.
+ */
+void drv_nvic_clear_pending_irq(int32_t irq_num);
+
+/**
+ \brief Get Active Interrupt
+ \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt.
+ \param [in] irq_num Device specific interrupt number.
+ \return 0 Interrupt status is not active.
+ \return 1 Interrupt status is active.
+ \note irq_num must not be negative.
+ */
+uint32_t drv_nvic_get_active(int32_t irq_num);
+
+/**
+ \brief Set Interrupt Priority
+ \details Sets the priority of an interrupt.
+ \note The priority cannot be set for every core interrupt.
+ \param [in] irq_num Interrupt number.
+ \param [in] priority Priority to set.
+*/
+void drv_nvic_set_prio(int32_t irq_num, uint32_t priority);
+/**
+ \brief Get Interrupt Priority
+ \details Reads the priority of an interrupt.
+ The interrupt number can be positive to specify an external (device specific) interrupt,
+ or negative to specify an internal (core) interrupt.
+ \param [in] irq_num Interrupt number.
+ \return Interrupt Priority.
+ Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+uint32_t drv_nvic_get_prio(int32_t irq_num);
+
+/*@} end of CSI_Core_NVICFunctions */
+
+
+/* ########################## Cache functions #################################### */
+
+/**
+ \brief Enable I-Cache
+ \details Turns on I-Cache
+ */
+void drv_icache_enable(void);
+
+/**
+ \brief Disable I-Cache
+ \details Turns off I-Cache
+ */
+void drv_icache_disable(void);
+
+/**
+ \brief Invalidate I-Cache
+ \details Invalidates I-Cache
+ */
+void drv_icache_invalid(void);
+
+/**
+ \brief Enable D-Cache
+ \details Turns on D-Cache
+ \note I-Cache also turns on.
+ */
+void drv_dcache_enable(void);
+
+/**
+ \brief Disable D-Cache
+ \details Turns off D-Cache
+ \note I-Cache also turns off.
+ */
+void drv_dcache_disable(void);
+
+/**
+ \brief Invalidate D-Cache
+ \details Invalidates D-Cache
+ \note I-Cache also invalid
+ */
+void drv_dcache_invalid(void);
+
+/**
+ \brief Clean D-Cache
+ \details Cleans D-Cache
+ \note I-Cache also cleans
+ */
+void drv_dcache_clean(void);
+
+/**
+ \brief Clean & Invalidate D-Cache
+ \details Cleans and Invalidates D-Cache
+ \note I-Cache also flush.
+ */
+void drv_dcache_clean_invalid(void);
+
+
+/**
+ \brief D-Cache Invalidate by address
+ \details Invalidates D-Cache for the given address
+ \param[in] addr address (aligned to 16-byte boundary)
+ \param[in] dsize size of memory block (in number of bytes)
+*/
+void drv_dcache_invalid_range(uint32_t *addr, int32_t dsize);
+
+/**
+ \brief D-Cache Clean by address
+ \details Cleans D-Cache for the given address
+ \param[in] addr address (aligned to 16-byte boundary)
+ \param[in] dsize size of memory block (in number of bytes)
+*/
+void drv_dcache_clean_range(uint32_t *addr, int32_t dsize);
+
+/**
+ \brief D-Cache Clean and Invalidate by address
+ \details Cleans and invalidates D_Cache for the given address
+ \param[in] addr address (aligned to 16-byte boundary)
+ \param[in] dsize size of memory block (in number of bytes)
+*/
+void drv_dcache_clean_invalid_range(uint32_t *addr, int32_t dsize);
+
+/**
+ \brief setup cacheable range Cache
+ \details setup Cache range
+ */
+void drv_cache_set_range(uint32_t index, uint32_t baseAddr, uint32_t size, uint32_t enable);
+
+/**
+ \brief Enable cache profile
+ \details Turns on Cache profile
+ */
+void drv_cache_enable_profile(void);
+
+/**
+ \brief Disable cache profile
+ \details Turns off Cache profile
+ */
+void drv_cache_disable_profile(void);
+/**
+ \brief Reset cache profile
+ \details Reset Cache profile
+ */
+void drv_cache_reset_profile(void);
+
+/**
+ \brief cache access times
+ \details Cache access times
+ \note every 256 access add 1.
+ */
+uint32_t drv_cache_get_access_time(void);
+
+/**
+ \brief cache miss times
+ \details Cache miss times
+ \note every 256 miss add 1.
+ */
+uint32_t drv_cache_get_miss_time(void);
+
+/* ################################## SysTick function ############################################ */
+
+/**
+ \brief CORE timer Configuration
+ \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ Counter is in free running mode to generate periodic interrupts.
+ \param [in] ticks Number of ticks between two interrupts.
+ \param [in] irq_num core timer Interrupt number.
+ \return 0 Function succeeded.
+ \return 1 Function failed.
+ \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+ function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+ must contain a vendor-specific implementation of this function.
+ */
+uint32_t drv_coret_config(uint32_t ticks, int32_t irq_num);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CORE_H_ */
diff --git a/libcpu/c-sky/common/csi_gcc.h b/libcpu/c-sky/common/csi_gcc.h
new file mode 100644
index 0000000000..51d9bf6944
--- /dev/null
+++ b/libcpu/c-sky/common/csi_gcc.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
+ *
+ * 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 csi_gcc.h
+ * @brief CSI Header File for GCC.
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+#ifndef _CSI_GCC_H_
+#define _CSI_GCC_H_
+
+#define __ASM __asm /*!< asm keyword for GNU Compiler */
+#define __INLINE inline /*!< inline keyword for GNU Compiler */
+#define __ALWAYS_INLINE __attribute__((always_inline)) static inline
+
+#include <stdlib.h>
+#include "csi_reg.h"
+#include "csi_instr.h"
+#include "csi_simd.h"
+
+#endif /* _CSI_GCC_H_ */
diff --git a/libcpu/c-sky/common/csi_instr.h b/libcpu/c-sky/common/csi_instr.h
new file mode 100644
index 0000000000..23e3ee05d4
--- /dev/null
+++ b/libcpu/c-sky/common/csi_instr.h
@@ -0,0 +1,447 @@
+/*
+ * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
+ *
+ * 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 csi_instr.h
+ * @brief CSI Header File for instruct.
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+#ifndef _CSI_INSTR_H_
+#define _CSI_INSTR_H_
+
+
+#define __CSI_GCC_OUT_REG(r) "=r" (r)
+#define __CSI_GCC_USE_REG(r) "r" (r)
+
+/**
+ \brief No Operation
+ \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+__ALWAYS_INLINE void __NOP(void)
+{
+ __ASM volatile("nop");
+}
+
+
+/**
+ \brief Wait For Interrupt
+ \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+__ALWAYS_INLINE void __WFI(void)
+{
+ __ASM volatile("wait");
+}
+
+/**
+ \brief Wait For Interrupt
+ \details Wait For Interrupt is a hint instruction that suspends execution until one interrupt occurs.
+ */
+__ALWAYS_INLINE void __WAIT(void)
+{
+ __ASM volatile("wait");
+}
+
+/**
+ \brief Doze For Interrupt
+ \details Doze For Interrupt is a hint instruction that suspends execution until one interrupt occurs.
+ */
+__ALWAYS_INLINE void __DOZE(void)
+{
+ __ASM volatile("doze");
+}
+
+/**
+ \brief Stop For Interrupt
+ \details Stop For Interrupt is a hint instruction that suspends execution until one interrupt occurs.
+ */
+__ALWAYS_INLINE void __STOP(void)
+{
+ __ASM volatile("stop");
+}
+
+/**
+ \brief Instruction Synchronization Barrier
+ \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+ so that all instructions following the ISB are fetched from cache or memory,
+ after the instruction has been completed.
+ */
+__ALWAYS_INLINE void __ISB(void)
+{
+ __ASM volatile("sync"::: "memory");
+}
+
+
+/**
+ \brief Data Synchronization Barrier
+ \details Acts as a special kind of Data Memory Barrier.
+ It completes when all explicit memory accesses before this instruction complete.
+ */
+__ALWAYS_INLINE void __DSB(void)
+{
+ __ASM volatile("sync"::: "memory");
+}
+
+
+/**
+ \brief Data Memory Barrier
+ \details Ensures the apparent order of the explicit memory operations before
+ and after the instruction, without ensuring their completion.
+ */
+__ALWAYS_INLINE void __DMB(void)
+{
+ __ASM volatile("sync"::: "memory");
+}
+
+
+/**
+ \brief Reverse byte order (32 bit)
+ \details Reverses the byte order in integer value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__ALWAYS_INLINE uint32_t __REV(uint32_t value)
+{
+ return __builtin_bswap32(value);
+}
+
+
+/**
+ \brief Reverse byte order (16 bit)
+ \details Reverses the byte order in two unsigned short values.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__ALWAYS_INLINE uint32_t __REV16(uint32_t value)
+{
+ uint32_t result;
+#if (__CK80X >= 2)
+ __ASM volatile("revh %0, %1" : __CSI_GCC_OUT_REG(result) : __CSI_GCC_USE_REG(value));
+#else
+ result = ((value & 0xFF000000) >> 8) | ((value & 0x00FF0000) << 8) |
+ ((value & 0x0000FF00) >> 8) | ((value & 0x000000FF) << 8);
+#endif
+ return (result);
+}
+
+
+/**
+ \brief Reverse byte order in signed short value
+ \details Reverses the byte order in a signed short value with sign extension to integer.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__ALWAYS_INLINE int32_t __REVSH(int32_t value)
+{
+ return (short)(((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8));
+}
+
+
+/**
+ \brief Rotate Right in unsigned value (32 bit)
+ \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+ \param [in] op1 Value to rotate
+ \param [in] op2 Number of Bits to rotate
+ \return Rotated value
+ */
+__ALWAYS_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+ return (op1 >> op2) | (op1 << (32U - op2));
+}
+
+
+/**
+ \brief Breakpoint
+ \details Causes the processor to enter Debug state
+ Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+ */
+__ALWAYS_INLINE void __BKPT()
+{
+ __ASM volatile("bkpt");
+}
+
+/**
+ \brief Reverse bit order of value
+ \details Reverses the bit order of the given value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__ALWAYS_INLINE uint32_t __RBIT(uint32_t value)
+{
+ uint32_t result;
+
+#if (__CK80X >= 0x03U)
+ __ASM volatile("brev %0, %1" : "=r"(result) : "r"(value));
+#else
+ int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
+
+ result = value; /* r will be reversed bits of v; first get LSB of v */
+
+ for (value >>= 1U; value; value >>= 1U)
+ {
+ result <<= 1U;
+ result |= value & 1U;
+ s--;
+ }
+
+ result <<= s; /* shift when v's highest bits are zero */
+#endif
+ return (result);
+}
+
+
+/**
+ \brief Count leading zeros
+ \details Counts the number of leading zeros of a data value.
+ \param [in] value Value to count the leading zeros
+ \return number of leading zeros in value
+ */
+#define __CLZ __builtin_clz
+/**
+ \details This function saturates a signed value.
+ \param [in] x Value to be saturated
+ \param [in] y Bit position to saturate to [1..32]
+ \return Saturated value.
+ */
+__ALWAYS_INLINE int32_t __SSAT(int32_t x, uint32_t y)
+{
+ int32_t posMax, negMin;
+ uint32_t i;
+
+ posMax = 1;
+
+ for (i = 0; i < (y - 1); i++)
+ {
+ posMax = posMax * 2;
+ }
+
+ if (x > 0)
+ {
+ posMax = (posMax - 1);
+
+ if (x > posMax)
+ {
+ x = posMax;
+ }
+
+// x &= (posMax * 2 + 1);
+ }
+ else
+ {
+ negMin = -posMax;
+
+ if (x < negMin)
+ {
+ x = negMin;
+ }
+
+// x &= (posMax * 2 - 1);
+ }
+
+ return (x);
+}
+
+/**
+ \brief Unsigned Saturate
+ \details Saturates an unsigned value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+__ALWAYS_INLINE uint32_t __USAT(uint32_t value, uint32_t sat)
+{
+ uint32_t result;
+
+ if ((((0xFFFFFFFF >> sat) << sat) & value) != 0)
+ {
+ result = 0xFFFFFFFF >> (32 - sat);
+ }
+ else
+ {
+ result = value;
+ }
+
+ return (result);
+}
+
+/**
+ \brief Unsigned Saturate for internal use
+ \details Saturates an unsigned value, should not call directly.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+__ALWAYS_INLINE uint32_t __IUSAT(uint32_t value, uint32_t sat)
+{
+ uint32_t result;
+
+ if (value & 0x80000000) /* only overflow set bit-31 */
+ {
+ result = 0;
+ }
+ else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0)
+ {
+ result = 0xFFFFFFFF >> (32 - sat);
+ }
+ else
+ {
+ result = value;
+ }
+
+ return (result);
+}
+
+/**
+ \brief Rotate Right with Extend
+ \details This function moves each bit of a bitstring right by one bit.
+ The carry input is shifted in at the left end of the bitstring.
+ \note carry input will always 0.
+ \param [in] op1 Value to rotate
+ \return Rotated value
+ */
+__ALWAYS_INLINE uint32_t __RRX(uint32_t op1)
+{
+#if (__CK80X >= 2)
+ uint32_t res = 0;
+ __ASM volatile("bgeni t0, 31\n\t"
+ "lsri %0, 1\n\t"
+ "movt %1, t0\n\t"
+ "or %1, %1, %0\n\t"
+ : "=r"(op1), "=r"(res): "0"(op1), "1"(res): "t0");
+ return res;
+#else
+ uint32_t res = 0;
+ __ASM volatile("movi r7, 0\n\t"
+ "bseti r7, 31\n\t"
+ "lsri %0, 1\n\t"
+ "bf 1f\n\t"
+ "mov %1, r7\n\t"
+ "1:\n\t"
+ "or %1, %1, %0\n\t"
+ : "=r"(op1), "=r"(res): "0"(op1), "1"(res): "r7");
+ return res;
+#endif
+}
+
+/**
+ \brief LDRT Unprivileged (8 bit)
+ \details Executes a Unprivileged LDRT instruction for 8 bit value.
+ \param [in] addr Pointer to location
+ \return value of type uint8_t at (*ptr)
+ */
+__ALWAYS_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
+{
+ uint32_t result;
+//#warning "__LDRBT"
+ __ASM volatile("ldb %0, (%1, 0)" : "=r"(result) : "r"(addr));
+ return ((uint8_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDRT Unprivileged (16 bit)
+ \details Executes a Unprivileged LDRT instruction for 16 bit values.
+ \param [in] addr Pointer to location
+ \return value of type uint16_t at (*ptr)
+ */
+__ALWAYS_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
+{
+ uint32_t result;
+
+//#warning "__LDRHT"
+ __ASM volatile("ldh %0, (%1, 0)" : "=r"(result) : "r"(addr));
+ return ((uint16_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDRT Unprivileged (32 bit)
+ \details Executes a Unprivileged LDRT instruction for 32 bit values.
+ \param [in] addr Pointer to location
+ \return value of type uint32_t at (*ptr)
+ */
+__ALWAYS_INLINE uint32_t __LDRT(volatile uint32_t *addr)
+{
+ uint32_t result;
+
+//#warning "__LDRT"
+ __ASM volatile("ldw %0, (%1, 0)" : "=r"(result) : "r"(addr));
+ return (result);
+}
+
+
+/**
+ \brief STRT Unprivileged (8 bit)
+ \details Executes a Unprivileged STRT instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] addr Pointer to location
+ */
+__ALWAYS_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
+{
+//#warning "__STRBT"
+ __ASM volatile("stb %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory");
+}
+
+
+/**
+ \brief STRT Unprivileged (16 bit)
+ \details Executes a Unprivileged STRT instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] addr Pointer to location
+ */
+__ALWAYS_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
+{
+//#warning "__STRHT"
+ __ASM volatile("sth %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory");
+}
+
+
+/**
+ \brief STRT Unprivileged (32 bit)
+ \details Executes a Unprivileged STRT instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] addr Pointer to location
+ */
+__ALWAYS_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
+{
+//#warning "__STRT"
+ __ASM volatile("stw %1, (%0, 0)" :: "r"(addr), "r"(value) : "memory");
+}
+
+/*@}*/ /* end of group CSI_Core_InstructionInterface */
+
+
+/* ########################## FPU functions #################################### */
+
+/**
+ \brief get FPU type
+ \details returns the FPU type, always 0.
+ \returns
+ - \b 0: No FPU
+ - \b 1: Single precision FPU
+ - \b 2: Double + Single precision FPU
+ */
+__ALWAYS_INLINE uint32_t __get_FPUType(void)
+{
+ uint32_t result;
+
+ __ASM volatile("mfcr %0, cr<13, 0>" : "=r"(result));
+ return 0;
+}
+
+
+#endif /* _CSI_INSTR_H_ */
diff --git a/libcpu/c-sky/common/csi_reg.h b/libcpu/c-sky/common/csi_reg.h
new file mode 100644
index 0000000000..6eefaa8ffe
--- /dev/null
+++ b/libcpu/c-sky/common/csi_reg.h
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
+ *
+ * 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 csi_reg.h
+ * @brief CSI Header File for reg.
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+#ifndef _CSI_REG_H_
+#define _CSI_REG_H_
+
+#include<csi_gcc.h>
+
+/**
+ \brief Enable IRQ Interrupts
+ \details Enables IRQ interrupts by setting the IE-bit in the PSR.
+ Can only be executed in Privileged modes.
+ */
+__ALWAYS_INLINE void __enable_irq(void)
+{
+ __ASM volatile("psrset ie");
+}
+
+
+
+/**
+ \brief Disable IRQ Interrupts
+ \details Disables IRQ interrupts by clearing the IE-bit in the PSR.
+ Can only be executed in Privileged modes.
+ */
+__ALWAYS_INLINE void __disable_irq(void)
+{
+ __ASM volatile("psrclr ie");
+}
+
+/**
+ \brief Get PSR
+ \details Returns the content of the PSR Register.
+ \return PSR Register value
+ */
+__ALWAYS_INLINE uint32_t __get_PSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile("mfcr %0, psr" : "=r"(result));
+ return (result);
+}
+
+/**
+ \brief Set PSR
+ \details Writes the given value to the PSR Register.
+ \param [in] psr PSR Register value to set
+ */
+__ALWAYS_INLINE void __set_PSR(uint32_t psr)
+{
+ __ASM volatile("mtcr %0, psr" : : "r"(psr));
+}
+
+/**
+ \brief Get SP
+ \details Returns the content of the SP Register.
+ \return SP Register value
+ */
+__ALWAYS_INLINE uint32_t __get_SP(void)
+{
+ uint32_t result;
+
+ __ASM volatile("mov %0, sp" : "=r"(result));
+ return (result);
+}
+
+/**
+ \brief Set SP
+ \details Writes the given value to the SP Register.
+ \param [in] sp SP Register value to set
+ */
+__ALWAYS_INLINE void __set_SP(uint32_t sp)
+{
+ __ASM volatile("mov sp, %0" : : "r"(sp): "sp");
+}
+
+
+/**
+ \brief Get VBR Register
+ \details Returns the content of the VBR Register.
+ \return VBR Register value
+ */
+__ALWAYS_INLINE uint32_t __get_VBR(void)
+{
+ uint32_t result;
+
+ __ASM volatile("mfcr %0, vbr" : "=r"(result));
+ return (result);
+}
+
+/**
+ \brief Set VBR
+ \details Writes the given value to the VBR Register.
+ \param [in] vbr VBR Register value to set
+ */
+__ALWAYS_INLINE void __set_VBR(uint32_t vbr)
+{
+ __ASM volatile("mtcr %0, vbr" : : "r"(vbr));
+}
+
+/**
+ \brief Get EPC Register
+ \details Returns the content of the EPC Register.
+ \return EPC Register value
+ */
+__ALWAYS_INLINE uint32_t __get_EPC(void)
+{
+ uint32_t result;
+
+ __ASM volatile("mfcr %0, epc" : "=r"(result));
+ return (result);
+}
+
+/**
+ \brief Set EPC
+ \details Writes the given value to the EPC Register.
+ \param [in] epc EPC Register value to set
+ */
+__ALWAYS_INLINE void __set_EPC(uint32_t epc)
+{
+ __ASM volatile("mtcr %0, epc" : : "r"(epc));
+}
+
+/**
+ \brief Get EPSR
+ \details Returns the content of the EPSR Register.
+ \return EPSR Register value
+ */
+__ALWAYS_INLINE uint32_t __get_EPSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile("mfcr %0, epsr" : "=r"(result));
+ return (result);
+}
+
+/**
+ \brief Set EPSR
+ \details Writes the given value to the EPSR Register.
+ \param [in] epsr EPSR Register value to set
+ */
+__ALWAYS_INLINE void __set_EPSR(uint32_t epsr)
+{
+ __ASM volatile("mtcr %0, epsr" : : "r"(epsr));
+}
+
+/**
+ \brief Get CPUID Register
+ \details Returns the content of the CPUID Register.
+ \return CPUID Register value
+ */
+__ALWAYS_INLINE uint32_t __get_CPUID(void)
+{
+ uint32_t result;
+
+ __ASM volatile("mfcr %0, cr<13, 0>" : "=r"(result));
+ return (result);
+}
+
+#if (__SOFTRESET_PRESENT == 1U)
+/**
+ \brief Set SRCR
+ \details Assigns the given value to the SRCR.
+ \param [in] srcr SRCR value to set
+ */
+__ALWAYS_INLINE void __set_SRCR(uint32_t srcr)
+{
+ __ASM volatile("mtcr %0, cr<31, 0>\n" : : "r"(srcr));
+}
+#endif /* __SOFTRESET_PRESENT == 1U */
+
+#if (__MGU_PRESENT == 1U)
+/**
+ \brief Get CCR
+ \details Returns the current value of the CCR.
+ \return CCR Register value
+ */
+__ALWAYS_INLINE uint32_t __get_CCR(void)
+{
+ register uint32_t result;
+
+ __ASM volatile("mfcr %0, cr<18, 0>\n" : "=r"(result));
+ return (result);
+}
+
+
+/**
+ \brief Set CCR
+ \details Assigns the given value to the CCR.
+ \param [in] ccr CCR value to set
+ */
+__ALWAYS_INLINE void __set_CCR(uint32_t ccr)
+{
+ __ASM volatile("mtcr %0, cr<18, 0>\n" : : "r"(ccr));
+}
+
+
+/**
+ \brief Get CAPR
+ \details Returns the current value of the CAPR.
+ \return CAPR Register value
+ */
+__ALWAYS_INLINE uint32_t __get_CAPR(void)
+{
+ register uint32_t result;
+
+ __ASM volatile("mfcr %0, cr<19, 0>\n" : "=r"(result));
+ return (result);
+}
+
+/**
+ \brief Set CAPR
+ \details Assigns the given value to the CAPR.
+ \param [in] capr CAPR value to set
+ */
+__ALWAYS_INLINE void __set_CAPR(uint32_t capr)
+{
+ __ASM volatile("mtcr %0, cr<19, 0>\n" : : "r"(capr));
+}
+
+
+/**
+ \brief Set PACR
+ \details Assigns the given value to the PACR.
+
+ \param [in] pacr PACR value to set
+ */
+__ALWAYS_INLINE void __set_PACR(uint32_t pacr)
+{
+ __ASM volatile("mtcr %0, cr<20, 0>\n" : : "r"(pacr));
+}
+
+
+/**
+ \brief Get PACR
+ \details Returns the current value of PACR.
+ \return PACR value
+ */
+__ALWAYS_INLINE uint32_t __get_PACR(void)
+{
+ uint32_t result;
+
+ __ASM volatile("mfcr %0, cr<20, 0>" : "=r"(result));
+ return (result);
+}
+
+/**
+ \brief Set PRSR
+ \details Assigns the given value to the PRSR.
+
+ \param [in] prsr PRSR value to set
+ */
+__ALWAYS_INLINE void __set_PRSR(uint32_t prsr)
+{
+ __ASM volatile("mtcr %0, cr<21, 0>\n" : : "r"(prsr));
+}
+
+/**
+ \brief Get PRSR
+ \details Returns the current value of PRSR.
+ \return PRSR value
+ */
+__ALWAYS_INLINE uint32_t __get_PRSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile("mfcr %0, cr<21, 0>" : "=r"(result));
+ return (result);
+}
+#endif /* __MGU_PRESENT == 1U */
+
+/**
+ \brief Get user sp
+ \details Returns the current value of user r14.
+ \return UR14 value
+ */
+__ALWAYS_INLINE uint32_t __get_UR14(void)
+{
+ uint32_t result;
+
+ __ASM volatile("mfcr %0, cr<14, 1>" : "=r"(result));
+ return (result);
+}
+
+/**
+ \brief Enable interrupts and exceptions
+ \details Enables interrupts and exceptions by setting the IE-bit and EE-bit in the PSR.
+ Can only be executed in Privileged modes.
+ */
+__ALWAYS_INLINE void __enable_excp_irq(void)
+{
+ __ASM volatile("psrset ee, ie");
+}
+
+
+/**
+ \brief Disable interrupts and exceptions
+ \details Disables interrupts and exceptions by clearing the IE-bit and EE-bit in the PSR.
+ Can only be executed in Privileged modes.
+ */
+__ALWAYS_INLINE void __disable_excp_irq(void)
+{
+ __ASM volatile("psrclr ee, ie");
+}
+
+#if (__GSR_GCR_PRESENT == 1U)
+/**
+ \brief Get GSR
+ \details Returns the content of the GSR Register.
+ \return GSR Register value
+ */
+__ALWAYS_INLINE uint32_t __get_GSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile("mfcr %0, cr<12, 0>" : "=r"(result));
+ return (result);
+}
+
+/**
+ \brief Get GCR
+ \details Returns the content of the GCR Register.
+ \return GCR Register value
+ */
+__ALWAYS_INLINE uint32_t __get_GCR(void)
+{
+ uint32_t result;
+
+ __ASM volatile("mfcr %0, cr<11, 0>" : "=r"(result));
+ return (result);
+}
+
+/**
+ \brief Set GCR
+ \details Writes the given value to the GCR Register.
+ \param [in] gcr GCR Register value to set
+ */
+__ALWAYS_INLINE void __set_GCR(uint32_t gcr)
+{
+ __ASM volatile("mtcr %0, cr<11, 0>" : : "r"(gcr));
+}
+
+#endif /* (__GSR_GCR_PRESENT == 1U) */
+
+
+#endif /* _CSI_REG_H_ */
diff --git a/libcpu/c-sky/common/csi_simd.h b/libcpu/c-sky/common/csi_simd.h
new file mode 100644
index 0000000000..c6ddfcbdc5
--- /dev/null
+++ b/libcpu/c-sky/common/csi_simd.h
@@ -0,0 +1,1483 @@
+/*
+ * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
+ *
+ * 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 csi_simd.h
+ * @brief CSI Single Instruction Multiple Data (SIMD) Header File for GCC.
+ * @version V1.0
+ * @date 02. June 2017
+ ******************************************************************************/
+
+#ifndef _CSI_SIMD_H_
+#define _CSI_SIMD_H_
+
+/**
+ \brief Halfword packing instruction. Combines bits[15:0] of val1 with bits[31:16]
+ of val2 levitated with the val3.
+ \details Combine a halfword from one register with a halfword from another register.
+ The second argument can be left-shifted before extraction of the halfword.
+ \param [in] val1 first 16-bit operands
+ \param [in] val2 second 16-bit operands
+ \param [in] val3 value for left-shifting val2. Value range [0..31].
+ \return the combination of halfwords.
+ \remark
+ res[15:0] = val1[15:0] \n
+ res[31:16] = val2[31:16] << val3
+ */
+__ALWAYS_INLINE uint32_t __PKHBT(uint32_t val1, uint32_t val2, uint32_t val3)
+{
+ return ((((int32_t)(val1) << 0) & (int32_t)0x0000FFFF) | (((int32_t)(val2) << val3) & (int32_t)0xFFFF0000));
+}
+
+/**
+ \brief Halfword packing instruction. Combines bits[31:16] of val1 with bits[15:0]
+ of val2 right-shifted with the val3.
+ \details Combine a halfword from one register with a halfword from another register.
+ The second argument can be right-shifted before extraction of the halfword.
+ \param [in] val1 first 16-bit operands
+ \param [in] val2 second 16-bit operands
+ \param [in] val3 value for right-shifting val2. Value range [1..32].
+ \return the combination of halfwords.
+ \remark
+ res[15:0] = val2[15:0] >> val3 \n
+ res[31:16] = val1[31:16]
+ */
+__ALWAYS_INLINE uint32_t __PKHTB(uint32_t val1, uint32_t val2, uint32_t val3)
+{
+ return ((((int32_t)(val1) << 0) & (int32_t)0xFFFF0000) | (((int32_t)(val2) >> val3) & (int32_t)0x0000FFFF));
+}
+
+/**
+ \brief Dual 16-bit signed saturate.
+ \details This function saturates a signed value.
+ \param [in] x two signed 16-bit values to be saturated.
+ \param [in] y bit position for saturation, an integral constant expression in the range 1 to 16.
+ \return the sum of the absolute differences of the following bytes, added to the accumulation value:\n
+ the signed saturation of the low halfword in val1, saturated to the bit position specified in
+ val2 and returned in the low halfword of the return value.\n
+ the signed saturation of the high halfword in val1, saturated to the bit position specified in
+ val2 and returned in the high halfword of the return value.
+ */
+__ALWAYS_INLINE uint32_t __SSAT16(int32_t x, const uint32_t y)
+{
+ int32_t r = 0, s = 0;
+
+ r = __SSAT((((int32_t)x << 16) >> 16), y) & (int32_t)0x0000FFFF;
+ s = __SSAT((((int32_t)x) >> 16), y) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+ \brief Dual 16-bit unsigned saturate.
+ \details This function enables you to saturate two signed 16-bit values to a selected unsigned range.
+ \param [in] x two signed 16-bit values to be saturated.
+ \param [in] y bit position for saturation, an integral constant expression in the range 1 to 16.
+ \return the saturation of the two signed 16-bit values, as non-negative values:
+ the saturation of the low halfword in val1, saturated to the bit position specified in
+ val2 and returned in the low halfword of the return value.\n
+ the saturation of the high halfword in val1, saturated to the bit position specified in
+ val2 and returned in the high halfword of the return value.
+ */
+__ALWAYS_INLINE uint32_t __USAT16(uint32_t x, const uint32_t y)
+{
+ int32_t r = 0, s = 0;
+
+ r = __IUSAT(((x << 16) >> 16), y) & 0x0000FFFF;
+ s = __IUSAT(((x) >> 16), y) & 0x0000FFFF;
+
+ return ((s << 16) | (r));
+}
+
+/**
+ \brief Quad 8-bit saturating addition.
+ \details This function enables you to perform four 8-bit integer additions,
+ saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1.
+ \param [in] x first four 8-bit summands.
+ \param [in] y second four 8-bit summands.
+ \return the saturated addition of the first byte of each operand in the first byte of the return value.\n
+ the saturated addition of the second byte of each operand in the second byte of the return value.\n
+ the saturated addition of the third byte of each operand in the third byte of the return value.\n
+ the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n
+ The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1.
+ \remark
+ res[7:0] = val1[7:0] + val2[7:0] \n
+ res[15:8] = val1[15:8] + val2[15:8] \n
+ res[23:16] = val1[23:16] + val2[23:16] \n
+ res[31:24] = val1[31:24] + val2[31:24]
+ */
+__ALWAYS_INLINE uint32_t __QADD8(uint32_t x, uint32_t y)
+{
+ int32_t r, s, t, u;
+
+ r = __SSAT(((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
+ s = __SSAT(((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
+ t = __SSAT(((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF;
+ u = __SSAT(((((int32_t)x) >> 24) + (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF;
+
+ return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r)));
+}
+
+/**
+ \brief Quad 8-bit unsigned saturating addition.
+ \details This function enables you to perform four unsigned 8-bit integer additions,
+ saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1.
+ \param [in] x first four 8-bit summands.
+ \param [in] y second four 8-bit summands.
+ \return the saturated addition of the first byte of each operand in the first byte of the return value.\n
+ the saturated addition of the second byte of each operand in the second byte of the return value.\n
+ the saturated addition of the third byte of each operand in the third byte of the return value.\n
+ the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n
+ The returned results are saturated to the 8-bit signed integer range 0 <= x <= 2^8 - 1.
+ \remark
+ res[7:0] = val1[7:0] + val2[7:0] \n
+ res[15:8] = val1[15:8] + val2[15:8] \n
+ res[23:16] = val1[23:16] + val2[23:16] \n
+ res[31:24] = val1[31:24] + val2[31:24]
+ */
+__ALWAYS_INLINE uint32_t __UQADD8(uint32_t x, uint32_t y)
+{
+ int32_t r, s, t, u;
+
+ r = __IUSAT((((x << 24) >> 24) + ((y << 24) >> 24)), 8) & 0x000000FF;
+ s = __IUSAT((((x << 16) >> 24) + ((y << 16) >> 24)), 8) & 0x000000FF;
+ t = __IUSAT((((x << 8) >> 24) + ((y << 8) >> 24)), 8) & 0x000000FF;
+ u = __IUSAT((((x) >> 24) + ((y) >> 24)), 8) & 0x000000FF;
+
+ return ((u << 24) | (t << 16) | (s << 8) | (r));
+}
+
+/**
+ \brief Quad 8-bit signed addition.
+ \details This function performs four 8-bit signed integer additions.
+ \param [in] x first four 8-bit summands.
+ \param [in] y second four 8-bit summands.
+ \return the addition of the first bytes from each operand, in the first byte of the return value.\n
+ the addition of the second bytes of each operand, in the second byte of the return value.\n
+ the addition of the third bytes of each operand, in the third byte of the return value.\n
+ the addition of the fourth bytes of each operand, in the fourth byte of the return value.
+ \remark
+ res[7:0] = val1[7:0] + val2[7:0] \n
+ res[15:8] = val1[15:8] + val2[15:8] \n
+ res[23:16] = val1[23:16] + val2[23:16] \n
+ res[31:24] = val1[31:24] + val2[31:24]
+ */
+__ALWAYS_INLINE uint32_t __SADD8(uint32_t x, uint32_t y)
+{
+ int32_t r, s, t, u;
+
+ r = ((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF;
+ s = ((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF;
+ t = ((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)) & (int32_t)0x000000FF;
+ u = ((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) & (int32_t)0x000000FF;
+
+ return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r)));
+}
+
+/**
+ \brief Quad 8-bit unsigned addition.
+ \details This function performs four unsigned 8-bit integer additions.
+ \param [in] x first four 8-bit summands.
+ \param [in] y second four 8-bit summands.
+ \return the addition of the first bytes from each operand, in the first byte of the return value.\n
+ the addition of the second bytes of each operand, in the second byte of the return value.\n
+ the addition of the third bytes of each operand, in the third byte of the return value.\n
+ the addition of the fourth bytes of each operand, in the fourth byte of the return value.
+ \remark
+ res[7:0] = val1[7:0] + val2[7:0] \n
+ res[15:8] = val1[15:8] + val2[15:8] \n
+ res[23:16] = val1[23:16] + val2[23:16] \n
+ res[31:24] = val1[31:24] + val2[31:24]
+ */
+__ALWAYS_INLINE uint32_t __UADD8(uint32_t x, uint32_t y)
+{
+ int32_t r, s, t, u;
+
+ r = (((x << 24) >> 24) + ((y << 24) >> 24)) & 0x000000FF;
+ s = (((x << 16) >> 24) + ((y << 16) >> 24)) & 0x000000FF;
+ t = (((x << 8) >> 24) + ((y << 8) >> 24)) & 0x000000FF;
+ u = (((x) >> 24) + ((y) >> 24)) & 0x000000FF;
+
+ return ((u << 24) | (t << 16) | (s << 8) | (r));
+}
+
+/**
+ \brief Quad 8-bit saturating subtract.
+ \details This function enables you to perform four 8-bit integer subtractions,
+ saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1.
+ \param [in] x first four 8-bit summands.
+ \param [in] y second four 8-bit summands.
+ \return the subtraction of the first byte of each operand in the first byte of the return value.\n
+ the subtraction of the second byte of each operand in the second byte of the return value.\n
+ the subtraction of the third byte of each operand in the third byte of the return value.\n
+ the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n
+ The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1.
+ \remark
+ res[7:0] = val1[7:0] - val2[7:0] \n
+ res[15:8] = val1[15:8] - val2[15:8] \n
+ res[23:16] = val1[23:16] - val2[23:16] \n
+ res[31:24] = val1[31:24] - val2[31:24]
+ */
+__ALWAYS_INLINE uint32_t __QSUB8(uint32_t x, uint32_t y)
+{
+ int32_t r, s, t, u;
+
+ r = __SSAT(((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
+ s = __SSAT(((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
+ t = __SSAT(((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF;
+ u = __SSAT(((((int32_t)x) >> 24) - (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF;
+
+ return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r)));
+}
+
+/**
+ \brief Quad 8-bit unsigned saturating subtraction.
+ \details This function enables you to perform four unsigned 8-bit integer subtractions,
+ saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1.
+ \param [in] x first four 8-bit summands.
+ \param [in] y second four 8-bit summands.
+ \return the subtraction of the first byte of each operand in the first byte of the return value.\n
+ the subtraction of the second byte of each operand in the second byte of the return value.\n
+ the subtraction of the third byte of each operand in the third byte of the return value.\n
+ the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n
+ The returned results are saturated to the 8-bit unsigned integer range 0 <= x <= 2^8 - 1.
+ \remark
+ res[7:0] = val1[7:0] - val2[7:0] \n
+ res[15:8] = val1[15:8] - val2[15:8] \n
+ res[23:16] = val1[23:16] - val2[23:16] \n
+ res[31:24] = val1[31:24] - val2[31:24]
+ */
+__ALWAYS_INLINE uint32_t __UQSUB8(uint32_t x, uint32_t y)
+{
+ int32_t r, s, t, u;
+
+ r = __IUSAT((((x << 24) >> 24) - ((y << 24) >> 24)), 8) & 0x000000FF;
+ s = __IUSAT((((x << 16) >> 24) - ((y << 16) >> 24)), 8) & 0x000000FF;
+ t = __IUSAT((((x << 8) >> 24) - ((y << 8) >> 24)), 8) & 0x000000FF;
+ u = __IUSAT((((x) >> 24) - ((y) >> 24)), 8) & 0x000000FF;
+
+ return ((u << 24) | (t << 16) | (s << 8) | (r));
+}
+
+/**
+ \brief Quad 8-bit signed subtraction.
+ \details This function enables you to perform four 8-bit signed integer subtractions.
+ \param [in] x first four 8-bit operands of each subtraction.
+ \param [in] y second four 8-bit operands of each subtraction.
+ \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n
+ the subtraction of the second bytes of each operand, in the second byte of the return value.\n
+ the subtraction of the third bytes of each operand, in the third byte of the return value.\n
+ the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.
+ \remark
+ res[7:0] = val1[7:0] - val2[7:0] \n
+ res[15:8] = val1[15:8] - val2[15:8] \n
+ res[23:16] = val1[23:16] - val2[23:16] \n
+ res[31:24] = val1[31:24] - val2[31:24]
+ */
+__ALWAYS_INLINE uint32_t __SSUB8(uint32_t x, uint32_t y)
+{
+ int32_t r, s, t, u;
+
+ r = ((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF;
+ s = ((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF;
+ t = ((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)) & (int32_t)0x000000FF;
+ u = ((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) & (int32_t)0x000000FF;
+
+ return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r)));
+}
+
+/**
+ \brief Quad 8-bit unsigned subtract.
+ \details This function enables you to perform four 8-bit unsigned integer subtractions.
+ \param [in] x first four 8-bit operands of each subtraction.
+ \param [in] y second four 8-bit operands of each subtraction.
+ \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n
+ the subtraction of the second bytes of each operand, in the second byte of the return value.\n
+ the subtraction of the third bytes of each operand, in the third byte of the return value.\n
+ the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.
+ \remark
+ res[7:0] = val1[7:0] - val2[7:0] \n
+ res[15:8] = val1[15:8] - val2[15:8] \n
+ res[23:16] = val1[23:16] - val2[23:16] \n
+ res[31:24] = val1[31:24] - val2[31:24]
+ */
+__ALWAYS_INLINE uint32_t __USUB8(uint32_t x, uint32_t y)
+{
+ int32_t r, s, t, u;
+
+ r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF;
+ s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF;
+ t = (((x << 8) >> 24) - ((y << 8) >> 24)) & 0x000000FF;
+ u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF;
+
+ return ((u << 24) | (t << 16) | (s << 8) | (r));
+}
+
+/**
+ \brief Unsigned sum of quad 8-bit unsigned absolute difference.
+ \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values
+ of the differences together, returning the result as a single unsigned integer.
+ \param [in] x first four 8-bit operands of each subtraction.
+ \param [in] y second four 8-bit operands of each subtraction.
+ \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n
+ the subtraction of the second bytes of each operand, in the second byte of the return value.\n
+ the subtraction of the third bytes of each operand, in the third byte of the return value.\n
+ the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.\n
+ The sum is returned as a single unsigned integer.
+ \remark
+ absdiff1 = val1[7:0] - val2[7:0] \n
+ absdiff2 = val1[15:8] - val2[15:8] \n
+ absdiff3 = val1[23:16] - val2[23:16] \n
+ absdiff4 = val1[31:24] - val2[31:24] \n
+ res[31:0] = absdiff1 + absdiff2 + absdiff3 + absdiff4
+ */
+__ALWAYS_INLINE uint32_t __USAD8(uint32_t x, uint32_t y)
+{
+ int32_t r, s, t, u;
+
+ r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF;
+ s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF;
+ t = (((x << 8) >> 24) - ((y << 8) >> 24)) & 0x000000FF;
+ u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF;
+
+ return (u + t + s + r);
+}
+
+/**
+ \brief Unsigned sum of quad 8-bit unsigned absolute difference with 32-bit accumulate.
+ \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values
+ of the differences to a 32-bit accumulate operand.
+ \param [in] x first four 8-bit operands of each subtraction.
+ \param [in] y second four 8-bit operands of each subtraction.
+ \param [in] sum accumulation value.
+ \return the sum of the absolute differences of the following bytes, added to the accumulation value:
+ the subtraction of the first bytes from each operand, in the first byte of the return value.\n
+ the subtraction of the second bytes of each operand, in the second byte of the return value.\n
+ the subtraction of the third bytes of each operand, in the third byte of the return value.\n
+ the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.
+ \remark
+ absdiff1 = val1[7:0] - val2[7:0] \n
+ absdiff2 = val1[15:8] - val2[15:8] \n
+ absdiff3 = val1[23:16] - val2[23:16] \n
+ absdiff4 = val1[31:24] - val2[31:24] \n
+ sum = absdiff1 + absdiff2 + absdiff3 + absdiff4 \n
+ res[31:0] = sum[31:0] + val3[31:0]
+ */
+__ALWAYS_INLINE uint32_t __USADA8(uint32_t x, uint32_t y, uint32_t sum)
+{
+ int32_t r, s, t, u;
+
+ r = (abs(((x << 24) >> 24) - ((y << 24) >> 24))) & 0x000000FF;
+ s = (abs(((x << 16) >> 24) - ((y << 16) >> 24))) & 0x000000FF;
+ t = (abs(((x << 8) >> 24) - ((y << 8) >> 24))) & 0x000000FF;
+ u = (abs(((x) >> 24) - ((y) >> 24))) & 0x000000FF;
+
+ return (u + t + s + r + sum);
+}
+
+/**
+ \brief Dual 16-bit saturating addition.
+ \details This function enables you to perform two 16-bit integer arithmetic additions in parallel,
+ saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+ \param [in] x first two 16-bit summands.
+ \param [in] y second two 16-bit summands.
+ \return the saturated addition of the low halfwords, in the low halfword of the return value.\n
+ the saturated addition of the high halfwords, in the high halfword of the return value.\n
+ The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+ \remark
+ res[15:0] = val1[15:0] + val2[15:0] \n
+ res[31:16] = val1[31:16] + val2[31:16]
+ */
+__ALWAYS_INLINE uint32_t __QADD16(uint32_t x, uint32_t y)
+{
+ int32_t r = 0, s = 0;
+
+ r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+ s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+ \brief Dual 16-bit unsigned saturating addition.
+ \details This function enables you to perform two unsigned 16-bit integer additions, saturating
+ the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1.
+ \param [in] x first two 16-bit summands.
+ \param [in] y second two 16-bit summands.
+ \return the saturated addition of the low halfwords, in the low halfword of the return value.\n
+ the saturated addition of the high halfwords, in the high halfword of the return value.\n
+ The results are saturated to the 16-bit unsigned integer range 0 < x < 2^16 - 1.
+ \remark
+ res[15:0] = val1[15:0] + val2[15:0] \n
+ res[31:16] = val1[31:16] + val2[31:16]
+ */
+__ALWAYS_INLINE uint32_t __UQADD16(uint32_t x, uint32_t y)
+{
+ int32_t r = 0, s = 0;
+
+ r = __IUSAT((((x << 16) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF;
+ s = __IUSAT((((x) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF;
+
+ return ((s << 16) | (r));
+}
+
+/**
+ \brief Dual 16-bit signed addition.
+ \details This function enables you to perform two 16-bit signed integer additions.
+ \param [in] x first two 16-bit summands.
+ \param [in] y second two 16-bit summands.
+ \return the addition of the low halfwords in the low halfword of the return value.\n
+ the addition of the high halfwords in the high halfword of the return value.
+ \remark
+ res[15:0] = val1[15:0] + val2[15:0] \n
+ res[31:16] = val1[31:16] + val2[31:16]
+ */
+__ALWAYS_INLINE uint32_t __SADD16(uint32_t x, uint32_t y)
+{
+ int32_t r = 0, s = 0;
+
+ r = ((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF;
+ s = ((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+ \brief Dual 16-bit unsigned addition
+ \details This function enables you to perform two 16-bit unsigned integer additions.
+ \param [in] x first two 16-bit summands for each addition.
+ \param [in] y second two 16-bit summands for each addition.
+ \return the addition of the low halfwords in the low halfword of the return value.\n
+ the addition of the high halfwords in the high halfword of the return value.
+ \remark
+ res[15:0] = val1[15:0] + val2[15:0] \n
+ res[31:16] = val1[31:16] + val2[31:16]
+ */
+__ALWAYS_INLINE uint32_t __UADD16(uint32_t x, uint32_t y)
+{
+ int32_t r = 0, s = 0;
+
+ r = (((x << 16) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF;
+ s = (((x) >> 16) + ((y) >> 16)) & 0x0000FFFF;
+
+ return ((s << 16) | (r));
+}
+
+
+/**
+ \brief Dual 16-bit signed addition with halved results.
+ \details This function enables you to perform two signed 16-bit integer additions, halving the results.
+ \param [in] x first two 16-bit summands.
+ \param [in] y second two 16-bit summands.
+ \return the halved addition of the low halfwords, in the low halfword of the return value.\n
+ the halved addition of the high halfwords, in the high halfword of the return value.
+ \remark
+ res[15:0] = (val1[15:0] + val2[15:0]) >> 1 \n
+ res[31:16] = (val1[31:16] + val2[31:16]) >> 1
+ */
+__ALWAYS_INLINE uint32_t __SHADD16(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = (((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+ s = (((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+ \brief Dual 16-bit unsigned addition with halved results.
+ \details This function enables you to perform two unsigned 16-bit integer additions, halving the results.
+ \param [in] x first two 16-bit summands.
+ \param [in] y second two 16-bit summands.
+ \return the halved addition of the low halfwords, in the low halfword of the return value.\n
+ the halved addition of the high halfwords, in the high halfword of the return value.
+ \remark
+ res[15:0] = (val1[15:0] + val2[15:0]) >> 1 \n
+ res[31:16] = (val1[31:16] + val2[31:16]) >> 1
+ */
+__ALWAYS_INLINE uint32_t __UHADD16(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = ((((x << 16) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF;
+ s = ((((x) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF;
+
+ return ((s << 16) | (r));
+}
+
+/**
+ \brief Quad 8-bit signed addition with halved results.
+ \details This function enables you to perform four signed 8-bit integer additions, halving the results.
+ \param [in] x first four 8-bit summands.
+ \param [in] y second four 8-bit summands.
+ \return the halved addition of the first bytes from each operand, in the first byte of the return value.\n
+ the halved addition of the second bytes from each operand, in the second byte of the return value.\n
+ the halved addition of the third bytes from each operand, in the third byte of the return value.\n
+ the halved addition of the fourth bytes from each operand, in the fourth byte of the return value.
+ \remark
+ res[7:0] = (val1[7:0] + val2[7:0] ) >> 1 \n
+ res[15:8] = (val1[15:8] + val2[15:8] ) >> 1 \n
+ res[23:16] = (val1[23:16] + val2[23:16]) >> 1 \n
+ res[31:24] = (val1[31:24] + val2[31:24]) >> 1
+ */
+__ALWAYS_INLINE uint32_t __SHADD8(uint32_t x, uint32_t y)
+{
+ int32_t r, s, t, u;
+
+ r = (((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF;
+ s = (((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF;
+ t = (((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)) >> 1) & (int32_t)0x000000FF;
+ u = (((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF;
+
+ return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r)));
+}
+
+/**
+ \brief Quad 8-bit unsigned addition with halved results.
+ \details This function enables you to perform four unsigned 8-bit integer additions, halving the results.
+ \param [in] x first four 8-bit summands.
+ \param [in] y second four 8-bit summands.
+ \return the halved addition of the first bytes from each operand, in the first byte of the return value.\n
+ the halved addition of the second bytes from each operand, in the second byte of the return value.\n
+ the halved addition of the third bytes from each operand, in the third byte of the return value.\n
+ the halved addition of the fourth bytes from each operand, in the fourth byte of the return value.
+ \remark
+ res[7:0] = (val1[7:0] + val2[7:0] ) >> 1 \n
+ res[15:8] = (val1[15:8] + val2[15:8] ) >> 1 \n
+ res[23:16] = (val1[23:16] + val2[23:16]) >> 1 \n
+ res[31:24] = (val1[31:24] + val2[31:24]) >> 1
+ */
+__ALWAYS_INLINE uint32_t __UHADD8(uint32_t x, uint32_t y)
+{
+ int32_t r, s, t, u;
+
+ r = ((((x << 24) >> 24) + ((y << 24) >> 24)) >> 1) & 0x000000FF;
+ s = ((((x << 16) >> 24) + ((y << 16) >> 24)) >> 1) & 0x000000FF;
+ t = ((((x << 8) >> 24) + ((y << 8) >> 24)) >> 1) & 0x000000FF;
+ u = ((((x) >> 24) + ((y) >> 24)) >> 1) & 0x000000FF;
+
+ return ((u << 24) | (t << 16) | (s << 8) | (r));
+}
+
+/**
+ \brief Dual 16-bit saturating subtract.
+ \details This function enables you to perform two 16-bit integer subtractions in parallel,
+ saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+ \param [in] x first two 16-bit summands.
+ \param [in] y second two 16-bit summands.
+ \return the saturated subtraction of the low halfwords, in the low halfword of the return value.\n
+ the saturated subtraction of the high halfwords, in the high halfword of the return value.\n
+ The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+ \remark
+ res[15:0] = val1[15:0] - val2[15:0] \n
+ res[31:16] = val1[31:16] - val2[31:16]
+ */
+__ALWAYS_INLINE uint32_t __QSUB16(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+ s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+ \brief Dual 16-bit unsigned saturating subtraction.
+ \details This function enables you to perform two unsigned 16-bit integer subtractions,
+ saturating the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1.
+ \param [in] x first two 16-bit operands for each subtraction.
+ \param [in] y second two 16-bit operands for each subtraction.
+ \return the saturated subtraction of the low halfwords, in the low halfword of the return value.\n
+ the saturated subtraction of the high halfwords, in the high halfword of the return value.\n
+ The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+ \remark
+ res[15:0] = val1[15:0] - val2[15:0] \n
+ res[31:16] = val1[31:16] - val2[31:16]
+ */
+__ALWAYS_INLINE uint32_t __UQSUB16(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = __IUSAT((((x << 16) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF;
+ s = __IUSAT((((x) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF;
+
+ return ((s << 16) | (r));
+}
+
+/**
+ \brief Dual 16-bit signed subtraction.
+ \details This function enables you to perform two 16-bit signed integer subtractions.
+ \param [in] x first two 16-bit operands of each subtraction.
+ \param [in] y second two 16-bit operands of each subtraction.
+ \return the subtraction of the low halfword in the second operand from the low
+ halfword in the first operand, in the low halfword of the return value. \n
+ the subtraction of the high halfword in the second operand from the high
+ halfword in the first operand, in the high halfword of the return value.
+ \remark
+ res[15:0] = val1[15:0] - val2[15:0] \n
+ res[31:16] = val1[31:16] - val2[31:16]
+ */
+__ALWAYS_INLINE uint32_t __SSUB16(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = ((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF;
+ s = ((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+ \brief Dual 16-bit unsigned subtract.
+ \details This function enables you to perform two 16-bit unsigned integer subtractions.
+ \param [in] x first two 16-bit operands of each subtraction.
+ \param [in] y second two 16-bit operands of each subtraction.
+ \return the subtraction of the low halfword in the second operand from the low
+ halfword in the first operand, in the low halfword of the return value. \n
+ the subtraction of the high halfword in the second operand from the high
+ halfword in the first operand, in the high halfword of the return value.
+ \remark
+ res[15:0] = val1[15:0] - val2[15:0] \n
+ res[31:16] = val1[31:16] - val2[31:16]
+ */
+__ALWAYS_INLINE uint32_t __USUB16(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = (((x << 16) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF;
+ s = (((x) >> 16) - ((y) >> 16)) & 0x0000FFFF;
+
+ return ((s << 16) | (r));
+}
+
+/**
+ \brief Dual 16-bit signed subtraction with halved results.
+ \details This function enables you to perform two signed 16-bit integer subtractions, halving the results.
+ \param [in] x first two 16-bit summands.
+ \param [in] y second two 16-bit summands.
+ \return the halved subtraction of the low halfwords, in the low halfword of the return value.\n
+ the halved subtraction of the high halfwords, in the high halfword of the return value.
+ \remark
+ res[15:0] = (val1[15:0] - val2[15:0]) >> 1 \n
+ res[31:16] = (val1[31:16] - val2[31:16]) >> 1
+ */
+__ALWAYS_INLINE uint32_t __SHSUB16(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = (((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+ s = (((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+ \brief Dual 16-bit unsigned subtraction with halved results.
+ \details This function enables you to perform two unsigned 16-bit integer subtractions, halving the results.
+ \param [in] x first two 16-bit summands.
+ \param [in] y second two 16-bit summands.
+ \return the halved subtraction of the low halfwords, in the low halfword of the return value.\n
+ the halved subtraction of the high halfwords, in the high halfword of the return value.
+ \remark
+ res[15:0] = (val1[15:0] - val2[15:0]) >> 1 \n
+ res[31:16] = (val1[31:16] - val2[31:16]) >> 1
+ */
+__ALWAYS_INLINE uint32_t __UHSUB16(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = ((((x << 16) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF;
+ s = ((((x) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF;
+
+ return ((s << 16) | (r));
+}
+
+/**
+ \brief Quad 8-bit signed addition with halved results.
+ \details This function enables you to perform four signed 8-bit integer subtractions, halving the results.
+ \param [in] x first four 8-bit summands.
+ \param [in] y second four 8-bit summands.
+ \return the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n
+ the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n
+ the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n
+ the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value.
+ \remark
+ res[7:0] = (val1[7:0] - val2[7:0] ) >> 1 \n
+ res[15:8] = (val1[15:8] - val2[15:8] ) >> 1 \n
+ res[23:16] = (val1[23:16] - val2[23:16]) >> 1 \n
+ res[31:24] = (val1[31:24] - val2[31:24]) >> 1
+ */
+__ALWAYS_INLINE uint32_t __SHSUB8(uint32_t x, uint32_t y)
+{
+ int32_t r, s, t, u;
+
+ r = (((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF;
+ s = (((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF;
+ t = (((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)) >> 1) & (int32_t)0x000000FF;
+ u = (((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF;
+
+ return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r)));
+}
+
+/**
+ \brief Quad 8-bit unsigned subtraction with halved results.
+ \details This function enables you to perform four unsigned 8-bit integer subtractions, halving the results.
+ \param [in] x first four 8-bit summands.
+ \param [in] y second four 8-bit summands.
+ \return the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n
+ the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n
+ the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n
+ the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value.
+ \remark
+ res[7:0] = (val1[7:0] - val2[7:0] ) >> 1 \n
+ res[15:8] = (val1[15:8] - val2[15:8] ) >> 1 \n
+ res[23:16] = (val1[23:16] - val2[23:16]) >> 1 \n
+ res[31:24] = (val1[31:24] - val2[31:24]) >> 1
+ */
+__ALWAYS_INLINE uint32_t __UHSUB8(uint32_t x, uint32_t y)
+{
+ int32_t r, s, t, u;
+
+ r = ((((x << 24) >> 24) - ((y << 24) >> 24)) >> 1) & 0x000000FF;
+ s = ((((x << 16) >> 24) - ((y << 16) >> 24)) >> 1) & 0x000000FF;
+ t = ((((x << 8) >> 24) - ((y << 8) >> 24)) >> 1) & 0x000000FF;
+ u = ((((x) >> 24) - ((y) >> 24)) >> 1) & 0x000000FF;
+
+ return ((u << 24) | (t << 16) | (s << 8) | (r));
+}
+
+/**
+ \brief Dual 16-bit add and subtract with exchange.
+ \details This function enables you to exchange the halfwords of the one operand,
+ then add the high halfwords and subtract the low halfwords,
+ saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+ \param [in] x first operand for the subtraction in the low halfword,
+ and the first operand for the addition in the high halfword.
+ \param [in] y second operand for the subtraction in the high halfword,
+ and the second operand for the addition in the low halfword.
+ \return the saturated subtraction of the high halfword in the second operand from the
+ low halfword in the first operand, in the low halfword of the return value.\n
+ the saturated addition of the high halfword in the first operand and the
+ low halfword in the second operand, in the high halfword of the return value.\n
+ The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+ \remark
+ res[15:0] = val1[15:0] - val2[31:16] \n
+ res[31:16] = val1[31:16] + val2[15:0]
+ */
+__ALWAYS_INLINE uint32_t __QASX(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF;
+ s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+ \brief Dual 16-bit unsigned saturating addition and subtraction with exchange.
+ \details This function enables you to exchange the halfwords of the second operand and
+ perform one unsigned 16-bit integer addition and one unsigned 16-bit subtraction,
+ saturating the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1.
+ \param [in] x first operand for the subtraction in the low halfword,
+ and the first operand for the addition in the high halfword.
+ \param [in] y second operand for the subtraction in the high halfword,
+ and the second operand for the addition in the low halfword.
+ \return the saturated subtraction of the high halfword in the second operand from the
+ low halfword in the first operand, in the low halfword of the return value.\n
+ the saturated addition of the high halfword in the first operand and the
+ low halfword in the second operand, in the high halfword of the return value.\n
+ The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1.
+ \remark
+ res[15:0] = val1[15:0] - val2[31:16] \n
+ res[31:16] = val1[31:16] + val2[15:0]
+ */
+__ALWAYS_INLINE uint32_t __UQASX(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = __IUSAT((((x << 16) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF;
+ s = __IUSAT((((x) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF;
+
+ return ((s << 16) | (r));
+}
+
+/**
+ \brief Dual 16-bit addition and subtraction with exchange.
+ \details It enables you to exchange the halfwords of the second operand, add the high halfwords
+ and subtract the low halfwords.
+ \param [in] x first operand for the subtraction in the low halfword,
+ and the first operand for the addition in the high halfword.
+ \param [in] y second operand for the subtraction in the high halfword,
+ and the second operand for the addition in the low halfword.
+ \return the subtraction of the high halfword in the second operand from the
+ low halfword in the first operand, in the low halfword of the return value.\n
+ the addition of the high halfword in the first operand and the
+ low halfword in the second operand, in the high halfword of the return value.
+ \remark
+ res[15:0] = val1[15:0] - val2[31:16] \n
+ res[31:16] = val1[31:16] + val2[15:0]
+ */
+__ALWAYS_INLINE uint32_t __SASX(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = ((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF;
+ s = ((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+ \brief Dual 16-bit unsigned addition and subtraction with exchange.
+ \details This function enables you to exchange the two halfwords of the second operand,
+ add the high halfwords and subtract the low halfwords.
+ \param [in] x first operand for the subtraction in the low halfword,
+ and the first operand for the addition in the high halfword.
+ \param [in] y second operand for the subtraction in the high halfword,
+ and the second operand for the addition in the low halfword.
+ \return the subtraction of the high halfword in the second operand from the
+ low halfword in the first operand, in the low halfword of the return value.\n
+ the addition of the high halfword in the first operand and the
+ low halfword in the second operand, in the high halfword of the return value.
+ \remark
+ res[15:0] = val1[15:0] - val2[31:16] \n
+ res[31:16] = val1[31:16] + val2[15:0]
+ */
+__ALWAYS_INLINE uint32_t __UASX(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = (((x << 16) >> 16) - ((y) >> 16)) & 0x0000FFFF;
+ s = (((x) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF;
+
+ return ((s << 16) | (r));
+}
+
+/**
+ \brief Dual 16-bit signed addition and subtraction with halved results.
+ \details This function enables you to exchange the two halfwords of one operand, perform one
+ signed 16-bit integer addition and one signed 16-bit subtraction, and halve the results.
+ \param [in] x first 16-bit operands.
+ \param [in] y second 16-bit operands.
+ \return the halved subtraction of the high halfword in the second operand from the
+ low halfword in the first operand, in the low halfword of the return value.\n
+ the halved addition of the low halfword in the second operand from the high
+ halfword in the first operand, in the high halfword of the return value.
+ \remark
+ res[15:0] = (val1[15:0] - val2[31:16]) >> 1 \n
+ res[31:16] = (val1[31:16] + val2[15:0]) >> 1
+ */
+__ALWAYS_INLINE uint32_t __SHASX(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = (((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+ s = (((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+ \brief Dual 16-bit unsigned addition and subtraction with halved results and exchange.
+ \details This function enables you to exchange the halfwords of the second operand,
+ add the high halfwords and subtract the low halfwords, halving the results.
+ \param [in] x first operand for the subtraction in the low halfword, and
+ the first operand for the addition in the high halfword.
+ \param [in] y second operand for the subtraction in the high halfword, and
+ the second operand for the addition in the low halfword.
+ \return the halved subtraction of the high halfword in the second operand from the
+ low halfword in the first operand, in the low halfword of the return value.\n
+ the halved addition of the low halfword in the second operand from the high
+ halfword in the first operand, in the high halfword of the return value.
+ \remark
+ res[15:0] = (val1[15:0] - val2[31:16]) >> 1 \n
+ res[31:16] = (val1[31:16] + val2[15:0]) >> 1
+ */
+__ALWAYS_INLINE uint32_t __UHASX(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = ((((x << 16) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF;
+ s = ((((x) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF;
+
+ return ((s << 16) | (r));
+}
+
+/**
+ \brief Dual 16-bit subtract and add with exchange.
+ \details This function enables you to exchange the halfwords of one operand,
+ then subtract the high halfwords and add the low halfwords,
+ saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+ \param [in] x first operand for the addition in the low halfword,
+ and the first operand for the subtraction in the high halfword.
+ \param [in] y second operand for the addition in the high halfword,
+ and the second operand for the subtraction in the low halfword.
+ \return the saturated addition of the low halfword of the first operand and the high
+ halfword of the second operand, in the low halfword of the return value.\n
+ the saturated subtraction of the low halfword of the second operand from the
+ high halfword of the first operand, in the high halfword of the return value.\n
+ The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1.
+ \remark
+ res[15:0] = val1[15:0] + val2[31:16] \n
+ res[31:16] = val1[31:16] - val2[15:0]
+ */
+__ALWAYS_INLINE uint32_t __QSAX(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF;
+ s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+ \brief Dual 16-bit unsigned saturating subtraction and addition with exchange.
+ \details This function enables you to exchange the halfwords of the second operand and perform
+ one unsigned 16-bit integer subtraction and one unsigned 16-bit addition, saturating
+ the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1.
+ \param [in] x first operand for the addition in the low halfword,
+ and the first operand for the subtraction in the high halfword.
+ \param [in] y second operand for the addition in the high halfword,
+ and the second operand for the subtraction in the low halfword.
+ \return the saturated addition of the low halfword of the first operand and the high
+ halfword of the second operand, in the low halfword of the return value.\n
+ the saturated subtraction of the low halfword of the second operand from the
+ high halfword of the first operand, in the high halfword of the return value.\n
+ The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1.
+ \remark
+ res[15:0] = val1[15:0] + val2[31:16] \n
+ res[31:16] = val1[31:16] - val2[15:0]
+ */
+__ALWAYS_INLINE uint32_t __UQSAX(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = __IUSAT((((x << 16) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF;
+ s = __IUSAT((((x) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF;
+
+ return ((s << 16) | (r));
+}
+
+/**
+ \brief Dual 16-bit unsigned subtract and add with exchange.
+ \details This function enables you to exchange the halfwords of the second operand,
+ subtract the high halfwords and add the low halfwords.
+ \param [in] x first operand for the addition in the low halfword,
+ and the first operand for the subtraction in the high halfword.
+ \param [in] y second operand for the addition in the high halfword,
+ and the second operand for the subtraction in the low halfword.
+ \return the addition of the low halfword of the first operand and the high
+ halfword of the second operand, in the low halfword of the return value.\n
+ the subtraction of the low halfword of the second operand from the
+ high halfword of the first operand, in the high halfword of the return value.\n
+ \remark
+ res[15:0] = val1[15:0] + val2[31:16] \n
+ res[31:16] = val1[31:16] - val2[15:0]
+ */
+__ALWAYS_INLINE uint32_t __USAX(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = (((x << 16) >> 16) + ((y) >> 16)) & 0x0000FFFF;
+ s = (((x) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF;
+
+ return ((s << 16) | (r));
+}
+
+/**
+ \brief Dual 16-bit signed subtraction and addition with exchange.
+ \details This function enables you to exchange the two halfwords of one operand and perform one
+ 16-bit integer subtraction and one 16-bit addition.
+ \param [in] x first operand for the addition in the low halfword, and the first operand
+ for the subtraction in the high halfword.
+ \param [in] y second operand for the addition in the high halfword, and the second
+ operand for the subtraction in the low halfword.
+ \return the addition of the low halfword of the first operand and the high
+ halfword of the second operand, in the low halfword of the return value.\n
+ the subtraction of the low halfword of the second operand from the
+ high halfword of the first operand, in the high halfword of the return value.\n
+ \remark
+ res[15:0] = val1[15:0] + val2[31:16] \n
+ res[31:16] = val1[31:16] - val2[15:0]
+ */
+__ALWAYS_INLINE uint32_t __SSAX(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = ((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF;
+ s = ((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r)));
+}
+
+
+/**
+ \brief Dual 16-bit signed subtraction and addition with halved results.
+ \details This function enables you to exchange the two halfwords of one operand, perform one signed
+ 16-bit integer subtraction and one signed 16-bit addition, and halve the results.
+ \param [in] x first 16-bit operands.
+ \param [in] y second 16-bit operands.
+ \return the halved addition of the low halfword in the first operand and the
+ high halfword in the second operand, in the low halfword of the return value.\n
+ the halved subtraction of the low halfword in the second operand from the
+ high halfword in the first operand, in the high halfword of the return value.
+ \remark
+ res[15:0] = (val1[15:0] + val2[31:16]) >> 1 \n
+ res[31:16] = (val1[31:16] - val2[15:0]) >> 1
+ */
+__ALWAYS_INLINE uint32_t __SHSAX(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = (((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+ s = (((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r)));
+}
+
+/**
+ \brief Dual 16-bit unsigned subtraction and addition with halved results and exchange.
+ \details This function enables you to exchange the halfwords of the second operand,
+ subtract the high halfwords and add the low halfwords, halving the results.
+ \param [in] x first operand for the addition in the low halfword, and
+ the first operand for the subtraction in the high halfword.
+ \param [in] y second operand for the addition in the high halfword, and
+ the second operand for the subtraction in the low halfword.
+ \return the halved addition of the low halfword in the first operand and the
+ high halfword in the second operand, in the low halfword of the return value.\n
+ the halved subtraction of the low halfword in the second operand from the
+ high halfword in the first operand, in the high halfword of the return value.
+ \remark
+ res[15:0] = (val1[15:0] + val2[31:16]) >> 1 \n
+ res[31:16] = (val1[31:16] - val2[15:0]) >> 1
+ */
+__ALWAYS_INLINE uint32_t __UHSAX(uint32_t x, uint32_t y)
+{
+ int32_t r, s;
+
+ r = ((((x << 16) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF;
+ s = ((((x) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF;
+
+ return ((s << 16) | (r));
+}
+
+/**
+ \brief Dual 16-bit signed multiply with exchange returning difference.
+ \details This function enables you to perform two 16-bit signed multiplications, subtracting
+ one of the products from the other. The halfwords of the second operand are exchanged
+ before performing the arithmetic. This produces top * bottom and bottom * top multiplication.
+ \param [in] x first 16-bit operands for each multiplication.
+ \param [in] y second 16-bit operands for each multiplication.
+ \return the difference of the products of the two 16-bit signed multiplications.
+ \remark
+ p1 = val1[15:0] * val2[31:16] \n
+ p2 = val1[31:16] * val2[15:0] \n
+ res[31:0] = p1 - p2
+ */
+__ALWAYS_INLINE uint32_t __SMUSDX(uint32_t x, uint32_t y)
+{
+ return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) -
+ ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16))));
+}
+
+/**
+ \brief Sum of dual 16-bit signed multiply with exchange.
+ \details This function enables you to perform two 16-bit signed multiplications with exchanged
+ halfwords of the second operand, adding the products together.
+ \param [in] x first 16-bit operands for each multiplication.
+ \param [in] y second 16-bit operands for each multiplication.
+ \return the sum of the products of the two 16-bit signed multiplications with exchanged halfwords of the second operand.
+ \remark
+ p1 = val1[15:0] * val2[31:16] \n
+ p2 = val1[31:16] * val2[15:0] \n
+ res[31:0] = p1 + p2
+ */
+__ALWAYS_INLINE uint32_t __SMUADX(uint32_t x, uint32_t y)
+{
+ return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) +
+ ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16))));
+}
+
+
+/**
+ \brief Saturating add.
+ \details This function enables you to obtain the saturating add of two integers.
+ \param [in] x first summand of the saturating add operation.
+ \param [in] y second summand of the saturating add operation.
+ \return the saturating addition of val1 and val2.
+ \remark
+ res[31:0] = SAT(val1 + SAT(val2))
+ */
+__ALWAYS_INLINE int32_t __QADD(int32_t x, int32_t y)
+{
+ int32_t result;
+
+ if (y >= 0)
+ {
+ if (x + y >= x)
+ {
+ result = x + y;
+ }
+ else
+ {
+ result = 0x7FFFFFFF;
+ }
+ }
+ else
+ {
+ if (x + y < x)
+ {
+ result = x + y;
+ }
+ else
+ {
+ result = 0x80000000;
+ }
+ }
+
+ return result;
+}
+
+/**
+ \brief Saturating subtract.
+ \details This function enables you to obtain the saturating add of two integers.
+ \param [in] x first summand of the saturating add operation.
+ \param [in] y second summand of the saturating add operation.
+ \return the saturating addition of val1 and val2.
+ \remark
+ res[31:0] = SAT(val1 + SAT(val2))
+ */
+__ALWAYS_INLINE int32_t __QSUB(int32_t x, int32_t y)
+{
+ int64_t tmp;
+ int32_t result;
+
+ tmp = (int64_t)x - (int64_t)y;
+
+ if (tmp > 0x7fffffff)
+ {
+ tmp = 0x7fffffff;
+ }
+ else if (tmp < (-2147483647 - 1))
+ {
+ tmp = -2147483647 - 1;
+ }
+
+ result = tmp;
+ return result;
+}
+
+/**
+ \brief Dual 16-bit signed multiply with single 32-bit accumulator.
+ \details This function enables you to perform two signed 16-bit multiplications,
+ adding both results to a 32-bit accumulate operand.
+ \param [in] x first 16-bit operands for each multiplication.
+ \param [in] y second 16-bit operands for each multiplication.
+ \param [in] sum accumulate value.
+ \return the product of each multiplication added to the accumulate value, as a 32-bit integer.
+ \remark
+ p1 = val1[15:0] * val2[15:0] \n
+ p2 = val1[31:16] * val2[31:16] \n
+ res[31:0] = p1 + p2 + val3[31:0]
+ */
+__ALWAYS_INLINE uint32_t __SMLAD(uint32_t x, uint32_t y, uint32_t sum)
+{
+ return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) +
+ ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) +
+ (((int32_t)sum))));
+}
+
+/**
+ \brief Pre-exchanged dual 16-bit signed multiply with single 32-bit accumulator.
+ \details This function enables you to perform two signed 16-bit multiplications with exchanged
+ halfwords of the second operand, adding both results to a 32-bit accumulate operand.
+ \param [in] x first 16-bit operands for each multiplication.
+ \param [in] y second 16-bit operands for each multiplication.
+ \param [in] sum accumulate value.
+ \return the product of each multiplication with exchanged halfwords of the second
+ operand added to the accumulate value, as a 32-bit integer.
+ \remark
+ p1 = val1[15:0] * val2[31:16] \n
+ p2 = val1[31:16] * val2[15:0] \n
+ res[31:0] = p1 + p2 + val3[31:0]
+ */
+__ALWAYS_INLINE uint32_t __SMLADX(uint32_t x, uint32_t y, uint32_t sum)
+{
+ return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) +
+ ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) +
+ (((int32_t)sum))));
+}
+
+/**
+ \brief Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate.
+ \details This function enables you to perform two 16-bit signed multiplications, take the
+ difference of the products, subtracting the high halfword product from the low
+ halfword product, and add the difference to a 32-bit accumulate operand.
+ \param [in] x first 16-bit operands for each multiplication.
+ \param [in] y second 16-bit operands for each multiplication.
+ \param [in] sum accumulate value.
+ \return the difference of the product of each multiplication, added to the accumulate value.
+ \remark
+ p1 = val1[15:0] * val2[15:0] \n
+ p2 = val1[31:16] * val2[31:16] \n
+ res[31:0] = p1 - p2 + val3[31:0]
+ */
+__ALWAYS_INLINE uint32_t __SMLSD(uint32_t x, uint32_t y, uint32_t sum)
+{
+ return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) -
+ ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) +
+ (((int32_t)sum))));
+}
+
+/**
+ \brief Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate.
+ \details This function enables you to exchange the halfwords in the second operand, then perform two 16-bit
+ signed multiplications. The difference of the products is added to a 32-bit accumulate operand.
+ \param [in] x first 16-bit operands for each multiplication.
+ \param [in] y second 16-bit operands for each multiplication.
+ \param [in] sum accumulate value.
+ \return the difference of the product of each multiplication, added to the accumulate value.
+ \remark
+ p1 = val1[15:0] * val2[31:16] \n
+ p2 = val1[31:16] * val2[15:0] \n
+ res[31:0] = p1 - p2 + val3[31:0]
+ */
+__ALWAYS_INLINE uint32_t __SMLSDX(uint32_t x, uint32_t y, uint32_t sum)
+{
+ return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) -
+ ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) +
+ (((int32_t)sum))));
+}
+
+/**
+ \brief Dual 16-bit signed multiply with single 64-bit accumulator.
+ \details This function enables you to perform two signed 16-bit multiplications, adding both results
+ to a 64-bit accumulate operand. Overflow is only possible as a result of the 64-bit addition.
+ This overflow is not detected if it occurs. Instead, the result wraps around modulo2^64.
+ \param [in] x first 16-bit operands for each multiplication.
+ \param [in] y second 16-bit operands for each multiplication.
+ \param [in] sum accumulate value.
+ \return the product of each multiplication added to the accumulate value.
+ \remark
+ p1 = val1[15:0] * val2[15:0] \n
+ p2 = val1[31:16] * val2[31:16] \n
+ sum = p1 + p2 + val3[63:32][31:0] \n
+ res[63:32] = sum[63:32] \n
+ res[31:0] = sum[31:0]
+ */
+__ALWAYS_INLINE uint64_t __SMLALD(uint32_t x, uint32_t y, uint64_t sum)
+{
+ return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) +
+ ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) +
+ (((uint64_t)sum))));
+}
+
+/**
+ \brief Dual 16-bit signed multiply with exchange with single 64-bit accumulator.
+ \details This function enables you to exchange the halfwords of the second operand, and perform two
+ signed 16-bit multiplications, adding both results to a 64-bit accumulate operand. Overflow
+ is only possible as a result of the 64-bit addition. This overflow is not detected if it occurs.
+ Instead, the result wraps around modulo2^64.
+ \param [in] x first 16-bit operands for each multiplication.
+ \param [in] y second 16-bit operands for each multiplication.
+ \param [in] sum accumulate value.
+ \return the product of each multiplication added to the accumulate value.
+ \remark
+ p1 = val1[15:0] * val2[31:16] \n
+ p2 = val1[31:16] * val2[15:0] \n
+ sum = p1 + p2 + val3[63:32][31:0] \n
+ res[63:32] = sum[63:32] \n
+ res[31:0] = sum[31:0]
+ */
+__ALWAYS_INLINE uint64_t __SMLALDX(uint32_t x, uint32_t y, uint64_t sum)
+{
+ return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) +
+ ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) +
+ (((uint64_t)sum))));
+}
+
+/**
+ \brief dual 16-bit signed multiply subtract with 64-bit accumulate.
+ \details This function It enables you to perform two 16-bit signed multiplications, take the difference
+ of the products, subtracting the high halfword product from the low halfword product, and add the
+ difference to a 64-bit accumulate operand. Overflow cannot occur during the multiplications or the
+ subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow is not
+ detected. Instead, the result wraps round to modulo2^64.
+ \param [in] x first 16-bit operands for each multiplication.
+ \param [in] y second 16-bit operands for each multiplication.
+ \param [in] sum accumulate value.
+ \return the difference of the product of each multiplication, added to the accumulate value.
+ \remark
+ p1 = val1[15:0] * val2[15:0] \n
+ p2 = val1[31:16] * val2[31:16] \n
+ res[63:0] = p1 - p2 + val3[63:0]
+ */
+__ALWAYS_INLINE uint64_t __SMLSLD(uint32_t x, uint32_t y, uint64_t sum)
+{
+ return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) -
+ ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) +
+ (((uint64_t)sum))));
+}
+
+/**
+ \brief Dual 16-bit signed multiply with exchange subtract with 64-bit accumulate.
+ \details This function enables you to exchange the halfwords of the second operand, perform two 16-bit multiplications,
+ adding the difference of the products to a 64-bit accumulate operand. Overflow cannot occur during the
+ multiplications or the subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow
+ is not detected. Instead, the result wraps round to modulo2^64.
+ \param [in] x first 16-bit operands for each multiplication.
+ \param [in] y second 16-bit operands for each multiplication.
+ \param [in] sum accumulate value.
+ \return the difference of the product of each multiplication, added to the accumulate value.
+ \remark
+ p1 = val1[15:0] * val2[31:16] \n
+ p2 = val1[31:16] * val2[15:0] \n
+ res[63:0] = p1 - p2 + val3[63:0]
+ */
+__ALWAYS_INLINE uint64_t __SMLSLDX(uint32_t x, uint32_t y, uint64_t sum)
+{
+ return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) -
+ ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) +
+ (((uint64_t)sum))));
+}
+
+/**
+ \brief 32-bit signed multiply with 32-bit truncated accumulator.
+ \details This function enables you to perform a signed 32-bit multiplications, adding the most
+ significant 32 bits of the 64-bit result to a 32-bit accumulate operand.
+ \param [in] x first operand for multiplication.
+ \param [in] y second operand for multiplication.
+ \param [in] sum accumulate value.
+ \return the product of multiplication (most significant 32 bits) is added to the accumulate value, as a 32-bit integer.
+ \remark
+ p = val1 * val2 \n
+ res[31:0] = p[61:32] + val3[31:0]
+ */
+__ALWAYS_INLINE uint32_t __SMMLA(int32_t x, int32_t y, int32_t sum)
+{
+ return (uint32_t)((int32_t)((int64_t)((int64_t)x * (int64_t)y) >> 32) + sum);
+}
+
+/**
+ \brief Sum of dual 16-bit signed multiply.
+ \details This function enables you to perform two 16-bit signed multiplications, adding the products together.
+ \param [in] x first 16-bit operands for each multiplication.
+ \param [in] y second 16-bit operands for each multiplication.
+ \return the sum of the products of the two 16-bit signed multiplications.
+ \remark
+ p1 = val1[15:0] * val2[15:0] \n
+ p2 = val1[31:16] * val2[31:16] \n
+ res[31:0] = p1 + p2
+ */
+__ALWAYS_INLINE uint32_t __SMUAD(uint32_t x, uint32_t y)
+{
+ return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) +
+ ((((int32_t)x) >> 16) * (((int32_t)y) >> 16))));
+}
+
+/**
+ \brief Dual 16-bit signed multiply returning difference.
+ \details This function enables you to perform two 16-bit signed multiplications, taking the difference
+ of the products by subtracting the high halfword product from the low halfword product.
+ \param [in] x first 16-bit operands for each multiplication.
+ \param [in] y second 16-bit operands for each multiplication.
+ \return the difference of the products of the two 16-bit signed multiplications.
+ \remark
+ p1 = val1[15:0] * val2[15:0] \n
+ p2 = val1[31:16] * val2[31:16] \n
+ res[31:0] = p1 - p2
+ */
+__ALWAYS_INLINE uint32_t __SMUSD(uint32_t x, uint32_t y)
+{
+ return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) -
+ ((((int32_t)x) >> 16) * (((int32_t)y) >> 16))));
+}
+
+/**
+ \brief Dual extracted 8-bit to 16-bit signed addition.
+ \details This function enables you to extract two 8-bit values from the second operand (at bit positions
+ [7:0] and [23:16]), sign-extend them to 16-bits each, and add the results to the first operand.
+ \param [in] x values added to the sign-extended to 16-bit values.
+ \param [in] y two 8-bit values to be extracted and sign-extended.
+ \return the addition of val1 and val2, where the 8-bit values in val2[7:0] and
+ val2[23:16] have been extracted and sign-extended prior to the addition.
+ \remark
+ res[15:0] = val1[15:0] + SignExtended(val2[7:0]) \n
+ res[31:16] = val1[31:16] + SignExtended(val2[23:16])
+ */
+__ALWAYS_INLINE uint32_t __SXTAB16(uint32_t x, uint32_t y)
+{
+ return ((uint32_t)((((((int32_t)y << 24) >> 24) + (((int32_t)x << 16) >> 16)) & (int32_t)0x0000FFFF) |
+ (((((int32_t)y << 8) >> 8) + (((int32_t)x >> 16) << 16)) & (int32_t)0xFFFF0000)));
+}
+
+/**
+ \brief Extracted 16-bit to 32-bit unsigned addition.
+ \details This function enables you to extract two 8-bit values from one operand, zero-extend
+ them to 16 bits each, and add the results to two 16-bit values from another operand.
+ \param [in] x values added to the zero-extended to 16-bit values.
+ \param [in] y two 8-bit values to be extracted and zero-extended.
+ \return the addition of val1 and val2, where the 8-bit values in val2[7:0] and
+ val2[23:16] have been extracted and zero-extended prior to the addition.
+ \remark
+ res[15:0] = ZeroExt(val2[7:0] to 16 bits) + val1[15:0] \n
+ res[31:16] = ZeroExt(val2[31:16] to 16 bits) + val1[31:16]
+ */
+__ALWAYS_INLINE uint32_t __UXTAB16(uint32_t x, uint32_t y)
+{
+ return ((uint32_t)(((((y << 24) >> 24) + ((x << 16) >> 16)) & 0x0000FFFF) |
+ ((((y << 8) >> 8) + ((x >> 16) << 16)) & 0xFFFF0000)));
+}
+
+/**
+ \brief Dual extract 8-bits and sign extend each to 16-bits.
+ \details This function enables you to extract two 8-bit values from an operand and sign-extend them to 16 bits each.
+ \param [in] x two 8-bit values in val[7:0] and val[23:16] to be sign-extended.
+ \return the 8-bit values sign-extended to 16-bit values.\n
+ sign-extended value of val[7:0] in the low halfword of the return value.\n
+ sign-extended value of val[23:16] in the high halfword of the return value.
+ \remark
+ res[15:0] = SignExtended(val[7:0]) \n
+ res[31:16] = SignExtended(val[23:16])
+ */
+__ALWAYS_INLINE uint32_t __SXTB16(uint32_t x)
+{
+ return ((uint32_t)(((((int32_t)x << 24) >> 24) & (int32_t)0x0000FFFF) |
+ ((((int32_t)x << 8) >> 8) & (int32_t)0xFFFF0000)));
+}
+
+/**
+ \brief Dual extract 8-bits and zero-extend to 16-bits.
+ \details This function enables you to extract two 8-bit values from an operand and zero-extend them to 16 bits each.
+ \param [in] x two 8-bit values in val[7:0] and val[23:16] to be zero-extended.
+ \return the 8-bit values sign-extended to 16-bit values.\n
+ sign-extended value of val[7:0] in the low halfword of the return value.\n
+ sign-extended value of val[23:16] in the high halfword of the return value.
+ \remark
+ res[15:0] = SignExtended(val[7:0]) \n
+ res[31:16] = SignExtended(val[23:16])
+ */
+__ALWAYS_INLINE uint32_t __UXTB16(uint32_t x)
+{
+ return ((uint32_t)((((x << 24) >> 24) & 0x0000FFFF) |
+ (((x << 8) >> 8) & 0xFFFF0000)));
+}
+
+#endif /* _CSI_SIMD_H_ */
diff --git a/libcpu/mips/loongson_1c/cpuport.c b/libcpu/mips/loongson_1c/cpuport.c
index f4914dfec4..03fdc2a514 100644
--- a/libcpu/mips/loongson_1c/cpuport.c
+++ b/libcpu/mips/loongson_1c/cpuport.c
@@ -17,6 +17,8 @@
#include <rtthread.h>
#include "ls1c.h"
+register rt_uint32_t $GP __asm__ ("$28");
+
/**
* @addtogroup Loongson LS1B
*/
@@ -68,12 +70,15 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_ad
{
rt_uint32_t *stk;
static rt_uint32_t g_sr = 0;
+ static rt_uint32_t g_gp = 0;
if (g_sr == 0)
{
g_sr = cp0_get_status();
g_sr &= 0xfffffffe;
g_sr |= 0x8401;
+
+ g_gp = $GP;
}
/** Start at stack top */
@@ -87,7 +92,7 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_ad
*(--stk) = (rt_uint32_t) texit; /* ra */
*(--stk) = (rt_uint32_t) 0x0000001e; /* s8 */
*(--stk) = (rt_uint32_t) stack_addr; /* sp */
- *(--stk) = (rt_uint32_t) 0x0000001c; /* gp */
+ *(--stk) = (rt_uint32_t) g_gp; /* gp */
*(--stk) = (rt_uint32_t) 0x0000001b; /* k1 */
*(--stk) = (rt_uint32_t) 0x0000001a; /* k0 */
*(--stk) = (rt_uint32_t) 0x00000019; /* t9 */
diff --git a/libcpu/mips/loongson_1c/sdram_cfg.h b/libcpu/mips/loongson_1c/sdram_cfg.h
new file mode 100644
index 0000000000..3f88f26623
--- /dev/null
+++ b/libcpu/mips/loongson_1c/sdram_cfg.h
@@ -0,0 +1,85 @@
+
+#ifndef __OPENLOONGSON_SDRAM_CFG_H
+#define __OPENLOONGSON_SDRAM_CFG_H
+
+
+//#define SD_FREQ (6 * PLL_M) / (2 * SDRAM_PARAM_DIV_NUM)
+#define SD_FREQ (((APB_CLK / 4) * (PLL_MULT / CPU_DIV)) / SDRAM_PARAM_DIV_NUM)
+
+
+/* 颗粒行数 */
+#define ROW_1K 0x7
+#define ROW_2K 0x0
+#define ROW_4K 0x1
+#define ROW_8K 0x2
+#define ROW_16K 0x3
+/* 颗粒列数 */
+#define COL_256 0x7
+#define COL_512 0x0
+#define COL_1K 0x1
+#define COL_2K 0x2
+#define COL_4K 0x3
+/* 颗粒位宽 */
+#define WIDTH_8 0x0
+#define WIDTH_16 0x1
+#define WIDTH_32 0x2
+
+#define TRCD 3
+#define TCL 3
+#define TRP 3
+#define TRFC 8
+#define TRAS 6
+#define TREF 0x818
+#define TWR 2
+
+#define DEF_SEL 0x1
+#define DEF_SEL_N 0x0
+#define HANG_UP 0x1
+#define HANG_UP_N 0x0
+#define CFG_VALID 0x1
+
+
+#if 0
+// 白菜板8MB
+/*
+ 以型号为IS42S16400的SDRAM为例,
+ 物理参数为,
+ 容量:8MB
+ 位宽:16位
+ 列宽:8位,即2的8次方,即256
+ 行宽:12位,即2的12次方,即4K
+
+ 所以,
+ 颗粒的位宽=WIDTH_16
+ 颗粒的列数=COL_256
+ 颗粒的行数=ROW_4K
+
+ 再结合宏SD_PARA0和芯片手册中寄存器SD_CONFIG,相信一看就能明白
+ 替换宏SD_PARA0中的行宽、列宽和位宽
+*/
+#define SDRAM_WIDTH (WIDTH_16)
+#define SDRAM_COL (COL_256)
+#define SDRAM_ROW (ROW_4K)
+
+#else
+
+// 智龙32MByte
+#define SDRAM_WIDTH (WIDTH_16)
+#define SDRAM_COL (COL_512)
+#define SDRAM_ROW (ROW_8K)
+
+#endif
+
+#define SD_PARA0 (0x7f<<25 | \
+ (TRAS << 21) | \
+ (TRFC << 17) | (TRP << 14) | (TCL << 11) | \
+ (TRCD << 8) | (SDRAM_WIDTH << 6) | (SDRAM_COL << 3) | \
+ SDRAM_ROW)
+
+#define SD_PARA1 ((HANG_UP_N << 8) | (DEF_SEL_N << 7) | (TWR << 5) | (TREF >> 7))
+
+#define SD_PARA1_EN ((CFG_VALID << 9) | (HANG_UP_N << 8) | \
+ (DEF_SEL_N << 7) | (TWR << 5) | (TREF >> 7))
+
+
+#endif
diff --git a/libcpu/mips/loongson_1c/start_gcc.S b/libcpu/mips/loongson_1c/start_gcc.S
index fd98335671..4e71bc0524 100644
--- a/libcpu/mips/loongson_1c/start_gcc.S
+++ b/libcpu/mips/loongson_1c/start_gcc.S
@@ -15,6 +15,34 @@
#include "../common/mips.inc"
#include "../common/stackframe.h"
+#include "sdram_cfg.h"
+#include "cache.h"
+#include "rtconfig.h"
+
+#define SR_BOOT_EXC_VEC 0x00400000
+
+
+/* config pll div for cpu and sdram */
+#define PLL_MULT (0x54) // 晶振为24Mhz时,PLL=504Mhz
+#define SDRAM_DIV (0) // SDRAM为CPU的2分频
+#define CPU_DIV (2) // CPU为PLL的2分频
+
+ // 配置内存大小
+#define MEM_SIZE (0x02000000) // 32MByte
+
+ /* Delay macro */
+#define DELAY(count) \
+ li v0, count; \
+ 99: \
+ bnez v0, 99b;\
+ addiu v0, -1
+
+
+#define msize s2
+#define output_en s3
+
+
+
.section ".start", "ax"
.set noreorder
@@ -25,6 +53,8 @@ _start:
.set noreorder
la ra, _start
+#if !defined(RT_USING_SELF_BOOT)
+
/* disable interrupt */
mfc0 t0, CP0_STATUS
and t0, 0xfffffffe # By default it will be disabled.
@@ -57,6 +87,46 @@ _clr_bss_loop:
/* restart, never die */
j _start
nop
+
+#else
+
+ mtc0 zero, CP0_STATUS // 清零cp0 status寄存器
+ mtc0 zero, CP0_CAUSE // 清零cp0 cause寄存器
+
+ /*
+ 设置启动异常向量入口地址为ROM地址(0xbfc00000)
+ 将寄存器cp0 status的BEV置1,使CPU采用ROM(kseg1)空间的异常入口点
+ */
+ li t0, SR_BOOT_EXC_VEC /* Exception to Boostrap Location */
+ mtc0 t0, CP0_STATUS
+
+ /* setup stack pointer */
+ li sp, SYSTEM_STACK
+ la gp, _gp
+
+ /* initialize spi */
+ li t0, 0xbfe80000 //地址0xbfe80000为SPI0的寄存器基地址
+ li t1, 0x17 // div 4, fast_read + burst_en + memory_en double I/O 模式 部分SPI flash可能不支持
+ sb t1, 0x4(t0) // 设置寄存器sfc_param
+ li t1, 0x05
+ sb t1, 0x6(t0) // 设置寄存器sfc_timing
+
+ /* 设置sdram cs1复用关系,开发板使用ejtag_sel gpio_0引脚(第五复用)作为第二片sdram的片选
+ 注意sw2拨码开关的设置,使用ejtag烧录pmon时需要调整拨码开关,烧录完再调整回来 */
+ li a0, 0xbfd011c0
+ lw a1, 0x40(a0)
+ ori a1, 0x01
+ sw a1, 0x40(a0)
+
+
+ bal locate
+ nop
+
+ /* restart, never die */
+ j _start
+ nop
+#endif
+
.set reorder
.globl cp0_get_cause
@@ -83,6 +153,328 @@ cp0_get_lo:
jr ra
nop
+#if defined(RT_USING_SELF_BOOT)
+
+/****************************************LOCATE*********************************/
+
+/*
+ * We get here from executing a bal to get the PC value of the current execute
+ * location into ra. Check to see if we run from ROM or if this is ramloaded.
+ * 寄存器ra内保持着函数的返回地址,根据ra的值来判断当前是从ROM冷启动,还是从RAM热复位的
+ * ROM冷启动由通电引起,RAM热复位为各种异常引起,比如看门狗引起的复位等,
+ * 也就是RAM热复位之前CPU已经开始运行了
+ * 如果是从ROM冷启动,则寄存器ra的值为指令"bal locate"所在位置加8字节,大概在0xBFC00000附近
+ * 如果是从RAM热复位,则集成器ra的值为0x80xxxxxx
+ */
+locate:
+// la s0, uncached
+// subu s0, ra, s0
+ /*
+ * start.s的这段汇编程序在ROM(入口点为0xBFC00000)中运行
+ * 而编译链接时指定的起始地址是0x80100000,所以需要修正一下地址
+ * s0中保存着ra与start的差值,在后续的代码中可以起到修正地址的作用
+ * 在看看文件开始的时候,对寄存器s0用途的描述是“ link versus load offset, used to relocate absolute adresses”
+ * 除了修正地址外,还通过s0的值来判断是从ROM冷启动,还是从RAM热启动
+ */
+
+ la s0, _start // s0 = _start, 其中start的地址为编译链接时,指定的0x80010000
+ subu s0, ra, s0 // s0 = ra - s0,其中ra的值在ROM入口地址0xBFC00000附近
+ and s0, 0xffff0000 // s0 = s0 & 0xffff0000
+
+ /*
+ * 初始化cp0的status寄存器和cause寄存器
+ * 在异常引起的(从RAM)热复位后,需要重新初始化cp0的status和cause,
+ * 如果是从ROM冷启动的,那么前面已经初始化了,这里是再次重复初始化,没有影响的
+ */
+ li t0, SR_BOOT_EXC_VEC
+ mtc0 t0, CP0_CONFIG // 重新初始化cp0的status寄存器
+ mtc0 zero, CP0_CAUSE // 重新清零cp0的cause寄存器
+ .set noreorder
+
+ li t0, 0xbfe78030 // 地址0xbfe78030为PLL/SDRAM频率配置寄存器的地址
+ /* 设置PLL倍频 及SDRAM分频 */
+ li t2, (0x80000008 | (PLL_MULT << 8) | (0x3 << 2) | SDRAM_DIV)
+ /* 设置CPU分频 */
+ li t3, (0x00008003 | (CPU_DIV << 8))
+ /* 注意:首先需要把分频使能位清零 */
+ li t1, 0x2
+ sw t1, 0x4(t0) // 清零CPU_DIV_VALID,即disable
+ sw t2, 0x0(t0) // 写寄存器START_FREQ
+ sw t3, 0x4(t0) // 写寄存器CLK_DIV_PARAM
+ DELAY(2000)
+
+ /* 芯片上电默认使用gpio(输入模式)但大多时候是使用模块的功能,如lcd i2c spi ac97等
+ 所以这里把gpio都关闭,方便使用模块功能。如果上电后需要gpio输出一个确定电平,
+ 如继电器、LDE等,可以修改这里的代码。*/
+ /* disable all gpio */
+ li a0,0xbfd00000
+ sw zero,0x10c0(a0) /* disable gpio 0-31 */
+ sw zero,0x10c4(a0) /* disable gpio 32-63 */
+ sw zero,0x10c8(a0) /* disable gpio 64-95 */
+ sw zero,0x10cc(a0)
+
+ li t0, 0xffffffff
+ sw t0, 0x10d0(a0)
+ sw t0, 0x10d4(a0)
+ sw t0, 0x10d8(a0)
+ sw t0, 0x10dc(a0)
+
+ sw t0, 0x10f0(a0)
+ sw t0, 0x10f4(a0)
+ sw t0, 0x10f8(a0)
+ sw t0, 0x10fc(a0)
+
+
+ /* lcd soft_reset and panel config & timing */
+#ifdef DC_FB0
+/* li a0, 0xbc301240
+ li a1, 0x00100103
+ sw a1, 0x0(a0)
+ li a1, 0x00000103
+ sw a1, 0x0(a0) //soft_reset
+ li a1, 0x00100103
+ sw a1, 0x0(a0)
+
+ li a1, 0x80001111
+ sw a1, 0x180(a0) //panel config
+ li a1, 0x33333333
+ sw a1, 0x1a0(a0)*/
+#endif
+
+ li output_en, 0x1
+#ifdef FAST_STARTUP
+ li a1, 0x03000000
+ sw a1, 0x10c4(a0)
+ sw a1, 0x10d4(a0)
+ lw a2, 0x10e4(a0)
+ and a2, a1
+ beq a2, a1, get_pin_val_finish
+ nop
+ li output_en, 0x1
+
+get_pin_val_finish:
+
+#endif
+
+ /* Initializing. Standby... */
+ /*
+ * 根据s0的值判断是否为ROM冷启动
+ * 如果s0不等于0,则是ROM冷启动;如果等于0,则是RAM热复位
+ * 冷启动,则需要初始化内存,cache,加载代码到内存等
+ */
+ bnez s0, 1f // 如果寄存器s0不等于0,则说明是ROM冷启动,则跳转到下一个标号1处进行彻底初始化
+ nop
+ li a0, 128
+
+ jal rtthread_startup // 热复位,则直接跳转到函数main
+ nop
+1:
+
+/* use only 8wins */
+#define CPU_WIN_BASE 0xbfd00000
+#define CPU_WIN_MASK 0xbfd00040
+#define CPU_WIN_MMAP 0xbfd00080
+
+#define set_cpu_window(id, base, mask, mmap) \
+ li t0, CPU_WIN_BASE ; \
+ sw $0, 0x80+id*8(t0) ; \
+ li t1, base ; \
+ sw t1, 0x00+id*8(t0) ; \
+ sw $0, 0x04+id*8(t0) ; \
+ li t1, mask ; \
+ sw t1, 0x40+id*8(t0) ; \
+ sw $0, 0x44+id*8(t0) ; \
+ li t1, mmap ; \
+ sw t1, 0x80+id*8(t0) ; \
+ sw $0, 0x84+id*8(t0)
+
+/* fixup cpu window */
+cpu_win_fixup:
+ //
+ // hit = (paddr & mask) == (mmap & mask)
+ // mapped_addr = paddr &~mask | mmap & mask
+ //
+ // mmap[7] -> enable
+ // mmap[5] -> block trans enable
+ // mmap[4] -> cachable
+ // mmap[1:0] -> destination
+ //
+ // NOTE: the address windows has priority, win0 > win1 > ... > win7
+
+/* set_cpu_window(0, 0x1c280000, 0xfff80000, 0x1c280083) // camera 512K
+ set_cpu_window(1, 0x1c300000, 0xfff00000, 0x1c300081) // dc 1M
+ set_cpu_window(2, 0x1fe10000, 0xffffe000, 0x1fe10082) // gmac0 8K
+ set_cpu_window(3, 0x1fe10000, 0xffff0000, 0x1fe100d0) // gmac0 64K
+ set_cpu_window(4, 0x1f000000, 0xff000000, 0x1f000082) // AXIMUX 16M
+ set_cpu_window(5, 0x00000000, 0x00000000, 0x000000f0) // ddr 0
+ set_cpu_window(6, 0x00000000, 0x00000000, 0x000000f0) // ddr 0
+ set_cpu_window(7, 0x00000000, 0x00000000, 0x000000f0) // ddr 0*/
+
+/* set_cpu_window(0, 0x1c280000, 0xfff80000, 0x1c2800d3) // camera
+// set_cpu_window(1, 0x1fc00000, 0xfff00000, 0x1fc000f2) //
+ set_cpu_window(2, 0x1c300000, 0xfff00000, 0x1c3000d1) // dc 1M
+// set_cpu_window(3, 0x1f000000, 0xff000000, 0x1f0000d2) //
+ set_cpu_window(4, 0x00000000, 0x00000000, 0x000000f0)
+ set_cpu_window(5, 0x00000000, 0x00000000, 0x000000f0)
+ set_cpu_window(6, 0x00000000, 0x00000000, 0x000000f0) // ddr 0
+ set_cpu_window(7, 0x00000000, 0x00000000, 0x000000f0) // ddr 0*/
+
+ // after this fixup, the kernel code should be compiled with
+ // uncached instruction fetch patch
+
+ /* 配置内存 */
+ li msize, MEM_SIZE
+#if !defined(NAND_BOOT_EN)
+
+ /*
+ 手册建议,先写寄存器SD_CONFIG[31:0],然后再写寄存器的SD_CONFIG[63:32],
+ 即先写低32位,再写高32位。
+ 写三次寄存器,最后一次将最高位置一,即使能
+ */
+
+ // 写第一次
+ li t1, 0xbfd00410 // 寄存器SD_CONFIG[31:0]的地址为0xbfd00410
+ li a1, SD_PARA0 // 宏SD_PARA0在sdram_cfg.S中定义的
+ sw a1, 0x0(t1) // 将宏SD_PARA0的值写入寄存器SD_CONFIG[31:0]
+ li a1, SD_PARA1
+ sw a1, 0x4(t1) // 同理,将宏SD_PARA1的值写入寄存器SD_CONFIG[63:32]
+
+ // 写第二次
+ li a1, SD_PARA0
+ sw a1, 0x0(t1)
+ li a1, SD_PARA1
+ sw a1, 0x4(t1)
+
+ // 写第三次
+ li a1, SD_PARA0
+ sw a1, 0x0(t1)
+ li a1, SD_PARA1_EN // 使能
+ sw a1, 0x4(t1)
+// DELAY(100)
+#endif
+
+ /**************************************CACHE*****************************/
+
+#define CF_7_SE (1 << 3) /* Secondary cache enable */
+#define CF_7_SC (1 << 31) /* Secondary cache not present */
+#define CF_7_TE (1 << 12) /* Tertiary cache enable */
+#define CF_7_TC (1 << 17) /* Tertiary cache not present */
+#define CF_7_TS (3 << 20) /* Tertiary cache size */
+#define CF_7_TS_AL 20 /* Shift to align */
+#define NOP8 nop;nop;nop;nop;nop;nop;nop;nop
+
+do_caches:
+ /* Init caches... */
+ li s7, 0 /* no L2 cache */
+ li s8, 0 /* no L3 cache */
+
+ bal cache_init // 调用汇编函数cache_init
+ nop
+
+ mfc0 a0, CP0_CONFIG // 将协处理器0的config寄存器的值加载到寄存器a0
+ and a0, a0, ~((1<<12) | 7) // a0 = a0 & ~((1<<12) | 7)
+ or a0, a0, 2 // a0 |= 2
+ mtc0 a0, CP0_CONFIG // 将寄存器a0的值写入协处理器0的config寄存器
+
+/***********************MEMORY DEBUGGING AND COPY SELF TO RAM***********************/
+//#include "newtest.32/mydebug.S"
+bootnow:
+ /* copy program to sdram to make copy fast */
+ /* 先将执行拷贝pmon到内存任务的代码,拷贝到内存0xa0000000 */
+
+ /* 先确定需要拷贝的代码段为标号121到标号122之间的代码
+ * 由于链接时指定的起始地址是0x80010000,
+ * 而目前正在ROM(SPI NOR FLASH,起始地址为0xBFC00000)运行
+ * 所以需要用寄存器s0来修正一下地址
+ */
+ la t0, 121f // 将下一个标号121所在地址,加载到寄存器t0
+ addu t0, s0 // 使用寄存器s0修正t0中的(标号121的)地址
+ la t1, 122f // 将下一个标号122所在地址,加载到寄存器t1
+ addu t1, s0 // 使用寄存器s0修正t1中的(标号122的)地址
+
+ li t2, 0xa0000000 // 将立即数0xa0000000(起始地址)加载到寄存器t2
+1:
+ lw v0, (t0) // 将寄存器t0所指的内存地址开始4字节的数据加载到寄存器v0
+ sw v0, (t2) // 将寄存器v0的内容保存到寄存器t2所指的内存中
+ addu t0, 4 // 寄存器t0向后移4字节
+ addu t2, 4 // 寄存器t2向后移4字节
+ ble t0, t1, 1b // 如果t0 <= t1,则跳转到上一个标号1处,继续拷贝后面的4字节
+ nop
+
+ li t0, 0xa0000000 // 将立即数0xa0000000加载到寄存器t0
+ jr t0 // 跳转到起始地址0xa0000000处开始执行(拷贝任务)
+ nop
+
+121:
+ /* Copy PMON to execute location... */
+ /* 将固件拷贝到起始地址为0xa0010000的内存空间
+ 由于kseg0(0x8000 0000 - 0x9FFF FFFF)和kseg1(0xA000 0000 - 0xBFFF FFFF)是映射到物理内存的相同区域
+ 即拷贝到0xA000 0000开始的kseg1,就相当于拷贝到0x8000 0000开始的kseg0
+ 这就是为什么链接时,指定的地址是0x8001 0000,而拷贝的目标起始地址是0xA001 0000
+ */
+ la a0, _start // 加载符号start所在地址0x80010000加载到寄存器a0中
+ addu a1, a0, s0 // 使用寄存器s0修正寄存器a0中的地址,a1=0xBFC00000
+ la a2, __bss_start // 加载_edata(链接脚本中的一个符号)到寄存器a2
+ or a0, 0xa0000000 // a0 = a0 | 0xa0000000 = 0xa0010000
+ or a2, 0xa0000000 // a2 = a2 | 0xa0000000,修正地址_edata
+ subu t1, a2, a0 // t1 = a2 - a0,即计算从start到_edata之间的长度(字节数)
+ srl t1, t1, 2 // t1 >>= 2,即t1除以4。(和前面类似,每次拷贝4字节,所以除以4)
+ // 似乎t1计算结果没有被使用,马上就被后面的覆盖了
+
+ move t0, a0 // t0 = a0 = 0xa0010000 (目标起始地址)
+ move t1, a1 // t1 = a1 = 0xBFC00000 (start在ROM中的地址,源起始地址)
+ move t2, a2 // t2 = a2 (_edata在ROM中的地址,源结束地址)
+
+ /* copy text section */
+1: and t3, t0, 0x0000ffff // t3 = t0 & 0x0000ffff,取低16位
+ bnez t3, 2f // 如果t3不等于0,则跳转到下一个标号2处继续执行,t3的计算结果似乎没被使用,就被后面的覆盖了
+ nop
+2: lw t3, 0(t1) // 从源地址t1处加载4字节到寄存器t3中
+ nop
+ sw t3, 0(t0) // 将寄存器t3中的4字节数据保存到目标地址t0处
+ addu t0, 4 // 目标地址t0后移4字节
+ addu t1, 4 // 源地址t1 后移4字节
+ bne t2, t0, 1b // 如果t2不等于t0,则跳到上一个标号1处继续拷贝,总的来说就是判断拷贝是否结束
+ nop
+ /* copy text section done. */
+
+ /* clear bss */
+ la t0, __bss_start
+ la t1, __bss_end
+_clr_bss_loop:
+ sw zero, 0(t0)
+ bne t0, t1, _clr_bss_loop
+ addiu t0, t0, 4
+
+ /* disable interrupt */
+ mfc0 t0, CP0_STATUS
+ and t0, 0xfffffffe # By default it will be disabled.
+ mtc0 t0, CP0_STATUS # Set CPU to disable interrupt.
+ nop
+
+ /* disable cache */
+ mfc0 t0, CP0_CONFIG
+ and t0, 0xfffffff8
+ or t0, 0x2 # disable,!default value is not it!
+ mtc0 t0, CP0_CONFIG # Set CPU to disable cache.
+ nop
+
+ /* jump to RT-Thread RTOS */
+ jal rtthread_startup
+ nop
+
+ /* restart, never die */
+ j _start
+ nop
+
+
+122:
+
+stuck:
+ b stuck
+ nop
+#endif
+
.extern tlb_refill_handler
.extern cache_error_handler
diff --git a/libcpu/nds32/context_gcc.S b/libcpu/nds32/context_gcc.S
deleted file mode 100644
index 8d5f3287e9..0000000000
--- a/libcpu/nds32/context_gcc.S
+++ /dev/null
@@ -1,188 +0,0 @@
-#include "nds32.h"
-#include "os_cpu_common.h"
-#include "config.h"
-
- .align 4
-! void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
-! R0 --> from
-! R1 --> to
- .section .text
- .global rt_hw_context_switch_interrupt
- .global rt_hw_context_switch
-rt_hw_context_switch_interrupt:
-rt_hw_context_switch:
- push25 $r6,#8 ! {$r6, $fp, $gp, $lp}
-
- la $r2, rt_thread_switch_interrupt_flag
- lw $r3, [$r2]
- movi $r4, #1
- beq $r3, $r4, _reswitch
- sw $r4, [$r2] ! set rt_thread_switch_interrupt_flag to 1
-
- la $r2, rt_interrupt_from_thread
- sw $r0, [$r2] ! set rt_interrupt_from_thread
-_reswitch:
- la $r2, rt_interrupt_to_thread
- sw $r1, [$r2] ! set rt_interrupt_to_thread
- bal hal_intc_swi_trigger ! trigger the swi exception (causes context switch)
-
- pop25 $r6,#8 ! {$r6, $fp, $gp, $lp}
-
-! R0 --> switch from thread stack
-! R1 --> switch to thread stack
-! psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack
-
- .align 4
- .global OS_Trap_Interrupt_SWI
-OS_Trap_Interrupt_SWI:
-! pushm $r0, $r5
- setgie.d ! disable interrupt to protect context switch
- dsb
-
- IntlDescend ! Descend interrupt level
-
- movi $r0, 0x0
- mtsr $r0, $INT_PEND ! clean SWI pending
-
- la $r0, rt_thread_switch_interrupt_flag ! get rt_thread_switch_interrupt_flag
- lw $r1, [$r0]
- beqz $r1, pendsv_exit ! swi has already been handled
-
- movi $r1, #0
- sw $r1, [$r0] ! clear rt_thread_switch_interrupt_flag to 0
-
- la $r0, rt_interrupt_from_thread
- lw $r1, [$r0]
- beqz $r1, switch_to_thread ! skip register save at the first time(os startup phase)
-
- SAVE_ALL
-
- move $r1, $sp
- la $r0, rt_interrupt_from_thread
- lw $r0, [$r0]
- sw $r1, [$r0]
-
-switch_to_thread:
- la $r1, rt_interrupt_to_thread
- lw $r1, [$r1]
- lw $r1, [$r1] ! load thread stack pointer
- move $sp, $r1 ! update stack pointer
- RESTORE_ALL ! pop registers
-
-pendsv_exit:
- setgie.e
- iret
-
- .align 4
-! void rt_hw_context_switch_to(rt_uint32 to);
-! R0 --> to
- .global rt_hw_context_switch_to
-rt_hw_context_switch_to:
- la $r1, rt_interrupt_to_thread
- sw $r0, [$r1]
-
- ! set from thread to 0
- la $r1, rt_interrupt_from_thread
- movi $r0, #0
- sw $r0, [$r1]
-
- ! set interrupt flag to 1
- la $r1, rt_thread_switch_interrupt_flag
- movi $r0, #1
- sw $r0, [$r1]
-
- ! set the SWI exception priority(must be the lowest level)
- ! todo
-
- ! trigger the SWI exception (causes context switch)
- jal hal_intc_swi_trigger
-
- setgie.e ! enable interrupts at processor level
-
-1:
- b 1b ! never reach here
-
-#ifndef VECTOR_NUMINTRS
-#define VECTOR_NUMINTRS 32
-#endif
-
- .global OS_Trap_Int_Common
-
- ! Set up Interrupt vector ISR
- ! HW#IRQ_SWI_VECTOR : OS_Trap_Interrupt_SWI (SWI)
- ! HW#n : OS_Trap_Int_Common
-
- .macro SET_HWISR num
- .global OS_Trap_Interrupt_HW\num
- .if \num == IRQ_SWI_VECTOR
- .set OS_Trap_Interrupt_HW\num, OS_Trap_Interrupt_SWI
- .else
- .set OS_Trap_Interrupt_HW\num, OS_Trap_Int_Common
- .endif
- .endm
-
- .altmacro
- .set irqno, 0
- .rept VECTOR_NUMINTRS
- SET_HWISR %irqno
- .set irqno, irqno+1
- .endr
- .noaltmacro
-
-! .global OS_Trap_Int_Common
-OS_Trap_Int_Common:
-#ifdef MPU_SUPPORT
- mfsr $p1, $PSW
- ori $p1, $p1, (PSW_mskIT | PSW_mskDT)
- mtsr $p1, $PSW ! enable IT/DT
- dsb
- pushm $r0, $r5
- move $r0, $p0 ! IRQ number
-#endif
- ! $r0 : HW Interrupt vector number
- SAVE_CALLER
-
- IntlDescend ! Descend interrupt level
-
- mfsr $r1, $IPSW ! Use IPSW.CPL to check come from thread or ISR
- srli45 $r1, #PSW_offCPL
- fexti33 $r1, #0x2 ! IPSW.CPL
- bnec $r1, #0x7, 2f ! IPSW.CPL != 7, come form ISR, reentrant
-
- move $fp, $sp ! save old stack pointer
- la $sp, __OS_Int_Stack ! switch to interrupt stack
-2:
- setgie.e ! allow nested now
-
- ! The entire CPU state is now stashed on the stack,
- ! and the stack is also 8-byte alignment.
- ! We can call C program based interrupt handler now.
- la $r1, OS_CPU_Vector_Table
- lw $r1, [$r1+($r0<<2)] ! ISR function pointer
- jral $r1 ! Call ISR
-
- la $r1, __OS_Int_Stack ! Check for nested interruption return
- bne $r1, $sp, 3f ! $sp != __OS_Int_Stack?
-
- move $sp, $fp ! Move back to the thread stack
-3:
- RESTORE_CALLER
-
- iret
-
-! .set OS_Trap_Interrupt_HW9, OS_Trap_Interrupt_SWI
-! .set OS_Trap_Interrupt_HW19, OS_Trap_Int_Common
-
-!*********************************************
-! POINTERS TO VARIABLES
-!*********************************************
-#ifdef MPU_SUPPORT
- .section privileged_data
-#else
- .section .bss
-#endif
- .skip IRQ_STACK_SIZE
- .align 3
-__OS_Int_Stack:
-
- .end
diff --git a/libcpu/nds32/cpuport.c b/libcpu/nds32/cpuport.c
deleted file mode 100644
index af113f673b..0000000000
--- a/libcpu/nds32/cpuport.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * File : cpuport.c
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Change Logs:
- * Date Author Notes
- * 2017-08-25 Archer first version
- */
-
-#include <rtthread.h>
-
-#include "nds32.h"
-
-/*
- * Initialise the stack of a task to look exactly as if a call to
- * SAVE_CONTEXT had been called.
- *
- * See header file for description.
- *
- *
- * Stack Layout:
- * High |-----------------|
- * | $R5 |
- * |-----------------|
- * | . |
- * | . |
- * |-----------------|
- * | $R0 |
- * |-----------------|
- * | $R30 (LP) |
- * |-----------------|
- * | $R29 (GP) |
- * |-----------------|
- * | $R28 (FP) |
- * |-----------------|
- * | $R15 $R27 |
- * |-----------------|
- * | $R10 $R26 |
- * |-----------------|
- * | . |
- * | . |
- * |-----------------|
- * | $R6 |
- * |-----------------|
- * | $IFC_LP | (Option)
- * |-----------------|
- * | $LC/$LE/$LB | (Option)
- * | (ZOL) |
- * |-----------------|
- * | $IPSW |
- * |-----------------|
- * | $IPC |
- * |-----------------|
- * | Dummy word | (Option, only exist when IFC & ZOL both configured)
- * |-----------------|
- * | $FPU | (Option)
- * |-----------------|
- * Low
- *
- */
-
-struct stack_frame
-{
- rt_uint32_t topOfStack[34];
-};
-
-/* flag in interrupt handling */
-rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
-rt_uint32_t rt_thread_switch_interrupt_flag;
-/* exception hook */
-static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL;
-
-rt_base_t rt_hw_interrupt_disable(void)
-{
- rt_base_t level = __nds32__mfsr(NDS32_SR_PSW);
-
- GIE_DISABLE();
-
- return level;
-}
-
-void rt_hw_interrupt_enable(rt_base_t level)
-{
- if (level & PSW_mskGIE)
- GIE_ENABLE();
-}
-
-/* For relax support, must initial $gp at task init*/
-extern uint32_t _SDA_BASE_ __attribute__ ((weak));
-
-/**************************************************************
- * This function will initialize thread stack
- *
- * @param tentry the entry of thread
- * @param parameter the parameter of entry
- * @param stack_addr the beginning stack address
- * @param texit the function will be called when thread exit
- *
- * @return stack address
- **************************************************************/
-rt_uint8_t *rt_hw_stack_init(void *tentry,
- void *parameter,
- rt_uint8_t *stack_addr,
- void *texit)
-{
- rt_int32_t i;
- rt_uint32_t *pxTopOfStack;
-
- pxTopOfStack = (rt_uint32_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 4);
-
- /* Simulate the stack frame as it would be created by a context switch */
- /* R0 ~ R5 registers */
- for (i = 5; i >= 1; i--) /* R5, R4, R3, R2 and R1. */
- *--pxTopOfStack = (rt_uint32_t)0x01010101UL * i;
- *--pxTopOfStack = (rt_uint32_t)parameter; /* R0 : Argument */
-
- /* R6 ~ R30 registers */
- *--pxTopOfStack = (rt_uint32_t)texit; /* R30: $LP */
- *--pxTopOfStack = (rt_uint32_t)&_SDA_BASE_; /* R29: $GP */
- *--pxTopOfStack = (rt_uint32_t)0x2828282828; /* R28: $FP */
-#ifdef __NDS32_REDUCE_REGS__
- *--pxTopOfStack = (rt_uint32_t)0x1515151515; /* R15 */
- for (i = 10; i >= 6; i--) /* R10 ~ R6 */
- *--pxTopOfStack = (rt_uint32_t)0x01010101UL * i;
-#else
- for (i = 27; i >= 6; i--) /* R27 ~ R6 */
- *--pxTopOfStack = (rt_uint32_t)0x01010101UL * i;
-#endif
-
- /* IFC system register */
-#ifdef __TARGET_IFC_EXT
- *--pxTopOfStack = (rt_uint32_t)0x0; /* $IFC_LP */
-#endif
-
- /* ZOL system registers */
-#ifdef __TARGET_ZOL_EXT
- *--pxTopOfStack = (rt_uint32_t)0x0; /* $LC */
- *--pxTopOfStack = (rt_uint32_t)0x0; /* $LE */
- *--pxTopOfStack = (rt_uint32_t)0x0; /* $LB */
-#endif
-
- /* IPSW and IPC system registers */
- /* Default IPSW: enable GIE, set CPL to 7, clear IFCON */
- i = (__nds32__mfsr(NDS32_SR_PSW) | PSW_mskGIE | PSW_mskCPL) & ~PSW_mskIFCON;
- *--pxTopOfStack = (rt_uint32_t)i; /* $IPSW */
- *--pxTopOfStack = (rt_uint32_t)tentry; /* $IPC */
-
- /* Dummy word for 8-byte stack alignment */
-#if defined(__TARGET_IFC_EXT) && defined(__TARGET_ZOL_EXT)
- *--pxTopOfStack = (rt_uint32_t)0xFFFFFFFF; /* Dummy */
-#endif
-
- /* FPU registers */
-#ifdef __TARGET_FPU_EXT
- for (i = 0; i < FPU_REGS; i++)
- *--pxTopOfStack = (rt_uint32_t)0x0; /* FPU */
-#endif
-
- return (rt_uint8_t *)pxTopOfStack;
-}
-
-/**
- * This function set the hook, which is invoked on fault exception handling.
- *
- * @param exception_handle the exception handling hook function.
- */
-void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context))
-{
- rt_exception_hook = exception_handle;
-}
-
-#ifdef RT_USING_CPU_FFS
-/**
- * This function finds the first bit set (beginning with the least significant bit)
- * in value and return the index of that bit.
- *
- * Bits are numbered starting at 1 (the least significant bit). A return value of
- * zero from any of these functions means that the argument was zero.
- *
- * @return return the index of the first bit set. If value is 0, then this function
- * shall return 0.
- */
-#if defined(__GNUC__)
-int __rt_ffs(int value)
-{
- return __builtin_ffs(value);
-}
-#endif
-
-#endif
diff --git a/libcpu/risc-v/e310/SConscript b/libcpu/risc-v/e310/SConscript
new file mode 100644
index 0000000000..4e4bc0c3d9
--- /dev/null
+++ b/libcpu/risc-v/e310/SConscript
@@ -0,0 +1,13 @@
+Import('rtconfig')
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('*.c')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_gcc.S')
+
+group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/risc-v/e310/context_gcc.S b/libcpu/risc-v/e310/context_gcc.S
index c727396736..7aaa8db432 100644
--- a/libcpu/risc-v/e310/context_gcc.S
+++ b/libcpu/risc-v/e310/context_gcc.S
@@ -1,7 +1,7 @@
;/*
; * File : context_gcc.S
; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; * COPYRIGHT (C) 2018, RT-Thread Development Team
; *
; * This program is free software; you can redistribute it and/or modify
; * it under the terms of the GNU General Public License as published by
@@ -19,54 +19,26 @@
; *
; * Change Logs:
; * Date Author Notes
-; * 2017-07-16 zhangjun for hifive1
+; * 2017-07-16 zhangjun for hifive1
+; * 2018-05-29 tanek optimize rt_hw_interrupt_*
+; * 2018-05-29 tanek add mie register to context
; */
-#include "encoding.h"
-#include "sifive/bits.h"
-
/*
- * rt_base_t rt_hw_interrupt_disable();
+ * rt_base_t rt_hw_interrupt_disable(void);
*/
.globl rt_hw_interrupt_disable
rt_hw_interrupt_disable:
- addi sp, sp, -12
- sw a5, (sp)
- li a5, 0x800
- csrr a0, mie
- blt a0, a5, 1f
-/* interrupt is enable before disable it*/
- addi a0, a0, 1
-
- li a5, 0x1
- addi a5, a5, -2048
- csrrc a5, mie, a5
-/* csrrc a5, mie, 128*/
- j 2f
-/* interrupt is disabled before disable it*/
-1:
- li a0, 0
-2:
- lw a5, (sp)
- addi sp, sp, 12
- ret
+ csrrci a0, mstatus, 8
+ ret
/*
* void rt_hw_interrupt_enable(rt_base_t level);
*/
.globl rt_hw_interrupt_enable
rt_hw_interrupt_enable:
- addi sp, sp, -12
- sw a5, (sp)
- beqz a0, 1f
- li a5, 0x1
- addi a5, a5, -2048
- csrrs a5, mie, a5
-/* csrrs a5, mie, 128*/
-1:
- lw a5, (sp)
- addi sp, sp, 12
- ret
+ csrw mstatus, a0
+ ret
/*
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
@@ -75,132 +47,151 @@ rt_hw_interrupt_enable:
*/
.globl rt_hw_context_switch
rt_hw_context_switch:
- addi sp, sp, -32*REGBYTES
- STORE sp, (a0)
- STORE x30, 1*REGBYTES(sp)
- STORE x31, 2*REGBYTES(sp)
- STORE x3, 3*REGBYTES(sp)
- STORE x4, 4*REGBYTES(sp)
- STORE x5, 5*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 x10, 29*REGBYTES(sp)
- STORE x1, 30*REGBYTES(sp)
- STORE x1, 31*REGBYTES(sp)
- csrr x10, mie
- STORE x10, 0*REGBYTES(sp)
-/*
- *Remain in M-mode after mret
- *enable interrupt in M-mode
- */
- li t0, 136
- csrrs t0, mstatus, t0
+ /* saved from thread context
+ * x1/ra -> sp(0)
+ * x1/ra -> sp(1)
+ * mstatus.mie -> sp(2)
+ * x(i) -> sp(i-4)
+ */
+ addi sp, sp, -32 * 4
+ sw sp, (a0)
+
+ sw x1, 0 * 4(sp)
+ sw x1, 1 * 4(sp)
+
+ csrr a0, mstatus
+ andi a0, a0, 8
+ beqz a0, save_mpie
+ li a0, 0x80
+save_mpie:
+ sw a0, 2 * 4(sp)
+
+ sw x4, 4 * 4(sp)
+ sw x5, 5 * 4(sp)
+ sw x6, 6 * 4(sp)
+ sw x7, 7 * 4(sp)
+ sw x8, 8 * 4(sp)
+ sw x9, 9 * 4(sp)
+ sw x10, 10 * 4(sp)
+ sw x11, 11 * 4(sp)
+ sw x12, 12 * 4(sp)
+ sw x13, 13 * 4(sp)
+ sw x14, 14 * 4(sp)
+ sw x15, 15 * 4(sp)
+ sw x16, 16 * 4(sp)
+ sw x17, 17 * 4(sp)
+ sw x18, 18 * 4(sp)
+ sw x19, 19 * 4(sp)
+ sw x20, 20 * 4(sp)
+ sw x21, 21 * 4(sp)
+ sw x22, 22 * 4(sp)
+ sw x23, 23 * 4(sp)
+ sw x24, 24 * 4(sp)
+ sw x25, 25 * 4(sp)
+ sw x26, 26 * 4(sp)
+ sw x27, 27 * 4(sp)
+ sw x28, 28 * 4(sp)
+ sw x29, 29 * 4(sp)
+ sw x30, 30 * 4(sp)
+ sw x31, 31 * 4(sp)
+
+ /* restore to thread context
+ * sp(0) -> epc;
+ * sp(1) -> ra;
+ * sp(i) -> x(i+2)
+ */
+ lw sp, (a1)
+
+ /* resw ra to mepc */
+ lw a1, 0 * 4(sp)
+ csrw mepc, a1
+ lw x1, 1 * 4(sp)
+
+ /* force to machin mode(MPP=11) */
+ li a1, 0x00001800;
+ csrs mstatus, a1
+ lw a1, 2 * 4(sp)
+ csrs mstatus, a1
+
+ lw x4, 4 * 4(sp)
+ lw x5, 5 * 4(sp)
+ lw x6, 6 * 4(sp)
+ lw x7, 7 * 4(sp)
+ lw x8, 8 * 4(sp)
+ lw x9, 9 * 4(sp)
+ lw x10, 10 * 4(sp)
+ lw x11, 11 * 4(sp)
+ lw x12, 12 * 4(sp)
+ lw x13, 13 * 4(sp)
+ lw x14, 14 * 4(sp)
+ lw x15, 15 * 4(sp)
+ lw x16, 16 * 4(sp)
+ lw x17, 17 * 4(sp)
+ lw x18, 18 * 4(sp)
+ lw x19, 19 * 4(sp)
+ lw x20, 20 * 4(sp)
+ lw x21, 21 * 4(sp)
+ lw x22, 22 * 4(sp)
+ lw x23, 23 * 4(sp)
+ lw x24, 24 * 4(sp)
+ lw x25, 25 * 4(sp)
+ lw x26, 26 * 4(sp)
+ lw x27, 27 * 4(sp)
+ lw x28, 28 * 4(sp)
+ lw x29, 29 * 4(sp)
+ lw x30, 30 * 4(sp)
+ lw x31, 31 * 4(sp)
+
+ addi sp, sp, 32 * 4
+ mret
- LOAD sp, (a1)
- LOAD x30, 1*REGBYTES(sp)
- LOAD x31, 2*REGBYTES(sp)
- LOAD x3, 3*REGBYTES(sp)
- 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 x29, 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 x10, 31*REGBYTES(sp)
- csrw mepc,x10
- LOAD x10, 0*REGBYTES(sp)
- csrw mie, x10
- LOAD x10, 29*REGBYTES(sp)
- LOAD x1, 30*REGBYTES(sp)
-
- addi sp, sp, 32*REGBYTES
- mret
-
/*
* void rt_hw_context_switch_to(rt_uint32 to);
* a0 --> to
*/
.globl rt_hw_context_switch_to
rt_hw_context_switch_to:
- LOAD sp, (a0)
- LOAD x30, 1*REGBYTES(sp)
- LOAD x31, 2*REGBYTES(sp)
- LOAD x3, 3*REGBYTES(sp)
- 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 x29, 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 x10, 31*REGBYTES(sp)
- csrw mepc,a0
- LOAD x10, 29*REGBYTES(sp)
- LOAD x1, 30*REGBYTES(sp)
-
+ lw sp, (a0)
+
+ /* load epc from stack */
+ lw a0, 0 * 4(sp)
+ csrw mepc, a0
+ lw x1, 1 * 4(sp)
+ /* load mstatus from stack */
+ lw a0, 2 * 4(sp)
+ csrw mstatus, a0
+ lw x4, 4 * 4(sp)
+ lw x5, 5 * 4(sp)
+ lw x6, 6 * 4(sp)
+ lw x7, 7 * 4(sp)
+ lw x8, 8 * 4(sp)
+ lw x9, 9 * 4(sp)
+ lw x10, 10 * 4(sp)
+ lw x11, 11 * 4(sp)
+ lw x12, 12 * 4(sp)
+ lw x13, 13 * 4(sp)
+ lw x14, 14 * 4(sp)
+ lw x15, 15 * 4(sp)
+ lw x16, 16 * 4(sp)
+ lw x17, 17 * 4(sp)
+ lw x18, 18 * 4(sp)
+ lw x19, 19 * 4(sp)
+ lw x20, 20 * 4(sp)
+ lw x21, 21 * 4(sp)
+ lw x22, 22 * 4(sp)
+ lw x23, 23 * 4(sp)
+ lw x24, 24 * 4(sp)
+ lw x25, 25 * 4(sp)
+ lw x26, 26 * 4(sp)
+ lw x27, 27 * 4(sp)
+ lw x28, 28 * 4(sp)
+ lw x29, 29 * 4(sp)
+ lw x30, 30 * 4(sp)
+ lw x31, 31 * 4(sp)
- addi sp, sp, 32*REGBYTES
- mret
-
+ addi sp, sp, 32 * 4
+ mret
/*
* void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
@@ -210,27 +201,27 @@ rt_hw_context_switch_to:
.globl rt_interrupt_to_thread
.globl rt_hw_context_switch_interrupt
rt_hw_context_switch_interrupt:
- addi sp, sp, -16
- sw s0, 12(sp)
- sw a0, 8(sp)
- sw a5, 4(sp)
+ addi sp, sp, -16
+ sw s0, 12(sp)
+ sw a0, 8(sp)
+ sw a5, 4(sp)
- la a0, rt_thread_switch_interrupt_flag
- lw a5, (a0)
- bnez a5, _reswitch
- li a5, 1
- sw a5, (a0)
+ la a0, rt_thread_switch_interrupt_flag
+ lw a5, (a0)
+ bnez a5, _reswitch
+ li a5, 1
+ sw a5, (a0)
- la a5, rt_interrupt_from_thread
- lw a0, 8(sp)
- sw a0, (a5)
+ la a5, rt_interrupt_from_thread
+ lw a0, 8(sp)
+ sw a0, (a5)
_reswitch:
- la a5, rt_interrupt_to_thread
- sw a1, (a5)
+ la a5, rt_interrupt_to_thread
+ sw a1, (a5)
- lw a5, 4(sp)
- lw a0, 8(sp)
- lw s0, 12(sp)
- addi sp, sp, 16
- ret
+ lw a5, 4(sp)
+ lw a0, 8(sp)
+ lw s0, 12(sp)
+ addi sp, sp, 16
+ ret
diff --git a/libcpu/risc-v/e310/encoding.h b/libcpu/risc-v/e310/encoding.h
deleted file mode 100644
index 35e0f9fe05..0000000000
--- a/libcpu/risc-v/e310/encoding.h
+++ /dev/null
@@ -1,1313 +0,0 @@
-// See LICENSE for license details.
-
-#ifndef RISCV_CSR_ENCODING_H
-#define RISCV_CSR_ENCODING_H
-
-#define MSTATUS_UIE 0x00000001
-#define MSTATUS_SIE 0x00000002
-#define MSTATUS_HIE 0x00000004
-#define MSTATUS_MIE 0x00000008
-#define MSTATUS_UPIE 0x00000010
-#define MSTATUS_SPIE 0x00000020
-#define MSTATUS_HPIE 0x00000040
-#define MSTATUS_MPIE 0x00000080
-#define MSTATUS_SPP 0x00000100
-#define MSTATUS_HPP 0x00000600
-#define MSTATUS_MPP 0x00001800
-#define MSTATUS_FS 0x00006000
-#define MSTATUS_XS 0x00018000
-#define MSTATUS_MPRV 0x00020000
-#define MSTATUS_PUM 0x00040000
-#define MSTATUS_MXR 0x00080000
-#define MSTATUS_VM 0x1F000000
-#define MSTATUS32_SD 0x80000000
-#define MSTATUS64_SD 0x8000000000000000
-
-#define SSTATUS_UIE 0x00000001
-#define SSTATUS_SIE 0x00000002
-#define SSTATUS_UPIE 0x00000010
-#define SSTATUS_SPIE 0x00000020
-#define SSTATUS_SPP 0x00000100
-#define SSTATUS_FS 0x00006000
-#define SSTATUS_XS 0x00018000
-#define SSTATUS_PUM 0x00040000
-#define SSTATUS32_SD 0x80000000
-#define SSTATUS64_SD 0x8000000000000000
-
-#define DCSR_XDEBUGVER (3U<<30)
-#define DCSR_NDRESET (1<<29)
-#define DCSR_FULLRESET (1<<28)
-#define DCSR_EBREAKM (1<<15)
-#define DCSR_EBREAKH (1<<14)
-#define DCSR_EBREAKS (1<<13)
-#define DCSR_EBREAKU (1<<12)
-#define DCSR_STOPCYCLE (1<<10)
-#define DCSR_STOPTIME (1<<9)
-#define DCSR_CAUSE (7<<6)
-#define DCSR_DEBUGINT (1<<5)
-#define DCSR_HALT (1<<3)
-#define DCSR_STEP (1<<2)
-#define DCSR_PRV (3<<0)
-
-#define DCSR_CAUSE_NONE 0
-#define DCSR_CAUSE_SWBP 1
-#define DCSR_CAUSE_HWBP 2
-#define DCSR_CAUSE_DEBUGINT 3
-#define DCSR_CAUSE_STEP 4
-#define DCSR_CAUSE_HALT 5
-
-#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4))
-#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5))
-#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11))
-
-#define MCONTROL_SELECT (1<<19)
-#define MCONTROL_TIMING (1<<18)
-#define MCONTROL_ACTION (0x3f<<12)
-#define MCONTROL_CHAIN (1<<11)
-#define MCONTROL_MATCH (0xf<<7)
-#define MCONTROL_M (1<<6)
-#define MCONTROL_H (1<<5)
-#define MCONTROL_S (1<<4)
-#define MCONTROL_U (1<<3)
-#define MCONTROL_EXECUTE (1<<2)
-#define MCONTROL_STORE (1<<1)
-#define MCONTROL_LOAD (1<<0)
-
-#define MCONTROL_TYPE_NONE 0
-#define MCONTROL_TYPE_MATCH 2
-
-#define MCONTROL_ACTION_DEBUG_EXCEPTION 0
-#define MCONTROL_ACTION_DEBUG_MODE 1
-#define MCONTROL_ACTION_TRACE_START 2
-#define MCONTROL_ACTION_TRACE_STOP 3
-#define MCONTROL_ACTION_TRACE_EMIT 4
-
-#define MCONTROL_MATCH_EQUAL 0
-#define MCONTROL_MATCH_NAPOT 1
-#define MCONTROL_MATCH_GE 2
-#define MCONTROL_MATCH_LT 3
-#define MCONTROL_MATCH_MASK_LOW 4
-#define MCONTROL_MATCH_MASK_HIGH 5
-
-#define MIP_SSIP (1 << IRQ_S_SOFT)
-#define MIP_HSIP (1 << IRQ_H_SOFT)
-#define MIP_MSIP (1 << IRQ_M_SOFT)
-#define MIP_STIP (1 << IRQ_S_TIMER)
-#define MIP_HTIP (1 << IRQ_H_TIMER)
-#define MIP_MTIP (1 << IRQ_M_TIMER)
-#define MIP_SEIP (1 << IRQ_S_EXT)
-#define MIP_HEIP (1 << IRQ_H_EXT)
-#define MIP_MEIP (1 << IRQ_M_EXT)
-
-#define SIP_SSIP MIP_SSIP
-#define SIP_STIP MIP_STIP
-
-#define PRV_U 0
-#define PRV_S 1
-#define PRV_H 2
-#define PRV_M 3
-
-#define VM_MBARE 0
-#define VM_MBB 1
-#define VM_MBBID 2
-#define VM_SV32 8
-#define VM_SV39 9
-#define VM_SV48 10
-
-#define IRQ_S_SOFT 1
-#define IRQ_H_SOFT 2
-#define IRQ_M_SOFT 3
-#define IRQ_S_TIMER 5
-#define IRQ_H_TIMER 6
-#define IRQ_M_TIMER 7
-#define IRQ_S_EXT 9
-#define IRQ_H_EXT 10
-#define IRQ_M_EXT 11
-#define IRQ_COP 12
-#define IRQ_HOST 13
-
-#define DEFAULT_RSTVEC 0x00001000
-#define DEFAULT_NMIVEC 0x00001004
-#define DEFAULT_MTVEC 0x00001010
-#define CONFIG_STRING_ADDR 0x0000100C
-#define EXT_IO_BASE 0x40000000
-#define DRAM_BASE 0x80000000
-
-// page table entry (PTE) fields
-#define PTE_V 0x001 // Valid
-#define PTE_R 0x002 // Read
-#define PTE_W 0x004 // Write
-#define PTE_X 0x008 // Execute
-#define PTE_U 0x010 // User
-#define PTE_G 0x020 // Global
-#define PTE_A 0x040 // Accessed
-#define PTE_D 0x080 // Dirty
-#define PTE_SOFT 0x300 // Reserved for Software
-
-#define PTE_PPN_SHIFT 10
-
-#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
-
-#ifdef __riscv
-
-#ifdef __riscv64
-# define MSTATUS_SD MSTATUS64_SD
-# define SSTATUS_SD SSTATUS64_SD
-# define RISCV_PGLEVEL_BITS 9
-#else
-# define MSTATUS_SD MSTATUS32_SD
-# define SSTATUS_SD SSTATUS32_SD
-# define RISCV_PGLEVEL_BITS 10
-#endif
-#define RISCV_PGSHIFT 12
-#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
-
-#ifndef __ASSEMBLER__
-
-#ifdef __GNUC__
-
-#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 swap_csr(reg, val) ({ unsigned long __tmp; \
- if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
- asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \
- else \
- asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \
- __tmp; })
-
-#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; })
-
-#define rdtime() read_csr(time)
-#define rdcycle() read_csr(cycle)
-#define rdinstret() read_csr(instret)
-
-#endif
-
-#endif
-
-#endif
-
-#endif
-/* Automatically generated by parse-opcodes */
-#ifndef RISCV_ENCODING_H
-#define RISCV_ENCODING_H
-#define MATCH_BEQ 0x63
-#define MASK_BEQ 0x707f
-#define MATCH_BNE 0x1063
-#define MASK_BNE 0x707f
-#define MATCH_BLT 0x4063
-#define MASK_BLT 0x707f
-#define MATCH_BGE 0x5063
-#define MASK_BGE 0x707f
-#define MATCH_BLTU 0x6063
-#define MASK_BLTU 0x707f
-#define MATCH_BGEU 0x7063
-#define MASK_BGEU 0x707f
-#define MATCH_JALR 0x67
-#define MASK_JALR 0x707f
-#define MATCH_JAL 0x6f
-#define MASK_JAL 0x7f
-#define MATCH_LUI 0x37
-#define MASK_LUI 0x7f
-#define MATCH_AUIPC 0x17
-#define MASK_AUIPC 0x7f
-#define MATCH_ADDI 0x13
-#define MASK_ADDI 0x707f
-#define MATCH_SLLI 0x1013
-#define MASK_SLLI 0xfc00707f
-#define MATCH_SLTI 0x2013
-#define MASK_SLTI 0x707f
-#define MATCH_SLTIU 0x3013
-#define MASK_SLTIU 0x707f
-#define MATCH_XORI 0x4013
-#define MASK_XORI 0x707f
-#define MATCH_SRLI 0x5013
-#define MASK_SRLI 0xfc00707f
-#define MATCH_SRAI 0x40005013
-#define MASK_SRAI 0xfc00707f
-#define MATCH_ORI 0x6013
-#define MASK_ORI 0x707f
-#define MATCH_ANDI 0x7013
-#define MASK_ANDI 0x707f
-#define MATCH_ADD 0x33
-#define MASK_ADD 0xfe00707f
-#define MATCH_SUB 0x40000033
-#define MASK_SUB 0xfe00707f
-#define MATCH_SLL 0x1033
-#define MASK_SLL 0xfe00707f
-#define MATCH_SLT 0x2033
-#define MASK_SLT 0xfe00707f
-#define MATCH_SLTU 0x3033
-#define MASK_SLTU 0xfe00707f
-#define MATCH_XOR 0x4033
-#define MASK_XOR 0xfe00707f
-#define MATCH_SRL 0x5033
-#define MASK_SRL 0xfe00707f
-#define MATCH_SRA 0x40005033
-#define MASK_SRA 0xfe00707f
-#define MATCH_OR 0x6033
-#define MASK_OR 0xfe00707f
-#define MATCH_AND 0x7033
-#define MASK_AND 0xfe00707f
-#define MATCH_ADDIW 0x1b
-#define MASK_ADDIW 0x707f
-#define MATCH_SLLIW 0x101b
-#define MASK_SLLIW 0xfe00707f
-#define MATCH_SRLIW 0x501b
-#define MASK_SRLIW 0xfe00707f
-#define MATCH_SRAIW 0x4000501b
-#define MASK_SRAIW 0xfe00707f
-#define MATCH_ADDW 0x3b
-#define MASK_ADDW 0xfe00707f
-#define MATCH_SUBW 0x4000003b
-#define MASK_SUBW 0xfe00707f
-#define MATCH_SLLW 0x103b
-#define MASK_SLLW 0xfe00707f
-#define MATCH_SRLW 0x503b
-#define MASK_SRLW 0xfe00707f
-#define MATCH_SRAW 0x4000503b
-#define MASK_SRAW 0xfe00707f
-#define MATCH_LB 0x3
-#define MASK_LB 0x707f
-#define MATCH_LH 0x1003
-#define MASK_LH 0x707f
-#define MATCH_LW 0x2003
-#define MASK_LW 0x707f
-#define MATCH_LD 0x3003
-#define MASK_LD 0x707f
-#define MATCH_LBU 0x4003
-#define MASK_LBU 0x707f
-#define MATCH_LHU 0x5003
-#define MASK_LHU 0x707f
-#define MATCH_LWU 0x6003
-#define MASK_LWU 0x707f
-#define MATCH_SB 0x23
-#define MASK_SB 0x707f
-#define MATCH_SH 0x1023
-#define MASK_SH 0x707f
-#define MATCH_SW 0x2023
-#define MASK_SW 0x707f
-#define MATCH_SD 0x3023
-#define MASK_SD 0x707f
-#define MATCH_FENCE 0xf
-#define MASK_FENCE 0x707f
-#define MATCH_FENCE_I 0x100f
-#define MASK_FENCE_I 0x707f
-#define MATCH_MUL 0x2000033
-#define MASK_MUL 0xfe00707f
-#define MATCH_MULH 0x2001033
-#define MASK_MULH 0xfe00707f
-#define MATCH_MULHSU 0x2002033
-#define MASK_MULHSU 0xfe00707f
-#define MATCH_MULHU 0x2003033
-#define MASK_MULHU 0xfe00707f
-#define MATCH_DIV 0x2004033
-#define MASK_DIV 0xfe00707f
-#define MATCH_DIVU 0x2005033
-#define MASK_DIVU 0xfe00707f
-#define MATCH_REM 0x2006033
-#define MASK_REM 0xfe00707f
-#define MATCH_REMU 0x2007033
-#define MASK_REMU 0xfe00707f
-#define MATCH_MULW 0x200003b
-#define MASK_MULW 0xfe00707f
-#define MATCH_DIVW 0x200403b
-#define MASK_DIVW 0xfe00707f
-#define MATCH_DIVUW 0x200503b
-#define MASK_DIVUW 0xfe00707f
-#define MATCH_REMW 0x200603b
-#define MASK_REMW 0xfe00707f
-#define MATCH_REMUW 0x200703b
-#define MASK_REMUW 0xfe00707f
-#define MATCH_AMOADD_W 0x202f
-#define MASK_AMOADD_W 0xf800707f
-#define MATCH_AMOXOR_W 0x2000202f
-#define MASK_AMOXOR_W 0xf800707f
-#define MATCH_AMOOR_W 0x4000202f
-#define MASK_AMOOR_W 0xf800707f
-#define MATCH_AMOAND_W 0x6000202f
-#define MASK_AMOAND_W 0xf800707f
-#define MATCH_AMOMIN_W 0x8000202f
-#define MASK_AMOMIN_W 0xf800707f
-#define MATCH_AMOMAX_W 0xa000202f
-#define MASK_AMOMAX_W 0xf800707f
-#define MATCH_AMOMINU_W 0xc000202f
-#define MASK_AMOMINU_W 0xf800707f
-#define MATCH_AMOMAXU_W 0xe000202f
-#define MASK_AMOMAXU_W 0xf800707f
-#define MATCH_AMOSWAP_W 0x800202f
-#define MASK_AMOSWAP_W 0xf800707f
-#define MATCH_LR_W 0x1000202f
-#define MASK_LR_W 0xf9f0707f
-#define MATCH_SC_W 0x1800202f
-#define MASK_SC_W 0xf800707f
-#define MATCH_AMOADD_D 0x302f
-#define MASK_AMOADD_D 0xf800707f
-#define MATCH_AMOXOR_D 0x2000302f
-#define MASK_AMOXOR_D 0xf800707f
-#define MATCH_AMOOR_D 0x4000302f
-#define MASK_AMOOR_D 0xf800707f
-#define MATCH_AMOAND_D 0x6000302f
-#define MASK_AMOAND_D 0xf800707f
-#define MATCH_AMOMIN_D 0x8000302f
-#define MASK_AMOMIN_D 0xf800707f
-#define MATCH_AMOMAX_D 0xa000302f
-#define MASK_AMOMAX_D 0xf800707f
-#define MATCH_AMOMINU_D 0xc000302f
-#define MASK_AMOMINU_D 0xf800707f
-#define MATCH_AMOMAXU_D 0xe000302f
-#define MASK_AMOMAXU_D 0xf800707f
-#define MATCH_AMOSWAP_D 0x800302f
-#define MASK_AMOSWAP_D 0xf800707f
-#define MATCH_LR_D 0x1000302f
-#define MASK_LR_D 0xf9f0707f
-#define MATCH_SC_D 0x1800302f
-#define MASK_SC_D 0xf800707f
-#define MATCH_ECALL 0x73
-#define MASK_ECALL 0xffffffff
-#define MATCH_EBREAK 0x100073
-#define MASK_EBREAK 0xffffffff
-#define MATCH_URET 0x200073
-#define MASK_URET 0xffffffff
-#define MATCH_SRET 0x10200073
-#define MASK_SRET 0xffffffff
-#define MATCH_HRET 0x20200073
-#define MASK_HRET 0xffffffff
-#define MATCH_MRET 0x30200073
-#define MASK_MRET 0xffffffff
-#define MATCH_DRET 0x7b200073
-#define MASK_DRET 0xffffffff
-#define MATCH_SFENCE_VM 0x10400073
-#define MASK_SFENCE_VM 0xfff07fff
-#define MATCH_WFI 0x10500073
-#define MASK_WFI 0xffffffff
-#define MATCH_CSRRW 0x1073
-#define MASK_CSRRW 0x707f
-#define MATCH_CSRRS 0x2073
-#define MASK_CSRRS 0x707f
-#define MATCH_CSRRC 0x3073
-#define MASK_CSRRC 0x707f
-#define MATCH_CSRRWI 0x5073
-#define MASK_CSRRWI 0x707f
-#define MATCH_CSRRSI 0x6073
-#define MASK_CSRRSI 0x707f
-#define MATCH_CSRRCI 0x7073
-#define MASK_CSRRCI 0x707f
-#define MATCH_FADD_S 0x53
-#define MASK_FADD_S 0xfe00007f
-#define MATCH_FSUB_S 0x8000053
-#define MASK_FSUB_S 0xfe00007f
-#define MATCH_FMUL_S 0x10000053
-#define MASK_FMUL_S 0xfe00007f
-#define MATCH_FDIV_S 0x18000053
-#define MASK_FDIV_S 0xfe00007f
-#define MATCH_FSGNJ_S 0x20000053
-#define MASK_FSGNJ_S 0xfe00707f
-#define MATCH_FSGNJN_S 0x20001053
-#define MASK_FSGNJN_S 0xfe00707f
-#define MATCH_FSGNJX_S 0x20002053
-#define MASK_FSGNJX_S 0xfe00707f
-#define MATCH_FMIN_S 0x28000053
-#define MASK_FMIN_S 0xfe00707f
-#define MATCH_FMAX_S 0x28001053
-#define MASK_FMAX_S 0xfe00707f
-#define MATCH_FSQRT_S 0x58000053
-#define MASK_FSQRT_S 0xfff0007f
-#define MATCH_FADD_D 0x2000053
-#define MASK_FADD_D 0xfe00007f
-#define MATCH_FSUB_D 0xa000053
-#define MASK_FSUB_D 0xfe00007f
-#define MATCH_FMUL_D 0x12000053
-#define MASK_FMUL_D 0xfe00007f
-#define MATCH_FDIV_D 0x1a000053
-#define MASK_FDIV_D 0xfe00007f
-#define MATCH_FSGNJ_D 0x22000053
-#define MASK_FSGNJ_D 0xfe00707f
-#define MATCH_FSGNJN_D 0x22001053
-#define MASK_FSGNJN_D 0xfe00707f
-#define MATCH_FSGNJX_D 0x22002053
-#define MASK_FSGNJX_D 0xfe00707f
-#define MATCH_FMIN_D 0x2a000053
-#define MASK_FMIN_D 0xfe00707f
-#define MATCH_FMAX_D 0x2a001053
-#define MASK_FMAX_D 0xfe00707f
-#define MATCH_FCVT_S_D 0x40100053
-#define MASK_FCVT_S_D 0xfff0007f
-#define MATCH_FCVT_D_S 0x42000053
-#define MASK_FCVT_D_S 0xfff0007f
-#define MATCH_FSQRT_D 0x5a000053
-#define MASK_FSQRT_D 0xfff0007f
-#define MATCH_FLE_S 0xa0000053
-#define MASK_FLE_S 0xfe00707f
-#define MATCH_FLT_S 0xa0001053
-#define MASK_FLT_S 0xfe00707f
-#define MATCH_FEQ_S 0xa0002053
-#define MASK_FEQ_S 0xfe00707f
-#define MATCH_FLE_D 0xa2000053
-#define MASK_FLE_D 0xfe00707f
-#define MATCH_FLT_D 0xa2001053
-#define MASK_FLT_D 0xfe00707f
-#define MATCH_FEQ_D 0xa2002053
-#define MASK_FEQ_D 0xfe00707f
-#define MATCH_FCVT_W_S 0xc0000053
-#define MASK_FCVT_W_S 0xfff0007f
-#define MATCH_FCVT_WU_S 0xc0100053
-#define MASK_FCVT_WU_S 0xfff0007f
-#define MATCH_FCVT_L_S 0xc0200053
-#define MASK_FCVT_L_S 0xfff0007f
-#define MATCH_FCVT_LU_S 0xc0300053
-#define MASK_FCVT_LU_S 0xfff0007f
-#define MATCH_FMV_X_S 0xe0000053
-#define MASK_FMV_X_S 0xfff0707f
-#define MATCH_FCLASS_S 0xe0001053
-#define MASK_FCLASS_S 0xfff0707f
-#define MATCH_FCVT_W_D 0xc2000053
-#define MASK_FCVT_W_D 0xfff0007f
-#define MATCH_FCVT_WU_D 0xc2100053
-#define MASK_FCVT_WU_D 0xfff0007f
-#define MATCH_FCVT_L_D 0xc2200053
-#define MASK_FCVT_L_D 0xfff0007f
-#define MATCH_FCVT_LU_D 0xc2300053
-#define MASK_FCVT_LU_D 0xfff0007f
-#define MATCH_FMV_X_D 0xe2000053
-#define MASK_FMV_X_D 0xfff0707f
-#define MATCH_FCLASS_D 0xe2001053
-#define MASK_FCLASS_D 0xfff0707f
-#define MATCH_FCVT_S_W 0xd0000053
-#define MASK_FCVT_S_W 0xfff0007f
-#define MATCH_FCVT_S_WU 0xd0100053
-#define MASK_FCVT_S_WU 0xfff0007f
-#define MATCH_FCVT_S_L 0xd0200053
-#define MASK_FCVT_S_L 0xfff0007f
-#define MATCH_FCVT_S_LU 0xd0300053
-#define MASK_FCVT_S_LU 0xfff0007f
-#define MATCH_FMV_S_X 0xf0000053
-#define MASK_FMV_S_X 0xfff0707f
-#define MATCH_FCVT_D_W 0xd2000053
-#define MASK_FCVT_D_W 0xfff0007f
-#define MATCH_FCVT_D_WU 0xd2100053
-#define MASK_FCVT_D_WU 0xfff0007f
-#define MATCH_FCVT_D_L 0xd2200053
-#define MASK_FCVT_D_L 0xfff0007f
-#define MATCH_FCVT_D_LU 0xd2300053
-#define MASK_FCVT_D_LU 0xfff0007f
-#define MATCH_FMV_D_X 0xf2000053
-#define MASK_FMV_D_X 0xfff0707f
-#define MATCH_FLW 0x2007
-#define MASK_FLW 0x707f
-#define MATCH_FLD 0x3007
-#define MASK_FLD 0x707f
-#define MATCH_FSW 0x2027
-#define MASK_FSW 0x707f
-#define MATCH_FSD 0x3027
-#define MASK_FSD 0x707f
-#define MATCH_FMADD_S 0x43
-#define MASK_FMADD_S 0x600007f
-#define MATCH_FMSUB_S 0x47
-#define MASK_FMSUB_S 0x600007f
-#define MATCH_FNMSUB_S 0x4b
-#define MASK_FNMSUB_S 0x600007f
-#define MATCH_FNMADD_S 0x4f
-#define MASK_FNMADD_S 0x600007f
-#define MATCH_FMADD_D 0x2000043
-#define MASK_FMADD_D 0x600007f
-#define MATCH_FMSUB_D 0x2000047
-#define MASK_FMSUB_D 0x600007f
-#define MATCH_FNMSUB_D 0x200004b
-#define MASK_FNMSUB_D 0x600007f
-#define MATCH_FNMADD_D 0x200004f
-#define MASK_FNMADD_D 0x600007f
-#define MATCH_C_NOP 0x1
-#define MASK_C_NOP 0xffff
-#define MATCH_C_ADDI16SP 0x6101
-#define MASK_C_ADDI16SP 0xef83
-#define MATCH_C_JR 0x8002
-#define MASK_C_JR 0xf07f
-#define MATCH_C_JALR 0x9002
-#define MASK_C_JALR 0xf07f
-#define MATCH_C_EBREAK 0x9002
-#define MASK_C_EBREAK 0xffff
-#define MATCH_C_LD 0x6000
-#define MASK_C_LD 0xe003
-#define MATCH_C_SD 0xe000
-#define MASK_C_SD 0xe003
-#define MATCH_C_ADDIW 0x2001
-#define MASK_C_ADDIW 0xe003
-#define MATCH_C_LDSP 0x6002
-#define MASK_C_LDSP 0xe003
-#define MATCH_C_SDSP 0xe002
-#define MASK_C_SDSP 0xe003
-#define MATCH_C_ADDI4SPN 0x0
-#define MASK_C_ADDI4SPN 0xe003
-#define MATCH_C_FLD 0x2000
-#define MASK_C_FLD 0xe003
-#define MATCH_C_LW 0x4000
-#define MASK_C_LW 0xe003
-#define MATCH_C_FLW 0x6000
-#define MASK_C_FLW 0xe003
-#define MATCH_C_FSD 0xa000
-#define MASK_C_FSD 0xe003
-#define MATCH_C_SW 0xc000
-#define MASK_C_SW 0xe003
-#define MATCH_C_FSW 0xe000
-#define MASK_C_FSW 0xe003
-#define MATCH_C_ADDI 0x1
-#define MASK_C_ADDI 0xe003
-#define MATCH_C_JAL 0x2001
-#define MASK_C_JAL 0xe003
-#define MATCH_C_LI 0x4001
-#define MASK_C_LI 0xe003
-#define MATCH_C_LUI 0x6001
-#define MASK_C_LUI 0xe003
-#define MATCH_C_SRLI 0x8001
-#define MASK_C_SRLI 0xec03
-#define MATCH_C_SRAI 0x8401
-#define MASK_C_SRAI 0xec03
-#define MATCH_C_ANDI 0x8801
-#define MASK_C_ANDI 0xec03
-#define MATCH_C_SUB 0x8c01
-#define MASK_C_SUB 0xfc63
-#define MATCH_C_XOR 0x8c21
-#define MASK_C_XOR 0xfc63
-#define MATCH_C_OR 0x8c41
-#define MASK_C_OR 0xfc63
-#define MATCH_C_AND 0x8c61
-#define MASK_C_AND 0xfc63
-#define MATCH_C_SUBW 0x9c01
-#define MASK_C_SUBW 0xfc63
-#define MATCH_C_ADDW 0x9c21
-#define MASK_C_ADDW 0xfc63
-#define MATCH_C_J 0xa001
-#define MASK_C_J 0xe003
-#define MATCH_C_BEQZ 0xc001
-#define MASK_C_BEQZ 0xe003
-#define MATCH_C_BNEZ 0xe001
-#define MASK_C_BNEZ 0xe003
-#define MATCH_C_SLLI 0x2
-#define MASK_C_SLLI 0xe003
-#define MATCH_C_FLDSP 0x2002
-#define MASK_C_FLDSP 0xe003
-#define MATCH_C_LWSP 0x4002
-#define MASK_C_LWSP 0xe003
-#define MATCH_C_FLWSP 0x6002
-#define MASK_C_FLWSP 0xe003
-#define MATCH_C_MV 0x8002
-#define MASK_C_MV 0xf003
-#define MATCH_C_ADD 0x9002
-#define MASK_C_ADD 0xf003
-#define MATCH_C_FSDSP 0xa002
-#define MASK_C_FSDSP 0xe003
-#define MATCH_C_SWSP 0xc002
-#define MASK_C_SWSP 0xe003
-#define MATCH_C_FSWSP 0xe002
-#define MASK_C_FSWSP 0xe003
-#define MATCH_CUSTOM0 0xb
-#define MASK_CUSTOM0 0x707f
-#define MATCH_CUSTOM0_RS1 0x200b
-#define MASK_CUSTOM0_RS1 0x707f
-#define MATCH_CUSTOM0_RS1_RS2 0x300b
-#define MASK_CUSTOM0_RS1_RS2 0x707f
-#define MATCH_CUSTOM0_RD 0x400b
-#define MASK_CUSTOM0_RD 0x707f
-#define MATCH_CUSTOM0_RD_RS1 0x600b
-#define MASK_CUSTOM0_RD_RS1 0x707f
-#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b
-#define MASK_CUSTOM0_RD_RS1_RS2 0x707f
-#define MATCH_CUSTOM1 0x2b
-#define MASK_CUSTOM1 0x707f
-#define MATCH_CUSTOM1_RS1 0x202b
-#define MASK_CUSTOM1_RS1 0x707f
-#define MATCH_CUSTOM1_RS1_RS2 0x302b
-#define MASK_CUSTOM1_RS1_RS2 0x707f
-#define MATCH_CUSTOM1_RD 0x402b
-#define MASK_CUSTOM1_RD 0x707f
-#define MATCH_CUSTOM1_RD_RS1 0x602b
-#define MASK_CUSTOM1_RD_RS1 0x707f
-#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b
-#define MASK_CUSTOM1_RD_RS1_RS2 0x707f
-#define MATCH_CUSTOM2 0x5b
-#define MASK_CUSTOM2 0x707f
-#define MATCH_CUSTOM2_RS1 0x205b
-#define MASK_CUSTOM2_RS1 0x707f
-#define MATCH_CUSTOM2_RS1_RS2 0x305b
-#define MASK_CUSTOM2_RS1_RS2 0x707f
-#define MATCH_CUSTOM2_RD 0x405b
-#define MASK_CUSTOM2_RD 0x707f
-#define MATCH_CUSTOM2_RD_RS1 0x605b
-#define MASK_CUSTOM2_RD_RS1 0x707f
-#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b
-#define MASK_CUSTOM2_RD_RS1_RS2 0x707f
-#define MATCH_CUSTOM3 0x7b
-#define MASK_CUSTOM3 0x707f
-#define MATCH_CUSTOM3_RS1 0x207b
-#define MASK_CUSTOM3_RS1 0x707f
-#define MATCH_CUSTOM3_RS1_RS2 0x307b
-#define MASK_CUSTOM3_RS1_RS2 0x707f
-#define MATCH_CUSTOM3_RD 0x407b
-#define MASK_CUSTOM3_RD 0x707f
-#define MATCH_CUSTOM3_RD_RS1 0x607b
-#define MASK_CUSTOM3_RD_RS1 0x707f
-#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b
-#define MASK_CUSTOM3_RD_RS1_RS2 0x707f
-#define CSR_FFLAGS 0x1
-#define CSR_FRM 0x2
-#define CSR_FCSR 0x3
-#define CSR_CYCLE 0xc00
-#define CSR_TIME 0xc01
-#define CSR_INSTRET 0xc02
-#define CSR_HPMCOUNTER3 0xc03
-#define CSR_HPMCOUNTER4 0xc04
-#define CSR_HPMCOUNTER5 0xc05
-#define CSR_HPMCOUNTER6 0xc06
-#define CSR_HPMCOUNTER7 0xc07
-#define CSR_HPMCOUNTER8 0xc08
-#define CSR_HPMCOUNTER9 0xc09
-#define CSR_HPMCOUNTER10 0xc0a
-#define CSR_HPMCOUNTER11 0xc0b
-#define CSR_HPMCOUNTER12 0xc0c
-#define CSR_HPMCOUNTER13 0xc0d
-#define CSR_HPMCOUNTER14 0xc0e
-#define CSR_HPMCOUNTER15 0xc0f
-#define CSR_HPMCOUNTER16 0xc10
-#define CSR_HPMCOUNTER17 0xc11
-#define CSR_HPMCOUNTER18 0xc12
-#define CSR_HPMCOUNTER19 0xc13
-#define CSR_HPMCOUNTER20 0xc14
-#define CSR_HPMCOUNTER21 0xc15
-#define CSR_HPMCOUNTER22 0xc16
-#define CSR_HPMCOUNTER23 0xc17
-#define CSR_HPMCOUNTER24 0xc18
-#define CSR_HPMCOUNTER25 0xc19
-#define CSR_HPMCOUNTER26 0xc1a
-#define CSR_HPMCOUNTER27 0xc1b
-#define CSR_HPMCOUNTER28 0xc1c
-#define CSR_HPMCOUNTER29 0xc1d
-#define CSR_HPMCOUNTER30 0xc1e
-#define CSR_HPMCOUNTER31 0xc1f
-#define CSR_SSTATUS 0x100
-#define CSR_SIE 0x104
-#define CSR_STVEC 0x105
-#define CSR_SSCRATCH 0x140
-#define CSR_SEPC 0x141
-#define CSR_SCAUSE 0x142
-#define CSR_SBADADDR 0x143
-#define CSR_SIP 0x144
-#define CSR_SPTBR 0x180
-#define CSR_MSTATUS 0x300
-#define CSR_MISA 0x301
-#define CSR_MEDELEG 0x302
-#define CSR_MIDELEG 0x303
-#define CSR_MIE 0x304
-#define CSR_MTVEC 0x305
-#define CSR_MSCRATCH 0x340
-#define CSR_MEPC 0x341
-#define CSR_MCAUSE 0x342
-#define CSR_MBADADDR 0x343
-#define CSR_MIP 0x344
-#define CSR_TSELECT 0x7a0
-#define CSR_TDATA1 0x7a1
-#define CSR_TDATA2 0x7a2
-#define CSR_TDATA3 0x7a3
-#define CSR_DCSR 0x7b0
-#define CSR_DPC 0x7b1
-#define CSR_DSCRATCH 0x7b2
-#define CSR_MCYCLE 0xb00
-#define CSR_MINSTRET 0xb02
-#define CSR_MHPMCOUNTER3 0xb03
-#define CSR_MHPMCOUNTER4 0xb04
-#define CSR_MHPMCOUNTER5 0xb05
-#define CSR_MHPMCOUNTER6 0xb06
-#define CSR_MHPMCOUNTER7 0xb07
-#define CSR_MHPMCOUNTER8 0xb08
-#define CSR_MHPMCOUNTER9 0xb09
-#define CSR_MHPMCOUNTER10 0xb0a
-#define CSR_MHPMCOUNTER11 0xb0b
-#define CSR_MHPMCOUNTER12 0xb0c
-#define CSR_MHPMCOUNTER13 0xb0d
-#define CSR_MHPMCOUNTER14 0xb0e
-#define CSR_MHPMCOUNTER15 0xb0f
-#define CSR_MHPMCOUNTER16 0xb10
-#define CSR_MHPMCOUNTER17 0xb11
-#define CSR_MHPMCOUNTER18 0xb12
-#define CSR_MHPMCOUNTER19 0xb13
-#define CSR_MHPMCOUNTER20 0xb14
-#define CSR_MHPMCOUNTER21 0xb15
-#define CSR_MHPMCOUNTER22 0xb16
-#define CSR_MHPMCOUNTER23 0xb17
-#define CSR_MHPMCOUNTER24 0xb18
-#define CSR_MHPMCOUNTER25 0xb19
-#define CSR_MHPMCOUNTER26 0xb1a
-#define CSR_MHPMCOUNTER27 0xb1b
-#define CSR_MHPMCOUNTER28 0xb1c
-#define CSR_MHPMCOUNTER29 0xb1d
-#define CSR_MHPMCOUNTER30 0xb1e
-#define CSR_MHPMCOUNTER31 0xb1f
-#define CSR_MUCOUNTEREN 0x320
-#define CSR_MSCOUNTEREN 0x321
-#define CSR_MHPMEVENT3 0x323
-#define CSR_MHPMEVENT4 0x324
-#define CSR_MHPMEVENT5 0x325
-#define CSR_MHPMEVENT6 0x326
-#define CSR_MHPMEVENT7 0x327
-#define CSR_MHPMEVENT8 0x328
-#define CSR_MHPMEVENT9 0x329
-#define CSR_MHPMEVENT10 0x32a
-#define CSR_MHPMEVENT11 0x32b
-#define CSR_MHPMEVENT12 0x32c
-#define CSR_MHPMEVENT13 0x32d
-#define CSR_MHPMEVENT14 0x32e
-#define CSR_MHPMEVENT15 0x32f
-#define CSR_MHPMEVENT16 0x330
-#define CSR_MHPMEVENT17 0x331
-#define CSR_MHPMEVENT18 0x332
-#define CSR_MHPMEVENT19 0x333
-#define CSR_MHPMEVENT20 0x334
-#define CSR_MHPMEVENT21 0x335
-#define CSR_MHPMEVENT22 0x336
-#define CSR_MHPMEVENT23 0x337
-#define CSR_MHPMEVENT24 0x338
-#define CSR_MHPMEVENT25 0x339
-#define CSR_MHPMEVENT26 0x33a
-#define CSR_MHPMEVENT27 0x33b
-#define CSR_MHPMEVENT28 0x33c
-#define CSR_MHPMEVENT29 0x33d
-#define CSR_MHPMEVENT30 0x33e
-#define CSR_MHPMEVENT31 0x33f
-#define CSR_MVENDORID 0xf11
-#define CSR_MARCHID 0xf12
-#define CSR_MIMPID 0xf13
-#define CSR_MHARTID 0xf14
-#define CSR_CYCLEH 0xc80
-#define CSR_TIMEH 0xc81
-#define CSR_INSTRETH 0xc82
-#define CSR_HPMCOUNTER3H 0xc83
-#define CSR_HPMCOUNTER4H 0xc84
-#define CSR_HPMCOUNTER5H 0xc85
-#define CSR_HPMCOUNTER6H 0xc86
-#define CSR_HPMCOUNTER7H 0xc87
-#define CSR_HPMCOUNTER8H 0xc88
-#define CSR_HPMCOUNTER9H 0xc89
-#define CSR_HPMCOUNTER10H 0xc8a
-#define CSR_HPMCOUNTER11H 0xc8b
-#define CSR_HPMCOUNTER12H 0xc8c
-#define CSR_HPMCOUNTER13H 0xc8d
-#define CSR_HPMCOUNTER14H 0xc8e
-#define CSR_HPMCOUNTER15H 0xc8f
-#define CSR_HPMCOUNTER16H 0xc90
-#define CSR_HPMCOUNTER17H 0xc91
-#define CSR_HPMCOUNTER18H 0xc92
-#define CSR_HPMCOUNTER19H 0xc93
-#define CSR_HPMCOUNTER20H 0xc94
-#define CSR_HPMCOUNTER21H 0xc95
-#define CSR_HPMCOUNTER22H 0xc96
-#define CSR_HPMCOUNTER23H 0xc97
-#define CSR_HPMCOUNTER24H 0xc98
-#define CSR_HPMCOUNTER25H 0xc99
-#define CSR_HPMCOUNTER26H 0xc9a
-#define CSR_HPMCOUNTER27H 0xc9b
-#define CSR_HPMCOUNTER28H 0xc9c
-#define CSR_HPMCOUNTER29H 0xc9d
-#define CSR_HPMCOUNTER30H 0xc9e
-#define CSR_HPMCOUNTER31H 0xc9f
-#define CSR_MCYCLEH 0xb80
-#define CSR_MINSTRETH 0xb82
-#define CSR_MHPMCOUNTER3H 0xb83
-#define CSR_MHPMCOUNTER4H 0xb84
-#define CSR_MHPMCOUNTER5H 0xb85
-#define CSR_MHPMCOUNTER6H 0xb86
-#define CSR_MHPMCOUNTER7H 0xb87
-#define CSR_MHPMCOUNTER8H 0xb88
-#define CSR_MHPMCOUNTER9H 0xb89
-#define CSR_MHPMCOUNTER10H 0xb8a
-#define CSR_MHPMCOUNTER11H 0xb8b
-#define CSR_MHPMCOUNTER12H 0xb8c
-#define CSR_MHPMCOUNTER13H 0xb8d
-#define CSR_MHPMCOUNTER14H 0xb8e
-#define CSR_MHPMCOUNTER15H 0xb8f
-#define CSR_MHPMCOUNTER16H 0xb90
-#define CSR_MHPMCOUNTER17H 0xb91
-#define CSR_MHPMCOUNTER18H 0xb92
-#define CSR_MHPMCOUNTER19H 0xb93
-#define CSR_MHPMCOUNTER20H 0xb94
-#define CSR_MHPMCOUNTER21H 0xb95
-#define CSR_MHPMCOUNTER22H 0xb96
-#define CSR_MHPMCOUNTER23H 0xb97
-#define CSR_MHPMCOUNTER24H 0xb98
-#define CSR_MHPMCOUNTER25H 0xb99
-#define CSR_MHPMCOUNTER26H 0xb9a
-#define CSR_MHPMCOUNTER27H 0xb9b
-#define CSR_MHPMCOUNTER28H 0xb9c
-#define CSR_MHPMCOUNTER29H 0xb9d
-#define CSR_MHPMCOUNTER30H 0xb9e
-#define CSR_MHPMCOUNTER31H 0xb9f
-#define CAUSE_MISALIGNED_FETCH 0x0
-#define CAUSE_FAULT_FETCH 0x1
-#define CAUSE_ILLEGAL_INSTRUCTION 0x2
-#define CAUSE_BREAKPOINT 0x3
-#define CAUSE_MISALIGNED_LOAD 0x4
-#define CAUSE_FAULT_LOAD 0x5
-#define CAUSE_MISALIGNED_STORE 0x6
-#define CAUSE_FAULT_STORE 0x7
-#define CAUSE_USER_ECALL 0x8
-#define CAUSE_SUPERVISOR_ECALL 0x9
-#define CAUSE_HYPERVISOR_ECALL 0xa
-#define CAUSE_MACHINE_ECALL 0xb
-#endif
-#ifdef DECLARE_INSN
-DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ)
-DECLARE_INSN(bne, MATCH_BNE, MASK_BNE)
-DECLARE_INSN(blt, MATCH_BLT, MASK_BLT)
-DECLARE_INSN(bge, MATCH_BGE, MASK_BGE)
-DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU)
-DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU)
-DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR)
-DECLARE_INSN(jal, MATCH_JAL, MASK_JAL)
-DECLARE_INSN(lui, MATCH_LUI, MASK_LUI)
-DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC)
-DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI)
-DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI)
-DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI)
-DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU)
-DECLARE_INSN(xori, MATCH_XORI, MASK_XORI)
-DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI)
-DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI)
-DECLARE_INSN(ori, MATCH_ORI, MASK_ORI)
-DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI)
-DECLARE_INSN(add, MATCH_ADD, MASK_ADD)
-DECLARE_INSN(sub, MATCH_SUB, MASK_SUB)
-DECLARE_INSN(sll, MATCH_SLL, MASK_SLL)
-DECLARE_INSN(slt, MATCH_SLT, MASK_SLT)
-DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU)
-DECLARE_INSN(xor, MATCH_XOR, MASK_XOR)
-DECLARE_INSN(srl, MATCH_SRL, MASK_SRL)
-DECLARE_INSN(sra, MATCH_SRA, MASK_SRA)
-DECLARE_INSN(or, MATCH_OR, MASK_OR)
-DECLARE_INSN(and, MATCH_AND, MASK_AND)
-DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW)
-DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW)
-DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW)
-DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW)
-DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW)
-DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW)
-DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW)
-DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW)
-DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW)
-DECLARE_INSN(lb, MATCH_LB, MASK_LB)
-DECLARE_INSN(lh, MATCH_LH, MASK_LH)
-DECLARE_INSN(lw, MATCH_LW, MASK_LW)
-DECLARE_INSN(ld, MATCH_LD, MASK_LD)
-DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU)
-DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU)
-DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU)
-DECLARE_INSN(sb, MATCH_SB, MASK_SB)
-DECLARE_INSN(sh, MATCH_SH, MASK_SH)
-DECLARE_INSN(sw, MATCH_SW, MASK_SW)
-DECLARE_INSN(sd, MATCH_SD, MASK_SD)
-DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE)
-DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I)
-DECLARE_INSN(mul, MATCH_MUL, MASK_MUL)
-DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH)
-DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU)
-DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU)
-DECLARE_INSN(div, MATCH_DIV, MASK_DIV)
-DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU)
-DECLARE_INSN(rem, MATCH_REM, MASK_REM)
-DECLARE_INSN(remu, MATCH_REMU, MASK_REMU)
-DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW)
-DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW)
-DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW)
-DECLARE_INSN(remw, MATCH_REMW, MASK_REMW)
-DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW)
-DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W)
-DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W)
-DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W)
-DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W)
-DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W)
-DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W)
-DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W)
-DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W)
-DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W)
-DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W)
-DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W)
-DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D)
-DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D)
-DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D)
-DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D)
-DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D)
-DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D)
-DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D)
-DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D)
-DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D)
-DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D)
-DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D)
-DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL)
-DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK)
-DECLARE_INSN(uret, MATCH_URET, MASK_URET)
-DECLARE_INSN(sret, MATCH_SRET, MASK_SRET)
-DECLARE_INSN(hret, MATCH_HRET, MASK_HRET)
-DECLARE_INSN(mret, MATCH_MRET, MASK_MRET)
-DECLARE_INSN(dret, MATCH_DRET, MASK_DRET)
-DECLARE_INSN(sfence_vm, MATCH_SFENCE_VM, MASK_SFENCE_VM)
-DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI)
-DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW)
-DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS)
-DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC)
-DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI)
-DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI)
-DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI)
-DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S)
-DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S)
-DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S)
-DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S)
-DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S)
-DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S)
-DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S)
-DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S)
-DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S)
-DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S)
-DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D)
-DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D)
-DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D)
-DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D)
-DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D)
-DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D)
-DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D)
-DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D)
-DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D)
-DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D)
-DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S)
-DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D)
-DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S)
-DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S)
-DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S)
-DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D)
-DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D)
-DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D)
-DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S)
-DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S)
-DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S)
-DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S)
-DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S)
-DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S)
-DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D)
-DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D)
-DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D)
-DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D)
-DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D)
-DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D)
-DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W)
-DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU)
-DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L)
-DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU)
-DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X)
-DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W)
-DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU)
-DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L)
-DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU)
-DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X)
-DECLARE_INSN(flw, MATCH_FLW, MASK_FLW)
-DECLARE_INSN(fld, MATCH_FLD, MASK_FLD)
-DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW)
-DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD)
-DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S)
-DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S)
-DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S)
-DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S)
-DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D)
-DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D)
-DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D)
-DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D)
-DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP)
-DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP)
-DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR)
-DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR)
-DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK)
-DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD)
-DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD)
-DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW)
-DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP)
-DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP)
-DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN)
-DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD)
-DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW)
-DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW)
-DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD)
-DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW)
-DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW)
-DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI)
-DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL)
-DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI)
-DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI)
-DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI)
-DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI)
-DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI)
-DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB)
-DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR)
-DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR)
-DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND)
-DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW)
-DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW)
-DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J)
-DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ)
-DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ)
-DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI)
-DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP)
-DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP)
-DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP)
-DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV)
-DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD)
-DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP)
-DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP)
-DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP)
-DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0)
-DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1)
-DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2)
-DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD)
-DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1)
-DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2)
-DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1)
-DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1)
-DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2)
-DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD)
-DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1)
-DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2)
-DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2)
-DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1)
-DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2)
-DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD)
-DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1)
-DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2)
-DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3)
-DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1)
-DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2)
-DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD)
-DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1)
-DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2)
-#endif
-#ifdef DECLARE_CSR
-DECLARE_CSR(fflags, CSR_FFLAGS)
-DECLARE_CSR(frm, CSR_FRM)
-DECLARE_CSR(fcsr, CSR_FCSR)
-DECLARE_CSR(cycle, CSR_CYCLE)
-DECLARE_CSR(time, CSR_TIME)
-DECLARE_CSR(instret, CSR_INSTRET)
-DECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3)
-DECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4)
-DECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5)
-DECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6)
-DECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7)
-DECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8)
-DECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9)
-DECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10)
-DECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11)
-DECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12)
-DECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13)
-DECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14)
-DECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15)
-DECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16)
-DECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17)
-DECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18)
-DECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19)
-DECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20)
-DECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21)
-DECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22)
-DECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23)
-DECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24)
-DECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25)
-DECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26)
-DECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27)
-DECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28)
-DECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29)
-DECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30)
-DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31)
-DECLARE_CSR(sstatus, CSR_SSTATUS)
-DECLARE_CSR(sie, CSR_SIE)
-DECLARE_CSR(stvec, CSR_STVEC)
-DECLARE_CSR(sscratch, CSR_SSCRATCH)
-DECLARE_CSR(sepc, CSR_SEPC)
-DECLARE_CSR(scause, CSR_SCAUSE)
-DECLARE_CSR(sbadaddr, CSR_SBADADDR)
-DECLARE_CSR(sip, CSR_SIP)
-DECLARE_CSR(sptbr, CSR_SPTBR)
-DECLARE_CSR(mstatus, CSR_MSTATUS)
-DECLARE_CSR(misa, CSR_MISA)
-DECLARE_CSR(medeleg, CSR_MEDELEG)
-DECLARE_CSR(mideleg, CSR_MIDELEG)
-DECLARE_CSR(mie, CSR_MIE)
-DECLARE_CSR(mtvec, CSR_MTVEC)
-DECLARE_CSR(mscratch, CSR_MSCRATCH)
-DECLARE_CSR(mepc, CSR_MEPC)
-DECLARE_CSR(mcause, CSR_MCAUSE)
-DECLARE_CSR(mbadaddr, CSR_MBADADDR)
-DECLARE_CSR(mip, CSR_MIP)
-DECLARE_CSR(tselect, CSR_TSELECT)
-DECLARE_CSR(tdata1, CSR_TDATA1)
-DECLARE_CSR(tdata2, CSR_TDATA2)
-DECLARE_CSR(tdata3, CSR_TDATA3)
-DECLARE_CSR(dcsr, CSR_DCSR)
-DECLARE_CSR(dpc, CSR_DPC)
-DECLARE_CSR(dscratch, CSR_DSCRATCH)
-DECLARE_CSR(mcycle, CSR_MCYCLE)
-DECLARE_CSR(minstret, CSR_MINSTRET)
-DECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3)
-DECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4)
-DECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5)
-DECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6)
-DECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7)
-DECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8)
-DECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9)
-DECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10)
-DECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11)
-DECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12)
-DECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13)
-DECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14)
-DECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15)
-DECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16)
-DECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17)
-DECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18)
-DECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19)
-DECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20)
-DECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21)
-DECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22)
-DECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23)
-DECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24)
-DECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25)
-DECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26)
-DECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27)
-DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28)
-DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29)
-DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30)
-DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31)
-DECLARE_CSR(mucounteren, CSR_MUCOUNTEREN)
-DECLARE_CSR(mscounteren, CSR_MSCOUNTEREN)
-DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3)
-DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4)
-DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5)
-DECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6)
-DECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7)
-DECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8)
-DECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9)
-DECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10)
-DECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11)
-DECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12)
-DECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13)
-DECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14)
-DECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15)
-DECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16)
-DECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17)
-DECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18)
-DECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19)
-DECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20)
-DECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21)
-DECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22)
-DECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23)
-DECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24)
-DECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25)
-DECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26)
-DECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27)
-DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28)
-DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29)
-DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30)
-DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31)
-DECLARE_CSR(mvendorid, CSR_MVENDORID)
-DECLARE_CSR(marchid, CSR_MARCHID)
-DECLARE_CSR(mimpid, CSR_MIMPID)
-DECLARE_CSR(mhartid, CSR_MHARTID)
-DECLARE_CSR(cycleh, CSR_CYCLEH)
-DECLARE_CSR(timeh, CSR_TIMEH)
-DECLARE_CSR(instreth, CSR_INSTRETH)
-DECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H)
-DECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H)
-DECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H)
-DECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H)
-DECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H)
-DECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H)
-DECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H)
-DECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H)
-DECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H)
-DECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H)
-DECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H)
-DECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H)
-DECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H)
-DECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H)
-DECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H)
-DECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H)
-DECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H)
-DECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H)
-DECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H)
-DECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H)
-DECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H)
-DECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H)
-DECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H)
-DECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H)
-DECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H)
-DECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H)
-DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H)
-DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H)
-DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H)
-DECLARE_CSR(mcycleh, CSR_MCYCLEH)
-DECLARE_CSR(minstreth, CSR_MINSTRETH)
-DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H)
-DECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H)
-DECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H)
-DECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H)
-DECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H)
-DECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H)
-DECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H)
-DECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H)
-DECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H)
-DECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H)
-DECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H)
-DECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H)
-DECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H)
-DECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H)
-DECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H)
-DECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H)
-DECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H)
-DECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H)
-DECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H)
-DECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H)
-DECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H)
-DECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H)
-DECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H)
-DECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H)
-DECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H)
-DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H)
-DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H)
-DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H)
-DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H)
-#endif
-#ifdef DECLARE_CAUSE
-DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH)
-DECLARE_CAUSE("fault fetch", CAUSE_FAULT_FETCH)
-DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION)
-DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT)
-DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD)
-DECLARE_CAUSE("fault load", CAUSE_FAULT_LOAD)
-DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE)
-DECLARE_CAUSE("fault store", CAUSE_FAULT_STORE)
-DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL)
-DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL)
-DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL)
-DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL)
-#endif
diff --git a/libcpu/risc-v/e310/entry_gcc.S b/libcpu/risc-v/e310/entry_gcc.S
new file mode 100644
index 0000000000..83631e67ee
--- /dev/null
+++ b/libcpu/risc-v/e310/entry_gcc.S
@@ -0,0 +1,145 @@
+/*
+ * File : context_gcc.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2018, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2018-05-29 tanek first implementation
+ */
+
+ .section .text.entry
+ .align 2
+ .global trap_entry
+trap_entry:
+
+ // save all from thread context
+ addi sp, sp, -32 * 4
+
+ sw x1, 1 * 4(sp)
+ li t0, 0x80
+ sw t0, 2 * 4(sp)
+
+ sw x4, 4 * 4(sp)
+ sw x5, 5 * 4(sp)
+ sw x6, 6 * 4(sp)
+ sw x7, 7 * 4(sp)
+ sw x8, 8 * 4(sp)
+ sw x9, 9 * 4(sp)
+ sw x10, 10 * 4(sp)
+ sw x11, 11 * 4(sp)
+ sw x12, 12 * 4(sp)
+ sw x13, 13 * 4(sp)
+ sw x14, 14 * 4(sp)
+ sw x15, 15 * 4(sp)
+ sw x16, 16 * 4(sp)
+ sw x17, 17 * 4(sp)
+ sw x18, 18 * 4(sp)
+ sw x19, 19 * 4(sp)
+ sw x20, 20 * 4(sp)
+ sw x21, 21 * 4(sp)
+ sw x22, 22 * 4(sp)
+ sw x23, 23 * 4(sp)
+ sw x24, 24 * 4(sp)
+ sw x25, 25 * 4(sp)
+ sw x26, 26 * 4(sp)
+ sw x27, 27 * 4(sp)
+ sw x28, 28 * 4(sp)
+ sw x29, 29 * 4(sp)
+ sw x30, 30 * 4(sp)
+ sw x31, 31 * 4(sp)
+
+ // switch to interrupt stack
+ move s0, sp
+ la sp, _sp
+
+ // interrupt handle
+ call rt_interrupt_enter
+ csrr a0, mcause
+ csrr a1, mepc
+ mv a2, sp
+ call handle_trap
+ call rt_interrupt_leave
+
+ // switch to from thread stack
+ move sp, s0
+
+ // need to switch new thread
+ la s0, rt_thread_switch_interrupt_flag
+ lw s2, 0(s0)
+ beqz s2, spurious_interrupt
+ sw zero, 0(s0)
+
+ csrr a0, mepc
+ sw a0, 0 * 4(sp)
+
+ la s0, rt_interrupt_from_thread
+ lw s1, 0(s0)
+ sw sp, 0(s1)
+
+ la s0, rt_interrupt_to_thread
+ lw s1, 0(s0)
+ lw sp, 0(s1)
+
+ lw a0, 0 * 4(sp)
+ csrw mepc, a0
+
+spurious_interrupt:
+ lw x1, 1 * 4(sp)
+
+ // Remain in M-mode after mret
+ li t0, 0x00001800
+ csrs mstatus, t0
+ lw t0, 2 * 4(sp)
+ csrs mstatus, t0
+
+ lw x4, 4 * 4(sp)
+ lw x5, 5 * 4(sp)
+ lw x6, 6 * 4(sp)
+ lw x7, 7 * 4(sp)
+ lw x8, 8 * 4(sp)
+ lw x9, 9 * 4(sp)
+ lw x10, 10 * 4(sp)
+ lw x11, 11 * 4(sp)
+ lw x12, 12 * 4(sp)
+ lw x13, 13 * 4(sp)
+ lw x14, 14 * 4(sp)
+ lw x15, 15 * 4(sp)
+ lw x16, 16 * 4(sp)
+ lw x17, 17 * 4(sp)
+ lw x18, 18 * 4(sp)
+ lw x19, 19 * 4(sp)
+ lw x20, 20 * 4(sp)
+ lw x21, 21 * 4(sp)
+ lw x22, 22 * 4(sp)
+ lw x23, 23 * 4(sp)
+ lw x24, 24 * 4(sp)
+ lw x25, 25 * 4(sp)
+ lw x26, 26 * 4(sp)
+ lw x27, 27 * 4(sp)
+ lw x28, 28 * 4(sp)
+ lw x29, 29 * 4(sp)
+ lw x30, 30 * 4(sp)
+ lw x31, 31 * 4(sp)
+
+ addi sp, sp, 32 * 4
+ mret
+
+.weak handle_trap
+handle_trap:
+1:
+ j 1b
diff --git a/libcpu/risc-v/e310/hifive1.h b/libcpu/risc-v/e310/hifive1.h
deleted file mode 100644
index 0db2f0f321..0000000000
--- a/libcpu/risc-v/e310/hifive1.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// See LICENSE for license details.
-
-#ifndef _SIFIVE_HIFIVE1_H
-#define _SIFIVE_HIFIVE1_H
-
-#include <stdint.h>
-
-/****************************************************************************
- * GPIO Connections
- *****************************************************************************/
-
-// These are the GPIO bit offsets for the RGB LED on HiFive1 Board.
-// These are also mapped to RGB LEDs on the Freedom E300 Arty
-// FPGA
-// Dev Kit.
-
-#define RED_LED_OFFSET 22
-#define GREEN_LED_OFFSET 19
-#define BLUE_LED_OFFSET 21
-
-// These are the GPIO bit offsets for the differen digital pins
-// on the headers for both the HiFive1 Board and the Freedom E300 Arty FPGA Dev Kit.
-#define PIN_0_OFFSET 16
-#define PIN_1_OFFSET 17
-#define PIN_2_OFFSET 18
-#define PIN_3_OFFSET 19
-#define PIN_4_OFFSET 20
-#define PIN_5_OFFSET 21
-#define PIN_6_OFFSET 22
-#define PIN_7_OFFSET 23
-#define PIN_8_OFFSET 0
-#define PIN_9_OFFSET 1
-#define PIN_10_OFFSET 2
-#define PIN_11_OFFSET 3
-#define PIN_12_OFFSET 4
-#define PIN_13_OFFSET 5
-//#define PIN_14_OFFSET 8 //This pin is not connected on either board.
-#define PIN_15_OFFSET 9
-#define PIN_16_OFFSET 10
-#define PIN_17_OFFSET 11
-#define PIN_18_OFFSET 12
-#define PIN_19_OFFSET 13
-
-// These are *PIN* numbers, not
-// GPIO Offset Numbers.
-#define PIN_SPI1_SCK (13u)
-#define PIN_SPI1_MISO (12u)
-#define PIN_SPI1_MOSI (11u)
-#define PIN_SPI1_SS0 (10u)
-#define PIN_SPI1_SS1 (14u)
-#define PIN_SPI1_SS2 (15u)
-#define PIN_SPI1_SS3 (16u)
-
-#define SS_PIN_TO_CS_ID(x) \
- ((x==PIN_SPI1_SS0 ? 0 : \
- (x==PIN_SPI1_SS1 ? 1 : \
- (x==PIN_SPI1_SS2 ? 2 : \
- (x==PIN_SPI1_SS3 ? 3 : \
- -1)))))
-
-
-// These buttons are present only on the Freedom E300 Arty Dev Kit.
-#ifdef HAS_BOARD_BUTTONS
-#define BUTTON_0_OFFSET 15
-#define BUTTON_1_OFFSET 30
-#define BUTTON_2_OFFSET 31
-
-#define INT_DEVICE_BUTTON_0 (INT_GPIO_BASE + BUTTON_0_OFFSET)
-#define INT_DEVICE_BUTTON_1 (INT_GPIO_BASE + BUTTON_1_OFFSET)
-#define INT_DEVICE_BUTTON_2 (INT_GPIO_BASE + BUTTON_2_OFFSET)
-
-#endif
-
-#define HAS_HFXOSC 1
-#define HAS_LFROSC_BYPASS 1
-
-#define RTC_FREQ 32768
-
-void write_hex(int fd, unsigned long int hex);
-
-#endif /* _SIFIVE_HIFIVE1_H */
diff --git a/libcpu/risc-v/e310/init.c b/libcpu/risc-v/e310/init.c
deleted file mode 100644
index a8db529804..0000000000
--- a/libcpu/risc-v/e310/init.c
+++ /dev/null
@@ -1,210 +0,0 @@
-#include <stdint.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include "platform.h"
-#include "encoding.h"
-
-extern int main(int argc, char** argv);
-extern void trap_entry();
-
-static unsigned long mtime_lo(void)
-{
- return *(volatile unsigned long *)(CLINT_CTRL_ADDR + CLINT_MTIME);
-}
-
-#ifdef __riscv32
-
-static uint32_t mtime_hi(void)
-{
- return *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIME + 4);
-}
-
-uint64_t get_timer_value()
-{
- while (1) {
- uint32_t hi = mtime_hi();
- uint32_t lo = mtime_lo();
- if (hi == mtime_hi())
- return ((uint64_t)hi << 32) | lo;
- }
-}
-
-#else /* __riscv32 */
-
-uint64_t get_timer_value()
-{
- return mtime_lo();
-}
-
-#endif
-
-unsigned long get_timer_freq()
-{
- return 32768;
-}
-
-static void use_hfrosc(int div, int trim)
-{
- // Make sure the HFROSC is running at its default setting
- PRCI_REG(PRCI_HFROSCCFG) = (ROSC_DIV(div) | ROSC_TRIM(trim) | ROSC_EN(1));
- while ((PRCI_REG(PRCI_HFROSCCFG) & ROSC_RDY(1)) == 0) ;
- PRCI_REG(PRCI_PLLCFG) &= ~PLL_SEL(1);
-}
-
-static void use_pll(int refsel, int bypass, int r, int f, int q)
-{
- // Ensure that we aren't running off the PLL before we mess with it.
- if (PRCI_REG(PRCI_PLLCFG) & PLL_SEL(1)) {
- // Make sure the HFROSC is running at its default setting
- use_hfrosc(4, 16);
- }
-
- // Set PLL Source to be HFXOSC if available.
- uint32_t config_value = 0;
-
- config_value |= PLL_REFSEL(refsel);
-
- if (bypass) {
- // Bypass
- config_value |= PLL_BYPASS(1);
-
- PRCI_REG(PRCI_PLLCFG) = config_value;
-
- // If we don't have an HFXTAL, this doesn't really matter.
- // Set our Final output divide to divide-by-1:
- PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0));
- } else {
- // In case we are executing from QSPI,
- // (which is quite likely) we need to
- // set the QSPI clock divider appropriately
- // before boosting the clock frequency.
-
- // Div = f_sck/2
- SPI0_REG(SPI_REG_SCKDIV) = 8;
-
- // Set DIV Settings for PLL
- // Both HFROSC and HFXOSC are modeled as ideal
- // 16MHz sources (assuming dividers are set properly for
- // HFROSC).
- // (Legal values of f_REF are 6-48MHz)
-
- // Set DIVR to divide-by-2 to get 8MHz frequency
- // (legal values of f_R are 6-12 MHz)
-
- config_value |= PLL_BYPASS(1);
- config_value |= PLL_R(r);
-
- // Set DIVF to get 512Mhz frequncy
- // There is an implied multiply-by-2, 16Mhz.
- // So need to write 32-1
- // (legal values of f_F are 384-768 MHz)
- config_value |= PLL_F(f);
-
- // Set DIVQ to divide-by-2 to get 256 MHz frequency
- // (legal values of f_Q are 50-400Mhz)
- config_value |= PLL_Q(q);
-
- // Set our Final output divide to divide-by-1:
- PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0));
-
- PRCI_REG(PRCI_PLLCFG) = config_value;
-
- // Un-Bypass the PLL.
- PRCI_REG(PRCI_PLLCFG) &= ~PLL_BYPASS(1);
-
- // Wait for PLL Lock
- // Note that the Lock signal can be glitchy.
- // Need to wait 100 us
- // RTC is running at 32kHz.
- // So wait 4 ticks of RTC.
- uint32_t now = mtime_lo();
- while (mtime_lo() - now < 4) ;
-
- // Now it is safe to check for PLL Lock
- while ((PRCI_REG(PRCI_PLLCFG) & PLL_LOCK(1)) == 0) ;
- }
-
- // Switch over to PLL Clock source
- PRCI_REG(PRCI_PLLCFG) |= PLL_SEL(1);
-}
-
-static void use_default_clocks()
-{
- // Turn off the LFROSC
- AON_REG(AON_LFROSC) &= ~ROSC_EN(1);
-
- // Use HFROSC
- use_hfrosc(4, 16);
-}
-
-static unsigned long __attribute__((noinline)) measure_cpu_freq(size_t n)
-{
- unsigned long start_mtime, delta_mtime;
- unsigned long mtime_freq = get_timer_freq();
-
- // Don't start measuruing until we see an mtime tick
- unsigned long tmp = mtime_lo();
- do {
- start_mtime = mtime_lo();
- } while (start_mtime == tmp);
-
- unsigned long start_mcycle = read_csr(mcycle);
-
- do {
- delta_mtime = mtime_lo() - start_mtime;
- } while (delta_mtime < n);
-
- unsigned long delta_mcycle = read_csr(mcycle) - start_mcycle;
-
- return (delta_mcycle / delta_mtime) * mtime_freq
- + ((delta_mcycle % delta_mtime) * mtime_freq) / delta_mtime;
-}
-
-unsigned long get_cpu_freq()
-{
- static uint32_t cpu_freq;
-
- if (!cpu_freq) {
- // warm up I$
- measure_cpu_freq(1);
- // measure for real
- cpu_freq = measure_cpu_freq(10);
- }
-
- return cpu_freq;
-}
-
-
-
-
-
-#ifdef USE_PLIC
-extern void handle_m_ext_interrupt();
-#endif
-
-#ifdef USE_M_TIME
-extern void handle_m_time_interrupt();
-#endif
-
-
-void _init()
-{
-
- #ifndef NO_INIT
- use_default_clocks();
- use_pll(0, 0, 1, 31, 1);
-
-
- write_csr(mtvec, &trap_entry);
- if (read_csr(misa) & (1 << ('F' - 'A'))) { // if F extension is present
- write_csr(mstatus, MSTATUS_FS); // allow FPU instructions without trapping
- write_csr(fcsr, 0); // initialize rounding mode, undefined at reset
- }
- #endif
-
-}
-
-void _fini()
-{
-}
diff --git a/libcpu/risc-v/e310/platform.h b/libcpu/risc-v/e310/platform.h
deleted file mode 100644
index 806fcfcabe..0000000000
--- a/libcpu/risc-v/e310/platform.h
+++ /dev/null
@@ -1,133 +0,0 @@
-// See LICENSE for license details.
-
-#ifndef _SIFIVE_PLATFORM_H
-#define _SIFIVE_PLATFORM_H
-
-// Some things missing from the official encoding.h
-#define MCAUSE_INT 0x80000000
-#define MCAUSE_CAUSE 0x7FFFFFFF
-
-#include "sifive/const.h"
-#include "sifive/devices/aon.h"
-#include "sifive/devices/clint.h"
-#include "sifive/devices/gpio.h"
-#include "sifive/devices/otp.h"
-#include "sifive/devices/plic.h"
-#include "sifive/devices/prci.h"
-#include "sifive/devices/pwm.h"
-#include "sifive/devices/spi.h"
-#include "sifive/devices/uart.h"
-
-/****************************************************************************
- * Platform definitions
- *****************************************************************************/
-
-// Memory map
-#define MASKROM_MEM_ADDR _AC(0x00001000,UL)
-#define TRAPVEC_TABLE_CTRL_ADDR _AC(0x00001010,UL)
-#define OTP_MEM_ADDR _AC(0x00020000,UL)
-#define CLINT_CTRL_ADDR _AC(0x02000000,UL)
-#define PLIC_CTRL_ADDR _AC(0x0C000000,UL)
-#define AON_CTRL_ADDR _AC(0x10000000,UL)
-#define PRCI_CTRL_ADDR _AC(0x10008000,UL)
-#define OTP_CTRL_ADDR _AC(0x10010000,UL)
-#define GPIO_CTRL_ADDR _AC(0x10012000,UL)
-#define UART0_CTRL_ADDR _AC(0x10013000,UL)
-#define SPI0_CTRL_ADDR _AC(0x10014000,UL)
-#define PWM0_CTRL_ADDR _AC(0x10015000,UL)
-#define UART1_CTRL_ADDR _AC(0x10023000,UL)
-#define SPI1_CTRL_ADDR _AC(0x10024000,UL)
-#define PWM1_CTRL_ADDR _AC(0x10025000,UL)
-#define SPI2_CTRL_ADDR _AC(0x10034000,UL)
-#define PWM2_CTRL_ADDR _AC(0x10035000,UL)
-#define SPI0_MEM_ADDR _AC(0x20000000,UL)
-#define MEM_CTRL_ADDR _AC(0x80000000,UL)
-
-// IOF masks
-#define IOF0_SPI1_MASK _AC(0x000007FC,UL)
-#define SPI11_NUM_SS (4)
-#define IOF_SPI1_SS0 (2u)
-#define IOF_SPI1_SS1 (8u)
-#define IOF_SPI1_SS2 (9u)
-#define IOF_SPI1_SS3 (10u)
-#define IOF_SPI1_MOSI (3u)
-#define IOF_SPI1_MISO (4u)
-#define IOF_SPI1_SCK (5u)
-#define IOF_SPI1_DQ0 (3u)
-#define IOF_SPI1_DQ1 (4u)
-#define IOF_SPI1_DQ2 (6u)
-#define IOF_SPI1_DQ3 (7u)
-
-#define IOF0_SPI2_MASK _AC(0xFC000000,UL)
-#define SPI2_NUM_SS (1)
-#define IOF_SPI2_SS0 (26u)
-#define IOF_SPI2_MOSI (27u)
-#define IOF_SPI2_MISO (28u)
-#define IOF_SPI2_SCK (29u)
-#define IOF_SPI2_DQ0 (27u)
-#define IOF_SPI2_DQ1 (28u)
-#define IOF_SPI2_DQ2 (30u)
-#define IOF_SPI2_DQ3 (31u)
-
-//#define IOF0_I2C_MASK _AC(0x00003000,UL)
-
-#define IOF0_UART0_MASK _AC(0x00030000, UL)
-#define IOF_UART0_RX (16u)
-#define IOF_UART0_TX (17u)
-
-#define IOF0_UART1_MASK _AC(0x03000000, UL)
-#define IOF_UART1_RX (24u)
-#define IOF_UART1_TX (25u)
-
-#define IOF1_PWM0_MASK _AC(0x0000000F, UL)
-#define IOF1_PWM1_MASK _AC(0x00780000, UL)
-#define IOF1_PWM2_MASK _AC(0x00003C00, UL)
-
-// Interrupt numbers
-#define INT_RESERVED 0
-#define INT_WDOGCMP 1
-#define INT_RTCCMP 2
-#define INT_UART0_BASE 3
-#define INT_UART1_BASE 4
-#define INT_SPI0_BASE 5
-#define INT_SPI1_BASE 6
-#define INT_SPI2_BASE 7
-#define INT_GPIO_BASE 8
-#define INT_PWM0_BASE 40
-#define INT_PWM1_BASE 44
-#define INT_PWM2_BASE 48
-
-// Helper functions
-#define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i)))
-#define _REG32P(p, i) ((volatile uint32_t *) ((p) + (i)))
-#define AON_REG(offset) _REG32(AON_CTRL_ADDR, offset)
-#define CLINT_REG(offset) _REG32(CLINT_CTRL_ADDR, offset)
-#define GPIO_REG(offset) _REG32(GPIO_CTRL_ADDR, offset)
-#define OTP_REG(offset) _REG32(OTP_CTRL_ADDR, offset)
-#define PLIC_REG(offset) _REG32(PLIC_CTRL_ADDR, offset)
-#define PRCI_REG(offset) _REG32(PRCI_CTRL_ADDR, offset)
-#define PWM0_REG(offset) _REG32(PWM0_CTRL_ADDR, offset)
-#define PWM1_REG(offset) _REG32(PWM1_CTRL_ADDR, offset)
-#define PWM2_REG(offset) _REG32(PWM2_CTRL_ADDR, offset)
-#define SPI0_REG(offset) _REG32(SPI0_CTRL_ADDR, offset)
-#define SPI1_REG(offset) _REG32(SPI1_CTRL_ADDR, offset)
-#define SPI2_REG(offset) _REG32(SPI2_CTRL_ADDR, offset)
-#define UART0_REG(offset) _REG32(UART0_CTRL_ADDR, offset)
-#define UART1_REG(offset) _REG32(UART1_CTRL_ADDR, offset)
-
-// Misc
-
-#include <stdint.h>
-
-#define NUM_GPIO 32
-
-#define PLIC_NUM_INTERRUPTS 52
-#define PLIC_NUM_PRIORITIES 7
-
-#include "hifive1.h"
-
-unsigned long get_cpu_freq(void);
-unsigned long get_timer_freq(void);
-uint64_t get_timer_value(void);
-
-#endif /* _SIFIVE_PLATFORM_H */
diff --git a/libcpu/risc-v/e310/sifive/bits.h b/libcpu/risc-v/e310/sifive/bits.h
deleted file mode 100644
index bfe656feb0..0000000000
--- a/libcpu/risc-v/e310/sifive/bits.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// See LICENSE for license details.
-#ifndef _RISCV_BITS_H
-#define _RISCV_BITS_H
-
-#define likely(x) __builtin_expect((x), 1)
-#define unlikely(x) __builtin_expect((x), 0)
-
-#define ROUNDUP(a, b) ((((a)-1)/(b)+1)*(b))
-#define ROUNDDOWN(a, b) ((a)/(b)*(b))
-
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#define CLAMP(a, lo, hi) MIN(MAX(a, lo), hi)
-
-#define EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
-#define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
-
-#define STR(x) XSTR(x)
-#define XSTR(x) #x
-
-#if __riscv_xlen == 64
-# define SLL32 sllw
-# define STORE sd
-# define LOAD ld
-# define LWU lwu
-# define LOG_REGBYTES 3
-#else
-# define SLL32 sll
-# define STORE sw
-# define LOAD lw
-# define LWU lw
-# define LOG_REGBYTES 2
-#endif
-#define REGBYTES (1 << LOG_REGBYTES)
-
-#endif
diff --git a/libcpu/risc-v/e310/sifive/const.h b/libcpu/risc-v/e310/sifive/const.h
deleted file mode 100644
index 8dcffbb064..0000000000
--- a/libcpu/risc-v/e310/sifive/const.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// See LICENSE for license details.
-/* Derived from <linux/const.h> */
-
-#ifndef _SIFIVE_CONST_H
-#define _SIFIVE_CONST_H
-
-#ifdef __ASSEMBLER__
-#define _AC(X,Y) X
-#define _AT(T,X) X
-#else
-#define _AC(X,Y) (X##Y)
-#define _AT(T,X) ((T)(X))
-#endif /* !__ASSEMBLER__*/
-
-#define _BITUL(x) (_AC(1,UL) << (x))
-#define _BITULL(x) (_AC(1,ULL) << (x))
-
-#endif /* _SIFIVE_CONST_H */
diff --git a/libcpu/risc-v/e310/sifive/devices/aon.h b/libcpu/risc-v/e310/sifive/devices/aon.h
deleted file mode 100644
index 63f1db3cd6..0000000000
--- a/libcpu/risc-v/e310/sifive/devices/aon.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// See LICENSE for license details.
-
-#ifndef _SIFIVE_AON_H
-#define _SIFIVE_AON_H
-
-/* Register offsets */
-
-#define AON_WDOGCFG 0x000
-#define AON_WDOGCOUNT 0x008
-#define AON_WDOGS 0x010
-#define AON_WDOGFEED 0x018
-#define AON_WDOGKEY 0x01C
-#define AON_WDOGCMP 0x020
-
-#define AON_RTCCFG 0x040
-#define AON_RTCLO 0x048
-#define AON_RTCHI 0x04C
-#define AON_RTCS 0x050
-#define AON_RTCCMP 0x060
-
-#define AON_BACKUP0 0x080
-#define AON_BACKUP1 0x084
-#define AON_BACKUP2 0x088
-#define AON_BACKUP3 0x08C
-#define AON_BACKUP4 0x090
-#define AON_BACKUP5 0x094
-#define AON_BACKUP6 0x098
-#define AON_BACKUP7 0x09C
-#define AON_BACKUP8 0x0A0
-#define AON_BACKUP9 0x0A4
-#define AON_BACKUP10 0x0A8
-#define AON_BACKUP11 0x0AC
-#define AON_BACKUP12 0x0B0
-#define AON_BACKUP13 0x0B4
-#define AON_BACKUP14 0x0B8
-#define AON_BACKUP15 0x0BC
-
-#define AON_PMUWAKEUPI0 0x100
-#define AON_PMUWAKEUPI1 0x104
-#define AON_PMUWAKEUPI2 0x108
-#define AON_PMUWAKEUPI3 0x10C
-#define AON_PMUWAKEUPI4 0x110
-#define AON_PMUWAKEUPI5 0x114
-#define AON_PMUWAKEUPI6 0x118
-#define AON_PMUWAKEUPI7 0x11C
-#define AON_PMUSLEEPI0 0x120
-#define AON_PMUSLEEPI1 0x124
-#define AON_PMUSLEEPI2 0x128
-#define AON_PMUSLEEPI3 0x12C
-#define AON_PMUSLEEPI4 0x130
-#define AON_PMUSLEEPI5 0x134
-#define AON_PMUSLEEPI6 0x138
-#define AON_PMUSLEEPI7 0x13C
-#define AON_PMUIE 0x140
-#define AON_PMUCAUSE 0x144
-#define AON_PMUSLEEP 0x148
-#define AON_PMUKEY 0x14C
-
-#define AON_LFROSC 0x070
-/* Constants */
-
-#define AON_WDOGKEY_VALUE 0x51F15E
-#define AON_WDOGFEED_VALUE 0xD09F00D
-
-#define AON_WDOGCFG_SCALE 0x0000000F
-#define AON_WDOGCFG_RSTEN 0x00000100
-#define AON_WDOGCFG_ZEROCMP 0x00000200
-#define AON_WDOGCFG_ENALWAYS 0x00001000
-#define AON_WDOGCFG_ENCOREAWAKE 0x00002000
-#define AON_WDOGCFG_CMPIP 0x10000000
-
-#define AON_RTCCFG_SCALE 0x0000000F
-#define AON_RTCCFG_ENALWAYS 0x00001000
-#define AON_RTCCFG_CMPIP 0x10000000
-
-#define AON_WAKEUPCAUSE_RESET 0x00
-#define AON_WAKEUPCAUSE_RTC 0x01
-#define AON_WAKEUPCAUSE_DWAKEUP 0x02
-#define AON_WAKEUPCAUSE_AWAKEUP 0x03
-
-#define AON_RESETCAUSE_POWERON 0x0000
-#define AON_RESETCAUSE_EXTERNAL 0x0100
-#define AON_RESETCAUSE_WATCHDOG 0x0200
-
-#define AON_PMUCAUSE_WAKEUPCAUSE 0x00FF
-#define AON_PMUCAUSE_RESETCAUSE 0xFF00
-
-#endif /* _SIFIVE_AON_H */
diff --git a/libcpu/risc-v/e310/sifive/devices/clint.h b/libcpu/risc-v/e310/sifive/devices/clint.h
deleted file mode 100644
index cd3e0c7a34..0000000000
--- a/libcpu/risc-v/e310/sifive/devices/clint.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// See LICENSE for license details
-
-#ifndef _SIFIVE_CLINT_H
-#define _SIFIVE_CLINT_H
-
-
-#define CLINT_MSIP 0x0000
-#define CLINT_MSIP_size 0x4
-#define CLINT_MTIMECMP 0x4000
-#define CLINT_MTIMECMP_size 0x8
-#define CLINT_MTIME 0xBFF8
-#define CLINT_MTIME_size 0x8
-
-#endif /* _SIFIVE_CLINT_H */
diff --git a/libcpu/risc-v/e310/sifive/devices/gpio.h b/libcpu/risc-v/e310/sifive/devices/gpio.h
deleted file mode 100644
index f7f0acb40f..0000000000
--- a/libcpu/risc-v/e310/sifive/devices/gpio.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// See LICENSE for license details.
-
-#ifndef _SIFIVE_GPIO_H
-#define _SIFIVE_GPIO_H
-
-#define GPIO_INPUT_VAL (0x00)
-#define GPIO_INPUT_EN (0x04)
-#define GPIO_OUTPUT_EN (0x08)
-#define GPIO_OUTPUT_VAL (0x0C)
-#define GPIO_PULLUP_EN (0x10)
-#define GPIO_DRIVE (0x14)
-#define GPIO_RISE_IE (0x18)
-#define GPIO_RISE_IP (0x1C)
-#define GPIO_FALL_IE (0x20)
-#define GPIO_FALL_IP (0x24)
-#define GPIO_HIGH_IE (0x28)
-#define GPIO_HIGH_IP (0x2C)
-#define GPIO_LOW_IE (0x30)
-#define GPIO_LOW_IP (0x34)
-#define GPIO_IOF_EN (0x38)
-#define GPIO_IOF_SEL (0x3C)
-#define GPIO_OUTPUT_XOR (0x40)
-
-#endif /* _SIFIVE_GPIO_H */
diff --git a/libcpu/risc-v/e310/sifive/devices/otp.h b/libcpu/risc-v/e310/sifive/devices/otp.h
deleted file mode 100644
index 93833e2b21..0000000000
--- a/libcpu/risc-v/e310/sifive/devices/otp.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// See LICENSE for license details.
-
-#ifndef _SIFIVE_OTP_H
-#define _SIFIVE_OTP_H
-
-/* Register offsets */
-
-#define OTP_LOCK 0x00
-#define OTP_CK 0x04
-#define OTP_OE 0x08
-#define OTP_SEL 0x0C
-#define OTP_WE 0x10
-#define OTP_MR 0x14
-#define OTP_MRR 0x18
-#define OTP_MPP 0x1C
-#define OTP_VRREN 0x20
-#define OTP_VPPEN 0x24
-#define OTP_A 0x28
-#define OTP_D 0x2C
-#define OTP_Q 0x30
-#define OTP_READ_TIMINGS 0x34
-
-#endif
diff --git a/libcpu/risc-v/e310/sifive/devices/plic.h b/libcpu/risc-v/e310/sifive/devices/plic.h
deleted file mode 100644
index e1ca5d6945..0000000000
--- a/libcpu/risc-v/e310/sifive/devices/plic.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// See LICENSE for license details.
-
-#ifndef PLIC_H
-#define PLIC_H
-
-#include <sifive/const.h>
-
-// 32 bits per source
-#define PLIC_PRIORITY_OFFSET _AC(0x0000,UL)
-#define PLIC_PRIORITY_SHIFT_PER_SOURCE 2
-// 1 bit per source (1 address)
-#define PLIC_PENDING_OFFSET _AC(0x1000,UL)
-#define PLIC_PENDING_SHIFT_PER_SOURCE 0
-
-//0x80 per target
-#define PLIC_ENABLE_OFFSET _AC(0x2000,UL)
-#define PLIC_ENABLE_SHIFT_PER_TARGET 7
-
-
-#define PLIC_THRESHOLD_OFFSET _AC(0x200000,UL)
-#define PLIC_CLAIM_OFFSET _AC(0x200004,UL)
-#define PLIC_THRESHOLD_SHIFT_PER_TARGET 12
-#define PLIC_CLAIM_SHIFT_PER_TARGET 12
-
-#define PLIC_MAX_SOURCE 1023
-#define PLIC_SOURCE_MASK 0x3FF
-
-#define PLIC_MAX_TARGET 15871
-#define PLIC_TARGET_MASK 0x3FFF
-
-#endif /* PLIC_H */
diff --git a/libcpu/risc-v/e310/sifive/devices/prci.h b/libcpu/risc-v/e310/sifive/devices/prci.h
deleted file mode 100644
index 1a3de58d29..0000000000
--- a/libcpu/risc-v/e310/sifive/devices/prci.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// See LICENSE for license details.
-
-#ifndef _SIFIVE_PRCI_H
-#define _SIFIVE_PRCI_H
-
-/* Register offsets */
-
-#define PRCI_HFROSCCFG (0x0000)
-#define PRCI_HFXOSCCFG (0x0004)
-#define PRCI_PLLCFG (0x0008)
-#define PRCI_PLLDIV (0x000C)
-#define PRCI_PROCMONCFG (0x00F0)
-
-/* Fields */
-#define ROSC_DIV(x) (((x) & 0x2F) << 0 )
-#define ROSC_TRIM(x) (((x) & 0x1F) << 16)
-#define ROSC_EN(x) (((x) & 0x1 ) << 30)
-#define ROSC_RDY(x) (((x) & 0x1 ) << 31)
-
-#define XOSC_EN(x) (((x) & 0x1) << 30)
-#define XOSC_RDY(x) (((x) & 0x1) << 31)
-
-#define PLL_R(x) (((x) & 0x7) << 0)
-// single reserved bit for F LSB.
-#define PLL_F(x) (((x) & 0x3F) << 4)
-#define PLL_Q(x) (((x) & 0x3) << 10)
-#define PLL_SEL(x) (((x) & 0x1) << 16)
-#define PLL_REFSEL(x) (((x) & 0x1) << 17)
-#define PLL_BYPASS(x) (((x) & 0x1) << 18)
-#define PLL_LOCK(x) (((x) & 0x1) << 31)
-
-#define PLL_R_default 0x1
-#define PLL_F_default 0x1F
-#define PLL_Q_default 0x3
-
-#define PLL_REFSEL_HFROSC 0x0
-#define PLL_REFSEL_HFXOSC 0x1
-
-#define PLL_SEL_HFROSC 0x0
-#define PLL_SEL_PLL 0x1
-
-#define PLL_FINAL_DIV(x) (((x) & 0x3F) << 0)
-#define PLL_FINAL_DIV_BY_1(x) (((x) & 0x1 ) << 8)
-
-#define PROCMON_DIV(x) (((x) & 0x1F) << 0)
-#define PROCMON_TRIM(x) (((x) & 0x1F) << 8)
-#define PROCMON_EN(x) (((x) & 0x1) << 16)
-#define PROCMON_SEL(x) (((x) & 0x3) << 24)
-#define PROCMON_NT_EN(x) (((x) & 0x1) << 28)
-
-#define PROCMON_SEL_HFCLK 0
-#define PROCMON_SEL_HFXOSCIN 1
-#define PROCMON_SEL_PLLOUTDIV 2
-#define PROCMON_SEL_PROCMON 3
-
-#endif // _SIFIVE_PRCI_H
diff --git a/libcpu/risc-v/e310/sifive/devices/pwm.h b/libcpu/risc-v/e310/sifive/devices/pwm.h
deleted file mode 100644
index 067889abba..0000000000
--- a/libcpu/risc-v/e310/sifive/devices/pwm.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// See LICENSE for license details.
-
-#ifndef _SIFIVE_PWM_H
-#define _SIFIVE_PWM_H
-
-/* Register offsets */
-
-#define PWM_CFG 0x00
-#define PWM_COUNT 0x08
-#define PWM_S 0x10
-#define PWM_CMP0 0x20
-#define PWM_CMP1 0x24
-#define PWM_CMP2 0x28
-#define PWM_CMP3 0x2C
-
-/* Constants */
-
-#define PWM_CFG_SCALE 0x0000000F
-#define PWM_CFG_STICKY 0x00000100
-#define PWM_CFG_ZEROCMP 0x00000200
-#define PWM_CFG_DEGLITCH 0x00000400
-#define PWM_CFG_ENALWAYS 0x00001000
-#define PWM_CFG_ONESHOT 0x00002000
-#define PWM_CFG_CMP0CENTER 0x00010000
-#define PWM_CFG_CMP1CENTER 0x00020000
-#define PWM_CFG_CMP2CENTER 0x00040000
-#define PWM_CFG_CMP3CENTER 0x00080000
-#define PWM_CFG_CMP0GANG 0x01000000
-#define PWM_CFG_CMP1GANG 0x02000000
-#define PWM_CFG_CMP2GANG 0x04000000
-#define PWM_CFG_CMP3GANG 0x08000000
-#define PWM_CFG_CMP0IP 0x10000000
-#define PWM_CFG_CMP1IP 0x20000000
-#define PWM_CFG_CMP2IP 0x40000000
-#define PWM_CFG_CMP3IP 0x80000000
-
-#endif /* _SIFIVE_PWM_H */
diff --git a/libcpu/risc-v/e310/sifive/devices/spi.h b/libcpu/risc-v/e310/sifive/devices/spi.h
deleted file mode 100644
index 916d86be26..0000000000
--- a/libcpu/risc-v/e310/sifive/devices/spi.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// See LICENSE for license details.
-
-#ifndef _SIFIVE_SPI_H
-#define _SIFIVE_SPI_H
-
-/* Register offsets */
-
-#define SPI_REG_SCKDIV 0x00
-#define SPI_REG_SCKMODE 0x04
-#define SPI_REG_CSID 0x10
-#define SPI_REG_CSDEF 0x14
-#define SPI_REG_CSMODE 0x18
-
-#define SPI_REG_DCSSCK 0x28
-#define SPI_REG_DSCKCS 0x2a
-#define SPI_REG_DINTERCS 0x2c
-#define SPI_REG_DINTERXFR 0x2e
-
-#define SPI_REG_FMT 0x40
-#define SPI_REG_TXFIFO 0x48
-#define SPI_REG_RXFIFO 0x4c
-#define SPI_REG_TXCTRL 0x50
-#define SPI_REG_RXCTRL 0x54
-
-#define SPI_REG_FCTRL 0x60
-#define SPI_REG_FFMT 0x64
-
-#define SPI_REG_IE 0x70
-#define SPI_REG_IP 0x74
-
-/* Fields */
-
-#define SPI_SCK_POL 0x1
-#define SPI_SCK_PHA 0x2
-
-#define SPI_FMT_PROTO(x) ((x) & 0x3)
-#define SPI_FMT_ENDIAN(x) (((x) & 0x1) << 2)
-#define SPI_FMT_DIR(x) (((x) & 0x1) << 3)
-#define SPI_FMT_LEN(x) (((x) & 0xf) << 16)
-
-/* TXCTRL register */
-#define SPI_TXWM(x) ((x) & 0xffff)
-/* RXCTRL register */
-#define SPI_RXWM(x) ((x) & 0xffff)
-
-#define SPI_IP_TXWM 0x1
-#define SPI_IP_RXWM 0x2
-
-#define SPI_FCTRL_EN 0x1
-
-#define SPI_INSN_CMD_EN 0x1
-#define SPI_INSN_ADDR_LEN(x) (((x) & 0x7) << 1)
-#define SPI_INSN_PAD_CNT(x) (((x) & 0xf) << 4)
-#define SPI_INSN_CMD_PROTO(x) (((x) & 0x3) << 8)
-#define SPI_INSN_ADDR_PROTO(x) (((x) & 0x3) << 10)
-#define SPI_INSN_DATA_PROTO(x) (((x) & 0x3) << 12)
-#define SPI_INSN_CMD_CODE(x) (((x) & 0xff) << 16)
-#define SPI_INSN_PAD_CODE(x) (((x) & 0xff) << 24)
-
-#define SPI_TXFIFO_FULL (1 << 31)
-#define SPI_RXFIFO_EMPTY (1 << 31)
-
-/* Values */
-
-#define SPI_CSMODE_AUTO 0
-#define SPI_CSMODE_HOLD 2
-#define SPI_CSMODE_OFF 3
-
-#define SPI_DIR_RX 0
-#define SPI_DIR_TX 1
-
-#define SPI_PROTO_S 0
-#define SPI_PROTO_D 1
-#define SPI_PROTO_Q 2
-
-#define SPI_ENDIAN_MSB 0
-#define SPI_ENDIAN_LSB 1
-
-
-#endif /* _SIFIVE_SPI_H */
diff --git a/libcpu/risc-v/e310/sifive/devices/uart.h b/libcpu/risc-v/e310/sifive/devices/uart.h
deleted file mode 100644
index 71bea6f403..0000000000
--- a/libcpu/risc-v/e310/sifive/devices/uart.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// See LICENSE for license details.
-
-#ifndef _SIFIVE_UART_H
-#define _SIFIVE_UART_H
-
-/* Register offsets */
-#define UART_REG_TXFIFO 0x00
-#define UART_REG_RXFIFO 0x04
-#define UART_REG_TXCTRL 0x08
-#define UART_REG_RXCTRL 0x0c
-#define UART_REG_IE 0x10
-#define UART_REG_IP 0x14
-#define UART_REG_DIV 0x18
-
-/* TXCTRL register */
-#define UART_TXEN 0x1
-#define UART_TXWM(x) (((x) & 0xffff) << 16)
-
-/* RXCTRL register */
-#define UART_RXEN 0x1
-#define UART_RXWM(x) (((x) & 0xffff) << 16)
-
-/* IP register */
-#define UART_IP_TXWM 0x1
-#define UART_IP_RXWM 0x2
-
-#endif /* _SIFIVE_UART_H */
diff --git a/libcpu/risc-v/e310/sifive/sections.h b/libcpu/risc-v/e310/sifive/sections.h
deleted file mode 100644
index 6e1f0518bc..0000000000
--- a/libcpu/risc-v/e310/sifive/sections.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// See LICENSE for license details.
-#ifndef _SECTIONS_H
-#define _SECTIONS_H
-
-extern unsigned char _rom[];
-extern unsigned char _rom_end[];
-
-extern unsigned char _ram[];
-extern unsigned char _ram_end[];
-
-extern unsigned char _ftext[];
-extern unsigned char _etext[];
-extern unsigned char _fbss[];
-extern unsigned char _ebss[];
-extern unsigned char _end[];
-
-#endif /* _SECTIONS_H */
diff --git a/libcpu/risc-v/e310/sifive/smp.h b/libcpu/risc-v/e310/sifive/smp.h
deleted file mode 100644
index 8e34388c04..0000000000
--- a/libcpu/risc-v/e310/sifive/smp.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef SIFIVE_SMP
-#define SIFIVE_SMP
-
-// The maximum number of HARTs this code supports
-#ifndef MAX_HARTS
-#define MAX_HARTS 32
-#endif
-#define CLINT_END_HART_IPI CLINT_CTRL_ADDR + (MAX_HARTS*4)
-
-// The hart that non-SMP tests should run on
-#ifndef NONSMP_HART
-#define NONSMP_HART 0
-#endif
-
-/* If your test cannot handle multiple-threads, use this:
- * smp_disable(reg1)
- */
-#define smp_disable(reg1, reg2) \
- csrr reg1, mhartid ;\
- li reg2, NONSMP_HART ;\
- beq reg1, reg2, hart0_entry ;\
-42: ;\
- wfi ;\
- j 42b ;\
-hart0_entry:
-
-/* If your test needs to temporarily block multiple-threads, do this:
- * smp_pause(reg1, reg2)
- * ... single-threaded work ...
- * smp_resume(reg1, reg2)
- * ... multi-threaded work ...
- */
-
-#define smp_pause(reg1, reg2) \
- li reg2, 0x8 ;\
- csrw mie, reg2 ;\
- csrr reg2, mhartid ;\
- bnez reg2, 42f
-
-#define smp_resume(reg1, reg2) \
- li reg1, CLINT_CTRL_ADDR ;\
-41: ;\
- li reg2, 1 ;\
- sw reg2, 0(reg1) ;\
- addi reg1, reg1, 4 ;\
- li reg2, CLINT_END_HART_IPI ;\
- blt reg1, reg2, 41b ;\
-42: ;\
- wfi ;\
- csrr reg2, mip ;\
- andi reg2, reg2, 0x8 ;\
- beqz reg2, 42b ;\
- li reg1, CLINT_CTRL_ADDR ;\
- csrr reg2, mhartid ;\
- slli reg2, reg2, 2 ;\
- add reg2, reg2, reg1 ;\
- sw zero, 0(reg2) ;\
-41: ;\
- lw reg2, 0(reg1) ;\
- bnez reg2, 41b ;\
- addi reg1, reg1, 4 ;\
- li reg2, CLINT_END_HART_IPI ;\
- blt reg1, reg2, 41b
-
-#endif
diff --git a/libcpu/risc-v/e310/stack.c b/libcpu/risc-v/e310/stack.c
index a86fae70ff..a68c646e39 100644
--- a/libcpu/risc-v/e310/stack.c
+++ b/libcpu/risc-v/e310/stack.c
@@ -19,10 +19,52 @@
*
* Change Logs:
* Date Author Notes
- * 2017-07-31 zhangjun copy from mini2440
+ * 2017-07-31 tanek first implementation
*/
+
#include <rtthread.h>
+/* flag in interrupt handling */
+rt_uint32_t rt_interrupt_from_thread;
+rt_uint32_t rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrupt_flag;
+
+struct stack_frame
+{
+ rt_ubase_t epc; /* epc - epc - program counter */
+ rt_ubase_t ra; /* x1 - ra - return address for jumps */
+ rt_ubase_t mstatus; /* - machine status register */
+ rt_ubase_t gp; /* x3 - gp - global pointer */
+ rt_ubase_t tp; /* x4 - tp - thread pointer */
+ rt_ubase_t t0; /* x5 - t0 - temporary register 0 */
+ rt_ubase_t t1; /* x6 - t1 - temporary register 1 */
+ rt_ubase_t t2; /* x7 - t2 - temporary register 2 */
+ rt_ubase_t s0_fp; /* x8 - s0/fp - saved register 0 or frame pointer */
+ rt_ubase_t s1; /* x9 - s1 - saved register 1 */
+ rt_ubase_t a0; /* x10 - a0 - return value or function argument 0 */
+ rt_ubase_t a1; /* x11 - a1 - return value or function argument 1 */
+ rt_ubase_t a2; /* x12 - a2 - function argument 2 */
+ rt_ubase_t a3; /* x13 - a3 - function argument 3 */
+ rt_ubase_t a4; /* x14 - a4 - function argument 4 */
+ rt_ubase_t a5; /* x15 - a5 - function argument 5 */
+ rt_ubase_t a6; /* x16 - a6 - function argument 6 */
+ rt_ubase_t a7; /* x17 - s7 - function argument 7 */
+ rt_ubase_t s2; /* x18 - s2 - saved register 2 */
+ rt_ubase_t s3; /* x19 - s3 - saved register 3 */
+ rt_ubase_t s4; /* x20 - s4 - saved register 4 */
+ rt_ubase_t s5; /* x21 - s5 - saved register 5 */
+ rt_ubase_t s6; /* x22 - s6 - saved register 6 */
+ rt_ubase_t s7; /* x23 - s7 - saved register 7 */
+ rt_ubase_t s8; /* x24 - s8 - saved register 8 */
+ rt_ubase_t s9; /* x25 - s9 - saved register 9 */
+ rt_ubase_t s10; /* x26 - s10 - saved register 10 */
+ rt_ubase_t s11; /* x27 - s11 - saved register 11 */
+ rt_ubase_t t3; /* x28 - t3 - temporary register 3 */
+ rt_ubase_t t4; /* x29 - t4 - temporary register 4 */
+ rt_ubase_t t5; /* x30 - t5 - temporary register 5 */
+ rt_ubase_t t6; /* x31 - t6 - temporary register 6 */
+};
+
/**
* This function will initialize thread stack
*
@@ -36,46 +78,27 @@
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
rt_uint8_t *stack_addr, void *texit)
{
- rt_uint32_t *stk;
+ struct stack_frame *stack_frame;
+ rt_uint8_t *stk;
+ int i;
+
+ stk = stack_addr + sizeof(rt_uint32_t);
+ stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8);
+ stk -= sizeof(struct stack_frame);
+
+ stack_frame = (struct stack_frame *)stk;
+
+ for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_ubase_t); i++)
+ {
+ ((rt_ubase_t *)stack_frame)[i] = 0xdeadbeef;
+ }
+
+ stack_frame->ra = (rt_ubase_t)texit;
+ stack_frame->a0 = (rt_ubase_t)parameter;
+ stack_frame->epc = (rt_ubase_t)tentry;
- //stk = (rt_uint32_t*)stack_addr;
- stack_addr += sizeof(rt_uint32_t);
- stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8);
- stk = (rt_uint32_t *)stack_addr;
+ // force to machine mode(MPP=11) and set MPIE to 1
+ stack_frame->mstatus = 0x00001880;
- *(--stk) = (rt_uint32_t)tentry; /* entry point */
- *(--stk) = (rt_uint32_t)texit; /* ra */
- *(--stk) = (rt_uint32_t)parameter; /* a0 */
- *(--stk) = 0xffffffff; /* a1 */
- *(--stk) = 0xffffffff; /* a2 */
- *(--stk) = 0xffffffff; /* a3 */
- *(--stk) = 0xffffffff; /* a4 */
- *(--stk) = 0xffffffff; /* a5 */
- *(--stk) = 0xffffffff; /* a6 */
- *(--stk) = 0xffffffff; /* a7 */
- *(--stk) = 0xffffffff; /* s0/fp */
- *(--stk) = 0xffffffff; /* s1 */
- *(--stk) = 0xffffffff; /* s2 */
- *(--stk) = 0xffffffff; /* s3 */
- *(--stk) = 0xffffffff; /* s4 */
- *(--stk) = 0xffffffff; /* s5 */
- *(--stk) = 0xffffffff; /* s6 */
- *(--stk) = 0xffffffff; /* s7 */
- *(--stk) = 0xffffffff; /* s8 */
- *(--stk) = 0xffffffff; /* s9 */
- *(--stk) = 0xffffffff; /* s10*/
- *(--stk) = 0xffffffff; /* s11*/
- *(--stk) = 0xffffffff; /* t0 */
- *(--stk) = 0xffffffff; /* t1 */
- *(--stk) = 0xffffffff; /* t2 */
- *(--stk) = 0xffffffff; /* t3 */
- *(--stk) = 0xffffffff; /* t4 */
- *(--stk) = 0xffffffff; /* t5 */
- *(--stk) = 0xffffffff; /* t6 */
- *(--stk) = 0xffffffff; /* tp */
- *(--stk) = 0xffffffff; /* gp */
- *(--stk) = 0x880; /* mie */
-// *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */
- /* return task's current stack address */
- return (rt_uint8_t *)stk;
+ return stk;
}
diff --git a/libcpu/risc-v/e310/start_gcc.S b/libcpu/risc-v/e310/start_gcc.S
deleted file mode 100644
index 5f1b087b78..0000000000
--- a/libcpu/risc-v/e310/start_gcc.S
+++ /dev/null
@@ -1,297 +0,0 @@
-;/*
-; * File : start_gcc.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006, RT-Thread Development Team
-; *
-; * This program is free software; you can redistribute it and/or modify
-; * it under the terms of the GNU General Public License as published by
-; * the Free Software Foundation; either version 2 of the License, or
-; * (at your option) any later version.
-; *
-; * This program is distributed in the hope that it will be useful,
-; * but WITHOUT ANY WARRANTY; without even the implied warranty of
-; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; * GNU General Public License for more details.
-; *
-; * You should have received a copy of the GNU General Public License along
-; * with this program; if not, write to the Free Software Foundation, Inc.,
-; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-; *
-; * Change Logs:
-; * Date Author Notes
-; * 2017-07-16 zhangjun for hifive1
-; */
-#include "sifive/smp.h"
-#define CLINT_CTRL_ADDR 0x02000000
-
-.section .init
-.globl _start
-.type _start,@function
-
-_start:
- .cfi_startproc
- .cfi_undefined ra
-.option push
-.option norelax
- la gp, __global_pointer$
-.option pop
- la sp, _sp
-/*
- *disable all interrupt at startup
- */
- csrrc a5, mstatus, 0xb
-
-#if defined(ENABLE_SMP)
- smp_pause(t0, t1)
-#endif
-
- /* 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
- /*call _init directly in rt-thread*/
- call _init
-
-#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
-
-#if defined(ENABLE_SMP)
- smp_resume(t0, t1)
-
- csrr a0, mhartid
- bnez a0, 2f
-#endif
-
- auipc ra, 0
- addi sp, sp, -16
-#if __riscv_xlen == 32
- sw ra, 8(sp)
-#else
- sd ra, 8(sp)
-#endif
-
- /* argc = argv = 0 */
- li a0, 0
- li a1, 0
- call main
- tail exit
-1:
- j 1b
-
-#if defined(ENABLE_SMP)
-2:
- la t0, trap_entry
- csrw mtvec, t0
-
- csrr a0, mhartid
- la t1, _sp
- slli t0, a0, 10
- sub sp, t1, t0
-
- auipc ra, 0
- addi sp, sp, -16
-#if __riscv_xlen == 32
- sw ra, 8(sp)
-#else
- sd ra, 8(sp)
-#endif
-
- call secondary_main
- tail exit
-
-1:
- j 1b
-#endif
- .cfi_endproc
-
-#include "encoding.h"
-#include "sifive/bits.h"
-
- .section .text.entry
- .align 2
- .global trap_entry
-trap_entry:
- addi sp, sp, -32*REGBYTES
-
- STORE x30, 1*REGBYTES(sp)
- STORE x31, 2*REGBYTES(sp)
- STORE x3, 3*REGBYTES(sp)
- STORE x4, 4*REGBYTES(sp)
- STORE x5, 5*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 x10, 29*REGBYTES(sp)
- STORE x1, 30*REGBYTES(sp)
- csrr x10, mepc
- STORE x10, 31*REGBYTES(sp)
- csrr x10, mie
- STORE x10, 0*REGBYTES(sp)
-
-
-/*
- *Remain in M-mode after mret
- *enable interrupt in M-mode
- */
- li t0, MSTATUS_MPP
- csrrs t0, mstatus, t0
-
- call rt_interrupt_enter
- csrr a0, mcause
- lui a5, 0x80000
- not a5, a5
- and a5, a5, a0
- li a4, 11
- mv s1, a1
- /*Machine external interrupt*/
- bne a5, a4, 1f
- call rt_hw_trap_irq
-1:
- /*Machine timer interrupt*/
- li a4, 7
- bne a5, a4, 2f
- call rt_systick_handler
-2:
- call rt_interrupt_leave
-
- la a0, rt_thread_switch_interrupt_flag
- lw a1, (a0)
- bnez a1, rt_hw_context_switch_interrupt_do
-
-
- LOAD x30, 1*REGBYTES(sp)
- LOAD x31, 2*REGBYTES(sp)
- LOAD x3, 3*REGBYTES(sp)
- 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 x29, 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 x10, 31*REGBYTES(sp)
- csrw mepc,x10
- LOAD x10, 0*REGBYTES(sp)
- csrw mie, x10
- LOAD x10, 29*REGBYTES(sp)
- LOAD x1, 30*REGBYTES(sp)
-
- addi sp, sp, 32*REGBYTES
- mret
-
-rt_hw_context_switch_interrupt_do:
- /*clear rt_thread_switch_interrupt_flag*/
- la a0, rt_thread_switch_interrupt_flag
- li a5, 0
- sw a5, (a0)
-
- LOAD a0, rt_interrupt_from_thread
- STORE sp, (a0)
- LOAD a0, rt_interrupt_to_thread
- LOAD sp, (a0)
- LOAD x30, 1*REGBYTES(sp)
- LOAD x31, 2*REGBYTES(sp)
- LOAD x3, 3*REGBYTES(sp)
- 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 x29, 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 x10, 31*REGBYTES(sp)
- csrw mepc,x10
- LOAD x10, 0*REGBYTES(sp)
- csrw mie, x10
- LOAD x10, 29*REGBYTES(sp)
- LOAD x1, 30*REGBYTES(sp)
-
- addi sp, sp, 32*REGBYTES
- mret
diff --git a/libcpu/risc-v/e310/trap.c b/libcpu/risc-v/e310/trap.c
deleted file mode 100644
index 7429e1a5f3..0000000000
--- a/libcpu/risc-v/e310/trap.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <rtthread.h>
-#include <rthw.h>
-#include <platform.h>
-#include <encoding.h>
-#include "interrupt.h"
-extern struct rt_irq_desc irq_desc[];
-extern rt_uint32_t rt_hw_interrupt_get_active(rt_uint32_t fiq_irq);
-void rt_hw_trap_irq()
-{
- rt_isr_handler_t isr_func;
- rt_uint32_t irq;
- void *param;
-
- /* get irq number */
- irq = rt_hw_interrupt_get_active(0);
-
- /* get interrupt service routine */
- isr_func = irq_desc[irq].handler;
- param = irq_desc[irq].param;
-
- /* turn to interrupt service routine */
- isr_func(irq, param);
- rt_hw_interrupt_ack(0, irq);
-
-#ifdef RT_USING_INTERRUPT_INFO
- irq_desc[irq].counter ++;
-#endif
-}
-void handle_m_ext_interrupt()
-{
-}
-void rt_systick_handler(void)
-{
- clear_csr(mie, MIP_MTIP);
-
- // Reset the timer for 3s in the future.
- // This also clears the existing timer interrupt.
-
- volatile uint64_t * mtime = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIME);
- volatile uint64_t * mtimecmp = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
- uint64_t now = *mtime;
- uint64_t then = now + 2 * RTC_FREQ/RT_TICK_PER_SECOND;
- *mtimecmp = then;
- rt_tick_increase();
-
- // read the current value of the LEDS and invert them.
-/*
- GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << RED_LED_OFFSET) |
- (0x1 << GREEN_LED_OFFSET) |
- (0x1 << BLUE_LED_OFFSET));
- */
-
- // Re-enable the timer interrupt.
- set_csr(mie, MIP_MTIP);
-}