예제 #1
0
        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);
        }
예제 #2
0
        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);
        }