public override NvInternalResult Ioctl(NvIoctl command, Span <byte> arguments) { NvInternalResult result = NvInternalResult.NotImplemented; if (command.Type == NvIoctl.NvHostCustomMagic) { switch (command.Number) { case 0x14: result = CallIoctlMethod <NvFence>(SyncptRead, arguments); break; case 0x15: result = CallIoctlMethod <uint>(SyncptIncr, arguments); break; case 0x16: result = CallIoctlMethod <SyncptWaitArguments>(SyncptWait, arguments); break; case 0x19: result = CallIoctlMethod <SyncptWaitExArguments>(SyncptWaitEx, arguments); break; case 0x1a: result = CallIoctlMethod <NvFence>(SyncptReadMax, arguments); break; 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; case 0x1d: result = CallIoctlMethod <EventWaitArguments>(EventWait, arguments); break; case 0x1e: result = CallIoctlMethod <EventWaitArguments>(EventWaitAsync, arguments); break; case 0x1f: result = CallIoctlMethod <uint>(EventRegister, arguments); break; } } return(result); }
private NvInternalResult GetConfig(GetConfigurationArguments arguments) { if (!_isProductionMode && NxSettings.Settings.TryGetValue($"{arguments.Domain}!{arguments.Parameter}".ToLower(), out object nvSetting)) { byte[] settingBuffer = new byte[0x101]; if (nvSetting is string stringValue) { if (stringValue.Length > 0x100) { Logger.Error?.Print(LogClass.ServiceNv, $"{arguments.Domain}!{arguments.Parameter} String value size is too big!"); } else { settingBuffer = Encoding.ASCII.GetBytes(stringValue + "\0"); } } else 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); } Logger.Debug?.Print(LogClass.ServiceNv, $"Got setting {arguments.Domain}!{arguments.Parameter}"); arguments.Configuration = settingBuffer; return(NvInternalResult.Success); } // NOTE: This actually return NotAvailableInProduction but this is directly translated as a InvalidInput before returning the ioctl. //return NvInternalResult.NotAvailableInProduction; return(NvInternalResult.InvalidInput); }