瀏覽代碼

Merge pull request #2665 from jesven/new_signal_fix

fix signal code
Bernard Xiong 6 年之前
父節點
當前提交
854d0144d3

+ 37 - 4
bsp/k210/.config

@@ -7,6 +7,7 @@
 # RT-Thread Kernel
 #
 CONFIG_RT_NAME_MAX=8
+# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
 CONFIG_RT_USING_SMP=y
 CONFIG_RT_CPUS_NR=2
 CONFIG_RT_ALIGN_SIZE=8
@@ -19,7 +20,7 @@ CONFIG_RT_USING_OVERFLOW_CHECK=y
 CONFIG_RT_USING_HOOK=y
 CONFIG_RT_USING_IDLE_HOOK=y
 CONFIG_RT_IDEL_HOOK_LIST_SIZE=4
-CONFIG_IDLE_THREAD_STACK_SIZE=1024
+CONFIG_IDLE_THREAD_STACK_SIZE=4096
 # CONFIG_RT_USING_TIMER_SOFT is not set
 CONFIG_RT_DEBUG=y
 CONFIG_RT_DEBUG_COLOR=y
@@ -43,7 +44,7 @@ CONFIG_RT_USING_MUTEX=y
 CONFIG_RT_USING_EVENT=y
 CONFIG_RT_USING_MAILBOX=y
 CONFIG_RT_USING_MESSAGEQUEUE=y
-# CONFIG_RT_USING_SIGNALS is not set
+CONFIG_RT_USING_SIGNALS=y
 
 #
 # Memory Management
@@ -139,6 +140,7 @@ CONFIG_RT_USING_DFS_DEVFS=y
 #
 CONFIG_RT_USING_DEVICE_IPC=y
 CONFIG_RT_PIPE_BUFSZ=512
+# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
 CONFIG_RT_USING_SERIAL=y
 CONFIG_RT_SERIAL_USING_DMA=y
 CONFIG_RT_SERIAL_RB_BUFSZ=64
@@ -202,6 +204,11 @@ CONFIG_RT_USING_POSIX=y
 #
 # CONFIG_RT_USING_SAL is not set
 
+#
+# Network interface device
+#
+# CONFIG_RT_USING_NETDEV is not set
+
 #
 # light weight TCP/IP stack
 #
@@ -225,7 +232,6 @@ CONFIG_RT_USING_POSIX=y
 #
 # Utilities
 #
-# CONFIG_RT_USING_LOGTRACE is not set
 # CONFIG_RT_USING_RYM is not set
 # CONFIG_RT_USING_ULOG is not set
 # CONFIG_RT_USING_UTEST is not set
@@ -354,7 +360,6 @@ CONFIG_RT_USING_POSIX=y
 # CONFIG_PKG_USING_MPU6XXX is not set
 # CONFIG_PKG_USING_PCF8574 is not set
 # CONFIG_PKG_USING_SX12XX is not set
-# CONFIG_PKG_USING_SIGNAL_LED is not set
 CONFIG_PKG_USING_KENDRYTE_SDK=y
 CONFIG_PKG_KENDRYTE_SDK_PATH="/packages/peripherals/kendryte-sdk"
 CONFIG_PKG_USING_KENDRYTE_SDK_V052=y
@@ -385,6 +390,34 @@ CONFIG_PKG_KENDRYTE_SDK_VER="v0.5.2"
 # CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
 # CONFIG_PKG_USING_HELLO is not set
 # CONFIG_PKG_USING_VI is not set
+
+#
+# Privated Packages of RealThread
+#
+# CONFIG_PKG_USING_CODEC is not set
+# CONFIG_PKG_USING_PLAYER is not set
+# CONFIG_PKG_USING_MPLAYER is not set
+# CONFIG_PKG_USING_PERSIMMON_SRC is not set
+# CONFIG_PKG_USING_JS_PERSIMMON is not set
+# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
+
+#
+# Network Utilities
+#
+# CONFIG_PKG_USING_WICED is not set
+# CONFIG_PKG_USING_CLOUDSDK is not set
+# CONFIG_PKG_USING_COREMARK is not set
+# CONFIG_PKG_USING_POWER_MANAGER is not set
+# CONFIG_PKG_USING_RT_OTA is not set
+# CONFIG_PKG_USING_RDBD_SRC is not set
+# CONFIG_PKG_USING_RTINSIGHT is not set
+# CONFIG_PKG_USING_SMARTCONFIG is not set
+# CONFIG_PKG_USING_RTX is not set
+# CONFIG_RT_USING_TESTCASE is not set
+# CONFIG_PKG_USING_NGHTTP2 is not set
+# CONFIG_PKG_USING_AVS is not set
+# CONFIG_PKG_USING_STS is not set
+# CONFIG_PKG_USING_DLMS is not set
 CONFIG_BOARD_K210_EVB=y
 CONFIG_BSP_USING_UART_HS=y
 # CONFIG_BSP_USING_UART1 is not set

+ 34 - 4
bsp/k210/rtconfig.h

@@ -7,6 +7,7 @@
 /* RT-Thread Kernel */
 
 #define RT_NAME_MAX 8
+/* RT_USING_ARCH_DATA_TYPE is not set */
 #define RT_USING_SMP
 #define RT_CPUS_NR 2
 #define RT_ALIGN_SIZE 8
@@ -19,7 +20,7 @@
 #define RT_USING_HOOK
 #define RT_USING_IDLE_HOOK
 #define RT_IDEL_HOOK_LIST_SIZE 4
-#define IDLE_THREAD_STACK_SIZE 1024
+#define IDLE_THREAD_STACK_SIZE 4096
 /* RT_USING_TIMER_SOFT is not set */
 #define RT_DEBUG
 #define RT_DEBUG_COLOR
@@ -42,7 +43,7 @@
 #define RT_USING_EVENT
 #define RT_USING_MAILBOX
 #define RT_USING_MESSAGEQUEUE
-/* RT_USING_SIGNALS is not set */
+#define RT_USING_SIGNALS
 
 /* Memory Management */
 
@@ -130,6 +131,7 @@
 
 #define RT_USING_DEVICE_IPC
 #define RT_PIPE_BUFSZ 512
+/* RT_USING_SYSTEM_WORKQUEUE is not set */
 #define RT_USING_SERIAL
 #define RT_SERIAL_USING_DMA
 #define RT_SERIAL_RB_BUFSZ 64
@@ -187,6 +189,10 @@
 
 /* RT_USING_SAL is not set */
 
+/* Network interface device */
+
+/* RT_USING_NETDEV is not set */
+
 /* light weight TCP/IP stack */
 
 /* RT_USING_LWIP is not set */
@@ -205,7 +211,6 @@
 
 /* Utilities */
 
-/* RT_USING_LOGTRACE is not set */
 /* RT_USING_RYM is not set */
 /* RT_USING_ULOG is not set */
 /* RT_USING_UTEST is not set */
@@ -318,7 +323,6 @@
 /* PKG_USING_MPU6XXX is not set */
 /* PKG_USING_PCF8574 is not set */
 /* PKG_USING_SX12XX is not set */
-/* PKG_USING_SIGNAL_LED is not set */
 #define PKG_USING_KENDRYTE_SDK
 #define PKG_USING_KENDRYTE_SDK_V052
 /* PKG_USING_KENDRYTE_SDK_LATEST_VERSION is not set */
@@ -345,6 +349,32 @@
 /* PKG_USING_PERIPHERAL_SAMPLES is not set */
 /* PKG_USING_HELLO is not set */
 /* PKG_USING_VI is not set */
+
+/* Privated Packages of RealThread */
+
+/* PKG_USING_CODEC is not set */
+/* PKG_USING_PLAYER is not set */
+/* PKG_USING_MPLAYER is not set */
+/* PKG_USING_PERSIMMON_SRC is not set */
+/* PKG_USING_JS_PERSIMMON is not set */
+/* PKG_USING_JERRYSCRIPT_WIN32 is not set */
+
+/* Network Utilities */
+
+/* PKG_USING_WICED is not set */
+/* PKG_USING_CLOUDSDK is not set */
+/* PKG_USING_COREMARK is not set */
+/* PKG_USING_POWER_MANAGER is not set */
+/* PKG_USING_RT_OTA is not set */
+/* PKG_USING_RDBD_SRC is not set */
+/* PKG_USING_RTINSIGHT is not set */
+/* PKG_USING_SMARTCONFIG is not set */
+/* PKG_USING_RTX is not set */
+/* RT_USING_TESTCASE is not set */
+/* PKG_USING_NGHTTP2 is not set */
+/* PKG_USING_AVS is not set */
+/* PKG_USING_STS is not set */
+/* PKG_USING_DLMS is not set */
 #define BOARD_K210_EVB
 #define BSP_USING_UART_HS
 /* BSP_USING_UART1 is not set */

+ 1 - 1
bsp/k210/rtconfig.py

@@ -15,7 +15,7 @@ if os.getenv('RTT_CC'):
 
 if  CROSS_TOOL == 'gcc':
     PLATFORM    = 'gcc'
-    EXEC_PATH   = r'/opt/riscv64-unknown-elf/bin'
+    EXEC_PATH   = r'/opt/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.1-20190425-1021/bin'
 else:
     print('Please make sure your toolchains is GNU GCC!')
     exit(0)

+ 5 - 2
include/rtdef.h

@@ -492,9 +492,10 @@ typedef siginfo_t rt_siginfo_t;
 #define RT_THREAD_CLOSE                 0x04                /**< Closed status */
 #define RT_THREAD_STAT_MASK             0x0f
 
-#define RT_THREAD_STAT_SIGNAL           0x10
+#define RT_THREAD_STAT_SIGNAL           0x10                /**< task hold signals */
 #define RT_THREAD_STAT_SIGNAL_READY     (RT_THREAD_STAT_SIGNAL | RT_THREAD_READY)
-#define RT_THREAD_STAT_SIGNAL_WAIT      0x20
+#define RT_THREAD_STAT_SIGNAL_WAIT      0x20                /**< task is waiting for signals */
+#define RT_THREAD_STAT_SIGNAL_PENDING   0x40                /**< signals is held and it has not been procressed */
 #define RT_THREAD_STAT_SIGNAL_MASK      0xf0
 
 /**
@@ -596,7 +597,9 @@ struct rt_thread
     rt_sigset_t     sig_pending;                        /**< the pending signals */
     rt_sigset_t     sig_mask;                           /**< the mask bits of signal */
 
+#ifndef RT_USING_SMP
     void            *sig_ret;                           /**< the return stack pointer from signal */
+#endif
     rt_sighandler_t *sig_vectors;                       /**< vectors of signal handler */
     void            *si_list;                           /**< the signal infor list */
 #endif

+ 27 - 54
libcpu/arm/cortex-a/context_gcc.S

@@ -46,16 +46,7 @@ rt_hw_context_switch_to:
     mov     r0, r1
     bl      rt_cpus_lock_status_restore
 #endif /*RT_USING_SMP*/
-
-#ifdef RT_USING_LWP
-    ldmfd sp, {r13, r14}^   @ pop usr_sp usr_lr
-    add sp, #8
-#endif
-
-    ldmfd sp!, {r4}         @ pop new task spsr
-    msr spsr_cxsf, r4
-
-    ldmfd sp!, {r0-r12, lr, pc}^   @ pop new task r0-r12, lr & pc
+    b       rt_hw_context_switch_exit
 
 .section .bss.share.isr
 _guest_switch_lvl:
