Update some gc types and other small tweaks

This commit is contained in:
Alex Barney 2024-06-15 18:27:38 -07:00
parent de84c72d2a
commit 559b8c89f9
14 changed files with 302 additions and 44 deletions

View File

@ -471,7 +471,7 @@ public static class ResultCodeGen
{
for (int i = prevResult + 1; i < result.DescriptionStart; i++)
{
int innerValue = 2 & 0x1ff | ((i & 0x7ffff) << 9);
int innerValue = module.Id & 0x1ff | ((i & 0x7ffff) << 9);
string unknownResultLine = $"Result_{result.ModuleId}_{i} = {innerValue},";
sb.AppendLine(unknownResultLine);
}
@ -488,7 +488,7 @@ public static class ResultCodeGen
{
for (int i = prevResult + 1; i < 8192; i++)
{
int innerValue = 2 & 0x1ff | ((i & 0x7ffff) << 9);
int innerValue = module.Id & 0x1ff | ((i & 0x7ffff) << 9);
string unknownResultLine = $"Result_{module.Id}_{i} = {innerValue},";
sb.AppendLine(unknownResultLine);
}

View File

@ -42,6 +42,7 @@ Id,Name,Default Namespace
168,CReport,
183,Debug,
189,Pwm,
192,Regulator,
198,Powctl,
202,Hid,
204,Cs,

1 Id Name Default Namespace
42 168 CReport
43 183 Debug
44 189 Pwm
45 192 Regulator
46 198 Powctl
47 202 Hid
48 204 Cs

View File

@ -204,7 +204,7 @@ Module,DescriptionStart,DescriptionEnd,Flags,Namespace,Name,Summary
2,2555,,,,GameCardInvalidT1CardCertificate,
2,2557,,,,GameCardInvalidCa10Certificate,
2,2558,,,,GameCardInvalidCa10CardHeader,
2,2558,,,,GameCardInvalidResponseVerificationValue,
2,2565,2595,,,GameCardCommunicationFailure,
2,2566,,,,GameCardFinishOperationFailed,
@ -241,7 +241,7 @@ Module,DescriptionStart,DescriptionEnd,Flags,Namespace,Name,Summary
2,2655,,,,GameCardChallengeAndResponseFailure,
2,2658,,,,GameCardChangeModeToSecureFailure,
2,2659,,,,GameCardExchangeRandomValuesFailure,
2,2660,,,,GameCardAsicChallengeCardExistenceFailure,
2,2660,,,,GameCardChallengeCardExistenceFailure,
2,2663,,,,GameCardInitializeAsicTimeOut,
2,2665,2669,,,GameCardSplFailure,

1 Module DescriptionStart DescriptionEnd Flags Namespace Name Summary
204 2 2640 GameCardSendSocCertificateFailure
205 2 2644 2647 GameCardGenerateCommonKeyFailure
206 2 2645 GameCardReceiveRandomValueFailure
207 2 2646 GameCardSendRandomValueFailure
208 2 2647 GameCardDecryptRandomValueFailure
209 2 2650 2655 GameCardAuthenticateMutuallyFailure
210 2 2651 GameCardReceiveDeviceChallengeFailure
241 2 2701 GameCardGeneralIoReleaseAsicResetFailure
242 2 2702 GameCardGeneralIoHoldAsicResetFailure
243 2 2703 GameCardSetVoltageFailure
244 2 2710 2718 GameCardDataIoFailure
245 2 2711 GameCardDataIoActivateFailure
246 2 2730 2749 GameCardCardCommandFailure
247 2 2731 GameCardCommandReadId1Failure

View File

@ -10,6 +10,7 @@ namespace LibHac.Common.FixedArrays;
[InlineArray(6)] public struct Array6<T> { public readonly int Length => 6; private T _0; }
[InlineArray(7)] public struct Array7<T> { public readonly int Length => 7; private T _0; }
[InlineArray(8)] public struct Array8<T> { public readonly int Length => 8; private T _0; }
[InlineArray(9)] public struct Array9<T> { public readonly int Length => 9; private T _0; }
[InlineArray(11)] public struct Array11<T> { public readonly int Length => 11; private T _0; }
[InlineArray(12)] public struct Array12<T> { public readonly int Length => 12; private T _0; }
[InlineArray(14)] public struct Array14<T> { public readonly int Length => 14; private T _0; }

View File

@ -1,4 +1,5 @@
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -33,19 +34,19 @@ public static class SpanExtensions
public static class SpanHelpers
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining), DebuggerStepThrough]
public static Span<T> CreateSpan<T>(ref T reference, int length)
{
return MemoryMarshal.CreateSpan(ref reference, length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining), DebuggerStepThrough]
public static Span<T> AsSpan<T>(ref T reference) where T : unmanaged
{
return new Span<T>(ref reference);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining), DebuggerStepThrough]
public static Span<TSpan> AsSpan<TStruct, TSpan>(ref TStruct reference)
where TStruct : unmanaged where TSpan : unmanaged
{
@ -53,25 +54,25 @@ public static class SpanHelpers
Unsafe.SizeOf<TStruct>() / Unsafe.SizeOf<TSpan>());
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining), DebuggerStepThrough]
public static Span<byte> AsByteSpan<T>(ref T reference) where T : unmanaged
{
return CreateSpan(ref Unsafe.As<T, byte>(ref reference), Unsafe.SizeOf<T>());
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining), DebuggerStepThrough]
public static ReadOnlySpan<T> CreateReadOnlySpan<T>(ref readonly T reference, int length)
{
return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in reference), length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining), DebuggerStepThrough]
public static ReadOnlySpan<T> AsReadOnlySpan<T>(ref readonly T reference) where T : unmanaged
{
return new ReadOnlySpan<T>(in reference);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining), DebuggerStepThrough]
public static ReadOnlySpan<TSpan> AsReadOnlySpan<TStruct, TSpan>(ref readonly TStruct reference)
where TStruct : unmanaged where TSpan : unmanaged
{
@ -79,26 +80,26 @@ public static class SpanHelpers
Unsafe.SizeOf<TStruct>() / Unsafe.SizeOf<TSpan>());
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining), DebuggerStepThrough]
public static ReadOnlySpan<byte> AsReadOnlyByteSpan<T>(ref readonly T reference) where T : unmanaged
{
return CreateReadOnlySpan(in Unsafe.As<T, byte>(ref Unsafe.AsRef(in reference)), Unsafe.SizeOf<T>());
}
// All AsStruct methods do bounds checks on the input
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining), DebuggerStepThrough]
public static ref T AsStruct<T>(Span<byte> span) where T : unmanaged
{
return ref MemoryMarshal.Cast<byte, T>(span)[0];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining), DebuggerStepThrough]
public static ref readonly T AsReadOnlyStruct<T>(ReadOnlySpan<byte> span) where T : unmanaged
{
return ref MemoryMarshal.Cast<byte, T>(span)[0];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining), DebuggerStepThrough]
public static ref TTo AsStruct<TFrom, TTo>(Span<TFrom> span)
where TFrom : unmanaged
where TTo : unmanaged
@ -106,7 +107,7 @@ public static class SpanHelpers
return ref MemoryMarshal.Cast<TFrom, TTo>(span)[0];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining), DebuggerStepThrough]
public static ref readonly TTo AsStruct<TFrom, TTo>(ReadOnlySpan<TFrom> span)
where TFrom : unmanaged
where TTo : unmanaged

