50 #include "u32std.h" |
50 #include "u32std.h" |
51 |
51 |
52 #ifdef __DMASIM__ |
52 #ifdef __DMASIM__ |
53 RTest test(_L("T_DMASIM")); |
53 RTest test(_L("T_DMASIM")); |
54 #else |
54 #else |
|
55 #if defined(DMA_INVERTED_THREAD_PRIORITIES) |
|
56 RTest test(_L("T_DMAINV")); |
|
57 #else |
55 RTest test(_L("T_DMA")); |
58 RTest test(_L("T_DMA")); |
|
59 #endif |
56 #endif |
60 #endif |
57 |
61 |
58 ////////////////////////////////////////////////////////////////////////////// |
62 ////////////////////////////////////////////////////////////////////////////// |
59 // Mini-framework for running tests either in a single thread or in |
63 // Mini-framework for running tests either in a single thread or in |
60 // several concurrent ones. |
64 // several concurrent ones. |
312 ASSERT(!iChannel.Handle()); |
316 ASSERT(!iChannel.Handle()); |
313 const TInt r = iChannel.Open(iChannelId, aDesCount, aMaxFragmentSize); |
317 const TInt r = iChannel.Open(iChannelId, aDesCount, aMaxFragmentSize); |
314 if (r == KErrNotSupported) |
318 if (r == KErrNotSupported) |
315 return r; |
319 return r; |
316 XTEST1(KErrNone == r || KErrInUse == r, r); |
320 XTEST1(KErrNone == r || KErrInUse == r, r); |
317 |
321 |
318 if(KErrInUse == r) |
322 if(KErrInUse == r) |
319 { |
323 { |
320 // Channel is in use. |
324 // Channel is in use. |
321 RDebug::Printf("\nDMA Channel %d is in use",iChannelId); |
325 RDebug::Printf("\nDMA Channel %d is in use",iChannelId); |
322 if(0 == iCurIter) |
326 if(0 == iCurIter) |
347 CActiveScheduler::Add(this); |
351 CActiveScheduler::Add(this); |
348 TBuf<16> name; |
352 TBuf<16> name; |
349 name = _L("TESTER-"); |
353 name = _L("TESTER-"); |
350 name.AppendNum(aIdx); |
354 name.AppendNum(aIdx); |
351 test(iThread.Create(name, ThreadFunction, 0x2000, NULL, this) == KErrNone); |
355 test(iThread.Create(name, ThreadFunction, 0x2000, NULL, this) == KErrNone); |
|
356 #if defined(DMA_INVERTED_THREAD_PRIORITIES) |
|
357 iThread.SetPriority(EPriorityRealTime); |
|
358 #else |
352 iThread.SetPriority(EPriorityLess); |
359 iThread.SetPriority(EPriorityLess); |
|
360 #endif // #if defined(DMA_INVERTED_THREAD_PRIORITIES) |
353 iThread.Logon(iStatus); |
361 iThread.Logon(iStatus); |
354 SetActive(); |
362 SetActive(); |
355 iThread.Resume(); |
363 iThread.Resume(); |
356 } |
364 } |
357 |
365 |
881 XTEST2(r == KErrNone, r, aSize); |
889 XTEST2(r == KErrNone, r, aSize); |
882 test(aChannel.FragmentCheck(KRequest2, aFragmentCount)); |
890 test(aChannel.FragmentCheck(KRequest2, aFragmentCount)); |
883 |
891 |
884 r = aChannel.Execute(_L8("Q0Q1Q2C")); |
892 r = aChannel.Execute(_L8("Q0Q1Q2C")); |
885 XTEST1(r == KErrNone, r); |
893 XTEST1(r == KErrNone, r); |
886 #ifdef __DMASIM__ |
|
887 // At least part of the last destination buffer should be |
|
888 // unchanged if cancel occured before the transfer completed. |
|
889 // Assert only on WINS as real DMACs are too fast. |
|
890 XTEST(! aChannel.CheckBuffer(KDestBuf2, 'C')); |
|
891 #endif |
|
892 |
894 |
893 // |
895 // |
894 // Perform another transfer to ensure cancel operation let the |
896 // Perform another transfer to ensure cancel operation let the |
895 // framework in a consistent state. |
897 // framework in a consistent state. |
896 // |
898 // |
921 r = aChannel.Fragment(KRequest2, KSrcBuf2, KDestBuf2, aSize, &rs2); |
923 r = aChannel.Fragment(KRequest2, KSrcBuf2, KDestBuf2, aSize, &rs2); |
922 XTEST2(r == KErrNone, r, aSize); |
924 XTEST2(r == KErrNone, r, aSize); |
923 test(aChannel.FragmentCheck(KRequest2, aFragmentCount)); |
925 test(aChannel.FragmentCheck(KRequest2, aFragmentCount)); |
924 // Queue first request (Q0) |
926 // Queue first request (Q0) |
925 r = aChannel.Execute(_L8("Q0")); |
927 r = aChannel.Execute(_L8("Q0")); |
926 // Wait a second, so next request will be queued on its own |
928 // Wait till Q0 completes before queuing next request |
927 // (instead of being appended to the previous one) |
929 // this is to ensure that Q0's link register doesn't |
928 User::After(1000000); |
930 // get over-written, which would lead to the test passing |
|
931 // trivially. |
|
932 // |
|
933 // Polling is the only way to achieve this under the |
|
934 // current test interface (since passing in a new |
|
935 // TRequestStatus necessitates re-fragmenting) |
|
936 for(TInt i = 0; i < 100; i++) |
|
937 { |
|
938 if(aChannel.CheckBuffer(KDestBuf0, 'A')) |
|
939 break; |
|
940 |
|
941 User::After(10000); // Wait 10 milliseconds |
|
942 } |
|
943 XTEST(aChannel.CheckBuffer(KDestBuf0, 'A')); |
|
944 |
929 // Queue third request (Q2) |
945 // Queue third request (Q2) |
930 r = aChannel.Execute(_L8("Q2")); |
946 r = aChannel.Execute(_L8("Q2")); |
931 XTEST1(r == KErrNone, r); |
947 XTEST1(r == KErrNone, r); |
932 User::WaitForRequest(rs2); |
948 User::WaitForRequest(rs2); |
933 XTEST1(rs2 == KErrNone, rs2.Int()); |
949 XTEST1(rs2 == KErrNone, rs2.Int()); |
934 XTEST(aChannel.CheckBuffer(KDestBuf0, 'A')); |
|
935 // KDestBuf1 should have been left untouched! |
950 // KDestBuf1 should have been left untouched! |
936 // If we find all B's in KDestBuf1, that means the last descriptor of the |
951 // If we find all B's in KDestBuf1, that means the last descriptor of the |
937 // first request (Q0) wasn't properly unlinked and still points to the Q1 |
952 // first request (Q0) wasn't properly unlinked and still points to the Q1 |
938 // descriptor chain from the previous run. |
953 // descriptor chain from the previous run. |
939 XTEST(aChannel.CheckBuffer(KDestBuf1, '\0')); |
954 XTEST(aChannel.CheckBuffer(KDestBuf1, '\0')); |
958 XTEST(aChannel.Fragment(KRequest2, KSrcBuf2, KDestBuf2, aSize) == KErrNone); |
973 XTEST(aChannel.Fragment(KRequest2, KSrcBuf2, KDestBuf2, aSize) == KErrNone); |
959 test(aChannel.FragmentCheck(KRequest2, aFragmentCount)); |
974 test(aChannel.FragmentCheck(KRequest2, aFragmentCount)); |
960 XTEST(aChannel.Execute(_L8("Q0Q1Q2")) == KErrNone); |
975 XTEST(aChannel.Execute(_L8("Q0Q1Q2")) == KErrNone); |
961 User::WaitForRequest(rs0); |
976 User::WaitForRequest(rs0); |
962 XTEST(rs0 != KErrNone); |
977 XTEST(rs0 != KErrNone); |
|
978 // Request 0 should definitely not succeed, due to the |
|
979 // fault injection. However, depending on the underlying |
|
980 // hardware type, the transfers for the |
|
981 // subsequent requests may or may not complete. |
|
982 // On a double buffered or scatter-gather controller |
|
983 // if the later requests were already programmed into the |
|
984 // second buffer, or linked in to the hardware descriptor chain |
|
985 // they could proceed autonomously. |
963 XTEST(! aChannel.CheckBuffer(KDestBuf0, 'A')); |
986 XTEST(! aChannel.CheckBuffer(KDestBuf0, 'A')); |
964 XTEST(! aChannel.CheckBuffer(KDestBuf1, 'B')); |
|
965 XTEST(! aChannel.CheckBuffer(KDestBuf2, 'C')); |
|
966 XTEST(aChannel.Execute(_L8("C")) == KErrNone); |
987 XTEST(aChannel.Execute(_L8("C")) == KErrNone); |
967 |
988 |
968 // Transfer again to ensure cancel cleaned-up correctly |
989 // Transfer again to ensure cancel cleaned-up correctly |
969 aChannel.FillBuffer(KDestBuf0, '\0'); |
990 aChannel.FillBuffer(KDestBuf0, '\0'); |
970 aChannel.FillBuffer(KDestBuf1, '\0'); |
991 aChannel.FillBuffer(KDestBuf1, '\0'); |
1082 } |
1103 } |
1083 |
1104 |
1084 |
1105 |
1085 TInt E32Main() |
1106 TInt E32Main() |
1086 { |
1107 { |
|
1108 COMPLETE_POST_BOOT_SYSTEM_TASKS(); |
1087 test.Title(); |
1109 test.Title(); |
1088 |
1110 |
1089 test.Start(_L("Parsing command-line")); |
1111 test.Start(_L("Parsing command-line")); |
1090 // Default values when run with empty command-line |
1112 // Default values when run with empty command-line |
1091 TInt maxfrag = 16; // 5 fragments needed to exercise fully double-buffering state machine |
1113 TInt maxfrag = 16; // 5 fragments needed to exercise fully double-buffering state machine |
1092 TInt maxIter = 3; |
1114 TInt maxIter = 1; |
1093 TInt maxchannel = KMaxTInt; |
1115 TInt maxchannel = KMaxTInt; |
1094 TBool crashDbg = EFalse; |
1116 TBool crashDbg = EFalse; |
1095 TInt maxFragSize = 0x4000; //16k |
1117 TInt maxFragSize = 0x4000; //16k |
1096 |
1118 |
1097 (void) ParseCmdLine(crashDbg, maxfrag, maxIter, maxchannel, maxFragSize); |
1119 (void) ParseCmdLine(crashDbg, maxfrag, maxIter, maxchannel, maxFragSize); |
1100 { |
1122 { |
1101 User::SetCritical(User::ESystemCritical); |
1123 User::SetCritical(User::ESystemCritical); |
1102 User::SetProcessCritical(User::ESystemCritical); |
1124 User::SetProcessCritical(User::ESystemCritical); |
1103 } |
1125 } |
1104 |
1126 |
|
1127 RProcess p; |
|
1128 RThread t; |
|
1129 #if defined(DMA_INVERTED_THREAD_PRIORITIES) |
|
1130 // Set the process priority to the maximum value allowed for normal apps. |
|
1131 // This will increase the system's interpretation of the thread priority. |
|
1132 test(p.SetPriority(EPriorityHigh) == KErrNone); |
|
1133 t.SetPriority(EPriorityRealTime); |
|
1134 #else |
|
1135 t.SetPriority(EPriorityLess); |
|
1136 #endif // #if defined(DMA_INVERTED_THREAD_PRIORITIES) |
|
1137 RDebug::Printf("Process priority: %d", p.Priority()); |
1105 |
1138 |
1106 TInt r; |
1139 TInt r; |
1107 #if defined(__DMASIM__) && defined(__WINS__) |
1140 #if defined(__DMASIM__) && defined(__WINS__) |
1108 test.Next(_L("Loading DMA simulator")); |
1141 test.Next(_L("Loading DMA simulator")); |
1109 r = User::LoadLogicalDevice(_L("DMASIM.DLL")); |
1142 r = User::LoadLogicalDevice(_L("DMASIM.DLL")); |