From cce585e320cc43514f1ab53b4d2b36852ccf82d0 Mon Sep 17 00:00:00 2001 From: patacongo Date: Thu, 21 Mar 2013 00:25:17 +0000 Subject: [PATCH] Fix syscall parameter passing for the case where the number of parameters is >4 git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5767 42af7a65-404d-4744-a932-0658087f49c3 --- ChangeLog | 3 ++ arch/arm/include/armv6-m/syscall.h | 15 +++++++-- arch/arm/include/armv7-m/syscall.h | 15 +++++++-- arch/arm/src/armv6-m/up_svcall.c | 44 +++++++++++++++++++-------- arch/arm/src/armv7-m/up_svcall.c | 49 +++++++++++++++++++----------- 5 files changed, 91 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index bddcb4367b..7f6a2b421e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4406,3 +4406,6 @@ up_release_stack.c: If creating or releasing the stack for a kernel thread, use the kernel allocator so that the kernel thread stacks are protected from user application meddling (2013-03-20). + * arch/arm/src/armv[6|7]-m/up_scall.c: Fix parameter passing for + all system call inline functions with > 3 parameters (2013-03-20) + diff --git a/arch/arm/include/armv6-m/syscall.h b/arch/arm/include/armv6-m/syscall.h index 9548ae4942..863a7afeca 100644 --- a/arch/arm/include/armv6-m/syscall.h +++ b/arch/arm/include/armv6-m/syscall.h @@ -156,7 +156,10 @@ static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, return reg0; } -/* SVC call with SYS_ call number and four parameters */ +/* SVC call with SYS_ call number and four parameters. + * + * NOTE the nonstandard parameter passing: parm4 is in R4 + */ static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3, @@ -180,7 +183,10 @@ static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, return reg0; } -/* SVC call with SYS_ call number and five parameters */ +/* SVC call with SYS_ call number and five parameters. + * + * NOTE the nonstandard parameter passing: parm4 and parm5 are in R4 and R5 + */ static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3, @@ -205,7 +211,10 @@ static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, return reg0; } -/* SVC call with SYS_ call number and six parameters */ +/* SVC call with SYS_ call number and six parameters. + * + * NOTE the nonstandard parameter passing: parm4-parm6 are in R4-R6 + */ static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3, diff --git a/arch/arm/include/armv7-m/syscall.h b/arch/arm/include/armv7-m/syscall.h index 91220f3591..f6321fb4a2 100644 --- a/arch/arm/include/armv7-m/syscall.h +++ b/arch/arm/include/armv7-m/syscall.h @@ -156,7 +156,10 @@ static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, return reg0; } -/* SVC call with SYS_ call number and four parameters */ +/* SVC call with SYS_ call number and four parameters. + * + * NOTE the nonstandard parameter passing: parm4 is in R4 + */ static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3, @@ -180,7 +183,10 @@ static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, return reg0; } -/* SVC call with SYS_ call number and five parameters */ +/* SVC call with SYS_ call number and five parameters. + * + * NOTE the nonstandard parameter passing: parm4 and parm5 are in R4 and R5 + */ static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3, @@ -205,7 +211,10 @@ static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, return reg0; } -/* SVC call with SYS_ call number and six parameters */ +/* SVC call with SYS_ call number and six parameters. + * + * NOTE the nonstandard parameter passing: parm4-parm6 are in R4-R6 + */ static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3, diff --git a/arch/arm/src/armv6-m/up_svcall.c b/arch/arm/src/armv6-m/up_svcall.c index cf9396414f..c917992ae5 100644 --- a/arch/arm/src/armv6-m/up_svcall.c +++ b/arch/arm/src/armv6-m/up_svcall.c @@ -91,17 +91,32 @@ * Name: dispatch_syscall * * Description: - * Call the stub function corresponding to the system call. + * Call the stub function corresponding to the system call. NOTE the non- + * standard parameter passing: * - * R0 - Need not be preserved until after the stub is called. - * R1-R3 - Need to be preserved until the stub is called. The values of - * R0 and R1 returned by the stub must be preserved. - * R4-R11 must be preserved to support the expectations of the user-space - * callee - * R12 - Need not be preserved - * R13 - (stack pointer) - * R14 - Need not be preserved - * R15 - (PC) + * R0 = SYS_ call number + * R1 = parm0 + * R2 = parm1 + * R3 = parm2 + * R4 = parm3 + * R5 = parm4 + * R6 = parm5 + * + * The values of R4-R5 may be preserved in the proxy called by the user + * code if they are used (but otherwise will not be). + * + * Register usage: + * + * R0 - Need not be preserved. + * R1-R3 - Need to be preserved until the stub is called. The values of + * R0 and R1 returned by the stub must be preserved. + * R4-R11 must be preserved to support the expectations of the user-space + * callee. R4-R6 may have been preserved by the proxy, but don't know + * for sure. + * R12 - Need not be preserved + * R13 - (stack pointer) + * R14 - Need not be preserved + * R15 - (PC) * ****************************************************************************/ @@ -112,14 +127,19 @@ static void dispatch_syscall(void) __asm__ __volatile__ ( " push {r4, r5}\n" /* Save R4 and R5 */ + " sub sp, sp, #12\n" /* Create a stack frame to hold 3 parms */ + " str r4, [sp, #0]\n" /* Move parameter 4 (if any) into position */ + " str r5, [sp, #4]\n" /* Move parameter 5 (if any) into position */ + " str r6, [sp, #8]\n" /* Move parameter 6 (if any) into position */ " mov r5, lr\n" /* Save lr in R5 */ " ldr r4, =g_stublookup\n" /* R4=The base of the stub lookup table */ " lsl r0, r0, #2\n" /* R0=Offset of the stub for this syscall */ " ldr r4, [r4, r0]\n" /* R4=Address of the stub for this syscall */ " blx r5\n" /* Call the stub (modifies lr) */ " mov lr, r5\n" /* Restore lr */ - " pop {r4, r5}\n" /* Restore R4 and R5*/ - " mov r2, r0\n" /* R2=Saves return value in R0 */ + " add sp, sp, #12\n" /* Destroy the stack frame */ + " pop {r4, r5}\n" /* Recover R4 and R5 */ + " mov r2, r0\n" /* R2=Save return value in R2 */ " mov r0, #3\n" /* R0=SYS_syscall_return */ " svc 0" /* Return from the syscall */ ); diff --git a/arch/arm/src/armv7-m/up_svcall.c b/arch/arm/src/armv7-m/up_svcall.c index e41b8c4c58..9f3a4ffaa6 100644 --- a/arch/arm/src/armv7-m/up_svcall.c +++ b/arch/arm/src/armv7-m/up_svcall.c @@ -88,20 +88,32 @@ ****************************************************************************/ /**************************************************************************** - * Name: dispatch_syscall + * Call the stub function corresponding to the system call. NOTE the non- + * standard parameter passing: * - * Description: - * Call the stub function corresponding to the system call. + * R0 = SYS_ call number + * R1 = parm0 + * R2 = parm1 + * R3 = parm2 + * R4 = parm3 + * R5 = parm4 + * R6 = parm5 * - * R0 - Need not be preserved until after the stub is called. - * R1-R3 - Need to be preserved until the stub is called. The values of - * R0 and R1 returned by the stub must be preserved. - * R4-R11 must be preserved to support the expectations of the user-space - * callee - * R12 - Need not be preserved - * R13 - (stack pointer) - * R14 - Need not be preserved - * R15 - (PC) + * The values of R4-R5 may be preserved in the proxy called by the user + * code if they are used (but otherwise will not be). + * + * Register usage: + * + * R0 - Need not be preserved. + * R1-R3 - Need to be preserved until the stub is called. The values of + * R0 and R1 returned by the stub must be preserved. + * R4-R11 must be preserved to support the expectations of the user-space + * callee. R4-R6 may have been preserved by the proxy, but don't know + * for sure. + * R12 - Need not be preserved + * R13 - (stack pointer) + * R14 - Need not be preserved + * R15 - (PC) * ****************************************************************************/ @@ -111,14 +123,17 @@ static void dispatch_syscall(void) { __asm__ __volatile__ ( - " push {r4}\n" /* Save R4 */ - " mov r4, lr\n" /* Save lr in R4 */ + " sub sp, sp, #16\n" /* Create a stack frame to hold 3 parms + lr */ + " str r4, [sp, #0]\n" /* Move parameter 4 (if any) into position */ + " str r5, [sp, #4]\n" /* Move parameter 5 (if any) into position */ + " str r6, [sp, #8]\n" /* Move parameter 6 (if any) into position */ + " str lr, [sp, #12]\n" /* Save lr in the stack frame */ " ldr ip, =g_stublookup\n" /* R12=The base of the stub lookup table */ " ldr ip, [ip, r0, lsl #2]\n" /* R12=The address of the stub for this syscall */ " blx ip\n" /* Call the stub (modifies lr)*/ - " mov lr, r4\n" /* Restore lr */ - " pop {r4}\n" /* Restore r4 */ - " mov r2, r0\n" /* R2=Saved return value in R0 */ + " ldr lr, [sp, #12]\n" /* Restore lr */ + " add sp, sp, #16\n" /* Destroy the stack frame */ + " mov r2, r0\n" /* R2=Save return value in R2 */ " mov r0, #3\n" /* R0=SYS_syscall_return */ " svc 0" /* Return from the syscall */ );