Skip to content

Commit

Permalink
Stack process's r4-r11 on kernel-side of syscall
Browse files Browse the repository at this point in the history
For system calls this doesn't make much of a difference*, but it will
allow us to do preemption. Basically, preemption happens without the
process's knowledge, so we have to stack those registers in the kernel
anyway. This change allows us to treat both situations the same when
context switching back to the process.

* Except for technically it would be possible to overrun the process
stack by 32 bytes in the interrupt handler, while not running with the
MPU. We ought to deal with that somehow. A fault page won't work because
interrupt handlers are never subject to MPU rules.
  • Loading branch information
alevy committed Jul 8, 2016
1 parent 1619a00 commit 3a258cc
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 50 deletions.
89 changes: 64 additions & 25 deletions src/arch/cortex-m0/ctx_switch.S
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,68 @@ EXC_RETURN_PSP:
.word 0xFFFFFFFD

.thumb_func
/* r0 is top of user stack, r1 is heap base */
/* r0 is top of user stack, r1 Process GOT */
switch_to_user:
/* Load bottom of stack into Process Stack Pointer */
msr psp, r0

/* Cortex-M0 can only push registers R0-R7 directly, so move R8-R11 to R0-R3.
* This is equivalent to the 32-bit "push {r4-r11}" instruction. */
push {r4-r7}
mov r4, r8
mov r5, r9
mov r6, r10
mov r7, r11
push {r4-r7}

mov r9, r1
svc 0xff

/* These instructions are equivalent to the 32-bit "pop {r4-r11}" */
pop {r4-r7}
mov r8, r4
mov r9, r5
mov r10, r6
mov r11, r7
pop {r4-r7}

bx lr
/* Cortex-M0 can only push registers R0-R7 directly, so move R8-R11 to R0-R3.
* This is equivalent to the 32-bit "push {r4-r11}" instruction. */
push {r4-r7}
mov r4, r8
mov r5, r9
mov r6, r10
mov r7, r11
push {r4-r7}

/* Load non-hardware-stacked registers from Process stack */
subs r0, #32
ldr r7, [r0, #0]
ldr r6, [r0, #4]
ldr r5, [r0, #8]
ldr r4, [r0, #12]
mov r4, r8
mov r5, r9
mov r6, r10
mov r7, r11
ldr r7, [r0, #16]
ldr r6, [r0, #20]
ldr r5, [r0, #24]
ldr r4, [r0, #28]
adds r0, #32
/* Load bottom of stack into Process Stack Pointer */
msr psp, r0

/* Set PIC base pointer to the Process GOT */
mov r9, r1

/* SWITCH */
svc 0xff /* It doesn't matter which SVC number we use here */

/* Push non-harware-stacked registers onto Process stack. r0 points to user
* stack (see to_kernel). We store the registers passed the stack to make it
* easier to address hardware-stacked registers in the rest of the kernel.
* This is fine since we just account for that above.
*/
str r4, [r0, #32]
str r5, [r0, #28]
str r6, [r0, #24]
str r7, [r0, #20]

mov r8, r4
mov r9, r5
mov r10, r6
mov r11, r7

str r4, [r0, #16]
str r6, [r0, #8]
str r5, [r0, #12]
str r7, [r0, #4]

/* These instructions are equivalent to the 32-bit "pop {r4-r11}" */
pop {r4-r7}
mov r8, r4
mov r9, r5
mov r10, r6
mov r11, r7
pop {r4-r7}

bx lr

12 changes: 0 additions & 12 deletions src/arch/cortex-m0/syscalls.S
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,7 @@
.global \NAME
.thumb_func
\NAME :
push {r4-r7}
mov r4, r8
mov r5, r9
mov r6, r10
mov r7, r11
push {r4-r7}
svc \NUM
pop {r4-r7}
mov r8, r4
mov r9, r5
mov r10, r6
mov r11, r7
pop {r4-r7}
bx lr
.endm

Expand Down
18 changes: 15 additions & 3 deletions src/arch/cortex-m4/ctx_switch.S
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,26 @@ to_kernel:
bx lr

.thumb_func
/* r0 is top of user stack, r1 is heap base */
/* r0 is top of user stack, r1 Process GOT */
switch_to_user:
push {r4-r11}

/* Load non-hardware-stacked registers from Process stack */
sub r0, #32
ldmia r0!, {r4-r11}
/* Load bottom of stack into Process Stack Pointer */
msr psp, r0

push {r4-r11}
/* Set PIC base pointer to the Process GOT */
mov r9, r1
svc 0xff

/* SWITCH */
svc 0xff /* It doesn't matter which SVC number we use here */

/* Push non-harware-stacked registers onto Process stack */
/* r0 points to user stack (see to_kernel) */
stmdb r0, {r4-r11}

pop {r4-r11}
bx lr

12 changes: 2 additions & 10 deletions src/arch/cortex-m4/syscalls.S
Original file line number Diff line number Diff line change
Expand Up @@ -13,36 +13,28 @@

.thumb_func
__wait:
push {r4-r11,lr}
push {lr}
svc 0
pop {r4-r11,lr}
pop {lr}
bx lr

.thumb_func
__allow:
push {r4-r11}
svc 3
pop {r4-r11}
bx lr

.thumb_func
__subscribe:
push {r4-r11}
svc 1
pop {r4-r11}
bx lr

.thumb_func
__command:
push {r4-r11}
svc 2
pop {r4-r11}
bx lr

.thumb_func
__memop:
push {r4-r11}
svc 4
pop {r4-r11}
bx lr

0 comments on commit 3a258cc

Please sign in to comment.