private static int GetId(ServiceCtx Context) { long InputPosition = Context.Request.GetBufferType0x21().Position; long OutputPosition = Context.Request.GetBufferType0x22().Position; NvMapGetId Args = AMemoryHelper.Read <NvMapGetId>(Context.Memory, InputPosition); NvMapHandle Map = GetNvMap(Context, Args.Handle); if (Map == null) { Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Args.Handle:x8}!"); return(NvResult.InvalidInput); } Args.Id = Args.Handle; AMemoryHelper.Write(Context.Memory, OutputPosition, Args); return(NvResult.Success); }
private static int Free(ServiceCtx Context) { long InputPosition = Context.Request.GetBufferType0x21().Position; long OutputPosition = Context.Request.GetBufferType0x22().Position; NvMapFree Args = AMemoryHelper.Read <NvMapFree>(Context.Memory, InputPosition); NvMapHandle Map = GetNvMap(Context, Args.Handle); if (Map == null) { Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Args.Handle:x8}!"); return(NvResult.InvalidInput); } long OldRefCount = Map.DecrementRefCount(); if (OldRefCount <= 1) { DeleteNvMap(Context, Args.Handle); Context.Ns.Log.PrintInfo(LogClass.ServiceNv, $"Deleted map {Args.Handle}!"); Args.Flags = 0; } else { Args.Flags = FlagNotFreedYet; } Args.RefCount = OldRefCount; Args.Size = Map.Size; AMemoryHelper.Write(Context.Memory, OutputPosition, Args); return(NvResult.Success); }
private static int Param(ServiceCtx Context) { long InputPosition = Context.Request.GetBufferType0x21().Position; long OutputPosition = Context.Request.GetBufferType0x22().Position; NvMapParam Args = AMemoryHelper.Read <NvMapParam>(Context.Memory, InputPosition); NvMapHandle Map = GetNvMap(Context, Args.Handle); if (Map == null) { Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Args.Handle:x8}!"); return(NvResult.InvalidInput); } switch ((NvMapHandleParam)Args.Param) { case NvMapHandleParam.Size: Args.Result = Map.Size; break; case NvMapHandleParam.Align: Args.Result = Map.Align; break; case NvMapHandleParam.Heap: Args.Result = 0x40000000; break; case NvMapHandleParam.Kind: Args.Result = Map.Kind; break; case NvMapHandleParam.Compr: Args.Result = 0; break; //Note: Base is not supported and returns an error. //Any other value also returns an error. default: return(NvResult.InvalidInput); } AMemoryHelper.Write(Context.Memory, OutputPosition, Args); return(NvResult.Success); }
private static int Alloc(ServiceCtx Context) { long InputPosition = Context.Request.GetBufferType0x21().Position; long OutputPosition = Context.Request.GetBufferType0x22().Position; NvMapAlloc Args = AMemoryHelper.Read <NvMapAlloc>(Context.Memory, InputPosition); NvMapHandle Map = GetNvMap(Context, Args.Handle); if (Map == null) { Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Args.Handle:x8}!"); return(NvResult.InvalidInput); } if ((Args.Align & (Args.Align - 1)) != 0) { Context.Ns.Log.PrintWarning(LogClass.ServiceNv, $"Invalid alignment 0x{Args.Align:x8}!"); return(NvResult.InvalidInput); } if ((uint)Args.Align < NvGpuVmm.PageSize) { Args.Align = NvGpuVmm.PageSize; } int Result = NvResult.Success; if (!Map.Allocated) { Map.Allocated = true; Map.Align = Args.Align; Map.Kind = (byte)Args.Kind; int Size = IntUtils.AlignUp(Map.Size, NvGpuVmm.PageSize); long Address = Args.Address; if (Address == 0) { //When the address is zero, we need to allocate //our own backing memory for the NvMap. if (!Context.Ns.Os.Allocator.TryAllocate((uint)Size, out Address)) { Result = NvResult.OutOfMemory; } } if (Result == NvResult.Success) { Map.Size = Size; Map.Address = Address; } } AMemoryHelper.Write(Context.Memory, OutputPosition, Args); return(Result); }