summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/common
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-05-17 17:18:19 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-05-17 17:18:19 +0000
commit0fa834d4332608374852575437d2714f820868c4 (patch)
tree4e57188abe5ff32b2639ca69314fec94378bed8d /nuttx/arch/arm/src/common
parent0368c4fac2539f3a8812f9471e9be74fb7aeb303 (diff)
downloadpx4-nuttx-0fa834d4332608374852575437d2714f820868c4.tar.gz
px4-nuttx-0fa834d4332608374852575437d2714f820868c4.tar.bz2
px4-nuttx-0fa834d4332608374852575437d2714f820868c4.zip
Debug Cortex-M3 interrupts
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1787 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/arm/src/common')
-rw-r--r--nuttx/arch/arm/src/common/up_blocktask.c9
-rw-r--r--nuttx/arch/arm/src/common/up_copystate.c19
-rw-r--r--nuttx/arch/arm/src/common/up_doirq.c11
-rw-r--r--nuttx/arch/arm/src/common/up_internal.h18
-rw-r--r--nuttx/arch/arm/src/common/up_releasepending.c6
-rw-r--r--nuttx/arch/arm/src/common/up_reprioritizertr.c4
-rw-r--r--nuttx/arch/arm/src/common/up_schedulesigaction.c10
-rw-r--r--nuttx/arch/arm/src/common/up_sigdeliver.c3
-rw-r--r--nuttx/arch/arm/src/common/up_unblocktask.c6
9 files changed, 67 insertions, 19 deletions
diff --git a/nuttx/arch/arm/src/common/up_blocktask.c b/nuttx/arch/arm/src/common/up_blocktask.c
index 819208a2c..2590597f8 100644
--- a/nuttx/arch/arm/src/common/up_blocktask.c
+++ b/nuttx/arch/arm/src/common/up_blocktask.c
@@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/common/up_blocktask.c
*
- * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -39,9 +39,12 @@
#include <nuttx/config.h>
#include <sys/types.h>
+
#include <sched.h>
#include <debug.h>
+
#include <nuttx/arch.h>
+
#include "os_internal.h"
#include "up_internal.h"
@@ -129,7 +132,7 @@ void up_block_task(_TCB *tcb, tstate_t task_state)
* Just copy the current_regs into the OLD rtcb.
*/
- up_copystate(rtcb->xcp.regs, current_regs);
+ up_savestate(rtcb->xcp.regs);
/* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list.
@@ -139,7 +142,7 @@ void up_block_task(_TCB *tcb, tstate_t task_state)
/* Then switch contexts */
- up_copystate(current_regs, rtcb->xcp.regs);
+ up_restorestate(rtcb->xcp.regs);
}
/* Copy the user C context into the TCB at the (old) head of the
diff --git a/nuttx/arch/arm/src/common/up_copystate.c b/nuttx/arch/arm/src/common/up_copystate.c
index 1c4cb42ec..b73c6c95c 100644
--- a/nuttx/arch/arm/src/common/up_copystate.c
+++ b/nuttx/arch/arm/src/common/up_copystate.c
@@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/common/up_copystate.c
*
- * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -69,9 +69,22 @@
void up_copystate(uint32 *dest, uint32 *src)
{
int i;
- for (i = 0; i < XCPTCONTEXT_REGS; i++)
+
+ /* In the current ARM model, the state is always copied to and from the
+ * stack and TCB. In the Cortex-M3 model, the state is copied from the
+ * stack to the TCB, but only a referenced is passed to get the the state
+ * from the TCB. So the following check makes sense only for the Cortex-M3
+ * model:
+ */
+
+#ifdef __thumb2__
+ if (src != dest)
+#endif
{
- *dest++ = *src++;
+ for (i = 0; i < XCPTCONTEXT_REGS; i++)
+ {
+ *dest++ = *src++;
+ }
}
}
diff --git a/nuttx/arch/arm/src/common/up_doirq.c b/nuttx/arch/arm/src/common/up_doirq.c
index b863ec0c5..861f5f3d8 100644
--- a/nuttx/arch/arm/src/common/up_doirq.c
+++ b/nuttx/arch/arm/src/common/up_doirq.c
@@ -66,7 +66,11 @@
* Public Functions
****************************************************************************/
-uint32 *up_doirq(int irq, uint32* regs)
+#ifdef __thumb2__
+uint32 *up_doirq(int irq, uint32 *regs)
+#else
+void up_doirq(int irq, uint32 *regs)
+#endif
{
up_ledon(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
@@ -94,8 +98,9 @@ uint32 *up_doirq(int irq, uint32* regs)
* of context switching for te particular chip.
*/
+#ifdef __thumb2__
regs = current_regs;
-
+#endif
/* Indicate that we are no long in an interrupt handler */
current_regs = NULL;
@@ -108,5 +113,7 @@ uint32 *up_doirq(int irq, uint32* regs)
}
up_ledoff(LED_INIRQ);
#endif
+#ifdef __thumb2__
return regs;
+#endif
}
diff --git a/nuttx/arch/arm/src/common/up_internal.h b/nuttx/arch/arm/src/common/up_internal.h
index 430631853..34a7918e1 100644
--- a/nuttx/arch/arm/src/common/up_internal.h
+++ b/nuttx/arch/arm/src/common/up_internal.h
@@ -71,6 +71,20 @@
# define CONFIG_ARCH_INTERRUPTSTACK 0
#endif
+/* Macros to handle saving and restore interrupt state. In the current ARM
+ * model, the state is always copied to and from the stack and TCB. In the
+ * Cortex-M3 model, the state is copied from the stack to the TCB, but only
+ * a referenced is passed to get the the state from the TCB.
+ */
+
+#ifdef __thumb2__
+# define up_savestate(regs) up_copystate(regs, current_regs)
+# define up_restorestate(regs) (current_regs = regs)
+#else
+# define up_savestate(regs) up_copystate(regs, current_regs)
+# define up_restorestate(regs) up_copystate(current_regs, regs)
+#endif
+
/****************************************************************************
* Public Types
****************************************************************************/
@@ -122,7 +136,11 @@ extern void up_boot(void);
extern void up_copystate(uint32 *dest, uint32 *src);
extern void up_dataabort(uint32 *regs);
extern void up_decodeirq(uint32 *regs);
+#ifdef __thumb2__
extern uint32 *up_doirq(int irq, uint32 *regs);
+#else
+extern void up_doirq(int irq, uint32 *regs);
+#endif
extern void up_fullcontextrestore(uint32 *regs) __attribute__ ((noreturn));
extern void up_irqinitialize(void);
extern void up_prefetchabort(uint32 *regs);
diff --git a/nuttx/arch/arm/src/common/up_releasepending.c b/nuttx/arch/arm/src/common/up_releasepending.c
index d62fb25c2..d81479e87 100644
--- a/nuttx/arch/arm/src/common/up_releasepending.c
+++ b/nuttx/arch/arm/src/common/up_releasepending.c
@@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/common/up_releasepending.c
*
- * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -94,7 +94,7 @@ void up_release_pending(void)
* Just copy the current_regs into the OLD rtcb.
*/
- up_copystate(rtcb->xcp.regs, current_regs);
+ up_savestate(rtcb->xcp.regs);
/* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list.
@@ -105,7 +105,7 @@ void up_release_pending(void)
/* Then switch contexts */
- up_copystate(current_regs, rtcb->xcp.regs);
+ up_restorestate(rtcb->xcp.regs);
}
/* Copy the exception context into the TCB of the task that
diff --git a/nuttx/arch/arm/src/common/up_reprioritizertr.c b/nuttx/arch/arm/src/common/up_reprioritizertr.c
index 41aa0d5e2..684ff7f43 100644
--- a/nuttx/arch/arm/src/common/up_reprioritizertr.c
+++ b/nuttx/arch/arm/src/common/up_reprioritizertr.c
@@ -142,7 +142,7 @@ void up_reprioritize_rtr(_TCB *tcb, ubyte priority)
* Just copy the current_regs into the OLD rtcb.
*/
- up_copystate(rtcb->xcp.regs, current_regs);
+ up_savestate(rtcb->xcp.regs);
/* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list.
@@ -153,7 +153,7 @@ void up_reprioritize_rtr(_TCB *tcb, ubyte priority)
/* Then switch contexts */
- up_copystate(current_regs, rtcb->xcp.regs);
+ up_restorestate(rtcb->xcp.regs);
}
/* Copy the exception context into the TCB at the (old) head of the
diff --git a/nuttx/arch/arm/src/common/up_schedulesigaction.c b/nuttx/arch/arm/src/common/up_schedulesigaction.c
index fb6798468..a4ae20953 100644
--- a/nuttx/arch/arm/src/common/up_schedulesigaction.c
+++ b/nuttx/arch/arm/src/common/up_schedulesigaction.c
@@ -1,7 +1,7 @@
/****************************************************************************
* common/up_schedulesigaction.c
*
- * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -137,6 +137,12 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver)
* interrupted task is the same as the one that
* must receive the signal, then we will have to modify
* the return state as well as the state in the TCB.
+ *
+ * Hmmm... there looks like a latent bug here: The following
+ * logic would fail in the strange case where we are in an
+ * interrupt handler, the thread is signalling itself, but
+ * a context switch to another task has occurred so that
+ * current_regs does not refer to the thread at g_readytorun.head!
*/
else
@@ -171,7 +177,7 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver)
* is the same as the interrupt return context.
*/
- up_copystate(tcb->xcp.regs, current_regs);
+ up_savestate(tcb->xcp.regs);
}
}
diff --git a/nuttx/arch/arm/src/common/up_sigdeliver.c b/nuttx/arch/arm/src/common/up_sigdeliver.c
index bf5661696..aff743884 100644
--- a/nuttx/arch/arm/src/common/up_sigdeliver.c
+++ b/nuttx/arch/arm/src/common/up_sigdeliver.c
@@ -1,7 +1,7 @@
/****************************************************************************
* common/up_sigdeliver.c
*
- * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -109,6 +109,7 @@ void up_sigdeliver(void)
#else
regs[REG_CPSR] = rtcb->xcp.saved_cpsr;
#endif
+
/* Get a local copy of the sigdeliver function pointer.
* we do this so that we can nullify the sigdeliver
* function point in the TCB and accept more signal
diff --git a/nuttx/arch/arm/src/common/up_unblocktask.c b/nuttx/arch/arm/src/common/up_unblocktask.c
index a657a1b84..ea64ed1c6 100644
--- a/nuttx/arch/arm/src/common/up_unblocktask.c
+++ b/nuttx/arch/arm/src/common/up_unblocktask.c
@@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/common/up_unblocktask.c
*
- * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -121,7 +121,7 @@ void up_unblock_task(_TCB *tcb)
* Just copy the current_regs into the OLD rtcb.
*/
- up_copystate(rtcb->xcp.regs, current_regs);
+ up_savestate(rtcb->xcp.regs);
/* Restore the exception context of the rtcb at the (new) head
* of the g_readytorun task list.
@@ -131,7 +131,7 @@ void up_unblock_task(_TCB *tcb)
/* Then switch contexts */
- up_copystate(current_regs, rtcb->xcp.regs);
+ up_restorestate(rtcb->xcp.regs);
}
/* We are not in an interrupt handler. Copy the user C context