diff -r 48e57fb1237e -r ddfd5aa0d58f kernel/eka/drivers/pbus/mmc/rpmbstack.cpp --- /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 +#include + +#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(aStackP)->CIMRpmbAccessSM());} +TMMCErr DMMCStack::CIMRpmbWriteAuthenticationKeySMST(TAny* aStackP) + {return(static_cast(aStackP)->CIMRpmbWriteAuthenticationKeySM());} +TMMCErr DMMCStack::CIMRpmbReadWrCounterSMST(TAny* aStackP) + {return(static_cast(aStackP)->CIMRpmbReadWrCounterSM());} +TMMCErr DMMCStack::CIMRpmbWriteSMST(TAny* aStackP) + {return(static_cast(aStackP)->CIMRpmbWriteSM());} +TMMCErr DMMCStack::CIMRpmbReadSMST(TAny* aStackP) + {return(static_cast(aStackP)->CIMRpmbReadSM());}