mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Add more fields to MultiMediaCard's Extended CSD.
This commit is contained in:
@@ -88,128 +88,249 @@ namespace Aaru.Decoders.MMC
|
||||
public byte PartitionsAttribute;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] MaxEnhancedAreaSize;
|
||||
public byte PartitioningSupport;
|
||||
public byte HPIManagement;
|
||||
public byte HWResetFunction;
|
||||
public byte EnableBackgroundOperationsHandshake;
|
||||
public byte ManuallyStartBackgroundOperations;
|
||||
public byte StartSanitizeOperation;
|
||||
public byte WriteReliabilityParameterRegister;
|
||||
public byte WriteReliabilitySettingRegister;
|
||||
public byte RPMBSize;
|
||||
public byte FirmwareConfiguration;
|
||||
public byte Reserved4;
|
||||
public byte UserAreaWriteProtectionRegister;
|
||||
public byte Reserved5;
|
||||
public byte BootAreaWriteProtectionRegister;
|
||||
public byte BootWriteProtectionStatus;
|
||||
public byte HighCapacityEraseGroupDefinition;
|
||||
public byte Reserved6;
|
||||
public byte BootBusConditions;
|
||||
public byte BootConfigProtection;
|
||||
public byte PartitionConfiguration;
|
||||
public byte Reserved7;
|
||||
public byte ErasedMemoryContent;
|
||||
public byte Reserved8;
|
||||
public byte BusWidth;
|
||||
public byte StrobeSupport;
|
||||
public byte HighSpeedInterfaceTiming;
|
||||
public byte Reserved9;
|
||||
public byte PowerClass;
|
||||
public byte Reserved10;
|
||||
public byte CommandSetRevision;
|
||||
public byte Reserved11;
|
||||
public byte CommandSet;
|
||||
public byte Revision;
|
||||
public byte Reserved12;
|
||||
public byte Structure;
|
||||
public byte Reserved13;
|
||||
public byte DeviceType;
|
||||
public byte DriverStrength;
|
||||
public byte OutOfInterruptBusyTiming;
|
||||
public byte PartitionSwitchingTime;
|
||||
public byte PowerClass52_195;
|
||||
public byte PowerClass26_195;
|
||||
public byte PowerClass52;
|
||||
public byte PowerClass26;
|
||||
public byte Reserved14;
|
||||
public byte MinimumReadPerformance26_4;
|
||||
public byte MinimumWritePerformance26_4;
|
||||
public byte MinimumReadPerformance26;
|
||||
public byte MinimumWritePerformance26;
|
||||
public byte MinimumReadPerformance52;
|
||||
public byte MinimumWritePerformance52;
|
||||
public byte SecureWriteProtectInformation;
|
||||
public uint SectorCount;
|
||||
public byte SleepNotificationTimeout;
|
||||
public byte SleepAwakeTimeout;
|
||||
public byte ProductionStateAwarenessTimeout;
|
||||
public byte SleepCurrentVccQ;
|
||||
public byte SleepCurrentVcc;
|
||||
public byte HighCapacityWriteProtectGroupSize;
|
||||
public byte ReliableWriteSectorCount;
|
||||
public byte HighCapacityEraseTimeout;
|
||||
public byte HighCapacityEraseUnitSize;
|
||||
public byte AccessSize;
|
||||
public byte BootPartitionSize;
|
||||
public byte Reserved15;
|
||||
public byte BootInformation;
|
||||
public byte SecureTRIMMultiplier;
|
||||
public byte SecureEraseMultiplier;
|
||||
public byte SecureFeatureSupport;
|
||||
public byte TRIMMultiplier;
|
||||
public byte Reserved16;
|
||||
public byte MinimumReadPerformanceDDR52;
|
||||
public byte MinimumWritePerformanceDDR52;
|
||||
public byte PowerClassDDR200_130;
|
||||
public byte PowerClassDDR200_195;
|
||||
public byte PowerClassDDR52_195;
|
||||
public byte PowerClassDDR52;
|
||||
public byte CacheFlushingPolicy;
|
||||
public byte InitializationTimeAfterPartition;
|
||||
public uint CorrectlyProgrammedSectors;
|
||||
public byte BackgroundOperationsStatus;
|
||||
public byte PowerOffNotificationTimeout;
|
||||
public byte GenericCMD6Timeout;
|
||||
public uint CacheSize;
|
||||
public byte PowerClassDDR200;
|
||||
public ulong FirmwareVersion;
|
||||
public ushort DeviceVersion;
|
||||
public byte OptimalTrimUnitSize;
|
||||
public byte OptimalWriteSize;
|
||||
public byte OptimalReadSize;
|
||||
public byte PreEOLInformation;
|
||||
public byte DeviceLifeEstimationTypeA;
|
||||
public byte DeviceLifeEstimationTypeB;
|
||||
public PartitioningSupport PartitioningSupport;
|
||||
public byte HPIManagement;
|
||||
public byte HWResetFunction;
|
||||
public byte EnableBackgroundOperationsHandshake;
|
||||
public byte ManuallyStartBackgroundOperations;
|
||||
public byte StartSanitizeOperation;
|
||||
public byte WriteReliabilityParameterRegister;
|
||||
public byte WriteReliabilitySettingRegister;
|
||||
public byte RPMBSize;
|
||||
public byte FirmwareConfiguration;
|
||||
public byte Reserved4;
|
||||
public UserAreaWriteProtectionRegister UserAreaWriteProtectionRegister;
|
||||
public byte Reserved5;
|
||||
public BootAreaWriteProtectionRegister BootAreaWriteProtectionRegister;
|
||||
public byte BootWriteProtectionStatus;
|
||||
public HighCapacityEraseGroupDefinition HighCapacityEraseGroupDefinition;
|
||||
public byte Reserved6;
|
||||
public byte BootBusConditions;
|
||||
public BootConfigProtection BootConfigProtection;
|
||||
public byte PartitionConfiguration;
|
||||
public byte Reserved7;
|
||||
public byte ErasedMemoryContent;
|
||||
public byte Reserved8;
|
||||
public byte BusWidth;
|
||||
public byte StrobeSupport;
|
||||
public byte HighSpeedInterfaceTiming;
|
||||
public byte Reserved9;
|
||||
public byte PowerClass;
|
||||
public byte Reserved10;
|
||||
public byte CommandSetRevision;
|
||||
public byte Reserved11;
|
||||
public byte CommandSet;
|
||||
public byte Revision;
|
||||
public byte Reserved12;
|
||||
public byte Structure;
|
||||
public byte Reserved13;
|
||||
public DeviceType DeviceType;
|
||||
public DriverStrength DriverStrength;
|
||||
public byte OutOfInterruptBusyTiming;
|
||||
public byte PartitionSwitchingTime;
|
||||
public byte PowerClass52_195;
|
||||
public byte PowerClass26_195;
|
||||
public byte PowerClass52;
|
||||
public byte PowerClass26;
|
||||
public byte Reserved14;
|
||||
public byte MinimumReadPerformance26_4;
|
||||
public byte MinimumWritePerformance26_4;
|
||||
public byte MinimumReadPerformance26;
|
||||
public byte MinimumWritePerformance26;
|
||||
public byte MinimumReadPerformance52;
|
||||
public byte MinimumWritePerformance52;
|
||||
public SecureWriteProtectInformation SecureWriteProtectInformation;
|
||||
public uint SectorCount;
|
||||
public byte SleepNotificationTimeout;
|
||||
public byte SleepAwakeTimeout;
|
||||
public byte ProductionStateAwarenessTimeout;
|
||||
public byte SleepCurrentVccQ;
|
||||
public byte SleepCurrentVcc;
|
||||
public byte HighCapacityWriteProtectGroupSize;
|
||||
public byte ReliableWriteSectorCount;
|
||||
public byte HighCapacityEraseTimeout;
|
||||
public byte HighCapacityEraseUnitSize;
|
||||
public byte AccessSize;
|
||||
public byte BootPartitionSize;
|
||||
public byte Reserved15;
|
||||
public BootInformation BootInformation;
|
||||
public byte SecureTRIMMultiplier;
|
||||
public byte SecureEraseMultiplier;
|
||||
public SecureFeatureSupport SecureFeatureSupport;
|
||||
public byte TRIMMultiplier;
|
||||
public byte Reserved16;
|
||||
public byte MinimumReadPerformanceDDR52;
|
||||
public byte MinimumWritePerformanceDDR52;
|
||||
public byte PowerClassDDR200_130;
|
||||
public byte PowerClassDDR200_195;
|
||||
public byte PowerClassDDR52_195;
|
||||
public byte PowerClassDDR52;
|
||||
public CacheFlushingPolicy CacheFlushingPolicy;
|
||||
public byte InitializationTimeAfterPartition;
|
||||
public uint CorrectlyProgrammedSectors;
|
||||
public byte BackgroundOperationsStatus;
|
||||
public byte PowerOffNotificationTimeout;
|
||||
public byte GenericCMD6Timeout;
|
||||
public uint CacheSize;
|
||||
public byte PowerClassDDR200;
|
||||
public ulong FirmwareVersion;
|
||||
public ushort DeviceVersion;
|
||||
public byte OptimalTrimUnitSize;
|
||||
public byte OptimalWriteSize;
|
||||
public byte OptimalReadSize;
|
||||
public byte PreEOLInformation;
|
||||
public byte DeviceLifeEstimationTypeA;
|
||||
public byte DeviceLifeEstimationTypeB;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||
public byte[] VendorHealthReport;
|
||||
public uint NumberofFWSectorsCorrectlyProgrammed;
|
||||
public byte Reserved17;
|
||||
public byte CMDQueuingDepth;
|
||||
public byte CMDQueuingSupport;
|
||||
public uint NumberOfFWSectorsCorrectlyProgrammed;
|
||||
public byte Reserved17;
|
||||
public byte CMDQueuingDepth;
|
||||
public CMDQueuingSupport CMDQueuingSupport;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 177)]
|
||||
public byte[] Reserved18;
|
||||
public byte BarrierSupport;
|
||||
public uint FFUArgument;
|
||||
public byte OperationCodesTimeout;
|
||||
public byte FFUFeatures;
|
||||
public byte SupportedModes;
|
||||
public byte ExtendedPartitionsSupport;
|
||||
public byte LargeUnitSize;
|
||||
public byte ContextManagementCaps;
|
||||
public byte TagResourcesSize;
|
||||
public byte TagUnitSize;
|
||||
public byte DataTagSupport;
|
||||
public byte MaxPackedWriteCommands;
|
||||
public byte MaxPackedReadCommands;
|
||||
public byte BackgroundOperationsSupport;
|
||||
public byte HPIFeatures;
|
||||
public byte SupportedCommandSets;
|
||||
public byte ExtendedSecurityCommandsError;
|
||||
public byte BarrierSupport;
|
||||
public uint FFUArgument;
|
||||
public byte OperationCodesTimeout;
|
||||
public FFUFeatures FFUFeatures;
|
||||
public SupportedModes SupportedModes;
|
||||
public ExtendedPartitionsSupport ExtendedPartitionsSupport;
|
||||
public byte LargeUnitSize;
|
||||
public byte ContextManagementCaps;
|
||||
public byte TagResourcesSize;
|
||||
public byte TagUnitSize;
|
||||
public DataTagSupport DataTagSupport;
|
||||
public byte MaxPackedWriteCommands;
|
||||
public byte MaxPackedReadCommands;
|
||||
public BackgroundOperationsSupport BackgroundOperationsSupport;
|
||||
public HPIFeatures HPIFeatures;
|
||||
public DeviceSupportedCommandSets SupportedCommandSets;
|
||||
public byte ExtendedSecurityCommandsError;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
|
||||
public byte[] Reserved19;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum DeviceSupportedCommandSets : byte
|
||||
{
|
||||
Standard = 1 << 0
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum HPIFeatures : byte
|
||||
{
|
||||
Supported = 1 << 0, CMD12 = 1 << 1
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum BackgroundOperationsSupport : byte
|
||||
{
|
||||
Supported = 1 << 0
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum DataTagSupport : byte
|
||||
{
|
||||
Supported = 1 << 0
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ExtendedPartitionsSupport : byte
|
||||
{
|
||||
SystemCode = 1 << 0, NonPersistent = 1 << 1
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum SupportedModes : byte
|
||||
{
|
||||
FFU = 1 << 0, VendorSpecific = 1 << 1
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum FFUFeatures : byte
|
||||
{
|
||||
SupportedModeOperationCodes = 1 << 0
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum CMDQueuingSupport : byte
|
||||
{
|
||||
Supported = 1 << 0
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum CacheFlushingPolicy : byte
|
||||
{
|
||||
FIFO = 1 << 0
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum SecureFeatureSupport : byte
|
||||
{
|
||||
Purge = 1 << 0, Defective = 1 << 2, Trim = 1 << 4,
|
||||
Sanitize = 1 << 6
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum BootInformation : byte
|
||||
{
|
||||
Alternative = 1 << 0, DDR = 1 << 1, HighSpeed = 1 << 2
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum SecureWriteProtectInformation : byte
|
||||
{
|
||||
Supported = 1 << 0, Enabled = 1 << 1
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum DriverStrength : byte
|
||||
{
|
||||
Type0 = 1 << 0, Type1 = 1 << 1, Type2 = 1 << 2,
|
||||
Type3 = 1 << 3, Type4 = 1 << 4
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum DeviceType : byte
|
||||
{
|
||||
HS_26 = 1 << 0, HS_52 = 1 << 1, HS_DDR_52 = 1 << 2,
|
||||
HS_DDR_52_LV = 1 << 3, HS200_18 = 1 << 4, HS200_12 = 1 << 5,
|
||||
HS400_18 = 1 << 6, HS400_12 = 1 << 7
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum BootConfigProtection : byte
|
||||
{
|
||||
PowerCycle = 1 << 0, Permanent = 1 << 4
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum HighCapacityEraseGroupDefinition : byte
|
||||
{
|
||||
Enabled = 1 << 0
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum BootAreaWriteProtectionRegister : byte
|
||||
{
|
||||
PowerOn = 1 << 0, PowerOnArea2 = 1 << 1, Permanent = 1 << 2,
|
||||
PermanentArea2 = 1 << 3, PermanentDisable = 1 << 4, PowerOnDisable = 1 << 6,
|
||||
Selected = 1 << 7
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum UserAreaWriteProtectionRegister : byte
|
||||
{
|
||||
ApplyPowerOn = 1 << 0, ApplyPermanent = 1 << 2, DisablePowerOn = 1 << 3,
|
||||
DisablePermanent = 1 << 4, DisableWriteProtect = 1 << 6, DisablePassword = 1 << 7
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum PartitioningSupport : byte
|
||||
{
|
||||
Supported = 1 << 0, Enhanced = 1 << 1, Extended = 1 << 2
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming"), SuppressMessage("ReSharper", "MemberCanBeInternal"),
|
||||
SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
||||
public static partial class Decoders
|
||||
@@ -236,39 +357,90 @@ namespace Aaru.Decoders.MMC
|
||||
|
||||
double unit;
|
||||
|
||||
if((csd.HPIFeatures & 0x01) == 0x01)
|
||||
sb.AppendLine((csd.HPIFeatures & 0x02) == 0x02 ? "\tDevice implements HPI using CMD12"
|
||||
if(csd.ExtendedSecurityCommandsError != 0)
|
||||
sb.AppendFormat("\tLast extended security error was {0}", csd.ExtendedSecurityCommandsError).
|
||||
AppendLine();
|
||||
|
||||
if(csd.SupportedCommandSets.HasFlag(DeviceSupportedCommandSets.Standard))
|
||||
sb.AppendLine("\tDevice supports standard MMC command set");
|
||||
|
||||
if(((int)csd.SupportedCommandSets & 0xFE) != 0)
|
||||
sb.AppendFormat("\tDevice supports unknown command sets 0x{0:X2}", (int)csd.SupportedCommandSets);
|
||||
|
||||
if(csd.HPIFeatures.HasFlag(HPIFeatures.Supported))
|
||||
sb.AppendLine(csd.HPIFeatures.HasFlag(HPIFeatures.CMD12) ? "\tDevice implements HPI using CMD12"
|
||||
: "\tDevice implements HPI using CMD13");
|
||||
|
||||
if((csd.BackgroundOperationsSupport & 0x01) == 0x01)
|
||||
if(csd.BackgroundOperationsSupport.HasFlag(BackgroundOperationsSupport.Supported))
|
||||
sb.AppendLine("\tDevice supports background operations");
|
||||
|
||||
sb.AppendFormat("\tDevice supports a maximum of {0} packed reads and {1} packed writes",
|
||||
csd.MaxPackedReadCommands, csd.MaxPackedWriteCommands).AppendLine();
|
||||
|
||||
if((csd.DataTagSupport & 0x01) == 0x01)
|
||||
if(csd.DataTagSupport.HasFlag(DataTagSupport.Supported))
|
||||
{
|
||||
sb.AppendLine("\tDevice supports Data Tag");
|
||||
sb.AppendFormat("\tTags must be in units of {0} sectors", Math.Pow(2, csd.TagUnitSize)).AppendLine();
|
||||
sb.AppendFormat("\tTag resources size is {0}.", csd.TagResourcesSize).AppendLine();
|
||||
}
|
||||
|
||||
if((csd.ExtendedPartitionsSupport & 0x01) == 0x01)
|
||||
if(csd.ContextManagementCaps != 0)
|
||||
{
|
||||
sb.AppendFormat("\tMax context ID is {0}.", csd.ContextManagementCaps & 0xF).AppendLine();
|
||||
|
||||
sb.AppendFormat("\tLarge unit maximum multiplier is {0}.",
|
||||
((csd.ContextManagementCaps & 0x70) >> 4) + 1).AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("\tLarge unit size is {0} MiB", csd.LargeUnitSize + 1).AppendLine();
|
||||
|
||||
if(csd.ExtendedPartitionsSupport.HasFlag(ExtendedPartitionsSupport.NonPersistent))
|
||||
sb.AppendLine("\tDevice supports non-persistent extended partitions");
|
||||
|
||||
if((csd.ExtendedPartitionsSupport & 0x02) == 0x02)
|
||||
if(csd.ExtendedPartitionsSupport.HasFlag(ExtendedPartitionsSupport.SystemCode))
|
||||
sb.AppendLine("\tDevice supports system code extended partitions");
|
||||
|
||||
if((csd.SupportedModes & 0x01) == 0x01)
|
||||
if(csd.SupportedModes.HasFlag(SupportedModes.FFU))
|
||||
{
|
||||
sb.AppendLine("\tDevice supports FFU");
|
||||
|
||||
if((csd.SupportedModes & 0x02) == 0x02)
|
||||
if(csd.FFUFeatures.HasFlag(FFUFeatures.SupportedModeOperationCodes))
|
||||
{
|
||||
// todo public byte ModeOperationCodes
|
||||
|
||||
if(csd.OperationCodesTimeout > 0)
|
||||
{
|
||||
unit = Math.Pow(2, csd.OperationCodesTimeout) * 100;
|
||||
|
||||
if(unit > 1000000)
|
||||
sb.
|
||||
AppendFormat("\t\tMaximum timeout for switch command when setting a value to the mode operation codes field is {0:D2}s",
|
||||
unit / 1000000).AppendLine();
|
||||
else if(unit > 1000)
|
||||
sb.
|
||||
AppendFormat("\tMaximum timeout for switch command when setting a value to the mode operation codes field is {0:D2}ms",
|
||||
unit / 1000).AppendLine();
|
||||
else
|
||||
sb.
|
||||
AppendFormat("\tMaximum timeout for switch command when setting a value to the mode operation codes field is {0:D2}µs",
|
||||
unit).AppendLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(csd.SupportedModes.HasFlag(SupportedModes.VendorSpecific))
|
||||
sb.AppendLine("\tDevice supports Vendor Specific Mode");
|
||||
|
||||
if((csd.CMDQueuingSupport & 0x01) == 0x01)
|
||||
if(csd.BarrierSupport == 0x01)
|
||||
{
|
||||
sb.AppendLine("\tDevice supports the barrier command");
|
||||
}
|
||||
|
||||
if(csd.CMDQueuingSupport.HasFlag(CMDQueuingSupport.Supported))
|
||||
sb.AppendFormat("\tDevice supports command queuing with a depth of {0}", csd.CMDQueuingDepth + 1).
|
||||
AppendLine();
|
||||
|
||||
sb.AppendFormat("\t{0} firmware sectors correctly programmed", csd.NumberofFWSectorsCorrectlyProgrammed).
|
||||
sb.AppendFormat("\t{0} firmware sectors correctly programmed", csd.NumberOfFWSectorsCorrectlyProgrammed).
|
||||
AppendLine();
|
||||
|
||||
switch(csd.DeviceLifeEstimationTypeB)
|
||||
@@ -383,9 +555,21 @@ namespace Aaru.Decoders.MMC
|
||||
break;
|
||||
}
|
||||
|
||||
sb.AppendFormat("\tOptimal read size is {0} logical sectors", csd.OptimalReadSize).AppendLine();
|
||||
sb.AppendFormat("\tOptimal write size is {0} logical sectors", csd.OptimalWriteSize).AppendLine();
|
||||
sb.AppendFormat("\tOptimal trim size is {0} logical sectors", csd.OptimalTrimUnitSize).AppendLine();
|
||||
if(csd.OptimalReadSize == 0)
|
||||
sb.AppendLine("\tDevice does not report an optimal read size");
|
||||
else
|
||||
sb.AppendFormat("\tOptimal read size is {0} KiB", 4 * csd.OptimalReadSize).AppendLine();
|
||||
|
||||
if(csd.OptimalWriteSize == 0)
|
||||
sb.AppendLine("\tDevice does not report an optimal write size");
|
||||
else
|
||||
sb.AppendFormat("\tOptimal write size is {0} KiB", 4 * csd.OptimalWriteSize).AppendLine();
|
||||
|
||||
if(csd.OptimalTrimUnitSize == 0)
|
||||
sb.AppendLine("\tDevice does not report an optimal trim size");
|
||||
else
|
||||
sb.AppendFormat("\tOptimal trim size is {0} KiB", 4 * Math.Pow(2, csd.OptimalTrimUnitSize - 1)).
|
||||
AppendLine();
|
||||
|
||||
sb.AppendFormat("\tDevice version: {0}", csd.DeviceVersion).AppendLine();
|
||||
sb.AppendFormat("\tFirmware version: {0}", csd.FirmwareVersion).AppendLine();
|
||||
@@ -393,7 +577,7 @@ namespace Aaru.Decoders.MMC
|
||||
if(csd.CacheSize == 0)
|
||||
sb.AppendLine("\tDevice has no cache");
|
||||
else
|
||||
sb.AppendFormat("\tDevice has {0} KiB of cache", csd.CacheSize).AppendLine();
|
||||
sb.AppendFormat("\tDevice has {0} KiB of cache", csd.CacheSize / 8).AppendLine();
|
||||
|
||||
if(csd.GenericCMD6Timeout > 0)
|
||||
sb.AppendFormat("\tDevice takes a maximum of {0} ms by default for a SWITCH command",
|
||||
@@ -431,23 +615,23 @@ namespace Aaru.Decoders.MMC
|
||||
sb.AppendFormat("\tDevice takes a maximum of {0} ms for initialization after partition",
|
||||
csd.InitializationTimeAfterPartition * 100).AppendLine();
|
||||
|
||||
if((csd.CacheFlushingPolicy & 0x01) == 0x01)
|
||||
if(csd.CacheFlushingPolicy.HasFlag(CacheFlushingPolicy.FIFO))
|
||||
sb.AppendLine("\tDevice uses a FIFO policy for cache flushing");
|
||||
|
||||
if(csd.TRIMMultiplier > 0)
|
||||
sb.AppendFormat("\tDevice takes a maximum of {0} ms for trimming a single erase group",
|
||||
csd.TRIMMultiplier * 300).AppendLine();
|
||||
|
||||
if((csd.SecureFeatureSupport & 0x40) == 0x40)
|
||||
if(csd.SecureFeatureSupport.HasFlag(SecureFeatureSupport.Sanitize))
|
||||
sb.AppendLine("\tDevice supports the sanitize operation");
|
||||
|
||||
if((csd.SecureFeatureSupport & 0x10) == 0x10)
|
||||
if(csd.SecureFeatureSupport.HasFlag(SecureFeatureSupport.Trim))
|
||||
sb.AppendLine("\tDevice supports supports the secure and insecure trim operations");
|
||||
|
||||
if((csd.SecureFeatureSupport & 0x04) == 0x04)
|
||||
if(csd.SecureFeatureSupport.HasFlag(SecureFeatureSupport.Defective))
|
||||
sb.AppendLine("\tDevice supports automatic erase on retired defective blocks");
|
||||
|
||||
if((csd.SecureFeatureSupport & 0x01) == 0x01)
|
||||
if(csd.SecureFeatureSupport.HasFlag(SecureFeatureSupport.Purge))
|
||||
sb.AppendLine("\tDevice supports secure purge operations");
|
||||
|
||||
if(csd.SecureEraseMultiplier > 0)
|
||||
@@ -458,21 +642,21 @@ namespace Aaru.Decoders.MMC
|
||||
sb.AppendFormat("\tDevice takes a maximum of {0} ms for securely trimming a single erase group",
|
||||
csd.SecureTRIMMultiplier * 300).AppendLine();
|
||||
|
||||
if((csd.BootInformation & 0x04) == 0x04)
|
||||
if(csd.BootInformation.HasFlag(BootInformation.HighSpeed))
|
||||
sb.AppendLine("\tDevice supports high speed timing on boot");
|
||||
|
||||
if((csd.BootInformation & 0x02) == 0x02)
|
||||
if(csd.BootInformation.HasFlag(BootInformation.DDR))
|
||||
sb.AppendLine("\tDevice supports dual data rate on boot");
|
||||
|
||||
if((csd.BootInformation & 0x01) == 0x01)
|
||||
if(csd.BootInformation.HasFlag(BootInformation.Alternative))
|
||||
sb.AppendLine("\tDevice supports alternative boot method");
|
||||
|
||||
if(csd.BootPartitionSize > 0)
|
||||
sb.AppendFormat("\tDevice has a {0} KiB boot partition", csd.BootPartitionSize * 128).AppendLine();
|
||||
|
||||
if((csd.AccessSize & 0x0F) > 0)
|
||||
sb.AppendFormat("\tDevice has a page size of {0} KiB", (csd.AccessSize & 0x0F) * 512.0 / 1024.0).
|
||||
AppendLine();
|
||||
sb.AppendFormat("\tDevice has a page size of {0} KiB",
|
||||
512 * Math.Pow(2, (csd.AccessSize & 0x0F) - 1) / 1024.0).AppendLine();
|
||||
|
||||
if(csd.HighCapacityEraseUnitSize > 0)
|
||||
sb.AppendFormat("\tDevice erase groups are {0} KiB", csd.HighCapacityEraseUnitSize * 512).AppendLine();
|
||||
@@ -551,15 +735,15 @@ namespace Aaru.Decoders.MMC
|
||||
|
||||
sb.AppendFormat("\tDevice has {0} sectors", csd.SectorCount).AppendLine();
|
||||
|
||||
if((csd.SecureWriteProtectInformation & 0x01) == 0x01)
|
||||
if(csd.SecureWriteProtectInformation.HasFlag(SecureWriteProtectInformation.Supported))
|
||||
{
|
||||
sb.AppendLine("\tDevice supports secure write protection");
|
||||
|
||||
if((csd.SecureWriteProtectInformation & 0x02) == 0x02)
|
||||
if(csd.SecureWriteProtectInformation.HasFlag(SecureWriteProtectInformation.Enabled))
|
||||
sb.AppendLine("\tDevice has secure write protection enabled");
|
||||
}
|
||||
|
||||
unit = csd.MinimumReadPerformance26 * 150;
|
||||
unit = csd.MinimumReadPerformance26 * 300;
|
||||
|
||||
if(csd.MinimumReadPerformance26 == 0)
|
||||
sb.AppendLine("\tDevice cannot achieve 2.4MB/s reading in SDR 26Mhz mode");
|
||||
@@ -567,7 +751,7 @@ namespace Aaru.Decoders.MMC
|
||||
sb.AppendFormat("\tDevice can achieve a minimum of {0}MB/s reading in SDR 26Mhz mode", unit / 1000).
|
||||
AppendLine();
|
||||
|
||||
unit = csd.MinimumReadPerformance26_4 * 150;
|
||||
unit = csd.MinimumReadPerformance26_4 * 300;
|
||||
|
||||
if(csd.MinimumReadPerformance26_4 == 0)
|
||||
sb.AppendLine("\tDevice cannot achieve 2.4MB/s reading in SDR 26Mhz 4-bit mode");
|
||||
@@ -575,7 +759,7 @@ namespace Aaru.Decoders.MMC
|
||||
sb.AppendFormat("\tDevice can achieve a minimum of {0}MB/s reading in SDR 26Mhz 4-bit mode",
|
||||
unit / 1000).AppendLine();
|
||||
|
||||
unit = csd.MinimumReadPerformance52 * 150;
|
||||
unit = csd.MinimumReadPerformance52 * 300;
|
||||
|
||||
if(csd.MinimumReadPerformance52 == 0)
|
||||
sb.AppendLine("\tDevice cannot achieve 2.4MB/s reading in SDR 52Mhz mode");
|
||||
@@ -583,7 +767,7 @@ namespace Aaru.Decoders.MMC
|
||||
sb.AppendFormat("\tDevice can achieve a minimum of {0}MB/s reading in SDR 52Mhz mode", unit / 1000).
|
||||
AppendLine();
|
||||
|
||||
unit = csd.MinimumReadPerformanceDDR52 * 300;
|
||||
unit = csd.MinimumReadPerformanceDDR52 * 600;
|
||||
|
||||
if(csd.MinimumReadPerformanceDDR52 == 0)
|
||||
sb.AppendLine("\tDevice cannot achieve 4.8MB/s reading in DDR 52Mhz mode");
|
||||
@@ -591,7 +775,7 @@ namespace Aaru.Decoders.MMC
|
||||
sb.AppendFormat("\tDevice can achieve a minimum of {0}MB/s reading in DDR 52Mhz mode", unit / 1000).
|
||||
AppendLine();
|
||||
|
||||
unit = csd.MinimumWritePerformance26 * 150;
|
||||
unit = csd.MinimumWritePerformance26 * 300;
|
||||
|
||||
if(csd.MinimumWritePerformance26 == 0)
|
||||
sb.AppendLine("\tDevice cannot achieve 2.4MB/s writing in SDR 26Mhz mode");
|
||||
@@ -599,7 +783,7 @@ namespace Aaru.Decoders.MMC
|
||||
sb.AppendFormat("\tDevice can achieve a minimum of {0}MB/s writing in SDR 26Mhz mode", unit / 1000).
|
||||
AppendLine();
|
||||
|
||||
unit = csd.MinimumWritePerformance26_4 * 150;
|
||||
unit = csd.MinimumWritePerformance26_4 * 300;
|
||||
|
||||
if(csd.MinimumWritePerformance26_4 == 0)
|
||||
sb.AppendLine("\tDevice cannot achieve 2.4MB/s writing in SDR 26Mhz 4-bit mode");
|
||||
@@ -607,7 +791,7 @@ namespace Aaru.Decoders.MMC
|
||||
sb.AppendFormat("\tDevice can achieve a minimum of {0}MB/s writing in SDR 26Mhz 4-bit mode",
|
||||
unit / 1000).AppendLine();
|
||||
|
||||
unit = csd.MinimumWritePerformance52 * 150;
|
||||
unit = csd.MinimumWritePerformance52 * 300;
|
||||
|
||||
if(csd.MinimumWritePerformance52 == 0)
|
||||
sb.AppendLine("\tDevice cannot achieve 2.4MB/s writing in SDR 52Mhz mode");
|
||||
@@ -615,7 +799,7 @@ namespace Aaru.Decoders.MMC
|
||||
sb.AppendFormat("\tDevice can achieve a minimum of {0}MB/s writing in SDR 52Mhz mode", unit / 1000).
|
||||
AppendLine();
|
||||
|
||||
unit = csd.MinimumWritePerformanceDDR52 * 300;
|
||||
unit = csd.MinimumWritePerformanceDDR52 * 600;
|
||||
|
||||
if(csd.MinimumWritePerformanceDDR52 == 0)
|
||||
sb.AppendLine("\tDevice cannot achieve 4.8MB/s writing in DDR 52Mhz mode");
|
||||
@@ -631,32 +815,100 @@ namespace Aaru.Decoders.MMC
|
||||
sb.AppendFormat("\tDevice can take a maximum of {0} ms when releasing from an interrupt",
|
||||
csd.OutOfInterruptBusyTiming * 10).AppendLine();
|
||||
|
||||
if((csd.DeviceType & 0x01) == 0x01)
|
||||
if(csd.DriverStrength.HasFlag(DriverStrength.Type0))
|
||||
sb.AppendLine("\tDevice supports I/O driver strength type 0.");
|
||||
|
||||
if(csd.DriverStrength.HasFlag(DriverStrength.Type1))
|
||||
sb.AppendLine("\tDevice supports I/O driver strength type 1.");
|
||||
|
||||
if(csd.DriverStrength.HasFlag(DriverStrength.Type2))
|
||||
sb.AppendLine("\tDevice supports I/O driver strength type 2.");
|
||||
|
||||
if(csd.DriverStrength.HasFlag(DriverStrength.Type3))
|
||||
sb.AppendLine("\tDevice supports I/O driver strength type 3.");
|
||||
|
||||
if(csd.DriverStrength.HasFlag(DriverStrength.Type4))
|
||||
sb.AppendLine("\tDevice supports I/O driver strength type 4.");
|
||||
|
||||
if(csd.DeviceType.HasFlag(DeviceType.HS_26))
|
||||
sb.AppendLine("\tDevice supports 26 Mhz mode");
|
||||
|
||||
if((csd.DeviceType & 0x02) == 0x02)
|
||||
if(csd.DeviceType.HasFlag(DeviceType.HS_52))
|
||||
sb.AppendLine("\tDevice supports 52 Mhz mode");
|
||||
|
||||
if((csd.DeviceType & 0x04) == 0x04)
|
||||
if(csd.DeviceType.HasFlag(DeviceType.HS_DDR_52))
|
||||
sb.AppendLine("\tDevice supports DDR 52 Mhz mode at 1.8V or 3V");
|
||||
|
||||
if((csd.DeviceType & 0x08) == 0x08)
|
||||
if(csd.DeviceType.HasFlag(DeviceType.HS_DDR_52_LV))
|
||||
sb.AppendLine("\tDevice supports DDR 52 Mhz mode 1.2V");
|
||||
|
||||
if((csd.DeviceType & 0x10) == 0x10)
|
||||
if(csd.DeviceType.HasFlag(DeviceType.HS200_18))
|
||||
sb.AppendLine("\tDevice supports HS-200 mode (SDR 200Mhz) at 1.8V");
|
||||
|
||||
if((csd.DeviceType & 0x20) == 0x20)
|
||||
if(csd.DeviceType.HasFlag(DeviceType.HS200_12))
|
||||
sb.AppendLine("\tDevice supports HS-200 mode (SDR 200Mhz) at 1.2V");
|
||||
|
||||
if((csd.DeviceType & 0x40) == 0x40)
|
||||
if(csd.DeviceType.HasFlag(DeviceType.HS400_18))
|
||||
sb.AppendLine("\tDevice supports HS-400 mode (DDR 200Mhz) at 1.8V");
|
||||
|
||||
if((csd.DeviceType & 0x80) == 0x80)
|
||||
if(csd.DeviceType.HasFlag(DeviceType.HS400_12))
|
||||
sb.AppendLine("\tDevice supports HS-400 mode (DDR 200Mhz) at 1.2V");
|
||||
|
||||
sb.AppendFormat("\tCSD version 1.{0} revision 1.{1}", csd.Structure, csd.Revision).AppendLine();
|
||||
|
||||
switch(csd.CommandSet)
|
||||
{
|
||||
case 0:
|
||||
sb.AppendLine("\tDevice follows compatibility MMC command set.");
|
||||
|
||||
break;
|
||||
case 1:
|
||||
switch(csd.CommandSetRevision)
|
||||
{
|
||||
case 0:
|
||||
sb.AppendLine("\tDevice follows standard MMC command set v4.0.");
|
||||
|
||||
break;
|
||||
default:
|
||||
sb.AppendFormat("\tDevice follows standard MMC command set with unknown version code {0}.",
|
||||
csd.CommandSetRevision).AppendLine();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
sb.AppendFormat("\tDevice follows unknown MMC command set code {0} with revision code {1}.",
|
||||
csd.CommandSet, csd.CommandSetRevision).AppendLine();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
switch(csd.HighSpeedInterfaceTiming & 0x0F)
|
||||
{
|
||||
case 0: break;
|
||||
case 1:
|
||||
sb.AppendLine("\tDevice is in High Speed mode.");
|
||||
|
||||
break;
|
||||
case 2:
|
||||
sb.AppendLine("\tDevice is in HS-200 mode.");
|
||||
|
||||
break;
|
||||
case 3:
|
||||
sb.AppendLine("\tDevice is in HS-400 mode.");
|
||||
|
||||
break;
|
||||
default:
|
||||
sb.AppendFormat("\tDevice has unknown timing mode {0}.", csd.HighSpeedInterfaceTiming & 0x0F).
|
||||
AppendLine();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
sb.AppendFormat("\tSelected driver strength is type {0}.", (csd.HighSpeedInterfaceTiming & 0xF0) >> 4).
|
||||
AppendLine();
|
||||
|
||||
if((csd.StrobeSupport & 0x01) == 0x01)
|
||||
{
|
||||
sb.AppendLine("\tDevice supports enhanced strobe mode");
|
||||
@@ -694,7 +946,20 @@ namespace Aaru.Decoders.MMC
|
||||
break;
|
||||
}
|
||||
|
||||
if((csd.PartitionConfiguration & 0x80) == 0x80)
|
||||
switch(csd.ErasedMemoryContent)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
sb.AppendFormat("\tErased memory range shall be '{0}'.", csd.ErasedMemoryContent).AppendLine();
|
||||
|
||||
break;
|
||||
default:
|
||||
sb.AppendFormat("\tUnknown erased memory content code {0}", csd.ErasedMemoryContent).AppendLine();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if((csd.PartitionConfiguration & 0x40) == 0x40)
|
||||
sb.AppendLine("\tDevice sends boot acknowledge");
|
||||
|
||||
switch((csd.PartitionConfiguration & 0x38) >> 3)
|
||||
@@ -747,6 +1012,139 @@ namespace Aaru.Decoders.MMC
|
||||
break;
|
||||
}
|
||||
|
||||
if(csd.BootConfigProtection.HasFlag(BootConfigProtection.Permanent))
|
||||
sb.AppendLine("\tChange of the boot configuration register bits is permanently disabled.");
|
||||
else if(csd.BootConfigProtection.HasFlag(BootConfigProtection.PowerCycle))
|
||||
sb.AppendLine("\tChange of the boot configuration register bits is disabled until the next power cycle.");
|
||||
|
||||
switch(csd.BootBusConditions & 0x03)
|
||||
{
|
||||
case 0:
|
||||
sb.AppendLine("\tDevice will boot up in x1 SDR or x4 DDR bus width.");
|
||||
|
||||
break;
|
||||
case 1:
|
||||
sb.AppendLine("\tDevice will boot up in x4 SDR or DDR bus width.");
|
||||
|
||||
break;
|
||||
case 2:
|
||||
sb.AppendLine("\tDevice will boot up in x8 SDR or DDR bus width.");
|
||||
|
||||
break;
|
||||
case 3:
|
||||
sb.AppendLine("\tUnknown boot condition for bus width with code 3.");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
sb.AppendLine((csd.BootBusConditions & 4) == 4
|
||||
? "\tDevice will retain boot conditions after boot operation."
|
||||
: "\tDevice will reset boot conditions to compatibility mode after boot operation.");
|
||||
|
||||
switch((csd.BootBusConditions & 0x24) >> 3)
|
||||
{
|
||||
case 0:
|
||||
sb.AppendLine("\tDevice will use single data rate with compatible timings in boot operation.");
|
||||
|
||||
break;
|
||||
case 1:
|
||||
sb.AppendLine("\tDevice will use single data rate with high speed timings in boot operation.");
|
||||
|
||||
break;
|
||||
case 2:
|
||||
sb.AppendLine("\tDevice will use dual data rate in boot operation.");
|
||||
|
||||
break;
|
||||
case 3:
|
||||
sb.AppendLine("\tDevice will use unknown boot mode with code 3.");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if(csd.HighCapacityEraseGroupDefinition.HasFlag(HighCapacityEraseGroupDefinition.Enabled))
|
||||
sb.AppendLine("\tDevice will use high capacity erase unit size, timeout and write protect group size definitions.");
|
||||
|
||||
switch(csd.BootWriteProtectionStatus & 0x03)
|
||||
{
|
||||
case 0:
|
||||
sb.AppendLine("\tBoot area 1 is not protected");
|
||||
|
||||
break;
|
||||
case 1:
|
||||
sb.AppendLine("\tBoot area 1 is power on protected");
|
||||
|
||||
break;
|
||||
case 2:
|
||||
sb.AppendLine("\tBoot area 1 is permanently protected");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
switch((csd.BootWriteProtectionStatus & 0x0C) >> 2)
|
||||
{
|
||||
case 0:
|
||||
sb.AppendLine("\tBoot area 2 is not protected");
|
||||
|
||||
break;
|
||||
case 1:
|
||||
sb.AppendLine("\tBoot area 2 is power on protected");
|
||||
|
||||
break;
|
||||
case 2:
|
||||
sb.AppendLine("\tBoot area 2 is permanently protected");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if(csd.BootAreaWriteProtectionRegister.HasFlag(BootAreaWriteProtectionRegister.Permanent))
|
||||
{
|
||||
if(csd.BootAreaWriteProtectionRegister.HasFlag(BootAreaWriteProtectionRegister.Selected))
|
||||
{
|
||||
sb.AppendLine(csd.BootAreaWriteProtectionRegister.HasFlag(BootAreaWriteProtectionRegister.
|
||||
PermanentArea2)
|
||||
? "\tBoot area 2 is permanently write protected."
|
||||
: "\tBoot area 1 is permanently write protected.");
|
||||
}
|
||||
else
|
||||
sb.AppendLine("\tBoth boot areas are permanently write protected.");
|
||||
}
|
||||
else if(csd.BootAreaWriteProtectionRegister.HasFlag(BootAreaWriteProtectionRegister.PowerOn))
|
||||
{
|
||||
if(csd.BootAreaWriteProtectionRegister.HasFlag(BootAreaWriteProtectionRegister.Selected))
|
||||
{
|
||||
sb.AppendLine(csd.BootAreaWriteProtectionRegister.HasFlag(BootAreaWriteProtectionRegister.
|
||||
PowerOnArea2)
|
||||
? "\tBoot area 2 is write protected until next power cycle."
|
||||
: "\tBoot area 1 is write protected until next power cycle.");
|
||||
}
|
||||
else
|
||||
sb.AppendLine("\tBoth boot areas are write protected until next power cycle.");
|
||||
}
|
||||
|
||||
if(csd.BootAreaWriteProtectionRegister.HasFlag(BootAreaWriteProtectionRegister.PermanentDisable))
|
||||
sb.AppendLine("\tPermanent write protection of boot areas is disabled.");
|
||||
|
||||
if(csd.BootAreaWriteProtectionRegister.HasFlag(BootAreaWriteProtectionRegister.PowerOnDisable))
|
||||
sb.AppendLine("\tPower cycled write protection of boot areas is disabled.");
|
||||
|
||||
if(csd.UserAreaWriteProtectionRegister.HasFlag(UserAreaWriteProtectionRegister.DisablePassword))
|
||||
sb.AppendLine("\tUse of password protection features is permanently disabled.");
|
||||
|
||||
if(csd.UserAreaWriteProtectionRegister.HasFlag(UserAreaWriteProtectionRegister.DisableWriteProtect))
|
||||
sb.AppendLine("\tUse of permanent write protection is disabled.");
|
||||
|
||||
if(csd.UserAreaWriteProtectionRegister.HasFlag(UserAreaWriteProtectionRegister.DisablePermanent))
|
||||
sb.AppendLine("\tPermanent write protection is disabled.");
|
||||
|
||||
if(csd.UserAreaWriteProtectionRegister.HasFlag(UserAreaWriteProtectionRegister.DisablePowerOn))
|
||||
sb.AppendLine("\tPower cycled write protection is disabled.");
|
||||
|
||||
if(csd.UserAreaWriteProtectionRegister.HasFlag(UserAreaWriteProtectionRegister.ApplyPermanent))
|
||||
sb.AppendLine("\tPermanent write protection will be applied to selected group.");
|
||||
|
||||
if(csd.UserAreaWriteProtectionRegister.HasFlag(UserAreaWriteProtectionRegister.ApplyPowerOn))
|
||||
sb.AppendLine("\tPower cycled write protection will be applied to selected group.");
|
||||
|
||||
if((csd.FirmwareConfiguration & 0x01) == 0x01)
|
||||
sb.AppendLine("\tFirmware updates are permanently disabled");
|
||||
|
||||
@@ -754,6 +1152,17 @@ namespace Aaru.Decoders.MMC
|
||||
sb.AppendFormat("\tDevice has a {0} KiB replay protected memory block", csd.RPMBSize * 128).
|
||||
AppendLine();
|
||||
|
||||
if(csd.PartitioningSupport.HasFlag(PartitioningSupport.Supported))
|
||||
{
|
||||
sb.AppendLine("\tDevice supports partitioning features");
|
||||
|
||||
if(csd.PartitioningSupport.HasFlag(PartitioningSupport.Enhanced))
|
||||
sb.AppendLine("\tDevice can have enhanced technological features in partitions and user data area");
|
||||
|
||||
if(csd.PartitioningSupport.HasFlag(PartitioningSupport.Extended))
|
||||
sb.AppendLine("\tDevice can have extended partitions attribute.");
|
||||
}
|
||||
|
||||
switch(csd.NativeSectorSize)
|
||||
{
|
||||
case 0:
|
||||
|
||||
Reference in New Issue
Block a user