83 __DATA_MEMORY_BARRIER_Z__(r12); |
83 __DATA_MEMORY_BARRIER_Z__(r12); |
84 asm("1: "); |
84 asm("1: "); |
85 LDREX(3,1); // r3 = iIdlingCpus |
85 LDREX(3,1); // r3 = iIdlingCpus |
86 asm("orr r3,r0,r3"); // orr in mask for this CPU |
86 asm("orr r3,r0,r3"); // orr in mask for this CPU |
87 asm("cmp r3,r2"); // compare to iAllEngagedCpusMask |
87 asm("cmp r3,r2"); // compare to iAllEngagedCpusMask |
88 asm("orreq r3,r3,#%a0" : : "i" ((TUint32)TIdleSupport::KGlobalIdleFlag)); // if equal orr in KGlobalIdleFlag |
88 asm("orreq r3,r3,#%a0" : : "i" ((TInt)TIdleSupport::KGlobalIdleFlag)); // if equal orr in KGlobalIdleFlag |
89 STREX(12,3,1); |
89 STREX(12,3,1); |
90 asm("cmp r12, #0 "); // |
90 asm("cmp r12, #0 "); // |
91 asm("bne 1b "); // write didn't succeed try again |
91 asm("bne 1b "); // write didn't succeed try again |
92 __DATA_MEMORY_BARRIER__(r12); |
92 __DATA_MEMORY_BARRIER__(r12); |
93 asm("and r0,r3,#%a0" : : "i" ((TUint32)TIdleSupport::KGlobalIdleFlag)); |
93 asm("and r0,r3,#%a0" : : "i" ((TInt)TIdleSupport::KGlobalIdleFlag)); |
94 __JUMP(,lr); |
94 __JUMP(,lr); |
95 asm("__iAllEngagedCpusMask:"); |
95 asm("__iAllEngagedCpusMask:"); |
96 asm(".word %a0" : : "i" ((TInt)&TIdleSupport::iAllEngagedCpusMask));// |
96 asm(".word %a0" : : "i" ((TInt)&TIdleSupport::iAllEngagedCpusMask));// |
97 } |
97 } |
98 |
98 |
147 asm("cmp r2,r4"); // if r2 == r4 then all cpus have set |
147 asm("cmp r2,r4"); // if r2 == r4 then all cpus have set |
148 ARM_SEVcc(CC_EQ); |
148 ARM_SEVcc(CC_EQ); |
149 #endif |
149 #endif |
150 asm("2: "); |
150 asm("2: "); |
151 asm("cmp r3,r5"); // all (old stage does not equal new stage) |
151 asm("cmp r3,r5"); // all (old stage does not equal new stage) |
152 asm("bne 3f"); // yup return |
152 asm("ldmnefd sp!, {r4-r5,pc}"); // yup return |
153 #ifdef SYNCPOINT_WFE |
153 #ifdef SYNCPOINT_WFE |
154 __DATA_MEMORY_BARRIER__(r12); |
154 __DATA_MEMORY_BARRIER__(r12); |
155 ARM_WFE; |
155 ARM_WFE; |
156 #endif |
156 #endif |
157 asm("ldr r2,[r0]"); // otherwise re read iWaitingCpusMask into r5 |
157 asm("ldr r2,[r0]"); // otherwise re read iWaitingCpusMask into r5 |
158 __DATA_MEMORY_BARRIER__(r12); // ensure read is observed |
158 __DATA_MEMORY_BARRIER__(r12); // ensure read is observed |
159 asm("mov r3,r2,lsr #16"); // re-read new stage |
159 asm("mov r3,r2,lsr #16"); // re-read new stage |
160 asm("b 2b"); // loop back |
160 asm("b 2b"); // loop back |
161 asm("3: "); |
|
162 asm("ldmfd sp!, {r4-r5,pc}"); // return |
|
163 } |
161 } |
164 |
162 |
165 /** |
163 /** |
166 |
164 |
167 Wait for all CPUs to reach the sync point. A CPU will only exit this function when all other CPUs |
165 Wait for all CPUs to reach the sync point. A CPU will only exit this function when all other CPUs |
208 asm("ands r3,r2,#0x80000000"); // MSB set? |
206 asm("ands r3,r2,#0x80000000"); // MSB set? |
209 ARM_SEVcc(CC_NE); |
207 ARM_SEVcc(CC_NE); |
210 #endif |
208 #endif |
211 asm("2: "); |
209 asm("2: "); |
212 asm("ands r3,r2,#0x80000000"); // MSB set? |
210 asm("ands r3,r2,#0x80000000"); // MSB set? |
213 asm("bne 4f"); // yup return |
211 asm("ldmnefd sp!, {r4,pc}"); // yup return |
214 #ifdef SYNCPOINT_WFE |
212 #ifdef SYNCPOINT_WFE |
215 __DATA_MEMORY_BARRIER__(r12); |
213 __DATA_MEMORY_BARRIER__(r12); |
216 ARM_WFE; |
214 ARM_WFE; |
217 #endif |
215 #endif |
218 asm("ldr r2,[r0]"); // otherwise re read iWaitingCpusMask into r5 |
216 asm("ldr r2,[r0]"); // otherwise re read iWaitingCpusMask into r5 |
293 { |
290 { |
294 return 0; |
291 return 0; |
295 } |
292 } |
296 #endif |
293 #endif |
297 |
294 |
298 __NAKED__ TUint32 TIdleSupport::IntPending() |
295 __NAKED__ TInt TIdleSupport::IntPending() |
299 { |
296 { |
300 asm("ldr r1,__KCPUIFAddr");//r1 = address of iBaseIntIfAddress |
297 asm("ldr r1,__KCPUIFAddr");//r1 = address of iBaseIntIfAddress |
301 asm("ldr r1, [r1]");//r1 = address of Hw GIC CPU interrupt interface base address |
298 asm("ldr r1, [r1]");//r1 = address of Hw GIC CPU interrupt interface base address |
302 asm("ldr r0, [r1, #%a0]" : : "i" _FOFF(GicCpuIfc, iHighestPending)); |
299 asm("ldr r0, [r1, #%a0]" : : "i" _FOFF(GicCpuIfc, iHighestPending)); |
303 __JUMP(,lr); |
300 __JUMP(,lr); |