cryptoplugins/cryptospiplugins/test/h4drv/crypto_h4/cryptoh4.cpp
changeset 8 35751d3474b7
child 15 da2ae96f639b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cryptoplugins/cryptospiplugins/test/h4drv/crypto_h4/cryptoh4.cpp	Thu Sep 10 14:01:51 2009 +0300
@@ -0,0 +1,344 @@
+/*
+* Copyright (c) 2007-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: 
+*
+*/
+
+
+/**
+ @file
+ @internalComponent
+ @released
+*/
+#include <kernel/kern_priv.h>
+#include <cryptodriver.h>
+#ifdef __MARM__
+#include <omap_hrp/assp/shared/omap_reg.h>
+#include <omap_hrp/assp/shared/omap_interrupt.h>
+#endif
+#include "cryptoh4.h"
+#include "cryptoh4rng.h"
+#include "cryptoh4aes.h"
+
+DECLARE_STANDARD_PDD()
+    {
+    return new DCryptoPddFactory;
+    }
+
+// Name for PDD, must match LDD name with a '.' and distinguishing name appended
+_LIT(KCryptoH4PddName,"crypto.h4");
+
+DCryptoPddFactory::DCryptoPddFactory()
+	// : iDfcQueInitialised(EFalse)
+    {
+	TRACE_FUNCTION("DCryptoPddFactory");
+	// Set version number for this device
+	//
+	// We re-use the version number of the LDD which effectively
+	// specifies the version of both the external RCryptoDriver
+	// interface to the LDD and the internal LDD to PDD interface.
+    iVersion=RCryptoDriver::VersionRequired();
+    }
+
+void DCryptoPddFactory::DeleteDfcQFunc(TAny *p)
+	{
+	TRACE_FUNCTION("DeleteDfcQFunc");
+	// We do not need to delete the TDfc because it is a static
+	// Delete the DFC queue.
+	TDfcQue *q = reinterpret_cast<TDfcQue *>(p);
+	delete q;
+	// Delete our thread
+	Kern::Exit(KErrNone);
+	}
+
+TDfc deleteDfcQDfc(0, 0, 0); // Dummy create, will be overwritten later
+
+DCryptoPddFactory::~DCryptoPddFactory()
+	{
+	TRACE_FUNCTION("~DCryptoPddFactory");
+	if(iDfcQueInitialised)
+		{
+		// Need to shutdown our DFC queue.
+		// 
+		// In theory the DFC could run after we have returned and the
+		// framework has deleting everything...
+		// 
+		// But the DLL will NOT be unloaded until the next time the
+		// IDLE task runs, so we know the DFC will reach completion
+		// before then (but it most not use any of our members....
+		//
+		// For the same reason we should use a TDfc which is not
+		// inside this object.
+		deleteDfcQDfc = TDfc(DeleteDfcQFunc, iDfcQue, iDfcQue, 0);
+		deleteDfcQDfc.Enque();
+		iDfcQueInitialised = EFalse;
+		}
+	}
+
+
+
+
+// Missing h/w registers & masks
+const TUint KHtRngSysResetStatus = KBit0;
+
+/**
+  Second stage constructor for DPhysicalDevice derived objects.
+  This must at least set a name for the driver object.
+
+  @return KErrNone or standard error code.
+*/
+_LIT(KCryptoHwQueueName, "CryptoHwDfcQue");
+TInt DCryptoPddFactory::Install()
+    {
+	TRACE_FUNCTION("Install");
+	// 28 is the recommended setting for a low priority kernel driver
+	// (I can't find an enum for this).
+	TInt r = Kern::DfcQCreate(iDfcQue, 28, &KCryptoHwQueueName);
+	if(r != KErrNone)
+		{
+		return r;
+		}
+	iDfcQueInitialised = ETrue;
+
+	// Reset h/w
+	Kern::Printf("DCryptoPddFactory::Install - Reseting h/w");
+#ifdef __MARM__
+	// RNG
+	// The RNG has no state worth reseting - a reset would delay the
+	// availabilty of a new random number (and maybe reduce its
+	// quality).
+	//	TOmap::SetRegister32(KHwBaseRngReg + KHoRng_Mask, KHtRngMaskSoftReset);
+
+	// DES/3DES
+	TOmap::SetRegister32(KHwBaseDes3DesReg + KHoDES_MASK, KHtDesMaskSoftReset);
+
+	// SHA1/MD5
+	TOmap::SetRegister32(KHwBaseSha1Md5Reg + KHoSHA_MASK, KHtShaMaskSoftReset);
+
+	// AES
+	TOmap::SetRegister32(KHwBaseAesReg + KHoAES_MASK, KHtAesMaskSoftReset);
+
+	// PKA
+	TOmap::SetRegister32(KHwBasePkaReg + KHoPKA_MASK, KHtPkaMaskSoftReset);
+	
+	// Make sure all cypto h/w (rng/des/sha1/aes/pka) is out of reset
+	while(((TOmap::Register32(KHwBaseRngReg + KHoRng_SysStatus) & KHtRngSysResetStatus) == 0) ||
+		  ((TOmap::Register32(KHwBaseDes3DesReg + KHoDES_SYSSTATUS) & KHtDesSysResetStatus) == 0) ||
+		  ((TOmap::Register32(KHwBaseSha1Md5Reg + KHoSHA_SYSSTATUS) & KHtShaSysResetStatus) == 0) ||
+		  ((TOmap::Register32(KHwBaseAesReg + KHoAES_SYSSTATUS) & KHtAesSysResetStatus) == 0) ||
+		  ((TOmap::Register32(KHwBasePkaReg + KHoPKA_SYSSTATUS) & KHtPkaSysResetStatus) == 0))
+		{
+		Kern::Printf("DCryptoPddFactory::Install - waiting for h/w");
+		}
+
+#endif
+	//	Kern::Printf("DCryptoPddFactory::Install - h/w reset complete");
+
+    return SetName(&KCryptoH4PddName);
+    }
+
+
+
+
+/**
+   Returns the drivers capabilities.
+
+   This is required by the Symbian OS device driver framework.
+   
+   It can NOT be used by the LDD factory GetCaps function because that
+   class does not contain a link tous (and we might not be loaded)....
+
+   NOT USED IN THIS DRIVER.
+   
+   @param aDes Descriptor to write capabilities information into
+*/
+void DCryptoPddFactory::GetCaps(TDes8& /* aDes */) const
+	{
+	TRACE_FUNCTION("GetCaps");
+	}
+
+
+/**
+  Called by the kernel's device driver framework to create a Physical Channel.
+  This is called in the context of the user thread (client) which requested the creation of a Logical Channel
+  (E.g. through a call to RBusLogicalChannel::DoCreate)
+  The thread is in a critical section.
+
+  @param aChannel Set to point to the created Physical Channel
+  @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate
+  @param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate
+  @param aVer The version number of the Logical Channel which will use this Physical Channel 
+
+  @return KErrNone or standard error code.
+*/
+TInt DCryptoPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
+    {
+	TRACE_FUNCTION("Create");
+    // Ignore the parameters we aren't interested in...
+    (void)aUnit;
+    (void)aInfo;
+    (void)aVer;
+
+    // Create a new physical channel
+DCryptoH4Chan* device=new DCryptoH4Chan(*this);
+    aChannel=device;
+    if (!device)
+        return KErrNoMemory;
+    return device->DoCreate();
+    }
+
+/**
+  Called by the kernel's device driver framework to check if this PDD is suitable for use with a Logical Channel.
+  This is called in the context of the user thread (client) which requested the creation of a Logical Channel
+  (E.g. through a call to RBusLogicalChannel::DoCreate)
+  The thread is in a critical section.
+
+  @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate
+  @param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate
+  @param aVer The version number of the Logical Channel which will use this Physical Channel 
+
+  @return KErrNone or standard error code.
+*/
+TInt DCryptoPddFactory::Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
+    {
+	TRACE_FUNCTION("Validate");
+    // Check version numbers
+    if ((!Kern::QueryVersionSupported(iVersion,aVer)) || (!Kern::QueryVersionSupported(aVer,TVersion(EMinimumLddMajorVersion,EMinimumLddMinorVersion,EMinimumLddBuild))))
+        return KErrNotSupported;
+
+    // We don't support units
+    if (aUnit != -1)
+        return KErrNotSupported;
+
+    // Ignore extra info, (this could be used for validation purposes)
+    // Note, aInfo is a pointer to a descriptor in user memory, therefore safe methods should
+    // be used for reading its contents. E.g. using Kern::KUDesGet()
+    (void)aInfo;
+
+    // OK
+    return KErrNone;
+    }
+
+
+TDfcQue *DCryptoPddFactory::DfcQue()
+	{
+	TRACE_FUNCTION("DfcQue");
+	return iDfcQue;
+	}
+
+
+
+//
+// DCryptoH4Chan
+//
+
+DCryptoH4Chan::DCryptoH4Chan(DCryptoPddFactory &iCryptoPddFactory)
+    : iCryptoPddFactory(iCryptoPddFactory),
+	  iFakeDriverSetting(100000)
+    {
+	TRACE_FUNCTION("DCryptoH4Chan");
+    }
+
+DCryptoH4Chan::~DCryptoH4Chan()
+    {
+	TRACE_FUNCTION("~DCryptoH4Chan");
+	if(iCryptoJobRandom)
+		{
+		// Make sure we are not queued on a job scheduler.
+		iCryptoJobRandom->DeScheduleJob();
+		delete iCryptoJobRandom;
+		}
+	if(iCryptoJobAes)
+		{
+		// Make sure we are not queued on a job scheduler.
+		iCryptoJobAes->DeScheduleJob();
+		delete iCryptoJobAes;
+		}
+    }
+
+
+TInt DCryptoH4Chan::DoCreate()
+    {
+	TRACE_FUNCTION("DoCreate");
+
+
+    return KErrNone;
+    }
+
+TDfcQue* DCryptoH4Chan::DfcQue()
+    {
+	TRACE_FUNCTION("DfcQue");
+    return iCryptoPddFactory.DfcQue();
+    }
+
+void DCryptoH4Chan::GetHwVersions(RCryptoDriver::THwVersions &aHwVersions) const
+	{
+	TRACE_FUNCTION("THwVersions");
+#ifdef __MARM__
+	aHwVersions.iRngHwVersion = TOmap::Register32(KHwBaseRngReg + KHoRng_Rev);
+	aHwVersions.iDes3DesHwVersion = TOmap::Register32(KHwBaseDes3DesReg + KHoDES_REV);
+	aHwVersions.iSha1Md5HwVersion = TOmap::Register32(KHwBaseSha1Md5Reg + KHoSHA_REV);
+	aHwVersions.iAesHwVersion = TOmap::Register32(KHwBaseAesReg + KHoAES_REV);
+	aHwVersions.iPkaHwVersion = TOmap::Register32(KHwBasePkaReg + KHoPKA_REV);
+	TOmap::SetRegister32(KHwBasePkaReg + KHoPKA_REV,42);
+	aHwVersions.iPkaHwVersion = TOmap::Register32(KHwBasePkaReg + KHoPKA_REV);
+#else
+	// Return fake hardware versions for testing
+	aHwVersions.iRngHwVersion = 42;
+	aHwVersions.iDes3DesHwVersion = 43;
+	aHwVersions.iSha1Md5HwVersion = 44;
+	aHwVersions.iAesHwVersion = 45;
+	aHwVersions.iPkaHwVersion = 46;
+#endif
+    }
+
+TInt DCryptoH4Chan::FakeDriverSetting() const
+    {
+	TRACE_FUNCTION("FakeDriverSetting");
+    return iFakeDriverSetting;
+    }
+
+TInt DCryptoH4Chan::SetFakeDriverSetting(TInt aFakeDriverSetting)
+    {
+	TRACE_FUNCTION("SetFakeDriverSetting");
+    if(aFakeDriverSetting<=0)
+        return KErrArgument;
+    iFakeDriverSetting = aFakeDriverSetting;
+    return KErrNone;
+    }
+
+CryptoJobRandom *DCryptoH4Chan::GetJobRandom(TBool aAutoCreate)
+	{
+	TRACE_FUNCTION("GetJobRandom");
+	if(aAutoCreate && iCryptoJobRandom == 0)
+		{
+		iCryptoJobRandom = new CryptoH4JobRandom(iCryptoLddChannel->iLddChanRandom);
+		iCryptoJobRandom->SetDfcQ(DfcQue());
+		}
+	return iCryptoJobRandom;
+	}
+
+CryptoJobAes *DCryptoH4Chan::GetJobAes(TBool aAutoCreate)
+	{
+	TRACE_FUNCTION("GetJobAes");
+	if(aAutoCreate && iCryptoJobAes == 0)
+		{
+		iCryptoJobAes = new CryptoH4JobAes(iCryptoLddChannel->iLddChanAes);
+		iCryptoJobAes->SetDfcQ(DfcQue());
+		}
+	return iCryptoJobAes;
+	}
+
+
+// End of file