From 479d1fd8b03528b7bbfdd38925475dce54a79f58 Mon Sep 17 00:00:00 2001
From: Mary-nyan <mary@mary.zone>
Date: Wed, 21 Dec 2022 19:23:11 +0100
Subject: [PATCH] hle: Handle GPU profiler and debugger device path correctly
 (#4138)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This fix a warning on "慟哭そして…" by handling correctly the debug mode
flag.

When debug mode isn't enabled, opening /dev/nvhost-dbg-gpu or /dev/nvhost-prof-gpu should fail with a not implemented error code.

This implement this behaviour and also define stubbed interfaces for
completness.
---
 Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs | 43 +++++++++++++------
 .../NvHostDbgGpu/NvHostDbgGpuDeviceFile.cs    | 11 +++++
 .../NvHostProfGpu/NvHostProfGpuDeviceFile.cs  | 11 +++++
 Ryujinx.HLE/Ryujinx.HLE.csproj                |  4 +-
 4 files changed, 52 insertions(+), 17 deletions(-)
 create mode 100644 Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostDbgGpu/NvHostDbgGpuDeviceFile.cs
 create mode 100644 Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostProfGpu/NvHostProfGpuDeviceFile.cs

diff --git a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs
index 9a1842268..32b429a6c 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs
@@ -8,6 +8,8 @@ using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu;
 using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel;
 using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl;
 using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu;
+using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostDbgGpu;
+using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostProfGpu;
 using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap;
 using Ryujinx.HLE.HOS.Services.Nv.Types;
 using Ryujinx.Memory;
@@ -23,7 +25,13 @@ namespace Ryujinx.HLE.HOS.Services.Nv
     [Service("nvdrv:t")]
     class INvDrvServices : IpcService
     {
-        private static Dictionary<string, Type> _deviceFileRegistry = new Dictionary<string, Type>()
+        private static readonly List<string> _deviceFileDebugRegistry = new List<string>()
+        {
+            "/dev/nvhost-dbg-gpu",
+            "/dev/nvhost-prof-gpu"
+        };
+
+        private static readonly Dictionary<string, Type> _deviceFileRegistry = new Dictionary<string, Type>()
         {
             { "/dev/nvmap",           typeof(NvMapDeviceFile)         },
             { "/dev/nvhost-ctrl",     typeof(NvHostCtrlDeviceFile)    },
@@ -35,6 +43,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv
             //{ "/dev/nvhost-nvjpg",    typeof(NvHostChannelDeviceFile) },
             { "/dev/nvhost-vic",      typeof(NvHostChannelDeviceFile) },
             //{ "/dev/nvhost-display",  typeof(NvHostChannelDeviceFile) },
+            { "/dev/nvhost-dbg-gpu",  typeof(NvHostDbgGpuDeviceFile)  },
+            { "/dev/nvhost-prof-gpu", typeof(NvHostProfGpuDeviceFile) },
         };
 
         public static IdDictionary DeviceFileIdRegistry = new IdDictionary();
@@ -44,13 +54,23 @@ namespace Ryujinx.HLE.HOS.Services.Nv
 
         private bool _transferMemInitialized = false;
 
+        // TODO: This should call set:sys::GetDebugModeFlag
+        private bool _debugModeEnabled = false;
+
         public INvDrvServices(ServiceCtx context) : base(context.Device.System.NvDrvServer)
         {
             _owner = 0;
         }
 
-        private int Open(ServiceCtx context, string path)
+        private NvResult Open(ServiceCtx context, string path, out int fd)
         {
+            fd = -1;
+
+            if (!_debugModeEnabled && _deviceFileDebugRegistry.Contains(path))
+            {
+                return NvResult.NotSupported;
+            }
+
             if (_deviceFileRegistry.TryGetValue(path, out Type deviceFileClass))
             {
                 ConstructorInfo constructor = deviceFileClass.GetConstructor(new Type[] { typeof(ServiceCtx), typeof(IVirtualMemoryManager), typeof(ulong) });
@@ -59,14 +79,14 @@ namespace Ryujinx.HLE.HOS.Services.Nv
 
                 deviceFile.Path = path;
 
-                return DeviceFileIdRegistry.Add(deviceFile);
-            }
-            else
-            {
-                Logger.Warning?.Print(LogClass.ServiceNv, $"Cannot find file device \"{path}\"!");
+                fd = DeviceFileIdRegistry.Add(deviceFile);
+
+                return NvResult.Success;
             }
 
-            return -1;
+            Logger.Warning?.Print(LogClass.ServiceNv, $"Cannot find file device \"{path}\"!");
+
+            return NvResult.FileOperationFailed;
         }
 
         private NvResult GetIoctlArgument(ServiceCtx context, NvIoctl ioctlCommand, out Span<byte> arguments)
@@ -229,12 +249,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv
 
                 string path = MemoryHelper.ReadAsciiString(context.Memory, pathPtr, (long)pathSize);
 
-                fd = Open(context, path);
-
-                if (fd == -1)
-                {
-                    errorCode = NvResult.FileOperationFailed;
-                }
+                errorCode = Open(context, path, out fd);
             }
 
             context.ResponseData.Write(fd);
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostDbgGpu/NvHostDbgGpuDeviceFile.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostDbgGpu/NvHostDbgGpuDeviceFile.cs
new file mode 100644
index 000000000..fe302b98e
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostDbgGpu/NvHostDbgGpuDeviceFile.cs
@@ -0,0 +1,11 @@
+using Ryujinx.Memory;
+using System;
+namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostDbgGpu
+{
+    class NvHostDbgGpuDeviceFile : NvDeviceFile
+    {
+        public NvHostDbgGpuDeviceFile(ServiceCtx context, IVirtualMemoryManager memory, ulong owner) : base(context, owner) { }
+
+        public override void Close() { }
+    }
+}
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostProfGpu/NvHostProfGpuDeviceFile.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostProfGpu/NvHostProfGpuDeviceFile.cs
new file mode 100644
index 000000000..0a2087edc
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostProfGpu/NvHostProfGpuDeviceFile.cs
@@ -0,0 +1,11 @@
+using Ryujinx.Memory;
+
+namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostProfGpu
+{
+    class NvHostProfGpuDeviceFile : NvDeviceFile
+    {
+        public NvHostProfGpuDeviceFile(ServiceCtx context, IVirtualMemoryManager memory, ulong owner) : base(context, owner) { }
+
+        public override void Close() { }
+    }
+}
diff --git a/Ryujinx.HLE/Ryujinx.HLE.csproj b/Ryujinx.HLE/Ryujinx.HLE.csproj
index 1e814ca98..f1f295a27 100644
--- a/Ryujinx.HLE/Ryujinx.HLE.csproj
+++ b/Ryujinx.HLE/Ryujinx.HLE.csproj
@@ -11,9 +11,7 @@
     <ProjectReference Include="..\Ryujinx.Graphics.Host1x\Ryujinx.Graphics.Host1x.csproj" />
     <ProjectReference Include="..\Ryujinx.Graphics.Nvdec\Ryujinx.Graphics.Nvdec.csproj" />
     <ProjectReference Include="..\Ryujinx.Graphics.Vic\Ryujinx.Graphics.Vic.csproj" />
-    <ProjectReference Include="..\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj"
-                      OutputItemType="Analyzer"
-                      ReferenceOutputAssembly="false" />
+    <ProjectReference Include="..\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
     <ProjectReference Include="..\Ryujinx.Memory\Ryujinx.Memory.csproj" />
     <ProjectReference Include="..\ARMeilleure\ARMeilleure.csproj" />
     <ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />