From 9a767b1654c074d9c39f8febcdfaf1c25745d624 Mon Sep 17 00:00:00 2001 From: Isaac Marovitz Date: Thu, 15 Feb 2024 13:05:18 -0500 Subject: [PATCH] Start Storage Impl --- src/Ryujinx.Horizon/Am/Ipc/Storage/Storage.cs | 24 +++++++------- .../Am/Ipc/Storage/StorageAccessor.cs | 31 ++++++++++++++++--- .../Am/Ipc/Storage/StorageChannel.cs | 10 +++--- .../Am/Ipc/Storage/TransferStorageAccessor.cs | 10 ++++-- src/Ryujinx.Horizon/Sdk/Am/AmResult.cs | 27 ++++++++++++++++ .../Sdk/Am/Storage/IStorage.cs | 1 - 6 files changed, 78 insertions(+), 25 deletions(-) create mode 100644 src/Ryujinx.Horizon/Sdk/Am/AmResult.cs diff --git a/src/Ryujinx.Horizon/Am/Ipc/Storage/Storage.cs b/src/Ryujinx.Horizon/Am/Ipc/Storage/Storage.cs index 6437d7758..8b475c2e6 100644 --- a/src/Ryujinx.Horizon/Am/Ipc/Storage/Storage.cs +++ b/src/Ryujinx.Horizon/Am/Ipc/Storage/Storage.cs @@ -7,11 +7,19 @@ namespace Ryujinx.Horizon.Am.Ipc.Storage { partial class Storage : IStorage { + public bool IsReadOnly { get; private set; } + public byte[] Data { get; private set; } + + public Storage(byte[] data, bool isReadOnly = false) + { + IsReadOnly = isReadOnly; + Data = data; + } + [CmifCommand(0)] public Result Open(out IStorageAccessor storageAccessor) { - storageAccessor = new StorageAccessor(); - Logger.Stub?.PrintStub(LogClass.ServiceAm); + storageAccessor = new StorageAccessor(this); return Result.Success; } @@ -19,17 +27,7 @@ namespace Ryujinx.Horizon.Am.Ipc.Storage [CmifCommand(1)] public Result OpenTransferStorage(out ITransferStorageAccessor transferStorageAccessor) { - transferStorageAccessor = new TransferStorageAccessor(); - Logger.Stub?.PrintStub(LogClass.ServiceAm); - - return Result.Success; - } - - // TODO: Get CMD No. - public Result GetAndInvalidate(out IStorage storage) - { - storage = new Storage(); - Logger.Stub?.PrintStub(LogClass.ServiceAm); + transferStorageAccessor = new TransferStorageAccessor(this); return Result.Success; } diff --git a/src/Ryujinx.Horizon/Am/Ipc/Storage/StorageAccessor.cs b/src/Ryujinx.Horizon/Am/Ipc/Storage/StorageAccessor.cs index 56b4e7651..dde4ff3c0 100644 --- a/src/Ryujinx.Horizon/Am/Ipc/Storage/StorageAccessor.cs +++ b/src/Ryujinx.Horizon/Am/Ipc/Storage/StorageAccessor.cs @@ -1,5 +1,5 @@ -using Ryujinx.Common.Logging; using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Am; using Ryujinx.Horizon.Sdk.Am.Storage; using Ryujinx.Horizon.Sdk.Sf; using Ryujinx.Horizon.Sdk.Sf.Hipc; @@ -9,11 +9,17 @@ namespace Ryujinx.Horizon.Am.Ipc.Storage { partial class StorageAccessor : IStorageAccessor { + private readonly Storage _storage; + + public StorageAccessor(Storage storage) + { + _storage = storage; + } + [CmifCommand(0)] public Result GetSize(out long size) { - size = 0; - Logger.Stub?.PrintStub(LogClass.ServiceAm); + size = _storage.Data.Length; return Result.Success; } @@ -21,7 +27,17 @@ namespace Ryujinx.Horizon.Am.Ipc.Storage [CmifCommand(10)] public Result Write(long offset, [Buffer(HipcBufferFlags.In | HipcBufferFlags.AutoSelect)] ReadOnlySpan span) { - Logger.Stub?.PrintStub(LogClass.ServiceAm); + if (_storage.IsReadOnly) + { + return AmResult.ObjectInvalid; + } + + if (offset > _storage.Data.Length) + { + return AmResult.OutOfBounds; + } + + // TODO: Write return Result.Success; } @@ -29,7 +45,12 @@ namespace Ryujinx.Horizon.Am.Ipc.Storage [CmifCommand(11)] public Result Read(long offset, [Buffer(HipcBufferFlags.Out | HipcBufferFlags.AutoSelect)] Span span) { - Logger.Stub?.PrintStub(LogClass.ServiceAm); + if (offset > _storage.Data.Length) + { + return AmResult.OutOfBounds; + } + + // TODO: Read return Result.Success; } diff --git a/src/Ryujinx.Horizon/Am/Ipc/Storage/StorageChannel.cs b/src/Ryujinx.Horizon/Am/Ipc/Storage/StorageChannel.cs index 9a2846e48..3b3409359 100644 --- a/src/Ryujinx.Horizon/Am/Ipc/Storage/StorageChannel.cs +++ b/src/Ryujinx.Horizon/Am/Ipc/Storage/StorageChannel.cs @@ -2,15 +2,18 @@ using Ryujinx.Common.Logging; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Am.Storage; using Ryujinx.Horizon.Sdk.Sf; +using System.Collections.Generic; namespace Ryujinx.Horizon.Am.Ipc.Storage { partial class StorageChannel : IStorageChannel { + private Stack _storages; + [CmifCommand(0)] public Result Push(IStorage storage) { - Logger.Stub?.PrintStub(LogClass.ServiceAm); + _storages.Push(storage); return Result.Success; } @@ -26,8 +29,7 @@ namespace Ryujinx.Horizon.Am.Ipc.Storage [CmifCommand(2)] public Result Pop(out IStorage storage) { - storage = new Storage(); - Logger.Stub?.PrintStub(LogClass.ServiceAm); + storage = _storages.Pop(); return Result.Success; } @@ -44,7 +46,7 @@ namespace Ryujinx.Horizon.Am.Ipc.Storage [CmifCommand(4)] public Result Clear() { - Logger.Stub?.PrintStub(LogClass.ServiceAm); + _storages.Clear(); return Result.Success; } diff --git a/src/Ryujinx.Horizon/Am/Ipc/Storage/TransferStorageAccessor.cs b/src/Ryujinx.Horizon/Am/Ipc/Storage/TransferStorageAccessor.cs index ac573907f..e4f7e5b4c 100644 --- a/src/Ryujinx.Horizon/Am/Ipc/Storage/TransferStorageAccessor.cs +++ b/src/Ryujinx.Horizon/Am/Ipc/Storage/TransferStorageAccessor.cs @@ -7,11 +7,17 @@ namespace Ryujinx.Horizon.Am.Ipc.Storage { partial class TransferStorageAccessor : ITransferStorageAccessor { + private readonly Storage _storage; + + public TransferStorageAccessor(Storage storage) + { + _storage = storage; + } + [CmifCommand(0)] public Result GetSize(out long size) { - size = 0; - Logger.Stub?.PrintStub(LogClass.ServiceAm); + size = _storage.Data.Length; return Result.Success; } diff --git a/src/Ryujinx.Horizon/Sdk/Am/AmResult.cs b/src/Ryujinx.Horizon/Sdk/Am/AmResult.cs new file mode 100644 index 000000000..877dea9eb --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Am/AmResult.cs @@ -0,0 +1,27 @@ +using Ryujinx.Horizon.Common; + +namespace Ryujinx.Horizon.Sdk.Am +{ + static class AmResult + { + private const int Moduleld = 128; + + public static Result NotAvailable => new(Moduleld, 2); + public static Result NoMessages => new(Moduleld, 3); + public static Result AppletLaunchFailed => new(Moduleld, 35); + public static Result TitleIdNotFound => new(Moduleld, 37); + public static Result ObjectInvalid => new(Moduleld, 500); + public static Result IStorageInUse => new(Moduleld, 502); + public static Result OutOfBounds => new(Moduleld, 502); + public static Result BufferNotAcquired => new(Moduleld, 504); + public static Result BufferAlreadyAcquired => new(Moduleld, 505); + public static Result InvalidParameters => new(Moduleld, 506); + public static Result OpenedAsWrongType => new(Moduleld, 511); + public static Result UnbalancedFatalSection => new(Moduleld, 512); + public static Result NullObject => new(Moduleld, 518); + public static Result MemoryAllocationFailed => new(Moduleld, 600); + public static Result StackPoolExhausted => new(Moduleld, 712); + public static Result DebugModeNotEnabled => new(Moduleld, 974); + public static Result DevFunctionNotEnabled => new(Moduleld, 980); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Am/Storage/IStorage.cs b/src/Ryujinx.Horizon/Sdk/Am/Storage/IStorage.cs index 524d2e923..099929876 100644 --- a/src/Ryujinx.Horizon/Sdk/Am/Storage/IStorage.cs +++ b/src/Ryujinx.Horizon/Sdk/Am/Storage/IStorage.cs @@ -7,6 +7,5 @@ namespace Ryujinx.Horizon.Sdk.Am.Storage { Result Open(out IStorageAccessor storageAccessor); Result OpenTransferStorage(out ITransferStorageAccessor transferStorageAccessor); - Result GetAndInvalidate(out IStorage storage); } }