View File

@ -25,6 +25,7 @@ public class MemoryStorage : IStorage
Assert.SdkRequiresNotNull(buffer);
Assert.SdkRequiresInRange(size, 0, buffer.Length);
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
Abort.DoAbortUnless(buffer is null || 0 <= size && size < buffer.Length);
_buffer = buffer;

View File

@ -316,7 +316,7 @@ public static class ResultFs
/// <summary>Error code: 2002-2557; Inner value: 0x13fa02</summary>
public static Result.Base GameCardInvalidCa10Certificate => new Result.Base(ModuleFs, 2557);
/// <summary>Error code: 2002-2558; Inner value: 0x13fc02</summary>
public static Result.Base GameCardInvalidCa10CardHeader => new Result.Base(ModuleFs, 2558);
public static Result.Base GameCardInvalidResponseVerificationValue => new Result.Base(ModuleFs, 2558);
/// <summary>Error code: 2002-2565; Range: 2565-2595; Inner value: 0x140a02</summary>
public static Result.Base GameCardCommunicationFailure { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleFs, 2565, 2595); }
@ -387,7 +387,7 @@ public static class ResultFs
/// <summary>Error code: 2002-2659; Inner value: 0x14c602</summary>
public static Result.Base GameCardExchangeRandomValuesFailure => new Result.Base(ModuleFs, 2659);
/// <summary>Error code: 2002-2660; Inner value: 0x14c802</summary>
public static Result.Base GameCardAsicChallengeCardExistenceFailure => new Result.Base(ModuleFs, 2660);
public static Result.Base GameCardChallengeCardExistenceFailure => new Result.Base(ModuleFs, 2660);
/// <summary>Error code: 2002-2663; Inner value: 0x14ce02</summary>
public static Result.Base GameCardInitializeAsicTimeOut => new Result.Base(ModuleFs, 2663);

