diff --git a/include/arch/arm/arch/32/mode/fastpath/fastpath.h b/include/arch/arm/arch/32/mode/fastpath/fastpath.h index ce7a795a3..9495f0b9f 100644 --- a/include/arch/arm/arch/32/mode/fastpath/fastpath.h +++ b/include/arch/arm/arch/32/mode/fastpath/fastpath.h @@ -16,6 +16,7 @@ #include #include #include +#include /* When building the fastpath the assembler in traps.S makes these * assumptions. Because compile_asserts are hard to do in assembler, diff --git a/include/arch/arm/arch/fastpath/fastpath.h b/include/arch/arm/arch/fastpath/fastpath.h index d656a2bee..00b2e0491 100644 --- a/include/arch/arm/arch/fastpath/fastpath.h +++ b/include/arch/arm/arch/fastpath/fastpath.h @@ -17,8 +17,23 @@ void slowpath(syscall_t syscall) VISIBLE NORETURN; -void fastpath_restore(word_t badge, word_t msgInfo, tcb_t *cur_thread) -VISIBLE NORETURN; +static inline void NORETURN fastpath_restore(word_t badge, word_t msgInfo, tcb_t *cur_thread) +{ + register word_t badge_reg asm("r0") = badge; + register word_t msgInfo_reg asm("r1") = msgInfo; + register word_t cur_thread_reg asm("r2") = (word_t)cur_thread; + asm volatile("mov sp, r2 \n\ + add sp, sp, %[LR_SVC_OFFSET] \n\ + ldmdb sp, {r2-lr}^ \n\ + rfeia sp" + : + : [badge]"r"(badge_reg), + [msginfo]"r"(msgInfo_reg), + [cur_thread]"r"(cur_thread_reg), + [LR_SVC_OFFSET]"i"(LR_svc * sizeof(word_t)) + : "memory"); + UNREACHABLE(); +} void fastpath_call(word_t cptr, word_t r_msgInfo) VISIBLE NORETURN SECTION(".vectors.fastpath_call"); diff --git a/include/kernel/traps.h b/include/kernel/traps.h new file mode 100644 index 000000000..7970e2c54 --- /dev/null +++ b/include/kernel/traps.h @@ -0,0 +1,20 @@ +/* + * Copyright 2016, General Dynamics C4 Systems + * + * This software may be distributed and modified according to the terms of + * the GNU General Public License version 2. Note that NO WARRANTY is provided. + * See "LICENSE_GPLv2.txt" for details. + * + * @TAG(GD_GPL) + */ + +#ifndef __KERNEL_TRAPS_H +#define __KERNEL_TRAPS_H + +#include +#include + +void c_handle_syscall(word_t cptr, word_t msgInfo, syscall_t syscall) +VISIBLE SECTION(".vectors.text"); + +#endif /* __KERNEL_TRAPS_H */ diff --git a/include/util.h b/include/util.h index 41c15c03a..95d44ca05 100644 --- a/include/util.h +++ b/include/util.h @@ -38,6 +38,7 @@ #define UNUSED __attribute__((unused)) #define USED __attribute__((used)) #define FASTCALL __attribute__((fastcall)) +#define UNREACHABLE() __builtin_unreachable() #define OFFSETOF(type, member) \ __builtin_offsetof(type, member) diff --git a/src/arch/arm/32/Makefile b/src/arch/arm/32/Makefile index 2f5303725..67873c602 100644 --- a/src/arch/arm/32/Makefile +++ b/src/arch/arm/32/Makefile @@ -15,6 +15,8 @@ include ${SOURCE_ROOT}/src/arch/$(ARCH)/32/kernel/Makefile include ${SOURCE_ROOT}/src/arch/$(ARCH)/32/model/Makefile include ${SOURCE_ROOT}/src/arch/$(ARCH)/32/machine/Makefile +ARCH_C_SOURCES += 32/c_traps.c + ARCH_ASM_SOURCES += 32/halt.S \ 32/head.S \ 32/idle.S \ diff --git a/src/arch/arm/32/c_traps.c b/src/arch/arm/32/c_traps.c new file mode 100644 index 000000000..c32977267 --- /dev/null +++ b/src/arch/arm/32/c_traps.c @@ -0,0 +1,33 @@ +/* + * Copyright 2014, General Dynamics C4 Systems + * + * This software may be distributed and modified according to the terms of + * the GNU General Public License version 2. Note that NO WARRANTY is provided. + * See "LICENSE_GPLv2.txt" for details. + * + * @TAG(GD_GPL) + */ + +#include +#include +#include +#include + +#include + +void VISIBLE c_handle_syscall(word_t cptr, word_t msgInfo, syscall_t syscall) +{ +#ifdef CONFIG_FASTPATH + if (syscall == SysCall) { + fastpath_call(cptr, msgInfo); + } else if (syscall == SysReplyRecv) { + fastpath_reply_recv(cptr, msgInfo); + } +#endif /* CONFIG_FASTPATH */ + + if (unlikely(syscall < SYSCALL_MIN || syscall > SYSCALL_MAX)) { + handleUnknownSyscall(syscall); + } else { + slowpath(syscall); + } +} diff --git a/src/arch/arm/32/traps.S b/src/arch/arm/32/traps.S index 731efc425..0fb987a05 100644 --- a/src/arch/arm/32/traps.S +++ b/src/arch/arm/32/traps.S @@ -93,30 +93,12 @@ BEGIN_FUNC(arm_swi_syscall) /* Store FaultInstruction */ str lr, [sp, #(PT_FaultInstruction - PT_LR_svc)] -#ifdef FASTPATH - cmp r7, #SYSCALL_REPLY_RECV -#endif - /* Stack all user registers */ stmdb sp, {r0-lr}^ /* Load the kernel's real stack pointer */ ldr sp, =(PPTR_KERNEL_STACK_TOP) -#ifdef FASTPATH - /* - * Call is -1 == 0xffffffff. - * We compared against -2 = 0xfffffffe above. - * Performing an unsigned higher than, there is only one unsigned number - * greater than -2. - */ - bhi fastpath_call - beq fastpath_reply_recv -#endif - - /* Load system call number for handleSyscall and handleUnknownSyscall() */ - mov r0, r7 - /* * RET_TO_USER needs ksCurThread. We can issue the load here where we have * some spare cycles, and the ARM ABI will preserve it across function @@ -124,12 +106,11 @@ BEGIN_FUNC(arm_swi_syscall) */ ldr r8, =ksCurThread - /* Check that syscall number is in range */ - add r2, r0, #(-SYSCALL_MIN) - cmp r2, #(SYSCALL_MAX - SYSCALL_MIN + 1) - bhs arm_swi_undefined_syscall - - blx handleSyscall + /* Load system call number as a c_handle_syscall argument. r0 and r1 are passed + * unmodified (cptr and msgIngo respectively. + */ + mov r2, r7 + blx c_handle_syscall /* Return to user. */ RET_TO_USER r8 @@ -152,17 +133,6 @@ BEGIN_FUNC(slowpath) RET_TO_USER r7 END_FUNC(slowpath) -BEGIN_FUNC(fastpath_restore) - /* Duplicate of above except r2 contains ksCurThread, - r0 and r1 should be preserved */ - mov sp, r2 - add sp, sp, #PT_LR_svc - - ldmdb sp, {r2-lr}^ - - rfeia sp -END_FUNC(fastpath_restore) - BEGIN_FUNC(arm_prefetch_abort_exception) /* Full save/restore, documented in arm_swi_syscall */ srsia #PMODE_SUPERVISOR