kernel/eka/include/drivers/mmc.inl
changeset 287 ddfd5aa0d58f
parent 279 957c583b417b
equal deleted inserted replaced
286:48e57fb1237e 287:ddfd5aa0d58f
     1 // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 1999-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    14 //
    14 //
    15 // WARNING: This file contains some APIs which are internal and are subject
    15 // WARNING: This file contains some APIs which are internal and are subject
    16 //          to change without noticed. Such APIs should therefore not be used
    16 //          to change without noticed. Such APIs should therefore not be used
    17 //          outside the Kernel and Hardware Services package.
    17 //          outside the Kernel and Hardware Services package.
    18 //
    18 //
       
    19 
       
    20 const TInt KOneKiloByte = 1024;
       
    21 const TInt KSectorSize  = 512;
    19 
    22 
    20 /**
    23 /**
    21  
    24  
    22  A static function that takes the 4 bytes that are stored in a memory location
    25  A static function that takes the 4 bytes that are stored in a memory location
    23  in ascending address order, and returns them as a 32-bit unsigned integer
    26  in ascending address order, and returns them as a 32-bit unsigned integer
   178 inline TUint TExtendedCSD::HighCapacityWriteProtectGroupSize() const {return iData[221];}
   181 inline TUint TExtendedCSD::HighCapacityWriteProtectGroupSize() const {return iData[221];}
   179 inline TUint TExtendedCSD::SleepCurrentVcc() const {return iData[220];}
   182 inline TUint TExtendedCSD::SleepCurrentVcc() const {return iData[220];}
   180 inline TUint TExtendedCSD::SleepCurrentVccQ() const {return iData[219];}
   183 inline TUint TExtendedCSD::SleepCurrentVccQ() const {return iData[219];}
   181 inline TUint TExtendedCSD::SleepAwakeTimeout() const {return iData[217];}
   184 inline TUint TExtendedCSD::SleepAwakeTimeout() const {return iData[217];}
   182 
   185 
       
   186 inline TUint TExtendedCSD::ErasedMemoryContent() const {return iData[181];}
       
   187 inline TUint TExtendedCSD::BootConfigProt() const {return iData[EBootConfigProtectionIndex];}
       
   188 inline TUint TExtendedCSD::BootAreaWriteProtectionReg() const {return iData[EBootAreaWriteProtectionIndex];}
       
   189 inline TUint TExtendedCSD::UserAreaWriteProtectionReg() const {return iData[EUserAreaWriteProtectionIndex];}
       
   190 inline TUint TExtendedCSD::FwConfiguration() const {return iData[EFwConfigIndex];}
       
   191 
       
   192 
       
   193 inline TUint32 TExtendedCSD::BootSizeInSectors() const
       
   194 	{
       
   195 		
       
   196 	return BootSizeMultiple() * 128 * KOneKiloByte / KSectorSize;
       
   197 	}
       
   198 
       
   199 inline TUint32 TExtendedCSD::RpmbSize() const 
       
   200     {
       
   201     return static_cast<TUint32>(iData[168]);
       
   202     }
       
   203     
       
   204 inline TUint32 TExtendedCSD::RpmbSizeInSectors() const 
       
   205 	{
       
   206 	
       
   207 	return RpmbSize() * 128 * KOneKiloByte / KSectorSize;
       
   208 	}
       
   209 
       
   210 inline TUint TExtendedCSD::HwResetFunction() const {return iData[EHardwareResetFunctionIndex];}
       
   211 inline TUint TExtendedCSD::PartitioningSupport() const {return iData[160];}
       
   212 
       
   213 inline TUint32 TExtendedCSD::MaxEnhancedAreaSize() const 
       
   214     {
       
   215     return(iData[157] | 
       
   216            (static_cast<TUint32>(iData[158]) << 8) | 
       
   217            (static_cast<TUint32>(iData[159]) << 16) * 
       
   218            HighCapacityWriteProtectGroupSize());
       
   219     }
       
   220 
       
   221 inline TUint TExtendedCSD::PartitionsAttribute() const {return iData[EPartitionsAttributeIndex];}
       
   222 inline TUint TExtendedCSD::PartitioningSetting() const {return iData[EPartitionSettingIndex];}
       
   223 
       
   224 inline TUint64 TExtendedCSD::PartitionSize(TUint8 aMult0, TUint8 aMult1, TUint8 aMult2, TUint32 aMultiplier) const
       
   225     {
       
   226     TUint64 size = static_cast<TUint64>(aMult2) * 8 * 8;
       
   227     size +=  static_cast<TUint64>(aMult1) * 8;
       
   228     size += static_cast<TUint64>(aMult0);
       
   229     
       
   230     size *= aMultiplier;
       
   231     return size;
       
   232     }
       
   233 
       
   234 inline TUint64 TExtendedCSD::GeneralPurposePartition1Size() const 
       
   235     {
       
   236     return PartitionSize(iData[143], 
       
   237                          iData[144], 
       
   238                          iData[145], 
       
   239                          (HighCapacityWriteProtectGroupSize() * HighCapacityEraseGroupSize() * 512 * 1024)
       
   240                         );            
       
   241     }
       
   242     
       
   243 inline TUint32 TExtendedCSD::GeneralPurposePartition1SizeInSectors() const 
       
   244 	{
       
   245 	return I64LOW(GeneralPurposePartition1Size() / KSectorSize);
       
   246 	}
       
   247 
       
   248 inline TUint64 TExtendedCSD::GeneralPurposePartition2Size() const 
       
   249     {
       
   250     return PartitionSize(iData[146], 
       
   251                          iData[147], 
       
   252                          iData[148], 
       
   253                          (HighCapacityWriteProtectGroupSize() * HighCapacityEraseGroupSize() * 512 * 1024)
       
   254                         );
       
   255     }
       
   256     
       
   257 inline TUint32 TExtendedCSD::GeneralPurposePartition2SizeInSectors() const 
       
   258 	{
       
   259 	return I64LOW(GeneralPurposePartition2Size() / KSectorSize);
       
   260 	}
       
   261 
       
   262     
       
   263 inline TUint64 TExtendedCSD::GeneralPurposePartition3Size() const 
       
   264     {
       
   265     return PartitionSize(iData[149], 
       
   266                          iData[150], 
       
   267                          iData[151], 
       
   268                          (HighCapacityWriteProtectGroupSize() * HighCapacityEraseGroupSize() * 512 * 1024)
       
   269                         );
       
   270     }
       
   271 
       
   272 inline TUint32 TExtendedCSD::GeneralPurposePartition3SizeInSectors() const 
       
   273 	{
       
   274 	return I64LOW(GeneralPurposePartition3Size() / KSectorSize);
       
   275 	}
       
   276 
       
   277 inline TUint64 TExtendedCSD::GeneralPurposePartition4Size() const 
       
   278     {
       
   279     return PartitionSize(iData[152], 
       
   280                          iData[153], 
       
   281                          iData[154], 
       
   282                          (HighCapacityWriteProtectGroupSize() * HighCapacityEraseGroupSize() * 512 * 1024)
       
   283                         );
       
   284 
       
   285     }
       
   286 
       
   287 inline TUint32 TExtendedCSD::GeneralPurposePartition4SizeInSectors() const 
       
   288 	{
       
   289 	return I64LOW(GeneralPurposePartition4Size() / KSectorSize);
       
   290 	}
       
   291 
       
   292 inline TUint64 TExtendedCSD::EnhancedUserDataAreaSize() const 
       
   293     {
       
   294     return PartitionSize(iData[140],
       
   295                          iData[141],
       
   296                          iData[142],
       
   297                          HighCapacityWriteProtectGroupSize()
       
   298                         );
       
   299     }
       
   300 
       
   301 inline TUint32 TExtendedCSD::EnhancedUserDataStartAddress() const 
       
   302     {
       
   303 	// note, for HC devices this is in sectors, otherwise in bytes
       
   304     return(iData[136] | 
       
   305            (static_cast<TUint32>(iData[137]) << 8) | 
       
   306            (static_cast<TUint32>(iData[138]) << 16) | 
       
   307            (static_cast<TUint32>(iData[139]) << 24));
       
   308     }
       
   309 
       
   310 inline TUint TExtendedCSD::BadBlockManagementMode() const {return iData[134];}
       
   311 
   183 // "Modes Segment" of Extended CSD - i.e. modifiable fields
   312 // "Modes Segment" of Extended CSD - i.e. modifiable fields
   184 inline TUint TExtendedCSD::CmdSet() const {return iData[ECmdSetIndex];}
   313 inline TUint TExtendedCSD::CmdSet() const {return iData[ECmdSetIndex];}
   185 inline TUint TExtendedCSD::CmdSetRev() const {return iData[ECmdSetRevIndex];}
   314 inline TUint TExtendedCSD::CmdSetRev() const {return iData[ECmdSetRevIndex];}
   186 inline TUint TExtendedCSD::PowerClass() const {return iData[EPowerClassIndex];}
   315 inline TUint TExtendedCSD::PowerClass() const {return iData[EPowerClassIndex];}
   187 inline TUint TExtendedCSD::HighSpeedTiming() const {return iData[EHighSpeedInterfaceTimingIndex];}
   316 inline TUint TExtendedCSD::HighSpeedTiming() const {return iData[EHighSpeedInterfaceTimingIndex];}
   942 	{
  1071 	{
   943 	__ASSERT_ALWAYS(--iCmdSP>=0,
  1072 	__ASSERT_ALWAYS(--iCmdSP>=0,
   944 		DMMCSocket::Panic(DMMCSocket::EMMCCommandStack));
  1073 		DMMCSocket::Panic(DMMCSocket::EMMCCommandStack));
   945 	}
  1074 	}
   946 
  1075 
       
  1076 
       
  1077 /**
       
  1078 Sets the target partition access bits
       
  1079 */	
       
  1080 inline void DMMCSession::SetPartition(TInt aPartition) 
       
  1081 	{
       
  1082 	TInt partition = aPartition & ~TExtendedCSD::EPartitionTestMode;
       
  1083 	__ASSERT_DEBUG( 
       
  1084 		partition >= TExtendedCSD::ESelectUserArea && 
       
  1085 		partition <= TExtendedCSD::ESelectGPAPartition4, 
       
  1086 		DMMCSocket::Panic(DMMCSocket::EMMCInvalidPartitionNumber));
       
  1087 		
       
  1088 		iPartition = partition;
       
  1089 		iPartition |= aPartition & TExtendedCSD::EPartitionTestMode;
       
  1090 	}
       
  1091 
       
  1092 
       
  1093 /**
       
  1094  * Returns the target partition
       
  1095  * @return The partition access identifier for which this session is destined
       
  1096 */	
       
  1097 inline TInt DMMCSession::Partition() const
       
  1098 	{
       
  1099 	return iPartition;
       
  1100 	}
       
  1101 
       
  1102 
   947 inline TMMCCommandDesc& DMMCSession::Command()
  1103 inline TMMCCommandDesc& DMMCSession::Command()
   948 /**
  1104 /**
   949  * Returns the current command, as referred to by the stack pointer.
  1105  * Returns the current command, as referred to by the stack pointer.
   950  * @return A TMMCCommandDesc reference, containing the current command.
  1106  * @return A TMMCCommandDesc reference, containing the current command.
   951  */
  1107  */
  1038 	ResetCommandStack();
  1194 	ResetCommandStack();
  1039 	FillCommandArgs(aBlockAddr, aBlocks << KMMCardHighCapBlockSizeLog2, NULL, 0);
  1195 	FillCommandArgs(aBlockAddr, aBlocks << KMMCardHighCapBlockSizeLog2, NULL, 0);
  1040 	Command().iFlags |= KMMCCmdFlagBlockAddress;
  1196 	Command().iFlags |= KMMCCmdFlagBlockAddress;
  1041 	iSessionID = ECIMEraseGroup;
  1197 	iSessionID = ECIMEraseGroup;
  1042 	}
  1198 	}
       
  1199 
       
  1200 inline void DMMCSession::SetupRpmbSendReadResultRegisterRequest()
       
  1201     {
       
  1202 /**
       
  1203  * Sets the session to send an RPMB read result register request to the RPMB partition.
       
  1204  *  
       
  1205  * Having set-up the session for this operation, the client must invoke, SMF_INVOKES. the 
       
  1206  * read write state machine. CIMReadWriteBlocksSM, and the operation will commence. The read
       
  1207  * write state machine initiates the result register read sequence by issuing the Write Multiple 
       
  1208  * command, CMD25. Prior to this the state machine has issued CMD23 with the block count set 
       
  1209  * to 1.
       
  1210  *  
       
  1211  *  
       
  1212  * All other RPMB request packets initiate an RPMB access and are constructed in the security code 
       
  1213  * and sent to the stack via the security driver and the RPMB kernel extension DLL. The result 
       
  1214  * register read request is used part ways through the program key and data write accesses to find 
       
  1215  * out about the success of the particular operation. It is not sent via the RPMB kernel extension 
       
  1216  * DLL so it is constructed here. Luckily it is easy to make.
       
  1217  */
       
  1218     TUint8* readRequestPtr = Command().iDataMemoryP;
       
  1219     memset(readRequestPtr, 0, KRpmbOneFramePacketLength);
       
  1220     * (readRequestPtr + KRpmbRequestLsbOffset) = KRpmbRequestReadResultRegister;
       
  1221     SetupRpmbSendRequest(EFalse);
       
  1222     }
       
  1223 
       
  1224 inline void DMMCSession::SetupRpmbSendRequest(TBool aSetReliableWrite)
       
  1225 /**
       
  1226  * Sets the session to send an RPMB request to the RPMB partition.
       
  1227  *  
       
  1228  * Having set-up the session for this operation, the client must invoke, SMF_INVOKES, the 
       
  1229  * read write state machine, CIMReadWriteBlocksSM, and the operation will commence. The read
       
  1230  * write state machine initiates the result read sequence by issuing the Write Multiple 
       
  1231  * command, CMD25. Prior to this the state machine has issued CMD23 with the block count set 
       
  1232  * to 1 and optionally, if aSetReliableWrite is TRUE, with the arguement bit (31) set to 1. 
       
  1233  */
       
  1234     {
       
  1235     iSessionID=ECIMWriteMBlock;
       
  1236     Command().iCommand = ECmdWriteMultipleBlock;
       
  1237     Command().iFlags |= KMMCCmdFlagRpmbIO;
       
  1238     if (aSetReliableWrite)
       
  1239         {
       
  1240         Command().iFlags |= KMMCCmdFlagReliableWrite;
       
  1241         }
       
  1242     }
       
  1243 
       
  1244 inline void DMMCSession::SetupRpmbReceiveResponse()
       
  1245 /**
       
  1246  * Sets the session to receive an RPMB resposne from the RPMB partition.
       
  1247  * 
       
  1248  * Having set-up the session for this operation, the client must invoke ,SMF_INVOKES. the 
       
  1249  * read write state machine, CIMReadWriteBlocksSM, and the operation will commence. The read
       
  1250  * write state machine initiates the result read sequence by issuing the Read Multiple 
       
  1251  * command, CMD18. Prior to this the state machine has issued CMD23 with the block count set 
       
  1252  * to 1.
       
  1253  */
       
  1254     {
       
  1255     iSessionID=ECIMReadMBlock;
       
  1256     Command().iCommand = ECmdReadMultipleBlock;
       
  1257     Command().iFlags |= KMMCCmdFlagRpmbIO;
       
  1258     }
  1043 
  1259 
  1044 inline void DMMCSession::EnableDoubleBuffering(TUint32 aNumBlocks)
  1260 inline void DMMCSession::EnableDoubleBuffering(TUint32 aNumBlocks)
  1045 /**
  1261 /**
  1046  * When called before a data transfer operation is engaged, specifies that the data 
  1262  * When called before a data transfer operation is engaged, specifies that the data 
  1047  * transfer operation is to be double-buffered.
  1263  * transfer operation is to be double-buffered.
  1553 /**
  1769 /**
  1554  * Returns ETrue if Erase Group commands are supported.
  1770  * Returns ETrue if Erase Group commands are supported.
  1555  * @return ETrue if Erase Group commands are supported.
  1771  * @return ETrue if Erase Group commands are supported.
  1556  */
  1772  */
  1557 	{return(iEraseFlags&KMMCEraseGroupCmdsSupported);}
  1773 	{return(iEraseFlags&KMMCEraseGroupCmdsSupported);}
       
  1774 
       
  1775 /**
       
  1776 Return RPMB information.
       
  1777 @param aDeviceIndex The RPMB specific device index. Must be zero in current implementation
       
  1778 @param aParams Retrieves the RPMB specific information required for initialisation
       
  1779 */
       
  1780 
       
  1781 inline TInt MRpmbInfo::RpmbInfo(TUint aDeviceIndex, TRpmbDeviceParms& aParams)
       
  1782     {
       
  1783 	// note that MMCGetExtInterface doesn't hand out an instance of MRpmbInfo until
       
  1784 	// RpmbParmsPopulated is true so baseport configuration has been read and any 
       
  1785 	// changes to NumberOfRpmbs and TheRpmbs are flushed
       
  1786 	if (aDeviceIndex>MaxIndexRpmb)
       
  1787 		{
       
  1788 		// currently support just one RPMB capable device at index 0
       
  1789 		return KErrGeneral;
       
  1790 		}
       
  1791 	else
       
  1792 		{
       
  1793 		if (NumberOfRpmbs==0)
       
  1794 			{
       
  1795 			// baseport configuration doesn't include an RPMB partition
       
  1796 			return KErrNotSupported;
       
  1797 			}
       
  1798 		else
       
  1799 			{	
       
  1800 			aParams = TheRpmbs[0];
       
  1801 			return KErrNone;
       
  1802 			}
       
  1803 		}
       
  1804 	}