Implement Ioctl3
This commit is contained in:
parent
72db77fbe6
commit
4cec3190ed
2 changed files with 55 additions and 5 deletions
|
@ -458,10 +458,49 @@ namespace Ryujinx.HLE.HOS.Services.Nv
|
|||
}
|
||||
|
||||
[Command(12)] // 3.0.0+
|
||||
// Ioctl2(s32 fd, u32 ioctl_cmd, buffer<bytes, 0x21> in_args) -> (u32 error_code, buffer<bytes, 0x22> out_args, buffer<bytes, 0x22> out_additional_buffer)
|
||||
// Ioctl3(s32 fd, u32 ioctl_cmd, buffer<bytes, 0x21> in_args) -> (u32 error_code, buffer<bytes, 0x22> out_args, buffer<bytes, 0x22> inline_out_buffer)
|
||||
public ResultCode Ioctl3(ServiceCtx context)
|
||||
{
|
||||
throw new ServiceNotImplementedException(context);
|
||||
NvResult errorCode = EnsureInitialized();
|
||||
|
||||
if (errorCode == NvResult.Success)
|
||||
{
|
||||
int fd = context.RequestData.ReadInt32();
|
||||
NvIoctl ioctlCommand = context.RequestData.ReadStruct<NvIoctl>();
|
||||
|
||||
(long inlineOutBufferPosition, long inlineOutBufferSize) = context.Request.GetBufferType0x22(1);
|
||||
|
||||
errorCode = GetIoctlArgument(context, ioctlCommand, out Span<byte> arguments);
|
||||
|
||||
Span<byte> inlineOutBuffer = new Span<byte>(context.Memory.ReadBytes(inlineOutBufferPosition, inlineOutBufferSize));
|
||||
|
||||
if (errorCode == NvResult.Success)
|
||||
{
|
||||
errorCode = GetFileDeviceFromFd(fd, out NvFileDevice fileDevice);
|
||||
|
||||
if (errorCode == NvResult.Success)
|
||||
{
|
||||
NvInternalResult internalResult = fileDevice.Ioctl3(ioctlCommand, arguments, inlineOutBuffer);
|
||||
|
||||
if (internalResult == NvInternalResult.NotImplemented)
|
||||
{
|
||||
throw new NvIoctlNotImplementedException(context, fileDevice, ioctlCommand);
|
||||
}
|
||||
|
||||
errorCode = ConvertInternalErrorCode(internalResult);
|
||||
|
||||
if (errorCode == NvResult.Success && (ioctlCommand.GetDirectionValue() & NvIoctl.Direction.Write) != 0)
|
||||
{
|
||||
context.Memory.WriteBytes(context.Request.GetBufferType0x22(0).Position, arguments.ToArray());
|
||||
context.Memory.WriteBytes(inlineOutBufferPosition, inlineOutBuffer.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.ResponseData.Write((uint)errorCode);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[Command(13)] // 3.0.0+
|
||||
|
|
|
@ -50,18 +50,22 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices
|
|||
|
||||
protected delegate NvInternalResult IoctlProcessor<T>(ref T arguments);
|
||||
protected delegate NvInternalResult IoctlProcessorSpan<T>(Span<T> arguments);
|
||||
protected delegate NvInternalResult IoctlProcessorInline<T, Y>(ref T arguments, Span<Y> inlineData);
|
||||
protected delegate NvInternalResult IoctlProcessorInline<T, Y>(ref T arguments, ref Y inlineData);
|
||||
protected delegate NvInternalResult IoctlProcessorInlineSpan<T, Y>(ref T arguments, Span<Y> inlineData);
|
||||
|
||||
protected static NvInternalResult CallIoctlMethod<T>(IoctlProcessor<T> callback, Span<byte> arguments) where T : struct
|
||||
{
|
||||
Debug.Assert(arguments.Length == Unsafe.SizeOf<T>());
|
||||
|
||||
return callback(ref MemoryMarshal.Cast<byte, T>(arguments)[0]);
|
||||
}
|
||||
|
||||
protected static NvInternalResult CallIoctlMethod<T, Y>(IoctlProcessorInline<T, Y> callback, Span<byte> arguments, Span<byte> inlineInBuffer) where T : struct where Y : struct
|
||||
protected static NvInternalResult CallIoctlMethod<T, Y>(IoctlProcessorInline<T, Y> callback, Span<byte> arguments, Span<byte> inlineBuffer) where T : struct where Y : struct
|
||||
{
|
||||
Debug.Assert(arguments.Length == Unsafe.SizeOf<T>());
|
||||
return callback(ref MemoryMarshal.Cast<byte, T>(arguments)[0], MemoryMarshal.Cast<byte, Y>(inlineInBuffer));
|
||||
Debug.Assert(inlineBuffer.Length == Unsafe.SizeOf<Y>());
|
||||
|
||||
return callback(ref MemoryMarshal.Cast<byte, T>(arguments)[0], ref MemoryMarshal.Cast<byte, Y>(inlineBuffer)[0]);
|
||||
}
|
||||
|
||||
protected static NvInternalResult CallIoctlMethod<T>(IoctlProcessorSpan<T> callback, Span<byte> arguments) where T : struct
|
||||
|
@ -69,6 +73,13 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices
|
|||
return callback(MemoryMarshal.Cast<byte, T>(arguments));
|
||||
}
|
||||
|
||||
protected static NvInternalResult CallIoctlMethod<T, Y>(IoctlProcessorInlineSpan<T, Y> callback, Span<byte> arguments, Span<byte> inlineBuffer) where T : struct where Y : struct
|
||||
{
|
||||
Debug.Assert(arguments.Length == Unsafe.SizeOf<T>());
|
||||
|
||||
return callback(ref MemoryMarshal.Cast<byte, T>(arguments)[0], MemoryMarshal.Cast<byte, Y>(inlineBuffer));
|
||||
}
|
||||
|
||||
public abstract void Close();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue