Merge in tip of phonesim-integ branch, to get svpframebuffer and some other stuff?
authorWilliam Roberts <williamr@symbian.org>
Sat, 27 Feb 2010 19:18:04 +0000
changeset 44 72a7468afdd4
parent 40 50cddb1eb3af (current diff)
parent 39 a65b6baedd2e (diff)
child 45 01c1ffcc4fca
Merge in tip of phonesim-integ branch, to get svpframebuffer and some other stuff?
baseport/syborg/bld.inf
--- a/baseport/syborg/bld.inf	Fri Jan 08 12:04:26 2010 +0000
+++ b/baseport/syborg/bld.inf	Sat Feb 27 19:18:04 2010 +0000
@@ -85,6 +85,8 @@
 svpsnapdriver/svpsnapdriver
 svpsnapdriver/snapapp
 
+//NGA framebuffer
+svpframebuffer/svpframebuffer
 
 //Add Sound Driver
 soundsc\soundsc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/svpframebuffer/svpframebuffer.cpp	Sat Feb 27 19:18:04 2010 +0000
@@ -0,0 +1,1055 @@
+/*
+* 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: Minimalistic frame buffer driver
+*
+*/
+#include <videodriver.h>
+#include "platform.h"
+#include <nkern.h>
+#include <kernel/kernel.h>
+#include <kernel/kern_priv.h>
+#include <kernel/kpower.h>
+
+#include <syborg_priv.h>
+#include "svpframebuffer.h"
+
+DLcdPowerHandler	*  DLcdPowerHandler::pLcd			= NULL;
+
+TPhysAddr Syborg::VideoRamPhys;
+TPhysAddr Syborg::VideoRamPhysSecure;		// Secure display memory
+
+TPhysAddr TSyborg::VideoRamPhys()
+{
+  __KTRACE_OPT(KEXTENSION,Kern::Printf("TSyborg::VideoRamPhys: VideoRamPhys=0x%x", Syborg::VideoRamPhys));
+  return Syborg::VideoRamPhys;
+}
+
+TPhysAddr TSyborg::VideoRamPhysSecure()
+{
+  return Syborg::VideoRamPhysSecure;
+}
+
+LOCAL_C TInt DoHalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
+{
+  DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr;
+  return pH->HalFunction(aFunction,a1,a2);
+}
+
+static void rxMsg(TAny* aPtr)
+{
+  DLcdPowerHandler& h=*(DLcdPowerHandler*)aPtr;
+  TMessageBase* pM = h.iMsgQ.iMessage;
+  if(pM)
+	h.HandleMsg(pM);
+}
+
+static void power_up_dfc(TAny* aPtr)
+{
+  ((DLcdPowerHandler*)aPtr)->PowerUpDfc();
+}
+
+void power_down_dfc(TAny* aPtr)
+{
+  ((DLcdPowerHandler*)aPtr)->PowerDownDfc();
+}
+
+void DLcdPowerHandler::DisplayOn()
+{ 
+  PowerUpLcd(iSecureDisplay);
+  iDisplayOn = ETrue;
+}
+
+void DLcdPowerHandler::DisplayOff()
+{
+  PowerDownLcd();
+  iDisplayOn = EFalse;
+}
+
+void DLcdPowerHandler::SwitchDisplay(TBool aSecure)
+ {
+   if(aSecure)
+	 {
+	   if(!iSecureDisplay)
+		 {
+		   DisplayOff();
+		   iSecureDisplay = ETrue;
+		   DisplayOn();
+		 }
+	 }
+   else
+	 {
+	   if(iSecureDisplay)
+		 {
+		   DisplayOff();
+		   iSecureDisplay = EFalse;
+		   DisplayOn();
+		 }
+	 }
+ }
+
+void DLcdPowerHandler::PowerUpDfc()
+{
+  DisplayOn();
+  PowerUpDone();
+}
+
+void DLcdPowerHandler::PowerDownDfc()
+{
+  DisplayOff();
+  PowerDownDone();
+}
+
+void DLcdPowerHandler::PowerDown(TPowerState)
+{
+  iPowerDownDfc.Enque();
+}
+
+void DLcdPowerHandler::PowerUp()
+{
+  iPowerUpDfc.Enque();
+}
+
+void DLcdPowerHandler::PowerUpLcd(TBool aSecure)
+{
+#if 1
+  WriteReg(iPortAddr, FB_ENABLED, 0);
+  WriteReg(iPortAddr, FB_BASE, aSecure ? iSecurevRamPhys : ivRamPhys);
+  WriteReg(iPortAddr, FB_WIDTH, iVideoInfo.iSizeInPixels.iWidth);
+  WriteReg(iPortAddr, FB_BLANK, 0);
+  WriteReg(iPortAddr, FB_BPP, 32);
+  WriteReg(iPortAddr, FB_COLOR_ORDER, 0);
+  WriteReg(iPortAddr, FB_BYTE_ORDER, 0);
+  WriteReg(iPortAddr, FB_PIXEL_ORDER, 0);
+  WriteReg(iPortAddr, FB_INT_MASK, 0);
+  WriteReg(iPortAddr, FB_ENABLED, 1);
+  WriteReg(iPortAddr, FB_HEIGHT, iVideoInfo.iSizeInPixels.iHeight);
+#endif
+}
+
+void DLcdPowerHandler::PowerDownLcd()
+{
+  WriteReg(iPortAddr, FB_BLANK, 1);
+}
+
+DLcdPowerHandler::DLcdPowerHandler()
+	:	DPowerHandler(KLitLcd),
+		iMsgQ(rxMsg,this,NULL,1),
+		iPowerUpDfc(&power_up_dfc,this,6),
+		iPowerDownDfc(&power_down_dfc,this,7)
+{
+}
+
+void DLcdPowerHandler::ScreenInfo(TScreenInfoV01& anInfo)
+{
+  anInfo.iWindowHandleValid = EFalse;
+  anInfo.iWindowHandle = NULL;
+  anInfo.iScreenAddressValid = ETrue;
+  anInfo.iScreenAddress = (TAny *)(iChunk->LinearAddress());
+  anInfo.iScreenSize.iWidth = iVideoInfo.iSizeInPixels.iWidth;
+  anInfo.iScreenSize.iHeight = iVideoInfo.iSizeInPixels.iHeight;
+}
+
+void DLcdPowerHandler::HandleMsg(TMessageBase* aMsg)
+{
+  if(aMsg->iValue)
+	DisplayOn();
+  else
+	DisplayOff();
+  aMsg->Complete(KErrNone,ETrue);
+}
+
+void DLcdPowerHandler::WsSwitchOnScreen()
+{
+  TThreadMessage& m = Kern::Message();
+  m.iValue = ETrue;
+  m.SendReceive(&iMsgQ);
+}
+
+void DLcdPowerHandler::WsSwitchOffScreen()
+{
+  TThreadMessage& m = Kern::Message();
+  m.iValue = EFalse;
+  m.SendReceive(&iMsgQ);
+}
+
+TInt DLcdPowerHandler::GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure)
+{
+  NKern::FMWait(&iLock);
+  if(aSecure)
+	aInfo = iSecureVideoInfo;
+  else
+	aInfo = iVideoInfo;
+  NKern::FMSignal(&iLock);
+  return KErrNone;
+}
+
+TInt DLcdPowerHandler::GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo)
+{
+  if(aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
+	return KErrArgument;
+  
+  NKern::FMWait(&iLock);
+  aInfo = iVideoInfo;
+  NKern::FMSignal(&iLock);
+
+  if(aMode != aInfo.iDisplayMode)
+	{
+	  aInfo.iOffsetToFirstPixel = KCOnfigOffsetToFirstPixel;
+	  aInfo.iIsPalettized       = KConfigIsPalettized;
+	  aInfo.iOffsetBetweenLines = KCOnfigOffsetBetweenLines;
+	  aInfo.iBitsPerPixel       = KConfigBitsPerPixel;
+	}
+  return KErrNone;
+}
+
+TInt DLcdPowerHandler::AllocateFrameBuffer()
+{
+	// Allocate physical RAM for video
+	TInt vSize = TSyborg::VideoRamSize();
+
+	NKern::ThreadEnterCS();
+	TInt r = Epoc::AllocPhysicalRam(vSize,Syborg::VideoRamPhys);
+	if (r != KErrNone)
+	{
+	        NKern::ThreadLeaveCS();
+		Kern::Fault("AllocVideoRam",r);
+	}
+
+	// Map the video RAM
+	ivRamPhys = TSyborg::VideoRamPhys();
+
+	r = DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
+
+	NKern::ThreadLeaveCS();
+
+	if(r != KErrNone)
+	  return r;
+
+	TUint* pV = (TUint*)iChunk->LinearAddress();
+
+	// Allocate physical RAM for secure display
+	NKern::ThreadEnterCS();
+	r = Epoc::AllocPhysicalRam(vSize,Syborg::VideoRamPhysSecure);
+	if (r != KErrNone)
+	{
+	        NKern::ThreadLeaveCS();
+		Kern::Fault("AllocVideoRam 2",r);
+	}
+	iSecurevRamPhys = ivRamPhys + vSize;
+	TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
+
+	NKern::ThreadLeaveCS();
+
+	if(r2 != KErrNone)
+	  return r2;
+
+	TUint* pV2 = (TUint*)iSecureChunk->LinearAddress();
+
+	iVideoInfo.iSizeInPixels.iWidth  = KConfigLcdWidth;
+	iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight;
+	iVideoInfo.iDisplayMode = KConfigLcdDisplayMode;
+	iVideoInfo.iOffsetToFirstPixel = KCOnfigOffsetToFirstPixel;
+	iVideoInfo.iOffsetBetweenLines = KCOnfigOffsetBetweenLines;
+	iVideoInfo.iIsPalettized = KConfigIsPalettized;
+	iVideoInfo.iBitsPerPixel = KConfigBitsPerPixel;
+	iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips;
+	iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips;
+	iVideoInfo.iIsMono = KConfigIsMono;
+	iVideoInfo.iVideoAddress = (TInt)pV;
+	iVideoInfo.iIsPixelOrderLandscape = KConfigPixelOrderLandscape;
+	iVideoInfo.iIsPixelOrderRGB = KConfigPixelOrderRGB;
+
+	iSecureVideoInfo = iVideoInfo;
+	iSecureVideoInfo.iVideoAddress = (TInt)pV2;
+
+	// Alloc Physical RAM for the Composition Buffers used by the GCE
+	iSize = 4*480*640;//FRAME_BUFFER_SIZE( iVideoInfo.iBitsPerPixel, iVideoInfo.iSizeInPixels.iWidth, iVideoInfo.iSizeInPixels.iHeight);
+	__GCE_DEBUG_PRINT2("DLcdPowerHandler.iSize  = %d\n", iSize );
+	// double and round the page size
+	TUint round = 2*Kern::RoundToPageSize(iSize);
+
+	r=Epoc::AllocPhysicalRam(round , iCompositionPhysical);
+	if(r!=KErrNone)
+		{
+		return r;
+		}
+	
+	return KErrNone;
+}
+
+
+TInt DLcdPowerHandler::SetDisplayMode(TInt aMode)
+{
+  if(aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
+	return KErrArgument;
+
+  // store the current mode
+  iVideoInfo.iDisplayMode = aMode;
+
+  // store the current mode for secure screen
+  iSecureVideoInfo.iDisplayMode = aMode;
+
+  return KErrNone;
+}
+
+TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
+{
+  TInt r=KErrNone;
+  switch(aFunction)
+	{
+	case EDisplayHalScreenInfo:
+	  {
+		TPckgBuf<TScreenInfoV01> vPckg;
+		ScreenInfo(vPckg());
+		Kern::InfoCopy(*(TDes8*)a1,vPckg);
+		break;
+	  }
+	case EDisplayHalWsRegisterSwitchOnScreenHandling:
+	  {
+		iWsSwitchOnScreen=(TBool)a1;
+		break;
+	  }
+	case EDisplayHalWsSwitchOnScreen:
+	  {
+		WsSwitchOnScreen();
+		break;
+	  }
+	case EDisplayHalModeCount:
+	  {
+		TInt ndm = KConfigLcdNumberOfDisplayModes;
+		kumemput32(a1, &ndm, sizeof(ndm));
+		break;
+	  }
+	case EDisplayHalSetMode:
+	  {
+		__KTRACE_OPT(KEXTENSION,Kern::Printf("EDisplayHalSetMode"));
+		__SECURE_KERNEL(
+						if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode")))
+						return KErrPermissionDenied;
+						)
+		  r = SetDisplayMode((TInt)a1);
+		break;
+	  }
+	case EDisplayHalMode:
+	  {
+		kumemput32(a1, &iVideoInfo.iDisplayMode, sizeof(iVideoInfo.iDisplayMode));
+		r = KErrNone;
+		break;
+	  }
+	case EDisplayHalSetPaletteEntry:
+	  {
+		__SECURE_KERNEL(
+						if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetPaletteEntry")))
+						return KErrPermissionDenied;
+						)
+		  r = KErrNotSupported;
+		break;
+	  }
+	case EDisplayHalPaletteEntry:
+	  {
+		TInt entry;
+		kumemget32(&entry, a1, sizeof(TInt));
+		r = KErrNotSupported;
+		break;
+	  }
+	case EDisplayHalSetState:
+	  {
+		__SECURE_KERNEL(
+						if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetState")))
+						return KErrPermissionDenied;
+						)
+		  if((TBool)a1)
+			WsSwitchOnScreen();
+		  else
+			WsSwitchOffScreen();
+		break;
+	  }
+	case EDisplayHalState:
+	  {
+		kumemput32(a1, &iDisplayOn, sizeof(TBool));
+		break;
+	  }
+	case EDisplayHalColors:
+	  {
+		TInt mdc = 1<<24;
+		kumemput32(a1, &mdc, sizeof(mdc));
+		break;
+	  }
+	case EDisplayHalCurrentModeInfo:
+	  {
+		TPckgBuf<TVideoInfoV01> vPckg;
+		r = GetCurrentDisplayModeInfo(vPckg(), (TBool)a2);
+		if(KErrNone == r)
+		  Kern::InfoCopy(*(TDes8*)a1,vPckg);
+		break;
+	  }
+	case EDisplayHalSpecifiedModeInfo:
+	  {
+		TPckgBuf<TVideoInfoV01> vPckg;
+		TInt mode;
+		kumemget32(&mode, a1, sizeof(mode));
+		r = GetSpecifiedDisplayModeInfo(mode, vPckg());
+		if(KErrNone == r)
+		  Kern::InfoCopy(*(TDes8*)a2,vPckg);
+		break;
+	  }	
+	case EDisplayHalSecure:
+	  {
+		kumemput32(a1, &iSecureDisplay, sizeof(TBool));
+		break;
+	  }
+	case EDisplayHalSetSecure:
+	  {
+		__SECURE_KERNEL(
+						if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetSecure")))
+						return KErrPermissionDenied;
+						)
+		  SwitchDisplay((TBool)a1);
+		break;
+	  }
+	default:
+	  {
+		r = KErrNotSupported;
+		break;
+	  }			
+	}
+  return r;
+}
+
+TInt DLcdPowerHandler::Create()
+{
+	__KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::Create") );
+	pLcd			= this;
+
+	iPortAddr = KHwBaseClcd;
+
+	iVideoInfo.iSizeInPixels.iWidth  = KConfigLcdWidth;
+	iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight;
+	iVideoInfo.iDisplayMode = KConfigLcdDisplayMode;
+	iVideoInfo.iOffsetToFirstPixel = KCOnfigOffsetToFirstPixel;
+	iVideoInfo.iOffsetBetweenLines = KCOnfigOffsetBetweenLines;
+	iVideoInfo.iIsPalettized = KConfigIsPalettized;
+	iVideoInfo.iBitsPerPixel = KConfigBitsPerPixel;
+	iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips;
+	iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips;
+	iVideoInfo.iIsMono = KConfigIsMono;
+	// !@!	iVideoInfo.iVideoAddress = (TInt)pV;
+	iVideoInfo.iIsPixelOrderLandscape = KConfigPixelOrderLandscape;
+	iVideoInfo.iIsPixelOrderRGB = KConfigPixelOrderRGB;
+
+	iSecureVideoInfo = iVideoInfo;
+	// !@! iSecureVideoInfo.iVideoAddress = (TInt)pV2;
+
+	TInt r = AllocateFrameBuffer();
+	if(r == KErrNone)
+		{
+		r = Kern::AddHalEntry(EHalGroupDisplay,DoHalFunction,this);
+		}
+	    
+	if(r != KErrNone)
+		{
+		__KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::Create failed %d", r) );
+		return r;
+		}
+
+	iPowerUpDfc.SetDfcQ(iDfcQ);
+	iPowerDownDfc.SetDfcQ(iDfcQ);
+	iMsgQ.SetDfcQ(iDfcQ);
+	iMsgQ.Receive();
+
+	Add();
+	DisplayOn();
+
+	return KErrNone;
+}
+
+/**
+ * Register the call back function.
+ * Components interested in receiving notification of the Vsync interrupt should register a callback function.
+ */
+EXPORT_C TInt DLcdPowerHandler::RegisterCallback(TLcdUserCallBack* aCbPtr)
+{
+	__KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::RegisterCallBack %08x\n",aCbPtr->iCbFn) );
+
+	TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock);
+
+	if(aCbPtr != NULL)
+		{
+		if ( pLcd->iAppCallBk[0] == NULL  )
+			{
+			pLcd->iAppCallBk[0] = aCbPtr;
+			}
+		else
+			{
+			if((pLcd->iAppCallBk[1] == NULL) && (pLcd->iAppCallBk[0]->iCbFn != aCbPtr->iCbFn))
+				{
+				pLcd->iAppCallBk[1] = aCbPtr;
+				}
+			else
+				{
+				__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
+				return KErrInUse;
+				}
+			}
+
+		__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
+		__KTRACE_OPT(KEXTENSION ,Kern::Printf("<DLcdPowerHandler::RegisterCallBack ok %08x\n",aCbPtr->iCbFn) );
+		return KErrNone;
+		}
+	else
+		{
+		__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
+		__KTRACE_OPT(KEXTENSION, Kern::Printf("Error: The supplied listener's callback is NULL"));
+		return KErrArgument;
+		}
+}
+
+
+/**
+ *DeRegister the call back function
+ */
+EXPORT_C void DLcdPowerHandler::DeRegisterCallback(TLcdUserCallBack* aCbPtr)
+{
+	__KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::DeRegisterCallBack %08x\n ",aCbPtr->iCbFn)  );
+
+	TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock);
+	if(aCbPtr != NULL)
+		{
+	    if( pLcd->iAppCallBk[0] != NULL)
+			{
+			if ( (pLcd->iAppCallBk[0]->iDataPtr == aCbPtr->iDataPtr) && (pLcd->iAppCallBk[0]->iCbFn == aCbPtr->iCbFn) )
+				{
+				pLcd->iAppCallBk[0] = NULL;
+				}
+			}
+
+		if( pLcd->iAppCallBk[1] != NULL)
+			{
+			if ( (pLcd->iAppCallBk[1]->iDataPtr == aCbPtr->iDataPtr) && (pLcd->iAppCallBk[1]->iCbFn == aCbPtr->iCbFn) )
+				{
+				pLcd->iAppCallBk[1] = NULL;
+				}
+			}
+		}
+	__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
+	__KTRACE_OPT(KEXTENSION ,Kern::Printf("<DLcdPowerHandler::DeRegisterCallBack %08x\n ",aCbPtr->iCbFn)  );
+}
+
+/**
+	Constructor
+*/
+DDisplayPddSyborg::DDisplayPddSyborg():
+	iPendingBuffer(NULL),
+	iActiveBuffer(NULL),
+	iChunk(NULL),
+	iLcdCallback(NULL),
+	iVSyncDfc(&VSyncDfcFn, this, KVSyncDfcPriority)
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddSyborg::DDisplayPddSyborg\n");
+
+	iPostFlag = EFalse;
+	}
+
+/**
+	Destructor
+*/
+DDisplayPddSyborg::~DDisplayPddSyborg()
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddSyborg::~DDisplayPddSyborg()  \n");
+
+	if(iLcdCallback)
+		{
+		DLcdPowerHandler::pLcd->DeRegisterCallback(iLcdCallback) ;
+		delete iLcdCallback;
+		iLcdCallback = NULL;
+		}
+
+	//The DFC Queue is owned by DLcdPowerHandler so we shouldn't call Destroy() at this point.
+	if (iDfcQ)
+		{
+		iDfcQ=NULL;
+		}
+
+	DChunk* chunk = (DChunk*) __e32_atomic_swp_ord_ptr(&iChunk, 0);
+
+	if(chunk)
+		{
+		Kern::ChunkClose(chunk);
+		}
+
+	}
+
+/**
+    Set the Legacy Mode by setting the appropriate Frame control value.
+
+*/
+TInt DDisplayPddSyborg::SetLegacyMode()
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddSyborg::SetLegacyMode()\n");
+
+    return KErrNone;
+	}
+
+/**
+    Set the GCE mode by posting a composition buffer.
+
+*/
+TInt DDisplayPddSyborg::SetGceMode()
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddSyborg::SetGceMode()\n");
+
+    PostCompositionBuffer(&iLdd->iCompositionBuffer[0]);
+    return KErrNone;
+	}
+
+/**
+	@param	aDegOfRot  The requested rotation
+	@return KErrNone
+*/
+TInt DDisplayPddSyborg::SetRotation(TInt aDegOfRot)
+	{
+	return KErrNone;
+	}
+
+/**
+    Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization
+    with V Sync so it will take affect in the next V Sync after that) and also set the buffer provided as the buffer to
+    be posted next. Layer 3 is associated with user buffers.
+
+	@param	aNode  Pointer to the User buffer to post.
+*/
+TInt DDisplayPddSyborg::PostUserBuffer(TBufferNode* aNode)
+	{
+
+	__GCE_DEBUG_PRINT2("DDisplayPddSyborg::PostUserBuffer :  aNode->iAddress = %08x\n", aNode->iAddress);
+
+	if(iPendingBuffer)
+		{
+		iPendingBuffer->iState = EBufferFree;
+		if (!(iPendingBuffer->iType == EBufferTypeUser) )
+			{
+			iPendingBuffer->iFree  = ETrue;
+			}
+		}
+
+	aNode->iState   = EBufferPending;
+	iPendingBuffer	= aNode;
+	iPostFlag		= ETrue;
+	
+  	// Activate the posted buffer
+	TUint32 physicalAddress = Epoc::LinearToPhysical( aNode->iAddress );
+  	WriteReg(DLcdPowerHandler::pLcd->iPortAddr, DLcdPowerHandler::FB_BASE, physicalAddress );
+	/* Queue a DFC to complete the request*/
+	iVSyncDfc.Enque();
+
+	return KErrNone;
+	}
+
+/**
+    Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization
+    with V Sync so it will take affect in the next V Sync after that) and also set the buffer provided as the buffer to
+    be posted next. Layer 1 and 2 are associated with composition buffers 0 and 1 respectively.
+
+	@param	aNode  Pointer to the Composition buffer to post.
+*/
+TInt DDisplayPddSyborg::PostCompositionBuffer(TBufferNode* aNode)
+	{
+
+	__GCE_DEBUG_PRINT2("DDisplayPddSyborg::PostCompositionBuffer :  aNode->iAddress = %08x\n", aNode->iAddress);
+
+	if(iPendingBuffer)
+		{
+		iPendingBuffer->iState = EBufferFree;
+		if (iPendingBuffer->iType == EBufferTypeUser)
+			{
+			RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrCancel);
+			}
+		else
+			{
+			iPendingBuffer->iFree  = ETrue;
+			}
+		}
+	aNode->iState	= EBufferPending;
+	aNode->iFree	= EFalse;
+	iPendingBuffer	= aNode;
+	iPostFlag		= ETrue;
+
+  	// Activate the posted buffer
+	TUint32 physicalAddress = Epoc::LinearToPhysical( aNode->iAddress );
+  	WriteReg(DLcdPowerHandler::pLcd->iPortAddr, DLcdPowerHandler::FB_BASE, physicalAddress );
+	
+	/* Queue a DFC to complete the request*/
+	iVSyncDfc.Enque();
+
+	return KErrNone;
+	}
+
+/**
+    Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization
+    with V Sync so it will take affect in the next V Sync after that) and also set the Legacy Buffer as the buffer to
+    be posted next.Layer 0 is associated with legacy buffer.
+
+	@param	aNode  Pointer to the Composition buffer to post.
+*/
+TInt DDisplayPddSyborg::PostLegacyBuffer()
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddSyborg::PostLegacyBuffer() \n");
+
+	if(iPendingBuffer)
+		{
+		iPendingBuffer->iState = EBufferFree;
+		if (iPendingBuffer->iType == EBufferTypeUser)
+			{
+
+			RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrCancel);
+			}
+		else
+			{
+			iPendingBuffer->iFree  = ETrue;
+			}
+		}
+
+
+	iLdd->iLegacyBuffer[0].iState		= EBufferPending;
+	iLdd->iLegacyBuffer[0].iFree		= EFalse;
+	iPendingBuffer						= &iLdd->iLegacyBuffer[0];
+	iPostFlag		= ETrue;
+
+  	// Activate the posted buffer
+  	WriteReg(DLcdPowerHandler::pLcd->iPortAddr, DLcdPowerHandler::FB_BASE, TSyborg::VideoRamPhys() );
+
+	/* Queue a DFC to complete the request*/
+	iVSyncDfc.Enque();
+
+	return KErrNone;
+	}
+
+/**
+    Handles device specific operations when a close message has been sent to the Logical Channel.
+
+*/
+TInt DDisplayPddSyborg::CloseMsg()
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddSyborg::CloseMsg()\n");
+
+	iPendingBuffer  = NULL;
+	iActiveBuffer	= NULL;
+
+	iVSyncDfc.Cancel();
+    return KErrNone;
+	}
+
+/**
+    Called by the LDD's DoCreate function to handle the device specific part of opening the channel.
+    (DoCreate is called by RDisplayChannel::Open)
+
+	@param aUnit	The screen unit
+
+    @return KErrNone if successful; or one of the other system wide error codes.
+*/
+TInt DDisplayPddSyborg::CreateChannelSetup(TInt aUnit)
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddSyborg::CreateChannelSetup\n");
+
+	iScreenInfo = DLcdPowerHandler::pLcd->iVideoInfo;
+	iLdd->iUnit = aUnit;
+
+	iLdd->iDisplayInfo.iAvailableRotations			= RDisplayChannel::ERotationNormal;
+	iLdd->iDisplayInfo.iNormal.iOffsetBetweenLines	= iScreenInfo.iOffsetBetweenLines;
+	iLdd->iDisplayInfo.iNormal.iHeight				= iScreenInfo.iSizeInPixels.iHeight;
+	iLdd->iDisplayInfo.iNormal.iWidth				= iScreenInfo.iSizeInPixels.iWidth;
+	iLdd->iDisplayInfo.iNumCompositionBuffers		= KDisplayCBMax;
+	iLdd->iDisplayInfo.iBitsPerPixel				= iScreenInfo.iBitsPerPixel;
+    iLdd->iDisplayInfo.iRefreshRateHz = 60;
+
+
+	switch (iScreenInfo.iBitsPerPixel)
+		{
+		case 16:
+			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatRGB_565;
+			break;
+		case 24:
+			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatRGB_888;
+			break;
+		case 32:
+			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatARGB_8888;
+			break;
+		default:
+			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatUnknown;
+			break;
+		}
+
+	iLdd->iCurrentRotation = RDisplayChannel::ERotationNormal;
+
+	// Open shared chunk to the composition framebuffer
+
+	DChunk* chunk = 0;
+	TLinAddr chunkKernelAddr  = 0;
+	TUint32 chunkMapAttr = 0;
+
+	// round to twice the page size
+	TUint round  =  2*Kern::RoundToPageSize(DLcdPowerHandler::pLcd->iSize);
+
+	__GCE_DEBUG_PRINT2("DDisplayPddSyborg::CreateChannelSetup DLcdPowerHandler::pLcd->iSize  = %d\n", DLcdPowerHandler::pLcd->iSize );
+
+	TChunkCreateInfo info;
+	info.iType					 = TChunkCreateInfo::ESharedKernelMultiple;
+	info.iMaxSize				 = round;
+	info.iMapAttr				 = EMapAttrFullyBlocking;
+	info.iOwnsMemory			 = EFalse;
+	info.iDestroyedDfc			 = 0;
+
+	TInt r = Kern::ChunkCreate(info, chunk, chunkKernelAddr, chunkMapAttr);
+
+	__GCE_DEBUG_PRINT2("CreateChannelSetup:ChunkCreate called for composition chunk. Set iChunkKernelAddr  = %08x\n", chunkKernelAddr );
+
+	if( r == KErrNone)
+		{
+		// map our chunk
+		r = Kern::ChunkCommitPhysical(chunk, 0,round , DLcdPowerHandler::pLcd->iCompositionPhysical);
+		__GCE_DEBUG_PRINT2("Mapping chunk %d", r);
+		if(r != KErrNone)
+			{
+			Kern::ChunkClose(chunk);
+			}
+		}
+
+	if ( r!= KErrNone)
+		{
+		return r;
+		}
+
+	iChunk	= chunk;
+
+	// init CB 0
+	iLdd->iCompositionBuffer[0].iType			= EBufferTypeComposition;
+	iLdd->iCompositionBuffer[0].iBufferId		= 0;
+	iLdd->iCompositionBuffer[0].iFree			= ETrue;
+	iLdd->iCompositionBuffer[0].iState			= EBufferFree;
+	iLdd->iCompositionBuffer[0].iAddress		= chunkKernelAddr;
+	iLdd->iCompositionBuffer[0].iPhysicalAddress = Epoc::LinearToPhysical(chunkKernelAddr);
+	iLdd->iCompositionBuffer[0].iChunk			= chunk;
+	iLdd->iCompositionBuffer[0].iHandle			= 0;
+	iLdd->iCompositionBuffer[0].iOffset			= 0;
+	iLdd->iCompositionBuffer[0].iSize			= DLcdPowerHandler::pLcd->iSize;
+	iLdd->iCompositionBuffer[0].iPendingRequest = 0;
+
+	// init CB 1
+	iLdd->iCompositionBuffer[1].iType			= EBufferTypeComposition;
+	iLdd->iCompositionBuffer[1].iBufferId		= 1;
+	iLdd->iCompositionBuffer[1].iFree			= ETrue;
+	iLdd->iCompositionBuffer[1].iState			= EBufferFree;
+	iLdd->iCompositionBuffer[1].iAddress		= chunkKernelAddr + DLcdPowerHandler::pLcd->iSize;
+	iLdd->iCompositionBuffer[1].iPhysicalAddress = Epoc::LinearToPhysical(chunkKernelAddr + DLcdPowerHandler::pLcd->iSize);
+	iLdd->iCompositionBuffer[1].iChunk			= chunk;
+	iLdd->iCompositionBuffer[1].iHandle			= 0;
+	iLdd->iCompositionBuffer[1].iOffset			= DLcdPowerHandler::pLcd->iSize;
+	iLdd->iCompositionBuffer[1].iSize			= DLcdPowerHandler::pLcd->iSize;
+	iLdd->iCompositionBuffer[1].iPendingRequest = 0;
+
+	iLdd->iCompositionBuffIdx					= 0;
+	//Use the same DFC queue created by the DLcdPowerHandler so all hardware accesses are executed under the same DFC thread.
+	iDfcQ= DLcdPowerHandler::pLcd->iDfcQ;
+
+	// Set the Post DFC.
+	iVSyncDfc.SetDfcQ(iDfcQ);
+
+
+	return KErrNone;
+	}
+
+/**
+Detect whether a post operation is pending
+*/
+TBool DDisplayPddSyborg::PostPending()
+	{
+	return (iPendingBuffer != NULL);
+	}
+
+/**
+	Return the DFC queue to be used for this device.
+ */
+TDfcQue * DDisplayPddSyborg::DfcQ(TInt aUnit)
+	{
+	return iDfcQ;
+	}
+
+void DDisplayPddSyborg::VSyncDfcFn(TAny* aChannel)
+	{
+	DDisplayPddSyborg * channel =(DDisplayPddSyborg*)aChannel;
+
+	if (channel->iPostFlag)
+		{
+		 channel->iPostFlag = EFalse;
+
+		if (channel->iActiveBuffer)
+			{
+			//When a User buffer is registered its iFree member becomes EFalse and Deregister sets it
+			//back to ETrue. Composition and Legacy buffers are not free when they are in the pending or
+			//active state.
+			if (channel->iActiveBuffer->iType == EBufferTypeUser)
+				{
+				channel->RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrNone);
+				}
+			else
+				{
+				channel->iActiveBuffer->iFree	= ETrue;
+				}
+
+			channel->iActiveBuffer->iState		= EBufferFree;
+
+
+			//If no buffer was available during a call to GetCompositionBuffer the active buffer has
+			//been returned as the next available one, so we must set the buffer to the proper state before we
+			//send the notification.
+			if(channel->iLdd->iPendingReq[RDisplayChannel::EReqGetCompositionBuffer].iStatus)
+				{
+				channel->iActiveBuffer->iState	= EBufferCompose;
+				channel->RequestComplete(RDisplayChannel::EReqGetCompositionBuffer, KErrNone);
+
+				}
+
+			channel->iActiveBuffer				= NULL;
+			}
+
+		if (channel->iPendingBuffer)
+			{
+			__GCE_DEBUG_PRINT2("DDisplayPddSyborg::VSyncDfcFn moving pending buffer at address %08x to the active state\n", channel->iPendingBuffer->iAddress);
+			channel->iActiveBuffer			= channel->iPendingBuffer;
+			channel->iActiveBuffer->iState	= EBufferActive;
+			channel->iPendingBuffer			= NULL;
+
+			channel->RequestComplete(RDisplayChannel::EReqWaitForPost,  KErrNone);
+			}
+		}
+	}
+//*****************************************************************
+//DDisplayPddFactory
+//*****************************************************************/
+
+
+/**
+	Constructor
+*/
+DDisplayPddFactory::DDisplayPddFactory()
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddFactory::DDisplayPddFactory()\n");
+
+	iVersion		= TVersion(KDisplayChMajorVersionNumber,
+                      KDisplayChMinorVersionNumber,
+                      KDisplayChBuildVersionNumber);
+	}
+
+/**
+	PDD factory function. Creates a PDD object.
+
+	@param  aChannel  A pointer to an PDD channel object which will be initialised on return.
+
+	@return KErrNone  if object successfully allocated, KErrNoMemory if not.
+*/
+TInt DDisplayPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
+	{
+	DDisplayPddSyborg *device= new DDisplayPddSyborg() ;
+	aChannel=device;
+	if (!device)
+		{
+		return KErrNoMemory;
+		}
+	return KErrNone;
+	}
+
+
+/**
+    Set the Pdd name and return error code
+*/
+TInt DDisplayPddFactory::Install()
+	{
+	__GCE_DEBUG_PRINT("DDisplayPddFactory::Install() \n");
+
+	TBuf<32> name(RDisplayChannel::Name());
+	_LIT(KPddExtension,".pdd");
+	name.Append(KPddExtension);
+	return SetName(&name);
+	}
+
+
+void DDisplayPddFactory::GetCaps(TDes8& /*aDes*/) const
+	{
+	//Not supported
+	}
+
+
+/**
+    Validate version and number of units.
+*/
+TInt DDisplayPddFactory::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer)
+	{
+	if (!Kern::QueryVersionSupported(iVersion,aVer))
+		{
+		return KErrNotSupported;
+		}
+
+	if (aUnit != 0)
+		{
+		return KErrNotSupported;
+		}
+
+	return KErrNone;
+	}
+
+DECLARE_EXTENSION_PDD()
+/**
+	"Standard PDD" entrypoint.Creates PDD factory when Kern::InstallPhysicalDevice is called
+
+	@return pointer to the PDD factory object.
+*/
+	{
+	__GCE_DEBUG_PRINT("DECLARE_EXTENSION_PDD()\n");
+	return new DDisplayPddFactory ;
+	}
+
+
+DECLARE_STANDARD_EXTENSION()
+{
+  TInt r = KErrNoMemory;
+  DLcdPowerHandler* pH=new DLcdPowerHandler;
+  if(pH)
+	{
+	r = pH->Create();
+	if ( r == KErrNone)
+		{
+		pH->iDfcQ = Kern::DfcQue0();	// use low priority DFC queue for this driver 
+
+		DDisplayPddFactory * device = new DDisplayPddFactory;
+
+		if (device==NULL)
+			{
+			r=KErrNoMemory;
+			}
+		else
+			{
+			r=Kern::InstallPhysicalDevice(device);
+			}
+
+		#ifdef CPU_AFFINITY_ANY
+        NKern::ThreadSetCpuAffinity((NThread*) pH->iDfcQ->iThread, KCpuAffinityAny);
+		#endif
+
+		__KTRACE_OPT(KEXTENSION,Kern::Printf("Installing the display device from the kernel extension returned with error code %d",r));
+
+		}
+	}
+  
+  return r;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/svpframebuffer/svpframebuffer.h	Sat Feb 27 19:18:04 2010 +0000
@@ -0,0 +1,297 @@
+/*
+* 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: Minimalistic frame buffer driver
+*
+*/
+
+#ifndef _SVPFRAMEBUFFER_H
+#define _SVPFRAMEBUFFER_H
+
+#include <display.h>
+
+#include <videodriver.h>
+#include <system.h>
+
+#define __SVPFRAMEBUFFER_DEBUG
+
+#ifdef __SVPFRAMEBUFFER_DEBUG
+
+#define  __GCE_DEBUG_PRINT(a) 		Kern::Printf(a)
+#define  __GCE_DEBUG_PRINT2(a,b) 	Kern::Printf(a,b)
+
+#else
+
+#define  __GCE_DEBUG_PRINT(a)
+#define  __GCE_DEBUG_PRINT2(a,b)
+
+#endif
+
+// Macro to calculate the screen buffer size
+// aBpp is the number of bits-per-pixel, aPpl is the number of pixels per line and aLpp number of lines per panel
+#define FRAME_BUFFER_SIZE(aBpp,aPpl,aLpp)	((aBpp/8)*aPpl*aLpp)	
+
+_LIT(KLitLcd,"SYBORG_FB");
+
+const TUint KConfigLcdWidth            = 640;
+const TUint	KConfigLcdHeight	       = 480;
+const TInt	KConfigLcdWidthInTwips     = 9638;
+const TInt	KConfigLcdHeightInTwips    = 7370;
+const TBool KConfigIsMono              = 0;
+const TBool KConfigIsPalettized        = 0;
+const TInt  KCOnfigOffsetToFirstPixel  = 0;
+const TBool KConfigPixelOrderRGB       = 0;
+const TBool KConfigPixelOrderLandscape = 1;
+const TInt  KConfigLcdDisplayMode       = 2;
+//const TInt  KConfigLcdDisplayMode       = 1;
+const TInt  KConfigLcdNumberOfDisplayModes = 3;
+
+
+const TInt  KConfigBitsPerPixel        = 24;
+const TInt  KCOnfigOffsetBetweenLines  = 2560;
+
+const TInt   KVSyncDfcPriority							= 7 ;   //priority of DFC within the queue (0 to 7, where 7 is highest)
+
+/********************************************************************/
+/* Class Definition                                                 */
+/********************************************************************/
+/**
+ * This class defines a callback mechanism that is used by a resource user to specify its callback. It contains a
+ * function pointer and data pointer. The function pointer specifies the user callback function to be invoked by the
+ * resource while the data pointer specifies the data to be passed to the callback function.
+ */
+class TLcdUserCallBack
+    {
+public:
+    // The constructor for the callback mechanism.
+    TLcdUserCallBack(TInt (*aFunction)(TUint aResID, TAny* aPtr), TAny* aPtr)
+
+        {
+        iCbFn = aFunction;
+        iDataPtr = aPtr;
+        }
+
+public:
+    // The callback function pointer.
+    TInt (*iCbFn)(TUint aResID, TAny* aPtr);
+
+    // Pointer to the data structure to be passed to the callback function.
+    TAny *iDataPtr;
+    };
+
+class DLcdPowerHandler : public DPowerHandler
+{
+public: // from DPowerHandler
+  void PowerDown(TPowerState);
+  void PowerUp();
+public:	// to prevent a race condition with WServer trying to power up/down at the same time
+  void PowerUpDfc();
+  void PowerDownDfc();
+public:
+  DLcdPowerHandler();
+  TInt Create();
+  void DisplayOn();
+  void DisplayOff();
+  TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2);
+
+  void PowerUpLcd(TBool aSecure);
+  void PowerDownLcd();
+
+  void ScreenInfo(TScreenInfoV01& aInfo);
+  void WsSwitchOnScreen();
+  void WsSwitchOffScreen();
+  void HandleMsg(TMessageBase* aMsg);
+  void SwitchDisplay(TBool aSecure);
+
+private:
+  TInt GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure);
+  TInt GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo);
+  TInt SetDisplayMode(TInt aMode);
+  TInt AllocateFrameBuffer();
+
+public:
+    IMPORT_C static    TInt    RegisterCallback(TLcdUserCallBack* aCbPtr);
+    IMPORT_C static    void    DeRegisterCallback(TLcdUserCallBack* aCbPtr);
+  
+private:
+  TBool iDisplayOn;
+  DPlatChunkHw* iChunk;
+  DPlatChunkHw* iSecureChunk;
+  TBool iWsSwitchOnScreen;
+  TBool iSecureDisplay;
+
+public:
+  TDfcQue* iDfcQ;
+  TMessageQue iMsgQ;					// to prevent a race condition with Power Manager trying to power up/down at the same time
+  TDfc iPowerUpDfc;
+  TDfc iPowerDownDfc;	
+
+private:
+  NFastMutex iLock;
+  TPhysAddr ivRamPhys;
+  TPhysAddr iSecurevRamPhys;
+  TLcdUserCallBack * iAppCallBk[2];
+
+public:
+  TVideoInfoV01 iVideoInfo;
+  TVideoInfoV01 iSecureVideoInfo;
+  TInt			iSize;
+  TLinAddr iPortAddr;
+  TPhysAddr		iCompositionPhysical;
+  static   DLcdPowerHandler 	* pLcd;
+
+enum {
+    FB_ID               = 0,
+    FB_BASE             = 1,
+    FB_HEIGHT           = 2,
+    FB_WIDTH            = 3,
+    FB_ORIENTATION      = 4,
+    FB_BLANK            = 5,
+    FB_INT_MASK         = 6,
+    /* begin new interface */
+    FB_INTERRUPT_CAUSE  = 7,
+    FB_BPP              = 8,
+    FB_COLOR_ORDER      = 9,
+    FB_BYTE_ORDER       = 10,
+    FB_PIXEL_ORDER      = 11,
+    FB_ROW_PITCH        = 12,
+    FB_ENABLED          = 13,
+    FB_PALETTE_START    = 0x400 >> 2,
+    FB_PALETTE_END   = FB_PALETTE_START+256-1,
+    /* end new interface */
+    };
+
+#define FB_INT_VSYNC            (1U << 0)
+#define FB_INT_BASE_UPDATE_DONE (1U << 1)
+
+};
+
+class DDisplayPddSyborg : public DDisplayPdd
+	{
+
+	public:
+	DDisplayPddSyborg();
+	~DDisplayPddSyborg();
+    
+  	/**  
+    Called by the LDD to handle the device specific part of switching to Legacy mode.
+ 
+	@return KErrNone if successful; or one of the other system wide error codes.
+    */    
+    virtual TInt  SetLegacyMode();
+        
+     /**
+     Called by the LDD to handle the device specific part of switching to GCE mode.
+     
+     @return KErrNone if successful; or one of the other system wide error codes.
+     */       
+    virtual TInt  SetGceMode();
+    
+     /**
+     Called by the LDD to handle the device specific part of setting the rotation.
+     
+     @return KErrNone if successful; or one of the other system wide error codes.
+     */       
+    virtual TInt  SetRotation(TInt aRotation);
+
+     /**
+     Called by the LDD to handle the device specific part of posting a User Buffer.
+     
+     @return KErrNone if successful; or one of the other system wide error codes.
+     */ 	
+	virtual TInt  PostUserBuffer(TBufferNode* aNode);
+	
+     /**
+     Called by the LDD to handle the device specific part of posting a Composition Buffer
+     
+     @return KErrNone if successful; or one of the other system wide error codes.
+     */ 		
+	virtual TInt  PostCompositionBuffer(TBufferNode* aNode);
+        
+     /**
+     Called by the LDD to handle the device specific part of posting the Legacy Buffuer
+     
+     @return KErrNone if successful; or one of the other system wide error codes.
+     */   
+    virtual TInt  PostLegacyBuffer();
+    
+    /**
+     Called by the LDD to handle device specific cleanup operations when a channel is closed.
+          
+     @return KErrNone if successful; or one of the other system wide error codes.
+     */  
+    virtual TInt  CloseMsg();
+            
+     /**
+     Called by the LDD to handle device specific initialisation tasks when a channel is opened.
+     
+     @param aUnit The screen/hardware unit number.
+     @return KErrNone if successful; or one of the other system wide error codes.
+     */    
+    virtual TInt  CreateChannelSetup(TInt aUnit);
+          
+     /**
+     Called by the LDD in order to detect whether a post operation is pending. This type of 
+     information is specific to the actual physical device.
+     
+     @return ETrue if a Post operation is pending otherwise EFalse.
+     */       
+   	virtual TBool  PostPending();
+    
+    /**
+     Called by the LDD to retrieve the DFC Queue created in the PDD.      
+     
+     @param aUnit The screen/hardware unit number.
+     @return A pointer to the TDfcQue object created in the PDD.
+     */    
+    virtual TDfcQue* DfcQ(TInt  aUnit);    
+            
+public:
+	static void VSyncDfcFn(TAny* aChannel);
+
+private:
+	TDfcQue* 		iDfcQ;
+
+    //generic  display info
+	TVideoInfoV01    	iScreenInfo;
+
+    //Pointer to a buffer in the Pending state
+    TBufferNode*     	iPendingBuffer;
+
+     //Pointer to a buffer in the Active state
+    TBufferNode*     	iActiveBuffer;
+
+    DChunk * 		 	iChunk;
+    TLcdUserCallBack*   iLcdCallback;
+
+ public:
+	TDfc 		     	iVSyncDfc;
+	};
+
+
+/**
+ PDD Factory class
+ */
+
+class DDisplayPddFactory : public DPhysicalDevice
+	{
+public:
+	DDisplayPddFactory();
+
+	virtual TInt Install();
+	virtual void GetCaps(TDes8& aDes) const;
+	virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer);
+	virtual TInt Validate(TInt aDeviceType, const TDesC8* anInfo, const TVersion& aVer);
+	};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/svpframebuffer/svpframebuffer.mmp	Sat Feb 27 19:18:04 2010 +0000
@@ -0,0 +1,40 @@
+/*
+* 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:
+*
+*/
+
+#include <variant.mmh>
+#include "kernel/kern_ext.mmh"
+
+TARGET			VariantTarget(svpframebuffer,dll)
+TARGETTYPE		kext
+
+SYMBIAN_BASE_SYSTEMINCLUDE(drivers)
+SYSTEMINCLUDE	AsspNKernIncludePath
+SYSTEMINCLUDE	.
+
+SOURCEPATH		.
+SOURCE			svpframebuffer.cpp
+
+LIBRARY			PlatformLib
+
+EPOCALLOWDLLDATA
+
+UID			    0x1000008d 0x100039e8
+VENDORID        0x70000001
+
+ROMTARGET		lcd.dll
+
+CAPABILITY		all
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/devtree.c	Fri Jan 08 12:04:26 2010 +0000
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/devtree.c	Sat Feb 27 19:18:04 2010 +0000
@@ -26,6 +26,7 @@
 #include "devtree.h"
 #include "hw/boards.h"
 #include "libfdt/libfdt.h"
