2 .extern vTaskSwitchContext
\r
4 .global vStartFirstTask
\r
7 .set portCONTEXT_SIZE, 156
\r
8 .set portR0_OFFSET, 152
\r
9 .set portGPR_OFFSET, 32
\r
10 .set portCR_OFFSET, 28
\r
11 .set portXER_OFFSET, 24
\r
12 .set portLR_OFFSET, 20
\r
13 .set portCTR_OFFSET, 16
\r
14 .set portUSPRG0_OFFSET, 12
\r
15 .set portSRR0_OFFSET, 8
\r
16 .set portSRR1_OFFSET, 4
\r
18 .macro portRESTORE_CONTEXT
\r
20 # Get the address of the TCB.
\r
22 addis SP, R0, pxCurrentTCB@ha
\r
23 lwz SP, pxCurrentTCB@l( SP )
\r
25 # Get the task stack pointer from the TCB.
\r
28 # Pop the special purpose registers
\r
29 lwz R0, portSRR1_OFFSET( SP )
\r
31 lwz R0, portSRR0_OFFSET( SP )
\r
33 lwz R0, portUSPRG0_OFFSET( SP )
\r
34 mtspr 256, R0 #USPRG0
\r
35 lwz R0, portCTR_OFFSET( SP )
\r
37 lwz R0, portLR_OFFSET( SP )
\r
39 lwz R0, portXER_OFFSET( SP )
\r
41 lwz R0, portCR_OFFSET( SP )
\r
45 lmw R2, portGPR_OFFSET( SP )
\r
47 # Finally pop R0 and correct the stack pointer
\r
48 lwz R0, portR0_OFFSET( SP )
\r
49 addi R1, R1, portCONTEXT_SIZE
\r
51 # Start the task running
\r
56 .macro portSAVE_CONTEXT
\r
58 # Make room on the stack.
\r
59 subi R1, R1, portCONTEXT_SIZE
\r
61 # Push R0, then the GPRs
\r
62 stw R0, portR0_OFFSET( SP )
\r
63 stm R2, portGPR_OFFSET( SP )
\r
67 stw R0, portCR_OFFSET( SP )
\r
69 stw R0, portXER_OFFSET( SP )
\r
71 stw R0, portLR_OFFSET( SP )
\r
73 stw R0, portCTR_OFFSET( SP )
\r
74 mfspr R0, 256 #USPRG0
\r
75 stw R0, portUSPRG0_OFFSET( SP )
\r
77 stw R0, portSRR0_OFFSET( SP )
\r
79 stw R0, portSRR1_OFFSET( SP )
\r
81 # Get the address of the TCB.
\r
83 addis R2, R0, pxCurrentTCB@ha
\r
84 lwz R2, pxCurrentTCB@l( R2 )
\r
86 # Store the stack pointer into the TCB
\r
100 bl vTaskSwitchContext
\r
101 portRESTORE_CONTEXT
\r