mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2025-02-09 13:14:46 +01:00
Update some gc types and other small tweaks
This commit is contained in:
parent
de84c72d2a
commit
559b8c89f9
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
|
@ -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,
|
||||||
|
|
@ -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; }
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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,10 +300,79 @@ 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;
|
||||||
public Array48<byte> Unk100;
|
public Array48<byte> Unk100;
|
||||||
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;
|
||||||
}
|
}
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -21,10 +21,18 @@ public class NativeHandle : IDisposable
|
|||||||
Handle = handle;
|
Handle = handle;
|
||||||
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();
|
||||||
|
}
|
||||||
}
|
}
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user