mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 00:14:22 +08:00
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
This commit is contained in:
@@ -4406,3 +4406,6 @@
|
|||||||
up_release_stack.c: If creating or releasing the stack for a kernel
|
up_release_stack.c: If creating or releasing the stack for a kernel
|
||||||
thread, use the kernel allocator so that the kernel thread stacks
|
thread, use the kernel allocator so that the kernel thread stacks
|
||||||
are protected from user application meddling (2013-03-20).
|
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)
|
||||||
|
|
||||||
|
|||||||
@@ -156,7 +156,10 @@ static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1,
|
|||||||
return reg0;
|
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,
|
static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1,
|
||||||
uintptr_t parm2, uintptr_t parm3,
|
uintptr_t parm2, uintptr_t parm3,
|
||||||
@@ -180,7 +183,10 @@ static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1,
|
|||||||
return reg0;
|
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,
|
static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1,
|
||||||
uintptr_t parm2, uintptr_t parm3,
|
uintptr_t parm2, uintptr_t parm3,
|
||||||
@@ -205,7 +211,10 @@ static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1,
|
|||||||
return reg0;
|
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,
|
static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1,
|
||||||
uintptr_t parm2, uintptr_t parm3,
|
uintptr_t parm2, uintptr_t parm3,
|
||||||
|
|||||||
@@ -156,7 +156,10 @@ static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1,
|
|||||||
return reg0;
|
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,
|
static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1,
|
||||||
uintptr_t parm2, uintptr_t parm3,
|
uintptr_t parm2, uintptr_t parm3,
|
||||||
@@ -180,7 +183,10 @@ static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1,
|
|||||||
return reg0;
|
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,
|
static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1,
|
||||||
uintptr_t parm2, uintptr_t parm3,
|
uintptr_t parm2, uintptr_t parm3,
|
||||||
@@ -205,7 +211,10 @@ static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1,
|
|||||||
return reg0;
|
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,
|
static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1,
|
||||||
uintptr_t parm2, uintptr_t parm3,
|
uintptr_t parm2, uintptr_t parm3,
|
||||||
|
|||||||
@@ -91,17 +91,32 @@
|
|||||||
* Name: dispatch_syscall
|
* Name: dispatch_syscall
|
||||||
*
|
*
|
||||||
* Description:
|
* 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.
|
* R0 = SYS_ call number
|
||||||
* R1-R3 - Need to be preserved until the stub is called. The values of
|
* R1 = parm0
|
||||||
* R0 and R1 returned by the stub must be preserved.
|
* R2 = parm1
|
||||||
* R4-R11 must be preserved to support the expectations of the user-space
|
* R3 = parm2
|
||||||
* callee
|
* R4 = parm3
|
||||||
* R12 - Need not be preserved
|
* R5 = parm4
|
||||||
* R13 - (stack pointer)
|
* R6 = parm5
|
||||||
* 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)
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
@@ -112,14 +127,19 @@ static void dispatch_syscall(void)
|
|||||||
__asm__ __volatile__
|
__asm__ __volatile__
|
||||||
(
|
(
|
||||||
" push {r4, r5}\n" /* Save R4 and R5 */
|
" 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 */
|
" mov r5, lr\n" /* Save lr in R5 */
|
||||||
" ldr r4, =g_stublookup\n" /* R4=The base of the stub lookup table */
|
" 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 */
|
" 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 */
|
" ldr r4, [r4, r0]\n" /* R4=Address of the stub for this syscall */
|
||||||
" blx r5\n" /* Call the stub (modifies lr) */
|
" blx r5\n" /* Call the stub (modifies lr) */
|
||||||
" mov lr, r5\n" /* Restore lr */
|
" mov lr, r5\n" /* Restore lr */
|
||||||
" pop {r4, r5}\n" /* Restore R4 and R5*/
|
" add sp, sp, #12\n" /* Destroy the stack frame */
|
||||||
" mov r2, r0\n" /* R2=Saves return value in R0 */
|
" 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 */
|
" mov r0, #3\n" /* R0=SYS_syscall_return */
|
||||||
" svc 0" /* Return from the syscall */
|
" svc 0" /* Return from the syscall */
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -88,20 +88,32 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: dispatch_syscall
|
* Call the stub function corresponding to the system call. NOTE the non-
|
||||||
|
* standard parameter passing:
|
||||||
*
|
*
|
||||||
* Description:
|
* R0 = SYS_ call number
|
||||||
* Call the stub function corresponding to the system call.
|
* R1 = parm0
|
||||||
|
* R2 = parm1
|
||||||
|
* R3 = parm2
|
||||||
|
* R4 = parm3
|
||||||
|
* R5 = parm4
|
||||||
|
* R6 = parm5
|
||||||
*
|
*
|
||||||
* R0 - Need not be preserved until after the stub is called.
|
* The values of R4-R5 may be preserved in the proxy called by the user
|
||||||
* R1-R3 - Need to be preserved until the stub is called. The values of
|
* code if they are used (but otherwise will not be).
|
||||||
* R0 and R1 returned by the stub must be preserved.
|
*
|
||||||
* R4-R11 must be preserved to support the expectations of the user-space
|
* Register usage:
|
||||||
* callee
|
*
|
||||||
* R12 - Need not be preserved
|
* R0 - Need not be preserved.
|
||||||
* R13 - (stack pointer)
|
* R1-R3 - Need to be preserved until the stub is called. The values of
|
||||||
* R14 - Need not be preserved
|
* R0 and R1 returned by the stub must be preserved.
|
||||||
* R15 - (PC)
|
* 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__
|
__asm__ __volatile__
|
||||||
(
|
(
|
||||||
" push {r4}\n" /* Save R4 */
|
" sub sp, sp, #16\n" /* Create a stack frame to hold 3 parms + lr */
|
||||||
" mov r4, lr\n" /* Save lr in R4 */
|
" 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, =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 */
|
" ldr ip, [ip, r0, lsl #2]\n" /* R12=The address of the stub for this syscall */
|
||||||
" blx ip\n" /* Call the stub (modifies lr)*/
|
" blx ip\n" /* Call the stub (modifies lr)*/
|
||||||
" mov lr, r4\n" /* Restore lr */
|
" ldr lr, [sp, #12]\n" /* Restore lr */
|
||||||
" pop {r4}\n" /* Restore r4 */
|
" add sp, sp, #16\n" /* Destroy the stack frame */
|
||||||
" mov r2, r0\n" /* R2=Saved return value in R0 */
|
" mov r2, r0\n" /* R2=Save return value in R2 */
|
||||||
" mov r0, #3\n" /* R0=SYS_syscall_return */
|
" mov r0, #3\n" /* R0=SYS_syscall_return */
|
||||||
" svc 0" /* Return from the syscall */
|
" svc 0" /* Return from the syscall */
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user