aboutsummaryrefslogtreecommitdiffstats
path: root/src/gos/gos_x_threads_cortexm01.h
diff options
context:
space:
mode:
authorinmarket <inmarket@ugfx.org>2016-12-30 18:57:09 +1000
committerinmarket <inmarket@ugfx.org>2016-12-30 18:57:09 +1000
commit6a30927a91497bc301a35c6260601eaf97cc9a76 (patch)
tree26f22baf314b028c6ecd203c5f84a15118154bec /src/gos/gos_x_threads_cortexm01.h
parent06de6f193132a61dbb5e9b8f9a37e56929f7643b (diff)
downloaduGFX-6a30927a91497bc301a35c6260601eaf97cc9a76.tar.gz
uGFX-6a30927a91497bc301a35c6260601eaf97cc9a76.tar.bz2
uGFX-6a30927a91497bc301a35c6260601eaf97cc9a76.zip
Fix Cortex m0 Raw32 scheduler.
Ensure 8 byte alignment of the stack for all ARM specific scheduler code.
Diffstat (limited to 'src/gos/gos_x_threads_cortexm01.h')
-rw-r--r--src/gos/gos_x_threads_cortexm01.h29
1 files changed, 19 insertions, 10 deletions
diff --git a/src/gos/gos_x_threads_cortexm01.h b/src/gos/gos_x_threads_cortexm01.h
index 659d7af7..15a90b2a 100644
--- a/src/gos/gos_x_threads_cortexm01.h
+++ b/src/gos/gos_x_threads_cortexm01.h
@@ -27,8 +27,10 @@
"mov r6, r10 \n\t"
"mov r7, r11 \n\t"
"push {r4, r5, r6, r7} \n\t"
- "str sp, %[oldtcxt] \n\t"
- "ldr sp, %[newtcxt] \n\t"
+ "mov r4, sp \n\t"
+ "str r4, %[oldtcxt] \n\t"
+ "ldr r4, %[newtcxt] \n\t"
+ "mov sp, r4 \n\t"
"pop {r4, r5, r6, r7} \n\t"
"mov r8, r4 \n\t"
"mov r9, r5 \n\t"
@@ -41,15 +43,17 @@
}
static __attribute__((pcs("aapcs"),naked)) void _gfxStartThread(thread *oldt, thread *newt) {
- newt->cxt = (char *)newt + newt->size;
+ newt->cxt = (void *)(((unsigned)newt + newt->size) & ~7);
__asm__ volatile ( "push {r4, r5, r6, r7, lr} \n\t"
"mov r4, r8 \n\t"
"mov r5, r9 \n\t"
"mov r6, r10 \n\t"
"mov r7, r11 \n\t"
"push {r4, r5, r6, r7} \n\t"
- "str sp, %[oldtcxt] \n\t"
- "ldr sp, %[newtcxt] \n\t"
+ "mov r4, sp \n\t"
+ "str r4, %[oldtcxt] \n\t"
+ "ldr r4, %[newtcxt] \n\t"
+ "mov sp, r4 \n\t"
: [newtcxt] "=m" (newt->cxt)
: [oldtcxt] "m" (oldt->cxt)
: "memory");
@@ -72,10 +76,12 @@
mov r6, r10
mov r7, r11
push {r4, r5, r6, r7}
- str sp, [r0,#__cpp(offsetof(thread,cxt))] // oldt->cxt
+ mov r4, sp
+ str r4, [r0,#__cpp(offsetof(thread,cxt))] // oldt->cxt
// Load the new context
- ldr sp, [r1,#__cpp(offsetof(thread,cxt))] // newt->cxt
+ ldr r4, [r1,#__cpp(offsetof(thread,cxt))] // newt->cxt
+ mov sp, r4
pop {r4, r5, r6, r7}
mov r8, r4
mov r9, r5
@@ -88,9 +94,10 @@
PRESERVE8
// Calculate where to generate the new context
- // newt->cxt = (char *)newt + newt->size;
+ // newt->cxt = (void *)(((unsigned)newt + newt->size) & ~7);
ldr r2,[r1,#__cpp(offsetof(thread,size))]
add r2,r2,r1
+ and r2, r2, #0xFFFFFFF8
str r2,[r1,#__cpp(offsetof(thread,cxt))]
// Save the old context
@@ -100,10 +107,12 @@
mov r6, r10
mov r7, r11
push {r4, r5, r6, r7}
- str sp, [r0,#__cpp(offsetof(thread,cxt))] // oldt->cxt
+ mov r4, sp
+ str r4, [r0,#__cpp(offsetof(thread,cxt))] // oldt->cxt
// Load the new (imcomplete) context
- ldr sp, [r1,#__cpp(offsetof(thread,cxt))] // newt->cxt
+ ldr r4, [r1,#__cpp(offsetof(thread,cxt))] // newt->cxt
+ mov sp, r4
// Run the users function - we save some code because gfxThreadExit() never returns
// gfxThreadExit(_gfxCurrentThread->fn(_gfxCurrentThread->param));