+#include "qemu-char.h"
 
 #define BADF(fmt, args...) \
 do { fprintf(stderr, "error: " fmt , ##args); exit(1);} while (0)
@@ -413,7 +414,15 @@
         if (propstr) {
             i = sscanf(propstr, "serial%d", &n);
             if (i == 1 && n >= 0 && n < MAX_SERIAL_PORTS)
+            {
+                if (!serial_hds[n])
+                {
+                    const char* target = fdt_getprop_string(dt, node, "target");
+                    if (target)
+                        serial_hds[n] = qemu_chr_open(propstr, target);
+                }
                 d->chardev = serial_hds[n];
+            }
         }
     }
     find_properties(d);
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/plugins/syborg_serial.py	Fri Jan 08 12:04:26 2010 +0000
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/plugins/syborg_serial.py	Sat Feb 27 19:18:04 2010 +0000
@@ -1,4 +1,6 @@
 import qemu
+import os
+import sys
 
 class syborg_serial(qemu.devclass):
   REG_ID           = 0
@@ -127,6 +129,57 @@
   regions = [qemu.ioregion(0x1000, readl=read_reg, writel=write_reg)]
   irqs = 1
   name = "syborg,serial"
-  properties = {"fifo-size":16, "chardev":None}
+  properties = {"fifo-size":16, "chardev":None, "target": ""}
 
 qemu.register_device(syborg_serial)
+
+class syborg_modem(syborg_serial):
+  
+  def create(self):
+    syborg_serial.create(self)
+    
+    # Find the path of the emulator executable
+    path = os.path.dirname(sys.executable)
+    executable = os.getenv("SVP_MODEM_EXECUTABLE")
+    if None == executable:
+      executable = self.modem_executable
+    
+    executable_name = executable
+    fq_executable = os.path.join(path, executable_name)
+    print(fq_executable)
+    
+    if not os.path.exists(fq_executable):
+      executable_name = executable + ".exe"
+      fq_executable = os.path.join(path, executable_name)
+      
+      if not os.path.exists(fq_executable):
+        sys.exit("Could not locate modem executable '" + executable + "' in '" + path + "'!\n")
+    
+    # Attempt to find the correct port from the target spec
+    target = self.properties["target"]
+    
+    if not(target.startswith("tcp:") or target.startswith("udp:")):
+      sys.exit("Modem device is not accessed via an acceptable socket.")
+    
+    target = target[4:]
+    port_start_idx = target.find(":");
+    port_end_idx = target.find(",")
+    if -1 == port_start_idx:
+      sys.exit("Could not extract port number from modem target spec!")
+    
+    port = ""
+    if -1 == port_end_idx:
+      port = target[port_start_idx + 1:]
+    else:
+      port = target[port_start_idx + 1:port_end_idx]
+    
+    os.spawnl(os.P_NOWAIT, fq_executable, executable_name, "-p", port)
+    self.chardev.handle_connect()
+  
+  # Name property override.
+  name = "syborg,serial,modem"
+  
+  # Default modem executable
+  modem_executable = "phonesim"
+
+qemu.register_device(syborg_modem)
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/python-plugin.c	Fri Jan 08 12:04:26 2010 +0000
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/python-plugin.c	Sat Feb 27 19:18:04 2010 +0000
@@ -1072,6 +1072,17 @@
     return 0;
 }
 
