First public contribution.
1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\nkernsa\testipi.cpp
18 #include <nktest/nkutils.h>
22 class TTestIPI : public TGenericIPI
26 static TTestIPI* New();
27 static void Isr(TGenericIPI*);
28 void Inc(TInt aCpu, TInt aInc=1) {iExpected[aCpu] += aInc;}
29 void IncM(TUint32 aMask);
32 TInt iCount[KMaxCpus];
33 TInt iExpected[KMaxCpus];
38 memclr(iCount, sizeof(iCount));
39 memclr(iExpected, sizeof(iExpected));
42 TTestIPI* TTestIPI::New()
44 TTestIPI* p = new TTestIPI;
49 void TTestIPI::Isr(TGenericIPI* a)
51 TTestIPI& ipi = *(TTestIPI*)a;
52 TInt cpu = NKern::CurrentCpu();
56 void TTestIPI::IncM(TUint32 aMask)
59 for(i=0; i<KMaxCpus; ++i)
66 void TTestIPI::Check()
69 for(i=0; i<KMaxCpus; ++i)
71 TEST_RESULT3(iCount[i]==iExpected[i], "CPU %d Count %d Expected %d", i, iCount[i], iExpected[i]);
75 void IPITestThread1(TAny*)
78 TUint32 all_cpus = ~(0xffffffffu << NKern::NumberOfCpus());
84 ipi.Queue(&TTestIPI::Isr, 1u<<cpu);
91 TUint32 m = all_cpus & ~(1u<<cpu);
92 ipi2.Queue(&TTestIPI::Isr, m);
93 ipi2.WaitCompletion();
100 ipi3.QueueAll(&TTestIPI::Isr);
101 ipi3.WaitCompletion();
107 ipi4.QueueAllOther(&TTestIPI::Isr);
108 ipi4.WaitCompletion();
109 ipi4.IncM(all_cpus & ~(1u<<NKern::CurrentCpu()) );
118 CreateThreadAndWaitForExit("IPITest1", &IPITestThread1, 12, 0, 0, -1, cpu);
123 class TTestIPI2 : public TGenericIPI
127 static TTestIPI2* New(TInt aId);
128 static void Isr(TGenericIPI*);
129 static void Thread(TAny*);
135 static volatile TInt NextPos;
136 static volatile TUint32 Buffer[EBufSize];
137 static volatile TUint32 PauseHere;
140 volatile TInt TTestIPI2::NextPos;
141 volatile TUint32 TTestIPI2::Buffer[TTestIPI2::EBufSize];
142 volatile TUint32 TTestIPI2::PauseHere;
144 __ASSERT_COMPILE(TTestIPI2::EBufSize >= TTestIPI2::EMaxIPI*KMaxCpus);
146 TTestIPI2::TTestIPI2(TInt aId)
151 TTestIPI2* TTestIPI2::New(TInt aId)
153 TTestIPI2* p = new TTestIPI2(aId);
158 void TTestIPI2::Isr(TGenericIPI* a)
160 TTestIPI2& ipi = *(TTestIPI2*)a;
161 TUint32 cpu = NKern::CurrentCpu();
162 TUint32 x = (cpu<<16) | ipi.iId;
163 TInt pos = __e32_atomic_tas_ord32(&NextPos, EBufSize, 0, 1);
166 while (PauseHere == x)
170 void TTestIPI2::Thread(TAny*)
172 TTestIPI2* ipi[EMaxIPI];
173 TUint32 all_cpus = ~(0xffffffffu << NKern::NumberOfCpus());
174 TInt this_cpu = NKern::CurrentCpu();
175 TInt pause_cpu = this_cpu + 1;
176 if (pause_cpu >= NKern::NumberOfCpus())
178 if (pause_cpu == this_cpu)
180 TUint32 this_cpu_mask = 1u<<this_cpu;
181 TUint32 pause_cpu_mask = (pause_cpu>=0) ? (1u<<pause_cpu) : 0;
182 TUint32 other_cpus = all_cpus & ~(this_cpu_mask | pause_cpu_mask);
183 TInt num_other_cpus = __e32_bit_count_32(other_cpus);
185 for(i=0; i<EMaxIPI; ++i)
191 PauseHere = (pause_cpu<<16) | (EMaxIPI/2);
193 TEST_PRINT3("this_cpu=%d pause_cpu=%d PauseHere=%x", this_cpu, pause_cpu, PauseHere);
195 TInt irq = NKern::DisableAllInterrupts();
196 for (i=0; i<EMaxIPI; ++i)
197 ipi[i]->QueueAll(&Isr);
199 TInt expected1 = num_other_cpus*EMaxIPI + EMaxIPI/2;
200 while (NextPos != expected1)
204 TInt expected2 = num_other_cpus*EMaxIPI + EMaxIPI;
205 while (NextPos != expected2)
207 NKern::RestoreInterrupts(irq);
208 ipi[EMaxIPI-1]->WaitCompletion();
210 for(i=0; i<NextPos; ++i)
212 TEST_PRINT1("%08x", Buffer[i]);
215 for(i=0; i<EMaxIPI; ++i)
224 CreateThreadAndWaitForExit("IPITest2", &TTestIPI2::Thread, 12, 0, 0, -1, cpu);
231 TEST_PRINT("Testing generic IPIs...");