View File

@ -6,7 +6,7 @@ namespace LibHac.Gc;
public struct GameCardStatus
{
public Array32<byte> PartitionFsHeaderHash;
public Array8<byte> PackageId;
public Array8<byte> PackageId;
public long CardSize;
public long PartitionFsHeaderAddress;
public long PartitionFsHeaderSize;

View File

@ -1,28 +1,108 @@
using System.Runtime.InteropServices;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using LibHac.Common.FixedArrays;
namespace LibHac.Gc.Impl;
public struct CardId1
public enum MakerCodeForCardId1 : byte
{
public byte MakerCode;
public MemoryCapacity MemoryCapacity;
public byte Reserved;
public byte MemoryType;
MegaChips = 0xC2,
Lapis = 0xAE
}
public enum MemoryCapacity : byte
{
// ReSharper disable InconsistentNaming
Capacity1GB = 0xFA,
Capacity2GB = 0xF8,
Capacity4GB = 0xF0,
Capacity8GB = 0xE0,
Capacity16GB = 0xE1,
Capacity32GB = 0xE2
// ReSharper restore InconsistentNaming
}
public enum MemoryType : byte
{
T1RomFast = 0x01,
T2RomFast = 0x02,
T1NandFast = 0x09,
T2NandFast = 0x0A,
T1RomLate = 0x21,
T2RomLate = 0x22,
T1NandLate = 0x29,
T2NandLate = 0x2A
}
public enum CardSecurityNumber : byte
{
Number0 = 0,
Number1 = 1,
Number2 = 2,
Number3 = 3,
Number4 = 4
}
public enum CardType : byte
{
Rom = 0,
WritableDevT1 = 1,
WritableProdT1 = 2,
WritableDevT2 = 3,
WritableProdT2 = 4
}
[StructLayout(LayoutKind.Sequential)]
public struct CardId1
{
public MakerCodeForCardId1 MakerCode;
public MemoryCapacity MemoryCapacity;
public byte Reserved;
public MemoryType MemoryType;
}
[StructLayout(LayoutKind.Sequential)]
public struct CardId2
{
public byte CardSecurityNumber;
public byte CardType;
public CardSecurityNumber CardSecurityNumber;
public CardType CardType;
public Array2<byte> Reserved;
}
[StructLayout(LayoutKind.Sequential)]
public struct CardId3
{
public Array4<byte> Reserved;
}
public enum MakerCodeForCardUid : byte
{
Maker0 = 0,
Maker1 = 1,
Maker2 = 2,
}
public enum CardTypeForUid : byte
{
WritableDev = 0xFE,
WritableProd = 0xFF
}
[StructLayout(LayoutKind.Sequential)]
public struct CardUid
{
public MakerCodeForCardUid MakerCode;
public byte Version;
public CardTypeForUid CardType;
public Array9<byte> UniqueData;
public uint Random;
public byte PlatformFlag;
public Array11<byte> Reserved;
public CardId1 CardId1;
public Array32<byte> Mac;
}
public enum DevCardRomSize : byte
{
// ReSharper disable InconsistentNaming
@ -79,6 +159,7 @@ public struct DevCardParameter
public Array436<byte> Reserved;
}
[StructLayout(LayoutKind.Sequential)]
public struct CardInitialDataPayload
{
public Array8<byte> PackageId;
@ -88,12 +169,25 @@ public struct CardInitialDataPayload
public Array12<byte> AuthNonce;
}
[StructLayout(LayoutKind.Sequential)]
public struct CardInitialData
{
public CardInitialDataPayload Payload;
public Array452<byte> Padding;
}
[StructLayout(LayoutKind.Sequential)]
public struct CardSpecificData
{
public uint AsicSecurityMode;
public uint AsicStatus;
public CardId1 CardId1;
public CardId2 CardId2;
public Array64<byte> CardUid;
public Array400<byte> Reserved;
public Array32<byte> Mac;
}
public enum FwVersion : byte
{
// ReSharper disable InconsistentNaming
@ -112,6 +206,7 @@ public enum KekIndex : byte
ForDev = 1
}
[StructLayout(LayoutKind.Sequential)]
public struct CardHeaderEncryptedData
{
public Array2<uint> FwVersion;
@ -131,18 +226,6 @@ public struct CardHeaderEncryptedData
public Array56<byte> Reserved38;
}
public enum MemoryCapacity : byte
{
// ReSharper disable InconsistentNaming
Capacity1GB = 0xFA,
Capacity2GB = 0xF8,
Capacity4GB = 0xF0,
Capacity8GB = 0xE0,
Capacity16GB = 0xE1,
Capacity32GB = 0xE2
// ReSharper restore InconsistentNaming
}
public enum AccessControl1ClockRate
{
ClockRate25MHz = 0xA10011,
@ -155,6 +238,15 @@ public enum SelSec
T2 = 2
}
public enum BusPower
{
// ReSharper disable InconsistentNaming
Power_3_1V = 0,
Power_1_8V = 1
// ReSharper restore InconsistentNaming
}
[StructLayout(LayoutKind.Sequential)]
public struct CardHeader
{
public static uint HeaderMagic => 0x44414548; // HEAD
@ -179,14 +271,19 @@ public struct CardHeader
public uint SelKey;
public uint LimAreaPage;
public CardHeaderEncryptedData EncryptedData;
public KekIndex KekIndex => (KekIndex)(KeyIndex & 0xF);
public byte TitleKeyDecIndex => (byte)(KeyIndex >> 4);
}
[StructLayout(LayoutKind.Sequential)]
public struct CardHeaderWithSignature
{
public Array256<byte> Signature;
public CardHeader Data;
}
[StructLayout(LayoutKind.Sequential)]
public struct T1CardCertificate
{
public static uint CertMagic => 0x54524543; // CERT
@ -203,10 +300,79 @@ public struct T1CardCertificate
public Array512<byte> Padding;
}
[StructLayout(LayoutKind.Sequential)]
public struct Ca10Certificate
{
public Array256<byte> Signature;
public Array48<byte> Unk100;
public Array256<byte> Modulus;
public Array464<byte> Unk230;
}
[StructLayout(LayoutKind.Sequential)]
public struct CardInitReceiveData
{
public uint CupVersion;
public CardId1 CardId1;
}
[StructLayout(LayoutKind.Sequential)]
public struct CardSecurityInformation
{
public uint MemoryInterfaceMode;
public uint AsicStatus;
public CardId1 Id1;
public CardId2 Id2;
public CardUid Uid;
public Array400<byte> Reserved;
public Array32<byte> Mac;
public Array1024<byte> CardCertificate;
public CardInitialData InitialData;
[UnscopedRef]
public ref T1CardCertificate T1Certificate =>
ref Unsafe.As<byte, T1CardCertificate>(ref MemoryMarshal.GetReference(CardCertificate[..]));
}
public enum AsicFirmwareType : byte
{
Read = 0,
Write = 1
}
public enum AsicState : byte
{
Initial = 0,
Secure = 1
}
public enum GameCardMode : byte
{
Initial = 0,
Normal = 1,
Secure = 2,
Debug = 3
}
[StructLayout(LayoutKind.Sequential)]
public struct TotalAsicInfo
{
public uint InitializeCount;
public uint AwakenCount;
public ushort AwakenFailureCount;
public Array2<byte> Reserved;
}
[StructLayout(LayoutKind.Sequential)]
public struct CardAccessInternalInfo
{
public ushort RetryLimitOutNum;
public ushort AsicReinitializeCount;
public ushort AsicReinitializeFailureNum;
public ushort RefreshSuccessCount;
public uint LastReadErrorPageAddress;
public uint LastReadErrorPageCount;
public uint ReadCountFromInsert;
public uint ReadCountFromAwaken;
public Result LastAsicReinitializeFailureResult;
}

View File

@ -22,7 +22,7 @@ namespace LibHac.GcSrv;
/// <summary>
/// Provides access to the game card and game card ASIC.
/// </summary>
/// <remarks><para> he manager keeps track of the state of the ASIC and uses a handle system to control access to the
/// <remarks><para>The manager keeps track of the state of the ASIC and uses a handle system to control access to the
/// storage device. When a consumer wants to access the device, they are given a handle that will be used to make sure
/// they're accessing the same device that they originally opened. The manager's internal handle is incremented every
/// time the game card is deactivated. This ensures the consumer doesn't do things like accidentally continue reading
@ -980,7 +980,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
if (res.IsFailure()) return res.Miss();
devHeaderBuffer.CopyTo(pooledBuffer.GetBuffer());
res = _gc.Writer.Write(pooledBuffer.GetBuffer(), GcCardKeyAreaPageCount, 1);
res = _gc.Writer.Write(pooledBuffer.GetBuffer(), GcCardKeyAreaPageCount, GcDeviceCertificatePageCount);
if (res.IsFailure()) return res.Miss();
// Read the cert area
@ -988,7 +988,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
res = _gc.Activate();
if (res.IsFailure()) return res.Miss();
res = _gc.Read(pooledBuffer.GetBuffer(), GcCertAreaPageAddress, 1);
res = _gc.Read(pooledBuffer.GetBuffer(), GcCertAreaPageAddress, GcDeviceCertificatePageCount);
if (res.IsFailure()) return res.Miss();
Span<byte> deviceCert = stackalloc byte[writeSize];
@ -1000,7 +1000,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
if (res.IsFailure()) return res.Miss();
originalHeaderBuffer.CopyTo(pooledBuffer.GetBuffer());
res = _gc.Writer.Write(pooledBuffer.GetBuffer(), GcCardKeyAreaPageCount, 1);
res = _gc.Writer.Write(pooledBuffer.GetBuffer(), GcCardKeyAreaPageCount, GcDeviceCertificatePageCount);
if (res.IsFailure()) return res.Miss();
deviceCert.CopyTo(outBuffer);

View File

@ -76,7 +76,7 @@ public partial class SdmmcApi
public void Initialize(Port port)
{
throw new NotImplementedException();
// Todo: Implement
}
public void Finalize(Port port)

View File

@ -94,6 +94,8 @@ public class SdCardManager : IStorageDeviceManager, IStorageDeviceOperator, ISdm
if (_isInitialized)
return;
_sdmmc.Initialize(_port);
// Missing: Work buffer management
if (_detectionEventManager.HasValue)

View File

@ -21,10 +21,18 @@ public class NativeHandle : IDisposable
Handle = handle;
IsManaged = isManaged;
}
public OsNativeHandle GetOsHandle() => throw new NotImplementedException();
public void Dispose()
{
if (IsManaged)
Os.CloseNativeHandle(Handle.Object);
}
public void Detach()
{
IsManaged = false;
Handle = new Handle();
}
}