+static PyObject *qemu_py_chardev_handle_connect(qemu_py_chardev *self,
+                                     PyObject *args)
+{
+    if (!self->chr)
+        Py_RETURN_NONE;
+    
+    qemu_chr_connect(self->chr);
+    
+    Py_RETURN_NONE; 
+}
+
 static PyObject *qemu_py_chardev_set_handlers(qemu_py_chardev *self,
                                               PyObject *args, PyObject *kwds)
 {
@@ -1147,6 +1158,9 @@
 };
 
 static PyMethodDef qemu_py_chardev_methods[] = {
+    {"handle_connect", (PyCFunction)qemu_py_chardev_handle_connect,
+      METH_NOARGS,
+      "Handle character device connect if required"},
     {"set_handlers", (PyCFunction)qemu_py_chardev_set_handlers,
       METH_VARARGS|METH_KEYWORDS,
      "Set event handlers"},
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.c	Fri Jan 08 12:04:26 2010 +0000
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.c	Sat Feb 27 19:18:04 2010 +0000
@@ -123,6 +123,12 @@
     }
 }
 
+void qemu_chr_connect(CharDriverState *s)
+{
+    if (s->chr_connect)
+        s->chr_connect(s);
+}
+
 int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
 {
     return s->chr_write(s, buf, len);
@@ -605,6 +611,20 @@
     return qemu_chr_open_fd(-1, fd_out);
 }
 
