From 1e06b28b22848706014b18bffcec7553cdab2b2b Mon Sep 17 00:00:00 2001
From: Ac_K <Acoustik666@gmail.com>
Date: Sat, 14 Oct 2023 04:13:15 +0200
Subject: Horizon: Migrate usb and psc services (#5800)

* Horizon: Migrate Usb and Psc services

* Fix formatting

* Adresses feedback
---
 .../HOS/Services/Ins/IReceiverManager.cs           |  8 ---
 src/Ryujinx.HLE/HOS/Services/Ins/ISenderManager.cs |  8 ---
 .../HOS/Services/Ovln/IReceiverService.cs          |  8 ---
 .../HOS/Services/Ovln/ISenderService.cs            |  8 ---
 src/Ryujinx.HLE/HOS/Services/Psc/IPmControl.cs     |  8 ---
 src/Ryujinx.HLE/HOS/Services/Psc/IPmService.cs     |  8 ---
 src/Ryujinx.HLE/HOS/Services/Psc/IPmUnknown.cs     |  8 ---
 .../HOS/Services/Srepo/ISrepoService.cs            |  9 ---
 .../HOS/Services/Usb/IClientRootSession.cs         |  9 ---
 src/Ryujinx.HLE/HOS/Services/Usb/IDsService.cs     |  8 ---
 .../HOS/Services/Usb/IPdCradleManager.cs           |  8 ---
 src/Ryujinx.HLE/HOS/Services/Usb/IPdManager.cs     |  8 ---
 src/Ryujinx.HLE/HOS/Services/Usb/IPmService.cs     |  8 ---
 src/Ryujinx.HLE/HOS/Services/Usb/IUnknown1.cs      |  8 ---
 src/Ryujinx.HLE/HOS/Services/Usb/IUnknown2.cs      |  8 ---
 .../Hipc/HipcGenerator.cs                          |  2 +-
 src/Ryujinx.Horizon/Hshl/HshlIpcServer.cs          | 47 ++++++++++++++
 src/Ryujinx.Horizon/Hshl/HshlMain.cs               | 17 ++++++
 src/Ryujinx.Horizon/Hshl/Ipc/Manager.cs            |  8 +++
 src/Ryujinx.Horizon/Hshl/Ipc/SetterManager.cs      |  8 +++
 src/Ryujinx.Horizon/Ins/InsIpcServer.cs            | 47 ++++++++++++++
 src/Ryujinx.Horizon/Ins/InsMain.cs                 | 17 ++++++
 src/Ryujinx.Horizon/Ins/Ipc/ReceiverManager.cs     |  8 +++
 src/Ryujinx.Horizon/Ins/Ipc/SenderManager.cs       |  8 +++
 src/Ryujinx.Horizon/Ovln/Ipc/ReceiverService.cs    |  8 +++
 src/Ryujinx.Horizon/Ovln/Ipc/SenderService.cs      |  8 +++
 src/Ryujinx.Horizon/Ovln/OvlnIpcServer.cs          | 48 +++++++++++++++
 src/Ryujinx.Horizon/Ovln/OvlnMain.cs               | 17 ++++++
 src/Ryujinx.Horizon/Psc/Ipc/PmControl.cs           |  8 +++
 src/Ryujinx.Horizon/Psc/Ipc/PmService.cs           |  8 +++
 src/Ryujinx.Horizon/Psc/Ipc/PmStateLock.cs         |  8 +++
 src/Ryujinx.Horizon/Psc/PscIpcServer.cs            | 50 +++++++++++++++
 src/Ryujinx.Horizon/Psc/PscMain.cs                 | 17 ++++++
 src/Ryujinx.Horizon/Sdk/Hshl/IManager.cs           |  8 +++
 src/Ryujinx.Horizon/Sdk/Hshl/ISetterManager.cs     |  8 +++
 src/Ryujinx.Horizon/Sdk/Ins/IReceiverManager.cs    |  8 +++
 src/Ryujinx.Horizon/Sdk/Ins/ISenderManager.cs      |  8 +++
 src/Ryujinx.Horizon/Sdk/Ovln/IReceiverService.cs   |  8 +++
 src/Ryujinx.Horizon/Sdk/Ovln/ISenderService.cs     |  8 +++
 src/Ryujinx.Horizon/Sdk/Psc/IPmControl.cs          |  8 +++
 src/Ryujinx.Horizon/Sdk/Psc/IPmService.cs          |  8 +++
 src/Ryujinx.Horizon/Sdk/Psc/IPmStateLock.cs        |  8 +++
 src/Ryujinx.Horizon/Sdk/Srepo/ISrepoService.cs     |  8 +++
 src/Ryujinx.Horizon/Sdk/Usb/IClientRootSession.cs  |  8 +++
 src/Ryujinx.Horizon/Sdk/Usb/IDsRootSession.cs      |  8 +++
 src/Ryujinx.Horizon/Sdk/Usb/IPdCradleManager.cs    |  8 +++
 src/Ryujinx.Horizon/Sdk/Usb/IPdManager.cs          |  8 +++
 .../Sdk/Usb/IPdManufactureManager.cs               |  8 +++
 src/Ryujinx.Horizon/Sdk/Usb/IPmObserverService.cs  |  8 +++
 src/Ryujinx.Horizon/Sdk/Usb/IPmService.cs          |  8 +++
 src/Ryujinx.Horizon/Sdk/Usb/IQdbManager.cs         |  8 +++
 src/Ryujinx.Horizon/ServiceTable.cs                | 14 ++++-
 src/Ryujinx.Horizon/Srepo/Ipc/SrepoService.cs      |  8 +++
 src/Ryujinx.Horizon/Srepo/SrepoIpcServer.cs        | 46 ++++++++++++++
 src/Ryujinx.Horizon/Srepo/SrepoMain.cs             | 17 ++++++
 src/Ryujinx.Horizon/Usb/Ipc/ClientRootSession.cs   |  8 +++
 src/Ryujinx.Horizon/Usb/Ipc/DsRootSession.cs       |  8 +++
 src/Ryujinx.Horizon/Usb/Ipc/PdCradleManager.cs     |  8 +++
 src/Ryujinx.Horizon/Usb/Ipc/PdManager.cs           |  9 +++
 .../Usb/Ipc/PdManufactureManager.cs                |  8 +++
 src/Ryujinx.Horizon/Usb/Ipc/PmObserverService.cs   |  8 +++
 src/Ryujinx.Horizon/Usb/Ipc/PmService.cs           |  8 +++
 src/Ryujinx.Horizon/Usb/Ipc/QdbManager.cs          |  8 +++
 src/Ryujinx.Horizon/Usb/UsbIpcServer.cs            | 71 ++++++++++++++++++++++
 src/Ryujinx.Horizon/Usb/UsbMain.cs                 | 17 ++++++
 65 files changed, 714 insertions(+), 124 deletions(-)
 delete mode 100644 src/Ryujinx.HLE/HOS/Services/Ins/IReceiverManager.cs
 delete mode 100644 src/Ryujinx.HLE/HOS/Services/Ins/ISenderManager.cs
 delete mode 100644 src/Ryujinx.HLE/HOS/Services/Ovln/IReceiverService.cs
 delete mode 100644 src/Ryujinx.HLE/HOS/Services/Ovln/ISenderService.cs
 delete mode 100644 src/Ryujinx.HLE/HOS/Services/Psc/IPmControl.cs
 delete mode 100644 src/Ryujinx.HLE/HOS/Services/Psc/IPmService.cs
 delete mode 100644 src/Ryujinx.HLE/HOS/Services/Psc/IPmUnknown.cs
 delete mode 100644 src/Ryujinx.HLE/HOS/Services/Srepo/ISrepoService.cs
 delete mode 100644 src/Ryujinx.HLE/HOS/Services/Usb/IClientRootSession.cs
 delete mode 100644 src/Ryujinx.HLE/HOS/Services/Usb/IDsService.cs
 delete mode 100644 src/Ryujinx.HLE/HOS/Services/Usb/IPdCradleManager.cs
 delete mode 100644 src/Ryujinx.HLE/HOS/Services/Usb/IPdManager.cs
 delete mode 100644 src/Ryujinx.HLE/HOS/Services/Usb/IPmService.cs
 delete mode 100644 src/Ryujinx.HLE/HOS/Services/Usb/IUnknown1.cs
 delete mode 100644 src/Ryujinx.HLE/HOS/Services/Usb/IUnknown2.cs
 create mode 100644 src/Ryujinx.Horizon/Hshl/HshlIpcServer.cs
 create mode 100644 src/Ryujinx.Horizon/Hshl/HshlMain.cs
 create mode 100644 src/Ryujinx.Horizon/Hshl/Ipc/Manager.cs
 create mode 100644 src/Ryujinx.Horizon/Hshl/Ipc/SetterManager.cs
 create mode 100644 src/Ryujinx.Horizon/Ins/InsIpcServer.cs
 create mode 100644 src/Ryujinx.Horizon/Ins/InsMain.cs
 create mode 100644 src/Ryujinx.Horizon/Ins/Ipc/ReceiverManager.cs
 create mode 100644 src/Ryujinx.Horizon/Ins/Ipc/SenderManager.cs
 create mode 100644 src/Ryujinx.Horizon/Ovln/Ipc/ReceiverService.cs
 create mode 100644 src/Ryujinx.Horizon/Ovln/Ipc/SenderService.cs
 create mode 100644 src/Ryujinx.Horizon/Ovln/OvlnIpcServer.cs
 create mode 100644 src/Ryujinx.Horizon/Ovln/OvlnMain.cs
 create mode 100644 src/Ryujinx.Horizon/Psc/Ipc/PmControl.cs
 create mode 100644 src/Ryujinx.Horizon/Psc/Ipc/PmService.cs
 create mode 100644 src/Ryujinx.Horizon/Psc/Ipc/PmStateLock.cs
 create mode 100644 src/Ryujinx.Horizon/Psc/PscIpcServer.cs
 create mode 100644 src/Ryujinx.Horizon/Psc/PscMain.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Hshl/IManager.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Hshl/ISetterManager.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Ins/IReceiverManager.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Ins/ISenderManager.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Ovln/IReceiverService.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Ovln/ISenderService.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Psc/IPmControl.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Psc/IPmService.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Psc/IPmStateLock.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Srepo/ISrepoService.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Usb/IClientRootSession.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Usb/IDsRootSession.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Usb/IPdCradleManager.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Usb/IPdManager.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Usb/IPdManufactureManager.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Usb/IPmObserverService.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Usb/IPmService.cs
 create mode 100644 src/Ryujinx.Horizon/Sdk/Usb/IQdbManager.cs
 create mode 100644 src/Ryujinx.Horizon/Srepo/Ipc/SrepoService.cs
 create mode 100644 src/Ryujinx.Horizon/Srepo/SrepoIpcServer.cs
 create mode 100644 src/Ryujinx.Horizon/Srepo/SrepoMain.cs
 create mode 100644 src/Ryujinx.Horizon/Usb/Ipc/ClientRootSession.cs
 create mode 100644 src/Ryujinx.Horizon/Usb/Ipc/DsRootSession.cs
 create mode 100644 src/Ryujinx.Horizon/Usb/Ipc/PdCradleManager.cs
 create mode 100644 src/Ryujinx.Horizon/Usb/Ipc/PdManager.cs
 create mode 100644 src/Ryujinx.Horizon/Usb/Ipc/PdManufactureManager.cs
 create mode 100644 src/Ryujinx.Horizon/Usb/Ipc/PmObserverService.cs
 create mode 100644 src/Ryujinx.Horizon/Usb/Ipc/PmService.cs
 create mode 100644 src/Ryujinx.Horizon/Usb/Ipc/QdbManager.cs
 create mode 100644 src/Ryujinx.Horizon/Usb/UsbIpcServer.cs
 create mode 100644 src/Ryujinx.Horizon/Usb/UsbMain.cs

(limited to 'src')

diff --git a/src/Ryujinx.HLE/HOS/Services/Ins/IReceiverManager.cs b/src/Ryujinx.HLE/HOS/Services/Ins/IReceiverManager.cs
deleted file mode 100644
index 8ee00d0e..00000000
--- a/src/Ryujinx.HLE/HOS/Services/Ins/IReceiverManager.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Ins
-{
-    [Service("ins:r")]
-    class IReceiverManager : IpcService
-    {
-        public IReceiverManager(ServiceCtx context) { }
-    }
-}
diff --git a/src/Ryujinx.HLE/HOS/Services/Ins/ISenderManager.cs b/src/Ryujinx.HLE/HOS/Services/Ins/ISenderManager.cs
deleted file mode 100644
index 239c4cc8..00000000
--- a/src/Ryujinx.HLE/HOS/Services/Ins/ISenderManager.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Ins
-{
-    [Service("ins:s")]
-    class ISenderManager : IpcService
-    {
-        public ISenderManager(ServiceCtx context) { }
-    }
-}
diff --git a/src/Ryujinx.HLE/HOS/Services/Ovln/IReceiverService.cs b/src/Ryujinx.HLE/HOS/Services/Ovln/IReceiverService.cs
deleted file mode 100644
index 99e929a7..00000000
--- a/src/Ryujinx.HLE/HOS/Services/Ovln/IReceiverService.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Ovln
-{
-    [Service("ovln:rcv")]
-    class IReceiverService : IpcService
-    {
-        public IReceiverService(ServiceCtx context) { }
-    }
-}
diff --git a/src/Ryujinx.HLE/HOS/Services/Ovln/ISenderService.cs b/src/Ryujinx.HLE/HOS/Services/Ovln/ISenderService.cs
deleted file mode 100644
index e445c16c..00000000
--- a/src/Ryujinx.HLE/HOS/Services/Ovln/ISenderService.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Ovln
-{
-    [Service("ovln:snd")]
-    class ISenderService : IpcService
-    {
-        public ISenderService(ServiceCtx context) { }
-    }
-}
diff --git a/src/Ryujinx.HLE/HOS/Services/Psc/IPmControl.cs b/src/Ryujinx.HLE/HOS/Services/Psc/IPmControl.cs
deleted file mode 100644
index 6682a848..00000000
--- a/src/Ryujinx.HLE/HOS/Services/Psc/IPmControl.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Psc
-{
-    [Service("psc:c")]
-    class IPmControl : IpcService
-    {
-        public IPmControl(ServiceCtx context) { }
-    }
-}
diff --git a/src/Ryujinx.HLE/HOS/Services/Psc/IPmService.cs b/src/Ryujinx.HLE/HOS/Services/Psc/IPmService.cs
deleted file mode 100644
index 1be33866..00000000
--- a/src/Ryujinx.HLE/HOS/Services/Psc/IPmService.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Psc
-{
-    [Service("psc:m")]
-    class IPmService : IpcService
-    {
-        public IPmService(ServiceCtx context) { }
-    }
-}
diff --git a/src/Ryujinx.HLE/HOS/Services/Psc/IPmUnknown.cs b/src/Ryujinx.HLE/HOS/Services/Psc/IPmUnknown.cs
deleted file mode 100644
index 95aff9ec..00000000
--- a/src/Ryujinx.HLE/HOS/Services/Psc/IPmUnknown.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Psc
-{
-    [Service("psc:l")] // 9.0.0+
-    class IPmUnknown : IpcService
-    {
-        public IPmUnknown(ServiceCtx context) { }
-    }
-}
diff --git a/src/Ryujinx.HLE/HOS/Services/Srepo/ISrepoService.cs b/src/Ryujinx.HLE/HOS/Services/Srepo/ISrepoService.cs
deleted file mode 100644
index f5467983..00000000
--- a/src/Ryujinx.HLE/HOS/Services/Srepo/ISrepoService.cs
+++ /dev/null
@@ -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) { }
-    }
-}
diff --git a/src/Ryujinx.HLE/HOS/Services/Usb/IClientRootSession.cs b/src/Ryujinx.HLE/HOS/Services/Usb/IClientRootSession.cs
deleted file mode 100644
index b41b8a48..00000000
--- a/src/Ryujinx.HLE/HOS/Services/Usb/IClientRootSession.cs
+++ /dev/null
@@ -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) { }
-    }
-}
diff --git a/src/Ryujinx.HLE/HOS/Services/Usb/IDsService.cs b/src/Ryujinx.HLE/HOS/Services/Usb/IDsService.cs
deleted file mode 100644
index ee6c8f07..00000000
--- a/src/Ryujinx.HLE/HOS/Services/Usb/IDsService.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Usb
-{
-    [Service("usb:ds")]
-    class IDsService : IpcService
-    {
-        public IDsService(ServiceCtx context) { }
-    }
-}
diff --git a/src/Ryujinx.HLE/HOS/Services/Usb/IPdCradleManager.cs b/src/Ryujinx.HLE/HOS/Services/Usb/IPdCradleManager.cs
deleted file mode 100644
index 18cbce79..00000000
--- a/src/Ryujinx.HLE/HOS/Services/Usb/IPdCradleManager.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Usb
-{
-    [Service("usb:pd:c")]
-    class IPdCradleManager : IpcService
-    {
-        public IPdCradleManager(ServiceCtx context) { }
-    }
-}
diff --git a/src/Ryujinx.HLE/HOS/Services/Usb/IPdManager.cs b/src/Ryujinx.HLE/HOS/Services/Usb/IPdManager.cs
deleted file mode 100644
index 011debaf..00000000
--- a/src/Ryujinx.HLE/HOS/Services/Usb/IPdManager.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Usb
-{
-    [Service("usb:pd")]
-    class IPdManager : IpcService
-    {
-        public IPdManager(ServiceCtx context) { }
-    }
-}
diff --git a/src/Ryujinx.HLE/HOS/Services/Usb/IPmService.cs b/src/Ryujinx.HLE/HOS/Services/Usb/IPmService.cs
deleted file mode 100644
index ed6bba69..00000000
--- a/src/Ryujinx.HLE/HOS/Services/Usb/IPmService.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Usb
-{
-    [Service("usb:pm")]
-    class IPmService : IpcService
-    {
-        public IPmService(ServiceCtx context) { }
-    }
-}
diff --git a/src/Ryujinx.HLE/HOS/Services/Usb/IUnknown1.cs b/src/Ryujinx.HLE/HOS/Services/Usb/IUnknown1.cs
deleted file mode 100644
index 65bf1c9f..00000000
--- a/src/Ryujinx.HLE/HOS/Services/Usb/IUnknown1.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Usb
-{
-    [Service("usb:qdb")] // 7.0.0+
-    class IUnknown1 : IpcService
-    {
-        public IUnknown1(ServiceCtx context) { }
-    }
-}
diff --git a/src/Ryujinx.HLE/HOS/Services/Usb/IUnknown2.cs b/src/Ryujinx.HLE/HOS/Services/Usb/IUnknown2.cs
deleted file mode 100644
index e0bf0bf4..00000000
--- a/src/Ryujinx.HLE/HOS/Services/Usb/IUnknown2.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Usb
-{
-    [Service("usb:obsv")] // 8.0.0+
-    class IUnknown2 : IpcService
-    {
-        public IUnknown2(ServiceCtx context) { }
-    }
-}
diff --git a/src/Ryujinx.Horizon.Generators/Hipc/HipcGenerator.cs b/src/Ryujinx.Horizon.Generators/Hipc/HipcGenerator.cs
index 1b92e918..4e14f47e 100644
--- a/src/Ryujinx.Horizon.Generators/Hipc/HipcGenerator.cs
+++ b/src/Ryujinx.Horizon.Generators/Hipc/HipcGenerator.cs
@@ -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());
             }
         }
 
diff --git a/src/Ryujinx.Horizon/Hshl/HshlIpcServer.cs b/src/Ryujinx.Horizon/Hshl/HshlIpcServer.cs
new file mode 100644
index 00000000..7182725c
--- /dev/null
+++ b/src/Ryujinx.Horizon/Hshl/HshlIpcServer.cs
@@ -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();
+        }
+    }
+}
diff --git a/src/Ryujinx.Horizon/Hshl/HshlMain.cs b/src/Ryujinx.Horizon/Hshl/HshlMain.cs
new file mode 100644
index 00000000..4e894b6f
--- /dev/null
+++ b/src/Ryujinx.Horizon/Hshl/HshlMain.cs
@@ -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();
+        }
+    }
+}
diff --git a/src/Ryujinx.Horizon/Hshl/Ipc/Manager.cs b/src/Ryujinx.Horizon/Hshl/Ipc/Manager.cs
new file mode 100644
index 00000000..29d9069a
--- /dev/null
+++ b/src/Ryujinx.Horizon/Hshl/Ipc/Manager.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Hshl;
+
+namespace Ryujinx.Horizon.Hshl.Ipc
+{
+    partial class Manager : IManager
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Hshl/Ipc/SetterManager.cs b/src/Ryujinx.Horizon/Hshl/Ipc/SetterManager.cs
new file mode 100644
index 00000000..ac1006f0
--- /dev/null
+++ b/src/Ryujinx.Horizon/Hshl/Ipc/SetterManager.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Hshl;
+
+namespace Ryujinx.Horizon.Hshl.Ipc
+{
+    partial class SetterManager : ISetterManager
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Ins/InsIpcServer.cs b/src/Ryujinx.Horizon/Ins/InsIpcServer.cs
new file mode 100644
index 00000000..68698bf6
--- /dev/null
+++ b/src/Ryujinx.Horizon/Ins/InsIpcServer.cs
@@ -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();
+        }
+    }
+}
diff --git a/src/Ryujinx.Horizon/Ins/InsMain.cs b/src/Ryujinx.Horizon/Ins/InsMain.cs
new file mode 100644
index 00000000..e428d090
--- /dev/null
+++ b/src/Ryujinx.Horizon/Ins/InsMain.cs
@@ -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();
+        }
+    }
+}
diff --git a/src/Ryujinx.Horizon/Ins/Ipc/ReceiverManager.cs b/src/Ryujinx.Horizon/Ins/Ipc/ReceiverManager.cs
new file mode 100644
index 00000000..6e9b29a9
--- /dev/null
+++ b/src/Ryujinx.Horizon/Ins/Ipc/ReceiverManager.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Ins;
+
+namespace Ryujinx.Horizon.Ins.Ipc
+{
+    partial class ReceiverManager : IReceiverManager
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Ins/Ipc/SenderManager.cs b/src/Ryujinx.Horizon/Ins/Ipc/SenderManager.cs
new file mode 100644
index 00000000..e133014e
--- /dev/null
+++ b/src/Ryujinx.Horizon/Ins/Ipc/SenderManager.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Ins;
+
+namespace Ryujinx.Horizon.Ins.Ipc
+{
+    partial class SenderManager : ISenderManager
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Ovln/Ipc/ReceiverService.cs b/src/Ryujinx.Horizon/Ovln/Ipc/ReceiverService.cs
new file mode 100644
index 00000000..6cc448e8
--- /dev/null
+++ b/src/Ryujinx.Horizon/Ovln/Ipc/ReceiverService.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Ovln;
+
+namespace Ryujinx.Horizon.Ovln.Ipc
+{
+    partial class ReceiverService : IReceiverService
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Ovln/Ipc/SenderService.cs b/src/Ryujinx.Horizon/Ovln/Ipc/SenderService.cs
new file mode 100644
index 00000000..cab123ec
--- /dev/null
+++ b/src/Ryujinx.Horizon/Ovln/Ipc/SenderService.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Ovln;
+
+namespace Ryujinx.Horizon.Ovln.Ipc
+{
+    partial class SenderService : ISenderService
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Ovln/OvlnIpcServer.cs b/src/Ryujinx.Horizon/Ovln/OvlnIpcServer.cs
new file mode 100644
index 00000000..2c00107f
--- /dev/null
+++ b/src/Ryujinx.Horizon/Ovln/OvlnIpcServer.cs
@@ -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();
+        }
+    }
+}
diff --git a/src/Ryujinx.Horizon/Ovln/OvlnMain.cs b/src/Ryujinx.Horizon/Ovln/OvlnMain.cs
new file mode 100644
index 00000000..8c6cf84e
--- /dev/null
+++ b/src/Ryujinx.Horizon/Ovln/OvlnMain.cs
@@ -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();
+        }
+    }
+}
diff --git a/src/Ryujinx.Horizon/Psc/Ipc/PmControl.cs b/src/Ryujinx.Horizon/Psc/Ipc/PmControl.cs
new file mode 100644
index 00000000..671472e4
--- /dev/null
+++ b/src/Ryujinx.Horizon/Psc/Ipc/PmControl.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Psc;
+
+namespace Ryujinx.Horizon.Psc.Ipc
+{
+    partial class PmControl : IPmControl
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Psc/Ipc/PmService.cs b/src/Ryujinx.Horizon/Psc/Ipc/PmService.cs
new file mode 100644
index 00000000..c38da858
--- /dev/null
+++ b/src/Ryujinx.Horizon/Psc/Ipc/PmService.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Psc;
+
+namespace Ryujinx.Horizon.Psc.Ipc
+{
+    partial class PmService : IPmService
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Psc/Ipc/PmStateLock.cs b/src/Ryujinx.Horizon/Psc/Ipc/PmStateLock.cs
new file mode 100644
index 00000000..cef68ac5
--- /dev/null
+++ b/src/Ryujinx.Horizon/Psc/Ipc/PmStateLock.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Psc;
+
+namespace Ryujinx.Horizon.Psc.Ipc
+{
+    partial class PmStateLock : IPmStateLock
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Psc/PscIpcServer.cs b/src/Ryujinx.Horizon/Psc/PscIpcServer.cs
new file mode 100644
index 00000000..f8da5672
--- /dev/null
+++ b/src/Ryujinx.Horizon/Psc/PscIpcServer.cs
@@ -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();
+        }
+    }
+}
diff --git a/src/Ryujinx.Horizon/Psc/PscMain.cs b/src/Ryujinx.Horizon/Psc/PscMain.cs
new file mode 100644
index 00000000..facb6bc0
--- /dev/null
+++ b/src/Ryujinx.Horizon/Psc/PscMain.cs
@@ -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();
+        }
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Hshl/IManager.cs b/src/Ryujinx.Horizon/Sdk/Hshl/IManager.cs
new file mode 100644
index 00000000..13955c69
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Hshl/IManager.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Hshl
+{
+    interface IManager : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Hshl/ISetterManager.cs b/src/Ryujinx.Horizon/Sdk/Hshl/ISetterManager.cs
new file mode 100644
index 00000000..8a4b93dd
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Hshl/ISetterManager.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Hshl
+{
+    interface ISetterManager : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Ins/IReceiverManager.cs b/src/Ryujinx.Horizon/Sdk/Ins/IReceiverManager.cs
new file mode 100644
index 00000000..28fc757e
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Ins/IReceiverManager.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Ins
+{
+    interface IReceiverManager : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Ins/ISenderManager.cs b/src/Ryujinx.Horizon/Sdk/Ins/ISenderManager.cs
new file mode 100644
index 00000000..878dbfb3
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Ins/ISenderManager.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Ins
+{
+    interface ISenderManager : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Ovln/IReceiverService.cs b/src/Ryujinx.Horizon/Sdk/Ovln/IReceiverService.cs
new file mode 100644
index 00000000..f59e8002
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Ovln/IReceiverService.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Ovln
+{
+    interface IReceiverService : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Ovln/ISenderService.cs b/src/Ryujinx.Horizon/Sdk/Ovln/ISenderService.cs
new file mode 100644
index 00000000..93323ba5
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Ovln/ISenderService.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Ovln
+{
+    interface ISenderService : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Psc/IPmControl.cs b/src/Ryujinx.Horizon/Sdk/Psc/IPmControl.cs
new file mode 100644
index 00000000..6a71d684
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Psc/IPmControl.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Psc
+{
+    interface IPmControl : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Psc/IPmService.cs b/src/Ryujinx.Horizon/Sdk/Psc/IPmService.cs
new file mode 100644
index 00000000..c5866581
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Psc/IPmService.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Psc
+{
+    interface IPmService : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Psc/IPmStateLock.cs b/src/Ryujinx.Horizon/Sdk/Psc/IPmStateLock.cs
new file mode 100644
index 00000000..41ead492
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Psc/IPmStateLock.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Psc
+{
+    interface IPmStateLock : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Srepo/ISrepoService.cs b/src/Ryujinx.Horizon/Sdk/Srepo/ISrepoService.cs
new file mode 100644
index 00000000..9a1f4ba4
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Srepo/ISrepoService.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Srepo
+{
+    interface ISrepoService : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IClientRootSession.cs b/src/Ryujinx.Horizon/Sdk/Usb/IClientRootSession.cs
new file mode 100644
index 00000000..4975ad6b
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Usb/IClientRootSession.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Usb
+{
+    interface IClientRootSession : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IDsRootSession.cs b/src/Ryujinx.Horizon/Sdk/Usb/IDsRootSession.cs
new file mode 100644
index 00000000..32d7aba6
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Usb/IDsRootSession.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Usb
+{
+    interface IDsRootSession : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IPdCradleManager.cs b/src/Ryujinx.Horizon/Sdk/Usb/IPdCradleManager.cs
new file mode 100644
index 00000000..0d386511
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Usb/IPdCradleManager.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Usb
+{
+    interface IPdCradleManager : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IPdManager.cs b/src/Ryujinx.Horizon/Sdk/Usb/IPdManager.cs
new file mode 100644
index 00000000..d6382151
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Usb/IPdManager.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Usb
+{
+    interface IPdManager : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IPdManufactureManager.cs b/src/Ryujinx.Horizon/Sdk/Usb/IPdManufactureManager.cs
new file mode 100644
index 00000000..18bac3ea
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Usb/IPdManufactureManager.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Usb
+{
+    interface IPdManufactureManager : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IPmObserverService.cs b/src/Ryujinx.Horizon/Sdk/Usb/IPmObserverService.cs
new file mode 100644
index 00000000..ef4cc65a
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Usb/IPmObserverService.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Usb
+{
+    interface IPmObserverService : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IPmService.cs b/src/Ryujinx.Horizon/Sdk/Usb/IPmService.cs
new file mode 100644
index 00000000..b8d177bd
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Usb/IPmService.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Usb
+{
+    interface IPmService : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Sdk/Usb/IQdbManager.cs b/src/Ryujinx.Horizon/Sdk/Usb/IQdbManager.cs
new file mode 100644
index 00000000..a8f61f05
--- /dev/null
+++ b/src/Ryujinx.Horizon/Sdk/Usb/IQdbManager.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Sf;
+
+namespace Ryujinx.Horizon.Sdk.Usb
+{
+    interface IQdbManager : IServiceObject
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/ServiceTable.cs b/src/Ryujinx.Horizon/ServiceTable.cs
index 41da222a..c79328a9 100644
--- a/src/Ryujinx.Horizon/ServiceTable.cs
+++ b/src/Ryujinx.Horizon/ServiceTable.cs
@@ -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<NgcMain>();
+            RegisterService<OvlnMain>();
             RegisterService<PrepoMain>();
+            RegisterService<PscMain>();
+            RegisterService<SrepoMain>();
+            RegisterService<UsbMain>();
             RegisterService<WlanMain>();
-            RegisterService<NgcMain>();
 
             _totalServices = entries.Count;
 
diff --git a/src/Ryujinx.Horizon/Srepo/Ipc/SrepoService.cs b/src/Ryujinx.Horizon/Srepo/Ipc/SrepoService.cs
new file mode 100644
index 00000000..501eb5fe
--- /dev/null
+++ b/src/Ryujinx.Horizon/Srepo/Ipc/SrepoService.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Srepo;
+
+namespace Ryujinx.Horizon.Srepo.Ipc
+{
+    partial class SrepoService : ISrepoService
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Srepo/SrepoIpcServer.cs b/src/Ryujinx.Horizon/Srepo/SrepoIpcServer.cs
new file mode 100644
index 00000000..a971f97b
--- /dev/null
+++ b/src/Ryujinx.Horizon/Srepo/SrepoIpcServer.cs
@@ -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();
+        }
+    }
+}
diff --git a/src/Ryujinx.Horizon/Srepo/SrepoMain.cs b/src/Ryujinx.Horizon/Srepo/SrepoMain.cs
new file mode 100644
index 00000000..78d813ac
--- /dev/null
+++ b/src/Ryujinx.Horizon/Srepo/SrepoMain.cs
@@ -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();
+        }
+    }
+}
diff --git a/src/Ryujinx.Horizon/Usb/Ipc/ClientRootSession.cs b/src/Ryujinx.Horizon/Usb/Ipc/ClientRootSession.cs
new file mode 100644
index 00000000..2167ebca
--- /dev/null
+++ b/src/Ryujinx.Horizon/Usb/Ipc/ClientRootSession.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Usb;
+
+namespace Ryujinx.Horizon.Usb.Ipc
+{
+    partial class ClientRootSession : IClientRootSession
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Usb/Ipc/DsRootSession.cs b/src/Ryujinx.Horizon/Usb/Ipc/DsRootSession.cs
new file mode 100644
index 00000000..8a84537f
--- /dev/null
+++ b/src/Ryujinx.Horizon/Usb/Ipc/DsRootSession.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Usb;
+
+namespace Ryujinx.Horizon.Usb.Ipc
+{
+    partial class DsRootSession : IDsRootSession
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Usb/Ipc/PdCradleManager.cs b/src/Ryujinx.Horizon/Usb/Ipc/PdCradleManager.cs
new file mode 100644
index 00000000..27e1c4e3
--- /dev/null
+++ b/src/Ryujinx.Horizon/Usb/Ipc/PdCradleManager.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Usb;
+
+namespace Ryujinx.Horizon.Usb.Ipc
+{
+    partial class PdCradleManager : IPdCradleManager
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Usb/Ipc/PdManager.cs b/src/Ryujinx.Horizon/Usb/Ipc/PdManager.cs
new file mode 100644
index 00000000..c501e3f2
--- /dev/null
+++ b/src/Ryujinx.Horizon/Usb/Ipc/PdManager.cs
@@ -0,0 +1,9 @@
+using Ryujinx.Horizon.Sdk.Sf.Hipc;
+using Ryujinx.Horizon.Sdk.Usb;
+
+namespace Ryujinx.Horizon.Usb.Ipc
+{
+    partial class PdManager : IPdManager
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Usb/Ipc/PdManufactureManager.cs b/src/Ryujinx.Horizon/Usb/Ipc/PdManufactureManager.cs
new file mode 100644
index 00000000..04f78b9c
--- /dev/null
+++ b/src/Ryujinx.Horizon/Usb/Ipc/PdManufactureManager.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Usb;
+
+namespace Ryujinx.Horizon.Usb.Ipc
+{
+    partial class PdManufactureManager : IPdManufactureManager
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Usb/Ipc/PmObserverService.cs b/src/Ryujinx.Horizon/Usb/Ipc/PmObserverService.cs
new file mode 100644
index 00000000..e2edf4cb
--- /dev/null
+++ b/src/Ryujinx.Horizon/Usb/Ipc/PmObserverService.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Usb;
+
+namespace Ryujinx.Horizon.Usb.Ipc
+{
+    partial class PmObserverService : IPmObserverService
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Usb/Ipc/PmService.cs b/src/Ryujinx.Horizon/Usb/Ipc/PmService.cs
new file mode 100644
index 00000000..625aaa49
--- /dev/null
+++ b/src/Ryujinx.Horizon/Usb/Ipc/PmService.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Usb;
+
+namespace Ryujinx.Horizon.Usb.Ipc
+{
+    partial class PmService : IPmService
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Usb/Ipc/QdbManager.cs b/src/Ryujinx.Horizon/Usb/Ipc/QdbManager.cs
new file mode 100644
index 00000000..1421142f
--- /dev/null
+++ b/src/Ryujinx.Horizon/Usb/Ipc/QdbManager.cs
@@ -0,0 +1,8 @@
+using Ryujinx.Horizon.Sdk.Usb;
+
+namespace Ryujinx.Horizon.Usb.Ipc
+{
+    partial class QdbManager : IQdbManager
+    {
+    }
+}
diff --git a/src/Ryujinx.Horizon/Usb/UsbIpcServer.cs b/src/Ryujinx.Horizon/Usb/UsbIpcServer.cs
new file mode 100644
index 00000000..a9158b50
--- /dev/null
+++ b/src/Ryujinx.Horizon/Usb/UsbIpcServer.cs
@@ -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();
+        }
+    }
+}
diff --git a/src/Ryujinx.Horizon/Usb/UsbMain.cs b/src/Ryujinx.Horizon/Usb/UsbMain.cs
new file mode 100644
index 00000000..c54b39a6
--- /dev/null
+++ b/src/Ryujinx.Horizon/Usb/UsbMain.cs
@@ -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();
+        }
+    }
+}
-- 
cgit v1.2.3-70-g09d2