@@ -93,15 +84,7 @@ rt_hw_context_switch:
     mov     r0, r2
     bl      rt_cpus_lock_status_restore
 #endif /*RT_USING_SMP*/
-
-#ifdef RT_USING_LWP
-    ldmfd sp, {r13, r14}^   @ pop usr_sp usr_lr
-    add sp, #8
-#endif
-
-    ldmfd sp!, {r4}         @ pop new task cpsr to spsr
-    msr spsr_cxsf, r4
-    ldmfd sp!, {r0-r12, lr, pc}^  @ pop new task r0-r12, lr & pc, copy spsr to cpsr
+    b       rt_hw_context_switch_exit
 
 /*
  * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
@@ -123,51 +106,19 @@ rt_hw_context_switch:
 .globl rt_hw_context_switch_interrupt
 rt_hw_context_switch_interrupt:
 #ifdef RT_USING_SMP
-    /* r0 :irq_mod context
+    /* r0 :svc_mod context
      * r1 :addr of from_thread's sp
      * r2 :addr of to_thread's sp
      * r3 :to_thread's tcb
      */
 
-    @ r0 point to {r0-r3} in stack
-    push    {r1 - r3}
-    mov     r1, r0
-    add     r0, r0, #4*4
-    ldmfd   r0!, {r4-r12,lr}@ reload saved registers
-    mrs     r3,  spsr       @ get cpsr of interrupt thread
-    sub     r2,  lr, #4     @ save old task's pc to r2
-    msr     cpsr_c, #I_Bit|F_Bit|Mode_SVC
-
-    stmfd   sp!, {r2}       @ push old task's pc
-    stmfd   sp!, {r4-r12,lr}@ push old task's lr,r12-r4
-    ldmfd   r1,  {r4-r7}    @ restore r0-r3 of the interrupt thread
-    stmfd   sp!, {r4-r7}    @ push old task's r0-r3
-    stmfd   sp!, {r3}       @ push old task's cpsr
-
-#ifdef RT_USING_LWP
-    stmfd sp, {r13,r14}^    @push usr_sp usr_lr
-    sub sp, #8
-#endif
-
-    msr     cpsr_c, #I_Bit|F_Bit|Mode_IRQ
-    pop     {r1 - r3}
-    mov     sp, r0
-    msr     cpsr_c, #I_Bit|F_Bit|Mode_SVC
-    str     sp, [r1]
+    str     r0, [r1]
 
     ldr     sp, [r2]
     mov     r0, r3
     bl      rt_cpus_lock_status_restore
 
-#ifdef RT_USING_LWP
-    ldmfd sp, {r13,r14}^    @pop usr_sp usr_lr
-    add sp, #8
-#endif
-
-    ldmfd   sp!, {r4}       @ pop new task's cpsr to spsr
-    msr     spsr_cxsf, r4
-
-    ldmfd   sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
+    b       rt_hw_context_switch_exit
 
 #else /*RT_USING_SMP*/
     ldr r2, =rt_thread_switch_interrupt_flag
@@ -183,3 +134,25 @@ _reswitch:
     str r1, [r2]
     bx  lr
 #endif /*RT_USING_SMP*/
+
+.global rt_hw_context_switch_exit
+rt_hw_context_switch_exit:
+
+#ifdef RT_USING_SMP
+#ifdef RT_USING_SIGNALS
+    mov     r0, sp
+    cps #Mode_IRQ
+    bl      rt_signal_check
+    cps #Mode_SVC
+    mov     sp, r0
+#endif
+#endif
+
+#ifdef RT_USING_LWP
+    ldmfd   sp, {r13, r14}^ /* usr_sp, usr_lr */
+    add     sp, #8
+#endif
+    ldmfd   sp!, {r1}
+    msr     spsr_cxsf, r1        /* original mode */
+    ldmfd   sp!, {r0-r12,lr,pc}^ /* irq return */
+

+ 33 - 6
libcpu/arm/cortex-a/start_gcc.S

@@ -11,7 +11,6 @@
  */
 
 #include "rtconfig.h"
-
 .equ Mode_USR,        0x10
 .equ Mode_FIQ,        0x11
 .equ Mode_IRQ,        0x12
@@ -158,20 +157,48 @@ vector_fiq:
 vector_irq:
 #ifdef RT_USING_SMP
     clrex
+
+    stmfd   sp!, {r0, r1}
+    cps     #Mode_SVC
+    mov     r0, sp          /* svc_sp */
+    mov     r1, lr          /* svc_lr */
+
+    cps     #Mode_IRQ
+    sub     lr, #4
+    stmfd   r0!, {r1, lr}       /* svc_lr, svc_pc */
+    stmfd   r0!, {r2 - r12}
+    ldmfd   sp!, {r1, r2}     /* original r0, r1 */
+    stmfd   r0!, {r1 - r2}
+    mrs     r1,  spsr         /* original mode */
+    stmfd   r0!, {r1}
+
+#ifdef RT_USING_LWP
+    stmfd   r0, {r13, r14}^ /* usr_sp, usr_lr */
+    sub   r0, #8
 #endif
-    stmfd   sp!, {r0-r12,lr}
+    /* now irq stack is clean */
+    /* r0 is task svc_sp */
+    /* backup r0 -> r8 */
+    mov r8, r0
 
     bl      rt_interrupt_enter
     bl      rt_hw_trap_irq
     bl      rt_interrupt_leave
 
-#ifdef RT_USING_SMP
-    mov     r0, sp
+    cps     #Mode_SVC
+    mov     sp, r8
+    mov     r0, r8
     bl      rt_scheduler_do_irq_switch
 
