[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