Beispiel #1
0
        private static int GetId(ServiceCtx context)
        {
            long inputPosition  = context.Request.GetBufferType0x21().Position;
            long outputPosition = context.Request.GetBufferType0x22().Position;

            NvMapGetId args = MemoryHelper.Read <NvMapGetId>(context.Memory, inputPosition);

            NvMapHandle map = GetNvMap(context, args.Handle);

            if (map == null)
            {
                Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{args.Handle:x8}!");

                return(NvResult.InvalidInput);
            }

            args.Id = args.Handle;

            MemoryHelper.Write(context.Memory, outputPosition, args);

            return(NvResult.Success);
        }
Beispiel #2
0
        private static int GetId(ServiceCtx Context)
        {
            long InputPosition  = Context.Request.GetBufferType0x21().Position;
            long OutputPosition = Context.Request.GetBufferType0x22().Position;

            NvMapGetId Args = MemoryHelper.Read <NvMapGetId>(Context.Memory, InputPosition);

            NvMapHandle Map = GetNvMap(Context, Args.Handle);

            if (Map == null)
            {
                Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Args.Handle:x8}!");

                return(NvResult.InvalidInput);
            }

            Args.Id = Args.Handle;

            MemoryHelper.Write(Context.Memory, OutputPosition, Args);

            return(NvResult.Success);
        }
Beispiel #3
0
        private static int Param(ServiceCtx context)
        {
            long inputPosition  = context.Request.GetBufferType0x21().Position;
            long outputPosition = context.Request.GetBufferType0x22().Position;

            NvMapParam args = MemoryHelper.Read <NvMapParam>(context.Memory, inputPosition);

            NvMapHandle map = GetNvMap(context, args.Handle);

            if (map == null)
            {
                Logger.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);
            }

            MemoryHelper.Write(context.Memory, outputPosition, args);

            return(NvResult.Success);
        }
Beispiel #4
0
        private static int Free(ServiceCtx context)
        {
            long inputPosition  = context.Request.GetBufferType0x21().Position;
            long outputPosition = context.Request.GetBufferType0x22().Position;

            NvMapFree args = MemoryHelper.Read <NvMapFree>(context.Memory, inputPosition);

            NvMapHandle map = GetNvMap(context, args.Handle);

            if (map == null)
            {
                Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{args.Handle:x8}!");

                return(NvResult.InvalidInput);
            }

            if (map.DecrementRefCount() <= 0)
            {
                DeleteNvMap(context, args.Handle);

                Logger.PrintInfo(LogClass.ServiceNv, $"Deleted map {args.Handle}!");

                args.Address = map.Address;
                args.Flags   = 0;
            }
            else
            {
                args.Address = 0;
                args.Flags   = FlagNotFreedYet;
            }

            args.Size = map.Size;

            MemoryHelper.Write(context.Memory, outputPosition, args);

            return(NvResult.Success);
        }
Beispiel #5
0
        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.Device.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);
        }
Beispiel #6
0
        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.Device.Log.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Args.Handle:x8}!");

                return(NvResult.InvalidInput);
            }

            if (Map.DecrementRefCount() <= 0)
            {
                DeleteNvMap(Context, Args.Handle);

                Context.Device.Log.PrintInfo(LogClass.ServiceNv, $"Deleted map {Args.Handle}!");

                Args.Address = Map.Address;
                Args.Flags   = 0;
            }
            else
            {
                Args.Address = 0;
                Args.Flags   = FlagNotFreedYet;
            }

            Args.Size = Map.Size;

            AMemoryHelper.Write(Context.Memory, OutputPosition, Args);

            return(NvResult.Success);
        }
Beispiel #7
0
        private static int FromId(ServiceCtx Context)
        {
            long InputPosition  = Context.Request.GetBufferType0x21().Position;
            long OutputPosition = Context.Request.GetBufferType0x22().Position;

            NvMapFromId Args = AMemoryHelper.Read <NvMapFromId>(Context.Memory, InputPosition);

            NvMapHandle Map = GetNvMap(Context, Args.Id);

            if (Map == null)
            {
                Context.Device.Log.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Args.Handle:x8}!");

                return(NvResult.InvalidInput);
            }

            Map.IncrementRefCount();

            Args.Handle = Args.Id;

            AMemoryHelper.Write(Context.Memory, OutputPosition, Args);

            return(NvResult.Success);
        }
Beispiel #8
0
        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.Device.Log.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{Args.Handle:x8}!");

                return(NvResult.InvalidInput);
            }

            if ((Args.Align & (Args.Align - 1)) != 0)
            {
                Context.Device.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.
                    //TODO: Is this allocation inside the transfer memory?
                    if (!Context.Device.Memory.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);
        }