-    ldmfd   sp!, {r0-r12,lr}
-    subs    pc,  lr, #4
+    b       rt_hw_context_switch_exit
+
 #else
+    stmfd   sp!, {r0-r12,lr}
+
+    bl      rt_interrupt_enter
+    bl      rt_hw_trap_irq
+    bl      rt_interrupt_leave
+
     @ if rt_thread_switch_interrupt_flag set, jump to
     @ rt_hw_context_switch_interrupt_do and don't return
     ldr     r0, =rt_thread_switch_interrupt_flag

+ 31 - 95
libcpu/risc-v/common/context_gcc.S

@@ -49,45 +49,9 @@ rt_hw_context_switch_to:
     mv   a0,   a1
     jal  rt_cpus_lock_status_restore
 #endif
-
-    /* load epc from stack */
-    LOAD a0,   0 * REGBYTES(sp)
-    csrw mepc, a0
-    LOAD x1,   1 * REGBYTES(sp)
-    /* load mstatus from stack */
     LOAD a0,   2 * REGBYTES(sp)
     csrw mstatus, a0
-    LOAD x4,   4 * REGBYTES(sp)
-    LOAD x5,   5 * REGBYTES(sp)
-    LOAD x6,   6 * REGBYTES(sp)
-    LOAD x7,   7 * REGBYTES(sp)
-    LOAD x8,   8 * REGBYTES(sp)
-    LOAD x9,   9 * REGBYTES(sp)
-    LOAD x10, 10 * REGBYTES(sp)
-    LOAD x11, 11 * REGBYTES(sp)
-    LOAD x12, 12 * REGBYTES(sp)
-    LOAD x13, 13 * REGBYTES(sp)
-    LOAD x14, 14 * REGBYTES(sp)
-    LOAD x15, 15 * REGBYTES(sp)
-    LOAD x16, 16 * REGBYTES(sp)
-    LOAD x17, 17 * REGBYTES(sp)
-    LOAD x18, 18 * REGBYTES(sp)
-    LOAD x19, 19 * REGBYTES(sp)
-    LOAD x20, 20 * REGBYTES(sp)
-    LOAD x21, 21 * REGBYTES(sp)
-    LOAD x22, 22 * REGBYTES(sp)
-    LOAD x23, 23 * REGBYTES(sp)
-    LOAD x24, 24 * REGBYTES(sp)
-    LOAD x25, 25 * REGBYTES(sp)
-    LOAD x26, 26 * REGBYTES(sp)
-    LOAD x27, 27 * REGBYTES(sp)
-    LOAD x28, 28 * REGBYTES(sp)
-    LOAD x29, 29 * REGBYTES(sp)
-    LOAD x30, 30 * REGBYTES(sp)
-    LOAD x31, 31 * REGBYTES(sp)
-
-    addi sp,  sp, 32 * REGBYTES
-    mret
+    j    rt_hw_context_switch_exit
 
 /*
  * #ifdef RT_USING_SMP
@@ -102,7 +66,6 @@ rt_hw_context_switch_to:
  */
     .globl rt_hw_context_switch
 rt_hw_context_switch:
-
     /* saved from thread context
      *     x1/ra       -> sp(0)
      *     x1/ra       -> sp(1)
@@ -163,48 +126,7 @@ save_mpie:
     jal  rt_cpus_lock_status_restore
 #endif /*RT_USING_SMP*/
 
-    /* resw ra to mepc */
-    LOAD a1,   0 * REGBYTES(sp)
-    csrw mepc, a1
-    LOAD x1,   1 * REGBYTES(sp)
-
-    /* force to machin mode(MPP=11) */
-    li a1, 0x00001800;
-    csrs mstatus, a1
-    LOAD a1,   2 * REGBYTES(sp)
-    csrs mstatus, a1
-
-    LOAD x4,   4 * REGBYTES(sp)
-    LOAD x5,   5 * REGBYTES(sp)
-    LOAD x6,   6 * REGBYTES(sp)
-    LOAD x7,   7 * REGBYTES(sp)
-    LOAD x8,   8 * REGBYTES(sp)
-    LOAD x9,   9 * REGBYTES(sp)
-    LOAD x10, 10 * REGBYTES(sp)
-    LOAD x11, 11 * REGBYTES(sp)
-    LOAD x12, 12 * REGBYTES(sp)
-    LOAD x13, 13 * REGBYTES(sp)
-    LOAD x14, 14 * REGBYTES(sp)
-    LOAD x15, 15 * REGBYTES(sp)
-    LOAD x16, 16 * REGBYTES(sp)
-    LOAD x17, 17 * REGBYTES(sp)
-    LOAD x18, 18 * REGBYTES(sp)
-    LOAD x19, 19 * REGBYTES(sp)
-    LOAD x20, 20 * REGBYTES(sp)
-    LOAD x21, 21 * REGBYTES(sp)
-    LOAD x22, 22 * REGBYTES(sp)
-    LOAD x23, 23 * REGBYTES(sp)
-    LOAD x24, 24 * REGBYTES(sp)
-    LOAD x25, 25 * REGBYTES(sp)
-    LOAD x26, 26 * REGBYTES(sp)
-    LOAD x27, 27 * REGBYTES(sp)
-    LOAD x28, 28 * REGBYTES(sp)
-    LOAD x29, 29 * REGBYTES(sp)
-    LOAD x30, 30 * REGBYTES(sp)
-    LOAD x31, 31 * REGBYTES(sp)
-
-    addi sp,  sp, 32 * REGBYTES
-    mret
+    j rt_hw_context_switch_exit
 
 #ifdef RT_USING_SMP
 /*
@@ -220,26 +142,42 @@ rt_hw_context_switch_interrupt:
 
     STORE a0, 0(a1)
 
-    csrr  a1, mepc
-    STORE a1, 0 * REGBYTES(a0)
-
-    csrr  a1, mstatus
-    STORE a1, 2 * REGBYTES(a0)
-
     LOAD  sp, 0(a2)
     move  a0, a3
     call rt_cpus_lock_status_restore
 
+    j rt_hw_context_switch_exit
+
+#endif
+
+.global rt_hw_context_switch_exit
+rt_hw_context_switch_exit:
+#ifdef RT_USING_SMP
+#ifdef RT_USING_SIGNALS
+    mv a0, sp
+
+    csrr  t0, mhartid
+    /* switch interrupt stack of current cpu */
+    la    sp, __stack_start__
+    addi  t1, t0, 1
+    li    t2, __STACKSIZE__
+    mul   t1, t1, t2
+    add   sp, sp, t1 /* sp = (cpuid + 1) * __STACKSIZE__ + __stack_start__ */
+
+    call rt_signal_check
+    mv sp, a0
+#endif
+#endif
     /* resw ra to mepc */
