Exemplo n.º 1
0
        private (long, KThread) MutexUnlock(AMemory Memory, KThread CurrentThread, long MutexAddress)
        {
            KThread NewOwnerThread = CurrentThread.RelinquishMutex(MutexAddress, out int Count);

            int MutexValue = 0;

            if (NewOwnerThread != null)
            {
                MutexValue = NewOwnerThread.ThreadHandleForUserMutex;

                if (Count >= 2)
                {
                    MutexValue |= HasListenersMask;
                }

                NewOwnerThread.SignaledObj   = null;
                NewOwnerThread.ObjSyncResult = 0;

                NewOwnerThread.ReleaseAndResume();
            }

            long Result = 0;

            if (!KernelToUserInt32(Memory, MutexAddress, MutexValue))
            {
                Result = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
            }

            return(Result, NewOwnerThread);
        }
Exemplo n.º 2
0
        public SvcHandler(Switch Ns, Process Process)
        {
            SvcFuncs = new Dictionary <int, SvcFunc>()
            {
                { 0x01, SvcSetHeapSize },
                { 0x03, SvcSetMemoryAttribute },
                { 0x04, SvcMapMemory },
                { 0x06, SvcQueryMemory },
                { 0x08, SvcCreateThread },
                { 0x09, SvcStartThread },
                { 0x0b, SvcSleepThread },
                { 0x0c, SvcGetThreadPriority },
                { 0x13, SvcMapSharedMemory },
                { 0x14, SvcUnmapSharedMemory },
                { 0x15, SvcCreateTransferMemory },
                { 0x16, SvcCloseHandle },
                { 0x17, SvcResetSignal },
                { 0x18, SvcWaitSynchronization },
                { 0x1a, SvcArbitrateLock },
                { 0x1b, SvcArbitrateUnlock },
                { 0x1c, SvcWaitProcessWideKeyAtomic },
                { 0x1d, SvcSignalProcessWideKey },
                { 0x1e, SvcGetSystemTick },
                { 0x1f, SvcConnectToNamedPort },
                { 0x21, SvcSendSyncRequest },
                { 0x22, SvcSendSyncRequestWithUserBuffer },
                { 0x26, SvcBreak },
                { 0x27, SvcOutputDebugString },
                { 0x29, SvcGetInfo }
            };

            this.Ns      = Ns;
            this.Process = Process;
            this.Memory  = Process.Memory;
        }
Exemplo n.º 3
0
        private unsafe static void Write4Bpp(AMemory Memory, Texture Texture, byte[] Data)
        {
            int Width  = Texture.Width;
            int Height = Texture.Height;

            ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 4);

            fixed(byte *BuffPtr = Data)
            {
                long InOffs = 0;

                for (int Y = 0; Y < Height; Y++)
                {
                    for (int X = 0; X < Width; X++)
                    {
                        long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);

                        int Pixel = *(int *)(BuffPtr + InOffs);

                        Memory.WriteInt32Unchecked(Texture.Position + Offset, Pixel);

                        InOffs += 4;
                    }
                }
            }
        }
Exemplo n.º 4
0
 public HTransferMem(AMemory Memory, AMemoryPerm Perm, long Position, long Size)
 {
     this.Memory   = Memory;
     this.Perm     = Perm;
     this.Position = Position;
     this.Size     = Size;
 }
Exemplo n.º 5
0
 public void Setup()
 {
     Ram       = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize);
     Allocator = new AMemoryAlloc();
     Memory    = new AMemory(Ram, Allocator);
     Memory.Manager.MapPhys(0x1000, 0x1000, 2, AMemoryPerm.Read | AMemoryPerm.Write | AMemoryPerm.Execute);
 }
Exemplo n.º 6
0
        public static void Blx(AThreadState State, AMemory Memory, AOpCode OpCode, bool X)
        {
            A32OpCodeBImmAl Op = (A32OpCodeBImmAl)OpCode;

            if (IsConditionTrue(State, Op.Cond))
            {
                uint Pc = GetPc(State);

                if (State.Thumb)
                {
                    State.R14 = Pc | 1;
                }
                else
                {
                    State.R14 = Pc - 4U;
                }

                if (X)
                {
                    State.Thumb = !State.Thumb;
                }

                if (!State.Thumb)
                {
                    Pc &= ~3U;
                }

                BranchWritePc(State, Pc + (uint)Op.Imm);
            }
        }