+static CharDriverState *qemu_chr_open_tempfile_out(const char *temp_file)
+{
+    CharDriverState *ret = NULL;
+    const char *temp_format = "/tmp/%s";
+    char *fname = qemu_mallocz(sizeof(char) * (strlen(temp_path) + strlen(temp_file)));
+    if (fname)
+    {
+        sprintf(fname, temp_format, temp_file);
+        ret = qemu_chr_open_file_out(fname);
+        qemu_free(fname);
+    }
+    return ret;
+}
+
 static CharDriverState *qemu_chr_open_pipe(const char *filename)
 {
     int fd_in, fd_out;
@@ -1757,6 +1777,29 @@
 
     return qemu_chr_open_win_file(fd_out);
 }
+
+static CharDriverState *qemu_chr_open_win_tempfile_out(const char *temp_file)
+{
+    CharDriverState *ret = NULL;
+    char* fname;
+    const char* temp_format = "%s\\%s";
+    const char* temp_path;
+    
+    temp_path = getenv("TEMP");
+    if (temp_path)
+    {
+        fname = qemu_mallocz(sizeof(char) * (strlen(temp_path) + strlen(temp_file) + strlen(temp_format)));
+        if (fname)
+        {
+            sprintf(fname, temp_format, temp_path, temp_file);
+            ret = qemu_chr_open_win_file_out(fname);
+            qemu_free(fname);
+        }
+    }
+
+    return ret;
+}
+
 #endif /* !_WIN32 */
 
 /***********************************************************/
