4 .extern vTaskSwitchContext
\r
6 .global vStartFirstTask
\r
9 .set portCONTEXT_SIZE, 156
\r
10 .set portR0_OFFSET, 152
\r
11 .set portGPR_OFFSET, 32
\r
12 .set portCR_OFFSET, 28
\r
13 .set portXER_OFFSET, 24
\r
14 .set portLR_OFFSET, 20
\r
15 .set portCTR_OFFSET, 16
\r
16 .set portUSPRG0_OFFSET, 12
\r
17 .set portSRR0_OFFSET, 8
\r
18 .set portSRR1_OFFSET, 4
\r
22 .set NextLRField, BChainField + 4
\r
23 .set MSRField, NextLRField + 4
\r
24 .set PCField, MSRField + 4
\r
25 .set LRField, PCField + 4
\r
26 .set CTRField, LRField + 4
\r
27 .set XERField, CTRField + 4
\r
28 .set CRField, XERField + 4
\r
29 .set USPRG0Field, CRField + 4
\r
30 .set r0Field, USPRG0Field + 4
\r
31 .set r2Field, r0Field + 4
\r
32 .set r3r31Field, r2Field + 4
\r
33 .set IFrameSize, r3r31Field + ( ( 31 - 3 ) + 1 ) * 4
\r
36 .macro portRESTORE_CONTEXT
\r
38 # Get the address of the TCB.
\r
40 addis SP, R0, pxCurrentTCB@ha
\r
41 lwz SP, pxCurrentTCB@l( SP )
\r
43 # Get the task stack pointer from the TCB.
\r
46 # Pop the special purpose registers
\r
47 lwz R0, portSRR1_OFFSET( SP )
\r
49 lwz R0, portSRR0_OFFSET( SP )
\r
51 lwz R0, portUSPRG0_OFFSET( SP )
\r
52 mtspr 256, R0 #USPRG0
\r
53 lwz R0, portCTR_OFFSET( SP )
\r
55 lwz R0, portLR_OFFSET( SP )
\r
57 lwz R0, portXER_OFFSET( SP )
\r
59 lwz R0, portCR_OFFSET( SP )
\r
63 lmw R2, portGPR_OFFSET( SP )
\r
65 # Finally pop R0 and correct the stack pointer
\r
66 lwz R0, portR0_OFFSET( SP )
\r
67 addi R1, R1, portCONTEXT_SIZE
\r
69 # Start the task running
\r
74 .macro portSAVE_CONTEXT
\r
76 # Make room on the stack.
\r
77 subi R1, R1, portCONTEXT_SIZE
\r
79 # Push R0, then the GPRs
\r
80 stw R0, portR0_OFFSET( SP )
\r
81 stm R2, portGPR_OFFSET( SP )
\r
85 stw R0, portCR_OFFSET( SP )
\r
87 stw R0, portXER_OFFSET( SP )
\r
89 stw R0, portLR_OFFSET( SP )
\r
91 stw R0, portCTR_OFFSET( SP )
\r
92 mfspr R0, 256 #USPRG0
\r
93 stw R0, portUSPRG0_OFFSET( SP )
\r
95 stw R0, portSRR0_OFFSET( SP )
\r
97 stw R0, portSRR1_OFFSET( SP )
\r
99 # Get the address of the TCB.
\r
101 addis R2, R0, pxCurrentTCB@ha
\r
102 lwz R2, pxCurrentTCB@l( R2 )
\r
104 # Store the stack pointer into the TCB
\r
110 .macro int_epilogue
\r
112 # Get the address of the TCB.
\r
114 addis SP, R0, pxCurrentTCB@ha
\r
115 lwz SP, pxCurrentTCB@l( SP )
\r
117 # Get the task stack pointer from the TCB.
\r
120 # Restore MSR register to SRR1.
\r
121 lwz R0,MSRField(R1)
\r
124 # Restore current PC location to SRR0.
\r
128 # Save USPRG0 register
\r
129 lwz R0,USPRG0Field(R1)
\r
132 # Restore Condition register
\r
136 # Restore Fixed Point Exception register
\r
137 lwz R0,XERField(R1)
\r
140 # Restore Counter register
\r
141 lwz R0,CTRField(R1)
\r
144 # Restore Link register
\r
148 # Restore remaining GPR registers.
\r
149 lmw R3,r3r31Field(R1)
\r
151 # Restore r0 and r2.
\r
155 # Remove frame from stack
\r
156 addi R1,R1,IFrameSize
\r
160 .macro portENTER_SWITCHING_ISR
\r
162 # Get the address of the TCB.
\r
164 addis R2, R0, pxCurrentTCB@ha
\r
165 lwz R2, pxCurrentTCB@l( R2 )
\r
167 # Store the stack pointer into the TCB
\r
172 .macro portEXIT_SWITCHING_ISR
\r
174 # Get the address of the TCB.
\r
176 addis SP, R0, pxCurrentTCB@ha
\r
177 lwz SP, pxCurrentTCB@l( R1 )
\r
179 # Get the task stack pointer from the TCB.
\r
182 # Load up the LR for the correct return.
\r
196 # portRESTORE_CONTEXT
\r
203 portENTER_SWITCHING_ISR
\r
204 bl vTaskSwitchContext
\r
205 portEXIT_SWITCHING_ISR
\r