4 .extern vTaskSwitchContext
\r
5 .extern vTaskIncrementTick
\r
7 .global vPortStartFirstTask
\r
11 .set portCONTEXT_SIZE, 156
\r
12 .set portR0_OFFSET, 152
\r
13 .set portGPR_OFFSET, 32
\r
14 .set portCR_OFFSET, 28
\r
15 .set portXER_OFFSET, 24
\r
16 .set portLR_OFFSET, 16
\r
17 .set portCTR_OFFSET, 16
\r
18 .set portUSPRG0_OFFSET, 12
\r
19 .set portSRR0_OFFSET, 8
\r
20 .set portSRR1_OFFSET, 4
\r
24 .set NextLRField, BChainField + 4
\r
25 .set MSRField, NextLRField + 4
\r
26 .set PCField, MSRField + 4
\r
27 .set LRField, PCField + 4
\r
28 .set CTRField, LRField + 4
\r
29 .set XERField, CTRField + 4
\r
30 .set CRField, XERField + 4
\r
31 .set USPRG0Field, CRField + 4
\r
32 .set r0Field, USPRG0Field + 4
\r
33 .set r2Field, r0Field + 4
\r
34 .set r3r31Field, r2Field + 4
\r
35 .set IFrameSize, r3r31Field + ( ( 31 - 3 ) + 1 ) * 4
\r
38 .macro portRESTORE_CONTEXT
\r
40 # Get the address of the TCB.
\r
42 addis SP, R0, pxCurrentTCB@ha
\r
43 lwz SP, pxCurrentTCB@l( SP )
\r
45 # Get the task stack pointer from the TCB.
\r
48 # Pop the special purpose registers
\r
49 lwz R0, portSRR1_OFFSET( SP )
\r
51 lwz R0, portSRR0_OFFSET( SP )
\r
53 lwz R0, portUSPRG0_OFFSET( SP )
\r
54 mtspr 256, R0 #USPRG0
\r
55 lwz R0, portCTR_OFFSET( SP )
\r
57 lwz R0, portLR_OFFSET( SP )
\r
59 lwz R0, portXER_OFFSET( SP )
\r
61 lwz R0, portCR_OFFSET( SP )
\r
65 lmw R2, portGPR_OFFSET( SP )
\r
67 # Finally pop R0 and correct the stack pointer
\r
68 lwz R0, portR0_OFFSET( SP )
\r
69 addi R1, R1, portCONTEXT_SIZE
\r
71 # Start the task running
\r
76 .macro portSAVE_CONTEXT
\r
78 # Make room on the stack.
\r
79 subi R1, R1, portCONTEXT_SIZE
\r
81 # Push R0, then the GPRs
\r
82 stw R0, portR0_OFFSET( SP )
\r
83 stm R2, portGPR_OFFSET( SP )
\r
87 stw R0, portCR_OFFSET( SP )
\r
89 stw R0, portXER_OFFSET( SP )
\r
91 stw R0, portLR_OFFSET( SP )
\r
93 stw R0, portCTR_OFFSET( SP )
\r
94 mfspr R0, 256 #USPRG0
\r
95 stw R0, portUSPRG0_OFFSET( SP )
\r
97 stw R0, portSRR0_OFFSET( SP )
\r
99 stw R0, portSRR1_OFFSET( SP )
\r
101 # Get the address of the TCB.
\r
103 addis R2, R0, pxCurrentTCB@ha
\r
104 lwz R2, pxCurrentTCB@l( R2 )
\r
106 # Store the stack pointer into the TCB
\r
112 .macro int_epilogue
\r
114 # Get the address of the TCB.
\r
116 addis SP, R0, pxCurrentTCB@ha
\r
117 lwz SP, pxCurrentTCB@l( SP )
\r
119 # Get the task stack pointer from the TCB.
\r
122 # Restore MSR register to SRR1.
\r
123 lwz R0,MSRField(R1)
\r
126 # Restore current PC location to SRR0.
\r
130 # Save USPRG0 register
\r
131 lwz R0,USPRG0Field(R1)
\r
134 # Restore Condition register
\r
138 # Restore Fixed Point Exception register
\r
139 lwz R0,XERField(R1)
\r
142 # Restore Counter register
\r
143 lwz R0,CTRField(R1)
\r
146 # Restore Link register
\r
150 # Restore remaining GPR registers.
\r
151 lmw R3,r3r31Field(R1)
\r
153 # Restore r0 and r2.
\r
157 # Remove frame from stack
\r
158 addi R1,R1,IFrameSize
\r
162 .macro portENTER_SWITCHING_ISR
\r
164 # Get the address of the TCB.
\r
166 addis R2, R0, pxCurrentTCB@ha
\r
167 lwz R2, pxCurrentTCB@l( R2 )
\r
169 # Store the stack pointer into the TCB
\r
172 # Save the link register
\r
181 .macro portEXIT_SWITCHING_ISR
\r
183 # Restore the link register
\r
190 # Get the address of the TCB.
\r
192 addis SP, R0, pxCurrentTCB@ha
\r
193 lwz SP, pxCurrentTCB@l( R1 )
\r
195 # Get the task stack pointer from the TCB.
\r
201 vPortStartFirstTask:
\r
206 #vPortStartFirstTask:
\r
207 # portRESTORE_CONTEXT
\r
214 portENTER_SWITCHING_ISR
\r
215 bl vTaskSwitchContext
\r
216 portEXIT_SWITCHING_ISR
\r
221 portENTER_SWITCHING_ISR
\r
222 bl vTaskIncrementTick
\r
223 #if configUSE_PREEMPTION == 1
\r
224 bl vTaskSwitchContext
\r
227 # Clear the interrupt
\r
231 portEXIT_SWITCHING_ISR
\r