@@ -1886,6 +1929,8 @@
     int do_telnetopt;
     int do_nodelay;
     int is_unix;
+    int wait_connect;
+    int device_handles_connect;
 } TCPCharDriver;
 
 static void tcp_chr_accept(void *opaque);
@@ -2063,6 +2108,26 @@
     tcp_chr_connect(chr);
 }
 
+static void tcp_chr_do_connect(CharDriverState* chr)
+{
+    TCPCharDriver *driver = (TCPCharDriver*)chr->opaque;
+    if (driver->device_handles_connect)
+    {
+        if (-1 != driver->listen_fd)
+        {
+            printf("QEMU waiting for connection...\n");
+            tcp_chr_accept(chr);
+            socket_set_nonblock(driver->listen_fd);
+        }
+        else
+        {
+            driver->connected = 1;
+            socket_set_nodelay(driver->fd);
+            tcp_chr_connect(chr);
+        }
+    }
+}
+
 static void tcp_chr_close(CharDriverState *chr)
 {
     TCPCharDriver *s = chr->opaque;
@@ -2083,6 +2148,7 @@
     int is_listen = 0;
     int is_waitconnect = 1;
     int do_nodelay = 0;
+    int is_device_handles_connect = 0;
     const char *ptr;
 
     ptr = host_str;
@@ -2096,6 +2162,8 @@
             do_nodelay = 1;
         } else if (!strncmp(ptr,"to=",3)) {
             /* nothing, inet_listen() parses this one */;
+        } else if (!strncmp(ptr, "devicehandlesconnect", 20) && !is_unix) {
+            is_device_handles_connect = 1;
         } else {
             printf("Unknown option: %s\n", ptr);
             goto fail;
@@ -2107,6 +2175,7 @@
     chr = qemu_mallocz(sizeof(CharDriverState));
     if (!chr)
         goto fail;
+        
     s = qemu_mallocz(sizeof(TCPCharDriver));
     if (!s)
         goto fail;
@@ -2147,10 +2216,13 @@
     s->listen_fd = -1;
     s->is_unix = is_unix;
     s->do_nodelay = do_nodelay && !is_unix;
+    s->wait_connect = is_waitconnect;
+    s->device_handles_connect = is_device_handles_connect;
 
     chr->opaque = s;
     chr->chr_write = tcp_chr_write;
     chr->chr_close = tcp_chr_close;
+    chr->chr_connect = tcp_chr_do_connect;
 
     if (is_listen) {
         s->listen_fd = fd;
@@ -2158,13 +2230,17 @@
         if (is_telnet)
             s->do_telnetopt = 1;
     } else {
-        s->connected = 1;
         s->fd = fd;
-        socket_set_nodelay(fd);
-        tcp_chr_connect(chr);
+        
+        if (!is_device_handles_connect)
+        {
+            s->connected = 1;
+            socket_set_nodelay(fd);
+            tcp_chr_connect(chr);
+        }
     }
 
-    if (is_listen && is_waitconnect) {
+    if (is_listen && is_waitconnect && !is_device_handles_connect) {
         printf("QEMU waiting for connection on: %s\n",
                chr->filename ? chr->filename : host_str);
         tcp_chr_accept(chr);
@@ -2220,6 +2296,8 @@
 	chr = qemu_chr_open_tcp(p, 0, 1);
     } else if (strstart(filename, "file:", &p)) {
         chr = qemu_chr_open_file_out(p);
+    } else if (strstart(filename, "tempfile:", &p)) {
+        chr = qemu_chr_open_tempfile_out(p);
     } else if (strstart(filename, "pipe:", &p)) {
         chr = qemu_chr_open_pipe(p);
     } else if (!strcmp(filename, "pty")) {
@@ -2252,6 +2330,9 @@
     if (strstart(filename, "file:", &p)) {
         chr = qemu_chr_open_win_file_out(p);
     } else
+    if (strstart(filename, "tempfile:", &p)) {
+        chr = qemu_chr_open_win_tempfile_out(p);
+    } else
     if (strstart(filename, "stdio", &p)) {
         return qemu_chr_open_win_stdio(filename);
     } else
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.h	Fri Jan 08 12:04:26 2010 +0000
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/qemu-char.h	Sat Feb 27 19:18:04 2010 +0000
@@ -46,6 +46,7 @@
     int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
     void (*chr_update_read_handler)(struct CharDriverState *s);
     int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
+    void (*chr_connect)(struct CharDriverState *s);
     IOEventHandler *chr_event;
     IOCanRWHandler *chr_can_read;
     IOReadHandler *chr_read;
@@ -64,6 +65,7 @@
 CharDriverState *qemu_chr_open(const char *label, const char *filename);
 void qemu_chr_close(CharDriverState *chr);
 void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
+void qemu_chr_connect(CharDriverState *s);
 int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
 void qemu_chr_send_event(CharDriverState *s, int event);
 void qemu_chr_add_handlers(CharDriverState *s,
--- a/symbian-qemu-0.9.1-12/qemu-symbian-svp/vl.c	Fri Jan 08 12:04:26 2010 +0000
+++ b/symbian-qemu-0.9.1-12/qemu-symbian-svp/vl.c	Sat Feb 27 19:18:04 2010 +0000
@@ -4666,14 +4666,12 @@
     cyls = heads = secs = 0;
     translation = BIOS_ATA_TRANSLATION_AUTO;
     monitor_device = "vc";
-
-    serial_devices[0] = "vc:80Cx24C";
-    for(i = 1; i < MAX_SERIAL_PORTS; i++)
+    
+    for(i = 0; i < MAX_SERIAL_PORTS; i++)
         serial_devices[i] = NULL;
     serial_device_index = 0;
-
-    parallel_devices[0] = "vc:640x480";
-    for(i = 1; i < MAX_PARALLEL_PORTS; i++)
+    
+    for(i = 0; i < MAX_PARALLEL_PORTS; i++)
         parallel_devices[i] = NULL;
     parallel_device_index = 0;