Some clean up and fixes

- Make sure to remove the fd of a closed channel.
- NvFileDevice now doesn't implement Disposable as it was never used.
- Rename NvHostCtrlGetConfigurationArgument to GetConfigurationArguments
to follow calling convention.
- Make sure to check every ioctls magic.
This commit is contained in:
Thog 2019-10-28 16:17:04 +01:00
commit be9d222bb9
No known key found for this signature in database
GPG key ID: 0CD291558FAFDBC6
9 changed files with 164 additions and 106 deletions

View file

@ -5,9 +5,9 @@ using Ryujinx.HLE.Exceptions;
using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Memory; using Ryujinx.HLE.HOS.Kernel.Memory;
using Ryujinx.HLE.HOS.Kernel.Process; using Ryujinx.HLE.HOS.Kernel.Process;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu; 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.NvHostCtrl;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap;
@ -28,13 +28,16 @@ namespace Ryujinx.HLE.HOS.Services.Nv
private static Dictionary<string, Type> _fileDeviceRegistry = private static Dictionary<string, Type> _fileDeviceRegistry =
new Dictionary<string, Type>() new Dictionary<string, Type>()
{ {
{ "/dev/nvhost-as-gpu", typeof(NvHostAsGpuFileDevice) }, { "/dev/nvmap", typeof(NvMapFileDevice) },
{ "/dev/nvhost-ctrl", typeof(NvHostCtrlFileDevice) }, { "/dev/nvhost-ctrl", typeof(NvHostCtrlFileDevice) },
{ "/dev/nvhost-ctrl-gpu", typeof(NvHostCtrlGpuFileDevice) }, { "/dev/nvhost-ctrl-gpu", typeof(NvHostCtrlGpuFileDevice) },
//{ "/dev/nvhost-gpu", typeof(NvMapFileDevice) }, { "/dev/nvhost-as-gpu", typeof(NvHostAsGpuFileDevice) },
//{ "/dev/nvhost-nvdec", typeof(NvMapFileDevice) }, { "/dev/nvhost-gpu", typeof(NvHostChannelFileDevice) },
//{ "/dev/nvhost-vic", typeof(NvMapFileDevice) }, //{ "/dev/nvhost-msenc", typeof(NvHostChannelFileDevice) },
{ "/dev/nvmap", typeof(NvMapFileDevice) } { "/dev/nvhost-nvdec", typeof(NvHostChannelFileDevice) },
//{ "/dev/nvhost-nvjpg", typeof(NvHostChannelFileDevice) },
{ "/dev/nvhost-vic", typeof(NvHostChannelFileDevice) },
//{ "/dev/nvhost-display", typeof(NvHostChannelFileDevice) },
}; };
private static IdDictionary _fileDeviceIdRegistry = new IdDictionary(); private static IdDictionary _fileDeviceIdRegistry = new IdDictionary();
@ -287,6 +290,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv
if (errorCode == NvResult.Success) if (errorCode == NvResult.Success)
{ {
fileDevice.Close(); fileDevice.Close();
_fileDeviceIdRegistry.Delete(fd);
} }
} }

View file

@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices
{ {
abstract class NvFileDevice : IDisposable abstract class NvFileDevice
{ {
protected KProcess _owner; protected KProcess _owner;
@ -62,10 +62,5 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices
} }
public abstract void Close(); public abstract void Close();
public void Dispose()
{
Close();
}
} }
} }

View file

@ -24,33 +24,37 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
{ {
NvInternalResult result = NvInternalResult.NotImplemented; NvInternalResult result = NvInternalResult.NotImplemented;
switch (command.GetNumberValue()) if (command.GetTypeValue() == NvIoctl.NvGpuAsMagic)
{ {
case 0x1: switch (command.GetNumberValue())
result = CallIoctlMethod<BindChannelArguments>(BindChannel, arguments); {
break; case 0x1:
case 0x2: result = CallIoctlMethod<BindChannelArguments>(BindChannel, arguments);
result = CallIoctlMethod<AllocSpaceArguments>(AllocSpace, arguments); break;
break; case 0x2:
case 0x3: result = CallIoctlMethod<AllocSpaceArguments>(AllocSpace, arguments);
result = CallIoctlMethod<FreeSpaceArguments>(FreeSpace, arguments); break;
break; case 0x3:
case 0x5: result = CallIoctlMethod<FreeSpaceArguments>(FreeSpace, arguments);
result = CallIoctlMethod<UnmapBufferArguments>(UnmapBuffer, arguments); break;
break; case 0x5:
case 0x6: result = CallIoctlMethod<UnmapBufferArguments>(UnmapBuffer, arguments);
result = CallIoctlMethod<MapBufferExArguments>(MapBufferEx, arguments); break;
break; case 0x6:
case 0x8: result = CallIoctlMethod<MapBufferExArguments>(MapBufferEx, arguments);
result = CallIoctlMethod<GetVaRegionsArguments>(GetVaRegions, arguments); break;
break; case 0x8:
case 0x9: result = CallIoctlMethod<GetVaRegionsArguments>(GetVaRegions, arguments);
result = CallIoctlMethod<InitializeExArguments>(InitializeEx, arguments); break;
break; case 0x9:
case 0x14: result = CallIoctlMethod<InitializeExArguments>(InitializeEx, arguments);
result = CallIoctlMethod<RemapArguments>(Remap, arguments); break;
break; case 0x14:
result = CallIoctlMethod<RemapArguments>(Remap, arguments);
break;
}
} }
return result; return result;
} }

