mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-13 18:17:39 -04:00
arm: add ARMv7-M support for thread context switching
On ARMv7-M, stm/ldm instructions can't include SP, so we must load and store that separately. This changes the order of registers in the context struct, but it doesn't seem to be accessed anywhere else so this shouldn't cause any problems. Change-Id: Ie1cd23272f23384e030f51f0b76739624fa7332b
This commit is contained in:
parent
6712779ccb
commit
1c96d51717
2 changed files with 26 additions and 0 deletions
|
@ -61,7 +61,12 @@ static void __attribute__((naked)) USED_ATTR start_thread(void)
|
|||
static inline void store_context(void* addr)
|
||||
{
|
||||
asm volatile(
|
||||
#if defined(CPU_ARM_MICRO) && ARCH_VERSION >= 7
|
||||
"stmia %0, { r4-r11, lr } \n"
|
||||
"str sp, [%0, #36] \n"
|
||||
#else
|
||||
"stmia %0, { r4-r11, sp, lr } \n"
|
||||
#endif
|
||||
: : "r" (addr)
|
||||
);
|
||||
}
|
||||
|
@ -85,7 +90,13 @@ static inline void load_context(const void* addr)
|
|||
"ldmiane %0, { r0, pc } \n"
|
||||
#endif
|
||||
|
||||
#if defined(CPU_ARM_MICRO) && ARCH_VERSION >= 7
|
||||
"mov r0, %0 \n"
|
||||
"ldmia r0, { r4-r11, lr } \n"
|
||||
"ldr sp, [r0, #36] \n"
|
||||
#else
|
||||
"ldmia %0, { r4-r11, sp, lr } \n" /* Load regs r4 to r14 from context */
|
||||
#endif
|
||||
END_ARM_ASM_SYNTAX_UNIFIED
|
||||
: : "r" (addr) : "r0" /* only! */
|
||||
);
|
||||
|
|
|
@ -21,6 +21,20 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#if defined(CPU_ARM_MICRO) && ARCH_VERSION >= 7
|
||||
/*
|
||||
* Cortex-M cannot load/store SP with ldm/stm so we need to store it
|
||||
* separately. This makes it slightly more efficient to store SP last
|
||||
* so as not to split the register list.
|
||||
*/
|
||||
struct regs
|
||||
{
|
||||
uint32_t r[8]; /* 0-28 - Registers r4-r11 */
|
||||
uint32_t lr; /* 32 - r14 (lr) */
|
||||
uint32_t sp; /* 36 - Stack pointer (r13) */
|
||||
uint32_t start; /* 40 - Thread start address, or NULL when started */
|
||||
};
|
||||
#else
|
||||
struct regs
|
||||
{
|
||||
uint32_t r[8]; /* 0-28 - Registers r4-r11 */
|
||||
|
@ -28,6 +42,7 @@ struct regs
|
|||
uint32_t lr; /* 36 - r14 (lr) */
|
||||
uint32_t start; /* 40 - Thread start address, or NULL when started */
|
||||
};
|
||||
#endif
|
||||
|
||||
#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
|
||||
#include <errno.h>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue