private static int Remap(ServiceCtx Context, int Cmd) { int Count = ((Cmd >> 16) & 0xff) / 0x14; long InputPosition = Context.Request.GetBufferType0x21().Position; for (int Index = 0; Index < Count; Index++, InputPosition += 0x14) { NvGpuASRemap Args = AMemoryHelper.Read <NvGpuASRemap>(Context.Memory, InputPosition); NvGpuVmm Vmm = GetASCtx(Context).Vmm; NvMapHandle Map = NvMapIoctl.GetNvMapWithFb(Context, Args.NvMapHandle); if (Map == null) { Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap handle 0x{Args.NvMapHandle:x8}!"); return(NvResult.InvalidInput); } long Result = Vmm.Map(Map.Address, (long)(uint)Args.Offset << 16, (long)(uint)Args.Pages << 16); if (Result < 0) { Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Page 0x{Args.Offset:x16} size 0x{Args.Pages:x16} not allocated!"); return(NvResult.InvalidInput); } } return(NvResult.Success); }
private static int Remap(ServiceCtx context, int cmd) { int count = ((cmd >> 16) & 0xff) / 0x14; long inputPosition = context.Request.GetBufferType0x21().Position; for (int index = 0; index < count; index++, inputPosition += 0x14) { NvGpuASRemap args = MemoryHelper.Read <NvGpuASRemap>(context.Memory, inputPosition); NvGpuVmm vmm = GetASCtx(context).Vmm; NvMapHandle map = NvMapIoctl.GetNvMapWithFb(context, args.NvMapHandle); if (map == null) { Logger.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap handle 0x{args.NvMapHandle:x8}!"); return(NvResult.InvalidInput); } long result = vmm.Map(map.Address, (long)(uint)args.Offset << 16, (long)(uint)args.Pages << 16); if (result < 0) { Logger.PrintWarning(LogClass.ServiceNv, $"Page 0x{args.Offset:x16} size 0x{args.Pages:x16} not allocated!"); return(NvResult.InvalidInput); } } return(NvResult.Success); }
private NvInternalResult Remap(Span <RemapArguments> arguments) { for (int index = 0; index < arguments.Length; index++) { NvGpuVmm vmm = GetAddressSpaceContext(Owner).Vmm; NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, arguments[index].NvMapHandle, true); if (map == null) { Logger.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap handle 0x{arguments[index].NvMapHandle:x8}!"); return(NvInternalResult.InvalidInput); } long result = vmm.Map(map.Address, (long)arguments[index].Offset << 16, (long)arguments[index].Pages << 16); if (result < 0) { Logger.PrintWarning(LogClass.ServiceNv, $"Page 0x{arguments[index].Offset:x16} size 0x{arguments[index].Pages:x16} not allocated!"); return(NvInternalResult.InvalidInput); } } return(NvInternalResult.Success); }
private static int Remap(ServiceCtx Context) { long InputPosition = Context.Request.GetBufferType0x21().Position; NvGpuASRemap Args = AMemoryHelper.Read <NvGpuASRemap>(Context.Memory, InputPosition); NvGpuVmm Vmm = GetVmm(Context); NvMapHandle Map = NvMapIoctl.GetNvMapWithFb(Context, Args.NvMapHandle); if (Map == null) { Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap handle 0x{Args.NvMapHandle:x8}!"); return(NvResult.InvalidInput); } //FIXME: This is most likely wrong... Vmm.Map(Map.Address, (long)(uint)Args.Offset << 16, (long)(uint)Args.Pages << 16); return(NvResult.Success); }
private static int MapBufferEx(ServiceCtx Context) { long InputPosition = Context.Request.GetBufferType0x21().Position; long OutputPosition = Context.Request.GetBufferType0x22().Position; NvGpuASMapBufferEx Args = AMemoryHelper.Read <NvGpuASMapBufferEx>(Context.Memory, InputPosition); NvGpuVmm Vmm = GetVmm(Context); NvMapHandle Map = NvMapIoctl.GetNvMapWithFb(Context, Args.NvMapHandle); if (Map == null) { Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Invalid NvMap handle 0x{Args.NvMapHandle:x8}!"); return(NvResult.InvalidInput); } long PA = Map.Address + Args.BufferOffset; long Size = Args.MappingSize; if (Size == 0) { Size = (uint)Map.Size; } int Result = NvResult.Success; //Note: When the fixed offset flag is not set, //the Offset field holds the alignment size instead. if ((Args.Flags & FlagFixedOffset) != 0) { long MapEnd = Args.Offset + Args.MappingSize; if ((ulong)MapEnd <= (ulong)Args.Offset) { Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Offset 0x{Args.Offset:x16} and size 0x{Args.MappingSize:x16} results in a overflow!"); return(NvResult.InvalidInput); } if ((Args.Offset & NvGpuVmm.PageMask) != 0) { Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Offset 0x{Args.Offset:x16} is not page aligned!"); return(NvResult.InvalidInput); } Args.Offset = Vmm.Map(PA, Args.Offset, Size); } else { Args.Offset = Vmm.Map(PA, Size); if (Args.Offset < 0) { Args.Offset = 0; Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"No memory to map size {Args.MappingSize:x16}!"); Result = NvResult.InvalidInput; } } AMemoryHelper.Write(Context.Memory, OutputPosition, Args); return(Result); }