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

View file

@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices
{
abstract class NvFileDevice : IDisposable
abstract class NvFileDevice
{
protected KProcess _owner;
@ -62,10 +62,5 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices
}
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;
switch (command.GetNumberValue())
if (command.GetTypeValue() == NvIoctl.NvGpuAsMagic)
{
case 0x1:
result = CallIoctlMethod<BindChannelArguments>(BindChannel, arguments);
break;
case 0x2:
result = CallIoctlMethod<AllocSpaceArguments>(AllocSpace, arguments);
break;
case 0x3:
result = CallIoctlMethod<FreeSpaceArguments>(FreeSpace, arguments);
break;
case 0x5:
result = CallIoctlMethod<UnmapBufferArguments>(UnmapBuffer, arguments);
break;
case 0x6:
result = CallIoctlMethod<MapBufferExArguments>(MapBufferEx, arguments);
break;
case 0x8:
result = CallIoctlMethod<GetVaRegionsArguments>(GetVaRegions, arguments);
break;
case 0x9:
result = CallIoctlMethod<InitializeExArguments>(InitializeEx, arguments);
break;
case 0x14:
result = CallIoctlMethod<RemapArguments>(Remap, arguments);
break;
switch (command.GetNumberValue())
{
case 0x1:
result = CallIoctlMethod<BindChannelArguments>(BindChannel, arguments);
break;
case 0x2:
result = CallIoctlMethod<AllocSpaceArguments>(AllocSpace, arguments);
break;
case 0x3:
result = CallIoctlMethod<FreeSpaceArguments>(FreeSpace, arguments);
break;
case 0x5:
result = CallIoctlMethod<UnmapBufferArguments>(UnmapBuffer, arguments);
break;
case 0x6:
result = CallIoctlMethod<MapBufferExArguments>(MapBufferEx, arguments);
break;
case 0x8:
result = CallIoctlMethod<GetVaRegionsArguments>(GetVaRegions, arguments);
break;
case 0x9:
result = CallIoctlMethod<InitializeExArguments>(InitializeEx, arguments);
break;
case 0x14:
result = CallIoctlMethod<RemapArguments>(Remap, arguments);
break;
}
}
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;
switch (command.GetNumberValue())
if (command.GetTypeValue() == NvIoctl.NvHostMagic)
{
case 0x1b:
// As Marshal cannot handle unaligned arrays, we do everything by hand here.
NvHostCtrlGetConfigurationArgument configArgument = NvHostCtrlGetConfigurationArgument.FromSpan(arguments);
result = GetConfig(configArgument);
switch (command.GetNumberValue())
{
case 0x1b:
// As Marshal cannot handle unaligned arrays, we do everything by hand here.
GetConfigurationArguments configArgument = GetConfigurationArguments.FromSpan(arguments);
result = GetConfig(configArgument);
if (result == NvInternalResult.Success)
{
configArgument.CopyTo(arguments);
}
break;
default:
break;
if (result == NvInternalResult.Success)
{
configArgument.CopyTo(arguments);
}
break;
default:
break;
}
}
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))
{

View file

@ -3,18 +3,18 @@ using System.Text;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl.Types
{
class NvHostCtrlGetConfigurationArgument
class GetConfigurationArguments
{
public string Domain;
public string Parameter;
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 parameter = Encoding.ASCII.GetString(span.Slice(0x41, 0x41));
NvHostCtrlGetConfigurationArgument result = new NvHostCtrlGetConfigurationArgument
GetConfigurationArguments result = new GetConfigurationArguments
{
Domain = domain.Substring(0, domain.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;
switch (command.GetNumberValue())
if (command.GetTypeValue() == NvIoctl.NvGpuMagic)
{
case 0x1:
result = CallIoctlMethod<ZcullGetCtxSizeArguments>(ZcullGetCtxSize, arguments);
break;
case 0x2:
result = CallIoctlMethod<ZcullGetInfoArguments>(ZcullGetInfo, arguments);
break;
case 0x3:
result = CallIoctlMethod<ZbcSetTableArguments>(ZbcSetTable, arguments);
break;
case 0x5:
result = CallIoctlMethod<GetCharacteristicsArguments>(GetCharacteristics, arguments);
break;
case 0x6:
result = CallIoctlMethod<GetTpcMasksArguments>(GetTpcMasks, arguments);
break;
case 0x14:
result = CallIoctlMethod<GetActiveSlotMaskArguments>(GetActiveSlotMask, arguments);
break;
case 0x1c:
result = CallIoctlMethod<GetGpuTimeArguments>(GetGpuTime, arguments);
break;
switch (command.GetNumberValue())
{
case 0x1:
result = CallIoctlMethod<ZcullGetCtxSizeArguments>(ZcullGetCtxSize, arguments);
break;
case 0x2:
result = CallIoctlMethod<ZcullGetInfoArguments>(ZcullGetInfo, arguments);
break;
case 0x3:
result = CallIoctlMethod<ZbcSetTableArguments>(ZbcSetTable, arguments);
break;
case 0x5:
result = CallIoctlMethod<GetCharacteristicsArguments>(GetCharacteristics, arguments);
break;
case 0x6:
result = CallIoctlMethod<GetTpcMasksArguments>(GetTpcMasks, arguments);
break;
case 0x14:
result = CallIoctlMethod<GetActiveSlotMaskArguments>(GetActiveSlotMask, arguments);
break;
case 0x1c:
result = CallIoctlMethod<GetGpuTimeArguments>(GetGpuTime, arguments);
break;
}
}
return result;

View file

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

View file

@ -6,6 +6,11 @@ namespace Ryujinx.HLE.HOS.Services.Nv
[StructLayout(LayoutKind.Sequential)]
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 TypeBits = 8;
private const int SizeBits = 14;