0
|
1 # Context switch
|
|
2 #
|
|
3 # void swtch(struct context **old, struct context *new);
|
|
4 #
|
|
5 # Save current register context in old
|
|
6 # and then load register context from new.
|
|
7 # The stack is as r4_svc-r12_svc, lr_svc, sp_usr, lr_usr, and pc_usr
|
|
8 .global swtch
|
|
9
|
|
10 swtch:
|
|
11 STMFD r13!, {r4-r12, lr} // push svc r4-r12, lr to the stack
|
|
12
|
|
13 # switch the stack
|
|
14 STR r13, [r0] // save current sp to the old PCB (**old)
|
|
15 MOV r13, r1 // load the next stack
|
|
16
|
|
17 # load the new registers. pc_usr is not restored here because
|
|
18 # LDMFD^ will switch mode if pc_usr is loaded. We just simply
|
|
19 # pop it out as pc_usr is saved on the stack, and will be loaded
|
|
20 # when we return from kernel to user space (swi or interrupt return)
|
|
21
|
|
22 LDMFD r13!, {r4-r12, lr} // pop svc r4-r12, lr
|
|
23
|
|
24 # return to the caller
|
|
25 bx lr
|
|
26
|