-    LOAD a1,   0 * REGBYTES(sp)
-    csrw mepc, a1
+    LOAD a0,   0 * REGBYTES(sp)
+    csrw mepc, a0
+
     LOAD x1,   1 * REGBYTES(sp)
 
-    /* force to machin mode(MPP=11) */
-    li a1, 0x00001800;
-    csrs mstatus, a1
-    LOAD a1,   2 * REGBYTES(sp)
-    csrs mstatus, a1
+    li    t0, 0x00001800
+    csrs  mstatus, t0
+    LOAD a0,   2 * REGBYTES(sp)
+    csrs mstatus, a0
 
     LOAD x4,   4 * REGBYTES(sp)
     LOAD x5,   5 * REGBYTES(sp)
@@ -272,5 +210,3 @@ rt_hw_context_switch_interrupt:
 
     addi sp,  sp, 32 * REGBYTES
     mret
-
-#endif

+ 10 - 47
libcpu/risc-v/k210/interrupt_gcc.S

@@ -20,8 +20,12 @@ trap_entry:
     addi sp, sp, -32 * REGBYTES
 
     STORE x1,   1 * REGBYTES(sp)
-    li    t0,   0x80
-    STORE t0,   2 * REGBYTES(sp)
+
+    csrr  x1, mstatus
+    STORE x1,   2 * REGBYTES(sp)
+
+    csrr  x1, mepc
+    STORE x1, 0 * REGBYTES(sp)
 
     STORE x4,   4 * REGBYTES(sp)
     STORE x5,   5 * REGBYTES(sp)
@@ -75,9 +79,11 @@ trap_entry:
 
 #ifdef RT_USING_SMP
     /* s0 --> sp */
+    mv  sp, s0
     mv  a0, s0
     call rt_scheduler_do_irq_switch
-    mv  sp, s0
+    j   rt_hw_context_switch_exit
+
 #else
 
     /* switch to from_thread stack */
@@ -89,9 +95,6 @@ trap_entry:
     beqz  s2, spurious_interrupt
     sw    zero, 0(s0)
 
-    csrr  a0, mepc
-    STORE a0, 0 * REGBYTES(sp)
-
     la    s0, rt_interrupt_from_thread
     LOAD  s1, 0(s0)
     STORE sp, 0(s1)
@@ -100,47 +103,7 @@ trap_entry:
     LOAD  s1, 0(s0)
     LOAD  sp, 0(s1)
 
-    LOAD  a0,  0 * REGBYTES(sp)
-    csrw  mepc, a0
 #endif
 
 spurious_interrupt:
-    LOAD  x1,   1 * REGBYTES(sp)
-
-    /* Remain in M-mode after mret */
-    li    t0, 0x00001800
-    csrs  mstatus, t0
-    LOAD  t0,   2 * REGBYTES(sp)
-    csrs  mstatus, t0 
-
-    LOAD  x4,   4 * REGBYTES(sp)
-    LOAD  x5,   5 * REGBYTES(sp)
-    LOAD  x6,   6 * REGBYTES(sp)
-    LOAD  x7,   7 * REGBYTES(sp)
-    LOAD  x8,   8 * REGBYTES(sp)
-    LOAD  x9,   9 * REGBYTES(sp)
-    LOAD  x10, 10 * REGBYTES(sp)
-    LOAD  x11, 11 * REGBYTES(sp)
-    LOAD  x12, 12 * REGBYTES(sp)
-    LOAD  x13, 13 * REGBYTES(sp)
-    LOAD  x14, 14 * REGBYTES(sp)
-    LOAD  x15, 15 * REGBYTES(sp)
-    LOAD  x16, 16 * REGBYTES(sp)
-    LOAD  x17, 17 * REGBYTES(sp)
-    LOAD  x18, 18 * REGBYTES(sp)
-    LOAD  x19, 19 * REGBYTES(sp)
-    LOAD  x20, 20 * REGBYTES(sp)
-    LOAD  x21, 21 * REGBYTES(sp)
-    LOAD  x22, 22 * REGBYTES(sp)
-    LOAD  x23, 23 * REGBYTES(sp)
-    LOAD  x24, 24 * REGBYTES(sp)
-    LOAD  x25, 25 * REGBYTES(sp)
-    LOAD  x26, 26 * REGBYTES(sp)
-    LOAD  x27, 27 * REGBYTES(sp)
-    LOAD  x28, 28 * REGBYTES(sp)
-    LOAD  x29, 29 * REGBYTES(sp)
-    LOAD  x30, 30 * REGBYTES(sp)
-    LOAD  x31, 31 * REGBYTES(sp)
-
-    addi  sp, sp, 32 * REGBYTES
-    mret
+    j rt_hw_context_switch_exit

+ 64 - 28
src/scheduler.c

@@ -128,17 +128,9 @@ static struct rt_thread* _get_highest_priority_thread(rt_ubase_t *highest_prio)
     register struct rt_thread *highest_priority_thread;
     register rt_ubase_t highest_ready_priority, local_highest_ready_priority;
     struct rt_cpu* pcpu = rt_cpu_self();
-
 #if RT_THREAD_PRIORITY_MAX > 32
     register rt_ubase_t number;
 
-    if (rt_thread_ready_priority_group == 0 && pcpu->priority_group == 0)
-    {
-        *highest_prio = pcpu->current_thread->current_priority;
-        /* only local IDLE is readly */
-        return pcpu->current_thread;
-    }
-
     number = __rt_ffs(rt_thread_ready_priority_group) - 1;
     highest_ready_priority = (number << 3) + __rt_ffs(rt_thread_ready_table[number]) - 1;
     number = __rt_ffs(pcpu->priority_group) - 1;
@@ -322,8 +314,23 @@ void rt_schedule(void)
     if (pcpu->irq_nest)
     {
         pcpu->irq_switch_flag = 1;
+        rt_hw_interrupt_enable(level);
+        goto __exit;
     }
-    else if (current_thread->scheduler_lock_nest == 1) /* whether lock scheduler */
+
+#ifdef RT_USING_SIGNALS
+    if ((current_thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND)
+    {
+        /* if current_thread signal is in pending */
+
+        if ((current_thread->stat & RT_THREAD_STAT_SIGNAL_MASK) & RT_THREAD_STAT_SIGNAL_PENDING)
+        {
+            rt_thread_resume(current_thread);
+        }
+    }
+#endif
+
+    if (current_thread->scheduler_lock_nest == 1) /* whether lock scheduler */
     {
         rt_ubase_t highest_ready_priority;
 
@@ -366,27 +373,32 @@ void rt_schedule(void)
                 _rt_scheduler_stack_check(to_thread);
 #endif
 
-                {
-                    extern void rt_thread_handle_sig(rt_bool_t clean_state);
-
-                    rt_hw_context_switch((rt_ubase_t)&current_thread->sp,
-                                         (rt_ubase_t)&to_thread->sp, to_thread);
-
-                    /* enable interrupt */
-                    rt_hw_interrupt_enable(level);
-
-#ifdef RT_USING_SIGNALS
-                    /* check signal status */
-                    rt_thread_handle_sig(RT_TRUE);
-#endif
-                    goto __exit;
-                }
+                rt_hw_context_switch((rt_ubase_t)&current_thread->sp,
+                        (rt_ubase_t)&to_thread->sp, to_thread);
             }
         }
     }
 
+#ifdef RT_USING_SIGNALS
+    if (current_thread->stat & RT_THREAD_STAT_SIGNAL_PENDING)
+    {
+        extern void rt_thread_handle_sig(rt_bool_t clean_state);
+
+        current_thread->stat &= ~RT_THREAD_STAT_SIGNAL_PENDING;
+
+        rt_hw_interrupt_enable(level);
+
+        /* check signal status */
+        rt_thread_handle_sig(RT_TRUE);
+    }
+    else
+    {
+        rt_hw_interrupt_enable(level);
+    }
+#else
     /* enable interrupt */
     rt_hw_interrupt_enable(level);
+#endif
 
 __exit:
     return ;
@@ -465,13 +477,25 @@ void rt_schedule(void)
 
                     rt_hw_context_switch((rt_ubase_t)&from_thread->sp,
                             (rt_ubase_t)&to_thread->sp);
+#ifdef RT_USING_SIGNALS
+                    if (rt_current_thread->stat & RT_THREAD_STAT_SIGNAL_PENDING)
+                    {
+                        extern void rt_thread_handle_sig(rt_bool_t clean_state);
 
+                        rt_current_thread->stat &= ~RT_THREAD_STAT_SIGNAL_PENDING;
+
+                        rt_hw_interrupt_enable(level);
+
+                        /* check signal status */
+                        rt_thread_handle_sig(RT_TRUE);
+                    }
+                    else
+                    {
+                        rt_hw_interrupt_enable(level);
+                    }
+#else
                     /* enable interrupt */
                     rt_hw_interrupt_enable(level);
-
-#ifdef RT_USING_SIGNALS
-                    /* check signal status */
-                    rt_thread_handle_sig(RT_TRUE);
 #endif
                     goto __exit;
                 }
@@ -519,6 +543,18 @@ void rt_scheduler_do_irq_switch(void *context)
     pcpu   = rt_cpu_index(cpu_id);
     current_thread = pcpu->current_thread;
 
