kernel/eka/drivers/pbus/mmc/rpmbstack.cpp
changeset 287 ddfd5aa0d58f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/pbus/mmc/rpmbstack.cpp	Mon Oct 11 19:11:06 2010 +0100
@@ -0,0 +1,356 @@
+// 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:
+//
+// Description:
+//
+
+/**
+ @file
+ @internalComponent
+ @prototype
+*/
+
+#include <drivers/mmc.h>
+#include <drivers/rpmbpacket.h>
+
+#include "OstTraceDefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "../../../include/drivers/locmedia_ost.h"
+#ifdef __VC32__
+#pragma warning(disable: 4127) // disabling warning "conditional expression is constant"
+#endif
+#include "rpmbstackTraces.h"
+#endif
+
+TMMCErr DMMCStack::CIMRpmbAccessSM()
+    {
+enum TStates
+        {
+        EStBegin,
+        EStEnd
+        };
+
+    DMMCSession& s=Session();
+
+    //Extract the RPMB request type from the command. JEDEC specify this to be situated
+    //at offset 0 in the packet. When accessing the hardware, this is reversed and is 
+    //at offset 511
+	TUint8 requestType = * (s.Command().iDataMemoryP + KRpmbRequestLsbOffset);
+	
+	//There are 5 possible rpmb request types that can be passed through the state machines:
+	//
+	//Authentication Key programming request:     KRpmbRequestWriteKey = 0x001
+	//Reading of the write counter value request: KRpmbRequestReadWriteCounter = 0x0002;
+	//Authenticated data write request:           KRpmbRequestWriteData = 0x0003;
+	//Authenticated data read request:            KRpmbRequestReadData = 0x0004;
+	//Result read request:                        KRpmbRequestReadResultRegister = 0x0005;
+	//
+
+	SMF_BEGIN
+	
+    switch (requestType)
+        {
+        case KRpmbRequestWriteKey:
+			SMF_INVOKES(CIMRpmbWriteAuthenticationKeySMST, EStEnd);
+        case KRpmbRequestReadWriteCounter:
+			SMF_INVOKES(CIMRpmbReadWrCounterSMST, EStEnd);
+        case KRpmbRequestWriteData:
+			SMF_INVOKES(CIMRpmbWriteSMST, EStEnd);
+        case KRpmbRequestReadData:
+ 			SMF_INVOKES(CIMRpmbReadSMST, EStEnd);
+        default:
+            break;   
+        }
+
+    SMF_END
+}
+
+
+TMMCErr DMMCStack::CIMRpmbWriteAuthenticationKeySM()
+    {
+    enum TStates
+        {
+        EStBegin,   // Write key request
+        EStSetupReadRequest,
+        EStReadResult,
+        EStError,
+        EStEnd
+        };
+
+    DMMCSession& s=Session();
+
+	SMF_BEGIN
+
+        //
+        // Setup write request
+        // CMD23 Reliable Write = 1 Block Count = 1
+        // CMD25
+        // 
+        s.SetupRpmbSendRequest(ETrue);
+		//
+        // KMMCErrByPass is routinely thrown in the ReadWriteBlocks state machine. 
+        // It is thrown to indicate that the current command in the state machine is not CMD42(lock/unlock)
+        // We need to trap this error here to stop the RPMB state machines from unravelling and passing
+        // the error upwards. 
+        //	
+		m.SetTraps(KMMCErrBypass);
+		
+		OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBWRITEAUTHENTICATIONKEYSM1, "RPMB: Write Key State Machine - send write key request packet");
+        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Write Key State Machine - send write key request packet"));
+        
+        SMF_INVOKES(CIMReadWriteBlocksSMST, EStSetupReadRequest);
+
+    SMF_STATE(EStSetupReadRequest)
+
+        OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBWRITEAUTHENTICATIONKEYSM2, "RPMB: Write Key State Machine - sent write key request packet");
+        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Write Key State Machine - sent write key request packet"));
+    
+		if (err != KMMCErrNone)
+			{
+		    OstTrace1(TRACE_FLOW, DMMCSTACK_CIMRPMBWRITEAUTHENTICATIONKEYSM3, "RPMB: Write Key State Machine - sent write key request packet error = %d", err);
+		    __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Write Key State Machine - sent write key request packet error = %d", err));
+			SMF_GOTOS(EStError);
+			}
+		// 
+        // Setup read result register request
+        // CMD23 Reliable Write = 0 Block Count = 1
+        // CMD25
+        //
+		s.SetupRpmbSendReadResultRegisterRequest();
+		OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBWRITEAUTHENTICATIONKEYSM4, "RPMB: Write Key State Machine - send read result register request packet");
+		__KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Write Key State Machine - send read result register request packet"));
+        SMF_INVOKES(CIMReadWriteBlocksSMST, EStReadResult)
+
+    SMF_STATE(EStReadResult)
+
+        OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBWRITEAUTHENTICATIONKEYSM5, "RPMB: Write Key State Machine - sent read result register request packet");
+        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Write Key State Machine - sent read result register request packet"));
+
+        if (err != KMMCErrNone)
+            {
+            OstTrace1(TRACE_FLOW, DMMCSTACK_CIMRPMBWRITEAUTHENTICATIONKEYSM6, "RPMB: Write Key State Machine - sent read result register request packet error = %d", err);
+            __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Write Key State Machine - sent read result register request packet error = %d", err));
+            SMF_GOTOS(EStError);
+            }
+        //
+        // Setup read response
+        // CMD23 Reliable Write = 0 Block Count = 1
+        // CMD18
+        //        
+        s.SetupRpmbReceiveResponse();
+        OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBWRITEAUTHENTICATIONKEYSM7, "RPMB: Write Key State Machine - get read packet");
+        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Write Key State Machine - get read packet"));
+        SMF_INVOKES(CIMReadWriteBlocksSMST, EStEnd);
+
+    SMF_STATE(EStError)
+        SMF_RETURN(err);
+
+    SMF_END
+    }
+
+
+TMMCErr DMMCStack::CIMRpmbReadWrCounterSM()
+    {
+    enum TStates
+        {
+        EStBegin,   // Read counter request
+        EStReadResult,
+        EStError,
+        EStEnd
+        };
+
+    DMMCSession& s=Session();
+
+	SMF_BEGIN
+	
+        //
+        // Setup write request
+        // CMD23 Reliable Write = 0 Block Count = 1
+        // CMD25
+        // 
+        s.SetupRpmbSendRequest(EFalse);
+        m.SetTraps(KMMCErrBypass);
+        
+        OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBREADWRCOUNTERSM1, "RPMB: Read Write Counter State Machine - send read counter request packet");
+        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Read Write Counter State Machine - send read counter request packet"));
+ 
+        SMF_INVOKES(CIMReadWriteBlocksSMST, EStReadResult)
+
+    SMF_STATE(EStReadResult)
+
+        OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBREADWRCOUNTERSM2, "RPMB: Read Write Counter State Machine - sent read counter request packet");
+        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Read Write Counter State Machine - sent read counter request packet"));
+
+        if (err != KMMCErrNone)
+            {
+            OstTrace1(TRACE_FLOW, DMMCSTACK_CIMRPMBREADWRCOUNTERSM3, "RPMB: Read Write Counter State Machine - sent read counter request packet error = %d", err);
+            __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Read Write Counter State Machine - sent read counter request packet error = %d", err));
+            SMF_GOTOS(EStError);
+            }
+        //
+        // Setup read response
+        // CMD23 Reliable Write = 0 Block Count = 1
+        // CMD18
+        //        
+        s.SetupRpmbReceiveResponse();
+        OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBREADWRCOUNTERSM4, "RPMB: Read Write Counter State Machine - get read packet");
+        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Read Write Counter State Machine - get read packet"));
+       SMF_INVOKES(CIMReadWriteBlocksSMST, EStEnd);
+
+    SMF_STATE(EStError)
+        SMF_RETURN(err);
+
+    SMF_END
+    }
+
+
+TMMCErr DMMCStack::CIMRpmbWriteSM()
+    {
+    enum TStates
+        {
+        EStBegin,   // Write data request
+        EStSetupReadRequest,
+        EStReadResult,
+        EStError,
+        EStEnd
+        };
+
+    DMMCSession& s=Session();
+
+	SMF_BEGIN
+
+        //
+        // Setup write request
+        // CMD23 Reliable Write = 1 Block Count = 1
+        // CMD25
+        // 
+        s.SetupRpmbSendRequest(ETrue);
+	    m.SetTraps(KMMCErrBypass);
+	    
+	    OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBWRITESM1, "RPMB: Write State Machine - send write request packet");
+	    __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Write State Machine - send write request packet"));
+
+	    SMF_INVOKES(CIMReadWriteBlocksSMST, EStSetupReadRequest);
+
+    SMF_STATE(EStSetupReadRequest)
+	    
+	    OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBWRITESM2, "RPMB: Write State Machine - sent write request packet");
+	    __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Write State Machine - sent write request packet"));
+
+		if (err != KMMCErrNone)
+			{
+		    OstTrace1(TRACE_FLOW, DMMCSTACK_CIMRPMBWRITESM3, "RPMB: Write State Machine - sent write request packet error = %d", err);
+		    __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Write State Machine - sent write request packet error = %d", err));
+			SMF_GOTOS(EStError);
+			}	
+        // 
+        // Setup read result register request
+        // CMD23 Reliable Write = 0 Block Count = 1
+        // CMD25
+        //
+        s.SetupRpmbSendReadResultRegisterRequest();
+        OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBWRITESM4, "RPMB: Write State Machine - send read result register request packet");
+        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Write State Machine - send read result register request packet"));
+        SMF_INVOKES(CIMReadWriteBlocksSMST, EStReadResult)
+
+    SMF_STATE(EStReadResult)
+        
+        OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBWRITESM5, "RPMB: Write State Machine - sent read result register request packet");
+        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Write State Machine - sent read result register request packet"));
+
+        if (err != KMMCErrNone)
+            {
+            OstTrace1(TRACE_FLOW, DMMCSTACK_CIMRPMBWRITESM6, "RPMB: Write State Machine - sent read result register request packet error = %d", err);
+            __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Write State Machine - sent read result register request packet error = %d", err));
+            SMF_GOTOS(EStError);
+            }
+        //
+        // Setup read response
+        // CMD23 Reliable Write = 0 Block Count = 1
+        // CMD18
+        //        
+        s.SetupRpmbReceiveResponse();
+        OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBWRITESM7, "RPMB: Write State Machine - get read packet");
+        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Write State Machine - get read packet"));
+        SMF_INVOKES(CIMReadWriteBlocksSMST, EStEnd);
+
+    SMF_STATE(EStError)
+       SMF_RETURN(err);
+
+    SMF_END
+    }
+
+
+TMMCErr DMMCStack::CIMRpmbReadSM()
+    {
+    enum TStates
+        {
+        EStBegin,   // Read data request
+        EStReadResult,
+        EStError,
+        EStEnd
+        };
+
+    DMMCSession& s=Session();
+
+    SMF_BEGIN
+         
+        //
+        // Setup write request
+        // CMD23 Reliable Write = 0 Block Count = 1
+        // CMD25
+        // 
+        s.SetupRpmbSendRequest(EFalse);
+        m.SetTraps(KMMCErrBypass);
+        
+        OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBREADSM1, "RPMB: Read State Machine - send read request packet");
+        __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Read State Machine - send read request packet"));
+
+		SMF_INVOKES(CIMReadWriteBlocksSMST, EStReadResult)
+
+    SMF_STATE(EStReadResult)
+        
+        OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBREADSM2, "RPMB: Read State Machine - sent read request packet");
+		__KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Read State Machine - sent read request packet"));
+		
+		if (err != KMMCErrNone)
+           {
+           OstTrace1(TRACE_FLOW, DMMCSTACK_CIMRPMBREADSM3, "RPMB: Read State Machine - sent read request packet error = %d", err);
+           __KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Read State Machine - sent read request packet error = %d", err));
+           SMF_GOTOS(EStError);
+           }
+        //
+        // Setup read response
+        // CMD23 Reliable Write = 0 Block Count = 1
+        // CMD18
+        //        
+		s.SetupRpmbReceiveResponse();
+		OstTrace0(TRACE_FLOW, DMMCSTACK_CIMRPMBREADSM4, "RPMB: Read State Machine - get read packet");
+		__KTRACE_OPT(KPBUS1, Kern::Printf("RPMB: Read State Machine - get read packet"));
+		SMF_INVOKES(CIMReadWriteBlocksSMST, EStEnd);
+
+    SMF_STATE(EStError)
+        SMF_RETURN(err);
+
+    SMF_END
+    }
+
+TMMCErr DMMCStack::CIMRpmbAccessSMST(TAny* aStackP)
+	{return(static_cast<DMMCStack*>(aStackP)->CIMRpmbAccessSM());}
+TMMCErr DMMCStack::CIMRpmbWriteAuthenticationKeySMST(TAny* aStackP)
+	{return(static_cast<DMMCStack*>(aStackP)->CIMRpmbWriteAuthenticationKeySM());}
+TMMCErr DMMCStack::CIMRpmbReadWrCounterSMST(TAny* aStackP)
+	{return(static_cast<DMMCStack*>(aStackP)->CIMRpmbReadWrCounterSM());}
+TMMCErr DMMCStack::CIMRpmbWriteSMST(TAny* aStackP)
+	{return(static_cast<DMMCStack*>(aStackP)->CIMRpmbWriteSM());}
+TMMCErr DMMCStack::CIMRpmbReadSMST(TAny* aStackP)
+	{return(static_cast<DMMCStack*>(aStackP)->CIMRpmbReadSM());}