[En-Nut-Discussion] [PATCH] Make context switch work in ARM system mode part 1.
Lwazi
lwazidub at gmail.com
Thu Aug 28 17:57:15 CEST 2014
The current context switch has undefined behavior in ARM system mode.
This is a patch I use for Marvell ARM9 processors. Comments are welcome.
Lwazi
----------------------------------------------
---
nut/arch/arm/os/context.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/nut/arch/arm/os/context.c b/nut/arch/arm/os/context.c
index 934a18d..d673682 100644
--- a/nut/arch/arm/os/context.c
+++ b/nut/arch/arm/os/context.c
@@ -136,12 +136,23 @@ void NutThreadSwitch(void)
"ldmfd sp!, {r0}\n\t"
/* ...enable interrupts */
"bic r0, r0, #0xC0\n\t"
+#if !defined(ENABLE_SYSMODE) /* no spsr in System mode*/
/* ...and save in spsr. */
"msr spsr, r0\n\t"
+#endif
/* Restore registers. */
"ldmfd sp!, {r4-r11, lr}\n\t"
+#if !defined(ENABLE_SYSMODE)
+ /* Undefined behaviour in system mode. No assembler warning.
+ Do not use in system mode. */
/* Restore status and return. */
"movs pc, lr"
+#else
+ "mrs r0, cpsr\n\t"
+ "bic r0, r0, #0xC0\n\t"
+ "msr cpsr, r0\n\t"
+ "mov pc, lr"
+#endif
/* Output. */
:
/* Input. */
@@ -224,8 +235,12 @@ HANDLE NutThreadCreate(char * name, void (*fn)
(void *), void *arg, size_t stack
* Setup the switch frame.
*/
sf->csf_lr = (uintptr_t) NutThreadEntry;
+#if !defined(ENABLE_SYSMODE)
+ sf->csf_cpsr = ARM_CPSR_I_BIT | ARM_CPSR_F_BIT | ARM_MODE_SVC;
+#else
sf->csf_cpsr = ARM_CPSR_I_BIT | ARM_CPSR_F_BIT | ARM_MODE_SYS;
+#endif
/*
* Initialize the thread info structure and insert it into the
* thread list and the run queue.
@@ -262,12 +277,20 @@ HANDLE NutThreadCreate(char * name, void (*fn)
(void *), void *arg, size_t stack
"ldmfd sp!, {r0}\n\t"
/* ...enable interrupts */
"bic r0, r0, #0xC0\n\t"
+#if !defined(ENABLE_SYSMODE) /* no spsr in System mode*/
/* ...and save in spsr. */
"msr spsr, r0\n\t"
+#endif
/* Restore registers. */
"ldmfd sp!, {r4-r11, lr}\n\t"
+#if !defined(ENABLE_SYSMODE)
+ /* Undefined behaviour in system mode. No assembler warning.
+ Do not use in system mode. */
/* Restore status and return. */
"movs pc, lr"
+#else
+ "mov pc, lr"
+#endif
/* Input. */
:
/* Output. */
--
More information about the En-Nut-Discussion
mailing list