+#ifdef RT_USING_SIGNALS
+    if ((current_thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND)
+    {
+        /* if current_thread signal is in pending */
+
+        if ((current_thread->stat & RT_THREAD_STAT_SIGNAL_MASK) & RT_THREAD_STAT_SIGNAL_PENDING)
+        {
+            rt_thread_resume(current_thread);
+        }
+    }
+#endif
+
     if (pcpu->irq_switch_flag == 0)
     {
         rt_hw_interrupt_enable(level);

+ 140 - 39
src/signal.c

@@ -23,7 +23,7 @@
 #endif
 
 #define DBG_TAG    "SIGN"
-#define DBG_LVL           DBG_INFO
+#define DBG_LVL           DBG_WARNING
 #include <rtdbg.h>
 
 #define sig_mask(sig_no)    (1u << sig_no)
@@ -52,17 +52,28 @@ static void _signal_entry(void *parameter)
     /* handle signal */
     rt_thread_handle_sig(RT_FALSE);
 
-    /* never come back... */
-    rt_hw_interrupt_disable();
+#ifdef RT_USING_SMP
+    {
+        struct rt_cpu* pcpu = rt_cpu_self();
+
+        pcpu->current_thread->cpus_lock_nest--;
+        if (pcpu->current_thread->cpus_lock_nest == 0)
+        {
+            pcpu->current_thread->scheduler_lock_nest--;
+        }
+
+    }
+#else
     /* return to thread */
     tid->sp = tid->sig_ret;
     tid->sig_ret = RT_NULL;
+#endif
 
     LOG_D("switch back to: 0x%08x\n", tid->sp);
     tid->stat &= ~RT_THREAD_STAT_SIGNAL;
 
 #ifdef RT_USING_SMP
-    rt_hw_context_switch_to((rt_ubase_t)&(tid->sp), tid);
+    rt_hw_context_switch_to((rt_base_t)&parameter, tid);
 #else
     rt_hw_context_switch_to((rt_ubase_t)&(tid->sp));
 #endif /*RT_USING_SMP*/
@@ -82,16 +93,21 @@ static void _signal_deliver(rt_thread_t tid)
 {
     rt_ubase_t level;
 
+    level = rt_hw_interrupt_disable();
+
     /* thread is not interested in pended signals */
-    if (!(tid->sig_pending & tid->sig_mask)) return;
+    if (!(tid->sig_pending & tid->sig_mask))
+    {
+        rt_hw_interrupt_enable(level);
+        return;
+    }
 
-    level = rt_hw_interrupt_disable();
     if ((tid->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND)
     {
         /* resume thread to handle signal */
         rt_thread_resume(tid);
         /* add signal state */
-        tid->stat |= RT_THREAD_STAT_SIGNAL;
+        tid->stat |= (RT_THREAD_STAT_SIGNAL | RT_THREAD_STAT_SIGNAL_PENDING);
 
         rt_hw_interrupt_enable(level);
 
@@ -108,17 +124,36 @@ static void _signal_deliver(rt_thread_t tid)
             rt_hw_interrupt_enable(level);
 
             /* do signal action in self thread context */
-            rt_thread_handle_sig(RT_TRUE);
+            if (rt_interrupt_get_nest() == 0)
+            {
+                rt_thread_handle_sig(RT_TRUE);
+            }
         }
         else if (!((tid->stat & RT_THREAD_STAT_SIGNAL_MASK) & RT_THREAD_STAT_SIGNAL))
         {
             /* add signal state */
-            tid->stat |= RT_THREAD_STAT_SIGNAL;
+            tid->stat |= (RT_THREAD_STAT_SIGNAL | RT_THREAD_STAT_SIGNAL_PENDING);
 
+#ifdef RT_USING_SMP
+            {
+                int cpu_id;
+
+                cpu_id = tid->oncpu;
+                if ((cpu_id != RT_CPU_DETACHED) && (cpu_id != rt_hw_cpu_id()))
+                {
+                    rt_uint32_t cpu_mask;
+
+                    cpu_mask = RT_CPU_MASK ^ (1 << cpu_id);
+                    rt_hw_ipi_send(RT_SCHEDULE_IPI, cpu_mask);
+                }
+            }
+#else
             /* point to the signal handle entry */
+            tid->stat &= ~RT_THREAD_STAT_SIGNAL_PENDING;
             tid->sig_ret = tid->sp;
             tid->sp = rt_hw_stack_init((void *)_signal_entry, RT_NULL,
                                        (void *)((char *)tid->sig_ret - 32), RT_NULL);
+#endif
 
             rt_hw_interrupt_enable(level);
             LOG_D("signal stack pointer @ 0x%08x", tid->sp);
@@ -133,14 +168,53 @@ static void _signal_deliver(rt_thread_t tid)
     }
 }
 
+#ifdef RT_USING_SMP
+void *rt_signal_check(void* context)
+{
+    rt_base_t level;
+    int cpu_id;
+    struct rt_cpu* pcpu;
+    struct rt_thread *current_thread;
+
+    level = rt_hw_interrupt_disable();
+    cpu_id = rt_hw_cpu_id();
+    pcpu   = rt_cpu_index(cpu_id);
+    current_thread = pcpu->current_thread;
+
+    if (pcpu->irq_nest)
+    {
+        rt_hw_interrupt_enable(level);
+        return context;
+    }
+
+    if (current_thread->cpus_lock_nest == 1)
+    {
+        if (current_thread->stat & RT_THREAD_STAT_SIGNAL_PENDING)
+        {
+            void *sig_context;
+
+            current_thread->stat &= ~RT_THREAD_STAT_SIGNAL_PENDING;
+
+            rt_hw_interrupt_enable(level);
+            sig_context = rt_hw_stack_init((void *)_signal_entry, context,
+                    (void *)(context - 32), RT_NULL);
+            return sig_context;
+        }
+    }
+    rt_hw_interrupt_enable(level);
+    return context;
+}
+#endif
+
 rt_sighandler_t rt_signal_install(int signo, rt_sighandler_t handler)
 {
+    rt_base_t level;
     rt_sighandler_t old = RT_NULL;
     rt_thread_t tid = rt_thread_self();
 
     if (!sig_valid(signo)) return SIG_ERR;
 
-    rt_enter_critical();
+    level = rt_hw_interrupt_disable();
     if (tid->sig_vectors == RT_NULL)
     {
         rt_thread_alloc_sig(tid);
@@ -154,7 +228,7 @@ rt_sighandler_t rt_signal_install(int signo, rt_sighandler_t handler)
         else if (handler == SIG_DFL) tid->sig_vectors[signo] = _signal_default_handler;
         else tid->sig_vectors[signo] = handler;
     }
-    rt_exit_critical();
+    rt_hw_interrupt_enable(level);
 
     return old;
 }
@@ -272,7 +346,20 @@ __done:
 
             LOG_D("sigwait: %d sig raised!", signo);
             if (si_prev) si_prev->list.next = si_node->list.next;
-            else tid->si_list = si_node->list.next;
+            else
+            {
+                struct siginfo_node *node_next;
+
+                if (si_node->list.next)
+                {
+                    node_next = (void *)rt_slist_entry(si_node->list.next, struct siginfo_node, list);
+                    tid->si_list = node_next;
+                }
+                else
+                {
+                    tid->si_list = RT_NULL;
+                }
+            }
 
             /* clear pending */
             tid->sig_pending &= ~sig_mask(signo);
@@ -281,7 +368,14 @@ __done:
         }
 
         si_prev = si_node;
-        si_node = (void *)rt_slist_entry(si_node->list.next, struct siginfo_node, list);
+        if (si_node->list.next)
+        {
+            si_node = (void *)rt_slist_entry(si_node->list.next, struct siginfo_node, list);
+        }
+        else
+        {
+            si_node = RT_NULL;
+        }
      }
 
 __done_int:
@@ -320,13 +414,13 @@ void rt_thread_handle_sig(rt_bool_t clean_state)
 
                 signo   = si_node->si.si_signo;
                 handler = tid->sig_vectors[signo];
+                tid->sig_pending &= ~sig_mask(signo);
                 rt_hw_interrupt_enable(level);
 
                 LOG_D("handle signal: %d, handler 0x%08x", signo, handler);
                 if (handler) handler(signo);
 
                 level = rt_hw_interrupt_disable();
-                tid->sig_pending &= ~sig_mask(signo);
                 error = -RT_EINTR;
 
                 rt_mp_free(si_node); /* release this siginfo node */
@@ -335,10 +429,16 @@ void rt_thread_handle_sig(rt_bool_t clean_state)
             }
 
             /* whether clean signal status */
-            if (clean_state == RT_TRUE) tid->stat &= ~RT_THREAD_STAT_SIGNAL;
+            if (clean_state == RT_TRUE)
+            {
+                tid->stat &= ~RT_THREAD_STAT_SIGNAL;
+            }
+            else
+            {
+                return;
+            }
         }
     }
-
     rt_hw_interrupt_enable(level);
 }
 
@@ -364,30 +464,30 @@ void rt_thread_alloc_sig(rt_thread_t tid)
 void rt_thread_free_sig(rt_thread_t tid)
 {
     rt_base_t level;
-    struct siginfo_node *si_list;
+    struct siginfo_node *si_node;
     rt_sighandler_t *sig_vectors;
 
     level = rt_hw_interrupt_disable();
-    si_list = (struct siginfo_node *)tid->si_list;
+    si_node = (struct siginfo_node *)tid->si_list;
     tid->si_list = RT_NULL;
 
     sig_vectors = tid->sig_vectors;
     tid->sig_vectors = RT_NULL;
     rt_hw_interrupt_enable(level);
 
-    if (si_list)
+    if (si_node)
     {
         struct rt_slist_node *node;
-        struct siginfo_node  *si_node;
+        struct rt_slist_node *node_to_free;
 
         LOG_D("free signal info list");
-        node = &(si_list->list);
+        node = &(si_node->list);
         do
         {
-            si_node = rt_slist_entry(node, struct siginfo_node, list);
-            rt_mp_free(si_node);
-
+            node_to_free = node;
             node = node->next;
+            si_node = rt_slist_entry(node_to_free, struct siginfo_node, list);
+            rt_mp_free(si_node);
         } while (node);
     }
 
@@ -418,30 +518,23 @@ int rt_thread_kill(rt_thread_t tid, int sig)
         struct rt_slist_node *node;
         struct siginfo_node  *entry;
 
-        node = (struct rt_slist_node *)tid->si_list;
-        rt_hw_interrupt_enable(level);
+        si_node = (struct siginfo_node *)tid->si_list;
+        if (si_node)
+            node = (struct rt_slist_node *)&si_node->list;
+        else
+            node = RT_NULL;
 
         /* update sig info */
-        rt_enter_critical();
         for (; (node) != RT_NULL; node = node->next)
         {
             entry = rt_slist_entry(node, struct siginfo_node, list);
             if (entry->si.si_signo == sig)
             {
                 memcpy(&(entry->si), &si, sizeof(siginfo_t));
-                rt_exit_critical();
+                rt_hw_interrupt_enable(level);
                 return 0;
             }
         }
-        rt_exit_critical();
-
-        /* disable interrupt to protect tcb */
-        level = rt_hw_interrupt_disable();
-    }
-    else
-    {
-        /* a new signal */
-        tid->sig_pending |= sig_mask(sig);
     }
     rt_hw_interrupt_enable(level);
 
@@ -452,14 +545,22 @@ int rt_thread_kill(rt_thread_t tid, int sig)
         memcpy(&(si_node->si), &si, sizeof(siginfo_t));
 
         level = rt_hw_interrupt_disable();
-        if (!tid->si_list) tid->si_list = si_node;
-        else
+
+        if (tid->si_list)
         {
             struct siginfo_node *si_list;
 
             si_list = (struct siginfo_node *)tid->si_list;
             rt_slist_append(&(si_list->list), &(si_node->list));
         }
+        else
+        {
+            tid->si_list = si_node;
+        }
+
+        /* a new signal */
+        tid->sig_pending |= sig_mask(sig);
+
         rt_hw_interrupt_enable(level);
     }
     else

+ 2 - 0
src/thread.c

@@ -191,7 +191,9 @@ static rt_err_t _rt_thread_init(struct rt_thread *thread,
     thread->sig_mask    = 0x00;
     thread->sig_pending = 0x00;
 
+#ifndef RT_USING_SMP
     thread->sig_ret     = RT_NULL;
+#endif
     thread->sig_vectors = RT_NULL;
     thread->si_list     = RT_NULL;
 #endif