private static int UnmapBuffer(ServiceCtx context) { long inputPosition = context.Request.GetBufferType0x21().Position; NvHostChannelMapBuffer args = MemoryHelper.Read <NvHostChannelMapBuffer>(context.Memory, inputPosition); NvGpuVmm vmm = NvGpuASIoctl.GetASCtx(context).Vmm; for (int index = 0; index < args.NumEntries; index++) { int handle = context.Memory.ReadInt32(inputPosition + 0xc + index * 8); NvMapHandle map = NvMapIoctl.GetNvMap(context, handle); if (map == null) { Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{handle:x8}!"); return(NvResult.InvalidInput); } lock (map) { if (map.DmaMapAddress != 0) { vmm.Free(map.DmaMapAddress, map.Size); map.DmaMapAddress = 0; } } } 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 = 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 Submit(ServiceCtx context) { long inputPosition = context.Request.GetBufferType0x21().Position; long outputPosition = context.Request.GetBufferType0x22().Position; NvHostChannelSubmit args = MemoryHelper.Read <NvHostChannelSubmit>(context.Memory, inputPosition); NvGpuVmm vmm = NvGpuASIoctl.GetASCtx(context).Vmm; for (int index = 0; index < args.CmdBufsCount; index++) { long cmdBufOffset = inputPosition + 0x10 + index * 0xc; NvHostChannelCmdBuf cmdBuf = MemoryHelper.Read <NvHostChannelCmdBuf>(context.Memory, cmdBufOffset); NvMapHandle map = NvMapIoctl.GetNvMap(context, cmdBuf.MemoryId); int[] cmdBufData = new int[cmdBuf.WordsCount]; for (int offset = 0; offset < cmdBufData.Length; offset++) { cmdBufData[offset] = context.Memory.ReadInt32(map.Address + cmdBuf.Offset + offset * 4); } context.Device.Gpu.PushCommandBuffer(vmm, cmdBufData); } // TODO: Relocation, waitchecks, etc. 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 static int Submit(ServiceCtx Context) { long InputPosition = Context.Request.GetBufferType0x21().Position; long OutputPosition = Context.Request.GetBufferType0x22().Position; NvHostChannelSubmit Args = MemoryHelper.Read <NvHostChannelSubmit>(Context.Memory, InputPosition); NvGpuVmm Vmm = NvGpuASIoctl.GetASCtx(Context).Vmm; for (int Index = 0; Index < Args.CmdBufsCount; Index++) { long CmdBufOffset = InputPosition + 0x10 + Index * 0xc; NvHostChannelCmdBuf CmdBuf = MemoryHelper.Read <NvHostChannelCmdBuf>(Context.Memory, CmdBufOffset); NvMapHandle Map = NvMapIoctl.GetNvMap(Context, CmdBuf.MemoryId); int[] CmdBufData = new int[CmdBuf.WordsCount]; for (int Offset = 0; Offset < CmdBufData.Length; Offset++) { CmdBufData[Offset] = Context.Memory.ReadInt32(Map.Address + CmdBuf.Offset + Offset * 4); } Context.Device.Gpu.PushCommandBuffer(Vmm, CmdBufData); } //TODO: Relocation, waitchecks, etc. return(NvResult.Success); }
private static int UnmapBuffer(ServiceCtx Context) { long InputPosition = Context.Request.GetBufferType0x21().Position; NvHostChannelMapBuffer Args = MemoryHelper.Read <NvHostChannelMapBuffer>(Context.Memory, InputPosition); NvGpuVmm Vmm = NvGpuASIoctl.GetASCtx(Context).Vmm; for (int Index = 0; Index < Args.NumEntries; Index++) { int Handle = Context.Memory.ReadInt32(InputPosition + 0xc + Index * 8); NvMapHandle Map = NvMapIoctl.GetNvMap(Context, Handle); if (Map == null) { Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Handle:x8}!"); return(NvResult.InvalidInput); } lock (Map) { if (Map.DmaMapAddress != 0) { Vmm.Free(Map.DmaMapAddress, Map.Size); Map.DmaMapAddress = 0; } } } return(NvResult.Success); }
public static void UnloadProcess(Process Process) { Fds.DeleteProcess(Process); NvGpuASIoctl.UnloadProcess(Process); NvHostCtrlIoctl.UnloadProcess(Process); NvMapIoctl.UnloadProcess(Process); }
public long Initialize(ServiceCtx Context) { long TransferMemSize = Context.RequestData.ReadInt64(); int TransferMemHandle = Context.Request.HandleDesc.ToCopy[0]; NvMapIoctl.InitializeNvMap(Context); Context.ResponseData.Write(0); return(0); }
// Initialize(u32 transfer_memory_size, handle<copy, process> current_process, handle<copy, transfer_memory> transfer_memory) -> u32 error_code public ResultCode Initialize(ServiceCtx context) { long transferMemSize = context.RequestData.ReadInt64(); int transferMemHandle = context.Request.HandleDesc.ToCopy[0]; NvMapIoctl.InitializeNvMap(context); context.ResponseData.Write(0); return(ResultCode.Success); }
public static void UnloadProcess(KProcess process) { Fds.DeleteProcess(process); NvGpuASIoctl.UnloadProcess(process); NvHostChannelIoctl.UnloadProcess(process); NvHostCtrlIoctl.UnloadProcess(process); NvMapIoctl.UnloadProcess(process); }
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) { const string MapErrorMsg = "Failed to map fixed buffer with offset 0x{0:x16} and size 0x{1:x16}!"; long InputPosition = Context.Request.GetBufferType0x21().Position; long OutputPosition = Context.Request.GetBufferType0x22().Position; NvGpuASMapBufferEx Args = AMemoryHelper.Read <NvGpuASMapBufferEx>(Context.Memory, InputPosition); NvGpuASCtx ASCtx = GetASCtx(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; if ((Args.Flags & FlagRemapSubRange) != 0) { lock (ASCtx) { if (ASCtx.TryGetMapPhysicalAddress(Args.Offset, out PA)) { long VA = Args.Offset + Args.BufferOffset; PA += Args.BufferOffset; if (ASCtx.Vmm.Map(PA, VA, Args.MappingSize) < 0) { string Msg = string.Format(MapErrorMsg, VA, Args.MappingSize); Context.Ns.Log.PrintWarning(LogClass.ServiceNv, Msg); return(NvResult.InvalidInput); } return(NvResult.Success); } else { Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Address 0x{Args.Offset:x16} not mapped!"); return(NvResult.InvalidInput); } } } PA = Map.Address + Args.BufferOffset; long Size = Args.MappingSize; if (Size == 0) { Size = (uint)Map.Size; } int Result = NvResult.Success; lock (ASCtx) { //Note: When the fixed offset flag is not set, //the Offset field holds the alignment size instead. bool VaAllocated = (Args.Flags & FlagFixedOffset) == 0; if (!VaAllocated) { if (ASCtx.ValidateFixedBuffer(Args.Offset, Size)) { Args.Offset = ASCtx.Vmm.Map(PA, Args.Offset, Size); } else { string Msg = string.Format(MapErrorMsg, Args.Offset, Size); Context.Ns.Log.PrintWarning(LogClass.ServiceNv, Msg); Result = NvResult.InvalidInput; } } else { Args.Offset = ASCtx.Vmm.Map(PA, Size); } if (Args.Offset < 0) { Args.Offset = 0; Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Failed to map size 0x{Size:x16}!"); Result = NvResult.InvalidInput; } else { ASCtx.AddMap(Args.Offset, Size, PA, VaAllocated); } } AMemoryHelper.Write(Context.Memory, OutputPosition, Args); return(Result); }
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); }
private static int MapBufferEx(ServiceCtx context) { const string mapErrorMsg = "Failed to map fixed buffer with offset 0x{0:x16} and size 0x{1:x16}!"; long inputPosition = context.Request.GetBufferType0x21().Position; long outputPosition = context.Request.GetBufferType0x22().Position; NvGpuASMapBufferEx args = MemoryHelper.Read <NvGpuASMapBufferEx>(context.Memory, inputPosition); NvGpuASCtx asCtx = GetASCtx(context); 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 pa; if ((args.Flags & FlagRemapSubRange) != 0) { lock (asCtx) { if (asCtx.TryGetMapPhysicalAddress(args.Offset, out pa)) { long va = args.Offset + args.BufferOffset; pa += args.BufferOffset; if (asCtx.Vmm.Map(pa, va, args.MappingSize) < 0) { string msg = string.Format(mapErrorMsg, va, args.MappingSize); Logger.PrintWarning(LogClass.ServiceNv, msg); return(NvResult.InvalidInput); } return(NvResult.Success); } else { Logger.PrintWarning(LogClass.ServiceNv, $"Address 0x{args.Offset:x16} not mapped!"); return(NvResult.InvalidInput); } } } pa = map.Address + args.BufferOffset; long size = args.MappingSize; if (size == 0) { size = (uint)map.Size; } int result = NvResult.Success; lock (asCtx) { // Note: When the fixed offset flag is not set, // the Offset field holds the alignment size instead. bool vaAllocated = (args.Flags & FlagFixedOffset) == 0; if (!vaAllocated) { if (asCtx.ValidateFixedBuffer(args.Offset, size)) { args.Offset = asCtx.Vmm.Map(pa, args.Offset, size); } else { string msg = string.Format(mapErrorMsg, args.Offset, size); Logger.PrintWarning(LogClass.ServiceNv, msg); result = NvResult.InvalidInput; } } else { args.Offset = asCtx.Vmm.Map(pa, size); } if (args.Offset < 0) { args.Offset = 0; Logger.PrintWarning(LogClass.ServiceNv, $"Failed to map size 0x{size:x16}!"); result = NvResult.InvalidInput; } else { asCtx.AddMap(args.Offset, size, pa, vaAllocated); } } MemoryHelper.Write(context.Memory, outputPosition, args); return(result); }