From e5c0dfa87e6a92dc7993677f9b5ee08e6e75caaa Mon Sep 17 00:00:00 2001 From: Isaac Marovitz Date: Sat, 21 Oct 2023 01:12:56 -0400 Subject: [PATCH] Start new IPC --- src/Ryujinx.Horizon/Am/AmIpcServer.cs | 44 +++++++++ src/Ryujinx.Horizon/Am/AmMain.cs | 17 ++++ src/Ryujinx.Horizon/Am/Ipc/ProxiesService.cs | 75 +++++++++++++++ .../Sdk/Am/IAllSystemAppletProxiesService.cs | 16 ++++ .../Sdk/Am/IApplicationProxy.cs | 17 ++++ .../Sdk/Am/ILibraryAppletProxy.cs | 20 ++++ .../Sdk/Am/IOverlayAppletProxy.cs | 19 ++++ .../Sdk/Am/ISystemAppletProxy.cs | 20 ++++ src/Ryujinx.Horizon/ServiceTable.cs | 2 + src/Ryujinx.Horizon/ServiceTable.cs.orig | 96 +++++++++++++++++++ 10 files changed, 326 insertions(+) create mode 100644 src/Ryujinx.Horizon/Am/AmIpcServer.cs create mode 100644 src/Ryujinx.Horizon/Am/AmMain.cs create mode 100644 src/Ryujinx.Horizon/Am/Ipc/ProxiesService.cs create mode 100644 src/Ryujinx.Horizon/Sdk/Am/IAllSystemAppletProxiesService.cs create mode 100644 src/Ryujinx.Horizon/Sdk/Am/IApplicationProxy.cs create mode 100644 src/Ryujinx.Horizon/Sdk/Am/ILibraryAppletProxy.cs create mode 100644 src/Ryujinx.Horizon/Sdk/Am/IOverlayAppletProxy.cs create mode 100644 src/Ryujinx.Horizon/Sdk/Am/ISystemAppletProxy.cs create mode 100644 src/Ryujinx.Horizon/ServiceTable.cs.orig diff --git a/src/Ryujinx.Horizon/Am/AmIpcServer.cs b/src/Ryujinx.Horizon/Am/AmIpcServer.cs new file mode 100644 index 000000000..e463794da --- /dev/null +++ b/src/Ryujinx.Horizon/Am/AmIpcServer.cs @@ -0,0 +1,44 @@ +using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sm; + +namespace Ryujinx.Horizon.Am +{ + internal class AmIpcServer + { + // TODO: Get actual values from RE + private const int MaxSessionsCount = 10; + private const int TotalMaxSessionsCount = MaxSessionsCount * 4; + + private const int PointerBufferSize = 0; + private const int MaxDomains = 0; + private const int MaxDomainObjects = 64; + private const int MaxPortsCount = 4; + + 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.RegisterServer(0, ServiceName.Encode("appletAE"), MaxSessionsCount); + } + + public void ServiceRequests() + { + _serverManager.ServiceRequests(); + } + + public void Shutdown() + { + _serverManager.Dispose(); + } + } +} diff --git a/src/Ryujinx.Horizon/Am/AmMain.cs b/src/Ryujinx.Horizon/Am/AmMain.cs new file mode 100644 index 000000000..fcd215469 --- /dev/null +++ b/src/Ryujinx.Horizon/Am/AmMain.cs @@ -0,0 +1,17 @@ +namespace Ryujinx.Horizon.Am +{ + class AmMain : IService + { + public static void Main(ServiceTable serviceTable) + { + AmIpcServer ipcServer = new(); + + ipcServer.Initialize(); + + serviceTable.SignalServiceReady(); + + ipcServer.ServiceRequests(); + ipcServer.Shutdown(); + } + } +} diff --git a/src/Ryujinx.Horizon/Am/Ipc/ProxiesService.cs b/src/Ryujinx.Horizon/Am/Ipc/ProxiesService.cs new file mode 100644 index 000000000..c851ae95f --- /dev/null +++ b/src/Ryujinx.Horizon/Am/Ipc/ProxiesService.cs @@ -0,0 +1,75 @@ +using LibHac.Diag; +using Ryujinx.Common.Logging; +using Ryujinx.Horizon.Common; +using Ryujinx.Horizon.Sdk.Am; +using Ryujinx.Horizon.Sdk.Sf; + +namespace Ryujinx.Horizon.Am.Ipc +{ + partial class ProxiesService : IAllSystemAppletProxiesService + { + [CmifCommand(100)] + public Result OpenSystemAppletProxy(out ISystemAppletProxy systemAppletProxy, [ClientProcessId] ulong pid) + { + Logger.Stub?.PrintStub(LogClass.ServiceAm); + + return Result.Success; + } + + [CmifCommand(200)] + public Result OpenLibraryAppletProxyOld(out ILibraryAppletProxy libraryAppletProxy, [ClientProcessId] ulong pid) + { + Logger.Stub?.PrintStub(LogClass.ServiceAm); + + return Result.Success; + } + + [CmifCommand(201)] + public Result OpenLibraryAppletProxy(out ILibraryAppletProxy libraryAppletProxy, [ClientProcessId] ulong pid) + { + Logger.Stub?.PrintStub(LogClass.ServiceAm); + + return Result.Success; + } + + [CmifCommand(300)] + public Result OpenOverlayAppletProxy(out IOverlayAppletProxy overlayAppletProxy, [ClientProcessId] ulong pid) + { + Logger.Stub?.PrintStub(LogClass.ServiceAm); + + return Result.Success; + } + + [CmifCommand(350)] + public Result OpenSystemApplicationProxy(out IApplicationProxy applicationProxy, [ClientProcessId] ulong pid) + { + Logger.Stub?.PrintStub(LogClass.ServiceAm); + + return Result.Success; + } + + [CmifCommand(400)] + public Result CreateSelfLibraryAppletCreatorForDevelop() + { + Logger.Stub?.PrintStub(LogClass.ServiceAm); + + return Result.Success; + } + + [CmifCommand(410)] + public Result GetSystemAppletControllerForDebug() + { + Logger.Stub?.PrintStub(LogClass.ServiceAm); + + return Result.Success; + } + + [CmifCommand(1000)] + public Result GetDebugFunctions() + { + Logger.Stub?.PrintStub(LogClass.ServiceAm); + + return Result.Success; + } + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Am/IAllSystemAppletProxiesService.cs b/src/Ryujinx.Horizon/Sdk/Am/IAllSystemAppletProxiesService.cs new file mode 100644 index 000000000..2ce1c6b50 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Am/IAllSystemAppletProxiesService.cs @@ -0,0 +1,16 @@ +using Ryujinx.Horizon.Common; + +namespace Ryujinx.Horizon.Sdk.Am +{ + public interface IAllSystemAppletProxiesService + { + Result OpenSystemAppletProxy(out ISystemAppletProxy systemAppletProxy, ulong pid); + Result OpenLibraryAppletProxyOld(out ILibraryAppletProxy libraryAppletProxy, ulong pid); + Result OpenLibraryAppletProxy(out ILibraryAppletProxy libraryAppletProxy, ulong pid); + Result OpenOverlayAppletProxy(out IOverlayAppletProxy overlayAppletProxy, ulong pid); + Result OpenSystemApplicationProxy(out IApplicationProxy applicationProxy, ulong pid); + Result CreateSelfLibraryAppletCreatorForDevelop(); + Result GetSystemAppletControllerForDebug(); + Result GetDebugFunctions(); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Am/IApplicationProxy.cs b/src/Ryujinx.Horizon/Sdk/Am/IApplicationProxy.cs new file mode 100644 index 000000000..33db045d3 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Am/IApplicationProxy.cs @@ -0,0 +1,17 @@ +using Ryujinx.Horizon.Common; + +namespace Ryujinx.Horizon.Sdk.Am +{ + public interface IApplicationProxy + { + Result GetCommonStateGetter(); + Result GetSelfController(); + Result GetWindowController(); + Result GetAudioController(); + Result GetDisplayController(); + Result GetProcessWindingController(); + Result GetLibraryAppletCreator(); + Result GetApplicationFunctions(); + Result GetDebugFunctions(); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Am/ILibraryAppletProxy.cs b/src/Ryujinx.Horizon/Sdk/Am/ILibraryAppletProxy.cs new file mode 100644 index 000000000..f647a2093 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Am/ILibraryAppletProxy.cs @@ -0,0 +1,20 @@ +using Ryujinx.Horizon.Common; + +namespace Ryujinx.Horizon.Sdk.Am +{ + public interface ILibraryAppletProxy + { + Result GetCommonStateGetter(); + Result GetSelfController(); + Result GetWindowController(); + Result GetAudioController(); + Result GetDisplayController(); + Result GetProcessWindingController(); + Result GetLibraryAppletCreator(); + Result OpenLibraryAppletSelfAccessor(); + Result GetAppletCommonFunctions(); + Result GetHomeMenuFunctions(); + Result GetGlobalStateController(); + Result GetDebugFunctions(); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Am/IOverlayAppletProxy.cs b/src/Ryujinx.Horizon/Sdk/Am/IOverlayAppletProxy.cs new file mode 100644 index 000000000..875bd7d3e --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Am/IOverlayAppletProxy.cs @@ -0,0 +1,19 @@ +using Ryujinx.Horizon.Common; + +namespace Ryujinx.Horizon.Sdk.Am +{ + public interface IOverlayAppletProxy + { + Result GetCommonStateGetter(); + Result GetSelfController(); + Result GetWindowController(); + Result GetAudioController(); + Result GetDisplayController(); + Result GetProcessWindingController(); + Result GetLibraryAppletCreator(); + Result GetOverlayFunctions(); + Result GetAppletCommonFunctions(); + Result GetGlobalStateController(); + Result GetDebugFunctions(); + } +} diff --git a/src/Ryujinx.Horizon/Sdk/Am/ISystemAppletProxy.cs b/src/Ryujinx.Horizon/Sdk/Am/ISystemAppletProxy.cs new file mode 100644 index 000000000..ef0e0c9b2 --- /dev/null +++ b/src/Ryujinx.Horizon/Sdk/Am/ISystemAppletProxy.cs @@ -0,0 +1,20 @@ +using Ryujinx.Horizon.Common; + +namespace Ryujinx.Horizon.Sdk.Am +{ + public interface ISystemAppletProxy + { + Result GetCommonStateGetter(); + Result GetSelfController(); + Result GetWindowController(); + Result GetAudioController(); + Result GetDisplayController(); + Result GetProcessWindingController(); + Result GetLibraryAppletCreator(); + Result GetHomeMenuFunctions(); + Result GetGlobalStateController(); + Result GetApplicationCreator(); + Result GetAppletCommonFunctions(); + Result GetDebugFunctions(); + } +} diff --git a/src/Ryujinx.Horizon/ServiceTable.cs b/src/Ryujinx.Horizon/ServiceTable.cs index b81e62a47..6bd0bc2c8 100644 --- a/src/Ryujinx.Horizon/ServiceTable.cs +++ b/src/Ryujinx.Horizon/ServiceTable.cs @@ -1,5 +1,6 @@ using Ryujinx.Horizon.Arp; using Ryujinx.Horizon.Audio; +using Ryujinx.Horizon.Am; using Ryujinx.Horizon.Bcat; using Ryujinx.Horizon.Friends; using Ryujinx.Horizon.Hshl; @@ -56,6 +57,7 @@ namespace Ryujinx.Horizon RegisterService(); RegisterService(); RegisterService(); + RegisterService(); _totalServices = entries.Count; diff --git a/src/Ryujinx.Horizon/ServiceTable.cs.orig b/src/Ryujinx.Horizon/ServiceTable.cs.orig new file mode 100644 index 000000000..478992c39 --- /dev/null +++ b/src/Ryujinx.Horizon/ServiceTable.cs.orig @@ -0,0 +1,96 @@ +<<<<<<< HEAD +using Ryujinx.Horizon.Arp; +using Ryujinx.Horizon.Audio; +======= +using Ryujinx.Horizon.Am; +>>>>>>> 8a4ff3542 (Start new IPC) +using Ryujinx.Horizon.Bcat; +using Ryujinx.Horizon.Friends; +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.Sdk.Arp; +using Ryujinx.Horizon.Srepo; +using Ryujinx.Horizon.Usb; +using Ryujinx.Horizon.Wlan; +using System.Collections.Generic; +using System.Threading; + +namespace Ryujinx.Horizon +{ + public class ServiceTable + { + private int _readyServices; + private int _totalServices; + + private readonly ManualResetEvent _servicesReadyEvent = new(false); + + public IReader ArpReader { get; internal set; } + public IWriter ArpWriter { get; internal set; } + + public IEnumerable GetServices(HorizonOptions options) + { + List entries = new(); + + void RegisterService() where T : IService + { + entries.Add(new ServiceEntry(T.Main, this, options)); + } + + RegisterService(); + RegisterService(); + RegisterService(); + RegisterService(); + RegisterService(); + RegisterService(); // TODO: Merge with audio once we can start multiple threads. + RegisterService(); + RegisterService(); + RegisterService(); + RegisterService(); + RegisterService(); + RegisterService(); + RegisterService(); + RegisterService(); + RegisterService(); + RegisterService(); + RegisterService(); + RegisterService(); + + _totalServices = entries.Count; + + return entries; + } + + internal void SignalServiceReady() + { + if (Interlocked.Increment(ref _readyServices) == _totalServices) + { + _servicesReadyEvent.Set(); + } + } + + public void WaitServicesReady() + { + _servicesReadyEvent.WaitOne(); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _servicesReadyEvent.Dispose(); + } + } + + public void Dispose() + { + Dispose(true); + } + } +}