diff --git a/bsp/k210/.config b/bsp/k210/.config index c7594a6301..e915942d65 100644 --- a/bsp/k210/.config +++ b/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 diff --git a/bsp/k210/rtconfig.h b/bsp/k210/rtconfig.h index e23e86aeb8..71fc783097 100644 --- a/bsp/k210/rtconfig.h +++ b/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 */ diff --git a/bsp/k210/rtconfig.py b/bsp/k210/rtconfig.py index 47ee1cc932..b9258cd374 100755 --- a/bsp/k210/rtconfig.py +++ b/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) diff --git a/include/rtdef.h b/include/rtdef.h index 743b91d959..2aff4afdb0 100644 --- a/include/rtdef.h +++ b/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 diff --git a/libcpu/arm/cortex-a/context_gcc.S b/libcpu/arm/cortex-a/context_gcc.S index af5c516e4d..dff7a1de68 100644 --- a/libcpu/arm/cortex-a/context_gcc.S +++ b/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 */ + diff --git a/libcpu/arm/cortex-a/start_gcc.S b/libcpu/arm/cortex-a/start_gcc.S index 51026b7ed5..014846f3aa 100644 --- a/libcpu/arm/cortex-a/start_gcc.S +++ b/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 + /* 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 + + cps #Mode_SVC + mov sp, r8 + mov r0, r8 + bl rt_scheduler_do_irq_switch + + 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 -#ifdef RT_USING_SMP - mov r0, sp - bl rt_scheduler_do_irq_switch - - ldmfd sp!, {r0-r12,lr} - subs pc, lr, #4 -#else @ 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 diff --git a/libcpu/risc-v/common/context_gcc.S b/libcpu/risc-v/common/context_gcc.S index 62e64d8104..f28b15319b 100644 --- a/libcpu/risc-v/common/context_gcc.S +++ b/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 diff --git a/libcpu/risc-v/k210/interrupt_gcc.S b/libcpu/risc-v/k210/interrupt_gcc.S index aeda72ab31..0393ea51f8 100644 --- a/libcpu/risc-v/k210/interrupt_gcc.S +++ b/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 diff --git a/src/scheduler.c b/src/scheduler.c index be29d9a7e0..b487bd4b60 100644 --- a/src/scheduler.c +++ b/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)¤t_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)¤t_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); diff --git a/src/signal.c b/src/signal.c index 06c2055d26..bea3615d34 100644 --- a/src/signal.c +++ b/src/signal.c @@ -23,7 +23,7 @@ #endif #define DBG_TAG "SIGN" -#define DBG_LVL DBG_INFO +#define DBG_LVL DBG_WARNING #include #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)¶meter, 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; - /* thread is not interested in pended signals */ - if (!(tid->sig_pending & tid->sig_mask)) return; - level = rt_hw_interrupt_disable(); + + /* thread is not interested in pended signals */ + if (!(tid->sig_pending & tid->sig_mask)) + { + rt_hw_interrupt_enable(level); + return; + } + 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 diff --git a/src/thread.c b/src/thread.c index 0f2e1dc3d0..276bba9938 100644 --- a/src/thread.c +++ b/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