View file

@ -0,0 +1,40 @@
using Ryujinx.HLE.HOS.Kernel.Process;
using System;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
{
class NvHostChannelFileDevice : NvFileDevice
{
public NvHostChannelFileDevice(KProcess owner) : base(owner)
{
}
public override NvInternalResult Ioctl(NvIoctl command, Span<byte> arguments)
{
NvInternalResult result = NvInternalResult.NotImplemented;
if (command.GetTypeValue() == NvIoctl.NvHostMagic)
{
switch (command.GetNumberValue())
{
}
}
else if (command.GetTypeValue() == NvIoctl.NvGpuMagic)
{
switch (command.GetNumberValue())
{
}
}
return result;
}
public override void Close()
{
throw new NotImplementedException();
}
}
}

View file

@ -23,26 +23,29 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
{ {
NvInternalResult result = NvInternalResult.NotImplemented; NvInternalResult result = NvInternalResult.NotImplemented;
switch (command.GetNumberValue()) if (command.GetTypeValue() == NvIoctl.NvHostMagic)
{ {
case 0x1b: switch (command.GetNumberValue())
// As Marshal cannot handle unaligned arrays, we do everything by hand here. {
NvHostCtrlGetConfigurationArgument configArgument = NvHostCtrlGetConfigurationArgument.FromSpan(arguments); case 0x1b:
result = GetConfig(configArgument); // As Marshal cannot handle unaligned arrays, we do everything by hand here.
GetConfigurationArguments configArgument = GetConfigurationArguments.FromSpan(arguments);
result = GetConfig(configArgument);
if (result == NvInternalResult.Success) if (result == NvInternalResult.Success)
{ {
configArgument.CopyTo(arguments); configArgument.CopyTo(arguments);
} }
break; break;
default: default:
break; break;
}
} }
return result; return result;
} }
private NvInternalResult GetConfig(NvHostCtrlGetConfigurationArgument arguments) private NvInternalResult GetConfig(GetConfigurationArguments arguments)
{ {
if (!_isProductionMode && NxSettings.Settings.TryGetValue($"{arguments.Domain}!{arguments.Parameter}".ToLower(), out object nvSetting)) if (!_isProductionMode && NxSettings.Settings.TryGetValue($"{arguments.Domain}!{arguments.Parameter}".ToLower(), out object nvSetting))
{ {

View file

@ -3,18 +3,18 @@ using System.Text;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl.Types namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl.Types
{ {
class NvHostCtrlGetConfigurationArgument class GetConfigurationArguments
{ {
public string Domain; public string Domain;
public string Parameter; public string Parameter;
public byte[] Configuration; public byte[] Configuration;
public static NvHostCtrlGetConfigurationArgument FromSpan(Span<byte> span) public static GetConfigurationArguments FromSpan(Span<byte> span)
{ {
string domain = Encoding.ASCII.GetString(span.Slice(0, 0x41)); string domain = Encoding.ASCII.GetString(span.Slice(0, 0x41));
string parameter = Encoding.ASCII.GetString(span.Slice(0x41, 0x41)); string parameter = Encoding.ASCII.GetString(span.Slice(0x41, 0x41));
NvHostCtrlGetConfigurationArgument result = new NvHostCtrlGetConfigurationArgument GetConfigurationArguments result = new GetConfigurationArguments
{ {
Domain = domain.Substring(0, domain.IndexOf('\0')), Domain = domain.Substring(0, domain.IndexOf('\0')),
Parameter = parameter.Substring(0, parameter.IndexOf('\0')), Parameter = parameter.Substring(0, parameter.IndexOf('\0')),

View file

@ -24,29 +24,32 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu
{ {
NvInternalResult result = NvInternalResult.NotImplemented; NvInternalResult result = NvInternalResult.NotImplemented;
switch (command.GetNumberValue()) if (command.GetTypeValue() == NvIoctl.NvGpuMagic)
{ {
case 0x1: switch (command.GetNumberValue())
result = CallIoctlMethod<ZcullGetCtxSizeArguments>(ZcullGetCtxSize, arguments); {
break; case 0x1:
case 0x2: result = CallIoctlMethod<ZcullGetCtxSizeArguments>(ZcullGetCtxSize, arguments);
result = CallIoctlMethod<ZcullGetInfoArguments>(ZcullGetInfo, arguments); break;
break; case 0x2:
case 0x3: result = CallIoctlMethod<ZcullGetInfoArguments>(ZcullGetInfo, arguments);
result = CallIoctlMethod<ZbcSetTableArguments>(ZbcSetTable, arguments); break;
break; case 0x3:
case 0x5: result = CallIoctlMethod<ZbcSetTableArguments>(ZbcSetTable, arguments);
result = CallIoctlMethod<GetCharacteristicsArguments>(GetCharacteristics, arguments); break;
break; case 0x5:
case 0x6: result = CallIoctlMethod<GetCharacteristicsArguments>(GetCharacteristics, arguments);
result = CallIoctlMethod<GetTpcMasksArguments>(GetTpcMasks, arguments); break;
break; case 0x6:
case 0x14: result = CallIoctlMethod<GetTpcMasksArguments>(GetTpcMasks, arguments);
result = CallIoctlMethod<GetActiveSlotMaskArguments>(GetActiveSlotMask, arguments); break;
break; case 0x14:
case 0x1c: result = CallIoctlMethod<GetActiveSlotMaskArguments>(GetActiveSlotMask, arguments);
result = CallIoctlMethod<GetGpuTimeArguments>(GetGpuTime, arguments); break;
break; case 0x1c:
result = CallIoctlMethod<GetGpuTimeArguments>(GetGpuTime, arguments);
break;
}
} }
return result; return result;

View file

@ -24,38 +24,41 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
{ {
NvInternalResult result = NvInternalResult.NotImplemented; NvInternalResult result = NvInternalResult.NotImplemented;
switch (command.GetNumberValue()) if (command.GetTypeValue() == NvIoctl.NvMapMagic)
{ {
case 0x1: switch (command.GetNumberValue())
result = CallIoctlMethod<NvMapCreate>(Create, arguments); {
break; case 0x1:
case 0x3: result = CallIoctlMethod<NvMapCreate>(Create, arguments);
result = CallIoctlMethod<NvMapFromId>(FromId, arguments); break;
break; case 0x3:
case 0x4: result = CallIoctlMethod<NvMapFromId>(FromId, arguments);
result = CallIoctlMethod<NvMapAlloc>(Alloc, arguments); break;
break; case 0x4:
case 0x5: result = CallIoctlMethod<NvMapAlloc>(Alloc, arguments);
result = CallIoctlMethod<NvMapFree>(Free, arguments); break;
break; case 0x5:
case 0x9: result = CallIoctlMethod<NvMapFree>(Free, arguments);
result = CallIoctlMethod<NvMapParam>(Param, arguments); break;
break; case 0x9:
case 0xe: result = CallIoctlMethod<NvMapParam>(Param, arguments);
result = CallIoctlMethod<NvMapGetId>(GetId, arguments); break;
break; case 0xe:
case 0x2: result = CallIoctlMethod<NvMapGetId>(GetId, arguments);
case 0x6: break;
case 0x7: case 0x2:
case 0x8: case 0x6:
case 0xa: case 0x7:
case 0xc: case 0x8:
case 0xd: case 0xa:
case 0xf: case 0xc:
case 0x10: case 0xd:
case 0x11: case 0xf:
result = NvInternalResult.NotSupported; case 0x10:
break; case 0x11:
result = NvInternalResult.NotSupported;
break;
}
} }
return result; return result;

View file

@ -6,6 +6,11 @@ namespace Ryujinx.HLE.HOS.Services.Nv
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
struct NvIoctl struct NvIoctl
{ {
public const int NvHostMagic = 0x00;
public const int NvMapMagic = 0x01;
public const int NvGpuAsMagic = 0x41;
public const int NvGpuMagic = 0x47;
private const int NumberBits = 8; private const int NumberBits = 8;
private const int TypeBits = 8; private const int TypeBits = 8;
private const int SizeBits = 14; private const int SizeBits = 14;