Changes for full working UI on 3.0.0 including Gareth's "persistent" RAM drives
authorTom Pritchard <tomp@symbian.org>
Tue, 27 Jul 2010 15:31:26 +0100
changeset 46 78c240f59c9d
parent 38 cdb163c0843f
child 47 deed9c658f70
Changes for full working UI on 3.0.0 including Gareth's "persistent" RAM drives
omap3530/beagle_drivers/lcd/lcd.mmp
omap3530/beagle_drivers/medstaticrd/beagle_medstaticrd.cpp
omap3530/beagle_drivers/medstaticrd/beagle_medstaticrd.h
omap3530/beagle_drivers/medstaticrd/bld.inf
omap3530/beagle_drivers/medstaticrd/medstaticrd.mmp
omap3530/beagleboard/bld.inf
omap3530/beagleboard/rom/base_beagle.iby
omap3530/beagleboard/rom/drive_c.img
omap3530/beagleboard/rom/estart.txt
omap3530/buildscripts/cleanbuild.mbc
omap3530/buildscripts/reallycleanbuild.mbc
omap3530/buildscripts/rebuild.mbc
--- a/omap3530/beagle_drivers/lcd/lcd.mmp	Thu Jul 01 17:46:13 2010 +0100
+++ b/omap3530/beagle_drivers/lcd/lcd.mmp	Tue Jul 27 15:31:26 2010 +0100
@@ -27,7 +27,7 @@
 #include			"kernel/kern_ext.mmh"
 
 //Need to define NGA_BUILD for a NGA compliant Display PDD
-//#define NGA_BUILD
+#define NGA_BUILD
 #ifdef NGA_BUILD
 MACRO ENABLE_GCE_MODE
 target				VariantTarget(lcd_gce,dll)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omap3530/beagle_drivers/medstaticrd/beagle_medstaticrd.cpp	Tue Jul 27 15:31:26 2010 +0100
