baseport/src/cedar/generic/base/syborg/svpsnapdriver/src/svpsnapdriver.cpp
changeset 0 ffa851df0825
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/src/cedar/generic/base/syborg/svpsnapdriver/src/svpsnapdriver.cpp	Fri Jul 31 14:43:15 2009 +0100
@@ -0,0 +1,247 @@
+/*
+* 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 "svpsnapdriver.h"
+#include "rsvpsnapdriver.h"
+#include "system.h"
+
+static inline TUint32 ReadReg(ESVPSnapReg aReg)
+{
+  DP("** (SVPSNAPDRIVER) ReadReg(%d)",aReg);
+
+	return *(volatile TUint32 *)(KHwSVPSnapDevice + (aReg << 2));
+}
+
+static inline void WriteReg(ESVPSnapReg aReg, TUint32 aVal)
+{
+  DP("** (SVPSNAPDRIVER) WriteReg(%d,%d)",aReg,aVal);
+
+  *(volatile TUint32*)(KHwSVPSnapDevice + (aReg << 2)) = aVal;
+}
+
+//
+// DSVPSnapDriverFactory
+//
+
+DSVPSnapDriverFactory::DSVPSnapDriverFactory()
+{
+  DP("** (SVPSNAPDRIVER) DSVPSnapDriverFactory::DSVPSnapDriverFactory()");
+
+  iVersion = TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);    
+}
+
+TInt DSVPSnapDriverFactory::Create(DLogicalChannelBase*& aChannel)
+{
+  DP("** (SVPSNAPDRIVER) DSVPSnapDriverFactory::Create()");
+	
+#if 0
+  if (iOpenChannels != 0)
+	return KErrInUse; // a channel is already open
+#endif
+	
+	aChannel = new DSVPSnapChannel(this);
+	
+	return aChannel ? KErrNone : KErrNoMemory;
+}
+
+TInt DSVPSnapDriverFactory::Install()
+{
+  DP("** (SVPSNAPDRIVER) DSVPSnapDriverFactory::Install()");
+
+  return(SetName(&KSVPSnapDriverName));
+}
+
+void DSVPSnapDriverFactory::GetCaps(TDes8& aDes) const
+{
+  DP("** (SVPSNAPDRIVER) DSVPSnapDriverFactory::GetCaps()");
+
+  TCapsSVPSnapDriver b;
+  b.iVersion = TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber);
+  aDes.FillZ(aDes.MaxLength());
+  aDes.Copy((TUint8 *)&b, Min(aDes.MaxLength(), sizeof(b)));
+}
+
+//
+// DSVPSnapChannel
+//
+
+DSVPSnapChannel::DSVPSnapChannel(DLogicalDevice* aLogicalDevice)
+{
+  DP("** (SVPSNAPDRIVER) DSVPSnapChannel::DSVPSnapChannel()");
+
+  iDevice = aLogicalDevice;
+  
+  iClientThread = &Kern::CurrentThread();
+  iClientThread->Open();
+}
+
+DSVPSnapChannel::~DSVPSnapChannel()
+{
+  DP("** (SVPSNAPDRIVER) DSVPSnapChannel::~DSVPSnapChannel() ->");
+  Kern::SafeClose((DObject*&)iClientThread, NULL);
+  DP("** (SVPSNAPDRIVER) DSVPSnapChannel::~DSVPSnapChannel() <-");
+}
+
+TInt DSVPSnapChannel::DoCreate(TInt /*aUnit*/, const TDesC* anInfo, const TVersion& aVer)
+{
+  DP("** (SVPSNAPDRIVER) DSVPSnapChannel::DoCreate()");
+
+  if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber), aVer))
+	return KErrNotSupported; 
+		       
+  //Setup the driver for receiving client messages
+  SetDfcQ(Kern::DfcQue0());
+  iMsgQ.Receive();  	
+
+  DP("** (SVPSNAPDRIVER) DSVPSnapChannel::DoCreate()- checking device");
+  TUint id = ReadReg(ESnapshot_Id);
+  DP("** (SVPSNAPDRIVER) DSVPSnapChannel::DoCreate()- checked device- 0x%08x", id);
+  WriteReg(ESnapshot_Address, 0);
+  return KErrNone;
+}
+
+void DSVPSnapChannel::DoCancel(TInt aReqNo)
+{
+  DP("** (SVPSNAPDRIVER) DSVPSnapChannel::DoCancel() %x(%d)", aReqNo, aReqNo);
+}
+
+TInt DSVPSnapChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
+{
+  DP("** (SVPSNAPDRIVER) DSVPSnapChannel::DoRequest() %x(%d)", aReqNo, aReqNo);
+
+  TInt err = KErrGeneral;         
+
+  switch(aReqNo)
+	{
+	case RSVPSnapDriver::ESaveVM:
+	  	  DP("RSVPSnapDriver::ESaveVM");
+	  	  err = SaveVM((const TDesC8*)a1);
+	  break;
+	case RSVPSnapDriver::ELoadVM:
+	  	 DP("RSVPSnapDriver::ELoadVM");
+	  	 err= LoadVM((const TDesC8*)a1);
+	  break;
+	default:
+	  	  DP("default");
+	  err = KErrGeneral;
+	  break;
+	}
+	
+  if (KErrNone != err)
+	DP("** (SVPSNAPDRIVER) Error %d from DoRequest", err);
+	
+  return err;
+}
+
+TInt DSVPSnapChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2)
+{
+  DP("** (SVPSNAPDRIVER) DSVPSnapChannel::DoControl(%d)", aFunction);
+
+  TInt err = KErrGeneral;         
+  /* There should be a good reason to use a control rather than a request. */
+
+  if (KErrNone != err) {
+	DP("** (SVPSNAPDRIVER) Error %d from control function", err);
+  }
+	
+  return err;
+}
+
+void DSVPSnapChannel::HandleMsg(TMessageBase* aMsg)
+{
+	
+  TThreadMessage& m = *(TThreadMessage*)aMsg;
+  TInt id = m.iValue;
+  
+  DP("** (SVPSNAPDRIVER) DSVPSnapChannel::HandleMsg() %x(%d)", id, id);
+
+  if (id == (TInt)ECloseMsg)
+	{
+	  m.Complete(KErrNone, EFalse); 
+	  return;
+	}
+  if (id == KMaxTInt)
+	{
+	  // DoCancel
+	  DoCancel(m.Int0());
+	  m.Complete(KErrNone, ETrue); 
+	  return;
+	}
+  if (id < 0)
+	{
+	  // DoRequest
+	  TRequestStatus* pStatus = (TRequestStatus*)m.Ptr0();
+	  TInt r = DoRequest(~id, pStatus, m.Ptr1(), m.Ptr2());
+	  //	  if (r != KErrNone)
+	  Kern::RequestComplete(iClientThread,pStatus,r);
+	  m.Complete(KErrNone, ETrue);
+	}
+  else
+	{
+	  // DoControl
+	  TInt r = DoControl(id, m.Ptr0(), m.Ptr1());
+	  m.Complete(r, ETrue);
+	}
+}
+
+TInt DSVPSnapChannel::SaveVM(const TDesC8* aData)
+{
+  DP("** DSVPSnapChannel::SaveVM()");
+   
+  TInt err = KErrNone; 
+  RET_IF_ERROR(err, Kern::ThreadDesRead(iClientThread, aData, iSendDataBuffer,0));
+  TUint32 * ptr = (TUint32*) iSendDataBuffer.Ptr();
+  
+  WriteReg(ESnapshot_Address, Epoc::LinearToPhysical((TUint32)ptr));
+  WriteReg(ESnapshot_Length, (TUint32) (iSendDataBuffer.Length()));
+  WriteReg(ESnapshot_Trigger, RSVPSnapDriver::ESaveVM);
+  
+  return err;
+}
+
+TInt DSVPSnapChannel::LoadVM(const TDesC8* aData)
+{
+  DP("** DSVPSnapChannel::LoadVM()");  
+
+  TInt err = KErrNone; 
+  RET_IF_ERROR(err, Kern::ThreadDesRead(iClientThread, aData, iSendDataBuffer,0));
+  
+  TUint32 * ptr = (TUint32*) iSendDataBuffer.Ptr();  
+  WriteReg(ESnapshot_Address, Epoc::LinearToPhysical((TUint32)ptr));
+  
+  return ReadReg(ESnapshot_Address);
+}
+
+DECLARE_EXTENSION_LDD()
+{
+  // FIXME: Not needed?
+  DP("** (SVPSNAPDRIVER) DSVPSnapDriverFactory created");
+  return new DSVPSnapDriverFactory;
+}
+
+DECLARE_STANDARD_EXTENSION()
+{
+  DP("** (SVPSNAPDRIVER) SVPSnap extension entry point");
+  TInt r;
+  DSVPSnapDriverFactory* device = new DSVPSnapDriverFactory;
+  if (device==NULL)
+	r=KErrNoMemory;
+  else
+	r=Kern::InstallLogicalDevice(device);
+  
+  return r;
+}