View File

@ -105,6 +105,24 @@ public class TypeLayoutTests
Assert.Equal(Values.GcRsaPublicExponentLength, s.PublicKeyExponent.Length);
}
[Fact]
public static void CardUid_Layout()
{
var s = new CardUid();
Assert.Equal(0x40, Unsafe.SizeOf<CardUid>());
Assert.Equal(0x00, GetOffset(in s, in s.MakerCode));
Assert.Equal(0x01, GetOffset(in s, in s.Version));
Assert.Equal(0x02, GetOffset(in s, in s.CardType));
Assert.Equal(0x03, GetOffset(in s, in s.UniqueData));
Assert.Equal(0x0C, GetOffset(in s, in s.Random));
Assert.Equal(0x10, GetOffset(in s, in s.PlatformFlag));
Assert.Equal(0x11, GetOffset(in s, in s.Reserved));
Assert.Equal(0x1C, GetOffset(in s, in s.CardId1));
Assert.Equal(0x20, GetOffset(in s, in s.Mac));
}
[Fact]
public static void CardInitialDataPayload_Layout()
{
@ -264,4 +282,64 @@ public class TypeLayoutTests
Assert.Equal(0x130, GetOffset(in s, in s.Modulus));
Assert.Equal(0x230, GetOffset(in s, in s.Unk230));
}
[Fact]
public static void CardInitReceiveData_Layout()
{
var s = new CardInitReceiveData();
Assert.Equal(8, Unsafe.SizeOf<CardInitReceiveData>());
Assert.Equal(0, GetOffset(in s, in s.CupVersion));
Assert.Equal(4, GetOffset(in s, in s.CardId1));
}
[Fact]
public static void CardSecurityInformation_Layout()
{
var s = new CardSecurityInformation();
Assert.Equal(0x800, Unsafe.SizeOf<CardSecurityInformation>());
Assert.Equal(0x000, GetOffset(in s, in s.MemoryInterfaceMode));
Assert.Equal(0x004, GetOffset(in s, in s.AsicStatus));
Assert.Equal(0x008, GetOffset(in s, in s.Id1));
Assert.Equal(0x00C, GetOffset(in s, in s.Id2));
Assert.Equal(0x010, GetOffset(in s, in s.Uid));
Assert.Equal(0x050, GetOffset(in s, in s.Reserved));
Assert.Equal(0x1E0, GetOffset(in s, in s.Mac));
Assert.Equal(0x200, GetOffset(in s, in s.CardCertificate));
Assert.Equal(0x600, GetOffset(in s, in s.InitialData));
}
[Fact]
public static void TotalAsicInfo_Layout()
{
var s = new TotalAsicInfo();
Assert.Equal(0xC, Unsafe.SizeOf<TotalAsicInfo>());
Assert.Equal(0x0, GetOffset(in s, in s.InitializeCount));
Assert.Equal(0x4, GetOffset(in s, in s.AwakenCount));
Assert.Equal(0x8, GetOffset(in s, in s.AwakenFailureCount));
Assert.Equal(0xA, GetOffset(in s, in s.Reserved));
}
[Fact]
public static void CardAccessInternalInfo_Layout()
{
var s = new CardAccessInternalInfo();
Assert.Equal(0x1C, Unsafe.SizeOf<CardAccessInternalInfo>());
Assert.Equal(0x00, GetOffset(in s, in s.RetryLimitOutNum));
Assert.Equal(0x02, GetOffset(in s, in s.AsicReinitializeCount));
Assert.Equal(0x04, GetOffset(in s, in s.AsicReinitializeFailureNum));
Assert.Equal(0x06, GetOffset(in s, in s.RefreshSuccessCount));
Assert.Equal(0x08, GetOffset(in s, in s.LastReadErrorPageAddress));
Assert.Equal(0x0C, GetOffset(in s, in s.LastReadErrorPageCount));
Assert.Equal(0x10, GetOffset(in s, in s.ReadCountFromInsert));
Assert.Equal(0x14, GetOffset(in s, in s.ReadCountFromAwaken));
Assert.Equal(0x18, GetOffset(in s, in s.LastAsicReinitializeFailureResult));
}
}