summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-03-17 16:13:28 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-03-17 16:13:28 +0000
commit2b2bbf6433f7271abce9c3e4cbdf2f456fcbeca3 (patch)
treedf9b3967acb62fff1190b1625cf373b8ed95f48a /nuttx/arch/arm/src
parentdb8769c0dbd3a9c33b60863a62f33cc5158bf7bd (diff)
downloadpx4-nuttx-2b2bbf6433f7271abce9c3e4cbdf2f456fcbeca3.tar.gz
px4-nuttx-2b2bbf6433f7271abce9c3e4cbdf2f456fcbeca3.tar.bz2
px4-nuttx-2b2bbf6433f7271abce9c3e4cbdf2f456fcbeca3.zip
Add support for nested system calls
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5752 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/arm/src')
-rw-r--r--nuttx/arch/arm/src/armv6-m/up_svcall.c19
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_svcall.c19
2 files changed, 22 insertions, 16 deletions
diff --git a/nuttx/arch/arm/src/armv6-m/up_svcall.c b/nuttx/arch/arm/src/armv6-m/up_svcall.c
index 745800532..cf9396414 100644
--- a/nuttx/arch/arm/src/armv6-m/up_svcall.c
+++ b/nuttx/arch/arm/src/armv6-m/up_svcall.c
@@ -258,18 +258,19 @@ int up_svcall(int irq, FAR void *context)
case SYS_syscall_return:
{
struct tcb_s *rtcb = sched_self();
+ int index = (int)rtcb->xcp.nsyscalls - 1;
/* Make sure that there is a saved syscall return address. */
- DEBUGASSERT(rtcb->xcp.sysreturn != 0);
+ DEBUGASSERT(index >= 0);
/* Setup to return to the saved syscall return address in
* the original mode.
*/
- regs[REG_PC] = rtcb->xcp.sysreturn;
- regs[REG_EXC_RETURN] = rtcb->xcp.excreturn;
- rtcb->xcp.sysreturn = 0;
+ regs[REG_PC] = rtcb->xcp.syscall[index].sysreturn;
+ regs[REG_EXC_RETURN] = rtcb->xcp.syscall[index].excreturn;
+ rtcb->xcp.nsyscalls = index;
/* The return value must be in R0-R1. dispatch_syscall() temporarily
* moved the value for R0 into R2.
@@ -425,6 +426,7 @@ int up_svcall(int irq, FAR void *context)
{
#ifdef CONFIG_NUTTX_KERNEL
FAR struct tcb_s *rtcb = sched_self();
+ int index = rtcb->xcp.nsyscalls;
/* Verify that the SYS call number is within range */
@@ -434,19 +436,20 @@ int up_svcall(int irq, FAR void *context)
* cannot yet handle nested system calls.
*/
- DEBUGASSERT(rtcb->xcp.sysreturn == 0);
+ DEBUGASSERT(index < CONFIG_SYS_NNEST);
/* Setup to return to dispatch_syscall in privileged mode. */
- rtcb->xcp.sysreturn = regs[REG_PC];
- rtcb->xcp.excreturn = regs[REG_EXC_RETURN];
+ rtcb->xcp.syscall[index].sysreturn = regs[REG_PC];
+ rtcb->xcp.syscall[index].excreturn = regs[REG_EXC_RETURN];
+ rtcb->xcp.nsyscalls = index + 1;
regs[REG_PC] = (uint32_t)dispatch_syscall;
regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
/* Offset R0 to account for the reserved values */
- regs[REG_R0] -= CONFIG_SYS_RESERVED;
+ regs[REG_R0] -= CONFIG_SYS_RESERVED;
#else
slldbg("ERROR: Bad SYS call: %d\n", regs[REG_R0]);
#endif
diff --git a/nuttx/arch/arm/src/armv7-m/up_svcall.c b/nuttx/arch/arm/src/armv7-m/up_svcall.c
index ab313671c..e41b8c4c5 100644
--- a/nuttx/arch/arm/src/armv7-m/up_svcall.c
+++ b/nuttx/arch/arm/src/armv7-m/up_svcall.c
@@ -262,18 +262,19 @@ int up_svcall(int irq, FAR void *context)
case SYS_syscall_return:
{
struct tcb_s *rtcb = sched_self();
+ int index = (int)rtcb->xcp.nsyscalls - 1;
/* Make sure that there is a saved syscall return address. */
- DEBUGASSERT(rtcb->xcp.sysreturn != 0);
+ DEBUGASSERT(index >= 0);
/* Setup to return to the saved syscall return address in
* the original mode.
*/
- regs[REG_PC] = rtcb->xcp.sysreturn;
- regs[REG_EXC_RETURN] = rtcb->xcp.excreturn;
- rtcb->xcp.sysreturn = 0;
+ regs[REG_PC] = rtcb->xcp.syscall[index].sysreturn;
+ regs[REG_EXC_RETURN] = rtcb->xcp.syscall[index].excreturn;
+ rtcb->xcp.nsyscalls = index;
/* The return value must be in R0-R1. dispatch_syscall() temporarily
* moved the value for R0 into R2.
@@ -429,6 +430,7 @@ int up_svcall(int irq, FAR void *context)
{
#ifdef CONFIG_NUTTX_KERNEL
FAR struct tcb_s *rtcb = sched_self();
+ int index = rtcb->xcp.nsyscalls;
/* Verify that the SYS call number is within range */
@@ -438,19 +440,20 @@ int up_svcall(int irq, FAR void *context)
* cannot yet handle nested system calls.
*/
- DEBUGASSERT(rtcb->xcp.sysreturn == 0);
+ DEBUGASSERT(index < CONFIG_SYS_NNEST);
/* Setup to return to dispatch_syscall in privileged mode. */
- rtcb->xcp.sysreturn = regs[REG_PC];
- rtcb->xcp.excreturn = regs[REG_EXC_RETURN];
+ rtcb->xcp.syscall[index].sysreturn = regs[REG_PC];
+ rtcb->xcp.syscall[index].excreturn = regs[REG_EXC_RETURN];
+ rtcb->xcp.nsyscalls = index + 1;
regs[REG_PC] = (uint32_t)dispatch_syscall;
regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
/* Offset R0 to account for the reserved values */
- regs[REG_R0] -= CONFIG_SYS_RESERVED;
+ regs[REG_R0] -= CONFIG_SYS_RESERVED;
#else
slldbg("ERROR: Bad SYS call: %d\n", regs[REG_R0]);
#endif