Exemplo n.º 7
0
        public bool IsRegionModified(AMemory Memory, NvGpuBufferType BufferType, long PA, long Size)
        {
            bool[] Modified = Memory.IsRegionModified(PA, Size);

            if (Modified == null)
            {
                return(true);
            }

            ClearCachedPagesIfNeeded();

            long PageSize = Memory.GetHostPageSize();

            long Mask = PageSize - 1;

            long PAEnd = PA + Size;

            bool RegMod = false;

            int Index = 0;

            while (PA < PAEnd)
            {
                long Key = PA & ~Mask;

                long PAPgEnd = Math.Min((PA + PageSize) & ~Mask, PAEnd);

                bool IsCached = Cache.TryGetValue(Key, out CachedPage Cp);

                if (IsCached)
                {
                    CpCount -= Cp.GetTotalCount();

                    SortedCache.Remove(Cp.Node);
                }
                else
                {
                    Cp = new CachedPage();

                    Cache.Add(Key, Cp);
                }

                if (Modified[Index++] && IsCached)
                {
                    Cp = new CachedPage();

                    Cache[Key] = Cp;
                }

                Cp.Node = SortedCache.AddLast(Key);

                RegMod |= Cp.AddRange(PA, PAPgEnd, BufferType);

                CpCount += Cp.GetTotalCount();

                PA = PAPgEnd;
            }

            return(RegMod);
        }
Exemplo n.º 8
0
        public Process(Switch Device, KProcessScheduler Scheduler, int ProcessId, Npdm MetaData)
        {
            this.Device    = Device;
            this.Scheduler = Scheduler;
            this.MetaData  = MetaData;
            this.ProcessId = ProcessId;

            Memory = new AMemory(Device.Memory.RamPointer);

            MemoryManager = new KMemoryManager(this);

            TlsPages = new List <KTlsPageManager>();

            ThreadArbiterList = new List <KThread>();

            ThreadSyncLock = new object();

            HandleTable = new KProcessHandleTable();

            AppletState = new AppletStateMgr();

            SvcHandler = new SvcHandler(Device, this);

            Threads = new ConcurrentDictionary <long, KThread>();

            Executables = new List <Executable>();

            ImageBase = MemoryManager.CodeRegionStart;
        }
Exemplo n.º 9
0
        public static AOpCode DecodeOpCode(AThreadState State, AMemory Memory, long Position)
        {
            int OpCode = Memory.ReadInt32(Position);

            AInst Inst;

            if (State.ExecutionMode == AExecutionMode.AArch64)
            {
                Inst = AOpCodeTable.GetInstA64(OpCode);
            }
            else
            {
                //TODO: Thumb support.
                Inst = AOpCodeTable.GetInstA32(OpCode);
            }

            AOpCode DecodedOpCode = new AOpCode(AInst.Undefined, Position, OpCode);

            if (Inst.Type != null)
            {
                DecodedOpCode = MakeOpCode(Inst.Type, Inst, Position, OpCode);
            }

            return(DecodedOpCode);
        }
Exemplo n.º 10
0
        public void SignalProcessWideKey(Process Process, AMemory Memory, long Address, int Count)
        {
            Queue <KThread> SignaledThreads = new Queue <KThread>();

            System.CriticalSectionLock.Lock();

            IOrderedEnumerable <KThread> SortedThreads = CondVarThreads.OrderBy(x => x.DynamicPriority);

            foreach (KThread CondVarThread in SortedThreads.Where(x => x.CondVarAddress == Address))
            {
                TryAcquireMutex(Process, Memory, CondVarThread);

                SignaledThreads.Enqueue(CondVarThread);

                //If the count is <= 0, we should signal all threads waiting
                //for the conditional variable.
                if (Count >= 1 && --Count == 0)
                {
                    break;
                }
            }

            while (SignaledThreads.TryDequeue(out KThread Thread))
            {
                CondVarThreads.Remove(Thread);
            }

            System.CriticalSectionLock.Unlock();
        }
