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 } |