mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-11-20 03:56:34 +00:00
[Ryujinx.Horizon] Address dotnet-format issues (#5381)
* dotnet format style --severity info Some changes were manually reverted. * dotnet format analyzers --serverity info Some changes have been minimally adapted. * Restore a few unused methods and variables * Silence dotnet format IDE0060 warnings * Silence dotnet format IDE0052 warnings * Address dotnet format CA1822 warnings * Address most dotnet format whitespace warnings * Apply dotnet format whitespace formatting A few of them have been manually reverted and the corresponding warning was silenced * Revert formatting changes for while and for-loops * Run dotnet format whitespace after rebase * Run dotnet format style after rebase * Run dotnet format after rebase and remove unused usings - analyzers - style - whitespace * Add comments to disabled warnings * Remove a few unused parameters * Simplify properties and array initialization, Use const when possible, Remove trailing commas * Address IDE0251 warnings * Silence IDE0060 in .editorconfig * Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas" This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e. * dotnet format whitespace after rebase * First dotnet format pass * Add trailing commas and fix formatting issues * Convert if-else chain to switch block * Address review feedback
This commit is contained in:
parent
801b71a128
commit
02b5c7ea89
105 changed files with 617 additions and 637 deletions
|
@ -1,5 +1,4 @@
|
||||||
using Ryujinx.Horizon.Bcat.Ipc;
|
using Ryujinx.Horizon.Bcat.Types;
|
||||||
using Ryujinx.Horizon.Bcat.Types;
|
|
||||||
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
||||||
using Ryujinx.Horizon.Sdk.Sm;
|
using Ryujinx.Horizon.Sdk.Sm;
|
||||||
|
|
||||||
|
@ -8,7 +7,7 @@ namespace Ryujinx.Horizon.Bcat
|
||||||
internal class BcatIpcServer
|
internal class BcatIpcServer
|
||||||
{
|
{
|
||||||
private const int BcatMaxSessionsCount = 8;
|
private const int BcatMaxSessionsCount = 8;
|
||||||
private const int BcatTotalMaxSessionsCount = BcatMaxSessionsCount * 4;
|
private const int BcatTotalMaxSessionsCount = BcatMaxSessionsCount * 4;
|
||||||
|
|
||||||
private const int PointerBufferSize = 0x400;
|
private const int PointerBufferSize = 0x400;
|
||||||
private const int MaxDomains = 64;
|
private const int MaxDomains = 64;
|
||||||
|
@ -29,10 +28,12 @@ namespace Ryujinx.Horizon.Bcat
|
||||||
|
|
||||||
_serverManager = new BcatServerManager(allocator, _sm, MaxPortsCount, _bcatManagerOptions, BcatTotalMaxSessionsCount);
|
_serverManager = new BcatServerManager(allocator, _sm, MaxPortsCount, _bcatManagerOptions, BcatTotalMaxSessionsCount);
|
||||||
|
|
||||||
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
_serverManager.RegisterServer((int)BcatPortIndex.Admin, ServiceName.Encode("bcat:a"), BcatMaxSessionsCount);
|
_serverManager.RegisterServer((int)BcatPortIndex.Admin, ServiceName.Encode("bcat:a"), BcatMaxSessionsCount);
|
||||||
_serverManager.RegisterServer((int)BcatPortIndex.Manager, ServiceName.Encode("bcat:m"), BcatMaxSessionsCount);
|
_serverManager.RegisterServer((int)BcatPortIndex.Manager, ServiceName.Encode("bcat:m"), BcatMaxSessionsCount);
|
||||||
_serverManager.RegisterServer((int)BcatPortIndex.User, ServiceName.Encode("bcat:u"), BcatMaxSessionsCount);
|
_serverManager.RegisterServer((int)BcatPortIndex.User, ServiceName.Encode("bcat:u"), BcatMaxSessionsCount);
|
||||||
_serverManager.RegisterServer((int)BcatPortIndex.System, ServiceName.Encode("bcat:s"), BcatMaxSessionsCount);
|
_serverManager.RegisterServer((int)BcatPortIndex.System, ServiceName.Encode("bcat:s"), BcatMaxSessionsCount);
|
||||||
|
#pragma warning restore IDE0055
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ServiceRequests()
|
public void ServiceRequests()
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
using Ryujinx.Horizon.LogManager;
|
namespace Ryujinx.Horizon.Bcat
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Ryujinx.Horizon.Bcat
|
|
||||||
{
|
{
|
||||||
internal class BcatMain : IService
|
internal class BcatMain : IService
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,12 +17,12 @@ namespace Ryujinx.Horizon.Bcat
|
||||||
{
|
{
|
||||||
return (BcatPortIndex)portIndex switch
|
return (BcatPortIndex)portIndex switch
|
||||||
{
|
{
|
||||||
BcatPortIndex.Admin => AcceptImpl(server, new ServiceCreator("bcat:a", BcatServicePermissionLevel.Admin)),
|
BcatPortIndex.Admin => AcceptImpl(server, new ServiceCreator("bcat:a", BcatServicePermissionLevel.Admin)),
|
||||||
BcatPortIndex.Manager => AcceptImpl(server, new ServiceCreator("bcat:m", BcatServicePermissionLevel.Manager)),
|
BcatPortIndex.Manager => AcceptImpl(server, new ServiceCreator("bcat:m", BcatServicePermissionLevel.Manager)),
|
||||||
BcatPortIndex.User => AcceptImpl(server, new ServiceCreator("bcat:u", BcatServicePermissionLevel.User)),
|
BcatPortIndex.User => AcceptImpl(server, new ServiceCreator("bcat:u", BcatServicePermissionLevel.User)),
|
||||||
BcatPortIndex.System => AcceptImpl(server, new ServiceCreator("bcat:s", BcatServicePermissionLevel.System)),
|
BcatPortIndex.System => AcceptImpl(server, new ServiceCreator("bcat:s", BcatServicePermissionLevel.System)),
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(portIndex)),
|
_ => throw new ArgumentOutOfRangeException(nameof(portIndex)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,7 @@ namespace Ryujinx.Horizon.Bcat.Ipc
|
||||||
{
|
{
|
||||||
partial class BcatService : IBcatService
|
partial class BcatService : IBcatService
|
||||||
{
|
{
|
||||||
private readonly BcatServicePermissionLevel _permissionLevel;
|
public BcatService(BcatServicePermissionLevel permissionLevel) { }
|
||||||
|
|
||||||
public BcatService(BcatServicePermissionLevel permissionLevel)
|
|
||||||
{
|
|
||||||
_permissionLevel = permissionLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
[CmifCommand(10100)]
|
[CmifCommand(10100)]
|
||||||
public Result RequestSyncDeliveryCache(out IDeliveryCacheProgressService deliveryCacheProgressService)
|
public Result RequestSyncDeliveryCache(out IDeliveryCacheProgressService deliveryCacheProgressService)
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace Ryujinx.Horizon.Bcat.Ipc
|
||||||
}
|
}
|
||||||
|
|
||||||
[CmifCommand(1)]
|
[CmifCommand(1)]
|
||||||
public Result Read(out int entriesRead, [Buffer(Sdk.Sf.Hipc.HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span<DeliveryCacheDirectoryEntry> entriesBuffer)
|
public Result Read(out int entriesRead, [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span<DeliveryCacheDirectoryEntry> entriesBuffer)
|
||||||
{
|
{
|
||||||
return _libHacService.Get.Read(out entriesRead, entriesBuffer).ToHorizonResult();
|
return _libHacService.Get.Read(out entriesRead, entriesBuffer).ToHorizonResult();
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace Ryujinx.Horizon.Bcat.Ipc
|
||||||
[CmifCommand(1)]
|
[CmifCommand(1)]
|
||||||
public Result Read(long offset, out long bytesRead, [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span<byte> data)
|
public Result Read(long offset, out long bytesRead, [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span<byte> data)
|
||||||
{
|
{
|
||||||
return _libHacService.Get.Read(out bytesRead, offset, data).ToHorizonResult();
|
return _libHacService.Get.Read(out bytesRead, offset, data).ToHorizonResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
[CmifCommand(2)]
|
[CmifCommand(2)]
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace Ryujinx.Horizon.Bcat.Ipc
|
||||||
deliveryCacheProgressImpl = new DeliveryCacheProgressImpl
|
deliveryCacheProgressImpl = new DeliveryCacheProgressImpl
|
||||||
{
|
{
|
||||||
State = DeliveryCacheProgressImpl.Status.Done,
|
State = DeliveryCacheProgressImpl.Status.Done,
|
||||||
Result = 0
|
Result = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
Logger.Stub?.PrintStub(LogClass.ServiceBcat);
|
Logger.Stub?.PrintStub(LogClass.ServiceBcat);
|
||||||
|
|
|
@ -8,11 +8,11 @@ namespace Ryujinx.Horizon.Bcat.Ipc.Types
|
||||||
public enum Status
|
public enum Status
|
||||||
{
|
{
|
||||||
// TODO: determine other values
|
// TODO: determine other values
|
||||||
Done = 9
|
Done = 9,
|
||||||
}
|
}
|
||||||
|
|
||||||
public Status State;
|
public Status State;
|
||||||
public uint Result;
|
public uint Result;
|
||||||
// TODO: reverse the rest of the structure
|
// TODO: reverse the rest of the structure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,6 @@
|
||||||
Admin,
|
Admin,
|
||||||
Manager,
|
Manager,
|
||||||
User,
|
User,
|
||||||
System
|
System,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
{
|
{
|
||||||
enum BcatServicePermissionLevel
|
enum BcatServicePermissionLevel
|
||||||
{
|
{
|
||||||
Admin = -1,
|
Admin = -1,
|
||||||
User = 1,
|
User = 1,
|
||||||
System = 2,
|
System = 2,
|
||||||
Manager = 6
|
Manager = 6,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,15 @@ namespace Ryujinx.Horizon
|
||||||
{
|
{
|
||||||
private const ulong InvalidAddress = ulong.MaxValue;
|
private const ulong InvalidAddress = ulong.MaxValue;
|
||||||
|
|
||||||
private struct Range : IComparable<Range>
|
private readonly struct Range : IComparable<Range>
|
||||||
{
|
{
|
||||||
public ulong Offset { get; }
|
public ulong Offset { get; }
|
||||||
public ulong Size { get; }
|
public ulong Size { get; }
|
||||||
|
|
||||||
public Range(ulong offset, ulong size)
|
public Range(ulong offset, ulong size)
|
||||||
{
|
{
|
||||||
Offset = offset;
|
Offset = offset;
|
||||||
Size = size;
|
Size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int CompareTo(Range other)
|
public int CompareTo(Range other)
|
||||||
|
@ -31,7 +31,7 @@ namespace Ryujinx.Horizon
|
||||||
|
|
||||||
public HeapAllocator()
|
public HeapAllocator()
|
||||||
{
|
{
|
||||||
_freeRanges = new List<Range>();
|
_freeRanges = new List<Range>();
|
||||||
_currentHeapSize = 0;
|
_currentHeapSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,8 +70,8 @@ namespace Ryujinx.Horizon
|
||||||
var range = _freeRanges[i];
|
var range = _freeRanges[i];
|
||||||
|
|
||||||
ulong alignedOffset = BitUtils.AlignUp(range.Offset, alignment);
|
ulong alignedOffset = BitUtils.AlignUp(range.Offset, alignment);
|
||||||
ulong sizeDelta = alignedOffset - range.Offset;
|
ulong sizeDelta = alignedOffset - range.Offset;
|
||||||
ulong usableSize = range.Size - sizeDelta;
|
ulong usableSize = range.Size - sizeDelta;
|
||||||
|
|
||||||
if (sizeDelta < range.Size && usableSize >= size)
|
if (sizeDelta < range.Size && usableSize >= size)
|
||||||
{
|
{
|
||||||
|
@ -82,7 +82,7 @@ namespace Ryujinx.Horizon
|
||||||
InsertFreeRange(range.Offset, sizeDelta);
|
InsertFreeRange(range.Offset, sizeDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong endOffset = range.Offset + range.Size;
|
ulong endOffset = range.Offset + range.Size;
|
||||||
ulong remainingSize = endOffset - (alignedOffset + size);
|
ulong remainingSize = endOffset - (alignedOffset + size);
|
||||||
if (remainingSize != 0)
|
if (remainingSize != 0)
|
||||||
{
|
{
|
||||||
|
@ -140,4 +140,4 @@ namespace Ryujinx.Horizon
|
||||||
_freeRanges.Insert(index, range);
|
_freeRanges.Insert(index, range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,18 @@ using LibHac;
|
||||||
|
|
||||||
namespace Ryujinx.Horizon
|
namespace Ryujinx.Horizon
|
||||||
{
|
{
|
||||||
public struct HorizonOptions
|
public readonly struct HorizonOptions
|
||||||
{
|
{
|
||||||
public bool IgnoreMissingServices { get; }
|
public bool IgnoreMissingServices { get; }
|
||||||
public bool ThrowOnInvalidCommandIds { get; }
|
public bool ThrowOnInvalidCommandIds { get; }
|
||||||
|
|
||||||
public HorizonClient BcatClient { get; }
|
public HorizonClient BcatClient { get; }
|
||||||
|
|
||||||
public HorizonOptions(bool ignoreMissingServices, HorizonClient bcatClient)
|
public HorizonOptions(bool ignoreMissingServices, HorizonClient bcatClient)
|
||||||
{
|
{
|
||||||
IgnoreMissingServices = ignoreMissingServices;
|
IgnoreMissingServices = ignoreMissingServices;
|
||||||
ThrowOnInvalidCommandIds = true;
|
ThrowOnInvalidCommandIds = true;
|
||||||
BcatClient = bcatClient;
|
BcatClient = bcatClient;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,24 +21,24 @@ namespace Ryujinx.Horizon
|
||||||
[ThreadStatic]
|
[ThreadStatic]
|
||||||
private static int _threadHandle;
|
private static int _threadHandle;
|
||||||
|
|
||||||
public static HorizonOptions Options => _options;
|
public static HorizonOptions Options => _options;
|
||||||
public static ISyscallApi Syscall => _syscall;
|
public static ISyscallApi Syscall => _syscall;
|
||||||
public static IVirtualMemoryManager AddressSpace => _addressSpace;
|
public static IVirtualMemoryManager AddressSpace => _addressSpace;
|
||||||
public static IThreadContext ThreadContext => _threadContext;
|
public static IThreadContext ThreadContext => _threadContext;
|
||||||
public static int CurrentThreadHandle => _threadHandle;
|
public static int CurrentThreadHandle => _threadHandle;
|
||||||
|
|
||||||
public static void Register(
|
public static void Register(
|
||||||
HorizonOptions options,
|
HorizonOptions options,
|
||||||
ISyscallApi syscallApi,
|
ISyscallApi syscallApi,
|
||||||
IVirtualMemoryManager addressSpace,
|
IVirtualMemoryManager addressSpace,
|
||||||
IThreadContext threadContext,
|
IThreadContext threadContext,
|
||||||
int threadHandle)
|
int threadHandle)
|
||||||
{
|
{
|
||||||
_options = options;
|
_options = options;
|
||||||
_syscall = syscallApi;
|
_syscall = syscallApi;
|
||||||
_addressSpace = addressSpace;
|
_addressSpace = addressSpace;
|
||||||
_threadContext = threadContext;
|
_threadContext = threadContext;
|
||||||
_threadHandle = threadHandle;
|
_threadHandle = threadHandle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,74 +95,52 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
||||||
|
|
||||||
LogDataChunkKey key = (LogDataChunkKey)type;
|
LogDataChunkKey key = (LogDataChunkKey)type;
|
||||||
|
|
||||||
if (key == LogDataChunkKey.Start)
|
switch (key)
|
||||||
{
|
{
|
||||||
reader.Skip(size);
|
case LogDataChunkKey.Start:
|
||||||
|
reader.Skip(size);
|
||||||
continue;
|
continue;
|
||||||
}
|
case LogDataChunkKey.Stop:
|
||||||
else if (key == LogDataChunkKey.Stop)
|
break;
|
||||||
{
|
case LogDataChunkKey.Line when !reader.TryRead(out _logPacket.Line):
|
||||||
break;
|
case LogDataChunkKey.DropCount when !reader.TryRead(out _logPacket.DropCount):
|
||||||
}
|
case LogDataChunkKey.Time when !reader.TryRead(out _logPacket.Time):
|
||||||
else if (key == LogDataChunkKey.Line)
|
|
||||||
{
|
|
||||||
if (!reader.TryRead<int>(out _logPacket.Line))
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
case LogDataChunkKey.Message:
|
||||||
}
|
|
||||||
else if (key == LogDataChunkKey.DropCount)
|
|
||||||
{
|
|
||||||
if (!reader.TryRead<long>(out _logPacket.DropCount))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (key == LogDataChunkKey.Time)
|
|
||||||
{
|
|
||||||
if (!reader.TryRead<long>(out _logPacket.Time))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (key == LogDataChunkKey.Message)
|
|
||||||
{
|
|
||||||
string text = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
|
||||||
|
|
||||||
if (isHeadPacket && isTailPacket)
|
|
||||||
{
|
|
||||||
_logPacket.Message = text;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logPacket.Message += text;
|
|
||||||
|
|
||||||
if (_logPacket.Message.Length >= MessageLengthLimit)
|
|
||||||
{
|
{
|
||||||
isTailPacket = true;
|
string text = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
||||||
|
|
||||||
|
if (isHeadPacket && isTailPacket)
|
||||||
|
{
|
||||||
|
_logPacket.Message = text;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logPacket.Message += text;
|
||||||
|
|
||||||
|
if (_logPacket.Message.Length >= MessageLengthLimit)
|
||||||
|
{
|
||||||
|
isTailPacket = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
case LogDataChunkKey.Filename:
|
||||||
}
|
_logPacket.Filename = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
||||||
else if (key == LogDataChunkKey.Filename)
|
break;
|
||||||
{
|
case LogDataChunkKey.Function:
|
||||||
_logPacket.Filename = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
_logPacket.Function = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
||||||
}
|
break;
|
||||||
else if (key == LogDataChunkKey.Function)
|
case LogDataChunkKey.Module:
|
||||||
{
|
_logPacket.Module = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
||||||
_logPacket.Function = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
break;
|
||||||
}
|
case LogDataChunkKey.Thread:
|
||||||
else if (key == LogDataChunkKey.Module)
|
_logPacket.Thread = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
||||||
{
|
break;
|
||||||
_logPacket.Module = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
case LogDataChunkKey.ProgramName:
|
||||||
}
|
_logPacket.ProgramName = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
||||||
else if (key == LogDataChunkKey.Thread)
|
break;
|
||||||
{
|
|
||||||
_logPacket.Thread = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
|
||||||
}
|
|
||||||
else if (key == LogDataChunkKey.ProgramName)
|
|
||||||
{
|
|
||||||
_logPacket.ProgramName = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +155,7 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!reader.TryRead<byte>(out encoded))
|
if (!reader.TryRead(out encoded))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -190,4 +168,4 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,4 +17,4 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,13 +9,13 @@ namespace Ryujinx.Horizon.LogManager
|
||||||
private const int LogMaxSessionsCount = 42;
|
private const int LogMaxSessionsCount = 42;
|
||||||
|
|
||||||
private const int PointerBufferSize = 0x400;
|
private const int PointerBufferSize = 0x400;
|
||||||
private const int MaxDomains = 31;
|
private const int MaxDomains = 31;
|
||||||
private const int MaxDomainObjects = 61;
|
private const int MaxDomainObjects = 61;
|
||||||
private const int MaxPortsCount = 1;
|
private const int MaxPortsCount = 1;
|
||||||
|
|
||||||
private static readonly ManagerOptions _logManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
private static readonly ManagerOptions _logManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
||||||
|
|
||||||
private SmApi _sm;
|
private SmApi _sm;
|
||||||
private ServerManager _serverManager;
|
private ServerManager _serverManager;
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
|
@ -40,4 +40,4 @@ namespace Ryujinx.Horizon.LogManager
|
||||||
_serverManager.Dispose();
|
_serverManager.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,4 +14,4 @@
|
||||||
ipcServer.Shutdown();
|
ipcServer.Shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,15 +5,15 @@ namespace Ryujinx.Horizon.LogManager.Types
|
||||||
{
|
{
|
||||||
struct LogPacket
|
struct LogPacket
|
||||||
{
|
{
|
||||||
public string Message;
|
public string Message;
|
||||||
public int Line;
|
public int Line;
|
||||||
public string Filename;
|
public string Filename;
|
||||||
public string Function;
|
public string Function;
|
||||||
public string Module;
|
public string Module;
|
||||||
public string Thread;
|
public string Thread;
|
||||||
public long DropCount;
|
public long DropCount;
|
||||||
public long Time;
|
public long Time;
|
||||||
public string ProgramName;
|
public string ProgramName;
|
||||||
public LogSeverity Severity;
|
public LogSeverity Severity;
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
@ -35,12 +35,12 @@ namespace Ryujinx.Horizon.LogManager.Types
|
||||||
{
|
{
|
||||||
builder.AppendLine($" ProgramName: {ProgramName}");
|
builder.AppendLine($" ProgramName: {ProgramName}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Module))
|
if (!string.IsNullOrEmpty(Module))
|
||||||
{
|
{
|
||||||
builder.AppendLine($" Module: {Module}");
|
builder.AppendLine($" Module: {Module}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Thread))
|
if (!string.IsNullOrEmpty(Thread))
|
||||||
{
|
{
|
||||||
builder.AppendLine($" Thread: {Thread}");
|
builder.AppendLine($" Thread: {Thread}");
|
||||||
|
@ -69,4 +69,4 @@ namespace Ryujinx.Horizon.LogManager.Types
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ using Ryujinx.Horizon.Sdk.Sf;
|
||||||
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using ApplicationId = Ryujinx.Horizon.Sdk.Ncm.ApplicationId;
|
||||||
|
|
||||||
namespace Ryujinx.Horizon.Prepo.Ipc
|
namespace Ryujinx.Horizon.Prepo.Ipc
|
||||||
{
|
{
|
||||||
|
@ -18,14 +19,14 @@ namespace Ryujinx.Horizon.Prepo.Ipc
|
||||||
enum PlayReportKind
|
enum PlayReportKind
|
||||||
{
|
{
|
||||||
Normal,
|
Normal,
|
||||||
System
|
System,
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly PrepoServicePermissionLevel _permissionLevel;
|
private readonly PrepoServicePermissionLevel _permissionLevel;
|
||||||
private ulong _systemSessionId;
|
private ulong _systemSessionId;
|
||||||
|
|
||||||
private bool _immediateTransmissionEnabled = false;
|
private bool _immediateTransmissionEnabled;
|
||||||
private bool _userAgreementCheckEnabled = true;
|
private bool _userAgreementCheckEnabled = true;
|
||||||
|
|
||||||
public PrepoService(PrepoServicePermissionLevel permissionLevel)
|
public PrepoService(PrepoServicePermissionLevel permissionLevel)
|
||||||
{
|
{
|
||||||
|
@ -107,7 +108,7 @@ namespace Ryujinx.Horizon.Prepo.Ipc
|
||||||
}
|
}
|
||||||
|
|
||||||
[CmifCommand(20100)]
|
[CmifCommand(20100)]
|
||||||
public Result SaveSystemReport([Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, Sdk.Ncm.ApplicationId applicationId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer)
|
public Result SaveSystemReport([Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, ApplicationId applicationId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer)
|
||||||
{
|
{
|
||||||
if ((_permissionLevel & PrepoServicePermissionLevel.System) != 0)
|
if ((_permissionLevel & PrepoServicePermissionLevel.System) != 0)
|
||||||
{
|
{
|
||||||
|
@ -118,7 +119,7 @@ namespace Ryujinx.Horizon.Prepo.Ipc
|
||||||
}
|
}
|
||||||
|
|
||||||
[CmifCommand(20101)]
|
[CmifCommand(20101)]
|
||||||
public Result SaveSystemReportWithUser(Uid userId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, Sdk.Ncm.ApplicationId applicationId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer)
|
public Result SaveSystemReportWithUser(Uid userId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, ApplicationId applicationId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer)
|
||||||
{
|
{
|
||||||
if ((_permissionLevel & PrepoServicePermissionLevel.System) != 0)
|
if ((_permissionLevel & PrepoServicePermissionLevel.System) != 0)
|
||||||
{
|
{
|
||||||
|
@ -164,7 +165,7 @@ namespace Ryujinx.Horizon.Prepo.Ipc
|
||||||
return PrepoResult.PermissionDenied;
|
return PrepoResult.PermissionDenied;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Result ProcessPlayReport(PlayReportKind playReportKind, ReadOnlySpan<byte> gameRoomBuffer, ReadOnlySpan<byte> reportBuffer, ulong pid, Uid userId, bool withUserId = false, Sdk.Ncm.ApplicationId applicationId = default)
|
private static Result ProcessPlayReport(PlayReportKind playReportKind, ReadOnlySpan<byte> gameRoomBuffer, ReadOnlySpan<byte> reportBuffer, ulong pid, Uid userId, bool withUserId = false, ApplicationId applicationId = default)
|
||||||
{
|
{
|
||||||
if (withUserId)
|
if (withUserId)
|
||||||
{
|
{
|
||||||
|
@ -191,7 +192,7 @@ namespace Ryujinx.Horizon.Prepo.Ipc
|
||||||
return PrepoResult.InvalidBufferSize;
|
return PrepoResult.InvalidBufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder builder = new();
|
StringBuilder builder = new();
|
||||||
MessagePackObject deserializedReport = MessagePackSerializer.UnpackMessagePackObject(reportBuffer.ToArray());
|
MessagePackObject deserializedReport = MessagePackSerializer.UnpackMessagePackObject(reportBuffer.ToArray());
|
||||||
|
|
||||||
builder.AppendLine();
|
builder.AppendLine();
|
||||||
|
@ -222,4 +223,4 @@ namespace Ryujinx.Horizon.Prepo.Ipc
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,13 @@ namespace Ryujinx.Horizon.Prepo
|
||||||
{
|
{
|
||||||
class PrepoIpcServer
|
class PrepoIpcServer
|
||||||
{
|
{
|
||||||
private const int PrepoMaxSessionsCount = 12;
|
private const int PrepoMaxSessionsCount = 12;
|
||||||
private const int PrepoTotalMaxSessionsCount = PrepoMaxSessionsCount * 6;
|
private const int PrepoTotalMaxSessionsCount = PrepoMaxSessionsCount * 6;
|
||||||
|
|
||||||
private const int PointerBufferSize = 0x80;
|
private const int PointerBufferSize = 0x80;
|
||||||
private const int MaxDomains = 64;
|
private const int MaxDomains = 64;
|
||||||
private const int MaxDomainObjects = 16;
|
private const int MaxDomainObjects = 16;
|
||||||
private const int MaxPortsCount = 6;
|
private const int MaxPortsCount = 6;
|
||||||
|
|
||||||
private static readonly ManagerOptions _prepoManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
private static readonly ManagerOptions _prepoManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
|
||||||
|
|
||||||
|
@ -28,12 +28,14 @@ namespace Ryujinx.Horizon.Prepo
|
||||||
|
|
||||||
_serverManager = new PrepoServerManager(allocator, _sm, MaxPortsCount, _prepoManagerOptions, PrepoTotalMaxSessionsCount);
|
_serverManager = new PrepoServerManager(allocator, _sm, MaxPortsCount, _prepoManagerOptions, PrepoTotalMaxSessionsCount);
|
||||||
|
|
||||||
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
_serverManager.RegisterServer((int)PrepoPortIndex.Admin, ServiceName.Encode("prepo:a"), PrepoMaxSessionsCount); // 1.0.0-5.1.0
|
_serverManager.RegisterServer((int)PrepoPortIndex.Admin, ServiceName.Encode("prepo:a"), PrepoMaxSessionsCount); // 1.0.0-5.1.0
|
||||||
_serverManager.RegisterServer((int)PrepoPortIndex.Admin2, ServiceName.Encode("prepo:a2"), PrepoMaxSessionsCount); // 6.0.0+
|
_serverManager.RegisterServer((int)PrepoPortIndex.Admin2, ServiceName.Encode("prepo:a2"), PrepoMaxSessionsCount); // 6.0.0+
|
||||||
_serverManager.RegisterServer((int)PrepoPortIndex.Manager, ServiceName.Encode("prepo:m"), PrepoMaxSessionsCount);
|
_serverManager.RegisterServer((int)PrepoPortIndex.Manager, ServiceName.Encode("prepo:m"), PrepoMaxSessionsCount);
|
||||||
_serverManager.RegisterServer((int)PrepoPortIndex.User, ServiceName.Encode("prepo:u"), PrepoMaxSessionsCount);
|
_serverManager.RegisterServer((int)PrepoPortIndex.User, ServiceName.Encode("prepo:u"), PrepoMaxSessionsCount);
|
||||||
_serverManager.RegisterServer((int)PrepoPortIndex.System, ServiceName.Encode("prepo:s"), PrepoMaxSessionsCount);
|
_serverManager.RegisterServer((int)PrepoPortIndex.System, ServiceName.Encode("prepo:s"), PrepoMaxSessionsCount);
|
||||||
_serverManager.RegisterServer((int)PrepoPortIndex.Debug, ServiceName.Encode("prepo:d"), PrepoMaxSessionsCount); // 1.0.0
|
_serverManager.RegisterServer((int)PrepoPortIndex.Debug, ServiceName.Encode("prepo:d"), PrepoMaxSessionsCount); // 1.0.0
|
||||||
|
#pragma warning restore IDE0055
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ServiceRequests()
|
public void ServiceRequests()
|
||||||
|
@ -46,4 +48,4 @@ namespace Ryujinx.Horizon.Prepo
|
||||||
_serverManager.Dispose();
|
_serverManager.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,4 +14,4 @@
|
||||||
ipcServer.Shutdown();
|
ipcServer.Shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,12 @@ namespace Ryujinx.Horizon.Prepo
|
||||||
{
|
{
|
||||||
private const int ModuleId = 129;
|
private const int ModuleId = 129;
|
||||||
|
|
||||||
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
public static Result InvalidArgument => new(ModuleId, 1);
|
public static Result InvalidArgument => new(ModuleId, 1);
|
||||||
public static Result InvalidState => new(ModuleId, 5);
|
public static Result InvalidState => new(ModuleId, 5);
|
||||||
public static Result InvalidBufferSize => new(ModuleId, 9);
|
public static Result InvalidBufferSize => new(ModuleId, 9);
|
||||||
public static Result PermissionDenied => new(ModuleId, 90);
|
public static Result PermissionDenied => new(ModuleId, 90);
|
||||||
public static Result InvalidPid => new(ModuleId, 101);
|
public static Result InvalidPid => new(ModuleId, 101);
|
||||||
|
#pragma warning restore IDE0055
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace Ryujinx.Horizon.Prepo
|
||||||
{
|
{
|
||||||
return (PrepoPortIndex)portIndex switch
|
return (PrepoPortIndex)portIndex switch
|
||||||
{
|
{
|
||||||
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
PrepoPortIndex.Admin => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Admin)),
|
PrepoPortIndex.Admin => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Admin)),
|
||||||
PrepoPortIndex.Admin2 => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Admin)),
|
PrepoPortIndex.Admin2 => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Admin)),
|
||||||
PrepoPortIndex.Manager => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Manager)),
|
PrepoPortIndex.Manager => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Manager)),
|
||||||
|
@ -24,7 +25,8 @@ namespace Ryujinx.Horizon.Prepo
|
||||||
PrepoPortIndex.System => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.System)),
|
PrepoPortIndex.System => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.System)),
|
||||||
PrepoPortIndex.Debug => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Debug)),
|
PrepoPortIndex.Debug => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Debug)),
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(portIndex)),
|
_ => throw new ArgumentOutOfRangeException(nameof(portIndex)),
|
||||||
|
#pragma warning restore IDE0055
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,6 @@
|
||||||
Manager,
|
Manager,
|
||||||
User,
|
User,
|
||||||
System,
|
System,
|
||||||
Debug
|
Debug,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
{
|
{
|
||||||
enum PrepoServicePermissionLevel
|
enum PrepoServicePermissionLevel
|
||||||
{
|
{
|
||||||
Admin = -1,
|
Admin = -1,
|
||||||
User = 1,
|
User = 1,
|
||||||
System = 2,
|
System = 2,
|
||||||
Manager = 6,
|
Manager = 6,
|
||||||
Debug = unchecked((int)0x80000006)
|
Debug = unchecked((int)0x80000006),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,14 +17,14 @@ namespace Ryujinx.Horizon.Sdk.Account
|
||||||
|
|
||||||
public Uid(long low, long high)
|
public Uid(long low, long high)
|
||||||
{
|
{
|
||||||
Low = low;
|
Low = low;
|
||||||
High = high;
|
High = high;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uid(byte[] bytes)
|
public Uid(byte[] bytes)
|
||||||
{
|
{
|
||||||
High = BitConverter.ToInt64(bytes, 0);
|
High = BitConverter.ToInt64(bytes, 0);
|
||||||
Low = BitConverter.ToInt64(bytes, 8);
|
Low = BitConverter.ToInt64(bytes, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uid(string hex)
|
public Uid(string hex)
|
||||||
|
@ -34,7 +34,7 @@ namespace Ryujinx.Horizon.Sdk.Account
|
||||||
throw new ArgumentException("Invalid Hex value!", nameof(hex));
|
throw new ArgumentException("Invalid Hex value!", nameof(hex));
|
||||||
}
|
}
|
||||||
|
|
||||||
Low = Convert.ToInt64(hex[16..], 16);
|
Low = Convert.ToInt64(hex[16..], 16);
|
||||||
High = Convert.ToInt64(hex[..16], 16);
|
High = Convert.ToInt64(hex[..16], 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,4 +59,4 @@ namespace Ryujinx.Horizon.Sdk.Account
|
||||||
return new UInt128((ulong)High, (ulong)Low);
|
return new UInt128((ulong)High, (ulong)Low);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Ryujinx.Horizon.Common;
|
using Ryujinx.Horizon.Common;
|
||||||
|
using Ryujinx.Horizon.Sdk.Ncm;
|
||||||
using Ryujinx.Horizon.Sdk.Sf;
|
using Ryujinx.Horizon.Sdk.Sf;
|
||||||
|
|
||||||
namespace Ryujinx.Horizon.Sdk.Bcat
|
namespace Ryujinx.Horizon.Sdk.Bcat
|
||||||
|
@ -7,6 +8,6 @@ namespace Ryujinx.Horizon.Sdk.Bcat
|
||||||
{
|
{
|
||||||
Result CreateBcatService(out IBcatService service, ulong pid);
|
Result CreateBcatService(out IBcatService service, ulong pid);
|
||||||
Result CreateDeliveryCacheStorageService(out IDeliveryCacheStorageService service, ulong pid);
|
Result CreateDeliveryCacheStorageService(out IDeliveryCacheStorageService service, ulong pid);
|
||||||
Result CreateDeliveryCacheStorageServiceWithApplicationId(out IDeliveryCacheStorageService service, Ncm.ApplicationId applicationId);
|
Result CreateDeliveryCacheStorageServiceWithApplicationId(out IDeliveryCacheStorageService service, ApplicationId applicationId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,6 @@ namespace Ryujinx.Horizon.Sdk.Diag
|
||||||
Info = 1,
|
Info = 1,
|
||||||
Warn = 2,
|
Warn = 2,
|
||||||
Error = 3,
|
Error = 3,
|
||||||
Fatal = 4
|
Fatal = 4,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,4 +9,4 @@ namespace Ryujinx.Horizon.Sdk.Lm
|
||||||
Result Log(Span<byte> message);
|
Result Log(Span<byte> message);
|
||||||
Result SetDestination(LogDestination destination);
|
Result SetDestination(LogDestination destination);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,4 +8,4 @@ namespace Ryujinx.Horizon.Sdk.Lm
|
||||||
{
|
{
|
||||||
Result OpenLogger(out LmLogger logger, ulong pid);
|
Result OpenLogger(out LmLogger logger, ulong pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,6 @@ namespace Ryujinx.Horizon.Sdk.Lm
|
||||||
Time = 9,
|
Time = 9,
|
||||||
ProgramName = 10,
|
ProgramName = 10,
|
||||||
|
|
||||||
Count
|
Count,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,6 @@ namespace Ryujinx.Horizon.Sdk.Lm
|
||||||
Uart = 1 << 1,
|
Uart = 1 << 1,
|
||||||
UartIfSleep = 1 << 2,
|
UartIfSleep = 1 << 2,
|
||||||
|
|
||||||
All = 0xffff
|
All = 0xffff,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,6 @@ namespace Ryujinx.Horizon.Sdk.Lm
|
||||||
{
|
{
|
||||||
IsHead = 1 << 0,
|
IsHead = 1 << 0,
|
||||||
IsTail = 1 << 1,
|
IsTail = 1 << 1,
|
||||||
IsLittleEndian = 1 << 2
|
IsLittleEndian = 1 << 2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,4 +49,4 @@
|
||||||
return $"0x{Id:x}";
|
return $"0x{Id:x}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
enum EventClearMode
|
enum EventClearMode
|
||||||
{
|
{
|
||||||
ManualClear,
|
ManualClear,
|
||||||
AutoClear
|
AutoClear,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,9 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
|
||||||
{
|
{
|
||||||
class MultiWaitImpl
|
class MultiWaitImpl
|
||||||
{
|
{
|
||||||
private const int WaitTimedOut = -1;
|
private const int WaitTimedOut = -1;
|
||||||
private const int WaitCancelled = -2;
|
private const int WaitCancelled = -2;
|
||||||
private const int WaitInvalid = -3;
|
private const int WaitInvalid = -3;
|
||||||
|
|
||||||
private readonly List<MultiWaitHolderBase> _multiWaits;
|
private readonly List<MultiWaitHolderBase> _multiWaits;
|
||||||
|
|
||||||
|
@ -63,10 +63,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == null)
|
result ??= WaitAnyHandleImpl(infinite, timeout);
|
||||||
{
|
|
||||||
result = WaitAnyHandleImpl(infinite, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
UnlinkHoldersFromObjectsList();
|
UnlinkHoldersFromObjectsList();
|
||||||
_waitingThreadHandle = 0;
|
_waitingThreadHandle = 0;
|
||||||
|
@ -98,7 +95,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
index = WaitSynchronization(objectHandles.Slice(0, count), minTimeout);
|
index = WaitSynchronization(objectHandles[..count], minTimeout);
|
||||||
|
|
||||||
DebugUtil.Assert(index != WaitInvalid);
|
DebugUtil.Assert(index != WaitInvalid);
|
||||||
}
|
}
|
||||||
|
@ -200,10 +197,8 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
|
||||||
{
|
{
|
||||||
return WaitCancelled;
|
return WaitCancelled;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
result.AbortOnFailure();
|
||||||
result.AbortOnFailure();
|
|
||||||
}
|
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,6 @@ namespace Ryujinx.Horizon.Sdk.OsTypes
|
||||||
enum InitializationState : byte
|
enum InitializationState : byte
|
||||||
{
|
{
|
||||||
NotInitialized,
|
NotInitialized,
|
||||||
Initialized
|
Initialized,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes
|
||||||
{
|
{
|
||||||
class MultiWaitHolderOfEvent : MultiWaitHolder
|
class MultiWaitHolderOfEvent : MultiWaitHolder
|
||||||
{
|
{
|
||||||
private Event _event;
|
private readonly Event _event;
|
||||||
private LinkedListNode<MultiWaitHolderBase> _node;
|
private LinkedListNode<MultiWaitHolderBase> _node;
|
||||||
|
|
||||||
public override TriBool Signaled
|
public override TriBool Signaled
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{
|
{
|
||||||
class MultiWaitHolderOfHandle : MultiWaitHolder
|
class MultiWaitHolderOfHandle : MultiWaitHolder
|
||||||
{
|
{
|
||||||
private int _handle;
|
private readonly int _handle;
|
||||||
|
|
||||||
public override int Handle => _handle;
|
public override int Handle => _handle;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes
|
||||||
InitiallySignaled = signaled,
|
InitiallySignaled = signaled,
|
||||||
ClearMode = clearMode,
|
ClearMode = clearMode,
|
||||||
State = InitializationState.Initialized,
|
State = InitializationState.Initialized,
|
||||||
Lock = new object()
|
Lock = new object(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,6 @@ namespace Ryujinx.Horizon.Sdk.OsTypes
|
||||||
{
|
{
|
||||||
private const int ModuleId = 3;
|
private const int ModuleId = 3;
|
||||||
|
|
||||||
public static Result OutOfResource => new Result(ModuleId, 9);
|
public static Result OutOfResource => new(ModuleId, 9);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
{
|
{
|
||||||
NotInitialized,
|
NotInitialized,
|
||||||
InitializedAsEvent,
|
InitializedAsEvent,
|
||||||
InitializedAsInterProcess
|
InitializedAsInterProcess,
|
||||||
}
|
}
|
||||||
|
|
||||||
public InterProcessEventType InterProcessEvent;
|
public InterProcessEventType InterProcessEvent;
|
||||||
public InitializationState State;
|
public InitializationState State;
|
||||||
|
|
||||||
public bool NotInitialized => State == InitializationState.NotInitialized;
|
public readonly bool NotInitialized => State == InitializationState.NotInitialized;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
{
|
{
|
||||||
False,
|
False,
|
||||||
True,
|
True,
|
||||||
Undefined
|
Undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using Ryujinx.Horizon.Sdk.Account;
|
using Ryujinx.Horizon.Sdk.Account;
|
||||||
using Ryujinx.Horizon.Sdk.Sf;
|
using Ryujinx.Horizon.Sdk.Sf;
|
||||||
using System;
|
using System;
|
||||||
|
using ApplicationId = Ryujinx.Horizon.Sdk.Ncm.ApplicationId;
|
||||||
|
|
||||||
namespace Ryujinx.Horizon.Sdk.Prepo
|
namespace Ryujinx.Horizon.Sdk.Prepo
|
||||||
{
|
{
|
||||||
|
@ -12,9 +13,9 @@ namespace Ryujinx.Horizon.Sdk.Prepo
|
||||||
Result RequestImmediateTransmission();
|
Result RequestImmediateTransmission();
|
||||||
Result GetTransmissionStatus(out int status);
|
Result GetTransmissionStatus(out int status);
|
||||||
Result GetSystemSessionId(out ulong systemSessionId);
|
Result GetSystemSessionId(out ulong systemSessionId);
|
||||||
Result SaveSystemReport(ReadOnlySpan<byte> gameRoomBuffer, Ncm.ApplicationId applicationId, ReadOnlySpan<byte> reportBuffer);
|
Result SaveSystemReport(ReadOnlySpan<byte> gameRoomBuffer, ApplicationId applicationId, ReadOnlySpan<byte> reportBuffer);
|
||||||
Result SaveSystemReportWithUser(Uid userId, ReadOnlySpan<byte> gameRoomBuffer, Ncm.ApplicationId applicationId, ReadOnlySpan<byte> reportBuffer);
|
Result SaveSystemReportWithUser(Uid userId, ReadOnlySpan<byte> gameRoomBuffer, ApplicationId applicationId, ReadOnlySpan<byte> reportBuffer);
|
||||||
Result IsUserAgreementCheckEnabled(out bool enabled);
|
Result IsUserAgreementCheckEnabled(out bool enabled);
|
||||||
Result SetUserAgreementCheckEnabled(bool enabled);
|
Result SetUserAgreementCheckEnabled(bool enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,15 +10,15 @@ namespace Ryujinx.Horizon.Sdk
|
||||||
public static Result SendRequest(out CmifResponse response, int sessionHandle, uint requestId, bool sendPid, scoped ReadOnlySpan<byte> data)
|
public static Result SendRequest(out CmifResponse response, int sessionHandle, uint requestId, bool sendPid, scoped ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
ulong tlsAddress = HorizonStatic.ThreadContext.TlsAddress;
|
ulong tlsAddress = HorizonStatic.ThreadContext.TlsAddress;
|
||||||
int tlsSize = Api.TlsMessageBufferSize;
|
int tlsSize = Api.TlsMessageBufferSize;
|
||||||
|
|
||||||
using (var tlsRegion = HorizonStatic.AddressSpace.GetWritableRegion(tlsAddress, tlsSize))
|
using (var tlsRegion = HorizonStatic.AddressSpace.GetWritableRegion(tlsAddress, tlsSize))
|
||||||
{
|
{
|
||||||
CmifRequest request = CmifMessage.CreateRequest(tlsRegion.Memory.Span, new CmifRequestFormat()
|
CmifRequest request = CmifMessage.CreateRequest(tlsRegion.Memory.Span, new CmifRequestFormat
|
||||||
{
|
{
|
||||||
DataSize = data.Length,
|
DataSize = data.Length,
|
||||||
RequestId = requestId,
|
RequestId = requestId,
|
||||||
SendPid = sendPid
|
SendPid = sendPid,
|
||||||
});
|
});
|
||||||
|
|
||||||
data.CopyTo(request.Data);
|
data.CopyTo(request.Data);
|
||||||
|
@ -36,4 +36,4 @@ namespace Ryujinx.Horizon.Sdk
|
||||||
return CmifMessage.ParseResponse(out response, HorizonStatic.AddressSpace.GetWritableRegion(tlsAddress, tlsSize).Memory.Span, false, 0);
|
return CmifMessage.ParseResponse(out response, HorizonStatic.AddressSpace.GetWritableRegion(tlsAddress, tlsSize).Memory.Span, false, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
struct CmifDomainInHeader
|
struct CmifDomainInHeader
|
||||||
{
|
{
|
||||||
public CmifDomainRequestType Type;
|
public CmifDomainRequestType Type;
|
||||||
public byte ObjectsCount;
|
public byte ObjectsCount;
|
||||||
public ushort DataSize;
|
public ushort DataSize;
|
||||||
public int ObjectId;
|
public int ObjectId;
|
||||||
public uint Padding;
|
public uint Padding;
|
||||||
public uint Token;
|
public uint Token;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{
|
{
|
||||||
struct CmifDomainOutHeader
|
struct CmifDomainOutHeader
|
||||||
{
|
{
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649 // Field is never assigned to
|
||||||
public uint ObjectsCount;
|
public uint ObjectsCount;
|
||||||
public uint Padding;
|
public uint Padding;
|
||||||
public uint Padding2;
|
public uint Padding2;
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
{
|
{
|
||||||
enum CmifDomainRequestType : byte
|
enum CmifDomainRequestType : byte
|
||||||
{
|
{
|
||||||
Invalid = 0,
|
Invalid = 0,
|
||||||
SendMessage = 1,
|
SendMessage = 1,
|
||||||
Close = 2
|
Close = 2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
{
|
{
|
||||||
static class CmifMessage
|
static class CmifMessage
|
||||||
{
|
{
|
||||||
public const uint CmifInHeaderMagic = 0x49434653; // SFCI
|
public const uint CmifInHeaderMagic = 0x49434653; // SFCI
|
||||||
public const uint CmifOutHeaderMagic = 0x4f434653; // SFCO
|
public const uint CmifOutHeaderMagic = 0x4f434653; // SFCO
|
||||||
|
|
||||||
public static CmifRequest CreateRequest(Span<byte> output, CmifRequestFormat format)
|
public static CmifRequest CreateRequest(Span<byte> output, CmifRequestFormat format)
|
||||||
|
@ -21,10 +21,10 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
}
|
}
|
||||||
|
|
||||||
totalSize += Unsafe.SizeOf<CmifInHeader>() + format.DataSize;
|
totalSize += Unsafe.SizeOf<CmifInHeader>() + format.DataSize;
|
||||||
totalSize = (totalSize + 1) & ~1;
|
totalSize = (totalSize + 1) & ~1;
|
||||||
|
|
||||||
int outPointerSizeTableOffset = totalSize;
|
int outPointerSizeTableOffset = totalSize;
|
||||||
int outPointerSizeTableSize = format.OutAutoBuffersCount + format.OutPointersCount;
|
int outPointerSizeTableSize = format.OutAutoBuffersCount + format.OutPointersCount;
|
||||||
|
|
||||||
totalSize += sizeof(ushort) * outPointerSizeTableSize;
|
totalSize += sizeof(ushort) * outPointerSizeTableSize;
|
||||||
|
|
||||||
|
@ -32,19 +32,19 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
|
|
||||||
CmifRequest request = new()
|
CmifRequest request = new()
|
||||||
{
|
{
|
||||||
Hipc = HipcMessage.WriteMessage(output, new HipcMetadata()
|
Hipc = HipcMessage.WriteMessage(output, new HipcMetadata
|
||||||
{
|
{
|
||||||
Type = format.Context != 0 ? (int)CommandType.RequestWithContext : (int)CommandType.Request,
|
Type = format.Context != 0 ? (int)CommandType.RequestWithContext : (int)CommandType.Request,
|
||||||
SendStaticsCount = format.InAutoBuffersCount + format.InPointersCount,
|
SendStaticsCount = format.InAutoBuffersCount + format.InPointersCount,
|
||||||
SendBuffersCount = format.InAutoBuffersCount + format.InBuffersCount,
|
SendBuffersCount = format.InAutoBuffersCount + format.InBuffersCount,
|
||||||
ReceiveBuffersCount = format.OutAutoBuffersCount + format.OutBuffersCount,
|
ReceiveBuffersCount = format.OutAutoBuffersCount + format.OutBuffersCount,
|
||||||
ExchangeBuffersCount = format.InOutBuffersCount,
|
ExchangeBuffersCount = format.InOutBuffersCount,
|
||||||
DataWordsCount = rawDataSizeInWords,
|
DataWordsCount = rawDataSizeInWords,
|
||||||
ReceiveStaticsCount = outPointerSizeTableSize + format.OutFixedPointersCount,
|
ReceiveStaticsCount = outPointerSizeTableSize + format.OutFixedPointersCount,
|
||||||
SendPid = format.SendPid,
|
SendPid = format.SendPid,
|
||||||
CopyHandlesCount = format.HandlesCount,
|
CopyHandlesCount = format.HandlesCount,
|
||||||
MoveHandlesCount = 0
|
MoveHandlesCount = 0,
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
Span<uint> data = request.Hipc.DataWords;
|
Span<uint> data = request.Hipc.DataWords;
|
||||||
|
@ -55,14 +55,14 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
|
|
||||||
int payloadSize = Unsafe.SizeOf<CmifInHeader>() + format.DataSize;
|
int payloadSize = Unsafe.SizeOf<CmifInHeader>() + format.DataSize;
|
||||||
|
|
||||||
domainHeader = new CmifDomainInHeader()
|
domainHeader = new CmifDomainInHeader
|
||||||
{
|
{
|
||||||
Type = CmifDomainRequestType.SendMessage,
|
Type = CmifDomainRequestType.SendMessage,
|
||||||
ObjectsCount = (byte)format.ObjectsCount,
|
ObjectsCount = (byte)format.ObjectsCount,
|
||||||
DataSize = (ushort)payloadSize,
|
DataSize = (ushort)payloadSize,
|
||||||
ObjectId = format.ObjectId,
|
ObjectId = format.ObjectId,
|
||||||
Padding = 0,
|
Padding = 0,
|
||||||
Token = format.Context
|
Token = format.Context,
|
||||||
};
|
};
|
||||||
|
|
||||||
data = data[(Unsafe.SizeOf<CmifDomainInHeader>() / sizeof(uint))..];
|
data = data[(Unsafe.SizeOf<CmifDomainInHeader>() / sizeof(uint))..];
|
||||||
|
@ -72,12 +72,12 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
|
|
||||||
ref CmifInHeader header = ref MemoryMarshal.Cast<uint, CmifInHeader>(data)[0];
|
ref CmifInHeader header = ref MemoryMarshal.Cast<uint, CmifInHeader>(data)[0];
|
||||||
|
|
||||||
header = new CmifInHeader()
|
header = new CmifInHeader
|
||||||
{
|
{
|
||||||
Magic = CmifInHeaderMagic,
|
Magic = CmifInHeaderMagic,
|
||||||
Version = format.Context != 0 ? 1u : 0u,
|
Version = format.Context != 0 ? 1u : 0u,
|
||||||
CommandId = format.RequestId,
|
CommandId = format.RequestId,
|
||||||
Token = format.ObjectId != 0 ? 0u : format.Context
|
Token = format.ObjectId != 0 ? 0u : format.Context,
|
||||||
};
|
};
|
||||||
|
|
||||||
request.Data = MemoryMarshal.Cast<uint, byte>(data)[Unsafe.SizeOf<CmifInHeader>()..];
|
request.Data = MemoryMarshal.Cast<uint, byte>(data)[Unsafe.SizeOf<CmifInHeader>()..];
|
||||||
|
@ -86,7 +86,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
|
|
||||||
Span<byte> outPointerTable = MemoryMarshal.Cast<uint, byte>(request.Hipc.DataWords)[(outPointerSizeTableOffset - paddingSizeBefore)..];
|
Span<byte> outPointerTable = MemoryMarshal.Cast<uint, byte>(request.Hipc.DataWords)[(outPointerSizeTableOffset - paddingSizeBefore)..];
|
||||||
|
|
||||||
request.OutPointerSizes = MemoryMarshal.Cast<byte, ushort>(outPointerTable);
|
request.OutPointerSizes = MemoryMarshal.Cast<byte, ushort>(outPointerTable);
|
||||||
request.ServerPointerSize = format.ServerPointerSize;
|
request.ServerPointerSize = format.ServerPointerSize;
|
||||||
|
|
||||||
return request;
|
return request;
|
||||||
|
@ -96,12 +96,12 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
{
|
{
|
||||||
HipcMessage responseMessage = new(input);
|
HipcMessage responseMessage = new(input);
|
||||||
|
|
||||||
Span<byte> data = MemoryMarshal.Cast<uint, byte>(responseMessage.Data.DataWords);
|
Span<byte> data = MemoryMarshal.Cast<uint, byte>(responseMessage.Data.DataWords);
|
||||||
Span<uint> objects = Span<uint>.Empty;
|
Span<uint> objects = Span<uint>.Empty;
|
||||||
|
|
||||||
if (isDomain)
|
if (isDomain)
|
||||||
{
|
{
|
||||||
data = data[Unsafe.SizeOf<CmifDomainOutHeader>()..];
|
data = data[Unsafe.SizeOf<CmifDomainOutHeader>()..];
|
||||||
objects = MemoryMarshal.Cast<byte, uint>(data[(Unsafe.SizeOf<CmifOutHeader>() + size)..]);
|
objects = MemoryMarshal.Cast<byte, uint>(data[(Unsafe.SizeOf<CmifOutHeader>() + size)..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,15 +121,15 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
return header.Result;
|
return header.Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
response = new CmifResponse()
|
response = new CmifResponse
|
||||||
{
|
{
|
||||||
Data = data[Unsafe.SizeOf<CmifOutHeader>()..],
|
Data = data[Unsafe.SizeOf<CmifOutHeader>()..],
|
||||||
Objects = objects,
|
Objects = objects,
|
||||||
CopyHandles = responseMessage.Data.CopyHandles,
|
CopyHandles = responseMessage.Data.CopyHandles,
|
||||||
MoveHandles = responseMessage.Data.MoveHandles
|
MoveHandles = responseMessage.Data.MoveHandles,
|
||||||
};
|
};
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,11 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
{
|
{
|
||||||
struct CmifOutHeader
|
struct CmifOutHeader
|
||||||
{
|
{
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649 // Field is never assigned to
|
||||||
public uint Magic;
|
public uint Magic;
|
||||||
public uint Version;
|
public uint Version;
|
||||||
public Result Result;
|
public Result Result;
|
||||||
public uint Token;
|
public uint Token;
|
||||||
#pragma warning restore CS0649
|
#pragma warning restore CS0649
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
ref struct CmifRequest
|
ref struct CmifRequest
|
||||||
{
|
{
|
||||||
public HipcMessageData Hipc;
|
public HipcMessageData Hipc;
|
||||||
public Span<byte> Data;
|
public Span<byte> Data;
|
||||||
public Span<ushort> OutPointerSizes;
|
public Span<ushort> OutPointerSizes;
|
||||||
public Span<uint> Objects;
|
public Span<uint> Objects;
|
||||||
public int ServerPointerSize;
|
public int ServerPointerSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,22 +2,22 @@
|
||||||
{
|
{
|
||||||
struct CmifRequestFormat
|
struct CmifRequestFormat
|
||||||
{
|
{
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649 // Field is never assigned to
|
||||||
public int ObjectId;
|
public int ObjectId;
|
||||||
public uint RequestId;
|
public uint RequestId;
|
||||||
public uint Context;
|
public uint Context;
|
||||||
public int DataSize;
|
public int DataSize;
|
||||||
public int ServerPointerSize;
|
public int ServerPointerSize;
|
||||||
public int InAutoBuffersCount;
|
public int InAutoBuffersCount;
|
||||||
public int OutAutoBuffersCount;
|
public int OutAutoBuffersCount;
|
||||||
public int InBuffersCount;
|
public int InBuffersCount;
|
||||||
public int OutBuffersCount;
|
public int OutBuffersCount;
|
||||||
public int InOutBuffersCount;
|
public int InOutBuffersCount;
|
||||||
public int InPointersCount;
|
public int InPointersCount;
|
||||||
public int OutPointersCount;
|
public int OutPointersCount;
|
||||||
public int OutFixedPointersCount;
|
public int OutFixedPointersCount;
|
||||||
public int ObjectsCount;
|
public int ObjectsCount;
|
||||||
public int HandlesCount;
|
public int HandlesCount;
|
||||||
public bool SendPid;
|
public bool SendPid;
|
||||||
#pragma warning restore CS0649
|
#pragma warning restore CS0649
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
{
|
{
|
||||||
public ReadOnlySpan<byte> Data;
|
public ReadOnlySpan<byte> Data;
|
||||||
public ReadOnlySpan<uint> Objects;
|
public ReadOnlySpan<uint> Objects;
|
||||||
public ReadOnlySpan<int> CopyHandles;
|
public ReadOnlySpan<int> CopyHandles;
|
||||||
public ReadOnlySpan<int> MoveHandles;
|
public ReadOnlySpan<int> MoveHandles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
{
|
{
|
||||||
enum CommandType
|
enum CommandType
|
||||||
{
|
{
|
||||||
Invalid = 0,
|
Invalid = 0,
|
||||||
LegacyRequest = 1,
|
LegacyRequest = 1,
|
||||||
Close = 2,
|
Close = 2,
|
||||||
LegacyControl = 3,
|
LegacyControl = 3,
|
||||||
Request = 4,
|
Request = 4,
|
||||||
Control = 5,
|
Control = 5,
|
||||||
RequestWithContext = 6,
|
RequestWithContext = 6,
|
||||||
ControlWithContext = 7
|
ControlWithContext = 7,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
return ProcessMessageImpl(ref context, ((DomainServiceObject)context.ServiceObject).GetServerDomain(), inRawData);
|
return ProcessMessageImpl(ref context, ((DomainServiceObject)context.ServiceObject).GetServerDomain(), inRawData);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result ProcessMessageImpl(ref ServiceDispatchContext context, ServerDomainBase domain, ReadOnlySpan<byte> inRawData)
|
private static Result ProcessMessageImpl(ref ServiceDispatchContext context, ServerDomainBase domain, ReadOnlySpan<byte> inRawData)
|
||||||
{
|
{
|
||||||
if (inRawData.Length < Unsafe.SizeOf<CmifDomainInHeader>())
|
if (inRawData.Length < Unsafe.SizeOf<CmifDomainInHeader>())
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,6 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
|
|
||||||
private int InObjectsCount => _inObjectIds.Length;
|
private int InObjectsCount => _inObjectIds.Length;
|
||||||
private int OutObjectsCount => _implMetadata.OutObjectsCount;
|
private int OutObjectsCount => _implMetadata.OutObjectsCount;
|
||||||
private int ImplOutHeadersSize => _implMetadata.OutHeadersSize;
|
|
||||||
private int ImplOutDataTotalSize => _implMetadata.OutDataSize + _implMetadata.OutHeadersSize;
|
private int ImplOutDataTotalSize => _implMetadata.OutDataSize + _implMetadata.OutHeadersSize;
|
||||||
|
|
||||||
public DomainServiceObjectProcessor(ServerDomainBase domain, int[] inObjectIds)
|
public DomainServiceObjectProcessor(ServerDomainBase domain, int[] inObjectIds)
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
|
|
||||||
public int this[int index]
|
public int this[int index]
|
||||||
{
|
{
|
||||||
get
|
readonly get
|
||||||
{
|
{
|
||||||
return index switch
|
return index switch
|
||||||
{
|
{
|
||||||
|
@ -29,22 +29,39 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
5 => _handle5,
|
5 => _handle5,
|
||||||
6 => _handle6,
|
6 => _handle6,
|
||||||
7 => _handle7,
|
7 => _handle7,
|
||||||
_ => throw new IndexOutOfRangeException()
|
_ => throw new IndexOutOfRangeException(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
case 0: _handle0 = value; break;
|
case 0:
|
||||||
case 1: _handle1 = value; break;
|
_handle0 = value;
|
||||||
case 2: _handle2 = value; break;
|
break;
|
||||||
case 3: _handle3 = value; break;
|
case 1:
|
||||||
case 4: _handle4 = value; break;
|
_handle1 = value;
|
||||||
case 5: _handle5 = value; break;
|
break;
|
||||||
case 6: _handle6 = value; break;
|
case 2:
|
||||||
case 7: _handle7 = value; break;
|
_handle2 = value;
|
||||||
default: throw new IndexOutOfRangeException();
|
break;
|
||||||
|
case 3:
|
||||||
|
_handle3 = value;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
_handle4 = value;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
_handle5 = value;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
_handle6 = value;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
_handle7 = value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IndexOutOfRangeException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
{
|
{
|
||||||
struct PointerAndSize
|
readonly struct PointerAndSize
|
||||||
{
|
{
|
||||||
public static PointerAndSize Empty => new(0UL, 0UL);
|
public static PointerAndSize Empty => new(0UL, 0UL);
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
public PointerAndSize(ulong address, ulong size)
|
public PointerAndSize(ulong address, ulong size)
|
||||||
{
|
{
|
||||||
Address = address;
|
Address = address;
|
||||||
Size = size;
|
Size = size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ using System;
|
||||||
|
|
||||||
namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
{
|
{
|
||||||
struct ScopedInlineContextChange : IDisposable
|
readonly struct ScopedInlineContextChange : IDisposable
|
||||||
{
|
{
|
||||||
private readonly int _previousContext;
|
private readonly int _previousContext;
|
||||||
|
|
||||||
|
|
|
@ -211,7 +211,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
private readonly EntryManager _entryManager;
|
private readonly EntryManager _entryManager;
|
||||||
private readonly object _entryOwnerLock;
|
private readonly object _entryOwnerLock;
|
||||||
private readonly HashSet<Domain> _domains;
|
private readonly HashSet<Domain> _domains;
|
||||||
private int _maxDomains;
|
private readonly int _maxDomains;
|
||||||
|
|
||||||
public ServerDomainManager(int entryCount, int maxDomains)
|
public ServerDomainManager(int entryCount, int maxDomains)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,30 +1,30 @@
|
||||||
namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
{
|
{
|
||||||
struct ServerMessageRuntimeMetadata
|
readonly struct ServerMessageRuntimeMetadata
|
||||||
{
|
{
|
||||||
public ushort InDataSize { get; }
|
public ushort InDataSize { get; }
|
||||||
public ushort OutDataSize { get; }
|
public ushort OutDataSize { get; }
|
||||||
public byte InHeadersSize { get; }
|
public byte InHeadersSize { get; }
|
||||||
public byte OutHeadersSize { get; }
|
public byte OutHeadersSize { get; }
|
||||||
public byte InObjectsCount { get; }
|
public byte InObjectsCount { get; }
|
||||||
public byte OutObjectsCount { get; }
|
public byte OutObjectsCount { get; }
|
||||||
|
|
||||||
public int UnfixedOutPointerSizeOffset => InDataSize + InHeadersSize + 0x10;
|
public int UnfixedOutPointerSizeOffset => InDataSize + InHeadersSize + 0x10;
|
||||||
|
|
||||||
public ServerMessageRuntimeMetadata(
|
public ServerMessageRuntimeMetadata(
|
||||||
ushort inDataSize,
|
ushort inDataSize,
|
||||||
ushort outDataSize,
|
ushort outDataSize,
|
||||||
byte inHeadersSize,
|
byte inHeadersSize,
|
||||||
byte outHeadersSize,
|
byte outHeadersSize,
|
||||||
byte inObjectsCount,
|
byte inObjectsCount,
|
||||||
byte outObjectsCount)
|
byte outObjectsCount)
|
||||||
{
|
{
|
||||||
InDataSize = inDataSize;
|
InDataSize = inDataSize;
|
||||||
OutDataSize = outDataSize;
|
OutDataSize = outDataSize;
|
||||||
InHeadersSize = inHeadersSize;
|
InHeadersSize = inHeadersSize;
|
||||||
OutHeadersSize = outHeadersSize;
|
OutHeadersSize = outHeadersSize;
|
||||||
InObjectsCount = inObjectsCount;
|
InObjectsCount = inObjectsCount;
|
||||||
OutObjectsCount = outObjectsCount;
|
OutObjectsCount = outObjectsCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,14 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
{
|
{
|
||||||
ref struct ServiceDispatchContext
|
ref struct ServiceDispatchContext
|
||||||
{
|
{
|
||||||
public IServiceObject ServiceObject;
|
public IServiceObject ServiceObject;
|
||||||
public ServerSessionManager Manager;
|
public ServerSessionManager Manager;
|
||||||
public ServerSession Session;
|
public ServerSession Session;
|
||||||
public ServerMessageProcessor Processor;
|
public ServerMessageProcessor Processor;
|
||||||
public HandlesToClose HandlesToClose;
|
public HandlesToClose HandlesToClose;
|
||||||
public PointerAndSize PointerBuffer;
|
public PointerAndSize PointerBuffer;
|
||||||
public ReadOnlySpan<byte> InMessageBuffer;
|
public ReadOnlySpan<byte> InMessageBuffer;
|
||||||
public Span<byte> OutMessageBuffer;
|
public Span<byte> OutMessageBuffer;
|
||||||
public HipcMessage Request;
|
public HipcMessage Request;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
{
|
{
|
||||||
struct ServiceDispatchMeta
|
readonly struct ServiceDispatchMeta
|
||||||
{
|
{
|
||||||
public ServiceDispatchTableBase DispatchTable { get; }
|
public ServiceDispatchTableBase DispatchTable { get; }
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
public ServiceDispatchTable(string objectName, IReadOnlyDictionary<int, CommandHandler> entries)
|
public ServiceDispatchTable(string objectName, IReadOnlyDictionary<int, CommandHandler> entries)
|
||||||
{
|
{
|
||||||
_objectName = objectName;
|
_objectName = objectName;
|
||||||
_entries = entries;
|
_entries = entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result ProcessMessage(ref ServiceDispatchContext context, ReadOnlySpan<byte> inRawData)
|
public override Result ProcessMessage(ref ServiceDispatchContext context, ReadOnlySpan<byte> inRawData)
|
||||||
|
@ -30,4 +30,4 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
return new ServiceDispatchTable(instance.GetType().Name, instance.GetCommandHandlers());
|
return new ServiceDispatchTable(instance.GetType().Name, instance.GetCommandHandlers());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
|
|
||||||
public abstract Result ProcessMessage(ref ServiceDispatchContext context, ReadOnlySpan<byte> inRawData);
|
public abstract Result ProcessMessage(ref ServiceDispatchContext context, ReadOnlySpan<byte> inRawData);
|
||||||
|
|
||||||
protected Result ProcessMessageImpl(ref ServiceDispatchContext context, ReadOnlySpan<byte> inRawData, IReadOnlyDictionary<int, CommandHandler> entries, string objectName)
|
protected static Result ProcessMessageImpl(ref ServiceDispatchContext context, ReadOnlySpan<byte> inRawData, IReadOnlyDictionary<int, CommandHandler> entries, string objectName)
|
||||||
{
|
{
|
||||||
if (inRawData.Length < Unsafe.SizeOf<CmifInHeader>())
|
if (inRawData.Length < Unsafe.SizeOf<CmifInHeader>())
|
||||||
{
|
{
|
||||||
|
@ -44,7 +44,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
// If ignore missing services is enabled, just pretend that everything is fine.
|
// If ignore missing services is enabled, just pretend that everything is fine.
|
||||||
PrepareForStubReply(ref context, out Span<byte> outRawData);
|
PrepareForStubReply(ref context, out Span<byte> outRawData);
|
||||||
CommandHandler.GetCmifOutHeaderPointer(ref outHeader, ref outRawData);
|
CommandHandler.GetCmifOutHeaderPointer(ref outHeader, ref outRawData);
|
||||||
outHeader[0] = new CmifOutHeader() { Magic = CmifMessage.CmifOutHeaderMagic, Result = Result.Success };
|
outHeader[0] = new CmifOutHeader { Magic = CmifMessage.CmifOutHeaderMagic, Result = Result.Success };
|
||||||
|
|
||||||
Logger.Warning?.Print(LogClass.Service, $"Missing service {objectName} (command ID: {commandId}) ignored");
|
Logger.Warning?.Print(LogClass.Service, $"Missing service {objectName} (command ID: {commandId}) ignored");
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
return commandResult;
|
return commandResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
outHeader[0] = new CmifOutHeader() { Magic = CmifMessage.CmifOutHeaderMagic, Result = commandResult };
|
outHeader[0] = new CmifOutHeader { Magic = CmifMessage.CmifOutHeaderMagic, Result = commandResult };
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
@ -91,4 +91,4 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
|
||||||
outRawData = MemoryMarshal.Cast<uint, byte>(response.DataWords);
|
outRawData = MemoryMarshal.Cast<uint, byte>(response.DataWords);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,42 +15,42 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
OutCopyHandle,
|
OutCopyHandle,
|
||||||
OutMoveHandle,
|
OutMoveHandle,
|
||||||
OutObject,
|
OutObject,
|
||||||
ProcessId
|
ProcessId,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CommandArg
|
readonly struct CommandArg
|
||||||
{
|
{
|
||||||
public CommandArgType Type { get; }
|
public CommandArgType Type { get; }
|
||||||
public HipcBufferFlags BufferFlags { get; }
|
public HipcBufferFlags BufferFlags { get; }
|
||||||
public ushort BufferFixedSize { get; }
|
public ushort BufferFixedSize { get; }
|
||||||
public int ArgSize { get; }
|
public int ArgSize { get; }
|
||||||
public int ArgAlignment { get; }
|
public int ArgAlignment { get; }
|
||||||
|
|
||||||
public CommandArg(CommandArgType type)
|
public CommandArg(CommandArgType type)
|
||||||
{
|
{
|
||||||
Type = type;
|
Type = type;
|
||||||
BufferFlags = default;
|
BufferFlags = default;
|
||||||
BufferFixedSize = 0;
|
BufferFixedSize = 0;
|
||||||
ArgSize = 0;
|
ArgSize = 0;
|
||||||
ArgAlignment = 0;
|
ArgAlignment = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandArg(CommandArgType type, int argSize, int argAlignment)
|
public CommandArg(CommandArgType type, int argSize, int argAlignment)
|
||||||
{
|
{
|
||||||
Type = type;
|
Type = type;
|
||||||
BufferFlags = default;
|
BufferFlags = default;
|
||||||
BufferFixedSize = 0;
|
BufferFixedSize = 0;
|
||||||
ArgSize = argSize;
|
ArgSize = argSize;
|
||||||
ArgAlignment = argAlignment;
|
ArgAlignment = argAlignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandArg(HipcBufferFlags flags, ushort fixedSize = 0)
|
public CommandArg(HipcBufferFlags flags, ushort fixedSize = 0)
|
||||||
{
|
{
|
||||||
Type = CommandArgType.Buffer;
|
Type = CommandArgType.Buffer;
|
||||||
BufferFlags = flags;
|
BufferFlags = flags;
|
||||||
BufferFixedSize = fixedSize;
|
BufferFixedSize = fixedSize;
|
||||||
ArgSize = 0;
|
ArgSize = 0;
|
||||||
ArgAlignment = 0;
|
ArgAlignment = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
[AttributeUsage(AttributeTargets.Parameter)]
|
[AttributeUsage(AttributeTargets.Parameter)]
|
||||||
class BufferAttribute : Attribute
|
class BufferAttribute : Attribute
|
||||||
{
|
{
|
||||||
public HipcBufferFlags Flags { get; }
|
public HipcBufferFlags Flags { get; }
|
||||||
public ushort FixedSize { get; }
|
public ushort FixedSize { get; }
|
||||||
|
|
||||||
public BufferAttribute(HipcBufferFlags flags)
|
public BufferAttribute(HipcBufferFlags flags)
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,7 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
|
|
||||||
public BufferAttribute(HipcBufferFlags flags, ushort fixedSize)
|
public BufferAttribute(HipcBufferFlags flags, ushort fixedSize)
|
||||||
{
|
{
|
||||||
Flags = flags | HipcBufferFlags.FixedSize;
|
Flags = flags | HipcBufferFlags.FixedSize;
|
||||||
FixedSize = fixedSize;
|
FixedSize = fixedSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,4 +35,4 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
class MoveHandleAttribute : Attribute
|
class MoveHandleAttribute : Attribute
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,20 +9,20 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
class CommandHandler
|
class CommandHandler
|
||||||
{
|
{
|
||||||
public delegate Result MethodInvoke(
|
public delegate Result MethodInvoke(
|
||||||
ref ServiceDispatchContext context,
|
ref ServiceDispatchContext context,
|
||||||
HipcCommandProcessor processor,
|
HipcCommandProcessor processor,
|
||||||
ServerMessageRuntimeMetadata runtimeMetadata,
|
ServerMessageRuntimeMetadata runtimeMetadata,
|
||||||
ReadOnlySpan<byte> inRawData,
|
ReadOnlySpan<byte> inRawData,
|
||||||
ref Span<CmifOutHeader> outHeader);
|
ref Span<CmifOutHeader> outHeader);
|
||||||
|
|
||||||
private readonly MethodInvoke _invoke;
|
private readonly MethodInvoke _invoke;
|
||||||
private readonly HipcCommandProcessor _processor;
|
private readonly HipcCommandProcessor _processor;
|
||||||
|
|
||||||
public string MethodName => _invoke.Method.Name;
|
public string MethodName => _invoke.Method.Name;
|
||||||
|
|
||||||
public CommandHandler(MethodInvoke invoke, params CommandArg[] args)
|
public CommandHandler(MethodInvoke invoke, params CommandArg[] args)
|
||||||
{
|
{
|
||||||
_invoke = invoke;
|
_invoke = invoke;
|
||||||
_processor = new HipcCommandProcessor(args);
|
_processor = new HipcCommandProcessor(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,16 +37,16 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
context.Processor.SetImplementationProcessor(_processor);
|
context.Processor.SetImplementationProcessor(_processor);
|
||||||
}
|
}
|
||||||
|
|
||||||
var runtimeMetadata = context.Processor.GetRuntimeMetadata();
|
var runtimeMetadata = context.Processor.GetRuntimeMetadata();
|
||||||
Result result = context.Processor.PrepareForProcess(ref context, runtimeMetadata);
|
Result result = context.Processor.PrepareForProcess(ref context, runtimeMetadata);
|
||||||
|
|
||||||
return result.IsFailure ? result : _invoke(ref context, _processor, runtimeMetadata, inRawData, ref outHeader);
|
return result.IsFailure ? result : _invoke(ref context, _processor, runtimeMetadata, inRawData, ref outHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void GetCmifOutHeaderPointer(ref Span<CmifOutHeader> outHeader, ref Span<byte> outRawData)
|
public static void GetCmifOutHeaderPointer(ref Span<CmifOutHeader> outHeader, ref Span<byte> outRawData)
|
||||||
{
|
{
|
||||||
outHeader = MemoryMarshal.Cast<byte, CmifOutHeader>(outRawData)[..1];
|
outHeader = MemoryMarshal.Cast<byte, CmifOutHeader>(outRawData)[..1];
|
||||||
outRawData = outRawData[Unsafe.SizeOf<CmifOutHeader>()..];
|
outRawData = outRawData[Unsafe.SizeOf<CmifOutHeader>()..];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,4 +66,4 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
response.MoveHandles[index] = value;
|
response.MoveHandles[index] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,10 +41,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
{
|
{
|
||||||
return HorizonStatic.Syscall.ReplyAndReceive(out _, handles, 0, -1L);
|
return HorizonStatic.Syscall.ReplyAndReceive(out _, handles, 0, -1L);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
throw new NotImplementedException();
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result Reply(int sessionHandle, ReadOnlySpan<byte> messageBuffer)
|
public static Result Reply(int sessionHandle, ReadOnlySpan<byte> messageBuffer)
|
||||||
|
@ -64,10 +62,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
{
|
{
|
||||||
return HorizonStatic.Syscall.ReplyAndReceive(out _, ReadOnlySpan<int>.Empty, sessionHandle, 0);
|
return HorizonStatic.Syscall.ReplyAndReceive(out _, ReadOnlySpan<int>.Empty, sessionHandle, 0);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
throw new NotImplementedException();
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result CreateSession(out int serverHandle, out int clientHandle)
|
public static Result CreateSession(out int serverHandle, out int clientHandle)
|
||||||
|
@ -82,4 +78,4 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,55 +10,55 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
|
|
||||||
public CommandType Type
|
public CommandType Type
|
||||||
{
|
{
|
||||||
get => (CommandType)_word0.Extract(0, 16);
|
readonly get => (CommandType)_word0.Extract(0, 16);
|
||||||
set => _word0 = _word0.Insert(0, 16, (uint)value);
|
set => _word0 = _word0.Insert(0, 16, (uint)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int SendStaticsCount
|
public int SendStaticsCount
|
||||||
{
|
{
|
||||||
get => (int)_word0.Extract(16, 4);
|
readonly get => (int)_word0.Extract(16, 4);
|
||||||
set => _word0 = _word0.Insert(16, 4, (uint)value);
|
set => _word0 = _word0.Insert(16, 4, (uint)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int SendBuffersCount
|
public int SendBuffersCount
|
||||||
{
|
{
|
||||||
get => (int)_word0.Extract(20, 4);
|
readonly get => (int)_word0.Extract(20, 4);
|
||||||
set => _word0 = _word0.Insert(20, 4, (uint)value);
|
set => _word0 = _word0.Insert(20, 4, (uint)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ReceiveBuffersCount
|
public int ReceiveBuffersCount
|
||||||
{
|
{
|
||||||
get => (int)_word0.Extract(24, 4);
|
readonly get => (int)_word0.Extract(24, 4);
|
||||||
set => _word0 = _word0.Insert(24, 4, (uint)value);
|
set => _word0 = _word0.Insert(24, 4, (uint)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ExchangeBuffersCount
|
public int ExchangeBuffersCount
|
||||||
{
|
{
|
||||||
get => (int)_word0.Extract(28, 4);
|
readonly get => (int)_word0.Extract(28, 4);
|
||||||
set => _word0 = _word0.Insert(28, 4, (uint)value);
|
set => _word0 = _word0.Insert(28, 4, (uint)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int DataWordsCount
|
public int DataWordsCount
|
||||||
{
|
{
|
||||||
get => (int)_word1.Extract(0, 10);
|
readonly get => (int)_word1.Extract(0, 10);
|
||||||
set => _word1 = _word1.Insert(0, 10, (uint)value);
|
set => _word1 = _word1.Insert(0, 10, (uint)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ReceiveStaticMode
|
public int ReceiveStaticMode
|
||||||
{
|
{
|
||||||
get => (int)_word1.Extract(10, 4);
|
readonly get => (int)_word1.Extract(10, 4);
|
||||||
set => _word1 = _word1.Insert(10, 4, (uint)value);
|
set => _word1 = _word1.Insert(10, 4, (uint)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ReceiveListOffset
|
public int ReceiveListOffset
|
||||||
{
|
{
|
||||||
get => (int)_word1.Extract(20, 11);
|
readonly get => (int)_word1.Extract(20, 11);
|
||||||
set => _word1 = _word1.Insert(20, 11, (uint)value);
|
set => _word1 = _word1.Insert(20, 11, (uint)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasSpecialHeader
|
public bool HasSpecialHeader
|
||||||
{
|
{
|
||||||
get => _word1.Extract(31);
|
readonly get => _word1.Extract(31);
|
||||||
set => _word1 = _word1.Insert(31, value);
|
set => _word1 = _word1.Insert(31, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
{
|
{
|
||||||
struct HipcBufferDescriptor
|
readonly struct HipcBufferDescriptor
|
||||||
{
|
{
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649 // Field is never assigned to
|
||||||
private uint _sizeLow;
|
private readonly uint _sizeLow;
|
||||||
private uint _addressLow;
|
private readonly uint _addressLow;
|
||||||
private uint _word2;
|
private readonly uint _word2;
|
||||||
#pragma warning restore CS0649
|
#pragma warning restore CS0649
|
||||||
|
|
||||||
public ulong Address => _addressLow | (((ulong)_word2 << 4) & 0xf00000000UL) | (((ulong)_word2 << 34) & 0x7000000000UL);
|
public ulong Address => _addressLow | (((ulong)_word2 << 4) & 0xf00000000UL) | (((ulong)_word2 << 34) & 0x7000000000UL);
|
||||||
|
|
|
@ -5,13 +5,13 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
[Flags]
|
[Flags]
|
||||||
enum HipcBufferFlags : byte
|
enum HipcBufferFlags : byte
|
||||||
{
|
{
|
||||||
In = 1 << 0,
|
In = 1 << 0,
|
||||||
Out = 1 << 1,
|
Out = 1 << 1,
|
||||||
MapAlias = 1 << 2,
|
MapAlias = 1 << 2,
|
||||||
Pointer = 1 << 3,
|
Pointer = 1 << 3,
|
||||||
FixedSize = 1 << 4,
|
FixedSize = 1 << 4,
|
||||||
AutoSelect = 1 << 5,
|
AutoSelect = 1 << 5,
|
||||||
MapTransferAllowsNonSecure = 1 << 6,
|
MapTransferAllowsNonSecure = 1 << 6,
|
||||||
MapTransferAllowsNonDevice = 1 << 7
|
MapTransferAllowsNonDevice = 1 << 7,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
{
|
{
|
||||||
enum HipcBufferMode
|
enum HipcBufferMode
|
||||||
{
|
{
|
||||||
Normal = 0,
|
Normal = 0,
|
||||||
NonSecure = 1,
|
NonSecure = 1,
|
||||||
Invalid = 2,
|
Invalid = 2,
|
||||||
NonDevice = 3
|
NonDevice = 3,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,4 +112,4 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
{
|
{
|
||||||
public const int AutoReceiveStatic = byte.MaxValue;
|
public const int AutoReceiveStatic = byte.MaxValue;
|
||||||
|
|
||||||
public HipcMetadata Meta;
|
public HipcMetadata Meta;
|
||||||
public HipcMessageData Data;
|
public HipcMessageData Data;
|
||||||
public ulong Pid;
|
public ulong Pid;
|
||||||
|
|
||||||
public HipcMessage(Span<byte> data)
|
public HipcMessage(Span<byte> data)
|
||||||
{
|
{
|
||||||
|
@ -22,8 +22,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
|
|
||||||
data = data[Unsafe.SizeOf<Header>()..];
|
data = data[Unsafe.SizeOf<Header>()..];
|
||||||
|
|
||||||
int receiveStaticsCount = 0;
|
int receiveStaticsCount = 0;
|
||||||
ulong pid = 0;
|
ulong pid = 0;
|
||||||
|
|
||||||
if (header.ReceiveStaticMode != 0)
|
if (header.ReceiveStaticMode != 0)
|
||||||
{
|
{
|
||||||
|
@ -42,75 +42,75 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
if (header.HasSpecialHeader)
|
if (header.HasSpecialHeader)
|
||||||
{
|
{
|
||||||
specialHeader = MemoryMarshal.Cast<byte, SpecialHeader>(data)[0];
|
specialHeader = MemoryMarshal.Cast<byte, SpecialHeader>(data)[0];
|
||||||
data = data[Unsafe.SizeOf<SpecialHeader>()..];
|
data = data[Unsafe.SizeOf<SpecialHeader>()..];
|
||||||
|
|
||||||
if (specialHeader.SendPid)
|
if (specialHeader.SendPid)
|
||||||
{
|
{
|
||||||
pid = MemoryMarshal.Cast<byte, ulong>(data)[0];
|
pid = MemoryMarshal.Cast<byte, ulong>(data)[0];
|
||||||
data = data[sizeof(ulong)..];
|
data = data[sizeof(ulong)..];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Meta = new HipcMetadata()
|
Meta = new HipcMetadata
|
||||||
{
|
{
|
||||||
Type = (int)header.Type,
|
Type = (int)header.Type,
|
||||||
SendStaticsCount = header.SendStaticsCount,
|
SendStaticsCount = header.SendStaticsCount,
|
||||||
SendBuffersCount = header.SendBuffersCount,
|
SendBuffersCount = header.SendBuffersCount,
|
||||||
ReceiveBuffersCount = header.ReceiveBuffersCount,
|
ReceiveBuffersCount = header.ReceiveBuffersCount,
|
||||||
ExchangeBuffersCount = header.ExchangeBuffersCount,
|
ExchangeBuffersCount = header.ExchangeBuffersCount,
|
||||||
DataWordsCount = header.DataWordsCount,
|
DataWordsCount = header.DataWordsCount,
|
||||||
ReceiveStaticsCount = receiveStaticsCount,
|
ReceiveStaticsCount = receiveStaticsCount,
|
||||||
SendPid = specialHeader.SendPid,
|
SendPid = specialHeader.SendPid,
|
||||||
CopyHandlesCount = specialHeader.CopyHandlesCount,
|
CopyHandlesCount = specialHeader.CopyHandlesCount,
|
||||||
MoveHandlesCount = specialHeader.MoveHandlesCount
|
MoveHandlesCount = specialHeader.MoveHandlesCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
Data = CreateMessageData(Meta, data, initialLength);
|
Data = CreateMessageData(Meta, data, initialLength);
|
||||||
Pid = pid;
|
Pid = pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HipcMessageData WriteResponse(
|
public static HipcMessageData WriteResponse(
|
||||||
Span<byte> destination,
|
Span<byte> destination,
|
||||||
int sendStaticCount,
|
int sendStaticCount,
|
||||||
int dataWordsCount,
|
int dataWordsCount,
|
||||||
int copyHandlesCount,
|
int copyHandlesCount,
|
||||||
int moveHandlesCount)
|
int moveHandlesCount)
|
||||||
{
|
{
|
||||||
return WriteMessage(destination, new HipcMetadata()
|
return WriteMessage(destination, new HipcMetadata
|
||||||
{
|
{
|
||||||
SendStaticsCount = sendStaticCount,
|
SendStaticsCount = sendStaticCount,
|
||||||
DataWordsCount = dataWordsCount,
|
DataWordsCount = dataWordsCount,
|
||||||
CopyHandlesCount = copyHandlesCount,
|
CopyHandlesCount = copyHandlesCount,
|
||||||
MoveHandlesCount = moveHandlesCount
|
MoveHandlesCount = moveHandlesCount,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HipcMessageData WriteMessage(Span<byte> destination, HipcMetadata meta)
|
public static HipcMessageData WriteMessage(Span<byte> destination, HipcMetadata meta)
|
||||||
{
|
{
|
||||||
int initialLength = destination.Length;
|
int initialLength = destination.Length;
|
||||||
bool hasSpecialHeader = meta.SendPid || meta.CopyHandlesCount != 0 || meta.MoveHandlesCount != 0;
|
bool hasSpecialHeader = meta.SendPid || meta.CopyHandlesCount != 0 || meta.MoveHandlesCount != 0;
|
||||||
|
|
||||||
MemoryMarshal.Cast<byte, Header>(destination)[0] = new Header()
|
MemoryMarshal.Cast<byte, Header>(destination)[0] = new Header
|
||||||
{
|
{
|
||||||
Type = (CommandType)meta.Type,
|
Type = (CommandType)meta.Type,
|
||||||
SendStaticsCount = meta.SendStaticsCount,
|
SendStaticsCount = meta.SendStaticsCount,
|
||||||
SendBuffersCount = meta.SendBuffersCount,
|
SendBuffersCount = meta.SendBuffersCount,
|
||||||
ReceiveBuffersCount = meta.ReceiveBuffersCount,
|
ReceiveBuffersCount = meta.ReceiveBuffersCount,
|
||||||
ExchangeBuffersCount = meta.ExchangeBuffersCount,
|
ExchangeBuffersCount = meta.ExchangeBuffersCount,
|
||||||
DataWordsCount = meta.DataWordsCount,
|
DataWordsCount = meta.DataWordsCount,
|
||||||
ReceiveStaticMode = meta.ReceiveStaticsCount != 0 ? (meta.ReceiveStaticsCount != AutoReceiveStatic ? meta.ReceiveStaticsCount + 2 : 2) : 0,
|
ReceiveStaticMode = meta.ReceiveStaticsCount != 0 ? (meta.ReceiveStaticsCount != AutoReceiveStatic ? meta.ReceiveStaticsCount + 2 : 2) : 0,
|
||||||
HasSpecialHeader = hasSpecialHeader
|
HasSpecialHeader = hasSpecialHeader,
|
||||||
};
|
};
|
||||||
|
|
||||||
destination = destination[Unsafe.SizeOf<Header>()..];
|
destination = destination[Unsafe.SizeOf<Header>()..];
|
||||||
|
|
||||||
if (hasSpecialHeader)
|
if (hasSpecialHeader)
|
||||||
{
|
{
|
||||||
MemoryMarshal.Cast<byte, SpecialHeader>(destination)[0] = new SpecialHeader()
|
MemoryMarshal.Cast<byte, SpecialHeader>(destination)[0] = new SpecialHeader
|
||||||
{
|
{
|
||||||
SendPid = meta.SendPid,
|
SendPid = meta.SendPid,
|
||||||
CopyHandlesCount = meta.CopyHandlesCount,
|
CopyHandlesCount = meta.CopyHandlesCount,
|
||||||
MoveHandlesCount = meta.MoveHandlesCount
|
MoveHandlesCount = meta.MoveHandlesCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
destination = destination[Unsafe.SizeOf<SpecialHeader>()..];
|
destination = destination[Unsafe.SizeOf<SpecialHeader>()..];
|
||||||
|
@ -184,9 +184,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
|
|
||||||
if (meta.DataWordsCount != 0)
|
if (meta.DataWordsCount != 0)
|
||||||
{
|
{
|
||||||
int dataOffset = initialLength - data.Length;
|
int dataOffset = initialLength - data.Length;
|
||||||
int dataOffsetAligned = BitUtils.AlignUp(dataOffset, 0x10);
|
int dataOffsetAligned = BitUtils.AlignUp(dataOffset, 0x10);
|
||||||
int padding = (dataOffsetAligned - dataOffset) / sizeof(uint);
|
int padding = (dataOffsetAligned - dataOffset) / sizeof(uint);
|
||||||
|
|
||||||
dataWords = MemoryMarshal.Cast<byte, uint>(data)[padding..meta.DataWordsCount];
|
dataWords = MemoryMarshal.Cast<byte, uint>(data)[padding..meta.DataWordsCount];
|
||||||
|
|
||||||
|
@ -202,16 +202,16 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
receiveList = MemoryMarshal.Cast<byte, HipcReceiveListEntry>(data)[..receiveListSize];
|
receiveList = MemoryMarshal.Cast<byte, HipcReceiveListEntry>(data)[..receiveListSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HipcMessageData()
|
return new HipcMessageData
|
||||||
{
|
{
|
||||||
SendStatics = sendStatics,
|
SendStatics = sendStatics,
|
||||||
SendBuffers = sendBuffers,
|
SendBuffers = sendBuffers,
|
||||||
ReceiveBuffers = receiveBuffers,
|
ReceiveBuffers = receiveBuffers,
|
||||||
ExchangeBuffers = exchangeBuffers,
|
ExchangeBuffers = exchangeBuffers,
|
||||||
DataWords = dataWords,
|
DataWords = dataWords,
|
||||||
ReceiveList = receiveList,
|
ReceiveList = receiveList,
|
||||||
CopyHandles = copyHandles,
|
CopyHandles = copyHandles,
|
||||||
MoveHandles = moveHandles
|
MoveHandles = moveHandles,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
public Span<HipcBufferDescriptor> SendBuffers;
|
public Span<HipcBufferDescriptor> SendBuffers;
|
||||||
public Span<HipcBufferDescriptor> ReceiveBuffers;
|
public Span<HipcBufferDescriptor> ReceiveBuffers;
|
||||||
public Span<HipcBufferDescriptor> ExchangeBuffers;
|
public Span<HipcBufferDescriptor> ExchangeBuffers;
|
||||||
public Span<uint> DataWords;
|
public Span<uint> DataWords;
|
||||||
public Span<HipcReceiveListEntry> ReceiveList;
|
public Span<HipcReceiveListEntry> ReceiveList;
|
||||||
public Span<int> CopyHandles;
|
public Span<int> CopyHandles;
|
||||||
public Span<int> MoveHandles;
|
public Span<int> MoveHandles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,15 @@
|
||||||
{
|
{
|
||||||
struct HipcMetadata
|
struct HipcMetadata
|
||||||
{
|
{
|
||||||
public int Type;
|
public int Type;
|
||||||
public int SendStaticsCount;
|
public int SendStaticsCount;
|
||||||
public int SendBuffersCount;
|
public int SendBuffersCount;
|
||||||
public int ReceiveBuffersCount;
|
public int ReceiveBuffersCount;
|
||||||
public int ExchangeBuffersCount;
|
public int ExchangeBuffersCount;
|
||||||
public int DataWordsCount;
|
public int DataWordsCount;
|
||||||
public int ReceiveStaticsCount;
|
public int ReceiveStaticsCount;
|
||||||
public bool SendPid;
|
public bool SendPid;
|
||||||
public int CopyHandlesCount;
|
public int CopyHandlesCount;
|
||||||
public int MoveHandlesCount;
|
public int MoveHandlesCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
{
|
{
|
||||||
struct HipcReceiveListEntry
|
readonly struct HipcReceiveListEntry
|
||||||
{
|
{
|
||||||
private uint _addressLow;
|
#pragma warning disable IDE0052 // Remove unread private member
|
||||||
private uint _word1;
|
private readonly uint _addressLow;
|
||||||
|
private readonly uint _word1;
|
||||||
|
#pragma warning restore IDE0052
|
||||||
|
|
||||||
public HipcReceiveListEntry(ulong address, ulong size)
|
public HipcReceiveListEntry(ulong address, ulong size)
|
||||||
{
|
{
|
||||||
_addressLow = (uint)address;
|
_addressLow = (uint)address;
|
||||||
_word1 = (ushort)(address >> 32) | (uint)(size << 16);
|
_word1 = (ushort)(address >> 32) | (uint)(size << 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
{
|
{
|
||||||
public const int ModuleId = 11;
|
public const int ModuleId = 11;
|
||||||
|
|
||||||
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
public static Result OutOfSessionMemory => new(ModuleId, 102);
|
public static Result OutOfSessionMemory => new(ModuleId, 102);
|
||||||
public static Result OutOfSessions => new(ModuleId, 131);
|
public static Result OutOfSessions => new(ModuleId, 131);
|
||||||
public static Result PointerBufferTooSmall => new(ModuleId, 141);
|
public static Result PointerBufferTooSmall => new(ModuleId, 141);
|
||||||
|
@ -15,5 +16,6 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
public static Result InvalidCmifRequest => new(ModuleId, 420);
|
public static Result InvalidCmifRequest => new(ModuleId, 420);
|
||||||
public static Result TargetNotDomain => new(ModuleId, 491);
|
public static Result TargetNotDomain => new(ModuleId, 491);
|
||||||
public static Result DomainObjectNotFound => new(ModuleId, 492);
|
public static Result DomainObjectNotFound => new(ModuleId, 492);
|
||||||
|
#pragma warning restore IDE0055
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
{
|
{
|
||||||
struct HipcStaticDescriptor
|
readonly struct HipcStaticDescriptor
|
||||||
{
|
{
|
||||||
private readonly ulong _data;
|
private readonly ulong _data;
|
||||||
|
|
||||||
public ulong Address => ((((_data >> 2) & 0x70) | ((_data >> 12) & 0xf)) << 32) | (_data >> 32);
|
public ulong Address => ((((_data >> 2) & 0x70) | ((_data >> 12) & 0xf)) << 32) | (_data >> 32);
|
||||||
public ushort Size => (ushort)(_data >> 16);
|
public ushort Size => (ushort)(_data >> 16);
|
||||||
public int ReceiveIndex => (int)(_data & 0xf);
|
public int ReceiveIndex => (int)(_data & 0xf);
|
||||||
|
|
||||||
public HipcStaticDescriptor(ulong address, ushort size, int receiveIndex)
|
public HipcStaticDescriptor(ulong address, ushort size, int receiveIndex)
|
||||||
{
|
{
|
||||||
|
@ -19,4 +19,4 @@
|
||||||
_data = data;
|
_data = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
{
|
{
|
||||||
struct ManagerOptions
|
readonly struct ManagerOptions
|
||||||
{
|
{
|
||||||
public static ManagerOptions Default => new(0, 0, 0, false);
|
public static ManagerOptions Default => new(0, 0, 0, false);
|
||||||
|
|
||||||
public int PointerBufferSize { get; }
|
public int PointerBufferSize { get; }
|
||||||
public int MaxDomains { get; }
|
public int MaxDomains { get; }
|
||||||
public int MaxDomainObjects { get; }
|
public int MaxDomainObjects { get; }
|
||||||
public bool CanDeferInvokeRequest { get; }
|
public bool CanDeferInvokeRequest { get; }
|
||||||
|
|
||||||
public ManagerOptions(int pointerBufferSize, int maxDomains, int maxDomainObjects, bool canDeferInvokeRequest)
|
public ManagerOptions(int pointerBufferSize, int maxDomains, int maxDomainObjects, bool canDeferInvokeRequest)
|
||||||
{
|
{
|
||||||
PointerBufferSize = pointerBufferSize;
|
PointerBufferSize = pointerBufferSize;
|
||||||
MaxDomains = maxDomains;
|
MaxDomains = maxDomains;
|
||||||
MaxDomainObjects = maxDomainObjects;
|
MaxDomainObjects = maxDomainObjects;
|
||||||
CanDeferInvokeRequest = canDeferInvokeRequest;
|
CanDeferInvokeRequest = canDeferInvokeRequest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
{
|
{
|
||||||
Success,
|
Success,
|
||||||
Closed,
|
Closed,
|
||||||
NeedsRetry
|
NeedsRetry,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,22 +6,22 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
{
|
{
|
||||||
class Server : MultiWaitHolderOfHandle
|
class Server : MultiWaitHolderOfHandle
|
||||||
{
|
{
|
||||||
public int PortIndex { get; }
|
public int PortIndex { get; }
|
||||||
public int PortHandle { get; }
|
public int PortHandle { get; }
|
||||||
public ServiceName Name { get; }
|
public ServiceName Name { get; }
|
||||||
public bool Managed { get; }
|
public bool Managed { get; }
|
||||||
public ServiceObjectHolder StaticObject { get; }
|
public ServiceObjectHolder StaticObject { get; }
|
||||||
|
|
||||||
public Server(
|
public Server(
|
||||||
int portIndex,
|
int portIndex,
|
||||||
int portHandle,
|
int portHandle,
|
||||||
ServiceName name,
|
ServiceName name,
|
||||||
bool managed,
|
bool managed,
|
||||||
ServiceObjectHolder staticHoder) : base(portHandle)
|
ServiceObjectHolder staticHoder) : base(portHandle)
|
||||||
{
|
{
|
||||||
PortHandle = portHandle;
|
PortHandle = portHandle;
|
||||||
Name = name;
|
Name = name;
|
||||||
Managed = managed;
|
Managed = managed;
|
||||||
|
|
||||||
if (staticHoder != null)
|
if (staticHoder != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,8 +14,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
private readonly bool _canDeferInvokeRequest;
|
private readonly bool _canDeferInvokeRequest;
|
||||||
private readonly int _maxSessions;
|
private readonly int _maxSessions;
|
||||||
|
|
||||||
private ulong _pointerBuffersBaseAddress;
|
private readonly ulong _pointerBuffersBaseAddress;
|
||||||
private ulong _savedMessagesBaseAddress;
|
private readonly ulong _savedMessagesBaseAddress;
|
||||||
|
|
||||||
private readonly object _resourceLock;
|
private readonly object _resourceLock;
|
||||||
private readonly ulong[] _sessionAllocationBitmap;
|
private readonly ulong[] _sessionAllocationBitmap;
|
||||||
|
@ -35,7 +35,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
|
|
||||||
if (options.CanDeferInvokeRequest)
|
if (options.CanDeferInvokeRequest)
|
||||||
{
|
{
|
||||||
_savedMessagesBaseAddress = allocator.Allocate((ulong)maxSessions * (ulong)Api.TlsMessageBufferSize);
|
_savedMessagesBaseAddress = allocator.Allocate((ulong)maxSessions * Api.TlsMessageBufferSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
_servers = new HashSet<Server>();
|
_servers = new HashSet<Server>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private PointerAndSize GetObjectBySessionIndex(ServerSession session, ulong baseAddress, ulong size)
|
private static PointerAndSize GetObjectBySessionIndex(ServerSession session, ulong baseAddress, ulong size)
|
||||||
{
|
{
|
||||||
return new PointerAndSize(baseAddress + (ulong)session.SessionIndex * size, size);
|
return new PointerAndSize(baseAddress + (ulong)session.SessionIndex * size, size);
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i <_sessionAllocationBitmap.Length; i++)
|
for (int i = 0; i < _sessionAllocationBitmap.Length; i++)
|
||||||
{
|
{
|
||||||
ref ulong mask = ref _sessionAllocationBitmap[i];
|
ref ulong mask = ref _sessionAllocationBitmap[i];
|
||||||
|
|
||||||
|
@ -145,10 +145,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
{
|
{
|
||||||
return GetObjectBySessionIndex(session, _pointerBuffersBaseAddress, (ulong)_pointerBufferSize);
|
return GetObjectBySessionIndex(session, _pointerBuffersBaseAddress, (ulong)_pointerBufferSize);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
return PointerAndSize.Empty;
|
||||||
return PointerAndSize.Empty;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override PointerAndSize GetSessionSavedMessageBuffer(ServerSession session)
|
protected override PointerAndSize GetSessionSavedMessageBuffer(ServerSession session)
|
||||||
|
@ -157,10 +155,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
{
|
{
|
||||||
return GetObjectBySessionIndex(session, _savedMessagesBaseAddress, Api.TlsMessageBufferSize);
|
return GetObjectBySessionIndex(session, _savedMessagesBaseAddress, Api.TlsMessageBufferSize);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
return PointerAndSize.Empty;
|
||||||
return PointerAndSize.Empty;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
{
|
{
|
||||||
private readonly SmApi _sm;
|
private readonly SmApi _sm;
|
||||||
|
|
||||||
private bool _canDeferInvokeRequest;
|
private readonly bool _canDeferInvokeRequest;
|
||||||
|
|
||||||
private readonly MultiWait _multiWait;
|
private readonly MultiWait _multiWait;
|
||||||
private readonly MultiWait _waitList;
|
private readonly MultiWait _waitList;
|
||||||
|
@ -26,8 +26,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
|
|
||||||
private enum UserDataTag
|
private enum UserDataTag
|
||||||
{
|
{
|
||||||
Server = 1,
|
Server = 1,
|
||||||
Session = 2
|
Session = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerManagerBase(SmApi sm, ManagerOptions options) : base(options.MaxDomainObjects, options.MaxDomains)
|
public ServerManagerBase(SmApi sm, ManagerOptions options) : base(options.MaxDomainObjects, options.MaxDomains)
|
||||||
|
@ -36,13 +36,13 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
_canDeferInvokeRequest = options.CanDeferInvokeRequest;
|
_canDeferInvokeRequest = options.CanDeferInvokeRequest;
|
||||||
|
|
||||||
_multiWait = new MultiWait();
|
_multiWait = new MultiWait();
|
||||||
_waitList = new MultiWait();
|
_waitList = new MultiWait();
|
||||||
|
|
||||||
_multiWaitSelectionLock = new object();
|
_multiWaitSelectionLock = new object();
|
||||||
_waitListLock = new object();
|
_waitListLock = new object();
|
||||||
|
|
||||||
_requestStopEvent = new Event(EventClearMode.ManualClear);
|
_requestStopEvent = new Event(EventClearMode.ManualClear);
|
||||||
_notifyEvent = new Event(EventClearMode.ManualClear);
|
_notifyEvent = new Event(EventClearMode.ManualClear);
|
||||||
|
|
||||||
_requestStopEventHolder = new MultiWaitHolderOfEvent(_requestStopEvent);
|
_requestStopEventHolder = new MultiWaitHolderOfEvent(_requestStopEvent);
|
||||||
_multiWait.LinkMultiWaitHolder(_requestStopEventHolder);
|
_multiWait.LinkMultiWaitHolder(_requestStopEventHolder);
|
||||||
|
@ -113,7 +113,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
|
|
||||||
public void ServiceRequests()
|
public void ServiceRequests()
|
||||||
{
|
{
|
||||||
while (WaitAndProcessRequestsImpl());
|
while (WaitAndProcessRequestsImpl())
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WaitAndProcessRequests()
|
public void WaitAndProcessRequests()
|
||||||
|
@ -183,7 +185,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
protected override void RegisterSessionToWaitList(ServerSession session)
|
protected override void RegisterSessionToWaitList(ServerSession session)
|
||||||
{
|
{
|
||||||
session.HasReceived = false;
|
session.HasReceived = false;
|
||||||
session.UserData = UserDataTag.Session;
|
session.UserData = UserDataTag.Session;
|
||||||
|
|
||||||
RegisterToWaitList(session);
|
RegisterToWaitList(session);
|
||||||
}
|
}
|
||||||
|
@ -209,9 +211,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
{
|
{
|
||||||
return (UserDataTag)holder.UserData switch
|
return (UserDataTag)holder.UserData switch
|
||||||
{
|
{
|
||||||
UserDataTag.Server => ProcessForServer(holder),
|
UserDataTag.Server => ProcessForServer(holder),
|
||||||
UserDataTag.Session => ProcessForSession(holder),
|
UserDataTag.Session => ProcessForSession(holder),
|
||||||
_ => throw new NotImplementedException(((UserDataTag)holder.UserData).ToString())
|
_ => throw new NotImplementedException(((UserDataTag)holder.UserData).ToString()),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,18 +6,18 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
class ServerSession : MultiWaitHolderOfHandle
|
class ServerSession : MultiWaitHolderOfHandle
|
||||||
{
|
{
|
||||||
public ServiceObjectHolder ServiceObjectHolder { get; set; }
|
public ServiceObjectHolder ServiceObjectHolder { get; set; }
|
||||||
public PointerAndSize PointerBuffer { get; set; }
|
public PointerAndSize PointerBuffer { get; set; }
|
||||||
public PointerAndSize SavedMessage { get; set; }
|
public PointerAndSize SavedMessage { get; set; }
|
||||||
public int SessionIndex { get; }
|
public int SessionIndex { get; }
|
||||||
public int SessionHandle { get; }
|
public int SessionHandle { get; }
|
||||||
public bool IsClosed { get; set; }
|
public bool IsClosed { get; set; }
|
||||||
public bool HasReceived { get; set; }
|
public bool HasReceived { get; set; }
|
||||||
|
|
||||||
public ServerSession(int index, int handle, ServiceObjectHolder obj) : base(handle)
|
public ServerSession(int index, int handle, ServiceObjectHolder obj) : base(handle)
|
||||||
{
|
{
|
||||||
ServiceObjectHolder = obj;
|
ServiceObjectHolder = obj;
|
||||||
SessionIndex = index;
|
SessionIndex = index;
|
||||||
SessionHandle = handle;
|
SessionHandle = handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
}
|
}
|
||||||
|
|
||||||
session.PointerBuffer = GetSessionPointerBuffer(session);
|
session.PointerBuffer = GetSessionPointerBuffer(session);
|
||||||
session.SavedMessage = GetSessionSavedMessageBuffer(session);
|
session.SavedMessage = GetSessionSavedMessageBuffer(session);
|
||||||
|
|
||||||
RegisterSessionToWaitList(session);
|
RegisterSessionToWaitList(session);
|
||||||
|
|
||||||
|
@ -110,10 +110,10 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual Server AllocateServer(
|
protected virtual Server AllocateServer(
|
||||||
int portIndex,
|
int portIndex,
|
||||||
int portHandle,
|
int portHandle,
|
||||||
ServiceName name,
|
ServiceName name,
|
||||||
bool managed,
|
bool managed,
|
||||||
ServiceObjectHolder staticHoder)
|
ServiceObjectHolder staticHoder)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
|
@ -161,29 +161,25 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
Result result = ProcessRequestImpl(session, message, message);
|
||||||
|
|
||||||
|
if (result.IsSuccess)
|
||||||
{
|
{
|
||||||
Result result = ProcessRequestImpl(session, message, message);
|
RegisterSessionToWaitList(session);
|
||||||
|
|
||||||
if (result.IsSuccess)
|
return Result.Success;
|
||||||
{
|
|
||||||
RegisterSessionToWaitList(session);
|
|
||||||
|
|
||||||
return Result.Success;
|
|
||||||
}
|
|
||||||
else if (SfResult.RequestContextChanged(result))
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger.Warning?.Print(LogClass.KernelIpc, $"Request processing returned error {result}");
|
|
||||||
|
|
||||||
CloseSessionImpl(session);
|
|
||||||
|
|
||||||
return Result.Success;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (SfResult.RequestContextChanged(result))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Warning?.Print(LogClass.KernelIpc, $"Request processing returned error {result}");
|
||||||
|
|
||||||
|
CloseSessionImpl(session);
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result ProcessRequestImpl(ServerSession session, Span<byte> inMessage, Span<byte> outMessage)
|
private Result ProcessRequestImpl(ServerSession session, Span<byte> inMessage, Span<byte> outMessage)
|
||||||
|
@ -192,18 +188,13 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
|
|
||||||
using var _ = new ScopedInlineContextChange(GetInlineContext(commandType, inMessage));
|
using var _ = new ScopedInlineContextChange(GetInlineContext(commandType, inMessage));
|
||||||
|
|
||||||
switch (commandType)
|
return commandType switch
|
||||||
{
|
{
|
||||||
case CommandType.Request:
|
CommandType.Request or CommandType.RequestWithContext => DispatchRequest(session.ServiceObjectHolder, session, inMessage, outMessage),
|
||||||
case CommandType.RequestWithContext:
|
CommandType.Control or CommandType.ControlWithContext => DispatchManagerRequest(session, inMessage, outMessage),
|
||||||
return DispatchRequest(session.ServiceObjectHolder, session, inMessage, outMessage);
|
_ => HipcResult.UnknownCommandType,
|
||||||
case CommandType.Control:
|
};
|
||||||
case CommandType.ControlWithContext:
|
|
||||||
return DispatchManagerRequest(session, inMessage, outMessage);
|
|
||||||
default:
|
|
||||||
return HipcResult.UnknownCommandType;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static int GetInlineContext(CommandType commandType, ReadOnlySpan<byte> inMessage)
|
private static int GetInlineContext(CommandType commandType, ReadOnlySpan<byte> inMessage)
|
||||||
{
|
{
|
||||||
|
@ -221,12 +212,12 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Result ReceiveRequest(ServerSession session, Span<byte> message)
|
protected static Result ReceiveRequest(ServerSession session, Span<byte> message)
|
||||||
{
|
{
|
||||||
return ReceiveRequestImpl(session, message);
|
return ReceiveRequestImpl(session, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result ReceiveRequestImpl(ServerSession session, Span<byte> message)
|
private static Result ReceiveRequestImpl(ServerSession session, Span<byte> message)
|
||||||
{
|
{
|
||||||
PointerAndSize pointerBuffer = session.PointerBuffer;
|
PointerAndSize pointerBuffer = session.PointerBuffer;
|
||||||
|
|
||||||
|
@ -234,19 +225,19 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
{
|
{
|
||||||
if (pointerBuffer.Address != 0)
|
if (pointerBuffer.Address != 0)
|
||||||
{
|
{
|
||||||
HipcMessageData messageData = HipcMessage.WriteMessage(message, new HipcMetadata()
|
HipcMessageData messageData = HipcMessage.WriteMessage(message, new HipcMetadata
|
||||||
{
|
{
|
||||||
Type = (int)CommandType.Invalid,
|
Type = (int)CommandType.Invalid,
|
||||||
ReceiveStaticsCount = HipcMessage.AutoReceiveStatic
|
ReceiveStaticsCount = HipcMessage.AutoReceiveStatic,
|
||||||
});
|
});
|
||||||
|
|
||||||
messageData.ReceiveList[0] = new HipcReceiveListEntry(pointerBuffer.Address, pointerBuffer.Size);
|
messageData.ReceiveList[0] = new HipcReceiveListEntry(pointerBuffer.Address, pointerBuffer.Size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MemoryMarshal.Cast<byte, Header>(message)[0] = new Header()
|
MemoryMarshal.Cast<byte, Header>(message)[0] = new Header
|
||||||
{
|
{
|
||||||
Type = CommandType.Invalid
|
Type = CommandType.Invalid,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,9 +267,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
|
|
||||||
protected virtual Result DispatchRequest(
|
protected virtual Result DispatchRequest(
|
||||||
ServiceObjectHolder objectHolder,
|
ServiceObjectHolder objectHolder,
|
||||||
ServerSession session,
|
ServerSession session,
|
||||||
Span<byte> inMessage,
|
Span<byte> inMessage,
|
||||||
Span<byte> outMessage)
|
Span<byte> outMessage)
|
||||||
{
|
{
|
||||||
HipcMessage request;
|
HipcMessage request;
|
||||||
|
|
||||||
|
@ -291,16 +282,16 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
return HipcResult.InvalidRequestSize;
|
return HipcResult.InvalidRequestSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dispatchCtx = new ServiceDispatchContext()
|
var dispatchCtx = new ServiceDispatchContext
|
||||||
{
|
{
|
||||||
ServiceObject = objectHolder.ServiceObject,
|
ServiceObject = objectHolder.ServiceObject,
|
||||||
Manager = this,
|
Manager = this,
|
||||||
Session = session,
|
Session = session,
|
||||||
HandlesToClose = new HandlesToClose(),
|
HandlesToClose = new HandlesToClose(),
|
||||||
PointerBuffer = session.PointerBuffer,
|
PointerBuffer = session.PointerBuffer,
|
||||||
InMessageBuffer = inMessage,
|
InMessageBuffer = inMessage,
|
||||||
OutMessageBuffer = outMessage,
|
OutMessageBuffer = outMessage,
|
||||||
Request = request
|
Request = request,
|
||||||
};
|
};
|
||||||
|
|
||||||
ReadOnlySpan<byte> inRawData = MemoryMarshal.Cast<uint, byte>(dispatchCtx.Request.Data.DataWords);
|
ReadOnlySpan<byte> inRawData = MemoryMarshal.Cast<uint, byte>(dispatchCtx.Request.Data.DataWords);
|
||||||
|
@ -337,4 +328,4 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,19 +8,19 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
|
||||||
|
|
||||||
public bool SendPid
|
public bool SendPid
|
||||||
{
|
{
|
||||||
get => _word.Extract(0);
|
readonly get => _word.Extract(0);
|
||||||
set => _word = _word.Insert(0, value);
|
set => _word = _word.Insert(0, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int CopyHandlesCount
|
public int CopyHandlesCount
|
||||||
{
|
{
|
||||||
get => (int)_word.Extract(1, 4);
|
readonly get => (int)_word.Extract(1, 4);
|
||||||
set => _word = _word.Insert(1, 4, (uint)value);
|
set => _word = _word.Insert(1, 4, (uint)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int MoveHandlesCount
|
public int MoveHandlesCount
|
||||||
{
|
{
|
||||||
get => (int)_word.Extract(5, 4);
|
readonly get => (int)_word.Extract(5, 4);
|
||||||
set => _word = _word.Insert(5, 4, (uint)value);
|
set => _word = _word.Insert(5, 4, (uint)value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,9 +134,9 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
ulong pointerBufferTail = context.PointerBuffer.Address;
|
ulong pointerBufferTail = context.PointerBuffer.Address;
|
||||||
ulong pointerBufferHead = pointerBufferTail + context.PointerBuffer.Size;
|
ulong pointerBufferHead = pointerBufferTail + context.PointerBuffer.Size;
|
||||||
|
|
||||||
int sendMapAliasIndex = 0;
|
int sendMapAliasIndex = 0;
|
||||||
int recvMapAliasIndex = 0;
|
int recvMapAliasIndex = 0;
|
||||||
int sendPointerIndex = 0;
|
int sendPointerIndex = 0;
|
||||||
int unfixedRecvPointerIndex = 0;
|
int unfixedRecvPointerIndex = 0;
|
||||||
|
|
||||||
for (int i = 0; i < _args.Length; i++)
|
for (int i = 0; i < _args.Length; i++)
|
||||||
|
@ -186,8 +186,8 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
if (flags.HasFlag(HipcBufferFlags.In))
|
if (flags.HasFlag(HipcBufferFlags.In))
|
||||||
{
|
{
|
||||||
var descriptor = context.Request.Data.SendStatics[sendPointerIndex++];
|
var descriptor = context.Request.Data.SendStatics[sendPointerIndex++];
|
||||||
ulong address = descriptor.Address;
|
ulong address = descriptor.Address;
|
||||||
ulong size = descriptor.Size;
|
ulong size = descriptor.Size;
|
||||||
|
|
||||||
_bufferRanges[i] = new PointerAndSize(address, size);
|
_bufferRanges[i] = new PointerAndSize(address, size);
|
||||||
|
|
||||||
|
@ -206,14 +206,14 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var data = MemoryMarshal.Cast<uint, byte>(context.Request.Data.DataWords);
|
var data = MemoryMarshal.Cast<uint, byte>(context.Request.Data.DataWords);
|
||||||
var recvPointerSizes = MemoryMarshal.Cast<byte, ushort>(data[runtimeMetadata.UnfixedOutPointerSizeOffset..]);
|
var recvPointerSizes = MemoryMarshal.Cast<byte, ushort>(data[runtimeMetadata.UnfixedOutPointerSizeOffset..]);
|
||||||
|
|
||||||
size = recvPointerSizes[unfixedRecvPointerIndex++];
|
size = recvPointerSizes[unfixedRecvPointerIndex++];
|
||||||
}
|
}
|
||||||
|
|
||||||
pointerBufferHead = BitUtils.AlignDown(pointerBufferHead - size, 0x10UL);
|
pointerBufferHead = BitUtils.AlignDown(pointerBufferHead - size, 0x10UL);
|
||||||
_bufferRanges[i] = new PointerAndSize(pointerBufferHead, size);
|
_bufferRanges[i] = new PointerAndSize(pointerBufferHead, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,13 +305,13 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
{
|
{
|
||||||
ref var meta = ref context.Request.Meta;
|
ref var meta = ref context.Request.Meta;
|
||||||
bool requestValid = true;
|
bool requestValid = true;
|
||||||
requestValid &= meta.SendPid == _hasInProcessIdHolder;
|
requestValid &= meta.SendPid == _hasInProcessIdHolder;
|
||||||
requestValid &= meta.SendStaticsCount == _inPointerBuffersCount;
|
requestValid &= meta.SendStaticsCount == _inPointerBuffersCount;
|
||||||
requestValid &= meta.SendBuffersCount == _inMapAliasBuffersCount;
|
requestValid &= meta.SendBuffersCount == _inMapAliasBuffersCount;
|
||||||
requestValid &= meta.ReceiveBuffersCount == _outMapAliasBuffersCount;
|
requestValid &= meta.ReceiveBuffersCount == _outMapAliasBuffersCount;
|
||||||
requestValid &= meta.ExchangeBuffersCount == 0;
|
requestValid &= meta.ExchangeBuffersCount == 0;
|
||||||
requestValid &= meta.CopyHandlesCount == _inCopyHandlesCount;
|
requestValid &= meta.CopyHandlesCount == _inCopyHandlesCount;
|
||||||
requestValid &= meta.MoveHandlesCount == _inMoveHandlesCount;
|
requestValid &= meta.MoveHandlesCount == _inMoveHandlesCount;
|
||||||
|
|
||||||
int rawSizeInBytes = meta.DataWordsCount * sizeof(uint);
|
int rawSizeInBytes = meta.DataWordsCount * sizeof(uint);
|
||||||
int commandRawSize = BitUtils.AlignUp(runtimeMetadata.UnfixedOutPointerSizeOffset + (OutUnfixedSizePointerBuffersCount * sizeof(ushort)), sizeof(uint));
|
int commandRawSize = BitUtils.AlignUp(runtimeMetadata.UnfixedOutPointerSizeOffset + (OutUnfixedSizePointerBuffersCount * sizeof(ushort)), sizeof(uint));
|
||||||
|
@ -345,7 +345,7 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = inObjectIndex++;
|
int index = inObjectIndex++;
|
||||||
var inObject = inObjects[index];
|
var inObject = inObjects[index];
|
||||||
|
|
||||||
objects[index] = inObject?.ServiceObject;
|
objects[index] = inObject?.ServiceObject;
|
||||||
|
@ -386,7 +386,9 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
outRawData = MemoryMarshal.Cast<uint, byte>(response.DataWords);
|
outRawData = MemoryMarshal.Cast<uint, byte>(response.DataWords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1822 // Mark member as static
|
||||||
public void SetOutObjects(ref ServiceDispatchContext context, HipcMessageData response, Span<IServiceObject> objects)
|
public void SetOutObjects(ref ServiceDispatchContext context, HipcMessageData response, Span<IServiceObject> objects)
|
||||||
|
#pragma warning restore CA1822
|
||||||
{
|
{
|
||||||
if (objects.Length == 0)
|
if (objects.Length == 0)
|
||||||
{
|
{
|
||||||
|
@ -411,7 +413,7 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetOutObjectImpl(int index, HipcMessageData response, ServerSessionManager manager, ServiceObjectHolder obj)
|
private static void SetOutObjectImpl(int index, HipcMessageData response, ServerSessionManager manager, ServiceObjectHolder obj)
|
||||||
{
|
{
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
{
|
{
|
||||||
|
@ -425,4 +427,4 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
response.MoveHandles[index] = clientHandle;
|
response.MoveHandles[index] = clientHandle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,15 +12,15 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
{
|
{
|
||||||
int argsCount = args.Length;
|
int argsCount = args.Length;
|
||||||
|
|
||||||
int[] sizes = new int[argsCount];
|
int[] sizes = new int[argsCount];
|
||||||
int[] aligns = new int[argsCount];
|
int[] aligns = new int[argsCount];
|
||||||
int[] map = new int[argsCount];
|
int[] map = new int[argsCount];
|
||||||
|
|
||||||
for (int i = 0; i < argsCount; i++)
|
for (int i = 0; i < argsCount; i++)
|
||||||
{
|
{
|
||||||
sizes[i] = args[i].ArgSize;
|
sizes[i] = args[i].ArgSize;
|
||||||
aligns[i] = args[i].ArgAlignment;
|
aligns[i] = args[i].ArgAlignment;
|
||||||
map[i] = i;
|
map[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i < argsCount; i++)
|
for (int i = 1; i < argsCount; i++)
|
||||||
|
@ -35,9 +35,9 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
|
|
||||||
foreach (int i in map)
|
foreach (int i in map)
|
||||||
{
|
{
|
||||||
offset = BitUtils.AlignUp(offset, aligns[i]);
|
offset = BitUtils.AlignUp(offset, aligns[i]);
|
||||||
offsets[i] = offset;
|
offsets[i] = offset;
|
||||||
offset += sizes[i];
|
offset += sizes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
offsets[argsCount] = offset;
|
offsets[argsCount] = offset;
|
||||||
|
@ -46,4 +46,4 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
return offsets;
|
return offsets;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
{
|
{
|
||||||
public const int ModuleId = 10;
|
public const int ModuleId = 10;
|
||||||
|
|
||||||
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
public static Result NotSupported => new(ModuleId, 1);
|
public static Result NotSupported => new(ModuleId, 1);
|
||||||
public static Result InvalidHeaderSize => new(ModuleId, 202);
|
public static Result InvalidHeaderSize => new(ModuleId, 202);
|
||||||
public static Result InvalidInHeader => new(ModuleId, 211);
|
public static Result InvalidInHeader => new(ModuleId, 211);
|
||||||
|
@ -23,5 +24,6 @@ namespace Ryujinx.Horizon.Sdk.Sf
|
||||||
public static bool RequestContextChanged(Result result) => result.InRange(800, 899);
|
public static bool RequestContextChanged(Result result) => result.InRange(800, 899);
|
||||||
public static bool Invalidated(Result result) => result.InRange(801, 809);
|
public static bool Invalidated(Result result) => result.InRange(801, 809);
|
||||||
public static bool RequestDeferred(Result result) => result.InRange(811, 819);
|
public static bool RequestDeferred(Result result) => result.InRange(811, 819);
|
||||||
|
#pragma warning restore IDE0055
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,4 +5,4 @@ namespace Ryujinx.Horizon.Sdk.Sm
|
||||||
interface IManagerService : IServiceObject
|
interface IManagerService : IServiceObject
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,4 +10,4 @@ namespace Ryujinx.Horizon.Sdk.Sm
|
||||||
Result RegisterService(out int handle, ServiceName name, int maxSessions, bool isLight);
|
Result RegisterService(out int handle, ServiceName name, int maxSessions, bool isLight);
|
||||||
Result UnregisterService(ServiceName name);
|
Result UnregisterService(ServiceName name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,13 @@ using System.Runtime.InteropServices;
|
||||||
namespace Ryujinx.Horizon.Sdk.Sm
|
namespace Ryujinx.Horizon.Sdk.Sm
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
struct ServiceName
|
readonly struct ServiceName
|
||||||
{
|
{
|
||||||
public static ServiceName Invalid { get; } = new ServiceName(0);
|
public static ServiceName Invalid { get; } = new(0);
|
||||||
|
|
||||||
public bool IsValid => Packed != 0;
|
public bool IsValid => Packed != 0;
|
||||||
|
|
||||||
public int Length => sizeof(ulong);
|
public const int Length = sizeof(ulong);
|
||||||
|
|
||||||
public ulong Packed { get; }
|
public ulong Packed { get; }
|
||||||
|
|
||||||
|
|
|
@ -110,4 +110,4 @@ namespace Ryujinx.Horizon.Sdk.Sm
|
||||||
return ServiceUtil.SendRequest(out _, _portHandle, 4, sendPid: true, data);
|
return ServiceUtil.SendRequest(out _, _portHandle, 4, sendPid: true, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,17 +4,17 @@ using System;
|
||||||
|
|
||||||
namespace Ryujinx.Horizon
|
namespace Ryujinx.Horizon
|
||||||
{
|
{
|
||||||
public struct ServiceEntry
|
public readonly struct ServiceEntry
|
||||||
{
|
{
|
||||||
private readonly Action<ServiceTable> _entrypoint;
|
private readonly Action<ServiceTable> _entrypoint;
|
||||||
private readonly ServiceTable _serviceTable;
|
private readonly ServiceTable _serviceTable;
|
||||||
private readonly HorizonOptions _options;
|
private readonly HorizonOptions _options;
|
||||||
|
|
||||||
internal ServiceEntry(Action<ServiceTable> entrypoint, ServiceTable serviceTable, HorizonOptions options)
|
internal ServiceEntry(Action<ServiceTable> entrypoint, ServiceTable serviceTable, HorizonOptions options)
|
||||||
{
|
{
|
||||||
_entrypoint = entrypoint;
|
_entrypoint = entrypoint;
|
||||||
_serviceTable = serviceTable;
|
_serviceTable = serviceTable;
|
||||||
_options = options;
|
_options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start(ISyscallApi syscallApi, IVirtualMemoryManager addressSpace, IThreadContext threadContext)
|
public void Start(ISyscallApi syscallApi, IVirtualMemoryManager addressSpace, IThreadContext threadContext)
|
||||||
|
@ -24,4 +24,4 @@ namespace Ryujinx.Horizon
|
||||||
_entrypoint(_serviceTable);
|
_entrypoint(_serviceTable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,4 +57,4 @@ namespace Ryujinx.Horizon
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,16 +5,16 @@ namespace Ryujinx.Horizon.Sm.Impl
|
||||||
struct ServiceInfo
|
struct ServiceInfo
|
||||||
{
|
{
|
||||||
public ServiceName Name;
|
public ServiceName Name;
|
||||||
public ulong OwnerProcessId;
|
public ulong OwnerProcessId;
|
||||||
public int PortHandle;
|
public int PortHandle;
|
||||||
|
|
||||||
public void Free()
|
public void Free()
|
||||||
{
|
{
|
||||||
HorizonStatic.Syscall.CloseHandle(PortHandle);
|
HorizonStatic.Syscall.CloseHandle(PortHandle);
|
||||||
|
|
||||||
Name = ServiceName.Invalid;
|
Name = ServiceName.Invalid;
|
||||||
OwnerProcessId = 0L;
|
OwnerProcessId = 0L;
|
||||||
PortHandle = 0;
|
PortHandle = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace Ryujinx.Horizon.Sm.Impl
|
||||||
return result == KernelResult.SessionCountExceeded ? SmResult.OutOfSessions : result;
|
return result == KernelResult.SessionCountExceeded ? SmResult.OutOfSessions : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result GetServiceImpl(out int handle, ref ServiceInfo serviceInfo)
|
private static Result GetServiceImpl(out int handle, ref ServiceInfo serviceInfo)
|
||||||
{
|
{
|
||||||
return HorizonStatic.Syscall.ConnectToPort(out handle, serviceInfo.PortHandle);
|
return HorizonStatic.Syscall.ConnectToPort(out handle, serviceInfo.PortHandle);
|
||||||
}
|
}
|
||||||
|
@ -96,8 +96,8 @@ namespace Ryujinx.Horizon.Sm.Impl
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
freeService.PortHandle = clientPort;
|
freeService.PortHandle = clientPort;
|
||||||
freeService.Name = name;
|
freeService.Name = name;
|
||||||
freeService.OwnerProcessId = processId;
|
freeService.OwnerProcessId = processId;
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
|
@ -140,7 +140,7 @@ namespace Ryujinx.Horizon.Sm.Impl
|
||||||
|
|
||||||
int nameLength = 1;
|
int nameLength = 1;
|
||||||
|
|
||||||
for (; nameLength < name.Length; nameLength++)
|
for (; nameLength < ServiceName.Length; nameLength++)
|
||||||
{
|
{
|
||||||
if (name[nameLength] == 0)
|
if (name[nameLength] == 0)
|
||||||
{
|
{
|
||||||
|
@ -148,7 +148,7 @@ namespace Ryujinx.Horizon.Sm.Impl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (nameLength < name.Length)
|
while (nameLength < ServiceName.Length)
|
||||||
{
|
{
|
||||||
if (name[nameLength++] != 0)
|
if (name[nameLength++] != 0)
|
||||||
{
|
{
|
||||||
|
@ -182,4 +182,4 @@ namespace Ryujinx.Horizon.Sm.Impl
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue