Compare commits

...

2 Commits

Author SHA1 Message Date
Ac_K
1e06b28b22 Horizon: Migrate usb and psc services (#5800)
* Horizon: Migrate Usb and Psc services

* Fix formatting

* Adresses feedback
2023-10-13 23:13:15 -03:00
sunshineinabox
e768a54f17 Replace ReaderWriterLock with ReaderWriterLockSlim (#5785)
* Replace ReaderWriterLock with ReaderWriterLockSlim

* Resolve Feedback + Correct typo

* Revert some unncessary logic
2023-10-12 18:11:15 +02:00
68 changed files with 773 additions and 181 deletions

View File

@@ -7,14 +7,14 @@ namespace ARMeilleure.Translation
internal class TranslatorCache<T>
{
private readonly IntervalTree<ulong, T> _tree;
private readonly ReaderWriterLock _treeLock;
private readonly ReaderWriterLockSlim _treeLock;
public int Count => _tree.Count;
public TranslatorCache()
{
_tree = new IntervalTree<ulong, T>();
_treeLock = new ReaderWriterLock();
_treeLock = new ReaderWriterLockSlim();
}
public bool TryAdd(ulong address, ulong size, T value)
@@ -24,70 +24,70 @@ namespace ARMeilleure.Translation
public bool AddOrUpdate(ulong address, ulong size, T value, Func<ulong, T, T> updateFactoryCallback)
{
_treeLock.AcquireWriterLock(Timeout.Infinite);
_treeLock.EnterWriteLock();
bool result = _tree.AddOrUpdate(address, address + size, value, updateFactoryCallback);
_treeLock.ReleaseWriterLock();
_treeLock.ExitWriteLock();
return result;
}
public T GetOrAdd(ulong address, ulong size, T value)
{
_treeLock.AcquireWriterLock(Timeout.Infinite);
_treeLock.EnterWriteLock();
value = _tree.GetOrAdd(address, address + size, value);
_treeLock.ReleaseWriterLock();
_treeLock.ExitWriteLock();
return value;
}
public bool Remove(ulong address)
{
_treeLock.AcquireWriterLock(Timeout.Infinite);
_treeLock.EnterWriteLock();
bool removed = _tree.Remove(address) != 0;
_treeLock.ReleaseWriterLock();
_treeLock.ExitWriteLock();
return removed;
}
public void Clear()
{
_treeLock.AcquireWriterLock(Timeout.Infinite);
_treeLock.EnterWriteLock();
_tree.Clear();
_treeLock.ReleaseWriterLock();
_treeLock.ExitWriteLock();
}
public bool ContainsKey(ulong address)
{
_treeLock.AcquireReaderLock(Timeout.Infinite);
_treeLock.EnterReadLock();
bool result = _tree.ContainsKey(address);
_treeLock.ReleaseReaderLock();
_treeLock.ExitReadLock();
return result;
}
public bool TryGetValue(ulong address, out T value)
{
_treeLock.AcquireReaderLock(Timeout.Infinite);
_treeLock.EnterReadLock();
bool result = _tree.TryGet(address, out value);
_treeLock.ReleaseReaderLock();
_treeLock.ExitReadLock();
return result;
}
public int GetOverlaps(ulong address, ulong size, ref ulong[] overlaps)
{
_treeLock.AcquireReaderLock(Timeout.Infinite);
_treeLock.EnterReadLock();
int count = _tree.Get(address, address + size, ref overlaps);
_treeLock.ReleaseReaderLock();
_treeLock.ExitReadLock();
return count;
}
public List<T> AsList()
{
_treeLock.AcquireReaderLock(Timeout.Infinite);
_treeLock.EnterReadLock();
List<T> list = _tree.AsList();
_treeLock.ReleaseReaderLock();
_treeLock.ExitReadLock();
return list;
}

View File

@@ -5,7 +5,7 @@ namespace Ryujinx.Common
{
public class ReactiveObject<T>
{
private readonly ReaderWriterLock _readerWriterLock = new();
private readonly ReaderWriterLockSlim _readerWriterLock = new();
private bool _isInitialized;
private T _value;
@@ -15,15 +15,15 @@ namespace Ryujinx.Common
{
get
{
_readerWriterLock.AcquireReaderLock(Timeout.Infinite);
_readerWriterLock.EnterReadLock();
T value = _value;
_readerWriterLock.ReleaseReaderLock();
_readerWriterLock.ExitReadLock();
return value;
}
set
{
_readerWriterLock.AcquireWriterLock(Timeout.Infinite);
_readerWriterLock.EnterWriteLock();
T oldValue = _value;
@@ -32,7 +32,7 @@ namespace Ryujinx.Common
_isInitialized = true;
_value = value;
_readerWriterLock.ReleaseWriterLock();
_readerWriterLock.ExitWriteLock();
if (!oldIsInitialized || oldValue == null || !oldValue.Equals(_value))
{

View File

@@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Vulkan
private int _flushTemp;
private int _lastFlushWrite = -1;
private readonly ReaderWriterLock _flushLock;
private readonly ReaderWriterLockSlim _flushLock;
private FenceHolder _flushFence;
private int _flushWaiting;
@@ -85,7 +85,7 @@ namespace Ryujinx.Graphics.Vulkan
_currentType = currentType;
DesiredType = currentType;
_flushLock = new ReaderWriterLock();
_flushLock = new ReaderWriterLockSlim();
_useMirrors = gd.IsTBDR;
}
@@ -106,7 +106,7 @@ namespace Ryujinx.Graphics.Vulkan
_currentType = currentType;
DesiredType = currentType;
_flushLock = new ReaderWriterLock();
_flushLock = new ReaderWriterLockSlim();
}
public bool TryBackingSwap(ref CommandBufferScoped? cbs)
@@ -116,7 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
// Only swap if the buffer is not used in any queued command buffer.
bool isRented = _buffer.HasRentedCommandBufferDependency(_gd.CommandBufferPool);
if (!isRented && _gd.CommandBufferPool.OwnedByCurrentThread && !_flushLock.IsReaderLockHeld && (_pendingData == null || cbs != null))
if (!isRented && _gd.CommandBufferPool.OwnedByCurrentThread && !_flushLock.IsReadLockHeld && (_pendingData == null || cbs != null))
{
var currentAllocation = _allocationAuto;
var currentBuffer = _buffer;
@@ -131,7 +131,7 @@ namespace Ryujinx.Graphics.Vulkan
ClearMirrors(cbs.Value, 0, Size);
}
_flushLock.AcquireWriterLock(Timeout.Infinite);
_flushLock.EnterWriteLock();
ClearFlushFence();
@@ -185,7 +185,7 @@ namespace Ryujinx.Graphics.Vulkan
_gd.PipelineInternal.SwapBuffer(currentBuffer, _buffer);
_flushLock.ReleaseWriterLock();
_flushLock.ExitWriteLock();
}
_swapQueued = false;
@@ -548,42 +548,44 @@ namespace Ryujinx.Graphics.Vulkan
private void WaitForFlushFence()
{
// Assumes the _flushLock is held as reader, returns in same state.
if (_flushFence == null)
{
return;
}
// If storage has changed, make sure the fence has been reached so that the data is in place.
_flushLock.ExitReadLock();
_flushLock.EnterWriteLock();
if (_flushFence != null)
{
// If storage has changed, make sure the fence has been reached so that the data is in place.
var fence = _flushFence;
Interlocked.Increment(ref _flushWaiting);
var cookie = _flushLock.UpgradeToWriterLock(Timeout.Infinite);
// Don't wait in the lock.
if (_flushFence != null)
_flushLock.ExitWriteLock();
fence.Wait();
_flushLock.EnterWriteLock();
if (Interlocked.Decrement(ref _flushWaiting) == 0)
{
var fence = _flushFence;
Interlocked.Increment(ref _flushWaiting);
// Don't wait in the lock.
var restoreCookie = _flushLock.ReleaseLock();
fence.Wait();
_flushLock.RestoreLock(ref restoreCookie);
if (Interlocked.Decrement(ref _flushWaiting) == 0)
{
fence.Put();
}
_flushFence = null;
fence.Put();
}
_flushLock.DowngradeFromWriterLock(ref cookie);
_flushFence = null;
}
// Assumes the _flushLock is held as reader, returns in same state.
_flushLock.ExitWriteLock();
_flushLock.EnterReadLock();
}
public PinnedSpan<byte> GetData(int offset, int size)
{
_flushLock.AcquireReaderLock(Timeout.Infinite);
_flushLock.EnterReadLock();
WaitForFlushFence();
@@ -603,7 +605,7 @@ namespace Ryujinx.Graphics.Vulkan
// Need to be careful here, the buffer can't be unmapped while the data is being used.
_buffer.IncrementReferenceCount();
_flushLock.ReleaseReaderLock();
_flushLock.ExitReadLock();
return PinnedSpan<byte>.UnsafeFromSpan(result, _buffer.DecrementReferenceCount);
}
@@ -621,7 +623,7 @@ namespace Ryujinx.Graphics.Vulkan
result = resource.GetFlushBuffer().GetBufferData(resource.GetPool(), this, offset, size);
}
_flushLock.ReleaseReaderLock();
_flushLock.ExitReadLock();
// Flush buffer is pinned until the next GetBufferData on the thread, which is fine for current uses.
return PinnedSpan<byte>.UnsafeFromSpan(result);
@@ -1073,11 +1075,11 @@ namespace Ryujinx.Graphics.Vulkan
_allocationAuto.Dispose();
}
_flushLock.AcquireWriterLock(Timeout.Infinite);
_flushLock.EnterWriteLock();
ClearFlushFence();
_flushLock.ReleaseWriterLock();
_flushLock.ExitWriteLock();
}
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Ins
{
[Service("ins:r")]
class IReceiverManager : IpcService
{
public IReceiverManager(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Ins
{
[Service("ins:s")]
class ISenderManager : IpcService
{
public ISenderManager(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Ovln
{
[Service("ovln:rcv")]
class IReceiverService : IpcService
{
public IReceiverService(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Ovln
{
[Service("ovln:snd")]
class ISenderService : IpcService
{
public ISenderService(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Psc
{
[Service("psc:c")]
class IPmControl : IpcService
{
public IPmControl(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Psc
{
[Service("psc:m")]
class IPmService : IpcService
{
public IPmService(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Psc
{
[Service("psc:l")] // 9.0.0+
class IPmUnknown : IpcService
{
public IPmUnknown(ServiceCtx context) { }
}
}

View File

@@ -1,9 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Srepo
{
[Service("srepo:a")] // 5.0.0+
[Service("srepo:u")] // 5.0.0+
class ISrepoService : IpcService
{
public ISrepoService(ServiceCtx context) { }
}
}

View File

@@ -1,9 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Usb
{
[Service("usb:hs")]
[Service("usb:hs:a")] // 7.0.0+
class IClientRootSession : IpcService
{
public IClientRootSession(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Usb
{
[Service("usb:ds")]
class IDsService : IpcService
{
public IDsService(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Usb
{
[Service("usb:pd:c")]
class IPdCradleManager : IpcService
{
public IPdCradleManager(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Usb
{
[Service("usb:pd")]
class IPdManager : IpcService
{
public IPdManager(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Usb
{
[Service("usb:pm")]
class IPmService : IpcService
{
public IPmService(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Usb
{
[Service("usb:qdb")] // 7.0.0+
class IUnknown1 : IpcService
{
public IUnknown1(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Usb
{
[Service("usb:obsv")] // 8.0.0+
class IUnknown2 : IpcService
{
public IUnknown2(ServiceCtx context) { }
}
}

View File

@@ -93,7 +93,7 @@ namespace Ryujinx.Horizon.Generators.Hipc
generator.LeaveScope();
generator.LeaveScope();
context.AddSource($"{className}.g.cs", generator.ToString());
context.AddSource($"{GetNamespaceName(commandInterface.ClassDeclarationSyntax)}.{className}.g.cs", generator.ToString());
}
}

View File

@@ -0,0 +1,47 @@
using Ryujinx.Horizon.Hshl.Ipc;
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
namespace Ryujinx.Horizon.Hshl
{
class HshlIpcServer
{
private const int HshlMaxSessionsCount = 10;
private const int TotalMaxSessionsCount = HshlMaxSessionsCount * 2;
private const int PointerBufferSize = 0;
private const int MaxDomains = 0;
private const int MaxDomainObjects = 0;
private const int MaxPortsCount = 2;
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm;
private ServerManager _serverManager;
public void Initialize()
{
HeapAllocator allocator = new();
_sm = new SmApi();
_sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
#pragma warning disable IDE0055 // Disable formatting
_serverManager.RegisterObjectForServer(new SetterManager(), ServiceName.Encode("hshl:set"), HshlMaxSessionsCount); // 11.0.0+
_serverManager.RegisterObjectForServer(new Manager(), ServiceName.Encode("hshl:sys"), HshlMaxSessionsCount); // 11.0.0+
#pragma warning restore IDE0055
}
public void ServiceRequests()
{
_serverManager.ServiceRequests();
}
public void Shutdown()
{
_serverManager.Dispose();
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Ryujinx.Horizon.Hshl
{
class HshlMain : IService
{
public static void Main(ServiceTable serviceTable)
{
HshlIpcServer ipcServer = new();
ipcServer.Initialize();
serviceTable.SignalServiceReady();
ipcServer.ServiceRequests();
ipcServer.Shutdown();
}
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Hshl;
namespace Ryujinx.Horizon.Hshl.Ipc
{
partial class Manager : IManager
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Hshl;
namespace Ryujinx.Horizon.Hshl.Ipc
{
partial class SetterManager : ISetterManager
{
}
}

View File

@@ -0,0 +1,47 @@
using Ryujinx.Horizon.Ins.Ipc;
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
namespace Ryujinx.Horizon.Ins
{
class InsIpcServer
{
private const int InsMaxSessionsCount = 8;
private const int TotalMaxSessionsCount = InsMaxSessionsCount * 2;
private const int PointerBufferSize = 0x200;
private const int MaxDomains = 0;
private const int MaxDomainObjects = 0;
private const int MaxPortsCount = 2;
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm;
private ServerManager _serverManager;
public void Initialize()
{
HeapAllocator allocator = new();
_sm = new SmApi();
_sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
#pragma warning disable IDE0055 // Disable formatting
_serverManager.RegisterObjectForServer(new ReceiverManager(), ServiceName.Encode("ins:r"), InsMaxSessionsCount); // 9.0.0+
_serverManager.RegisterObjectForServer(new SenderManager(), ServiceName.Encode("ins:s"), InsMaxSessionsCount); // 9.0.0+
#pragma warning restore IDE0055
}
public void ServiceRequests()
{
_serverManager.ServiceRequests();
}
public void Shutdown()
{
_serverManager.Dispose();
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Ryujinx.Horizon.Ins
{
class InsMain : IService
{
public static void Main(ServiceTable serviceTable)
{
InsIpcServer ipcServer = new();
ipcServer.Initialize();
serviceTable.SignalServiceReady();
ipcServer.ServiceRequests();
ipcServer.Shutdown();
}
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Ins;
namespace Ryujinx.Horizon.Ins.Ipc
{
partial class ReceiverManager : IReceiverManager
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Ins;
namespace Ryujinx.Horizon.Ins.Ipc
{
partial class SenderManager : ISenderManager
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Ovln;
namespace Ryujinx.Horizon.Ovln.Ipc
{
partial class ReceiverService : IReceiverService
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Ovln;
namespace Ryujinx.Horizon.Ovln.Ipc
{
partial class SenderService : ISenderService
{
}
}

View File

@@ -0,0 +1,48 @@
using Ryujinx.Horizon.Ovln.Ipc;
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
namespace Ryujinx.Horizon.Ovln
{
class OvlnIpcServer
{
private const int OvlnRcvMaxSessionsCount = 2;
private const int OvlnSndMaxSessionsCount = 20;
private const int TotalMaxSessionsCount = OvlnRcvMaxSessionsCount + OvlnSndMaxSessionsCount;
private const int PointerBufferSize = 0;
private const int MaxDomains = 21;
private const int MaxDomainObjects = 60;
private const int MaxPortsCount = 2;
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm;
private ServerManager _serverManager;
public void Initialize()
{
HeapAllocator allocator = new();
_sm = new SmApi();
_sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
#pragma warning disable IDE0055 // Disable formatting
_serverManager.RegisterObjectForServer(new ReceiverService(), ServiceName.Encode("ovln:rcv"), OvlnRcvMaxSessionsCount); // 8.0.0+
_serverManager.RegisterObjectForServer(new SenderService(), ServiceName.Encode("ovln:snd"), OvlnSndMaxSessionsCount); // 8.0.0+
#pragma warning restore IDE0055
}
public void ServiceRequests()
{
_serverManager.ServiceRequests();
}
public void Shutdown()
{
_serverManager.Dispose();
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Ryujinx.Horizon.Ovln
{
class OvlnMain : IService
{
public static void Main(ServiceTable serviceTable)
{
OvlnIpcServer ipcServer = new();
ipcServer.Initialize();
serviceTable.SignalServiceReady();
ipcServer.ServiceRequests();
ipcServer.Shutdown();
}
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Psc;
namespace Ryujinx.Horizon.Psc.Ipc
{
partial class PmControl : IPmControl
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Psc;
namespace Ryujinx.Horizon.Psc.Ipc
{
partial class PmService : IPmService
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Psc;
namespace Ryujinx.Horizon.Psc.Ipc
{
partial class PmStateLock : IPmStateLock
{
}
}

View File

@@ -0,0 +1,50 @@
using Ryujinx.Horizon.Psc.Ipc;
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
namespace Ryujinx.Horizon.Psc
{
class PscIpcServer
{
private const int PscCMaxSessionsCount = 1;
private const int PscMMaxSessionsCount = 50;
private const int PscLMaxSessionsCount = 5;
private const int TotalMaxSessionsCount = PscCMaxSessionsCount + PscMMaxSessionsCount + PscLMaxSessionsCount;
private const int PointerBufferSize = 0;
private const int MaxDomains = 0;
private const int MaxDomainObjects = 0;
private const int MaxPortsCount = 3;
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm;
private ServerManager _serverManager;
public void Initialize()
{
HeapAllocator allocator = new();
_sm = new SmApi();
_sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
#pragma warning disable IDE0055 // Disable formatting
_serverManager.RegisterObjectForServer(new PmControl(), ServiceName.Encode("psc:c"), PscCMaxSessionsCount);
_serverManager.RegisterObjectForServer(new PmService(), ServiceName.Encode("psc:m"), PscMMaxSessionsCount);
_serverManager.RegisterObjectForServer(new PmStateLock(), ServiceName.Encode("psc:l"), PscLMaxSessionsCount); // 9.0.0+
#pragma warning restore IDE0055
}
public void ServiceRequests()
{
_serverManager.ServiceRequests();
}
public void Shutdown()
{
_serverManager.Dispose();
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Ryujinx.Horizon.Psc
{
class PscMain : IService
{
public static void Main(ServiceTable serviceTable)
{
PscIpcServer ipcServer = new();
ipcServer.Initialize();
serviceTable.SignalServiceReady();
ipcServer.ServiceRequests();
ipcServer.Shutdown();
}
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Hshl
{
interface IManager : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Hshl
{
interface ISetterManager : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Ins
{
interface IReceiverManager : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Ins
{
interface ISenderManager : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Ovln
{
interface IReceiverService : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Ovln
{
interface ISenderService : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Psc
{
interface IPmControl : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Psc
{
interface IPmService : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Psc
{
interface IPmStateLock : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Srepo
{
interface ISrepoService : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IClientRootSession : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IDsRootSession : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IPdCradleManager : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IPdManager : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IPdManufactureManager : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IPmObserverService : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IPmService : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IQdbManager : IServiceObject
{
}
}

View File

@@ -1,9 +1,15 @@
using Ryujinx.Horizon.Bcat;
using Ryujinx.Horizon.Hshl;
using Ryujinx.Horizon.Ins;
using Ryujinx.Horizon.Lbl;
using Ryujinx.Horizon.LogManager;
using Ryujinx.Horizon.MmNv;
using Ryujinx.Horizon.Ngc;
using Ryujinx.Horizon.Ovln;
using Ryujinx.Horizon.Prepo;
using Ryujinx.Horizon.Psc;
using Ryujinx.Horizon.Srepo;
using Ryujinx.Horizon.Usb;
using Ryujinx.Horizon.Wlan;
using System.Collections.Generic;
using System.Threading;
@@ -27,12 +33,18 @@ namespace Ryujinx.Horizon
}
RegisterService<BcatMain>();
RegisterService<HshlMain>();
RegisterService<InsMain>();
RegisterService<LblMain>();
RegisterService<LmMain>();
RegisterService<MmNvMain>();
RegisterService<PrepoMain>();
RegisterService<WlanMain>();
RegisterService<NgcMain>();
RegisterService<OvlnMain>();
RegisterService<PrepoMain>();
RegisterService<PscMain>();
RegisterService<SrepoMain>();
RegisterService<UsbMain>();
RegisterService<WlanMain>();
_totalServices = entries.Count;

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Srepo;
namespace Ryujinx.Horizon.Srepo.Ipc
{
partial class SrepoService : ISrepoService
{
}
}

View File

@@ -0,0 +1,46 @@
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
using Ryujinx.Horizon.Srepo.Ipc;
namespace Ryujinx.Horizon.Srepo
{
class SrepoIpcServer
{
private const int SrepoAMaxSessionsCount = 2;
private const int SrepoUMaxSessionsCount = 30;
private const int TotalMaxSessionsCount = SrepoAMaxSessionsCount + SrepoUMaxSessionsCount;
private const int PointerBufferSize = 0x80;
private const int MaxDomains = 32;
private const int MaxDomainObjects = 192;
private const int MaxPortsCount = 2;
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm;
private ServerManager _serverManager;
public void Initialize()
{
HeapAllocator allocator = new();
_sm = new SmApi();
_sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
_serverManager.RegisterObjectForServer(new SrepoService(), ServiceName.Encode("srepo:a"), SrepoAMaxSessionsCount); // 5.0.0+
_serverManager.RegisterObjectForServer(new SrepoService(), ServiceName.Encode("srepo:u"), SrepoUMaxSessionsCount); // 5.0.0+
}
public void ServiceRequests()
{
_serverManager.ServiceRequests();
}
public void Shutdown()
{
_serverManager.Dispose();
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Ryujinx.Horizon.Srepo
{
class SrepoMain : IService
{
public static void Main(ServiceTable serviceTable)
{
SrepoIpcServer ipcServer = new();
ipcServer.Initialize();
serviceTable.SignalServiceReady();
ipcServer.ServiceRequests();
ipcServer.Shutdown();
}
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class ClientRootSession : IClientRootSession
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class DsRootSession : IDsRootSession
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class PdCradleManager : IPdCradleManager
{
}
}

View File

@@ -0,0 +1,9 @@
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class PdManager : IPdManager
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class PdManufactureManager : IPdManufactureManager
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class PmObserverService : IPmObserverService
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class PmService : IPmService
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class QdbManager : IQdbManager
{
}
}

View File

@@ -0,0 +1,71 @@
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
using Ryujinx.Horizon.Usb.Ipc;
namespace Ryujinx.Horizon.Usb
{
class UsbIpcServer
{
private const int UsbDsMaxSessionsCount = 4;
private const int UsbHsMaxSessionsCount = 20;
private const int UsbHsAMaxSessionsCount = 3;
private const int UsbObsvMaxSessionsCount = 2;
private const int UsbPdMaxSessionsCount = 6;
private const int UsbPdCMaxSessionsCount = 4;
private const int UsbPdMMaxSessionsCount = 1;
private const int UsbPmMaxSessionsCount = 5;
private const int UsbQdbMaxSessionsCount = 4;
private const int TotalMaxSessionsCount =
UsbDsMaxSessionsCount +
UsbHsMaxSessionsCount +
UsbHsAMaxSessionsCount +
UsbObsvMaxSessionsCount +
UsbPdMaxSessionsCount +
UsbPdCMaxSessionsCount +
UsbPdMMaxSessionsCount +
UsbPmMaxSessionsCount +
UsbQdbMaxSessionsCount;
private const int PointerBufferSize = 0;
private const int MaxDomains = 0;
private const int MaxDomainObjects = 0;
private const int MaxPortsCount = 9;
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm;
private ServerManager _serverManager;
public void Initialize()
{
HeapAllocator allocator = new();
_sm = new SmApi();
_sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
#pragma warning disable IDE0055 // Disable formatting
_serverManager.RegisterObjectForServer(new DsRootSession(), ServiceName.Encode("usb:ds"), UsbDsMaxSessionsCount);
_serverManager.RegisterObjectForServer(new ClientRootSession(), ServiceName.Encode("usb:hs"), UsbHsMaxSessionsCount);
_serverManager.RegisterObjectForServer(new ClientRootSession(), ServiceName.Encode("usb:hs:a"), UsbHsAMaxSessionsCount); // 7.0.0+
_serverManager.RegisterObjectForServer(new PmObserverService(), ServiceName.Encode("usb:obsv"), UsbObsvMaxSessionsCount); // 8.0.0+
_serverManager.RegisterObjectForServer(new PdManager(), ServiceName.Encode("usb:pd"), UsbPdMaxSessionsCount);
_serverManager.RegisterObjectForServer(new PdCradleManager(), ServiceName.Encode("usb:pd:c"), UsbPdCMaxSessionsCount);
_serverManager.RegisterObjectForServer(new PdManufactureManager(), ServiceName.Encode("usb:pd:m"), UsbPdMMaxSessionsCount); // 1.0.0
_serverManager.RegisterObjectForServer(new PmService(), ServiceName.Encode("usb:pm"), UsbPmMaxSessionsCount);
_serverManager.RegisterObjectForServer(new QdbManager(), ServiceName.Encode("usb:qdb"), UsbQdbMaxSessionsCount); // 7.0.0+
#pragma warning restore IDE0055
}
public void ServiceRequests()
{
_serverManager.ServiceRequests();
}
public void Shutdown()
{
_serverManager.Dispose();
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Ryujinx.Horizon.Usb
{
class UsbMain : IService
{
public static void Main(ServiceTable serviceTable)
{
UsbIpcServer ipcServer = new();
ipcServer.Initialize();
serviceTable.SignalServiceReady();
ipcServer.ServiceRequests();
ipcServer.Shutdown();
}
}
}