@@ -0,0 +1,807 @@
+/*
+* Copyright (c) 2010 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 - contribution.
+*
+* Contributors:
+* Gareth Long - Symbian Foundation
+*
+* Description: Minimalistic non volatile memory driver
+*
+*/
+
+
+#include "locmedia.h"
+#include "platform.h"
+#include "\sf\adaptation\beagleboard\omap3530\beagleboard\inc\variantmediadef.h"
+#include "beagle_medstaticrd.h"
+//#include "syborg.h"
+
+#define NVMEM1_DRIVENAME "STATICRD"
+#define NVMEM1_DRIVECOUNT 1
+#define NVMEM1_DRIVELIST 1
+#define NVMEM1_NUMMEDIA 1
+
+_LIT(KNVMemPddName, "Media.MEDTATICRD");
+_LIT(KNVMemDriveName,NVMEM1_DRIVENAME);
+
+class DPhysicalDeviceMediaStaticRD : public DPhysicalDevice
+	{
+public:
+	DPhysicalDeviceMediaStaticRD();
+public:
+	// Implementing the interface
+	virtual TInt Install();
+	virtual void GetCaps(TDes8& aDes) const;
+	virtual TInt Create(DBase*& aChannel, TInt aMediaId, const TDesC8* anInfo, const TVersion& aVer);
+	virtual TInt Validate(TInt aDeviceType, const TDesC8* anInfo, const TVersion& aVer);
+	virtual TInt Info(TInt aFunction, TAny* a1);
+	};
+								
+class DMediaDriverStaticRD : public DMediaDriver
+	{
+public:
+	DMediaDriverStaticRD(TInt aMediaId);
+public:
+	// Implementing the interface
+	virtual TInt Request(TLocDrvRequest& aRequest);
+	virtual void Disconnect(DLocalDrive* aLocalDrive, TThreadMessage* aMsg);
+	virtual TInt PartitionInfo(TPartitionInfo &anInfo);
+	virtual void NotifyPowerDown();
+	virtual void NotifyEmergencyPowerDown();
+public:
+	void CompleteRequest(TInt aReason);
+	TInt DoCreate(TInt aMediaId);
+	TInt Caps(TLocDrvRequest& aRequest);
+	TInt Read();
+	TInt Write();
+	TInt Format();
+	static void TransactionLaunchDfc(TAny* aMediaDriver);
+	void DoTransactionLaunchDfc();
+	static void SessionEndDfc(TAny* aMediaDriver);
+	void DoSessionEndDfc();
+	TUint32 GetNVMemSize( void );
+
+public:
+	TUint32 iLatestTransferSectorCount;
+	TDfc iSessionEndDfc;
+
+private:
+	TInt ContinueTransaction( TUint32 aTransactionSectorOffset, TUint32 aTransactionSectorCount, TUint32 aDirection );
+	static void Isr(TAny* aPtr);
+
+private:
+	TLocDrvRequest* iCurrentRequest;				// Current Request
+	Int64 iTotalLength;
+	Int64 iProsessedLength;
+	Int64 iPos;
+	TPhysAddr iTransferBufferPhys;
+	TUint8* iTransferBufferLin;
+	TUint8* iDiscBufferLin;
+	TUint32 iHead;
+	TUint32 iTail;
+	TUint32 iSplitted;
+	TUint32 iAlignmentOverhead;
+	TBool iReadModifyWrite;
+	TDfc iTransactionLaunchDfc;
+	};
+
+DPhysicalDeviceMediaStaticRD::DPhysicalDeviceMediaStaticRD()
+//
+// Constructor
+//
+	{
+	__DEBUG_PRINT(">DPhysicalDeviceMediaStaticRD::DPhysicalDeviceMediaStaticRD");
+	iUnitsMask=0x1;
+	iVersion=TVersion(KMediaDriverInterfaceMajorVersion,KMediaDriverInterfaceMinorVersion,KMediaDriverInterfaceBuildVersion);
+	}
+
+TInt DPhysicalDeviceMediaStaticRD::Install()
+//
+// Install the Internal NVMem PDD.
+//
+	{
+	__DEBUG_PRINT("DPhysicalDeviceMediaStaticRD::Install()");
+	return SetName(&KNVMemPddName);
+	}
+
+void DPhysicalDeviceMediaStaticRD::GetCaps(TDes8& /*aDes*/) const
+//
+// Return the media drivers capabilities.
+//
+	{
+	__DEBUG_PRINT("DPhysicalDeviceMediaStaticRD::GetCaps()");
+	}
+
+TInt DPhysicalDeviceMediaStaticRD::Create(DBase*& aChannel, TInt aMediaId, const TDesC8* /* anInfo */,const TVersion &aVer)
+//
+// Create an Internal Ram media driver.
+//
+	{
+	__DEBUG_PRINT("DPhysicalDeviceMediaStaticRD::Create()");
+	if (!Kern::QueryVersionSupported(iVersion,aVer))
+		return KErrNotSupported;
+	TInt r=KErrNoMemory;
+	DMediaDriverStaticRD* pD=new DMediaDriverStaticRD(aMediaId);
+	aChannel=pD;
+	if (pD)
+		{
+		r=pD->DoCreate(aMediaId);
+		}
+	if( r==KErrNone )
+		{
+		pD->OpenMediaDriverComplete(KErrNone);
+		}
+
+	return r;
+	}
+
+TInt DPhysicalDeviceMediaStaticRD::Validate(TInt aDeviceType, const TDesC8* /*anInfo*/, const TVersion& aVer)
+	{
+	__DEBUG_PRINT("DPhysicalDeviceMediaStaticRD::Validate()");
+	if (!Kern::QueryVersionSupported(iVersion,aVer))
+		return KErrNotSupported;
+	if (aDeviceType!=EFixedMedia1)
+		return KErrNotSupported;
+	return KErrNone;
+	}
+
+TInt DPhysicalDeviceMediaStaticRD::Info(TInt aFunction, TAny*)
+//
+// Return the priority of this media driver
+//
+	{
+	__DEBUG_PRINT("DPhysicalDeviceMediaStaticRD::Info()");
+	if (aFunction==EPriority)
+		return KMediaDriverPriorityNormal;
+	return KErrNotSupported;
+	}
+
+DMediaDriverStaticRD::DMediaDriverStaticRD(TInt aMediaId)
+//
+// Constructor.
+//
+	:	DMediaDriver(aMediaId),
+		iSessionEndDfc(DMediaDriverStaticRD::SessionEndDfc, this, 1),
+		iTransferBufferPhys(0),
+		iTransactionLaunchDfc(DMediaDriverStaticRD::TransactionLaunchDfc, this, KMaxDfcPriority)
+	{
+	__DEBUG_PRINT("DMediaDriverStaticRD::DMediaDriverStaticRD()");
+	}
+
+TInt DMediaDriverStaticRD::DoCreate(TInt /*aMediaId*/)
+//
+// Create the media driver.
+//
+	{
+	__DEBUG_PRINT(">DMediaDriverStaticRD::DoCreate");
+	TInt r = KErrNone; 
+	// Inform our size
+	Int64 size=GetNVMemSize()<<KDiskSectorShift;
+	if( size<=0 )
+		{
+		Kern::Fault("DMediaDriverStaticRD zero size nv memory array", 0);
+		}
+	SetTotalSizeInBytes(size);
+	// Some dfc initialization
+	if( r==KErrNone )
+		{
+		iSessionEndDfc.SetDfcQ( this->iPrimaryMedia->iDfcQ );
+		iTransactionLaunchDfc.SetDfcQ( this->iPrimaryMedia->iDfcQ );
+		}
+	// Create our piece of physically contiguous transfer buffer. 
+	r = Epoc::AllocPhysicalRam( KNVMemTransferBufferSize, iTransferBufferPhys );
+	if( r != KErrNone )
+		{
+		Kern::Fault("DMediaDriverStaticRD Allocate Ram %d",r);
+		}
+
+    DPlatChunkHw* bufChunk = NULL;
+    DPlatChunkHw* bufChunk2 = NULL;
+
+    // Create HW Memory Chunk
+    r = DPlatChunkHw::New( bufChunk, iTransferBufferPhys, KNVMemTransferBufferSize, EMapAttrUserRw | EMapAttrFullyBlocking );
+
+    if( r != KErrNone )
+        {
+        // Check Physical Memory
+        if( iTransferBufferPhys )
+			{
+            // Free Physical Memory
+            Epoc::FreePhysicalRam( iTransferBufferPhys, KNVMemTransferBufferSize );
+			}
+		Kern::Fault("DMediaDriverStaticRD error in creating transfer buffer", r);
+        }
+    
+
+    // Set Main Buffer Pointer
+    iTransferBufferLin = reinterpret_cast<TUint8*>(bufChunk->LinearAddress());
+
+    
+    
+    // Create HW Memory Chunk for drive image
+       r = DPlatChunkHw::New( bufChunk2, 0x81000000, 0x1000000, EMapAttrUserRw | EMapAttrFullyBlocking );
+       if( r != KErrNone )
+              {
+			   Kern::Fault("DMediaDriverStaticRD error in creating disc image linear address", r);
+              }
+            
+           
+       // Set Main Buffer Pointer
+       iDiscBufferLin = reinterpret_cast<TUint8*>(bufChunk2->LinearAddress());
+
+       
+  	// Inform "hardware" about the shared memory
+  	//WriteReg( KHwNVMemoryDevice, R_NVMEM_SHARED_MEMORY_BASE, iTransferBufferPhys );
+  	//WriteReg( KHwNVMemoryDevice, R_NVMEM_SHARED_MEMORY_SIZE, KNVMemTransferBufferSize );
+  	//WriteReg( KHwNVMemoryDevice, R_NVMEM_ENABLE, 1 );
+
+	// Set up interrupt service
+  	//r = Interrupt::Bind( EIntNVMemoryDevice, Isr, this );
+  	//Interrupt::Enable( EIntNVMemoryDevice );
+
+
+	__DEBUG_PRINT("<DMediaDriverStaticRD::DoCreate %d", r);
+	return(r);
+	}
+
+TInt DMediaDriverStaticRD::Request(TLocDrvRequest& m)
+	{
+	TInt request=m.Id();
+	__DEBUG_PRINT(">DMediaDriverStaticRD::Request %d",request);
+	TInt r=KErrNone;
+	
+	// Requests that can be handled synchronously
+	if( request == DLocalDrive::ECaps ) 
+		{
+		r=Caps(m);
+		return r;
+		}
+
+	// All other requests must be deferred if a request is currently in progress
+	if (iCurrentRequest)
+		{
+		// a request is already in progress, so hold on to this one
+		r = KMediaDriverDeferRequest;
+		}
+	else
+		{
+
+		iCurrentRequest=&m;
+		iProsessedLength = 0;
+		iHead = 0;
+		iTail = 0;
+		iSplitted = 0;
+		iAlignmentOverhead = 0;
+
+		iPos = m.Pos();
+		iTotalLength = m.Length();
+
+
+		__DEBUG_PRINT(">DMediaDriverStaticRD::Request pos:0x%lx len:0x%lx", iPos, iTotalLength);
+		if( iTotalLength<0 || iPos<0 )
+			{
+			Kern::Fault("DMediaDriverStaticRD::Request: illegal access!", 0);
+			}
+		// Handle unaligned operations
+		iHead = iPos % KDiskSectorSize;
+		TUint32 tailAlignment = ((iHead + iTotalLength) % KDiskSectorSize);
+		if( tailAlignment )
+			{
+			iTail = KDiskSectorSize - tailAlignment;
+			}
+
+		iSplitted = (iTotalLength + iHead + iTail) / KNVMemTransferBufferSize;
+
+		__DEBUG_PRINT(">DMediaDriverStaticRD::Request head: %d tail: %d splitted: %d\n", iHead, iTail, iSplitted );
+		__DEBUG_PRINT(">DMediaDriverStaticRD::Request partitionlen: %lx", iCurrentRequest->Drive()->iPartitionLen );
+
+		if( (iTotalLength + iPos) > iCurrentRequest->Drive()->iPartitionLen )
+			{
+			Kern::Fault("DMediaDriverStaticRD::Request: Access over partition boundary!", 0);
+			}
+		if( iTotalLength > KMaxTInt32 )
+			{
+			Kern::Fault("DMediaDriverStaticRD::Request: Access length overflow!", 0);
+			}
+		switch (request)
+			{
+			case DLocalDrive::ERead:
+			case DLocalDrive::EWrite:
+			case DLocalDrive::EFormat:
+				__DEBUG_PRINT("DMediaDriverStaticRD::Request iTransactionLaunchDfc.Enque()>");
+				iTransactionLaunchDfc.Enque();
+				__DEBUG_PRINT("DMediaDriverStaticRD::Request iTransactionLaunchDfc.Enque()<");
+			break;
+			case DLocalDrive::EEnlarge:
+			case DLocalDrive::EReduce:
+			default:
+				r=KErrNotSupported;
+			break;
+			}
+		}
+
+	__DEBUG_PRINT("<DMediaDriverStaticRD::Request %d",r);
+	return r;
+	}
+
+void DMediaDriverStaticRD::CompleteRequest(TInt aReason)
+//
+// completes the request which is being currently processed
+//
+	{
+	__DEBUG_PRINT("DMediaDriverStaticRD::CompleteRequest() reason: %d", aReason);
+	TLocDrvRequest* pR=iCurrentRequest;
+	if (pR)
+		{
+		iCurrentRequest=NULL;
+		DMediaDriver::Complete(*pR,aReason);
+		}
+	}
+
+void DMediaDriverStaticRD::Disconnect( DLocalDrive* aLocalDrive, TThreadMessage* aMsg )
+	{
+	__DEBUG_PRINT(">DMediaDriverStaticRD::Disconnect()");
+	// Complete using the default implementation
+	DMediaDriver::Disconnect(aLocalDrive, aMsg);
+	__DEBUG_PRINT("<DMediaDriverStaticRD::Disconnect()");
+	}
+
+void DMediaDriverStaticRD::NotifyPowerDown()
+	{
+	__DEBUG_PRINT("DMediaDriverStaticRD::NotifyPowerDown()");
+	// no action required
+	}
+
+void DMediaDriverStaticRD::NotifyEmergencyPowerDown()
+	{
+	__DEBUG_PRINT("DMediaDriverStaticRD::NotifyEmergencyPowerDown()");
+	// no action required
+	}
+
+TInt DMediaDriverStaticRD::Caps(TLocDrvRequest& m)
+	{
+	__DEBUG_PRINT("DMediaDriverStaticRD::Caps()");
+	TLocalDriveCapsV6& caps=*(TLocalDriveCapsV6*)m.RemoteDes();
+	caps.iType=EMediaHardDisk;
+	caps.iConnectionBusType=EConnectionBusInternal;
+	caps.iDriveAtt=KDriveAttLocal|KDriveAttInternal;
+	caps.iMediaAtt=KMediaAttFormattable;
+	caps.iFileSystemId=KDriveFileSysFAT;
+	caps.iPartitionType=KPartitionTypeFAT16;
+	caps.iSize=m.Drive()->iPartitionLen;
+	caps.iHiddenSectors=0;
+	caps.iEraseBlockSize = KNVMemTransferBufferSize; 
+	caps.iBlockSize=KDiskSectorSize;
+	caps.iMaxBytesPerFormat = KNVMemTransferBufferSize;
+
+	return KErrCompletion;									
+	}
+
+TInt DMediaDriverStaticRD::Read()
+	{
+	__DEBUG_PRINT(">DMediaDriverStaticRD::Read() pos: %lx, size: %lx", iPos, iTotalLength);
+	// Set our sector offset
+	TUint32 transactionSectorOffset = (TUint32)(iPos / KDiskSectorSize); 
+	TUint32 transactionLength = 0;
+	TUint32 transactionDirection = NVMEM_TRANSACTION_READ;
+	// Do we have an operation longer than our shared memory?
+	if( iSplitted > 0 )
+		{
+		transactionLength = KNVMemTransferBufferSize;
+		}
+	else
+		{
+		// Do the whole operation in one go since we have enough room in our memory
+		transactionLength = I64LOW(iTotalLength);
+		// Read the "broken" tail sector
+		if( iTail )
+			{
+			transactionLength += iTail;
+			iAlignmentOverhead += iTail;
+			}
+		}
+	// Read the "broken" head sector
+	if( iHead > 0 )
+		{
+		transactionLength += iHead;
+		iAlignmentOverhead += iHead;
+		}
+
+	// We should be ok to continue
+	ContinueTransaction( transactionSectorOffset, transactionLength/KDiskSectorSize, transactionDirection );
+	__DEBUG_PRINT("<DMediaDriverStaticRD::Read()");
+	return KErrNone;
+	}
+
+TInt DMediaDriverStaticRD::Write()
+	{
+	__DEBUG_PRINT("DMediaDriverStaticRD::Write() pos: 0x%lx, size: 0x%lx", iPos, iTotalLength);
+	TInt r = KErrNone;
+	// Set our sector offset
+	TUint32 transactionSectorOffset = (TUint32)(iPos / KDiskSectorSize); 
+	TUint32 transactionLength = 0;
+	TUint32 transactionDirection = NVMEM_TRANSACTION_WRITE;
+	// Do we have an operation longer than our shared memory?
+	if( iSplitted > 0 )
+		{
+		transactionLength = KNVMemTransferBufferSize;
+		}
+	else
+		{
+		// Do the whole operation in one go since we have enough room in our memory
+		transactionLength = I64LOW(iTotalLength);
+		if( iTail )
+			{
+			iReadModifyWrite = ETrue;
+			// Read the "broken" tail sector
+			transactionLength += iTail;
+			iAlignmentOverhead += iTail;
+			}
+		}
+	// Is there a need to read modify write the "broken" head sector of the operation
+	if( iHead > 0 )
+		{
+		iReadModifyWrite = ETrue;
+		// If splitted operation we only need the broken sector
+		if( iSplitted > 0 )
+			{
+			transactionLength = KDiskSectorSize;
+			iAlignmentOverhead += iHead;
+			}
+		else
+			{
+			// Read the "broken" head sector in addition to everything else
+			transactionLength += iHead;
+			iAlignmentOverhead += iHead;
+			}
+		}
+	
+	// Was there a need to read-modify before writing
+	if( iReadModifyWrite )
+		{
+		transactionDirection = NVMEM_TRANSACTION_READ;
+		}
+	else
+		{
+		// Handle format here
+		if( iCurrentRequest->Id() == DLocalDrive::EFormat )
+			{
+			// Not much handling just flow through since we have filled the shared memory with zeroes already
+			}
+		else
+			{
+			// Read from client
+			TPtr8 targetDescriptor(iTransferBufferLin, transactionLength);
+			r = iCurrentRequest->ReadRemote(&targetDescriptor,0);
+			}
+		}
+	
+	// We should be ok to continue
+	ContinueTransaction( transactionSectorOffset, transactionLength/KDiskSectorSize, transactionDirection );
+
+	return r;
+	}
+
+
+TInt DMediaDriverStaticRD::Format()
+	{
+	__DEBUG_PRINT("DMediaDriverStaticRD::Format() pos: 0x%lx, size: 0x%lx", iPos, iTotalLength);
+	memset( iTransferBufferLin, 0x00, KNVMemTransferBufferSize );
+	// Stop the nonsense here. Write operations should be used for partial sector data removal operations
+	if( iHead > 0 || iTail > 0 )
+		{
+		Kern::Fault("DMediaDriverStaticRD::Format: alignment violation!", 0);
+		}
+	Write();
+//	DoTransaction( m, NVMEM_TRANSACTION_WRITE );
+	return KErrNone;
+	}
+
+TInt DMediaDriverStaticRD::ContinueTransaction( TUint32 aTransactionSectorOffset, TUint32 aTransactionSectorCount, TUint32 aTransactionDirection )
+	{
+	__DEBUG_PRINT("DMediaDriverStaticRD::ContinueTransaction() sectoroffset: %d, sectorcount: %d, direction: %d", aTransactionSectorOffset, aTransactionSectorCount, aTransactionDirection);
+	if( aTransactionDirection != NVMEM_TRANSACTION_UNDEFINED )
+		{
+	  	//WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_OFFSET, aTransactionSectorOffset );
+	  	//WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_SIZE, aTransactionSectorCount );
+	  	//WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_DIRECTION, aTransactionDirection );
+	  	//WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_EXECUTE, aTransactionDirection );
+		if ( aTransactionDirection == NVMEM_TRANSACTION_WRITE )
+		{
+			memcpy( (TAny *)(iDiscBufferLin+(aTransactionSectorOffset<<9)), iTransferBufferLin, aTransactionSectorCount*512 );
+		}
+		else if ( aTransactionDirection == NVMEM_TRANSACTION_READ )
+		{
+			memcpy( iTransferBufferLin, (TAny *)(iDiscBufferLin+(aTransactionSectorOffset<<9)), aTransactionSectorCount*512 );
+		}
+		iLatestTransferSectorCount = aTransactionSectorCount;
+		Isr(this); // terrible hack, we've yransferred all the sectors and now we pretend to generate an interrupt
+		}
+	else
+		{
+		Kern::Fault("DMediaDriverStaticRD::ContinueTransaction: Undefined transaction!", 0);
+		}
+	return KErrNone;
+	}
+
+
+TInt DMediaDriverStaticRD::PartitionInfo(TPartitionInfo& anInfo)
+//
+// Return partition information on the media.
+//
+	{
+	__DEBUG_PRINT("DMediaDriverStaticRD::PartitionInfo()");
+	anInfo.iPartitionCount=1;
+	anInfo.iEntry[0].iPartitionBaseAddr=0;
+	anInfo.iEntry[0].iPartitionLen=anInfo.iMediaSizeInBytes=TotalSizeInBytes();
+	anInfo.iEntry[0].iPartitionType=KPartitionTypeFAT16;
+	return KErrCompletion;
+	}
+
+void DMediaDriverStaticRD::TransactionLaunchDfc(TAny* aMediaDriver)
+	{
+	static_cast<DMediaDriverStaticRD*>(aMediaDriver)->DoTransactionLaunchDfc();
+	}
+
+void DMediaDriverStaticRD::DoTransactionLaunchDfc()
+	{
+	__DEBUG_PRINT(">DMediaDriverStaticRD::DoTransactionLaunchDfc()");
+	TInt request = iCurrentRequest->Id();
+	TInt r(KErrNone);
+	switch (request)
+		{
+		case DLocalDrive::ERead:
+			r=Read();
+		break;
+		case DLocalDrive::EWrite:
+			r=Write();
+		break;
+		case DLocalDrive::EFormat:
+			r=Format();
+		break;
+		case DLocalDrive::EEnlarge:
+		case DLocalDrive::EReduce:
+		default:
+			r=KErrNotSupported;
+		break;
+		}
+	if( r != KErrNone )
+		{
+		// TODO some proper error handling here
+		}
+	__DEBUG_PRINT("<MediaDriverStaticRD::DoTransactionLaunchDfc %d",r);
+	}
+
+void DMediaDriverStaticRD::SessionEndDfc(TAny* aMediaDriver)
+	{
+	static_cast<DMediaDriverStaticRD*>(aMediaDriver)->DoSessionEndDfc();
+	}
+
+void DMediaDriverStaticRD::DoSessionEndDfc()
+	{
+	__DEBUG_PRINT(">DMediaDriverStaticRD::DoSessionEndDfc()");
+	TInt r = KErrNone;
+	// Check that we have a request in process
+	if( iCurrentRequest )
+		{
+		// Transaction variables
+		TUint32 transactionSectorOffset(0);
+		TUint32 transactionLength(0);
+		TUint32 transactionDirection( NVMEM_TRANSACTION_UNDEFINED );
+		// How much did we actually transfer? 
+		TUint32 latestTransferSize = (iLatestTransferSectorCount * KDiskSectorSize);
+		__DEBUG_PRINT("DMediaDriverStaticRD::DoSessionEndDfc() latestTransferSize: %d", latestTransferSize );
+		// Subtract alignment overhead
+		latestTransferSize = latestTransferSize - iAlignmentOverhead;
+		// For decision whether the buffer is ready for operation already
+		TBool bufferReady(EFalse);
+		// For decision whether we have finished the latest request
+		TBool sessionComplete(EFalse);
+
+		// Was there a read-modify-write (RWM) for which we need to do some buffer manipulation before proceeding?
+		// Note that in case of format we triggered to alignment violation in earlier method already and can not enter to following 
+		// condition when there is a format operation going on
+		if( iReadModifyWrite )
+			{
+			bufferReady = ETrue;
+			iReadModifyWrite = EFalse;
+			// Was it a splitted operation for which we only need to take care of the broken head sector.
+			if( iSplitted > 0 )
+				{
+				// We have a sector here here filled with data from mass memory. Modify with client data.
+				__DEBUG_PRINT("DMediaDriverStaticRD::DoSessionEndDfc() readremote splitted: %d head: %d", latestTransferSize, iHead );
+				TPtr8 targetDescriptor(&iTransferBufferLin[iHead], KNVMemTransferBufferSize - iHead);
+				r = iCurrentRequest->ReadRemote(&targetDescriptor,0);
+				}
+			// Else we need to take care of both head and tail
+			else
+				{
+				// We have a piece of data read from mass memory. Modify with client data.
+				__DEBUG_PRINT("DMediaDriverStaticRD::DoSessionEndDfc() readremote: %d head: %d", I64LOW(iTotalLength - iProsessedLength), iHead );
+				TPtr8 targetDescriptor(&iTransferBufferLin[iHead], I64LOW(iTotalLength - iProsessedLength));
+				r = iCurrentRequest->ReadRemote(&targetDescriptor,0);
+//				latestTransferSize -= (KDiskSectorSize - iTail);
+				iTail = 0;
+				}
+			}
+		else
+			{
+			// Overhead is processed when we enter here
+			iAlignmentOverhead = 0;
+			// Update position
+			iPos += latestTransferSize;
+			// Save the information on how many bytes we transferred already
+			iProsessedLength += latestTransferSize; 
+			// Update the splitted information. We don't take head into account here anymore since it is already taken care of
+			iSplitted = (iTotalLength - iProsessedLength + iTail) / KNVMemTransferBufferSize;
+			// Check if we have done already
+			if( iProsessedLength >= iTotalLength )
+				{
+				// If this was the final transfer for this request let's take tail into account as well (if not taken already)
+				// iProsessedLength -= iTail;
+				// latestTransferSize -= iTail;
+				if( iProsessedLength > iTotalLength )
+					{
+					Kern::Fault("DMediaDriverStaticRD: Illegal transfer operation!", 0);
+					}
+				sessionComplete = ETrue;
+				}
+			}
+
+		TInt request = iCurrentRequest->Id();
+
+		// Set our sector offset
+		transactionSectorOffset = (TUint32)(iPos / KDiskSectorSize); 
+		
+		if( bufferReady )
+			{
+			// Write as much as we read in RMW operation
+			transactionLength = (iLatestTransferSectorCount * KDiskSectorSize);
+			}
+		else
+			{
+			// Do we have an operation longer than our shared memory?
+			if( iSplitted > 0 )
+				{
+				transactionLength = KNVMemTransferBufferSize;
+				}
+			else
+				{
+				// Do the whole operation in one go since we have enough room in our memory
+				transactionLength = I64LOW(iTotalLength - iProsessedLength);
+				// Read the "broken" tail sector
+				if( iTail > 0 && request == DLocalDrive::EWrite )
+					{
+					iReadModifyWrite = ETrue;
+					// Read the "broken" tail sector
+					transactionLength += iTail;
+	   				iAlignmentOverhead = iTail;
+	   				}
+				}
+			}
+		
+		// Was there a need to read-modify before writing
+		if( iReadModifyWrite )
+			{
+			transactionDirection = NVMEM_TRANSACTION_READ;
+			}
+		else
+			{
+			if( request == DLocalDrive::ERead )
+				{
+				transactionDirection = NVMEM_TRANSACTION_READ;
+				// Write to client
+				__DEBUG_PRINT("DMediaDriverStaticRD::DoSessionEndDfc() WriteRemote: %d head: %d", latestTransferSize, iHead );
+				TPtrC8 sourceDescriptor(&iTransferBufferLin[iHead], latestTransferSize);
+				r = iCurrentRequest->WriteRemote( &sourceDescriptor, 0 );
+				}
+			// Head is processed
+			iHead = 0;
+			if( request == DLocalDrive::EWrite && !sessionComplete )
+				{
+				transactionDirection = NVMEM_TRANSACTION_WRITE;
+				if( bufferReady )
+					{
+					// Actually no need for any actions here
+					}
+				else
+					{
+					// Prepare a buffer for transfer
+					__DEBUG_PRINT("DMediaDriverStaticRD::DoSessionEndDfc() ReadRemote: %d head: %d", latestTransferSize, iHead );
+					TPtr8 targetDescriptor(iTransferBufferLin, transactionLength);
+					r = iCurrentRequest->ReadRemote(&targetDescriptor,0);
+					}
+				}
+			if( request == DLocalDrive::EFormat )
+				{
+				transactionDirection = NVMEM_TRANSACTION_WRITE;
+				}
+			}
+		if( sessionComplete )
+			{
+			CompleteRequest( r );
+			}
+		else
+			{
+			ContinueTransaction( transactionSectorOffset, transactionLength/KDiskSectorSize, transactionDirection );
+			}
+		}
+	else
+		{
+		// Let's just flow through for now
+		}
+
+	__DEBUG_PRINT("<DMediaDriverStaticRD::DoSessionEndDfc()" );
+	}
+
+
+TUint32  DMediaDriverStaticRD::GetNVMemSize( void )
+	{
+	__DEBUG_PRINT("DMediaDriverStaticRD::GetNVMemSize()");
+	TUint32 sizeInSectors = 32768;//ReadReg( KHwNVMemoryDevice, R_NVMEM_NV_MEMORY_SIZE );
+	return sizeInSectors; 
+	}
+
+void DMediaDriverStaticRD::Isr(TAny* aPtr)
+	{
+	__DEBUG_PRINT(">DMediaDriverStaticRD::Isr");
+
+    DMediaDriverStaticRD* nvMem = reinterpret_cast<DMediaDriverStaticRD*>(aPtr);
+
+	// Save the amount of transferred sectors. This clears the interrupt from HW as well
+	//nvMem->iLatestTransferSectorCount = ReadReg( KHwNVMemoryDevice, R_NVMEM_STATUS );
+
+	// Clear from framework
+	//Interrupt::Clear( EIntNVMemoryDevice );
+
+	nvMem->iSessionEndDfc.Add();
+	}
+
+
+DECLARE_EXTENSION_PDD()
+	{
+	__DEBUG_PRINT(">MediaDriverStaticRD create device");
+	return new DPhysicalDeviceMediaStaticRD;
+	}
+
+static const TInt NVMemDriveNumbers[NVMEM1_DRIVECOUNT]={NVMEM1_DRIVELIST};	
+
+DECLARE_STANDARD_EXTENSION()
+	{
+	__DEBUG_PRINT("Registering STATICRD drive");
+	TInt r=KErrNoMemory;
+
+	DPrimaryMediaBase* pM=new DPrimaryMediaBase;
+
+	TDynamicDfcQue* NVMemoryDfcQ;
+	 
+	r = Kern::DynamicDfcQCreate( NVMemoryDfcQ, KNVMemDfcThreadPriority, KNVMemDriveName );
+
+	if( r == KErrNone )
+		{
+		pM->iDfcQ = NVMemoryDfcQ;
+		}
+	else
+		{
+		__DEBUG_PRINT("NVMEM DFCQ initialization failed");
+		}
+
+	if (pM)
+
+		{
+		r=LocDrv::RegisterMediaDevice(EFixedMedia1,NVMEM1_DRIVECOUNT,&NVMemDriveNumbers[0],pM,NVMEM1_NUMMEDIA,KNVMemDriveName);
+		}
+
+	pM->iMsgQ.Receive();
+
+	__DEBUG_PRINT("Registering NVMEM drive - return %d",r);
+
+	return r;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omap3530/beagle_drivers/medstaticrd/beagle_medstaticrd.h	Tue Jul 27 15:31:26 2010 +0100
@@ -0,0 +1,61 @@
+/*
+* Copyright (c) 2010 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:
+* Gareth Long - Symbian Foundation
+*
+* Description: Minimalistic non volatile memory driver
+*
+*/
+
+#ifndef _BEAGLE_STATICRD_H
+#define _BEAGLE_STATICRD_H
+
+#include <kpower.h>
+#include <e32keys.h>
+//#include <system.h>
+
+//#define DEBUG_MEDSTATICRD
+#ifdef DEBUG_MEDSTATICRD
+#define __DEBUG_PRINT(format...)    Kern::Printf(format)
+#else
+#define __DEBUG_PRINT(format...)    __KTRACE_OPT(KLOCDRV,Kern::Printf(format))
+#endif
+
+#define R_NVMEM_ID                                0x0000
+#define R_NVMEM_TRANSACTION_OFFSET                0x0004
+#define R_NVMEM_TRANSACTION_SIZE                  0x0008
+#define R_NVMEM_TRANSACTION_DIRECTION             0x000c
+#define R_NVMEM_TRANSACTION_EXECUTE               0x0010
+#define R_NVMEM_SHARED_MEMORY_BASE                0x0014
+#define R_NVMEM_NV_MEMORY_SIZE                    0x0018
+#define R_NVMEM_SHARED_MEMORY_SIZE                0x001c
+#define R_NVMEM_STATUS                            0x0020
+#define R_NVMEM_ENABLE                            0x0024
+#define R_NVMEM_LASTREG                           0x0028  // not a register, address of last register
+
+#define NVMEM_TRANSACTION_UNDEFINED 0
+#define NVMEM_TRANSACTION_READ 1
+#define NVMEM_TRANSACTION_WRITE 2
+
+// 512 Byte sectors
+const TInt KDiskSectorShift	= 9;
+const TInt KDiskSectorSize	= 0x200;
+
+// Dfc thread priority 
+const TInt KNVMemDfcThreadPriority = 24;
+
+// Transfer buffer size 256kBytes 
+const TInt KNVMemTransferBufferSize = 0x40000;
+// Transfer buffer size in sectors
+const TInt KNVMemTransferBufferSectorCount = KNVMemTransferBufferSize/KDiskSectorSize;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omap3530/beagle_drivers/medstaticrd/bld.inf	Tue Jul 27 15:31:26 2010 +0100
@@ -0,0 +1,23 @@
+// 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:
+// Gareth Long - Symbian Foundation
+//
+// Description:
+// omap3530/beagle_drivers/medstaticrd/bld.inf
+//
+
+PRJ_PLATFORMS
+ARMV5
+
+PRJ_MMPFILES
+medstaticrd
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omap3530/beagle_drivers/medstaticrd/medstaticrd.mmp	Tue Jul 27 15:31:26 2010 +0100
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2010 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:
+* Gareth Long - Symbian Foundation
+*
+* Description:
+*
+*/
+
+#include "beagle/variant.mmh"
+#include "kernel/kern_ext.mmh"
+
+TARGET			VariantTarget(medstaticrd,pdd)
+TARGETTYPE		pdd
+//TARGETTYPE		kext
+ROMTARGET		staticrd.dll
+
+systeminclude		+/include/drivers
+SYMBIAN_BASE_SYSTEMINCLUDE(drivers)
+SYSTEMINCLUDE	AsspNKernIncludePath
+
+SOURCEPATH		.
+SOURCE			beagle_medstaticrd.cpp
+
+//LIBRARY			ekern.lib
+//LIBRARY			AsspTarget(PlatformLib)
+LIBRARY			elocd.lib
+
+//NOEXPORTLIBRARY
+
+//DEFFILE			../e32/~/empty.def
+//DEFFILE			./~/exkey.def
+
+//NOSTRICTDEF
+
+epocallowdlldata
+
+UID				0x100039cf 0x100000db
+VENDORID        0x70000001
+
+CAPABILITY		all
--- a/omap3530/beagleboard/bld.inf	Thu Jul 01 17:46:13 2010 +0100
+++ b/omap3530/beagleboard/bld.inf	Tue Jul 27 15:31:26 2010 +0100
@@ -31,6 +31,8 @@
 rom/header.iby		../rom/beagle/
 rom/kernel.iby		../rom/beagle/
 rom/test.iby			../rom/beagle/
+rom/estart.txt		../rom/beagle/
+rom/drive_c.img		../../nvmemory/
 
 PRJ_MMPFILES
 src/vbeagle
--- a/omap3530/beagleboard/rom/base_beagle.iby	Thu Jul 01 17:46:13 2010 +0100
+++ b/omap3530/beagleboard/rom/base_beagle.iby	Tue Jul 27 15:31:26 2010 +0100
@@ -102,14 +102,19 @@
 //extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_beagle_resman.pdd					\sys\bin\resman.pdd
 extension[VARID]=KERNEL_DIR\BUILD_DIR\resman.ldd							\sys\bin\resman.ldd
 
+extension[VARID]=	KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_medstaticrd.pdd		\sys\bin\medstaticrd.pdd
+
 extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_omap3530_i2c.dll			\sys\bin\i2c.dll
 #include <../omapshared/tps65950.iby>
 
+#ifdef SYMBIAN_BASE_USE_GCE
+extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_beagle_lcd_gce.dll	\sys\bin\lcd.dll
+device[VARID]=KERNEL_DIR\DEBUG_DIR\display.ldd			\sys\bin\display0.ldd
+#file=ABI_DIR\DEBUG_DIR\_beagle_ekdata.dll				\sys\bin\ekdata.dll
+#else
 #ifdef TSHELL_SERIAL
 	//Use VT100 Over Serial
 #	define EDISP_DRV	\EDISP_VT100.DLL
-	device[VARID]=KERNEL_DIR\BUILD_DIR\_omap3530_EUART.PDD				\sys\bin\euart.pdd
-	device[VARID]=KERNEL_DIR\BUILD_DIR\ECOMM.LDD						\sys\bin\ecomm.ldd
 #else
 	extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_beagle_lcd.dll				\sys\bin\lcd.dll
 #	ifdef TSHELL_SERIALMOUSE
@@ -118,9 +123,13 @@
 //		extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_omap3530_serialkeyboard.DLL	\sys\bin\ekeyb.dll
 #	endif
 #endif
+#endif //SYMBIAN_BASE_USE_GCE
+
+device[VARID]=KERNEL_DIR\BUILD_DIR\_omap3530_EUART.PDD				\sys\bin\euart.pdd
+device[VARID]=KERNEL_DIR\BUILD_DIR\ECOMM.LDD						\sys\bin\ecomm.ldd
 extension[VARID]=KERNEL_DIR\BUILD_DIR\elocd.ldd								\sys\bin\elocd.ldd
 extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_beagle_medint.pdd					\sys\bin\medint.pdd
-device[VARID]	=KERNEL_DIR\BUILD_DIR\pipelib.ldd							\sys\bin\pipelib.ldd
+//device[VARID]	=KERNEL_DIR\BUILD_DIR\pipelib.ldd							\sys\bin\pipelib.ldd // Removed for clash in 3.0.0
 //device[VARID]	=KERNEL_DIR\BUILD_DIR\minkda.ldd							\sys\bin\minkda.ldd
 extension[VARID]=KERNEL_DIR\BUILD_DIR\exstart.dll							\sys\bin\exstart.dll
 //extension[VARID]=\epoc32\release\ARMV5\BUILD_DIR\_beagle_led.dll						\sys\bin\led.dll
Binary file omap3530/beagleboard/rom/drive_c.img has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omap3530/beagleboard/rom/estart.txt	Tue Jul 27 15:31:26 2010 +0100
@@ -0,0 +1,7 @@
+#
+# Beagle RAM Disk ESTART.TXT
+#
+
+D:  0  ELOCAL  FAT   0       FS_FORMAT_COLD,FS_SYNC_DRIVE       # IRAM
+C:  1  ELOCAL  FAT   0       FS_FORMAT_CORRUPT,FS_NOT_RUGGED    # "Persistent" RAM disk
+
--- a/omap3530/buildscripts/cleanbuild.mbc	Thu Jul 01 17:46:13 2010 +0100
+++ b/omap3530/buildscripts/cleanbuild.mbc	Tue Jul 27 15:31:26 2010 +0100
@@ -35,6 +35,7 @@
 //..\beagle_drivers\prm
 ..\beagle_drivers\serialmouse
 ..\beagle_drivers\usbv
+..\beagle_drivers\medstaticrd
 ..\kernel
 
 
--- a/omap3530/buildscripts/reallycleanbuild.mbc	Thu Jul 01 17:46:13 2010 +0100
+++ b/omap3530/buildscripts/reallycleanbuild.mbc	Tue Jul 27 15:31:26 2010 +0100
@@ -39,6 +39,7 @@
 //.\beagle_drivers\prm
 ..\beagle_drivers\serialmouse
 ..\beagle_drivers\usbv
+..\beagle_drivers\medstaticrd
 ..\kernel
 
 
--- a/omap3530/buildscripts/rebuild.mbc	Thu Jul 01 17:46:13 2010 +0100
+++ b/omap3530/buildscripts/rebuild.mbc	Tue Jul 27 15:31:26 2010 +0100
@@ -33,6 +33,7 @@
 //.\beagle_drivers\prm
 ..\beagle_drivers\serialmouse
 ..\beagle_drivers\usbv
+..\beagle_drivers\medstaticrd
 ..\kernel