Exemplo n.º 11
0
        public IAudioRenderer(AMemory Memory, IAalOutput AudioOut, AudioRendererParameter Params)
        {
            m_Commands = new Dictionary <int, ServiceProcessRequest>()
            {
                { 4, RequestUpdateAudioRenderer },
                { 5, StartAudioRenderer },
                { 6, StopAudioRenderer },
                { 7, QuerySystemEvent }
            };

            UpdateEvent = new KEvent();

            this.Memory   = Memory;
            this.AudioOut = AudioOut;
            this.Params   = Params;

            Track = AudioOut.OpenTrack(
                AudioConsts.HostSampleRate,
                AudioConsts.HostChannelsCount,
                AudioCallback);

            MemoryPools = CreateArray <MemoryPoolContext>(Params.EffectCount + Params.VoiceCount * 4);

            Voices = CreateArray <VoiceContext>(Params.VoiceCount);

            InitializeAudioOut();
        }
Exemplo n.º 12
0
        private void ExecuteSubroutineA64(AThreadState State, AMemory Memory, long Position)
        {
            do
            {
                if (EnableCpuTrace)
                {
                    if (!SymbolTable.TryGetValue(Position, out string SubName))
                    {
                        SubName = string.Empty;
                    }

                    CpuTrace?.Invoke(this, new ACpuTraceEventArgs(Position, SubName));
                }

                if (!CachedSubs.TryGetValue(Position, out ATranslatedSub Sub))
                {
                    Sub = TranslateTier0(State, Memory, Position);
                }

                if (Sub.ShouldReJit())
                {
                    TranslateTier1(State, Memory, Position);
                }

                Position = Sub.Execute(State, Memory);
            }while (Position != 0 && State.Running);
        }
Exemplo n.º 13
0
 public void Teardown()
 {
     Thread    = null;
     Memory    = null;
     Allocator = null;
     Marshal.FreeHGlobal(Ram);
 }
Exemplo n.º 14
0
        private unsafe static byte[] Read8Bpt4x4(AMemory Memory, Texture Texture)
        {
            int Width  = (Texture.Width + 3) / 4;
            int Height = (Texture.Height + 3) / 4;

            byte[] Output = new byte[Width * Height * 8];

            ISwizzle Swizzle = GetSwizzle(Texture, 8);

            fixed(byte *BuffPtr = Output)
            {
                long OutOffs = 0;

                for (int Y = 0; Y < Height; Y++)
                {
                    for (int X = 0; X < Width; X++)
                    {
                        long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);

                        long Tile = Memory.ReadInt64Unchecked(Texture.Position + Offset);

                        *(long *)(BuffPtr + OutOffs) = Tile;

                        OutOffs += 8;
                    }
                }
            }

            return(Output);
        }
Exemplo n.º 15
0
 public void Teardown()
 {
     Marshal.FreeHGlobal(RamPointer);
     Memory     = null;
     Thread     = null;
     UnicornEmu = null;
 }
Exemplo n.º 16
0
        public long Execute(AThreadState ThreadState, AMemory Memory)
        {
            if (!HasDelegate)
            {
                string Name = $"{Method.Name}_Dispatch";

                DynamicMethod Mthd = new DynamicMethod(Name, typeof(long), FixedArgTypes);

                ILGenerator Generator = Mthd.GetILGenerator();

                Generator.EmitLdargSeq(FixedArgTypes.Length);

                foreach (ARegister Reg in Params)
                {
                    Generator.EmitLdarg(StateArgIdx);

                    Generator.Emit(OpCodes.Ldfld, Reg.GetField());
                }

                Generator.Emit(OpCodes.Call, Method);
                Generator.Emit(OpCodes.Ret);

                ExecDelegate = (AA64Subroutine)Mthd.CreateDelegate(typeof(AA64Subroutine));

                HasDelegate = true;
            }

            return(ExecDelegate(ThreadState, Memory));
        }
