Просмотр исходного кода

NvGetConfig with production/non production swapping (#243)

* GetConfig should return 0x30006 in production mode

* GetConfig will now check settings only if nv!rmos_set_production_mode is set to "0"

* Code formatting, TryGetValue

* Slight fixup

* dont forget the setting

* Implemented non production mode setting grabbing

* format issue

* style changes
David 7 лет назад
Родитель
Сommit
37071285bc

+ 51 - 8
Ryujinx.HLE/OsHle/Services/Nv/NvHostCtrl/NvHostCtrlIoctl.cs

@@ -2,6 +2,7 @@ using ChocolArm64.Memory;
 using Ryujinx.HLE.Logging;
 using System;
 using System.Collections.Concurrent;
+using System.Text;
 using System.Threading;
 
 namespace Ryujinx.HLE.OsHle.Services.Nv.NvHostCtrl
@@ -10,9 +11,16 @@ namespace Ryujinx.HLE.OsHle.Services.Nv.NvHostCtrl
     {
         private static ConcurrentDictionary<Process, NvHostCtrlUserCtx> UserCtxs;
 
+        private static bool IsProductionMode = true;
+
         static NvHostCtrlIoctl()
         {
             UserCtxs = new ConcurrentDictionary<Process, NvHostCtrlUserCtx>();
+
+            if (Set.NxSettings.Settings.TryGetValue("nv!rmos_set_production_mode", out object ProductionModeSetting))
+            {
+                IsProductionMode = ((string)ProductionModeSetting) != "0"; // Default value is ""
+            }
         }
 
         public static int ProcessIoctl(ServiceCtx Context, int Cmd)
@@ -71,17 +79,52 @@ namespace Ryujinx.HLE.OsHle.Services.Nv.NvHostCtrl
 
         private static int GetConfig(ServiceCtx Context)
         {
-            long InputPosition  = Context.Request.GetBufferType0x21().Position;
-            long OutputPosition = Context.Request.GetBufferType0x22().Position;
+            if (!IsProductionMode)
+            {
+                long InputPosition  = Context.Request.GetBufferType0x21().Position;
+                long OutputPosition = Context.Request.GetBufferType0x22().Position;
 
-            string Nv   = AMemoryHelper.ReadAsciiString(Context.Memory, InputPosition + 0,    0x41);
-            string Name = AMemoryHelper.ReadAsciiString(Context.Memory, InputPosition + 0x41, 0x41);
+                string Domain = AMemoryHelper.ReadAsciiString(Context.Memory, InputPosition + 0, 0x41);
+                string Name   = AMemoryHelper.ReadAsciiString(Context.Memory, InputPosition + 0x41, 0x41);
 
-            Context.Memory.WriteByte(OutputPosition + 0x82, 0);
+                if (Set.NxSettings.Settings.TryGetValue($"{Domain}!{Name}", out object NvSetting))
+                {
+                    byte[] SettingBuffer = new byte[0x101];
 
-            Context.Ns.Log.PrintStub(LogClass.ServiceNv, "Stubbed.");
+                    if (NvSetting is string StringValue)
+                    {
+                        if (StringValue.Length > 0x100)
+                        {
+                            Context.Ns.Log.PrintError(Logging.LogClass.ServiceNv, $"{Domain}!{Name} String value size is too big!");
+                        }
+                        else
+                        {
+                            SettingBuffer = Encoding.ASCII.GetBytes(StringValue + "\0");
+                        }
+                    }
 
-            return NvResult.Success;
+                    if (NvSetting is int IntValue)
+                    {
+                        SettingBuffer = BitConverter.GetBytes(IntValue);
+                    }
+                    else if (NvSetting is bool BoolValue)
+                    {
+                        SettingBuffer[0] = BoolValue ? (byte)1 : (byte)0;
+                    }
+                    else
+                    {
+                        throw new NotImplementedException(NvSetting.GetType().Name);
+                    }
+
+                    Context.Memory.WriteBytes(OutputPosition + 0x82, SettingBuffer);
+
+                    Context.Ns.Log.PrintDebug(Logging.LogClass.ServiceNv, $"Got setting {Domain}!{Name}");
+                }
+                
+                return NvResult.Success;
+            }
+
+            return NvResult.NotAvailableInProduction;
         }
 
         private static int EventWait(ServiceCtx Context)
@@ -352,4 +395,4 @@ namespace Ryujinx.HLE.OsHle.Services.Nv.NvHostCtrl
             UserCtxs.TryRemove(Process, out _);
         }
     }
-}
+}

+ 9 - 8
Ryujinx.HLE/OsHle/Services/Nv/NvResult.cs

@@ -2,12 +2,13 @@ namespace Ryujinx.HLE.OsHle.Services.Nv
 {
     static class NvResult
     {
-        public const int Success      = 0;
-        public const int TryAgain     = -11;
-        public const int OutOfMemory  = -12;
-        public const int InvalidInput = -22;
-        public const int NotSupported = -25;
-        public const int Restart      = -85;
-        public const int TimedOut     = -110;
+        public const int NotAvailableInProduction = 196614;
+        public const int Success                  = 0;
+        public const int TryAgain                 = -11;
+        public const int OutOfMemory              = -12;
+        public const int InvalidInput             = -22;
+        public const int NotSupported             = -25;
+        public const int Restart                  = -85;
+        public const int TimedOut                 = -110;
     }
-}
+}