summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-03-21 00:25:17 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-03-21 00:25:17 +0000
commit55a46f0500f36567ce352048454534135aff92f2 (patch)
tree8b08f2ca6a982e81e2f644e07f52525ff9a35053
parentae6758d5518a0e92f10476592dc156af38f36244 (diff)
downloadnuttx-55a46f0500f36567ce352048454534135aff92f2.tar.gz
nuttx-55a46f0500f36567ce352048454534135aff92f2.tar.bz2
nuttx-55a46f0500f36567ce352048454534135aff92f2.zip
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
-rw-r--r--nuttx/ChangeLog3
-rw-r--r--nuttx/arch/arm/include/armv6-m/syscall.h15
-rw-r--r--nuttx/arch/arm/include/armv7-m/syscall.h15
-rw-r--r--nuttx/arch/arm/src/armv6-m/up_svcall.c44
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_svcall.c49
5 files changed, 91 insertions, 35 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index bddcb4367..7f6a2b421 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/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/nuttx/arch/arm/include/armv6-m/syscall.h b/nuttx/arch/arm/include/armv6-m/syscall.h
index 9548ae494..863a7afec 100644
--- a/nuttx/arch/arm/include/armv6-m/syscall.h
+++ b/nuttx/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/nuttx/arch/arm/include/armv7-m/syscall.h b/nuttx/arch/arm/include/armv7-m/syscall.h
index 91220f359..f6321fb4a 100644
--- a/nuttx/arch/arm/include/armv7-m/syscall.h
+++ b/nuttx/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/nuttx/arch/arm/src/armv6-m/up_svcall.c b/nuttx/arch/arm/src/armv6-m/up_svcall.c
index cf9396414..c917992ae 100644
--- a/nuttx/arch/arm/src/armv6-m/up_svcall.c
+++ b/nuttx/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/nuttx/arch/arm/src/armv7-m/up_svcall.c b/nuttx/arch/arm/src/armv7-m/up_svcall.c
index e41b8c4c5..9f3a4ffaa 100644
--- a/nuttx/arch/arm/src/armv7-m/up_svcall.c
+++ b/nuttx/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
+ *
+ * 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 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 - 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 */
);