Exemplo n.º 17
0
        private unsafe static byte[] Read2Bpp(AMemory Memory, Texture Texture)
        {
            int Width  = Texture.Width;
            int Height = Texture.Height;

            byte[] Output = new byte[Width * Height * 2];

            ISwizzle Swizzle = GetSwizzle(Texture, 2);

            fixed(byte *BuffPtr = Output)
            {
                long OutOffs = 0;

                for (int Y = 0; Y < Height; Y++)
                {
                    for (int X = 0; X < Width; X++)
                    {
                        long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);

                        short Pixel = Memory.ReadInt16Unchecked(Texture.Position + Offset);

                        *(short *)(BuffPtr + OutOffs) = Pixel;

                        OutOffs += 2;
                    }
                }
            }

            return(Output);
        }
Exemplo n.º 18
0
        private void UploadTexture(AMemory Memory, long BasePosition, int TexIndex, int HndIndex)
        {
            long Position = BasePosition + HndIndex * 4;

            int TextureHandle = Memory.ReadInt32(Position);

            int TicIndex = (TextureHandle >> 0) & 0xfffff;
            int TscIndex = (TextureHandle >> 20) & 0xfff;

            TryGetCpuAddr(NvGpuEngine3dReg.TexHeaderPoolOffset, out long TicPosition);
            TryGetCpuAddr(NvGpuEngine3dReg.TexSamplerPoolOffset, out long TscPosition);

            TicPosition += TicIndex * 0x20;
            TscPosition += TscIndex * 0x20;

            GalTextureSampler Sampler = TextureFactory.MakeSampler(Gpu, Memory, TscPosition);

            long TextureAddress = Memory.ReadInt64(TicPosition + 4) & 0xffffffffffff;

            if (FrameBuffers.Contains(TextureAddress))
            {
                //This texture is a frame buffer texture,
                //we shouldn't read anything from memory and bind
                //the frame buffer texture instead, since we're not
                //really writing anything to memory.
                Gpu.Renderer.BindFrameBufferTexture(TextureAddress, TexIndex, Sampler);
            }
            else
            {
                GalTexture Texture = TextureFactory.MakeTexture(Gpu, Memory, TicPosition);

                Gpu.Renderer.SetTextureAndSampler(TexIndex, Texture, Sampler);
                Gpu.Renderer.BindTexture(TexIndex);
            }
        }
Exemplo n.º 19
0
        public Process(Switch Ns, AMemoryAlloc Allocator, int ProcessId)
        {
            this.Ns        = Ns;
            this.ProcessId = ProcessId;

            Memory = new AMemory(Ns.Ram, Allocator);

            Scheduler = new KProcessScheduler();

            SvcHandler = new SvcHandler(Ns, this);

            TlsSlots = new ConcurrentDictionary<int, AThread>();

            ThreadsByTpidr = new ConcurrentDictionary<long, HThread>();

            Executables = new List<Executable>();

            ImageBase = 0x8000000;

            Memory.Manager.MapPhys(
                TlsPageAddr,
                TlsTotalSize,
                (int)MemoryType.ThreadLocal,
                AMemoryPerm.RW);
        }
Exemplo n.º 20
0
        private void UploadUniforms(AMemory Memory)
        {
            long BasePosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress);

            for (int Index = 0; Index < 5; Index++)
            {
                int Control = ReadRegister(NvGpuEngine3dReg.ShaderNControl + (Index + 1) * 0x10);
                int Offset  = ReadRegister(NvGpuEngine3dReg.ShaderNOffset + (Index + 1) * 0x10);

                //Note: Vertex Program (B) is always enabled.
                bool Enable = (Control & 1) != 0 || Index == 0;

                if (!Enable)
                {
                    continue;
                }

                for (int Cbuf = 0; Cbuf < ConstBuffers.Length; Cbuf++)
                {
                    ConstBuffer Cb = ConstBuffers[Cbuf];

                    if (Cb.Enabled)
                    {
                        long CbPosition = Cb.Position + Index * Cb.Size;

                        byte[] Data = AMemoryHelper.ReadBytes(Memory, CbPosition, (uint)Cb.Size);

                        Gpu.Renderer.SetConstBuffer(BasePosition + (uint)Offset, Cbuf, Data);
                    }
                }
            }
        }
Exemplo n.º 21
0
        private ATranslatedSub TranslateTier0(AThreadState State, AMemory Memory, long Position)
        {
            ABlock Block = ADecoder.DecodeBasicBlock(State, Memory, Position);

            ABlock[] Graph = new ABlock[] { Block };

            string SubName = GetSubroutineName(Position);

            AILEmitterCtx Context = new AILEmitterCtx(Cache, Graph, Block, SubName);

            do
            {
                Context.EmitOpCode();
            }while (Context.AdvanceOpCode());

            ATranslatedSub Subroutine = Context.GetSubroutine();

            Subroutine.SetType(ATranslatedSubType.SubTier0);

            Cache.AddOrUpdate(Position, Subroutine, Block.OpCodes.Count);

            AOpCode LastOp = Block.GetLastOp();

            return(Subroutine);
        }
Exemplo n.º 22
0
        private void UploadTextures(AMemory Memory, long[] Tags)
        {
            long BaseShPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress);

            int TextureCbIndex = ReadRegister(NvGpuEngine3dReg.TextureCbIndex);

            long BasePosition = ConstBuffers[TextureCbIndex].Position;

            long Size = (uint)ConstBuffers[TextureCbIndex].Size;

            //Note: On the emulator renderer, Texture Unit 0 is
            //reserved for drawing the frame buffer.
            int TexIndex = 1;

            for (int Index = 0; Index < Tags.Length; Index++)
            {
                foreach (ShaderDeclInfo DeclInfo in Gpu.Renderer.GetTextureUsage(Tags[Index]))
                {
                    long Position = BasePosition + Index * Size;

                    UploadTexture(Memory, Position, TexIndex, DeclInfo.Index);

                    Gpu.Renderer.SetUniform1(DeclInfo.Name, TexIndex);

                    TexIndex++;
                }
            }
        }
Exemplo n.º 23
0
        public static string ReadHbAbiNextLoadPath(AMemory Memory, long Position)
        {
            string FileName = null;

            while (true)
            {
                long Key = Memory.ReadInt64(Position);

                if (Key == 2)
                {
                    long Value0 = Memory.ReadInt64(Position + 0x08);
                    long Value1 = Memory.ReadInt64(Position + 0x10);

                    FileName = AMemoryHelper.ReadAsciiString(Memory, Value0, Value1 - Value0);

                    break;
                }
                else if (Key == 0)
                {
                    break;
                }

                Position += 0x18;
            }

            return(FileName);
        }
Exemplo n.º 24
0
        public static GalTextureSampler MakeSampler(NsGpu Gpu, AMemory Memory, long TscPosition)
        {
            int[] Tsc = ReadWords(Memory, TscPosition, 8);

            GalTextureWrap AddressU = (GalTextureWrap)((Tsc[0] >> 0) & 7);
            GalTextureWrap AddressV = (GalTextureWrap)((Tsc[0] >> 3) & 7);
            GalTextureWrap AddressP = (GalTextureWrap)((Tsc[0] >> 6) & 7);

            GalTextureFilter    MagFilter = (GalTextureFilter)((Tsc[1] >> 0) & 3);
            GalTextureFilter    MinFilter = (GalTextureFilter)((Tsc[1] >> 4) & 3);
            GalTextureMipFilter MipFilter = (GalTextureMipFilter)((Tsc[1] >> 6) & 3);

            GalColorF BorderColor = new GalColorF(
                BitConverter.Int32BitsToSingle(Tsc[4]),
                BitConverter.Int32BitsToSingle(Tsc[5]),
                BitConverter.Int32BitsToSingle(Tsc[6]),
                BitConverter.Int32BitsToSingle(Tsc[7]));

            return(new GalTextureSampler(
                       AddressU,
                       AddressV,
                       AddressP,
                       MinFilter,
                       MagFilter,
                       MipFilter,
                       BorderColor));
        }
