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++) 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},"; string unknownResultLine = $"Result_{result.ModuleId}_{i} = {innerValue},";
sb.AppendLine(unknownResultLine); sb.AppendLine(unknownResultLine);
} }
@ -488,7 +488,7 @@ public static class ResultCodeGen
{ {
for (int i = prevResult + 1; i < 8192; i++) 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},"; string unknownResultLine = $"Result_{module.Id}_{i} = {innerValue},";
sb.AppendLine(unknownResultLine); sb.AppendLine(unknownResultLine);
} }

View File

@ -42,6 +42,7 @@ Id,Name,Default Namespace
168,CReport, 168,CReport,
183,Debug, 183,Debug,
189,Pwm, 189,Pwm,
192,Regulator,
198,Powctl, 198,Powctl,
202,Hid, 202,Hid,
204,Cs, 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,2555,,,,GameCardInvalidT1CardCertificate,
2,2557,,,,GameCardInvalidCa10Certificate, 2,2557,,,,GameCardInvalidCa10Certificate,
2,2558,,,,GameCardInvalidCa10CardHeader, 2,2558,,,,GameCardInvalidResponseVerificationValue,
2,2565,2595,,,GameCardCommunicationFailure, 2,2565,2595,,,GameCardCommunicationFailure,
2,2566,,,,GameCardFinishOperationFailed, 2,2566,,,,GameCardFinishOperationFailed,
@ -241,7 +241,7 @@ Module,DescriptionStart,DescriptionEnd,Flags,Namespace,Name,Summary
2,2655,,,,GameCardChallengeAndResponseFailure, 2,2655,,,,GameCardChallengeAndResponseFailure,
2,2658,,,,GameCardChangeModeToSecureFailure, 2,2658,,,,GameCardChangeModeToSecureFailure,
2,2659,,,,GameCardExchangeRandomValuesFailure, 2,2659,,,,GameCardExchangeRandomValuesFailure,
2,2660,,,,GameCardAsicChallengeCardExistenceFailure, 2,2660,,,,GameCardChallengeCardExistenceFailure,
2,2663,,,,GameCardInitializeAsicTimeOut, 2,2663,,,,GameCardInitializeAsicTimeOut,
2,2665,2669,,,GameCardSplFailure, 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(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(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(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(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(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; } [InlineArray(14)] public struct Array14<T> { public readonly int Length => 14; private T _0; }

View File

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

View File

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

View File

@ -316,7 +316,7 @@ public static class ResultFs
/// <summary>Error code: 2002-2557; Inner value: 0x13fa02</summary> /// <summary>Error code: 2002-2557; Inner value: 0x13fa02</summary>
public static Result.Base GameCardInvalidCa10Certificate => new Result.Base(ModuleFs, 2557); public static Result.Base GameCardInvalidCa10Certificate => new Result.Base(ModuleFs, 2557);
/// <summary>Error code: 2002-2558; Inner value: 0x13fc02</summary> /// <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> /// <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); } 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> /// <summary>Error code: 2002-2659; Inner value: 0x14c602</summary>
public static Result.Base GameCardExchangeRandomValuesFailure => new Result.Base(ModuleFs, 2659); public static Result.Base GameCardExchangeRandomValuesFailure => new Result.Base(ModuleFs, 2659);
/// <summary>Error code: 2002-2660; Inner value: 0x14c802</summary> /// <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> /// <summary>Error code: 2002-2663; Inner value: 0x14ce02</summary>
public static Result.Base GameCardInitializeAsicTimeOut => new Result.Base(ModuleFs, 2663); public static Result.Base GameCardInitializeAsicTimeOut => new Result.Base(ModuleFs, 2663);

View File

@ -6,7 +6,7 @@ namespace LibHac.Gc;
public struct GameCardStatus public struct GameCardStatus
{ {
public Array32<byte> PartitionFsHeaderHash; public Array32<byte> PartitionFsHeaderHash;
public Array8<byte> PackageId; public Array8<byte> PackageId;
public long CardSize; public long CardSize;
public long PartitionFsHeaderAddress; public long PartitionFsHeaderAddress;
public long PartitionFsHeaderSize; 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; using LibHac.Common.FixedArrays;
namespace LibHac.Gc.Impl; namespace LibHac.Gc.Impl;
public struct CardId1 public enum MakerCodeForCardId1 : byte
{ {
public byte MakerCode; MegaChips = 0xC2,
public MemoryCapacity MemoryCapacity; Lapis = 0xAE
public byte Reserved;
public byte MemoryType;
} }
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 struct CardId2
{ {
public byte CardSecurityNumber; public CardSecurityNumber CardSecurityNumber;
public byte CardType; public CardType CardType;
public Array2<byte> Reserved; public Array2<byte> Reserved;
} }
[StructLayout(LayoutKind.Sequential)]
public struct CardId3 public struct CardId3
{ {
public Array4<byte> Reserved; 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 public enum DevCardRomSize : byte
{ {
// ReSharper disable InconsistentNaming // ReSharper disable InconsistentNaming
@ -79,6 +159,7 @@ public struct DevCardParameter
public Array436<byte> Reserved; public Array436<byte> Reserved;
} }
[StructLayout(LayoutKind.Sequential)]
public struct CardInitialDataPayload public struct CardInitialDataPayload
{ {
public Array8<byte> PackageId; public Array8<byte> PackageId;
@ -88,12 +169,25 @@ public struct CardInitialDataPayload
public Array12<byte> AuthNonce; public Array12<byte> AuthNonce;
} }
[StructLayout(LayoutKind.Sequential)]
public struct CardInitialData public struct CardInitialData
{ {
public CardInitialDataPayload Payload; public CardInitialDataPayload Payload;
public Array452<byte> Padding; 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 public enum FwVersion : byte
{ {
// ReSharper disable InconsistentNaming // ReSharper disable InconsistentNaming
@ -112,6 +206,7 @@ public enum KekIndex : byte
ForDev = 1 ForDev = 1
} }
[StructLayout(LayoutKind.Sequential)]
public struct CardHeaderEncryptedData public struct CardHeaderEncryptedData
{ {
public Array2<uint> FwVersion; public Array2<uint> FwVersion;
@ -131,18 +226,6 @@ public struct CardHeaderEncryptedData
public Array56<byte> Reserved38; 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 public enum AccessControl1ClockRate
{ {
ClockRate25MHz = 0xA10011, ClockRate25MHz = 0xA10011,
@ -155,6 +238,15 @@ public enum SelSec
T2 = 2 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 struct CardHeader
{ {
public static uint HeaderMagic => 0x44414548; // HEAD public static uint HeaderMagic => 0x44414548; // HEAD
@ -179,14 +271,19 @@ public struct CardHeader
public uint SelKey; public uint SelKey;
public uint LimAreaPage; public uint LimAreaPage;
public CardHeaderEncryptedData EncryptedData; public CardHeaderEncryptedData EncryptedData;
public KekIndex KekIndex => (KekIndex)(KeyIndex & 0xF);
public byte TitleKeyDecIndex => (byte)(KeyIndex >> 4);
} }
[StructLayout(LayoutKind.Sequential)]
public struct CardHeaderWithSignature public struct CardHeaderWithSignature
{ {
public Array256<byte> Signature; public Array256<byte> Signature;
public CardHeader Data; public CardHeader Data;
} }
[StructLayout(LayoutKind.Sequential)]
public struct T1CardCertificate public struct T1CardCertificate
{ {
public static uint CertMagic => 0x54524543; // CERT public static uint CertMagic => 0x54524543; // CERT
@ -203,6 +300,7 @@ public struct T1CardCertificate
public Array512<byte> Padding; public Array512<byte> Padding;
} }
[StructLayout(LayoutKind.Sequential)]
public struct Ca10Certificate public struct Ca10Certificate
{ {
public Array256<byte> Signature; public Array256<byte> Signature;
@ -210,3 +308,71 @@ public struct Ca10Certificate
public Array256<byte> Modulus; public Array256<byte> Modulus;
public Array464<byte> Unk230; 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> /// <summary>
/// Provides access to the game card and game card ASIC. /// Provides access to the game card and game card ASIC.
/// </summary> /// </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 /// 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 /// 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 /// 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(); if (res.IsFailure()) return res.Miss();
devHeaderBuffer.CopyTo(pooledBuffer.GetBuffer()); 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(); if (res.IsFailure()) return res.Miss();
// Read the cert area // Read the cert area
@ -988,7 +988,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
res = _gc.Activate(); res = _gc.Activate();
if (res.IsFailure()) return res.Miss(); 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(); if (res.IsFailure()) return res.Miss();
Span<byte> deviceCert = stackalloc byte[writeSize]; Span<byte> deviceCert = stackalloc byte[writeSize];
@ -1000,7 +1000,7 @@ public class GameCardManager : IStorageDeviceManager, IStorageDeviceOperator, IG
if (res.IsFailure()) return res.Miss(); if (res.IsFailure()) return res.Miss();
originalHeaderBuffer.CopyTo(pooledBuffer.GetBuffer()); 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(); if (res.IsFailure()) return res.Miss();
deviceCert.CopyTo(outBuffer); deviceCert.CopyTo(outBuffer);

View File

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

View File

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

View File

@ -22,9 +22,17 @@ public class NativeHandle : IDisposable
IsManaged = isManaged; IsManaged = isManaged;
} }
public OsNativeHandle GetOsHandle() => throw new NotImplementedException();
public void Dispose() public void Dispose()
{ {
if (IsManaged) if (IsManaged)
Os.CloseNativeHandle(Handle.Object); 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); 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] [Fact]
public static void CardInitialDataPayload_Layout() public static void CardInitialDataPayload_Layout()
{ {
@ -264,4 +282,64 @@ public class TypeLayoutTests
Assert.Equal(0x130, GetOffset(in s, in s.Modulus)); Assert.Equal(0x130, GetOffset(in s, in s.Modulus));
Assert.Equal(0x230, GetOffset(in s, in s.Unk230)); 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));
}
} }