# HG changeset patch # User Dremov Kirill (Nokia-D-MSW/Tampere) # Date 1286974105 -10800 # Node ID 7151b503b58de4dbc45d50459dfecd7bf7893a1d # Parent a4ff6126ec76acc5696cee75d0c1ee4d273ccd6b Revision: 201041 Kit: 201041 diff -r a4ff6126ec76 -r 7151b503b58d emulator/emulatorbsp/inc/variantmediadef.h --- a/emulator/emulatorbsp/inc/variantmediadef.h Wed Sep 15 13:26:16 2010 +0300 +++ b/emulator/emulatorbsp/inc/variantmediadef.h Wed Oct 13 15:48:25 2010 +0300 @@ -57,17 +57,4 @@ #define NAND_NUMMEDIA 1 #define NAND_DRIVENAME "Nand" -// Variant parameters for test NFE media extension driver -#define NFE_DRIVECOUNT 2 -#define NFE_DRIVELIST 1,5 -#define NFE_DRIVELETTERLIST 23,20 // EDRive? IDs of the each instance. (EDriveX,EDriveU from estart.txt) - -#define NFE_INSTANCE_COUNT 2 // the number of NFE media driver instances -#define NFE_INSTANCE_DRIVE_COUNTS 1,1 // the number of drives in NFE_DRIVELIST for each instance of the driver - -// Variant parameters for production NFE media extension driver (same as NFE_DRIVELETTERLIST) -#define NFE_INSTANCE_UI_DRIVE_ID 23,20 // EDRive? IDs of the each instance. (EDriveX,EDriveU from estart.txt) - - - #endif diff -r a4ff6126ec76 -r 7151b503b58d emulator/emulatorbsp/specific/mmc.cpp --- a/emulator/emulatorbsp/specific/mmc.cpp Wed Sep 15 13:26:16 2010 +0300 +++ b/emulator/emulatorbsp/specific/mmc.cpp Wed Oct 13 15:48:25 2010 +0300 @@ -307,27 +307,11 @@ FILE_FLAG_RANDOM_ACCESS, // DWORD dwFlagsAndAttributes NULL); // HANDLE hTemplateFile - TInt fileSize = 0; - if (*aHandle!=INVALID_HANDLE_VALUE) - { - fileSize = GetFileSize(*aHandle,NULL); - // Check whether MMC card force mount property is set. - // Force mount MMC card image regardless of whether the size of the image file is - // as specified in the epoc.ini. - // Specify "MMCCardForceMount 1" in the epoc.ini to enable force mount. - TBool forceMount = Property::GetBool("MMCCardForceMount"); - if (forceMount && fileSize != INVALID_FILE_SIZE) - { - TInt sizeInKB = fileSize >> 10; - SetupDiskParms(sizeInKB); - TotalMDiskSize = fileSize; - } - } - - if (fileSize!=TotalMDiskSize) + TInt fileSize=GetFileSize(*aHandle,NULL); + if (fileSize>TotalMDiskSize) // // The Drive file already exists and size of emulated drive as configured in - // epoc.ini has been changed. Musn't corrupt the emulated drive so delete the + // epoc.ini has been reduced. Musn't corrupt the emulated drive so delete the // drive file and start from scratch. The emulated drive contents will be // erased. // @@ -395,21 +379,6 @@ delete cip; return(err); } - - TBool forceMount = Property::GetBool("MMCCardForceMount"); - if (forceMount) - { - // if Force Mount as image file size, CSIZE and CSIZE_MULT will be set - // again inside the CreateBinFileForCard() call above. - cip->iForceMount = ETrue; - cip->iForceMountCSIZE = CSIZE; - cip->iForceMountCSIZE_MULT = CSIZE_MULT; - } - else - { - cip->iForceMountCSIZE = EFalse; - } - cip->iWinHandle=h; iCardPool[aCardNum]=cip; return(KErrNone); @@ -1345,20 +1314,6 @@ void TWinsCardInfo::GetCSD(TUint8* aResp) const { - TUint size; - TUint sizeMult; - - if (iForceMount) - { - size = iForceMountCSIZE; - sizeMult = iForceMountCSIZE_MULT; - } - else - { - size = DWinsMMCStack::CSIZE; - sizeMult = DWinsMMCStack::CSIZE_MULT; - } - // Bits 127-96 TUint32 csd=(KCsdStructure<<30); /* CSD_STRUCTURE */ csd|= (KCsdSpecVers<<26); /* SPEC_VERS */ @@ -1386,16 +1341,16 @@ csd|= (0x0<<14); /* WRITE_BLK_MISALIGN: No */ csd|= (0x0<<13); /* READ_BLK_MISALIGN: No */ csd|= (0x0<<12); /* DSR_IMP: No DSR */ - csd|= ((size>>10&3)<<8); /* C_SIZE: MMCSz Kb */ - csd|= ((size>>2) & 0xFF); /* C_SIZE: MMCSz Kb */ + csd|= ((DWinsMMCStack::CSIZE>>10&3)<<8); /* C_SIZE: MMCSz Kb */ + csd|= ((DWinsMMCStack::CSIZE>>2) & 0xFF); /* C_SIZE: MMCSz Kb */ TMMC::BigEndian4Bytes(&aResp[4],csd); // Bits 63-32 - csd= ((size&3)<<30); /* C_SIZE: MMCSz Kb */ + csd= ((DWinsMMCStack::CSIZE&3)<<30); /* C_SIZE: MMCSz Kb */ csd|= (0x1<<27); /* VDD_R_CURR_MIN: 1mA */ csd|= (0x1<<24); /* VDD_R_CURR_MAX: 5mA */ csd|= (0x2<<21); /* VDD_W_CURR_MIN: 5mA */ csd|= (0x3<<18); /* VDD_W_CURR_MAX: 25mA */ - csd|= ((sizeMult&0x07)<<15); /* C_SIZE_MULT: 0 */ + csd|= ((DWinsMMCStack::CSIZE_MULT&0x07)<<15); /* C_SIZE_MULT: 0 */ csd|= (0x0<<10); /* SECTOR_SIZE: 1 write block */ csd|= (0x0<<5); /* ERASE_GRP_SIZE: 1 secotr */ csd|= (0x0); /* WP_GRP_SIZE: 1 erase group */ diff -r a4ff6126ec76 -r 7151b503b58d emulator/emulatorbsp/specific/mmci.h --- a/emulator/emulatorbsp/specific/mmci.h Wed Sep 15 13:26:16 2010 +0300 +++ b/emulator/emulatorbsp/specific/mmci.h Wed Oct 13 15:48:25 2010 +0300 @@ -52,10 +52,6 @@ TMMCardStateEnum iState; // Simulation of card's current state HANDLE iWinHandle; TRCA iRCA; - - TBool iForceMount; - TUint iForceMountCSIZE; // mmc card size field - TUint iForceMountCSIZE_MULT; // mmc card size field }; class DWinsMMCStack : public DMMCStack diff -r a4ff6126ec76 -r 7151b503b58d emulator/emulatorbsp/specific/property.cpp --- a/emulator/emulatorbsp/specific/property.cpp Wed Sep 15 13:26:16 2010 +0300 +++ b/emulator/emulatorbsp/specific/property.cpp Wed Oct 13 15:48:25 2010 +0300 @@ -435,16 +435,6 @@ } - // Get the name of the extension media drivers from epoc.ini (optional) - value = NULL; - iProperties.GetString("MediaExtensionDriver", value); - if (value) - { - if (iProperties.Append("Extension", value) == NULL) - return KErrNoMemory; - } - - // load additional configuration specific properties // get the multi property "configuration" diff -r a4ff6126ec76 -r 7151b503b58d emulator/emulatorbsp/test/bld.inf --- a/emulator/emulatorbsp/test/bld.inf Wed Sep 15 13:26:16 2010 +0300 +++ b/emulator/emulatorbsp/test/bld.inf Wed Oct 13 15:48:25 2010 +0300 @@ -20,7 +20,6 @@ PRJ_EXPORTS PRJ_MMPFILES -mediaext/d_nfe.mmp PRJ_TESTMMPFILES diff -r a4ff6126ec76 -r 7151b503b58d emulator/emulatorbsp/test/mediaext/d_nfe.mmp --- a/emulator/emulatorbsp/test/mediaext/d_nfe.mmp Wed Sep 15 13:26:16 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). -// All rights reserved. -// This component and the accompanying materials are made available -// under the terms of the License "Eclipse Public License v1.0" -// which accompanies this distribution, and is available -// at the URL "http://www.eclipse.org/legal/epl-v10.html". -// -// Initial Contributors: -// Nokia Corporation - initial contribution. -// -// Contributors: -// -// Description: -// e32test\group\d_nfe.mmp -// -// - -/** -@file - -@SYMPurpose medtestnfe.pdd NFE test Media Driver -*/ - -#include "../variant.mmh" - -target VariantTarget(medtestnfe,pdd) - -targettype pdd - -#include "kernel/kern_ext.mmh" -#include "drivers/elocd.mmh" - -//macro COMPOSITE_DRIVES - -OS_LAYER_SYSTEMINCLUDE_SYMBIAN - -// point to variantmediadef.h -SYMBIAN_BASE_SYSTEMINCLUDE(wins) - -sourcepath ../../../../../kernelhwsrv/kerneltest/e32test/mediaext -source d_nfe.cpp -library elocd.lib - -start wins -win32_headers -end - -epocallowdlldata - -uid 0x100039d0 0xA000E7C5 -VENDORID 0x70000001 -capability all - - - -SMPSAFE diff -r a4ff6126ec76 -r 7151b503b58d naviengine/navienginebsp/ne1_tb/test/pci/d_pci.cpp --- a/naviengine/navienginebsp/ne1_tb/test/pci/d_pci.cpp Wed Sep 15 13:26:16 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,882 +0,0 @@ -/* -* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This material, including documentation and any related computer -* programs, is protected by copyright controlled by Nokia. All -* rights are reserved. Copying, including reproducing, storing -* adapting or translating, any or all of this material requires the -* prior written consent of Nokia. This material also contains -* confidential information which may not be disclosed to others -* without the prior written consent of Nokia. -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: Device-driver for naviEngine PCI testing -* -*/ - -#include -#include -#include -#include -#include -#include "allocator.h" -#include "pci-ne.h" -#include "pci_priv.h" -#include -#include "t_pci.h" -#include "../../naviengine_assp/naviengine_pci.h" - -#define TEST(X) __NK_ASSERT_ALWAYS(X) -#define TEST_KERRNONE(X) if((X) !=KErrNone) {\ - Kern::Printf("Assertion Failed X=%d", (X)); FAULT();} - -#define FUNC_LOG() __KTRACE_OPT(KPCI, Kern::Printf(__PRETTY_FUNCTION__)) - - -void TestAllocator(); - -/** -So that the test app can get notification -when PCI DChunks' cleanup operation has run -we will replace their cleanup object with this -one, which will call the original object's destroy -function as well completing a notification -*/ -class TPciCleanupWrapper : public TChunkCleanup - { -public: - - ~TPciCleanupWrapper() - { - delete iOriginal; - Kern::DestroyClientRequest(iClientRequest); - iClient->Close(NULL); - } - - static TPciCleanupWrapper* Create(TRequestStatus* aRequestStatus) - { - __KTRACE_OPT(KPCI, Kern::Printf("TPciCleanupWrapper::Create aRequestStatus=0x%08x", aRequestStatus)); - TClientRequest* request = NULL; - TInt r = Kern::CreateClientRequest(request); - if(r != KErrNone) - { - __KTRACE_OPT(KPCI, Kern::Printf("TPciCleanupWrapper::Create Failed to create client request r=%d", r)); - return NULL; - } - - r = request->SetStatus(aRequestStatus); - if(r != KErrNone) - { - __KTRACE_OPT(KPCI, Kern::Printf("TPciCleanupWrapper::Create Failed to set status r=%d", r)); - Kern::DestroyClientRequest(request); - return NULL; - } - - return new TPciCleanupWrapper(request); - } - - /** - Insert the cleanup object into aChunk, remembering - the original one - - @param aChunk a chunk known to have TChunkCleanup derived cleanup object - */ - void Insert(DChunk* aChunk) - { - __KTRACE_OPT(KPCI, Kern::Printf("TPciCleanupWrapper::Insert aChunk=0x%08x", aChunk)); - __NK_ASSERT_DEBUG(aChunk); - __KTRACE_OPT(KPCI, Kern::Printf("TPciCleanupWrapper replace 0x%08x with 0x%08x", aChunk->iDestroyedDfc, this)); - iOriginal = static_cast(aChunk->iDestroyedDfc); - - __NK_ASSERT_DEBUG(iOriginal); - aChunk->iDestroyedDfc = this; - } - - /** - Run the original object's destroy method - then notify client - */ - void Destroy() - { - __KTRACE_OPT(KPCI, Kern::Printf("TPciCleanupWrapper::Destroy\n")); - iOriginal->Destroy(); - - __NK_ASSERT_ALWAYS(iClientRequest->IsReady()); - Kern::QueueRequestComplete(iClient, iClientRequest, KErrNone); - } - -private: - TPciCleanupWrapper(TClientRequest* aRequest) - :TChunkCleanup(), iOriginal(NULL), iClientRequest(aRequest), iClient(&Kern::CurrentThread()) - { - __ASSERT_CRITICAL; - iClient->Open(); //don't allow thread object to be destroyed before we signal - } - - - TChunkCleanup* iOriginal; - TClientRequest* iClientRequest; - DThread* const iClient; - }; - - - - -//This information will come from the pci driver -//if this code is ever made generic -TPciTestInfo KTestInfo = - { - TPciDevice(0x1033, 0x35, 0), - TPciTestInfo::TAddrSpaceTest(0, 0x00351033, 0), - TPciTestInfo::TAddrSpaceTest(KPciBar0, 0, 0xFFF), - 0, - TPciTestInfo::TAddrSpaceTest(0x34, 0x2EDF, 0), - TPciTestInfo::TAddrSpaceTest(0x20, 0, 0xF), - KNeBridgeNumberOfBars - }; - -/** -Class for a DChunk to remove a DPlatHwChunk chunk -*/ -class TPciPlatChunkCleanup : public TChunkCleanup - { -public: - TPciPlatChunkCleanup(TInt aPciFunction, DPlatChunkHw* aPciPlatChunk); - virtual void Destroy(); -public: - TInt iPciFunction; - DPlatChunkHw* iPciChunk; - }; - -TPciPlatChunkCleanup::TPciPlatChunkCleanup(TInt aPciFunction, DPlatChunkHw* aPciPlatChunk) - : TChunkCleanup(), iPciFunction(aPciFunction), iPciChunk(aPciPlatChunk) - { - } - -void TPciPlatChunkCleanup::Destroy() - { - __KTRACE_OPT(KPCI, Kern::Printf("SHAREDCHUNK ChunkDestroyed DFC\n")); - TInt r = Pci::RemoveChunk(iPciFunction, iPciChunk); - __NK_ASSERT_ALWAYS(r==KErrNone); - } - -/** -Cleanup class to remove the mapping for an externally -mapped chunk -*/ -class TPciMappedChunkCleanup : public TChunkCleanup - { -public: - TPciMappedChunkCleanup (TInt aPciFunction,TUint32 aPhysicalAddress); - virtual void Destroy(); -public: - TInt iPciFunction; - TUint32 iPhysicalAddress; - }; - -TPciMappedChunkCleanup::TPciMappedChunkCleanup(TInt aPciFunction,TUint32 aPhysicalAddress) - : TChunkCleanup(), iPciFunction(aPciFunction),iPhysicalAddress(aPhysicalAddress) - { - } - -void TPciMappedChunkCleanup::Destroy() - { - //remove mapping - TInt r = Pci::RemoveMapping(iPciFunction, iPhysicalAddress); - __NK_ASSERT_ALWAYS(r==KErrNone); - __KTRACE_OPT(KPCI, Kern::Printf("MAPPING REMOVED ChunkDestroyed DFC\n")); - } - -class DPciTestChannel : public DLogicalChannelBase - { -public: - DPciTestChannel(); - virtual ~DPciTestChannel(); - TInt DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); - virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2); - -private: - TInt OpenPciDChunk(TUint32& aPciAddr,TInt aPciChunkSize, TRequestStatus* aStatus); - TInt OpenPciPlatHwChunk(TUint32& aPciAddr,TInt aPciChunkSize, TRequestStatus* aStatus); - TInt OpenPciMappedChunk(TUint32& aPciAddr,TInt aPciChunkSize, TRequestStatus* aStatus); - TInt CreateSharedChunk(TInt aPciChunkSize, TUint32 aAttributes, DChunk*& aChunk, TLinAddr& aVirt, TPhysAddr& aPhysicalAddress); - TInt OpenPciWindowChunk(); - void RunUnitTests(); - -private: - const TPciTestInfo& iTestInfo; - TInt iFunction; ///< PCI function number this channel is associated with - }; - -DPciTestChannel::DPciTestChannel() - : iTestInfo(KTestInfo), iFunction(-1) - { - FUNC_LOG(); - } - -DPciTestChannel::~DPciTestChannel() - { - FUNC_LOG(); - } - -TInt DPciTestChannel::DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer) - { - if(aInfo == NULL) - return KErrNone; //Not a device specific channel - - TPciDevice dev; - TPckg devPckg(dev); - TInt r = Kern::ThreadDesRead(&Kern::CurrentThread(), aInfo, devPckg, 0, KChunkShiftBy0); - if(r != KErrNone) - return r; - - NKern::ThreadEnterCS(); - RArray indicies; - r = Pci::Probe(indicies, dev.iVendorId, dev.iDeviceId); - - if((KErrNone == r) && (dev.iInstance < indicies.Count())) - { - iFunction = indicies[dev.iInstance]; - } - else - { - r = KErrNotFound; - } - - indicies.Close(); - NKern::ThreadLeaveCS(); - return r; - } - -TInt DPciTestChannel::Request(TInt aFunction, TAny* a1, TAny* a2) - { - switch (aFunction) - { - case EGetTestInfo: - { - TDes8& dest(*(TDes8*)a1); - TPckgC info(iTestInfo); - Kern::KUDesPut(dest, info); - return KErrNone; - } - case EAccessConfigSpace: - { - TPckgBuf pckg; - Kern::KUDesGet(pckg, *reinterpret_cast(a1)); - - TAddrSpace* configSpace = Pci::GetConfigSpace(iFunction); - if(configSpace == NULL) - { - Kern::PanicCurrentThread(KPciTest, KErrGeneral); - return KErrGeneral; - } - return pckg().KRun(*configSpace); - } - case EAccessMemorySpace: - { - TPckgBuf pckg; - Kern::KUDesGet(pckg, *reinterpret_cast(a1)); - - TAddrSpace* memSpace = Pci::GetMemorySpace(iFunction, pckg().BarIndex()); - if(memSpace == NULL) - { - Kern::PanicCurrentThread(KPciTest, KErrGeneral); - return KErrGeneral; - } - return pckg().KRun(*memSpace); - } - case EOpenPciWindowChunk: - { - TInt rHandle = 0; - rHandle = OpenPciWindowChunk(); - return rHandle; - } - case EOpenPciDChunk: //Fall-through - case EOpenPciPlatHwChunk: - case EOpenPciMappedChunk: - { - TPckgBuf pckg; - Kern::KUDesGet(pckg, *reinterpret_cast(a1)); - - TUint32 pciAddr; - TInt rHandle = 0; - switch (aFunction) - { - case EOpenPciDChunk: - { - rHandle = OpenPciDChunk(pciAddr, pckg().iSize, pckg().iStatus); - break; - } - case EOpenPciPlatHwChunk: - { - rHandle = OpenPciPlatHwChunk(pciAddr, pckg().iSize, pckg().iStatus); - break; - } - case EOpenPciMappedChunk: - { - rHandle = OpenPciMappedChunk(pciAddr, pckg().iSize, pckg().iStatus); - break; - } - default: - { - FAULT(); - } - } - //write back PCI address to user - umemput(pckg().iPciAddress,&pciAddr,sizeof(pciAddr)); - return rHandle; - } - case ERunUnitTests: - { - RunUnitTests(); - return KErrNone; - } - default: - return KErrNotSupported; - } - } - -/** -This function runs tests for the address allocator -*/ -void DPciTestChannel::RunUnitTests() -{ - // Enter critical section - NKern::ThreadEnterCS(); - - TestAllocator(); - - // Finished - NKern::ThreadLeaveCS(); -} - - -/** -This function creates and opens a PCI DChunk and returns the PCI addresss -@param aPciAddr on return contains the pci address -@param aPciChunkSize contains the size of the PCI DChunk which is to be created -*/ -TInt DPciTestChannel::OpenPciDChunk(TUint32& aPciAddr,TInt aPciChunkSize, TRequestStatus* aStatus) -{ - //Chunk Attributes - TChunkCreateInfo aInfo; - aInfo.iType = TChunkCreateInfo::ESharedKernelMultiple; - aInfo.iMapAttr = EMapAttrSupRw|EMapAttrFullyBlocking; - aInfo.iOwnsMemory = EFalse; // We'll be using our own devices memory - - DChunk* pciChunk; - pciChunk=NULL; - - // Enter critical section - NKern::ThreadEnterCS(); - - //Create DChunk - TInt r = Pci::CreateChunk(iFunction, pciChunk, aInfo,0,aPciChunkSize,aPciAddr); - if(r!=KErrNone) - { - // Failed to create DChunk - __KTRACE_OPT(KPCI,Kern::Printf("Failed to create DChunk: Error code is=%d", r) ); - NKern::ThreadLeaveCS(); // Finished - return r; - } - else - { - TInt rHandle = KErrGeneral; - if(aStatus) - { - TPciCleanupWrapper* wrapper = TPciCleanupWrapper::Create(aStatus); - if(wrapper == NULL) - { - __KTRACE_OPT(KPCI,Kern::Printf("Creation of TPciCleanupWrapper failed")); - goto End; - } - wrapper->Insert(pciChunk); - } - - __KTRACE_OPT(KPCI,Kern::Printf("Created DChunk: PCI_ADDRESS=0x%08x",aPciAddr)); - rHandle = Kern::MakeHandleAndOpen(NULL, pciChunk);//Get DChunk handle - -End: - pciChunk->Close(NULL); // Close DChunk - NKern::ThreadLeaveCS(); // Finished - return rHandle; - } -} - -/** -This function creates and opens a PCI DPlatChunk and returns the PCI addresss. -A DPlatChunk is intially created and then a DChunk is set to point to the same -memory as the DPlatChunk.This is done so that it can be accessed on the user side. -@param aPciAddr on return contains the pci address -@param aPciChunkSize contains the size of the PCI PlatHwChunk which is to be created -*/ -TInt DPciTestChannel::OpenPciPlatHwChunk(TUint32& aPciAddr,TInt aPciChunkSize, TRequestStatus* aStatus) -{ - TUint32 pciPhysicalAddr; - TUint32 pciChunkMapAttr; - TLinAddr pciChunkKernelAddr; - - DPlatChunkHw* pciPlatChunk; - pciPlatChunk=NULL; - - // Enter critical section - NKern::ThreadEnterCS(); - - //Create DPlatChunkHw - TInt r = Pci::CreateChunk(iFunction,pciPlatChunk,aPciChunkSize,(EMapAttrSupRw|EMapAttrFullyBlocking),aPciAddr); - if(r!=KErrNone) - { - // Failed to create DPlatChunkHw - __KTRACE_OPT(KPCI,Kern::Printf("Failed to create DPlatChunkHw chunk: Error code is=%d", r)); - NKern::ThreadLeaveCS(); // Finished - return r; - } - - //Get physical addresss - pciPhysicalAddr = pciPlatChunk->PhysicalAddress(); - - // Create DChunk cleanup object - TPciPlatChunkCleanup* cleanup = new TPciPlatChunkCleanup(iFunction, pciPlatChunk); - if(!cleanup) - { - pciPlatChunk->Close(NULL); //close pciPlatChunk - NKern::ThreadLeaveCS(); - return KErrNoMemory; - } - - //Chunk Attributes for DChunk - TChunkCreateInfo chunkinfo; - chunkinfo.iType = TChunkCreateInfo::ESharedKernelMultiple; - chunkinfo.iMaxSize = 0x4000; - chunkinfo.iMapAttr = EMapAttrSupRw|EMapAttrFullyBlocking; // No caching - chunkinfo.iOwnsMemory = EFalse; // Use memory from system's free pool - chunkinfo.iDestroyedDfc = cleanup; - - DChunk* pciDChunk; - - //Create DChunk - r = Kern::ChunkCreate(chunkinfo, pciDChunk, pciChunkKernelAddr, pciChunkMapAttr); - if(r!=KErrNone) - { - pciPlatChunk->Close(NULL); //close pciPlatChunk - delete cleanup; - NKern::ThreadLeaveCS(); - return r; - } - - pciPlatChunk=NULL; // pciDChunk now owns chunk - - if(aStatus) - { - TPciCleanupWrapper* wrapper = TPciCleanupWrapper::Create(aStatus); - if(wrapper == NULL) - { - pciDChunk->Close(NULL); // Close pciDChunk - NKern::ThreadLeaveCS(); // Finished - return KErrGeneral; - } - wrapper->Insert(pciDChunk); - } - - //Commit memory to a DChunk using DPlatChunkHw physical address - r = Kern::ChunkCommitPhysical(pciDChunk,0,aPciChunkSize,pciPhysicalAddr); - if(r!=KErrNone) - { - // Failed to commit memory - Kern::Printf("Commit failed: Error code is=%d", r); - __KTRACE_OPT(KPCI,Kern::Printf("Commit failed: Error code is=%d", r)); - - // Close chunk, which will then get deleted at some point - Kern::ChunkClose(pciDChunk); - NKern::ThreadLeaveCS(); - return r; - } - - //Close pciPlatChunk using pciDChunk as pciDChunk now owns it - const TInt rHandle = Kern::MakeHandleAndOpen(NULL, pciDChunk); //Get DChunk handle - pciDChunk->Close(NULL); // Close pciDChunk - NKern::ThreadLeaveCS(); // Finished - return rHandle; -} - -/** -This function creates and opens a PCI mapped DChunk and returns the PCI addresss -@param aPciAddr on return contains the pci address -@param aPciChunkSize contains the size of the PCI DChunk which is to be created -*/ -TInt DPciTestChannel::OpenPciMappedChunk(TUint32& aPciAddr,TInt aPciChunkSize, TRequestStatus* aStatus) -{ - TLinAddr virt=NULL; - TPhysAddr physicalAddress=NULL; - DChunk* pciChunk=NULL; - TUint32 pciAttributes=EMapAttrSupRw|EMapAttrFullyBlocking; - - // Enter critical section - NKern::ThreadEnterCS(); - - //create DChunk - TInt r = CreateSharedChunk(aPciChunkSize, pciAttributes, pciChunk, virt, physicalAddress); - if(r!=KErrNone) - { - __KTRACE_OPT(KPCI,Kern::Printf("Create shared Chunk failed: Error code is=%d", r)); - return r; - } - - __NK_ASSERT_ALWAYS(pciChunk); - - //create mapping - r=Pci::CreateMapping(iFunction, physicalAddress, aPciChunkSize, aPciAddr); - if(r!=KErrNone) - { - pciChunk->Close(NULL); - __KTRACE_OPT(KPCI,Kern::Printf("Create mapping failed: Error code is=%d", r)); - return r; - } - - - // Create DChunk cleanup object - TPciMappedChunkCleanup* cleanup = new TPciMappedChunkCleanup(iFunction, physicalAddress); - if(!cleanup) - { - pciChunk->Close(NULL); - NKern::ThreadLeaveCS(); - return KErrNoMemory; - } - - //must add the cleanup dfc to the chunk after creation - //since the cleanup parameters aren't known - //till after creating it and allocating memory to it - pciChunk->iDestroyedDfc = cleanup; - - if(aStatus) - { - TPciCleanupWrapper* wrapper = TPciCleanupWrapper::Create(aStatus); - if(wrapper == NULL) - { - pciChunk->Close(NULL); // Close pciDChunk - NKern::ThreadLeaveCS(); - return KErrGeneral; - } - wrapper->Insert(pciChunk); - } - - //Get DChunk handle - const TInt rHandle = Kern::MakeHandleAndOpen(NULL, pciChunk); - - // Close DChunk - pciChunk->Close(NULL); - - // Finished - NKern::ThreadLeaveCS(); - return rHandle; -} - -/** -This function creates and opens a PCI Window Chunk and returns the PCI Window addresss -@param aPciChunkSize contains the size of the PCI Window DChunk which is to be created -*/ -TInt DPciTestChannel::OpenPciWindowChunk() -{ - TUint32 pciChunkMapAttr; - TLinAddr pciChunkKernelAddr=NULL; - DChunk* pciWindowChunk=NULL; - - //Chunk Attributes for DChunk - TChunkCreateInfo chunkinfo; - chunkinfo.iType = TChunkCreateInfo::ESharedKernelMultiple; - chunkinfo.iMaxSize = 0x2000; - chunkinfo.iMapAttr = EMapAttrSupRw|EMapAttrFullyBlocking; // No caching - chunkinfo.iOwnsMemory = EFalse; // Use memory from system's free pool - - // Enter critical section - NKern::ThreadEnterCS(); - - //Create shared chunk for PCI window - TInt r = Kern::ChunkCreate(chunkinfo, pciWindowChunk, pciChunkKernelAddr, pciChunkMapAttr); - if(r!=KErrNone) - { - // Failed to create DChunk - __KTRACE_OPT(KPCI,Kern::Printf("Failed to create DChunk: Error code is=%d", r) ); - NKern::ThreadLeaveCS(); - return r; - } - - //This address is PSL specific. This will have to be changed - //if d_pci.cpp is ever made generic - TUint32 pciPhysicalAddr = KHwUSBHPhys; // Internal PCI window address - - //Commit memory to a DChunk using Internal PCI window address - r = Kern::ChunkCommitPhysical(pciWindowChunk,0,KHwUSBHInternalPciWindowSize, pciPhysicalAddr); - if(r!=KErrNone) - { - // Failed to commit memory - Kern::Printf("Commit failed: Error code is=%d", r); - __KTRACE_OPT(KPCI,Kern::Printf("Commit failed: Error code is=%d", r)); - - // Close chunk, which will then get deleted at some point - Kern::ChunkClose(pciWindowChunk); - NKern::ThreadLeaveCS(); - return r; - } - - //Close pciPlatChunk using pciDChunk as pciDChunk now owns it - const TInt rHandle = Kern::MakeHandleAndOpen(NULL, pciWindowChunk); //Get PCI Window DChunk handle - pciWindowChunk->Close(NULL); // Close pci window chunk - NKern::ThreadLeaveCS(); // Finished - return rHandle; -} - -/** -This function creates and opens a shared chunk. The chunk is then commited to a contiguous memory -@param aPciChunkSize contains the size of the PCI DChunk which is to be created -@param aAttributes on return, this is set to the mmu mapping attributes used for the chunk -@param aChunk on return, a reference to the shared chunk -@param aVirt on return, this is set to the virtual address shared chunk -@param aPhysicalAddress on return, this is set to the physical address of the first page of memory - which was committed. -*/ -TInt DPciTestChannel::CreateSharedChunk(TInt aPciChunkSize, TUint32 aAttributes, DChunk*& aChunk, TLinAddr& aVirt, TPhysAddr& aPhysicalAddress) -{ - __NK_ASSERT_DEBUG(aChunk==NULL); - aPciChunkSize = Kern::RoundToPageSize(aPciChunkSize); - DChunk* pC=NULL; - - // Enter critical section - NKern::ThreadEnterCS(); - - //Chunk Attributes for DChunk - TChunkCreateInfo info; - info.iType=TChunkCreateInfo::ESharedKernelSingle; - info.iMaxSize=aPciChunkSize; - info.iMapAttr=aAttributes; - info.iOwnsMemory=ETrue; - - //Create DChunk - TInt r=Kern::ChunkCreate(info, pC, aVirt, aAttributes); - if(r!=KErrNone) - { - NKern::ThreadLeaveCS(); - return r; - } - //Commit DChunk to Contiguous memory - r = Kern::ChunkCommitContiguous(pC, 0, aPciChunkSize, aPhysicalAddress); - if(r==KErrNone) - { - aChunk=pC; - } - else - { - Kern::ChunkClose(pC); - __KTRACE_OPT(KPCI,Kern::Printf("Commit DChunk to Contiguous memory Failed : Error code is=%d",r)); - return r; - } - - NKern::ThreadLeaveCS(); // Finished - __KTRACE_OPT(KPCI, Kern::Printf("Created SC: size=0x%08x, virtual= 0x%08x, phys=0x%08x", aPciChunkSize, aVirt, aPhysicalAddress)); - return r; -} - -class DPciDevice : public DLogicalDevice - { -public: - DPciDevice(); - ~DPciDevice(); - TInt Install(); - void GetCaps(TDes8& aDes) const; - TInt Create(DLogicalChannelBase*& aChannel); - }; - -DPciDevice::DPciDevice() - { - FUNC_LOG(); - } - -DPciDevice::~DPciDevice() - { - FUNC_LOG(); - } - -TInt DPciDevice::Install() - { - return SetName(&KPciLddFactory); - } - -void DPciDevice::GetCaps(TDes8&) const - { - } - -TInt DPciDevice::Create(DLogicalChannelBase*& aChannel) - { - aChannel = new DPciTestChannel; - return aChannel ? KErrNone : KErrNoMemory; - } - -/**************************************** -TUserPciSpace -*/ - -/** -Decides what action to run based on contents of class -*/ -TUint TUserPciSpace::KRun(TAddrSpace& aAddrSp) - { - - //this could be reworked as a function pointer - //table, but this might be clearer - switch(iBitWidth) - { - case 8: - { - switch(iOperation) - { - case ERead: - { - return aAddrSp.Read8(iOffset); - } - case EWrite: - { - aAddrSp.Write8(iOffset, iWriteValue); - return KErrNone; - } - case EModify: - { - aAddrSp.Modify8(iOffset, iClearMask, iSetMask); - return KErrNone; - } - default: - { - Kern::PanicCurrentThread(KPciTest, KErrNotReady); - } - } - } - case 16: - { - switch(iOperation) - { - case ERead: - { - return aAddrSp.Read16(iOffset); - } - case EWrite: - { - aAddrSp.Write16(iOffset, iWriteValue); - return KErrNone; - } - case EModify: - { - aAddrSp.Modify16(iOffset, iClearMask, iSetMask); - return KErrNone; - } - default: - { - Kern::PanicCurrentThread(KPciTest, KErrNotReady); - } - } - } - case 32: - { - switch(iOperation) - { - case ERead: - { - return aAddrSp.Read32(iOffset); - } - case EWrite: - { - aAddrSp.Write32(iOffset, iWriteValue); - return KErrNone; - } - case EModify: - { - aAddrSp.Modify32(iOffset, iClearMask, iSetMask); - return KErrNone; - } - default: - { - Kern::PanicCurrentThread(KPciTest, KErrNotReady); - } - } - } - default: - { - Kern::PanicCurrentThread(KPciTest, KErrArgument); - } - - } - - //unreachable return - return KMaxTUint; - } - -//stub implementation for kernel side -TUint TUserConfigSpace::Call() - { - FAULT(); - return 0; - } - -TUserPciSpace* TUserConfigSpace::Clone() const - { - FAULT(); - return 0; - } - -//stub implementation for kernel side -TUint TUserMemorySpace::Call() - { - FAULT(); - return 0; - } - -TUserPciSpace* TUserMemorySpace::Clone() const - { - FAULT(); - return 0; - } - -void TestAllocator() - { - __KTRACE_OPT(KPCI, Kern::Printf("Testing address allocator")); - TAddressAllocator allocator(0x80000000); //2 GB - TLinAddr rcvdAddr=NULL; - TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x10) ); - TEST(0x0 ==rcvdAddr); - TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x100) ); - TEST(0x100 ==rcvdAddr); - TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x10) ); - TEST(0x10 ==rcvdAddr); - TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x10) ); - TEST(0x20 ==rcvdAddr); - //test deallocating - TEST_KERRNONE(allocator.DeAllocate(0x0)); - TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x10) ); - TEST(0x000 ==rcvdAddr); - - TEST_KERRNONE(allocator.DeAllocate(0x100)); - TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x100) ); - TEST(0x100 ==rcvdAddr); - - TEST_KERRNONE(allocator.DeAllocate(0x10)); - TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x10) ); - TEST(0x10 ==rcvdAddr); - - TEST_KERRNONE(allocator.DeAllocate(0x20)); - TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x20) ); - TEST(0x20 ==rcvdAddr); - - TEST(allocator.DeAllocate(0x40)==KErrNotFound); - TEST_KERRNONE(allocator.DeAllocate(0x100)); - TEST_KERRNONE(allocator.DeAllocate(0x20)); - TEST_KERRNONE(allocator.DeAllocate(0x0)); - TEST_KERRNONE(allocator.DeAllocate(0x10)); - } - - -DECLARE_STANDARD_LDD() - { - return new DPciDevice; - } diff -r a4ff6126ec76 -r 7151b503b58d naviengine/navienginebsp/ne1_tb/test/pci/t_pci.cpp --- a/naviengine/navienginebsp/ne1_tb/test/pci/t_pci.cpp Wed Sep 15 13:26:16 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1087 +0,0 @@ -// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -// All rights reserved. -// This component and the accompanying materials are made available -// under the terms of the License "Eclipse Public License v1.0" -// which accompanies this distribution, and is available -// at the URL "http://www.eclipse.org/legal/epl-v10.html". -// -// Initial Contributors: -// Nokia Corporation - initial contribution. -// -// Contributors: -// -// Description: -// This is a test for the PCI driver, so far implemented only on the -// Naviengine platform. It aims to test: -// -That known values of data in config and memory space, on a given -// device can be read as expected. -// -That data can be written and modified in config and memory space -// -PCI memory buffers mapped or allocated by the PCI driver work as -// expected. These are -// -DChunk created by PCI driver and accessible from PCI -// -DPlatHwChunk created by PCI driver and accessible from PCI -// -DChunk created externally, then mapped in to PCI memory space -// There are tests to: -// - Create and close each buffer. Heap checking ensures proper -// cleanup -// - Create and close multiple buffers from multiple threads. -// This is an SMP focused test to check that the implementation -// of the chunk manager and allocator in the driver are thread -// safe. The tests should pass without triggering any assertions in -// the driver's invariance checks. -// - Write to buffers from software, and read back via the -// system to PCI window, and vice-versa -- a loop-back test. -// This checks that PCI buffers are indeed accessible to PCI devices. -// -// The tests require several pieces of PSL specific information: -// - A TPciDevice containing the vendor and device IDs of a PCI device -// to use for testing. -// - TAddrSpaceTests which identify regions of a device's config and -// memory space with known values, or which are known to be writable. -// -// The test driver grants access to the PCI API with the following -// constructs: -// - TUserConfigSpace and TUserMemorySpace, derived from TUserPciSpace, -// which are user side equivalents of kernel-side objects allowing -// accesses of different sizes to a PCI device's config space or -// memory space. -// - RPciChunk which is derived from and RChunk and corresponds to -// a kernel-side DChunk, which in turn corresponds to a PCI chunk or -// buffer. The test driver uses these for all PCI chunk types (a -// "wrapper" DChunk is used to map the memory of a PCI DPlatHwChunk -// to user side). -// -// Known Issues: -// The test driver d_pci is intended to be platform independent but -// for now still contains some PSL specific information .eg the test -// info structure (which should really be passed up from the PSL) and -// the address and size of the system to pci window. For now the -// test driver code will remain in the Naviengine baseport directory. -// If the PCI driver is ever ported to a new platform this can be -// rectified. -// -// -// -#include -#define __E32TEST_EXTENSION__ -#include -#include "t_pci.h" -#include - -#define __E32TEST_EXTENSION__ -#include -#include -#include -#include -#include -#include -#include -#include - - -_LIT(KPciPanicCat, "test_thread.h"); - -static const TInt KPciHeapSize=0x2000; - -enum TPciPanicCode - { - EThreadCreateFailed - }; - -/** -A utility class for running functions in other threads/processes -*/ -class TTestRemote - { -public: - virtual TInt WaitForExitL() = 0; - virtual ~TTestRemote() - {} - - virtual void Rendezvous(TRequestStatus& aStatus) = 0; - -protected: - TTestRemote() - {} - - static TInt RunFunctor(TAny* aFunctor) - { - TFunctor& functor = *(TFunctor*)aFunctor; - functor(); - return KErrNone; - } - - TRequestStatus iLogonStatus; - static TInt iCount; - }; -TInt TTestRemote::iCount=0; - -class TTestThread : public TTestRemote - { -public: - TTestThread(const TDesC& aName, TThreadFunction aFn, TAny* aData, TBool aAutoResume=ETrue) - { - Init(aName, aFn, aData, aAutoResume); - } - - /** - Run aFunctor in another thread - */ - TTestThread(const TDesC& aName, TFunctor& aFunctor, TBool aAutoResume=ETrue) - { - Init(aName, RunFunctor, &aFunctor, aAutoResume); - } - - ~TTestThread() - { - //RTest::CloseHandleAndWaitForDestruction(iThread); - iThread.Close(); - } - - void Resume() - { - iThread.Resume(); - } - - /** - If thread exited normally, return its return code - Otherwise, leave with exit reason - */ - virtual TInt WaitForExitL() - { - User::WaitForRequest(iLogonStatus); - const TInt exitType = iThread.ExitType(); - const TInt exitReason = iThread.ExitReason(); - - __ASSERT_ALWAYS(exitType != EExitPending, User::Panic(_L("TTestThread"),0)); - - if(exitType != EExitKill) - User::Leave(exitReason); - - return exitReason; - } - - virtual void Rendezvous(TRequestStatus& aStatus) - { - iThread.Rendezvous(aStatus); - } - -private: - void Init(const TDesC& aName, TThreadFunction aFn, TAny* aData, TBool aAutoResume) - { - TKName name(aName); - name.AppendFormat(_L("-%d"), iCount++); - TInt r=iThread.Create(name, aFn, KDefaultStackSize, KPciHeapSize, KPciHeapSize, aData); - if(r!=KErrNone) - { - RDebug::Printf("RThread::Create failed, code=%d", r); - User::Panic(KPciPanicCat, EThreadCreateFailed); - } - - iThread.Logon(iLogonStatus); - __ASSERT_ALWAYS(iLogonStatus == KRequestPending, User::Panic(_L("TTestThread"),0)); - - if(aAutoResume) - iThread.Resume(); - } - - RThread iThread; - }; - -class CTest : public CBase, public TFunctor - { -public: - ~CTest() - { - iName.Close(); - } - - virtual void operator()() - { - RTest test(iName); - test.Start(iName); - for(TInt i=0; i testArray; - RPointerArray threadArray; - - for(TInt i=0; iWaitForExitL()); - if(leaveCode != KErrNone) - { - test.Printf(_L("Thread %d: Panic code:%d\n"), j, leaveCode); - test_KErrNone(leaveCode); - } - - if(r!=KErrNone) - { - test.Printf(_L("Thread Number %d\n"), j); - test_KErrNone(r); - } - } - - threadArray.ResetAndDestroy(); - threadArray.Close(); - - testArray.ResetAndDestroy(); - testArray.Close(); - } - -class RPci; -/** -Extends RChunk to hold the PCI address -associated with a chunk. -*/ -class RPciChunk: public RChunk - { -public: - TUint PciBase() - { - return iPciBaseAddr; - } - - /** - Return the PCI accessible size - */ - TInt Size() const - { - return iPciSize; - } - -private: - friend class RPci; - TUint iPciBaseAddr; - TInt iPciSize; //size of the region mapped into PCI - }; - -typedef TInt (RPci::*ChunkOpenFn)(RPciChunk&, TInt, TRequestStatus*); - -class RPci : public RBusLogicalChannel - { -public: - TInt Open(); - TInt GetTestInfo(TPciTestInfo& aTestInfo); - - TInt Open(const TPciDevice&); - - TUint AccessConfigSpace(const TUserConfigSpace& aCs); - TUint AccessMemorySpace(const TUserMemorySpace& aMs); - TInt OpenPciDChunk(RPciChunk& aPciChunk,TInt aPciChunkSize, TRequestStatus* aStatus=0); - TInt OpenPciPlatHwChunk(RPciChunk& aPciHwChunk,TInt aPciChunkSize, TRequestStatus* aStatus=0); - TInt OpenPciMappedChunk(RPciChunk& aPciMappedChunk,TInt aPciChunkSize, TRequestStatus* aStatus=0); - TInt OpenPciWindowChunk(RChunk& aPciWindowChunk); - TInt RunUnitTests(); -private: - TInt DoOpenPciChunk(RPciChunk& aPciChunk, TInt aPciChunkSize, TPciTestCmd aCmd, TRequestStatus* aStatus); - }; - -inline TInt RPci::Open() - { - return DoCreate(KPciLddFactory, TVersion(), KNullUnit, NULL, NULL); - } - -inline TInt RPci::Open(const TPciDevice& aDevice) - { - TPckgC devicePkg(aDevice); - return DoCreate(KPciLddFactory, TVersion(), KNullUnit, NULL, &devicePkg); - } - -inline TInt RPci::GetTestInfo(TPciTestInfo& aTestInfo) - { - TPckg info(aTestInfo); - return DoControl(EGetTestInfo, &info); - } - -inline TInt RPci::RunUnitTests() - { - return DoControl(ERunUnitTests); - } - -TUint RPci::AccessConfigSpace(const TUserConfigSpace& aCs) - { - TPckgC pkg(aCs); - return DoControl(EAccessConfigSpace, &pkg); - } - -TUint RPci::AccessMemorySpace(const TUserMemorySpace& aMs) - { - TPckgC pkg(aMs); - return DoControl(EAccessMemorySpace, &pkg); - } - -TInt RPci::OpenPciDChunk(RPciChunk& aPciChunk,TInt aPciChunkSize, TRequestStatus* aStatus) - { - return DoOpenPciChunk(aPciChunk, aPciChunkSize, EOpenPciDChunk, aStatus); - } - -TInt RPci::OpenPciPlatHwChunk(RPciChunk& aPciHwChunk,TInt aPciChunkSize, TRequestStatus* aStatus) - { - return DoOpenPciChunk(aPciHwChunk, aPciChunkSize, EOpenPciPlatHwChunk, aStatus); - } - -TInt RPci::OpenPciMappedChunk(RPciChunk& aPciMappedChunk,TInt aPciChunkSize, TRequestStatus* aStatus) - { - return DoOpenPciChunk(aPciMappedChunk, aPciChunkSize, EOpenPciMappedChunk, aStatus); - } - -TInt RPci::OpenPciWindowChunk(RChunk& aPciWindowChunk) - { - TUint chunkHandle = DoControl(EOpenPciWindowChunk); - return aPciWindowChunk.SetReturnedHandle(chunkHandle); - } - -TInt RPci::DoOpenPciChunk(RPciChunk& aPciChunk, TInt aPciChunkSize, TPciTestCmd aCmd, TRequestStatus* aStatus) - { - const TInt constPciChunkSize = aPciChunkSize; - TPciChunkCreateInfo info(constPciChunkSize, aPciChunk.iPciBaseAddr, aStatus); - TPckgC pkg(info); - - TUint chunkHandle = DoControl(aCmd, &pkg); - - const TInt r = aPciChunk.SetReturnedHandle(chunkHandle); - if(r == KErrNone) - { - aPciChunk.iPciSize = constPciChunkSize; - } - return r; - } - -TUserPciSpace::TUserPciSpace(RPci& aPci) - :iPci(&aPci) - {} - -TUserConfigSpace::TUserConfigSpace(RPci& aPci) - :TUserPciSpace(aPci) - {} - -TUint TUserConfigSpace::Call() - { - return iPci->AccessConfigSpace(*this); - } - -TUserPciSpace* TUserConfigSpace::Clone() const - { - return new TUserConfigSpace(*this); - } - -TUserMemorySpace::TUserMemorySpace(RPci& aPci, TInt aBarIndex) - :TUserPciSpace(aPci), iBarIndex(aBarIndex) - {} - -TUint TUserMemorySpace::Call() - { - return iPci->AccessMemorySpace(*this); - } - -TUserPciSpace* TUserMemorySpace::Clone() const - { - return new TUserMemorySpace(*this); - } - -/** -Test address allocator -*/ -TInt TestRunPciUnitTest(RPci& pci) - { - return pci.RunUnitTests(); - } - - -/** -Read from a defined address in memory or config space, compare against expected values. -8,16, and 32 bit accesses performed. - -@param aSpace Object gving access to either the config or memory space of a PCI device -@param aInfo Contains the address and expected value of a dword -*/ -void TestReadAddressSpace(TUserPciSpace& aSpace, const TPciTestInfo::TAddrSpaceTest& aInfo, RTest& test, TBool aVerbose=EFalse) - { - const TUint os = aInfo.iOffset; - //Iterate over different widths, and possible - //subfields of 32 bit word - for(TInt bitWidth=32; bitWidth>=8; bitWidth>>=1) - { - const TInt numberOfFields = (32/bitWidth); - for(TInt i=0; i< numberOfFields; i++) - { - const TInt extraByteOffset = i * (bitWidth >> 3); - const TInt byteOffset = os + extraByteOffset; - if(aVerbose) - test.Printf(_L("Access bitWidth=%d byte offset=%d\n"), bitWidth, byteOffset); - - const TUint expected = aInfo.Expected(bitWidth, byteOffset); - const TUint read = aSpace.Read(bitWidth, byteOffset); - if(aVerbose) - test.Printf(_L("expect 0x%08x, read 0x%08x\n"), expected, read); - test_Equal(expected, read); - } - } - } - -/** -Verify writes and modifications to a defined address in memory or config space. 8,16, and 32 bit -accesses performed. - -@param aSpace Object gving access to either the config or memory space of a PCI device -@param aInfo Contains the address of a (at least partially) writable dword -*/ -void TestWriteAddressSpace(TUserPciSpace& aSpace, TPciTestInfo::TAddrSpaceTest& aInfo, RTest& test, TBool aVerbose=EFalse) - { - const TUint original = aSpace.Read(32, aInfo.iOffset); - const TUint os = aInfo.iOffset; - TUint mask = ~aInfo.iReadOnlyMask; - - //The pattern will be truncated when used with bit widths - //less than 32. - const TUint initPattern = 0xFFFFFFFF; - - for(TInt bitWidth=32; bitWidth>=8; bitWidth>>=1) - { - const TUint pattern = initPattern >> (32-bitWidth); - const TInt numberOfFields = (32/bitWidth); - for(TInt i=0; i< numberOfFields; i++) - { - const TInt extraByteOffset = i * (bitWidth >> 3); - const TInt byteOffset = os + extraByteOffset; - if(aVerbose) - test.Printf(_L("Access bitWidth=%d byte offset=%d\n"), bitWidth, byteOffset); - //the full dword we expect - //currently assume that the unwritable bits will be 0 - const TUint writeExpect = (pattern << (bitWidth * i) ) & mask; - const TUint clearExpect = 0; - - //do write followed by clear - const TUint expect[] = {writeExpect, clearExpect}; - const TUint write[] = {pattern, 0}; - for(TInt n = 0; n < 2; n++) - { - aSpace.Write(bitWidth, byteOffset, write[n]); - TUint result = aSpace.Read(32, os); - - if(aVerbose) - test.Printf(_L("wrote 0x%08x, expect 0x%08x, read 0x%08x\n"), - write[n], expect[n], result); - test_Equal(expect[n], result); - } - - //test Modify calls. Set then clear pattern - TUint set[] = {pattern, 0}; - TUint clear[] = {0, pattern}; - - for(TInt m = 0; m < 2; m++) - { - aSpace.Modify(bitWidth, byteOffset, clear[m], set[m]); - TUint result = aSpace.Read(32, os); - - if(aVerbose) - test.Printf(_L("clear 0x%08x, set 0x%08x, expect 0x%08x, read 0x%08x\n"), clear[m], set[m], expect[m], result); - test_Equal(expect[m], result); - } - } - } - - //restore orginal value or we will not be able to access device - aSpace.Write(32, os, original); - } - - -/** -Verify that a PCI DChunk can be opened and closed from user side - -@param pci The RPci object to use -@param test The RTest object to use -@param aPciChunkSize The size of the DChunk which would be created -*/ -void TestOpenAndCloseDChunk(RPci& pci,RTest& test,TInt aPciChunkSize) - { - RPciChunk testPciDChunk; - - // Create and open Chunk - TRequestStatus status; - TInt r = pci.OpenPciDChunk(testPciDChunk,aPciChunkSize, &status); - test_KErrNone(r); - - test(testPciDChunk.IsWritable()); - test(testPciDChunk.IsReadable()); - - test.Printf(_L("PCI Chunk base = 0x%08x\n"), testPciDChunk.Base()); - test.Printf(_L("PCI Chunk size = %d\n"), testPciDChunk.Size()); - test.Printf(_L("PCI Address = 0x%08x\n"), testPciDChunk.PciBase()); - - //Close Chunk - test.Next(_L("Close PCI Chunk handle")); - - RTest::CloseHandleAndWaitForDestruction(testPciDChunk); - User::WaitForRequest(status); - } - -/** -Verify that a PCI PlatHwChunk can be opened and closed from user side - - -@param pci The RPci object to use -@param test The RTest object to use -@param aPciChunkSize The size of the PlatHwChunk which would be created -*/ -void TestOpenAndClosePciPlatHwChunk(RPci& pci,RTest& test,TInt aPciChunkSize) - { - RPciChunk testPciPlatHwChunk; - - // Create and open Chunk - TRequestStatus status; - TInt r = pci.OpenPciPlatHwChunk(testPciPlatHwChunk,aPciChunkSize, &status); - test_KErrNone(r); - - test(testPciPlatHwChunk.IsWritable()); - test(testPciPlatHwChunk.IsReadable()); - - test.Printf(_L("PCI Chunk base = 0x%08x\n"), testPciPlatHwChunk.Base()); - test.Printf(_L("PCI Chunk size = %d\n"), testPciPlatHwChunk.Size()); - test.Printf(_L("PCI Address = 0x%08x\n"), testPciPlatHwChunk.PciBase()); - - //Close Chunk - testPciPlatHwChunk.Close(); - User::WaitForRequest(status); - test.Next(_L("Closed PCI PlatHwChunk handle")); - } - -/** -Verify that pci-mapped DChunk can be opended and closed form user side - -@param pci The RPci object to use -@param test The RTest object to use -@param aPciChunkSize The size of the pci-mapped DChunk which would be created -*/ -void TestPciMapppedChunk(RPci& pci,RTest& test,TInt aPciChunkSize) - { - RPciChunk testPciMappedChunk; - - // Create and open Chunk - TRequestStatus status; - TInt r = pci.OpenPciMappedChunk(testPciMappedChunk,aPciChunkSize, &status); - test_KErrNone(r); - - test(testPciMappedChunk.IsWritable()); - test(testPciMappedChunk.IsReadable()); - - test.Printf(_L("PCI Chunk base = 0x%08x\n"), testPciMappedChunk.Base()); - test.Printf(_L("PCI Chunk size = %d\n"), testPciMappedChunk.Size()); - test.Printf(_L("PCI Address = 0x%08x\n"), testPciMappedChunk.PciBase()); - - //Close Chunk - testPciMappedChunk.Close(); - User::WaitForRequest(status); - test.Next(_L("Closed PCI Mapped Chunk handle")); - } - -/** -Verify that an RChunk can be open to grant access to the internal PCI window from the user side - -@param pci The RPci object to use -@param test The RTest object to use -*/ -void TestPciWindowChunk(RPci& pci,RTest& test) - { - RChunk testPciWindowChunk; - - // Create and open DChunk - TInt r = pci.OpenPciWindowChunk(testPciWindowChunk); - test_KErrNone(r); - - test(testPciWindowChunk.IsWritable()); - test(testPciWindowChunk.IsReadable()); - - test.Printf(_L("PCI Window Chunk base = 0x%08x\n"), testPciWindowChunk.Base()); - test.Printf(_L("PCI Window Chunk size = %d\n"), testPciWindowChunk.Size()); - - //Close Chunk - testPciWindowChunk.Close(); - test.Next(_L("Closed PCI Window Chunk handle")); - } - - -class CPciTest : public CTest - { -protected: - CPciTest(const TDesC& aName, TInt aIterations, RPci& aDevice) - : CTest(aName, aIterations), iDevice(aDevice) - {} - - RPci iDevice; - }; - -/** -Each instance of test will open a chunk, using the function specified in -the template argument, FUNC. - -The total number of chunks that can be opened by all instances is limited -by iMaxCount. - -All intances of the test will hold their chunk open until iMaxCount has -been reached. -*/ -template -class CPciOpenChunkTest : public CPciTest - { -public: - CPciOpenChunkTest(const TDesC& aName, TInt aIterations, RPci& aDevice, - RSemaphore aSemOpen, RSemaphore aSemClose, RFastLock aLock, TInt aMaxCount) - :CPciTest(aName, aIterations, aDevice), - iSemOpen(aSemOpen), iSemClose(aSemClose), iLock(aLock), iMaxCount(aMaxCount) - { - } - - virtual void RunTest() - { - RTest test(iName); - RPciChunk chunk; - - iSemOpen.Wait(); - TRequestStatus status; - const TInt chunkSize = 0x400; - //open chunk by calling FUNC - TInt r = ((iDevice).*(FUNC))(chunk, chunkSize, &status); - test_KErrNone(r); - - iLock.Wait(); - iOpenCount++; - test.Printf(_L("Opened chunk %d\n"), iOpenCount); - if(iOpenCount == iMaxCount) - { - test.Printf(_L("Opened=%d, max=%d: Allow chunks to close\n"), iOpenCount, iMaxCount); - //release all waiting threads - //plus 1 preincrement so this - //thread also passes - iSemClose.Signal(iOpenCount); - iOpenCount = 0; - } - iLock.Signal(); - - - iSemClose.Wait(); - chunk.Close(); - User::WaitForRequest(status); - - // permit another chunk to be opened - iSemOpen.Signal(); - test.Close(); - } - - virtual CTest* Clone() const - { - //make shallow copy - return new CPciOpenChunkTest(*this); - } - - -private: - RSemaphore& iSemOpen; ///!< Represents the number of available PCI mappings - RSemaphore& iSemClose; ///!< Represents the number of threads waiting to close their chunk - RFastLock& iLock; - static TInt iOpenCount; - const TInt iMaxCount; - }; - -template -TInt CPciOpenChunkTest::iOpenCount = 0; - - -/** -Test which will perform various reads from a PCI address -space (config or memory) and confirm that values are read -as expected -*/ -class CPciAddressSpaceRead : public CPciTest - { -public: - CPciAddressSpaceRead(const TDesC& aName, TInt aIterations, RPci& aDevice, - const TUserPciSpace& aSpace, const TPciTestInfo::TAddrSpaceTest& aInfo) - :CPciTest(aName, aIterations, aDevice), - iAddressSpace(aSpace.Clone()), iSpaceTestInfo(aInfo) - { - } - - CPciAddressSpaceRead(const CPciAddressSpaceRead& aOther) - :CPciTest(aOther)/* TODO-REVIEW have object-sliced aOther - is this ok?*/, - iAddressSpace(aOther.iAddressSpace->Clone()), iSpaceTestInfo(aOther.iSpaceTestInfo) - { - } - - virtual ~CPciAddressSpaceRead() - { - delete iAddressSpace; - } - - virtual void RunTest() - { - __UHEAP_MARK; - RTest test(iName); - TestReadAddressSpace(*iAddressSpace, iSpaceTestInfo, test); - test.Close(); - __UHEAP_MARKEND; - } - - virtual CTest* Clone() const - { - //make shallow copy - return new CPciAddressSpaceRead(*this); - } - -private: - TUserPciSpace* iAddressSpace; - const TPciTestInfo::TAddrSpaceTest& iSpaceTestInfo; - }; - -/** -For aBuffer, test writing to it then reading back from aWindow -then write via window and read back from chunk - -@param test The RTest object to use -@param aBuffer RChunk corresponding to a PCI accessible buffer -@param aWindow RChunk coressponding an appropriate System-to-PCI memory window -It is presumed to start at PCI address 0 -*/ -void DoLoopBackTest(RTest& test, RPciChunk aBuffer, RChunk aWindow) - { - test.Start(_L("Test accessing memory via PCI")); - - TUint8* const bufferBase = aBuffer.Base(); - const TUint bufferSize = aBuffer.Size(); - const TUint bufferPciBase = aBuffer.PciBase(); - - TUint8* const windowBase = aWindow.Base(); - const TUint windowSize = aWindow.Size(); - -#define PRINT(N) RDebug::Printf("%s = 0x%08x (%d)", #N, (N), (N)) - PRINT(bufferBase); - PRINT(bufferSize); - PRINT(bufferPciBase); - - PRINT(windowBase); - PRINT(windowSize); - -#undef PRINT - - //need to check that the end of the buffer - //is within the windowed region - test(bufferPciBase + bufferSize <= windowSize); - TUint8* const bufferBaseWithinWindow = windowBase + bufferPciBase; - - test.Next(_L("write chunk")); - for(TUint i = 0; i < bufferSize; ++i) - { - //each byte will hold its own offset modulo 256 - bufferBase[i] = (TUint8)i; - } - - test.Next(_L("read back via window")); - for(TUint j=0; j < bufferSize; ++j) - { - const TUint8 result = bufferBaseWithinWindow[j]; - test_Equal(j%256, result); - } - - //clear chunk - memclr(bufferBase, bufferSize); - test.Next(_L("write via window")); - for(TUint k=0; k < bufferSize; ++k) - { - //each byte will hold its own offset modulo 256 - bufferBaseWithinWindow[k] = (TUint8)k; - } - - test.Next(_L("read back from chunk")); - for(TUint l=0; l < bufferSize; ++l) - { - const TUint8 result = bufferBase[l]; - test_Equal(l%256, result); - } - - test.End(); - } - -/** -Take care of opening a chunk, running the test and closing -*/ -template -inline void LoopBackTest(RPci& aPci, RTest& test, RChunk& aWindow) - { - RPciChunk pciChunk; - const TInt chunkSize = 0x400; //1k - - //call the specified chunk opening function - TRequestStatus status; - TInt r = ((aPci).*(OPEN_FUNC))(pciChunk, chunkSize, &status); - test_KErrNone(r); - DoLoopBackTest(test, pciChunk, aWindow); - pciChunk.Close(); - User::WaitForRequest(status); - } - -/** -Run the loopback test for the 3 types of buffer supported by the PCI driver. -DChunk -DPlatChunk -Mapped In external memory -*/ -void TestLoopBack(RPci& aPci, RTest& test) - { - test.Next(_L("Open PCI window")); - RChunk window; - - TInt r = aPci.OpenPciWindowChunk(window); - test_KErrNone(r); - - test.Next(_L("DChunk")); - LoopBackTest<&RPci::OpenPciDChunk>(aPci, test, window); - - test.Next(_L("DPlatHwChunk")); - LoopBackTest<&RPci::OpenPciPlatHwChunk>(aPci, test, window); - - test.Next(_L("DChunk (mapped in)")); - LoopBackTest<&RPci::OpenPciMappedChunk>(aPci, test, window); - - window.Close(); - } -#ifndef __VC32__ //visual studio 6 doesn't approve of pointer to member function template parameters -/** -Run the CPciOpenChunkTest for each type of chunk. This function also creates (and destroys) the -necessary semaphores and locks. -CPciOpenChunkTest objects are run in multiple threads using MultipleTestRun(). - -@param aDevice Handle to the test driver -@param test RTest to use. -@param aBufferLimit The maximum number of buffers which can be opened simultaneously -*/ -void TestBufferOpenConcurrency(RPci& aDevice, RTest& test, TInt aBufferLimit) - { - RSemaphore semaphoreOpen; - RSemaphore semaphoreClose; - RFastLock lock; - - TInt r = semaphoreOpen.CreateLocal(aBufferLimit); - test_KErrNone(r); - - r = semaphoreClose.CreateLocal(0); - test_KErrNone(r); - - r = lock.CreateLocal(); - test_KErrNone(r); - - const TInt iterations = 3; - { - test.Printf(_L("Opening %d PCI DChunks in %d threads\n"), aBufferLimit, aBufferLimit); - CPciOpenChunkTest<&RPci::OpenPciDChunk> - dChunkTest(_L("Concurrent-DChunk"), iterations, aDevice, semaphoreOpen, semaphoreClose, lock, aBufferLimit); - - MultipleTestRun(test, dChunkTest, aBufferLimit); - } - - { - test.Printf(_L("Opening %d PCI DPlatHwChunks in %d threads\n"), aBufferLimit, aBufferLimit); - CPciOpenChunkTest<&RPci::OpenPciPlatHwChunk> - platChunkTest(_L("Concurrent-DPlatHwChunk"), iterations, aDevice, semaphoreOpen, semaphoreClose, lock, aBufferLimit); - - MultipleTestRun(test, platChunkTest, aBufferLimit); - } - - { - test.Printf(_L("Opening %d PCI Mapped chunks in %d threads\n"), aBufferLimit, aBufferLimit); - CPciOpenChunkTest<&RPci::OpenPciMappedChunk> - mappedChunkTest(_L("Concurrent-DChunk(mapped)"), iterations, aDevice, semaphoreOpen, semaphoreClose, lock, aBufferLimit); - - MultipleTestRun(test, mappedChunkTest, aBufferLimit); - } - - semaphoreOpen.Close(); - semaphoreClose.Close(); - lock.Close(); - } -#endif - -TInt E32Main() - { - __UHEAP_MARK; - - _LIT(KPci, "PCI"); - RTest test(KPci); - test.Start(_L("Running PCI tests\n")); - - TInt r = User::LoadLogicalDevice(KPciLdd); - - __KHEAP_MARK; - - if(r==KErrNotFound) - { - test.Printf(_L("No PCI system present - skipping test\n")); - return KErrNone; - } - if(r!=KErrNone && r!=KErrAlreadyExists) - { - test_KErrNone(r); - } - - test.Next(_L("Open non-existant device\n")); - RPci device; - TPciDevice unavailable; - r = device.Open(unavailable); - test_Equal(KErrNotFound, r); - - RPci pciInfo; - r = pciInfo.Open(); - test_KErrNone(r); - - test.Next(_L("Get test info from driver\n")); - TPciTestInfo info; - r = pciInfo.GetTestInfo(info); - test_KErrNone(r); - pciInfo.Close(); - - test.Next(_L("Open test device\n")); - r = device.Open(info.iDevice); - test_KErrNone(r); - - test.Next(_L("Run Device Unit Test\n")); - r=TestRunPciUnitTest(device); - test_KErrNone(r); - - test.Next(_L("Read config space\n")); - TUserConfigSpace cs(device); - TestReadAddressSpace(cs, info.iCfgSpaceRead, test); - - test.Next(_L("Write config space\n")); - TestWriteAddressSpace(cs, info.iCfgSpaceWrite, test); - - test.Next(_L("Read memory space\n")); - TUserMemorySpace ms(device, info.iMemSpaceIndex); - TestReadAddressSpace(ms, info.iMemSpaceRead, test); - - test.Next(_L("Modify memory space\n")); - TestWriteAddressSpace(ms, info.iMemSpaceWrite, test); - - { - const TInt addrSpaceThreadCount = 4; - const TInt iterations = 100; - test.Next(_L("Concurrent config space reads")); - CPciAddressSpaceRead cfgSpaceRead(_L("Cfg Space Read"), iterations, device, cs, info.iCfgSpaceRead); - MultipleTestRun(test, cfgSpaceRead, addrSpaceThreadCount); - - test.Next(_L("Concurrent memory space reads")); - CPciAddressSpaceRead memSpaceRead(_L("Memory Space Read"), iterations, device, ms, info.iMemSpaceRead); - MultipleTestRun(test, memSpaceRead, addrSpaceThreadCount); - } - - TInt testDChunkSize = 0x4000; - test.Next(_L("Open and Close DChunks\n")); - TestOpenAndCloseDChunk(device,test,testDChunkSize); - - TInt testDPlatChunkSize = 0x2000; - test.Next(_L("Open and Close PlatHwChunks\n")); - TestOpenAndClosePciPlatHwChunk(device,test,testDPlatChunkSize); - - //TestPciMapppedChunk() fails for sizes greater than 4K. - //The issue is that a block of externally mapped memory must be - //naturally alligned in order to be accessible to the PCI bus (ie - //an 8k buffer would have to start at an address which is a - //multiple of 8k. - // - //Now we could fix this for sure on the kernel side, by making - //sure we only commit correctly aligned memory into the chunk (as - //the pci driver itself does), - //However, by using a 4k chunk, we know this will be on a page - //boundary so the alignment is correct (assuming the page size - //isn't changed). - TInt testMapppedChunkSize = 0x1000; - test.Next(_L("Open and Close Pci Mappped Chunk\n")); - TestPciMapppedChunk(device,test,testMapppedChunkSize); - - test.Next(_L("Open and Close Pci Window Chunk\n")); - TestPciWindowChunk(device,test); - - const TInt numberOfThreads = info.iNumberOfBars; - test.Printf(_L("Open buffers concurrently, max supported = %d\n"), numberOfThreads); -#ifndef __VC32__ - TestBufferOpenConcurrency(device, test, numberOfThreads); -#else - test.Printf(_L("TestBufferOpenConcurrency not implemented for WINS"), numberOfThreads); -#endif - - test.Next(_L("Test loop back")); - TestLoopBack(device, test); - - device.Close(); - __KHEAP_MARKEND; - - r = User::FreeLogicalDevice(KPciLdd); - test_KErrNone(r); - - test.End(); - test.Close(); - - __UHEAP_MARKEND; - return KErrNone; - } diff -r a4ff6126ec76 -r 7151b503b58d naviengine/navienginebsp/ne1_tb/test/pci/t_pci.h --- a/naviengine/navienginebsp/ne1_tb/test/pci/t_pci.h Wed Sep 15 13:26:16 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,254 +0,0 @@ -// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -// All rights reserved. -// This component and the accompanying materials are made available -// under the terms of the License "Eclipse Public License v1.0" -// which accompanies this distribution, and is available -// at the URL "http://www.eclipse.org/legal/epl-v10.html". -// -// Initial Contributors: -// Nokia Corporation - initial contribution. -// -// Contributors: -// -// Description: This is the header file for the PCI driver test , so far implemented -// only on the Naviengine platform - -#ifndef __TPCI_TEST_H -#define __TPCI_TEST_H - -#ifndef __KERNEL_MODE__ -#define __E32TEST_EXTENSION__ -#include - #include -#endif // __KERNEL_MODE__ - -_LIT(KPciLdd, "d_pci.ldd"); -_LIT(KPciLddFactory, "PCI_test_factory"); -_LIT(KPciTest, "PCI Test LDD"); - -/** -Test driver op-codes -*/ -enum TPciTestCmd - { - EGetTestInfo, - EAccessConfigSpace, - EAccessMemorySpace, - EOpenPciDChunk, - EOpenPciPlatHwChunk, - EOpenPciMappedChunk, - EOpenPciWindowChunk, - ERunUnitTests - }; - -/** -Identifies a PCI Function (device) on the system -*/ -struct TPciDevice - { - TPciDevice() - :iVendorId(0xFFFFFFFF), iDeviceId(0xFFFFFFFF), iInstance(0) {} - - TPciDevice(TUint aVendorId, TUint aDeviceId, TInt aInstance=0) - :iVendorId(aVendorId), iDeviceId(aDeviceId), iInstance(aInstance) {} - - TUint iVendorId; - TUint iDeviceId; - TInt iInstance; ///< Unit to open (there could be multiple devices on system) - }; - -/** -Used to send chunk size and recieve -PCI address -*/ -struct TPciChunkCreateInfo - { - TPciChunkCreateInfo() - :iSize(0), iPciAddress(NULL) - { - } - - TPciChunkCreateInfo(TInt aSize, TUint& aPciAddress, TRequestStatus* aStatus=NULL) - :iSize(aSize), iPciAddress(&aPciAddress), iStatus(aStatus) - { - } - TInt iSize; - TUint* iPciAddress; - TRequestStatus* iStatus; - }; - -/** -Information about the PSL required by the -user side test -*/ -struct TPciTestInfo - { - TPciDevice iDevice; ///< Probe for this - - /** - Supplies the necessary information to test Read, Write, and - Modify for a word of PCI memory or configuration space - */ - struct TAddrSpaceTest - { - TAddrSpaceTest() - :iOffset(0), iExpectedValue(0), iReadOnlyMask(0) - {} - - TAddrSpaceTest(TUint aOffset, TUint aExpectedValue, TUint aReadOnlyMask) - :iOffset(aOffset), iExpectedValue(aExpectedValue), iReadOnlyMask(aReadOnlyMask) - {} - - /** - Returns a specified sub byte, or word from the whole dword - */ - inline TUint Expected(TInt aBitWidth, TInt aExtraOffset) const - { - //the right shift required to get field to bit 0 - const TInt shift = 8 *((aExtraOffset + iOffset) % 4); - - const TUint mask = 0xFFFFFFFF >> (32-aBitWidth); - return (iExpectedValue >> shift) & mask; - } - - const TUint iOffset; - const TUint iExpectedValue; ///< The initial value of word - const TUint iReadOnlyMask; ///< Mask of unwritable bits - //Future work, memory spaces should state a bar index - }; - - - TAddrSpaceTest iCfgSpaceRead; - TAddrSpaceTest iCfgSpaceWrite; - - TUint iMemSpaceIndex; ///< Memory space to select - TAddrSpaceTest iMemSpaceRead; - TAddrSpaceTest iMemSpaceWrite; - - TInt iNumberOfBars; ///< Number of simultaneous mappings into PCI space - }; - -class RPci; -class TAddrSpace; -/** -This class encapsulates all the various read/write/and modify commands -that can be carried out on a PCI memory space. The command is stored user -side, and then executed on kernel side when KRun() is called. -*/ -class TUserPciSpace - { -public: - TUserPciSpace() - :iPci(NULL), iOperation(EInvalid), iBitWidth(0), iOffset(0), - iWriteValue(0), iClearMask(0), iSetMask(0) - {} - TUserPciSpace(RPci& aPci); - - /** - Perform the encapsulated read/write/or modify - @note Only run on kernel side - */ - TUint KRun(TAddrSpace& aAddrSpace); - - /** - Clone method is required so that multiple threads may - have their own copy of a TUserPciSpace (without knowing - its runtime type) - */ - virtual TUserPciSpace* Clone() const = 0; - - TUint Read(TInt aBitWidth, TUint aOffset) - { - iOffset = aOffset; - iOperation = ERead; - iBitWidth = aBitWidth; - - return Call(); - } - - void Write(TInt aBitWidth, TUint aOffset, TUint aValue) - { - iOffset = aOffset; - iOperation = EWrite; - iBitWidth = aBitWidth; - - iWriteValue = aValue; - Call(); - } - - void Modify(TInt aBitWidth, TUint aOffset, TUint aClearMask, TUint aSetMask) - { - iOffset = aOffset; - iOperation = EModify; - iBitWidth = aBitWidth; - - iClearMask = aClearMask; - iSetMask = aSetMask; - Call(); - } - -protected: - /** - Makes a request to iPci and passes a copy of this object to - the kernel side. - */ - virtual TUint Call() =0; - - enum TOperation {EInvalid, ERead, EWrite, EModify}; - - /** - Pointer to a PCI device handle - */ - RPci* iPci; - - TOperation iOperation; //!< Type of access to perform - TInt iBitWidth; - - TUint iOffset; - TUint32 iWriteValue; - TUint32 iClearMask; - TUint32 iSetMask; - }; - -/** -Grants access to a PCI device's (identified -by aPci) config space from user side -*/ -class TUserConfigSpace : public TUserPciSpace - { -public: - TUserConfigSpace() - :TUserPciSpace() - {} - TUserConfigSpace(RPci& aPci); - - virtual TUserPciSpace* Clone() const; -private: - TUint Call(); - }; - -/** -Grants access to some region of a PCI -device's memory space. A PCI device(or function) -may have up to 8 distinct memory spaces -*/ -class TUserMemorySpace : public TUserPciSpace - { -public: - TUserMemorySpace() - :TUserPciSpace(), iBarIndex(-1) - {} - - TUserMemorySpace(RPci& aPci, TInt aBarIndex); - - virtual TUserPciSpace* Clone() const; - - inline TInt BarIndex() {return iBarIndex;} - -private: - TUint Call(); - - TInt iBarIndex; ///< Each PCI function may have up to 8 memory spaces - }; - -#endif //__TPCI_TEST_H