0
0
Fork 0

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
This commit is contained in:
David 2018-07-12 11:41:35 +10:00 committed by Ac_K
parent 09c53fe06f
commit 37071285bc
2 changed files with 60 additions and 16 deletions

View file

@ -2,6 +2,7 @@ using ChocolArm64.Memory;
using Ryujinx.HLE.Logging; using Ryujinx.HLE.Logging;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Text;
using System.Threading; using System.Threading;
namespace Ryujinx.HLE.OsHle.Services.Nv.NvHostCtrl 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 ConcurrentDictionary<Process, NvHostCtrlUserCtx> UserCtxs;
private static bool IsProductionMode = true;
static NvHostCtrlIoctl() static NvHostCtrlIoctl()
{ {
UserCtxs = new ConcurrentDictionary<Process, NvHostCtrlUserCtx>(); 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) public static int ProcessIoctl(ServiceCtx Context, int Cmd)
@ -70,20 +78,55 @@ namespace Ryujinx.HLE.OsHle.Services.Nv.NvHostCtrl
} }
private static int GetConfig(ServiceCtx Context) private static int GetConfig(ServiceCtx Context)
{
if (!IsProductionMode)
{ {
long InputPosition = Context.Request.GetBufferType0x21().Position; long InputPosition = Context.Request.GetBufferType0x21().Position;
long OutputPosition = Context.Request.GetBufferType0x22().Position; long OutputPosition = Context.Request.GetBufferType0x22().Position;
string Nv = AMemoryHelper.ReadAsciiString(Context.Memory, InputPosition + 0, 0x41); string Domain = AMemoryHelper.ReadAsciiString(Context.Memory, InputPosition + 0, 0x41);
string Name = AMemoryHelper.ReadAsciiString(Context.Memory, InputPosition + 0x41, 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");
}
}
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.Success;
} }
return NvResult.NotAvailableInProduction;
}
private static int EventWait(ServiceCtx Context) private static int EventWait(ServiceCtx Context)
{ {
return EventWait(Context, Async: false); return EventWait(Context, Async: false);

View file

@ -2,6 +2,7 @@ namespace Ryujinx.HLE.OsHle.Services.Nv
{ {
static class NvResult static class NvResult
{ {
public const int NotAvailableInProduction = 196614;
public const int Success = 0; public const int Success = 0;
public const int TryAgain = -11; public const int TryAgain = -11;
public const int OutOfMemory = -12; public const int OutOfMemory = -12;