sl@0: // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32test\debug\t_cache.cpp sl@0: // Overview: sl@0: // Performs cache checking in order to ensure it is running correctly. sl@0: // Runs automatically or as manual test. (Type "t_cache help" for details.) sl@0: // API Information: sl@0: // class Cache sl@0: // class L2Cache sl@0: // Details: sl@0: // -Test1 - Displays cache properties. sl@0: // -Test2 - Gets thresholds. sl@0: // -Test3 - Sets thresholds. sl@0: // -Test4 - Compares different memory mappings of data. sl@0: // -Test5 - Compares different memory mappings of code. sl@0: // -Test6 - Tests Write Back mode. sl@0: // -Test7 - Tests cache maintenance functions sl@0: // It can also perform more specified tests if run manually: sl@0: // - t_cache info Test1 only sl@0: // - t_cache data Runs data chunk test (Test 4) with specified chunk size. For example, sl@0: // "t_cache data 10000" will run data chunk test against 64KB chunk. sl@0: // - t_cache code Runs code chunk test (Test 5) for specified chink size. For example, sl@0: // "t_cache code 10000" will run code chunk test against 64KB chunk. sl@0: // - t_cache data+ Runs data chunk test for specified set of chunk sizes. For example, sl@0: // "t_cache data+1000" will perform data chunk test for sizes 4K, 8K,... up to 512K. sl@0: // - t_cache code+ Runs code chunk test for specified set of sizes. For example, sl@0: // "t_cache code+1000" will perform code chunk test for sizes 4K, 8K,... up to 512K. sl@0: // - t_cache threshold Diplays thresholds for all caches on the platform. sl@0: // - t_cache threshold T P C H Sets new values for cache thresholds: sl@0: // - "T" specifies the type of cache to whose threshould are to be chenged: sl@0: // 1 for Instruction (or Unified) Cache. sl@0: // 2 for Data Cache (for ARMv7 and later, this is Point-of-Coherency threshold. sl@0: // 4 for XScale AltData Cache. sl@0: // 8 for Point-of-Unification Data Cache Threshold for ARMv7 and later platforms. sl@0: // 10 for L2 (L210 or XScale L2 cache) sl@0: // - "P" "C" & "H" are hex values for purge, clean & flush thresholds. sl@0: // For example: "t_cache 1 10000 10000 10000" sets 64KB for all thresholds in Instruction Cache. sl@0: // - t_cache usecase Runs particular use case tests. sl@0: // - t_cache help Displays the list of manual commands. sl@0: // Platforms/Drives/Compatibility: sl@0: // Hardware - ARM only (Manual). Not supported on emulator. sl@0: // Assumptions/Requirement/Pre-requisites: sl@0: // Failures and causes: sl@0: // Base Port information: sl@0: // d_cache.mmp to be built from the baseport. sl@0: // sl@0: // sl@0: sl@0: #include sl@0: #include "d_cache.h" sl@0: sl@0: //------------globals--------------------- sl@0: LOCAL_D RTest test(_L("T_CACHE")); sl@0: _LIT(KPrintCacheInfos,"info"); sl@0: _LIT(KTestData,"data"); sl@0: _LIT(KTestCode,"code"); sl@0: _LIT(KHelp,"help"); sl@0: _LIT(KThreshold,"threshold"); sl@0: _LIT(KIncremental,"+"); sl@0: _LIT(KUseCase,"usecase"); sl@0: sl@0: RCacheTestDevice Device; sl@0: RCacheTestDevice::TCacheInfo CacheInfo; sl@0: TBuf TempBuff; sl@0: sl@0: const TInt KDefaultDataSize = 0x20000; sl@0: const TInt KDefaultCodeSize = 0x804; //2K+4. Should be <= TestCodeFuncSize(). Otherwise, code test won't run against rom image. sl@0: const TInt KMaxChunkSize = 0x80000; //512KB Incremental tests limit sl@0: const TInt KWriteBackTestSizeSize = 0x4000; // Shouldn't go over cache thresholds (where purge becomes flush). sl@0: sl@0: extern void DataSegmetTestFunct(void* aBase, TInt aSize); sl@0: sl@0: /** Loads & opens LDD.*/ sl@0: void StartDriver() sl@0: { sl@0: TInt r = User::LoadLogicalDevice(KCacheTestDriverName); sl@0: test( r==KErrNone || r==KErrAlreadyExists); sl@0: if((r = Device.Open())!=KErrNone) sl@0: { sl@0: User::FreeLogicalDevice(KCacheTestDriverName); sl@0: test.Printf(_L("Could not open LDD")); sl@0: test(0); sl@0: } sl@0: } sl@0: sl@0: /** Closes and unloads LDD.*/ sl@0: void StopDriver() sl@0: { sl@0: Device.Close(); sl@0: User::FreeLogicalDevice(KCacheTestDriverName); sl@0: } sl@0: sl@0: /** Get cache info from device driver. This will update CacheInfo global variable.*/ sl@0: void GetCacheInfo() sl@0: { sl@0: TInt r = Device.GetCacheInfo(CacheInfo); sl@0: test(r==KErrNone); sl@0: } sl@0: sl@0: //--------------------------------------------- sl@0: //! @SYMTestCaseID MMU-T_CACHE-01 sl@0: //! @SYMTestType ST sl@0: //! @SYMPREQ PREQ305 sl@0: //! @SYMREQ REQ5795 sl@0: //! @SYMTestCaseDesc Displays cache properties. sl@0: //! @SYMTestExpectedResults KErrNone sl@0: //! @SYMTestPriority Low sl@0: //! @SYMTestStatus Implemented sl@0: //--------------------------------------------- sl@0: void Test1() sl@0: { sl@0: TInt i; sl@0: sl@0: test.Printf(_L("General Info:\n")); sl@0: TPtr ptr = CacheInfo.iDesc.Expand(); sl@0: test.Printf(ptr); sl@0: test.Printf(_L("CacheCount:%d, MaxCacheSize:%xH, MemoryRemapping:%d, OuterCache:%d\n"),CacheInfo.iCacheCount, CacheInfo.iMaxCacheSize, CacheInfo.iMemoryRemapping, CacheInfo.iOuterCache); sl@0: test.Printf(_L("DMAMemoryAlignement:%d\n"),CacheInfo.iDmaBufferAlignment); sl@0: sl@0: sl@0: test.Printf(_L("Per Level Info:\n")); sl@0: test.Printf(_L("Level\tData\tInstr\tSize(b)\tLine(b)\tWays\tSets\tDescription\n")); sl@0: sl@0: for (i = 0; i>=1; sl@0: info[i].iClean >>=1; sl@0: info[i].iFlush >>=1; sl@0: test(KErrNone==Device.SetThreshold(info[i])); sl@0: } sl@0: test.Printf(_L(" ... %d caches present & tested\n"), tested); sl@0: } sl@0: sl@0: sl@0: sl@0: void DoTest4(RCacheTestDevice::TCacheAttr aCacheAttr, RCacheTestDevice::TChunkTest& aDC, TInt& aTime1, TInt& aTime2) sl@0: { sl@0: aDC.iCacheAttr = aCacheAttr; sl@0: sl@0: aDC.iShared = EFalse; sl@0: test(KErrNone==Device.TestDataChunk(aDC)); sl@0: aTime1 = aDC.iTime; sl@0: sl@0: aDC.iShared = ETrue; sl@0: test(KErrNone==Device.TestDataChunk(aDC)); sl@0: aTime2 = aDC.iTime; sl@0: } sl@0: //--------------------------------------------- sl@0: //! @SYMTestCaseID MMU-T_CACHE-04 sl@0: //! @SYMTestType ST sl@0: //! @SYMPREQ PREQ305 sl@0: //! @SYMREQ REQ5795 sl@0: //! @SYMTestCaseDesc Compares different memory mappings of data. sl@0: //! @SYMTestActions Runs the same performance test against data in the chunks with different cache attributes. sl@0: //! Also, runs the same test against data from user & kernel heaps. sl@0: //! @SYMTestExpectedResults KErrNone sl@0: //! @SYMTestPriority Low sl@0: //! @SYMTestStatus Implemented sl@0: //--------------------------------------------- sl@0: void Test4(TInt aSize) sl@0: { sl@0: RCacheTestDevice::TChunkTest dC; sl@0: dC.iSize = aSize; sl@0: dC.iUseCase = 0; //not used sl@0: dC.iLoops = 0; //not used sl@0: TInt timeNS=0, timeS=0; sl@0: sl@0: test.Printf(_L(" Time\n")); sl@0: test.Printf(_L("Mem_Type ActualMapAttr NotShared Shared\n")); sl@0: test.Printf(_L("----------------------------------------------\n")); sl@0: sl@0: DoTest4(RCacheTestDevice::E_FullyBlocking, dC, timeNS, timeS); sl@0: test.Printf(_L("FullyBlocking %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_Buffered_NC, dC, timeNS, timeS); sl@0: test.Printf(_L("Buffered_NC %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_Buffered_C, dC, timeNS, timeS); sl@0: test.Printf(_L("Buffered_C %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: sl@0: sl@0: DoTest4(RCacheTestDevice::E_InnerWT, dC, timeNS, timeS); sl@0: test.Printf(_L("InnerWT %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_InnerWBRA, dC, timeNS, timeS); sl@0: test.Printf(_L("InnerWBRA %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_InnerWB, dC, timeNS, timeS); sl@0: test.Printf(_L("InnerWB %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: sl@0: if(CacheInfo.iOuterCache) sl@0: { sl@0: DoTest4(RCacheTestDevice::E_OuterWT, dC, timeNS, timeS); sl@0: test.Printf(_L("OuterWT %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_OuterWBRA, dC, timeNS, timeS); sl@0: test.Printf(_L("OuterWBRA %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_OuterWB, dC, timeNS, timeS); sl@0: test.Printf(_L("OuterWB %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: sl@0: DoTest4(RCacheTestDevice::E_InOutWT, dC, timeNS, timeS); sl@0: test.Printf(_L("InOutWT %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_InOutWBRA, dC, timeNS, timeS); sl@0: test.Printf(_L("InOutWBRA %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_InOutWB, dC, timeNS, timeS); sl@0: test.Printf(_L("InOutWB %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: } sl@0: sl@0: sl@0: DoTest4(RCacheTestDevice::E_StronglyOrder, dC, timeNS, timeS); sl@0: test.Printf(_L("StronglyOrder %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_Device, dC, timeNS, timeS); sl@0: test.Printf(_L("Device %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_Normal_Uncached, dC, timeNS, timeS); sl@0: test.Printf(_L("Normal_Uncached %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_Normal_Cached, dC, timeNS, timeS); sl@0: test.Printf(_L("Normal_Cached %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: sl@0: if(CacheInfo.iMemoryRemapping) sl@0: { sl@0: DoTest4(RCacheTestDevice::E_KernelInternal4, dC, timeNS, timeS); sl@0: test.Printf(_L("KernelInternal4 %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_PlatformSpecific5, dC, timeNS, timeS); sl@0: test.Printf(_L("PlatSpecific5 %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_PlatformSpecific6, dC, timeNS, timeS); sl@0: test.Printf(_L("PlatSpecific6 %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_PlatformSpecific7, dC, timeNS, timeS); sl@0: test.Printf(_L("PlatSpecific7 %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: sl@0: sl@0: DoTest4(RCacheTestDevice::E_InnerWT_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("InnerWT_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_InnerWBRA_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("InnerWBRA_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_InnerWB_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("InnerWB_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: sl@0: if(CacheInfo.iOuterCache) sl@0: { sl@0: DoTest4(RCacheTestDevice::E_OuterWT_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("OuterWT_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_OuterWBRA_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("OuterWBRA_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_OuterWB_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("OuterWB_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: sl@0: DoTest4(RCacheTestDevice::E_InOutWT_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("InOutWT_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_InOutWBRA_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("InOutWBRA_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest4(RCacheTestDevice::E_InOutWB_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("InOutWB_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: } sl@0: } sl@0: sl@0: //Run against kernel heap - allow the test to fail due to OOM sl@0: dC.iCacheAttr = RCacheTestDevice::E_Default; sl@0: TInt r = Device.TestDataChunk(dC); sl@0: if (r==KErrNone) test.Printf(_L("Kernel Heap ---------\t%7d\t-------\n"), dC.iTime); sl@0: else if (r==KErrNoMemory) test.Printf(_L("Kernel Heap Cannot allocate memory\n")); sl@0: else test(0);//fail sl@0: sl@0: //Run against user heap - allow the test to fail due to OOM sl@0: void* buffer = User::Alloc(dC.iSize); sl@0: if (buffer == NULL) sl@0: { sl@0: test.Printf(_L("User Heap Cannot allocate memory\n")); sl@0: return; sl@0: } sl@0: TInt time = User::NTickCount(); sl@0: DataSegmetTestFunct(buffer , dC.iSize); sl@0: time = User::NTickCount() - time; sl@0: User::Free(buffer); sl@0: test.Printf(_L("User Heap ---------\t%7d\t-------\n"), time); sl@0: sl@0: } sl@0: sl@0: sl@0: void DoTest5(RCacheTestDevice::TCacheAttr aCacheAttr, RCacheTestDevice::TChunkTest& aDC, TInt& aTime1, TInt& aTime2) sl@0: { sl@0: aDC.iCacheAttr = aCacheAttr; sl@0: sl@0: aDC.iShared = EFalse; sl@0: test(KErrNone==Device.TestCodeChunk(aDC)); sl@0: aTime1 = aDC.iTime; sl@0: sl@0: aDC.iShared = ETrue; sl@0: test(KErrNone==Device.TestCodeChunk(aDC)); sl@0: aTime2 = aDC.iTime; sl@0: } sl@0: //--------------------------------------------- sl@0: //! @SYMTestCaseID MMU-T_CACHE-05 sl@0: //! @SYMTestType ST sl@0: //! @SYMPREQ PREQ305 sl@0: //! @SYMREQ REQ5795 sl@0: //! @SYMTestCaseDesc Compares different memory mappings of code. sl@0: //! @SYMTestActions Runs the same performance test against code in chunks with different cache attributes. sl@0: //! Also, runs the same test against code from rom.. sl@0: //! @SYMTestExpectedResults KErrNone sl@0: //! @SYMTestPriority Low sl@0: //! @SYMTestStatus Implemented sl@0: //--------------------------------------------- sl@0: void Test5(TInt aSize) sl@0: { sl@0: RCacheTestDevice::TChunkTest dC; sl@0: dC.iSize = aSize; sl@0: dC.iUseCase = 0; //not used sl@0: dC.iLoops = 0; //not used sl@0: TInt timeNS=0, timeS=0; sl@0: sl@0: test.Printf(_L(" Time\n")); sl@0: test.Printf(_L("Mem_Type AttemptedMapAttr NotShared Shared\n")); sl@0: test.Printf(_L("----------------------------------------------\n")); sl@0: sl@0: DoTest5(RCacheTestDevice::E_FullyBlocking, dC, timeNS, timeS); sl@0: test.Printf(_L("FullyBlocking %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_Buffered_NC, dC, timeNS, timeS); sl@0: test.Printf(_L("Buffered_NC %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_Buffered_C, dC, timeNS, timeS); sl@0: test.Printf(_L("Buffered_C %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: sl@0: sl@0: DoTest5(RCacheTestDevice::E_InnerWT, dC, timeNS, timeS); sl@0: test.Printf(_L("InnerWT %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_InnerWBRA, dC, timeNS, timeS); sl@0: test.Printf(_L("InnerWBRA %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_InnerWB, dC, timeNS, timeS); sl@0: test.Printf(_L("InnerWB %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: sl@0: if(CacheInfo.iOuterCache) sl@0: { sl@0: DoTest5(RCacheTestDevice::E_OuterWT, dC, timeNS, timeS); sl@0: test.Printf(_L("OuterWT %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_OuterWBRA, dC, timeNS, timeS); sl@0: test.Printf(_L("OuterWBRA %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_OuterWB, dC, timeNS, timeS); sl@0: test.Printf(_L("OuterWB %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: sl@0: DoTest5(RCacheTestDevice::E_InOutWT, dC, timeNS, timeS); sl@0: test.Printf(_L("InOutWT %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_InOutWBRA, dC, timeNS, timeS); sl@0: test.Printf(_L("InOutWBRA %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_InOutWB, dC, timeNS, timeS); sl@0: test.Printf(_L("InOutWB %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: } sl@0: sl@0: sl@0: DoTest5(RCacheTestDevice::E_StronglyOrder, dC, timeNS, timeS); sl@0: test.Printf(_L("StronglyOrder %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_Device, dC, timeNS, timeS); sl@0: test.Printf(_L("Device %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_Normal_Uncached, dC, timeNS, timeS); sl@0: test.Printf(_L("Normal_Uncached %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_Normal_Cached, dC, timeNS, timeS); sl@0: test.Printf(_L("Normal_Cached %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: sl@0: if(CacheInfo.iMemoryRemapping) sl@0: { sl@0: DoTest5(RCacheTestDevice::E_InnerWT_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("InnerWT_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_InnerWBRA_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("InnerWBRA_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_InnerWB_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("InnerWB_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: sl@0: if(CacheInfo.iOuterCache) sl@0: { sl@0: DoTest5(RCacheTestDevice::E_OuterWT_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("OuterWT_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_OuterWBRA_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("OuterWBRA_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_OuterWB_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("OuterWB_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: sl@0: DoTest5(RCacheTestDevice::E_InOutWT_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("InOutWT_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_InOutWBRA_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("InOutWBRA_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: DoTest5(RCacheTestDevice::E_InOutWB_Remapped, dC, timeNS, timeS); sl@0: test.Printf(_L("InOutWB_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS); sl@0: } sl@0: } sl@0: sl@0: //Run against kernel heap - allow the test to fail due to OOM sl@0: dC.iCacheAttr = RCacheTestDevice::E_Default; sl@0: TInt r = Device.TestCodeChunk(dC); sl@0: if (r==KErrNone) test.Printf(_L("Run from rom ---------\t%7d\t-------\n"), dC.iTime); sl@0: else if (r==KErrNoMemory) test.Printf(_L("Run from rom Cannot allocate memory\n")); sl@0: else test(0);//fail sl@0: sl@0: } sl@0: sl@0: sl@0: sl@0: //--------------------------------------------- sl@0: //! @SYMTestCaseID MMU-T_CACHE-06 sl@0: //! @SYMTestType ST sl@0: //! @SYMPREQ PREQ305 sl@0: //! @SYMREQ REQ5795 sl@0: //! @SYMTestCaseDesc Tests Write Back mode. sl@0: //! @SYMTestActions The driver allocates write back chunk, write data into it and invalidate (aka purge) sl@0: // the chunk from the cache. Then, it counts the number of bytes of the chunk that sl@0: // reached the physical memory. sl@0: //! @SYMTestExpectedResults KErrNone sl@0: //! @SYMTestPriority Low sl@0: //! @SYMTestStatus Implemented sl@0: //--------------------------------------------- sl@0: sl@0: void Test6() sl@0: { sl@0: test.Printf(_L("Test4: Testing WriteBack cache mode...\n")); sl@0: RCacheTestDevice::TChunkTest dC; sl@0: sl@0: sl@0: test.Printf(_L("Cache\tMemType\tChecking\tSize\tBytesInRAM\tVerdict\n")); sl@0: test.Printf(_L("-----\t-------\t--------\t----\t----------\t-------\n")); sl@0: // sl@0: dC.iSize = KWriteBackTestSizeSize; sl@0: if(CacheInfo.iMemoryRemapping) dC.iCacheAttr = RCacheTestDevice::E_InnerWBRA_Remapped; sl@0: else dC.iCacheAttr = RCacheTestDevice::E_InnerWBRA; sl@0: test(Device.TestWriteBackReadAllocate(dC)==KErrNone); sl@0: if (dC.iSize& command) sl@0: { sl@0: TUint arg; sl@0: TInt length = command.Length()-5; sl@0: if (length <=0) sl@0: return KErrArgument; sl@0: TPtrC ptr = command.Mid(5,length); sl@0: TLex lex(ptr); sl@0: lex.Val(arg, EHex); sl@0: return arg; sl@0: } sl@0: sl@0: /** Invoked by "t_cache info"*/ sl@0: void ManualCacheInfo() sl@0: { sl@0: sl@0: test.Start(_L("Cache Info:")); sl@0: StartDriver(); sl@0: GetCacheInfo(); sl@0: Test1(); sl@0: test.Printf(_L("Press any key...\n")); sl@0: test.Getch(); sl@0: StopDriver(); sl@0: test.End(); sl@0: return; sl@0: } sl@0: sl@0: /** Invoked by "t_cache code threshold [

]"*/ sl@0: TInt ManualThresholds(TBuf<64>& command) sl@0: { sl@0: TUint arg[4]; sl@0: TInt argCurrent=0; sl@0: TInt argStart = 9; //jump over "threshold" sl@0: TInt argEnd; sl@0: TChar c; sl@0: sl@0: test.Start(_L("Thresholds:")); sl@0: StartDriver(); sl@0: GetCacheInfo(); sl@0: sl@0: sl@0: // Decode input arguments from the command line sl@0: while (argCurrent<4) sl@0: { sl@0: find_arg_start: sl@0: if (argStart >= command.Length()) break; sl@0: c = command[argStart]; sl@0: if (c.IsSpace()) sl@0: { sl@0: argStart++; sl@0: goto find_arg_start; sl@0: } sl@0: sl@0: argEnd = argStart+1; sl@0: find_arg_end: sl@0: if (argEnd >= command.Length()) goto get_arg; sl@0: c = command[argEnd]; sl@0: if (c.IsSpace()) goto get_arg; sl@0: argEnd++; sl@0: goto find_arg_end; sl@0: sl@0: get_arg: sl@0: TPtrC ptr = command.Mid(argStart,argEnd-argStart); sl@0: TLex lex(ptr); sl@0: lex.Val(arg[argCurrent++], EHex); sl@0: argStart=argEnd; sl@0: } sl@0: sl@0: test.Printf(_L("%d argument(s) decoded\n"),argCurrent); sl@0: sl@0: RCacheTestDevice::TThresholdInfo info; sl@0: sl@0: //If te values are provided in the command line, set thresholds with the given paramaters. sl@0: if (argCurrent == 4) sl@0: { sl@0: test.Printf(_L("Setting thresholds: ...\n")); sl@0: test.Printf(_L("Cache Type:%xh P:%xh C:%xh F:%xh\n"),arg[0], arg[1], arg[2], arg[3]); sl@0: info.iCacheType=arg[0]; sl@0: info.iPurge = arg[1]; sl@0: info.iClean = arg[2]; sl@0: info.iFlush = arg[3]; sl@0: TInt r = Device.SetThreshold(info); sl@0: test.Printf(_L("... returned %d\n"),r); sl@0: } sl@0: sl@0: //Read thresholds from Kernel. sl@0: test.Printf(_L("Reading thresholds(hex)...\n")); sl@0: Test2(); sl@0: sl@0: test.Printf(_L("Press any key...\n")); sl@0: test.Getch(); sl@0: StopDriver(); sl@0: test.End(); sl@0: return 0; sl@0: } sl@0: sl@0: sl@0: /** Invoked by "t_cache data "*/ sl@0: void ManualDataTest(TInt aSize) sl@0: { sl@0: StartDriver(); sl@0: GetCacheInfo(); sl@0: sl@0: Test4(aSize); sl@0: sl@0: test.Printf(_L("Press any key...\n")); sl@0: test.Getch(); sl@0: StopDriver(); sl@0: test.End(); sl@0: } sl@0: sl@0: /** Invoked by "t_cache code "*/ sl@0: void ManualCodeTest(TInt aSize) sl@0: { sl@0: StartDriver(); sl@0: GetCacheInfo(); sl@0: sl@0: Test5(aSize); sl@0: sl@0: test.Printf(_L("Press any key...\n")); sl@0: test.Getch(); sl@0: StopDriver(); sl@0: test.End(); sl@0: } sl@0: sl@0: void DoUseCase(TInt aUseCase, TInt aMaxSize, TInt aLoops ) sl@0: { sl@0: RCacheTestDevice::TChunkTest dC(aUseCase, 0x1000, aLoops); sl@0: sl@0: TInt time[5]; sl@0: sl@0: test.Printf(_L("size(H)\tloops\tNormal/NC\tNormal/WT\tFullyCached\n")); sl@0: test.Printf(_L("-------\t-----\t---------\t---------\t-----------\n")); sl@0: sl@0: while (dC.iSize<=aMaxSize) sl@0: { sl@0: dC.iCacheAttr = RCacheTestDevice::E_Normal_Cached; sl@0: test(Device.TestUseCase(dC)==KErrNone); sl@0: time[2]=dC.iTime; sl@0: sl@0: if(time[2] < 20) sl@0: {dC.iLoops *=2; continue;} //Time too short. Double the loops and try the same chunk size. sl@0: sl@0: dC.iCacheAttr = RCacheTestDevice::E_Normal_Uncached; sl@0: test(Device.TestUseCase(dC)==KErrNone); sl@0: time[0]=dC.iTime; sl@0: sl@0: if(CacheInfo.iMemoryRemapping) dC.iCacheAttr = RCacheTestDevice::E_InOutWT_Remapped; sl@0: else dC.iCacheAttr = RCacheTestDevice::E_InOutWT; sl@0: test(Device.TestUseCase(dC)==KErrNone); sl@0: time[1]=dC.iTime; sl@0: sl@0: sl@0: test.Printf(_L("%6xH\t%5d\t%9d\t%9d\t%11d\n"),dC.iSize,dC.iLoops,time[0],time[1],time[2]); sl@0: sl@0: if ((time[2] > 100) && (dC.iLoops >= 8)) sl@0: dC.iLoops /=2; //Time too long. Half the loops. sl@0: sl@0: dC.iSize+=0x1000; // Next chunk size. sl@0: } sl@0: } sl@0: sl@0: /** Invoked by "t_cache usecase"*/ sl@0: void ManualUseCase() sl@0: { sl@0: test.Start(_L("Use Case manual tests")); sl@0: StartDriver(); sl@0: GetCacheInfo(); sl@0: sl@0: test.Printf(_L("\nUseCase: Read From Chunk\n")); sl@0: DoUseCase(0,Min(CacheInfo.iMaxCacheSize*4, 0x40000),32); sl@0: sl@0: test.Printf(_L("\nUseCase: Read From Chunk & Read From Heap\n")); sl@0: DoUseCase(1,Min(CacheInfo.iMaxCacheSize*4, 0x40000),32); sl@0: sl@0: test.Printf(_L("\nUseCase: Write To Chunk\n")); sl@0: DoUseCase(2,Min(CacheInfo.iMaxCacheSize*4, 0x40000),32); sl@0: sl@0: test.Printf(_L("\nUseCase: Write To Chunk & Read From Heap\n")); sl@0: DoUseCase(3,Min(CacheInfo.iMaxCacheSize*4, 0x40000),32); sl@0: sl@0: sl@0: test.Printf(_L("Press any key...\n")); sl@0: test.Getch(); sl@0: StopDriver(); sl@0: test.End(); sl@0: } sl@0: sl@0: sl@0: // Invoked by "t_cache data+" sl@0: void ManualDataTestIncremental(TInt aIncrement) sl@0: { sl@0: TInt time[4]; sl@0: TInt r = KErrNone; sl@0: TInt size = aIncrement; sl@0: RCacheTestDevice::TChunkTest dC; sl@0: sl@0: StartDriver(); sl@0: GetCacheInfo(); sl@0: sl@0: test.Printf(_L("Chunk\t\tTime(KernelTicks):\n")); sl@0: test.Printf(_L("Size(KB)\tUnCached\tInner\tOuter\tIn&Out\n")); sl@0: sl@0: while(size < KMaxChunkSize) sl@0: { sl@0: dC.iSize = size; sl@0: sl@0: dC.iCacheAttr = RCacheTestDevice::E_Buffered_C; sl@0: r = Device.TestDataChunk(dC); sl@0: if (r!=KErrNone) break; sl@0: time[0] = dC.iTime; sl@0: sl@0: if(CacheInfo.iMemoryRemapping) dC.iCacheAttr = RCacheTestDevice::E_InnerWB_Remapped; sl@0: else dC.iCacheAttr = RCacheTestDevice::E_InnerWB; sl@0: r = Device.TestDataChunk(dC); sl@0: if (r!=KErrNone) break; sl@0: time[1] = dC.iTime; sl@0: sl@0: if(CacheInfo.iOuterCache) sl@0: { sl@0: if(CacheInfo.iMemoryRemapping) dC.iCacheAttr = RCacheTestDevice::E_OuterWB_Remapped; sl@0: else dC.iCacheAttr = RCacheTestDevice::E_OuterWB; sl@0: r = Device.TestDataChunk(dC); sl@0: if (r!=KErrNone) break; sl@0: time[2] = dC.iTime; sl@0: sl@0: dC.iCacheAttr = RCacheTestDevice::E_InOutWB; sl@0: r = Device.TestDataChunk(dC); sl@0: if (r!=KErrNone) break; sl@0: time[3] = dC.iTime; sl@0: } sl@0: else sl@0: { sl@0: time[2]= time[3]=0; sl@0: } sl@0: test.Printf(_L("%d\t%d\t%d\t%d\t%d\n"),size/0x400, time[0],time[1],time[2],time[3]); sl@0: size += aIncrement; sl@0: } sl@0: sl@0: test.Printf(_L("The test exited with %d\n"), r); sl@0: test.Printf(_L("Press any key...\n")); sl@0: test.Getch(); sl@0: StopDriver(); sl@0: test.End(); sl@0: } sl@0: sl@0: // Invoked by "t_cache code+" sl@0: void ManualCodeTestIncremental(TInt aIncrement) sl@0: { sl@0: TInt time[4]; sl@0: TInt r = KErrNone; sl@0: TInt size = aIncrement; sl@0: RCacheTestDevice::TChunkTest dC; sl@0: sl@0: StartDriver(); sl@0: GetCacheInfo(); sl@0: sl@0: test.Printf(_L("Chunk\t\tTime(KernelTicks):\n")); sl@0: test.Printf(_L("Size(KB)\tUnCached\tInner\tOuter\tIn&Out\n")); sl@0: sl@0: while(size < KMaxChunkSize) sl@0: { sl@0: TempBuff.SetLength(0); sl@0: sl@0: dC.iSize = size; sl@0: sl@0: dC.iCacheAttr = RCacheTestDevice::E_Buffered_C; sl@0: r = Device.TestCodeChunk(dC); sl@0: if (r!=KErrNone) break; sl@0: time[0] = dC.iTime; sl@0: sl@0: if(CacheInfo.iMemoryRemapping) dC.iCacheAttr = RCacheTestDevice::E_InnerWB_Remapped; sl@0: else dC.iCacheAttr = RCacheTestDevice::E_InnerWB; sl@0: r = Device.TestCodeChunk(dC); sl@0: if (r!=KErrNone) break; sl@0: time[1] = dC.iTime; sl@0: sl@0: if(CacheInfo.iOuterCache) sl@0: { sl@0: if(CacheInfo.iMemoryRemapping) dC.iCacheAttr = RCacheTestDevice::E_OuterWB_Remapped; sl@0: else dC.iCacheAttr = RCacheTestDevice::E_OuterWB; sl@0: r = Device.TestCodeChunk(dC); sl@0: if (r!=KErrNone) break; sl@0: time[2] = dC.iTime; sl@0: // sl@0: dC.iCacheAttr = RCacheTestDevice::E_InOutWB; sl@0: r = Device.TestCodeChunk(dC); sl@0: if (r!=KErrNone) break; sl@0: time[3] = dC.iTime; sl@0: } sl@0: else sl@0: { sl@0: time[2]=time[3] = 0; sl@0: } sl@0: sl@0: test.Printf(_L("%d\t%d\t%d\t%d\t%d\n"),size/0x400, time[0],time[1],time[2],time[3]); sl@0: size += aIncrement; sl@0: } sl@0: sl@0: test.Printf(_L("The test exited with %d\n"), r); sl@0: test.Printf(_L("Press any key...\n")); sl@0: test.Getch(); sl@0: StopDriver(); sl@0: test.End(); sl@0: } sl@0: sl@0: TInt E32Main() sl@0: { sl@0: sl@0: TBuf<64> c; sl@0: TInt size; sl@0: User::CommandLine(c); sl@0: if (c.FindF(KPrintCacheInfos) >= 0) {ManualCacheInfo(); return 0;} sl@0: if (c.FindF(KUseCase) >= 0) {ManualUseCase(); return 0;} sl@0: if (c.FindF(KThreshold) >= 0) {ManualThresholds(c); return 0;} sl@0: sl@0: if (c.FindF(KTestData) >= 0) sl@0: { sl@0: test.Start(_L("Data Chunk")); sl@0: size = GetSizeFromCommandLine(c); sl@0: // Always round up the size to 1K boundary (because of DataSegmetTestFunct) sl@0: size +=0x3ff; size &=~0x3ff; sl@0: sl@0: if (c.FindF(KIncremental) >= 0) sl@0: { sl@0: // Invoked by "t_cache data+" sl@0: test.Printf(_L(" size + %xH\n"),size); sl@0: if (size<=0) sl@0: return KErrArgument; sl@0: ManualDataTestIncremental(size); sl@0: } sl@0: else sl@0: { sl@0: // Invoked by "t_cache data " sl@0: test.Printf(_L("chunk size %xH\n"),size); sl@0: if (size<=0) sl@0: return KErrArgument; sl@0: ManualDataTest(size); sl@0: } sl@0: return 0; sl@0: } sl@0: sl@0: if (c.FindF(KTestCode) >= 0) sl@0: { sl@0: test.Start(_L("Code Chunk")); sl@0: size = GetSizeFromCommandLine(c); sl@0: // Always round up the size to 1K boundary sl@0: size +=0x3ff; size &=~0x3ff; sl@0: if (c.FindF(KIncremental) >= 0) sl@0: { sl@0: // Invoked by "t_cache code+" sl@0: test.Printf(_L(" size + %xH\n"),size); sl@0: if (size<=0) sl@0: return KErrArgument; sl@0: ManualCodeTestIncremental(size); sl@0: } sl@0: else sl@0: { sl@0: // Invoked by "t_cache code " sl@0: test.Printf(_L("chunk size %xH\n"),size); sl@0: if (size<=0) sl@0: return KErrArgument; sl@0: ManualCodeTest(size); sl@0: } sl@0: return 0; sl@0: } sl@0: sl@0: if (c.FindF(KHelp) >= 0) sl@0: { sl@0: // Invoked by "t_cache help" sl@0: test.Start(_L("t_cache usage:\n")); sl@0: test.Printf(_L("t_cache info\n")); sl@0: test.Printf(_L("t_cache data \n")); sl@0: test.Printf(_L("t_cache code \n")); sl@0: test.Printf(_L("t_cache data+\n")); sl@0: test.Printf(_L("t_cache code+\n")); sl@0: test.Printf(_L("t_cache usecase\n\n")); sl@0: test.Printf(_L("t_cache threshold [ ]\n\n")); sl@0: test.Printf(_L("... where = 1,2,4,8 or 10\n\n")); sl@0: test.Printf(_L("Press any key...\n")); sl@0: test.Getch(); sl@0: test.End(); sl@0: return 0; sl@0: } sl@0: sl@0: sl@0: // auto test starts here sl@0: CTrapCleanup* trap = CTrapCleanup::New(); sl@0: if (!trap) sl@0: return KErrNoMemory; sl@0: test.Title(); sl@0: __UHEAP_MARK; sl@0: TRAPD(r,AutoTestL()); sl@0: __UHEAP_MARKEND; sl@0: delete trap; sl@0: return r; sl@0: }