Exemplo n.º 25
0
        private void UploadTextures(AMemory Memory, long[] Tags)
        {
            long BaseShPosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress);

            int TextureCbIndex = ReadRegister(NvGpuEngine3dReg.TextureCbIndex);

            long BasePosition = Cbs[TextureCbIndex].Position;

            long Size = (uint)Cbs[TextureCbIndex].Size;

            int TexIndex = 0;

            for (int Index = 0; Index < Tags.Length; Index++)
            {
                foreach (ShaderDeclInfo DeclInfo in Gpu.Renderer.GetTextureUsage(Tags[Index]))
                {
                    long Position = BasePosition + Index * Size;

                    UploadTexture(Memory, Position, TexIndex, DeclInfo.Index);

                    Gpu.Renderer.SetUniform1(DeclInfo.Name, TexIndex);

                    TexIndex++;
                }
            }
        }
Exemplo n.º 26
0
        public Process(Switch Ns, KProcessScheduler Scheduler, int ProcessId)
        {
            this.Ns        = Ns;
            this.Scheduler = Scheduler;
            this.ProcessId = ProcessId;

            Memory = new AMemory();

            HandleTable = new KProcessHandleTable();

            AppletState = new AppletStateMgr();

            SvcHandler = new SvcHandler(Ns, this);

            TlsSlots = new ConcurrentDictionary <int, AThread>();

            ThreadsByTpidr = new ConcurrentDictionary <long, KThread>();

            Executables = new List <Executable>();

            ImageBase = MemoryRegions.AddrSpaceStart;

            MapRWMemRegion(
                MemoryRegions.TlsPagesAddress,
                MemoryRegions.TlsPagesSize,
                MemoryType.ThreadLocal);
        }
Exemplo n.º 27
0
        private void UpdateBuffer(AMemory Memory)
        {
            //TODO: Implement conversion for formats other
            //than interleaved stereo (2 channels).
            //As of now, it assumes that HostChannelsCount == 2.
            WaveBuffer Wb = WaveBuffers[BufferIndex];

            if (SampleFormat == SampleFormat.PcmInt16)
            {
                int SamplesCount = (int)(Wb.Size / (sizeof(short) * ChannelsCount));

                Samples = new int[SamplesCount * AudioConsts.HostChannelsCount];

                if (ChannelsCount == 1)
                {
                    for (int Index = 0; Index < SamplesCount; Index++)
                    {
                        short Sample = Memory.ReadInt16(Wb.Position + Index * 2);

                        Samples[Index * 2 + 0] = Sample;
                        Samples[Index * 2 + 1] = Sample;
                    }
                }
                else
                {
                    for (int Index = 0; Index < SamplesCount * 2; Index++)
                    {
                        Samples[Index] = Memory.ReadInt16(Wb.Position + Index * 2);
                    }
                }
            }
            else if (SampleFormat == SampleFormat.Adpcm)
            {
                byte[] Buffer = Memory.ReadBytes(Wb.Position, Wb.Size);

                Samples = AdpcmDecoder.Decode(Buffer, AdpcmCtx);
            }
            else
            {
                throw new InvalidOperationException();
            }

            if (SampleRate != AudioConsts.HostSampleRate)
            {
                //TODO: We should keep the frames being discarded (see the 4 below)
                //on a buffer and include it on the next samples buffer, to allow
                //the resampler to do seamless interpolation between wave buffers.
                int SamplesCount = Samples.Length / AudioConsts.HostChannelsCount;

                SamplesCount = Math.Max(SamplesCount - 4, 0);

                Samples = Resampler.Resample2Ch(
                    Samples,
                    SampleRate,
                    AudioConsts.HostSampleRate,
                    SamplesCount,
                    ref ResamplerFracPart);
            }
        }
Exemplo n.º 28
0
        private void Send(AMemory Memory, int Value)
        {
            NsGpuPBEntry PBEntry = new NsGpuPBEntry(MethAddr, 0, Value);

            Engine.CallMethod(Memory, PBEntry);

            MethAddr += MethIncr;
        }
Exemplo n.º 29
0
        private int ReadCb(AMemory Memory, int Cbuf, int Offset)
        {
            long Position = ConstBuffers[Cbuf].Position;

            int Value = Memory.ReadInt32(Position + Offset);

            return(Value);
        }
Exemplo n.º 30
0
        private void FetchOpCode(AMemory Memory)
        {
            OpCode = PipeOp;

            PipeOp = Memory.ReadInt32(Pc);

            Pc += 4;
        }