Exemplo n.º 1
0
        private void SvcSignalProcessWideKey(AThreadState ThreadState)
        {
            long CondVarAddress = (long)ThreadState.X0;
            int  Count          = (int)ThreadState.X1;

            HThread CurrThread = Process.GetThread(ThreadState.Tpidr);

            if (Ns.Os.CondVars.TryGetValue(CondVarAddress, out CondVar Cv))
            {
                Cv.SetSignal(CurrThread, Count);
            }

            ThreadState.X0 = (int)SvcResult.Success;
        }
Exemplo n.º 2
0
        public bool TestExclusive(AThreadState ThreadState, long Position)
        {
            Position &= ~ErgMask;

            lock (Monitors)
            {
                if (!Monitors.TryGetValue(ThreadState.ThreadId, out ExMonitor Monitor))
                {
                    return(false);
                }

                return(Monitor.HasExclusiveAccess(Position));
            }
        }
Exemplo n.º 3
0
        private void SvcGetThreadPriority(AThreadState ThreadState)
        {
            int Handle = (int)ThreadState.X1;

            HThread Thread = Ns.Os.Handles.GetData <HThread>(Handle);

            if (Thread != null)
            {
                ThreadState.X1 = (ulong)Thread.Priority;
                ThreadState.X0 = (int)SvcResult.Success;
            }

            //TODO: Error codes.
        }
Exemplo n.º 4
0
        private void SvcWaitForAddress(AThreadState ThreadState)
        {
            long            Address = (long)ThreadState.X0;
            ArbitrationType Type    = (ArbitrationType)ThreadState.X1;
            int             Value   = (int)ThreadState.X2;
            ulong           Timeout = ThreadState.X3;

            Ns.Log.PrintDebug(LogClass.KernelSvc,
                              "Address = " + Address.ToString("x16") + ", " +
                              "ArbitrationType = " + Type.ToString() + ", " +
                              "Value = " + Value.ToString("x8") + ", " +
                              "Timeout = " + Timeout.ToString("x16"));

            if (IsPointingInsideKernel(Address))
            {
                Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid address 0x{Address:x16}!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);

                return;
            }

            if (IsWordAddressUnaligned(Address))
            {
                Ns.Log.PrintWarning(LogClass.KernelSvc, $"Unaligned address 0x{Address:x16}!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);

                return;
            }

            switch (Type)
            {
            case ArbitrationType.WaitIfLessThan:
                ThreadState.X0 = AddressArbiter.WaitForAddressIfLessThan(Process, ThreadState, Memory, Address, Value, Timeout, false);
                break;

            case ArbitrationType.DecrementAndWaitIfLessThan:
                ThreadState.X0 = AddressArbiter.WaitForAddressIfLessThan(Process, ThreadState, Memory, Address, Value, Timeout, true);
                break;

            case ArbitrationType.WaitIfEqual:
                ThreadState.X0 = AddressArbiter.WaitForAddressIfEqual(Process, ThreadState, Memory, Address, Value, Timeout);
                break;

            default:
                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidEnumValue);
                break;
            }
        }
Exemplo n.º 5
0
        public void Frecps_V([Random(10)] float A, [Random(10)] float B)
        {
            AThreadState ThreadState = SingleOpcode(0x4E20FC44, V2: new AVec {
                S0 = A, S1 = A, S2 = A, S3 = A
            },
                                                    V0: new AVec {
                S0 = B, S1 = B, S2 = B, S3 = B
            });

            Assert.That(ThreadState.V4.S0, Is.EqualTo(2 - (A * B)));
            Assert.That(ThreadState.V4.S1, Is.EqualTo(2 - (A * B)));
            Assert.That(ThreadState.V4.S2, Is.EqualTo(2 - (A * B)));
            Assert.That(ThreadState.V4.S3, Is.EqualTo(2 - (A * B)));
        }
Exemplo n.º 6
0
        public void Adds(uint A, bool Zero, bool Carry)
        {
            //ADDS WZR, WSP, #5
            AThreadState ThreadState = SingleOpcode(0x310017FF, X31: A);

            Assert.Multiple(() =>
            {
                Assert.IsFalse(ThreadState.Negative);
                Assert.IsFalse(ThreadState.Overflow);
                Assert.AreEqual(Zero, ThreadState.Zero);
                Assert.AreEqual(Carry, ThreadState.Carry);
                Assert.AreEqual(A, ThreadState.X31);
            });
        }
Exemplo n.º 7
0
        public void Fmax_V(uint A, uint B, uint C, uint D, uint Result0, uint Result1)
        {
            uint Opcode                   = 0x4E22F420;
            Vector128 <float> V1          = MakeVectorE0E1(A, B);
            Vector128 <float> V2          = MakeVectorE0E1(C, D);
            AThreadState      ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);

            Assert.Multiple(() =>
            {
                Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
                Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
            });
            CompareAgainstUnicorn();
        }
Exemplo n.º 8
0
        public void Adcs(uint Opcode, uint A, uint B, bool CarryState, bool Negative, bool Zero, bool Carry, uint Result)
        {
            //ADCS (X0/W0), (X1, W1), (X2/W2)
            AThreadState ThreadState = SingleOpcode(Opcode, X1: A, X2: B, Carry: CarryState);

            Assert.Multiple(() =>
            {
                Assert.IsFalse(ThreadState.Overflow);
                Assert.AreEqual(Negative, ThreadState.Negative);
                Assert.AreEqual(Zero, ThreadState.Zero);
                Assert.AreEqual(Carry, ThreadState.Carry);
                Assert.AreEqual(Result, ThreadState.X0);
            });
        }
Exemplo n.º 9
0
        public void Frintp_S(uint A, bool DefaultNaN, uint Result)
        {
            int FpcrTemp = 0x0;

            if (DefaultNaN)
            {
                FpcrTemp = 0x2000000;
            }
            Vector128 <float> V1          = MakeVectorE0(A);
            AThreadState      ThreadState = SingleOpcode(0x1E24C020, V1: V1, Fpcr: FpcrTemp);

            Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
            CompareAgainstUnicorn();
        }
Exemplo n.º 10
0
        public void Trn2_V_4S([Random(2)] uint A0, [Random(2)] uint A1, [Random(2)] uint A2, [Random(2)] uint A3,
                              [Random(2)] uint B0, [Random(2)] uint B1, [Random(2)] uint B2, [Random(2)] uint B3)
        {
            uint Opcode          = 0x4E826820;
            Vector128 <float> V1 = Sse.StaticCast <uint, float>(Sse2.SetVector128(A3, A2, A1, A0));
            Vector128 <float> V2 = Sse.StaticCast <uint, float>(Sse2.SetVector128(B3, B2, B1, B0));

            AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);

            Assert.That(Sse41.Extract(Sse.StaticCast <float, uint>(ThreadState.V0), (byte)0), Is.EqualTo(A1));
            Assert.That(Sse41.Extract(Sse.StaticCast <float, uint>(ThreadState.V0), (byte)1), Is.EqualTo(B1));
            Assert.That(Sse41.Extract(Sse.StaticCast <float, uint>(ThreadState.V0), (byte)2), Is.EqualTo(A3));
            Assert.That(Sse41.Extract(Sse.StaticCast <float, uint>(ThreadState.V0), (byte)3), Is.EqualTo(B3));
        }
Exemplo n.º 11
0
        private void SvcGetThreadPriority(AThreadState ThreadState)
        {
            int Handle = (int)ThreadState.X1;

            KThread Thread = Process.HandleTable.GetData <KThread>(Handle);

            if (Thread != null)
            {
                ThreadState.X0 = 0;
                ThreadState.X1 = (ulong)Thread.Priority;
            }

            //TODO: Error codes.
        }
Exemplo n.º 12
0
        private void SvcUnmapPhysicalMemory(AThreadState ThreadState)
        {
            long Position = (long)ThreadState.X0;
            long Size     = (long)ThreadState.X1;

            if (!PageAligned(Position))
            {
                Device.Log.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);

                return;
            }

            if (!PageAligned(Size) || Size == 0)
            {
                Device.Log.PrintWarning(LogClass.KernelSvc, $"Size 0x{Size:x16} is not page aligned or is zero!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidSize);

                return;
            }

            if ((ulong)(Position + Size) <= (ulong)Position)
            {
                Device.Log.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Position:x16} / size 0x{Size:x16}!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);

                return;
            }

            if (!InsideAddrSpace(Position, Size))
            {
                Device.Log.PrintWarning(LogClass.KernelSvc, $"Invalid address {Position:x16}!");

                ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);

                return;
            }

            long Result = Process.MemoryManager.UnmapPhysicalMemory(Position, Size);

            if (Result != 0)
            {
                Device.Log.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{Result:x}!");
            }

            ThreadState.X0 = (ulong)Result;
        }
Exemplo n.º 13
0
        private void SvcGetInfo(AThreadState ThreadState)
        {
            long StackPtr = (long)ThreadState.X0;
            int  InfoType = (int)ThreadState.X1;
            long Handle   = (long)ThreadState.X2;
            int  InfoId   = (int)ThreadState.X3;

            //Fail for info not available on older Kernel versions.
            if (InfoType == 18 ||
                InfoType == 19)
            {
                ThreadState.X0 = (int)SvcResult.ErrBadInfo;

                return;
            }

            switch (InfoType)
            {
            case 0:  ThreadState.X1 = AllowedCpuIdBitmask();           break;

            case 2:  ThreadState.X1 = GetMapRegionBaseAddr();          break;

            case 3:  ThreadState.X1 = GetMapRegionSize();              break;

            case 4:  ThreadState.X1 = GetHeapRegionBaseAddr();         break;

            case 5:  ThreadState.X1 = GetHeapRegionSize();             break;

            case 6:  ThreadState.X1 = GetTotalMem();                   break;

            case 7:  ThreadState.X1 = GetUsedMem();                    break;

            case 8:  ThreadState.X1 = IsCurrentProcessBeingDebugged(); break;

            case 11: ThreadState.X1 = GetRnd64();                      break;

            case 12: ThreadState.X1 = GetAddrSpaceBaseAddr();          break;

            case 13: ThreadState.X1 = GetAddrSpaceSize();              break;

            case 14: ThreadState.X1 = GetMapRegionBaseAddr();          break;

            case 15: ThreadState.X1 = GetMapRegionSize();              break;

            default: throw new NotImplementedException($"SvcGetInfo: {InfoType} {Handle} {InfoId}");
            }

            ThreadState.X0 = (int)SvcResult.Success;
        }
Exemplo n.º 14
0
        private void SvcStartThread(AThreadState ThreadState)
        {
            int Handle = (int)ThreadState.X0;

            HThread Thread = Ns.Os.Handles.GetData <HThread>(Handle);

            if (Thread != null)
            {
                Process.Scheduler.StartThread(Thread);

                ThreadState.X0 = (int)SvcResult.Success;
            }

            //TODO: Error codes.
        }
Exemplo n.º 15
0
        private void SvcSleepThread(AThreadState ThreadState)
        {
            ulong NanoSecs = ThreadState.X0;

            HThread CurrThread = Process.GetThread(ThreadState.Tpidr);

            if (NanoSecs == 0)
            {
                Process.Scheduler.Yield(CurrThread);
            }
            else
            {
                Process.Scheduler.WaitForSignal(CurrThread, (int)(NanoSecs / 1000000));
            }
        }
Exemplo n.º 16
0
        [TestCase((ushort)0x0001, 0x33800000u)] // 5.96046448e-8 (Smallest Subnormal)
        public void Fcvtl_V_f16(ushort Value, uint Result)
        {
            uint Opcode          = 0x0E217801;
            Vector128 <float> V0 = Sse.StaticCast <ushort, float>(Sse2.SetAllVector128(Value));

            AThreadState ThreadState = SingleOpcode(Opcode, V0: V0);

            Assert.Multiple(() =>
            {
                Assert.That(Sse41.Extract(Sse.StaticCast <float, uint>(ThreadState.V1), (byte)0), Is.EqualTo(Result));
                Assert.That(Sse41.Extract(Sse.StaticCast <float, uint>(ThreadState.V1), (byte)1), Is.EqualTo(Result));
                Assert.That(Sse41.Extract(Sse.StaticCast <float, uint>(ThreadState.V1), (byte)2), Is.EqualTo(Result));
                Assert.That(Sse41.Extract(Sse.StaticCast <float, uint>(ThreadState.V1), (byte)3), Is.EqualTo(Result));
            });
        }
Exemplo n.º 17
0
        public void Movz_64bit([Values(0u, 31u)] uint Rd,
                               [Values(0u, 65535u)][Random(0u, 65535u, RndCntImm)] uint imm,
                               [Values(0u, 16u, 32u, 48u)] uint shift)
        {
            uint Opcode = 0xD2800000; // MOVZ X0, #0, LSL #0

            Opcode |= ((Rd & 31) << 0);
            Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);

            ulong _X31 = TestContext.CurrentContext.Random.NextULong();

            AThreadState ThreadState = SingleOpcode(Opcode, X31: _X31);

            CompareAgainstUnicorn();
        }
Exemplo n.º 18
0
        public void Frinta_S(uint A, bool DefaultNaN, uint Result)
        {
            int FpcrTemp = 0x0;

            if (DefaultNaN)
            {
                FpcrTemp = 0x2000000;
            }
            AVec V1 = new AVec {
                X0 = A
            };
            AThreadState ThreadState = SingleOpcode(0x1E264020, V1: V1, Fpcr: FpcrTemp);

            Assert.AreEqual(Result, ThreadState.V0.X0);
        }
Exemplo n.º 19
0
        static ulong WaitForAddress(Process Process, AThreadState ThreadState, long Address, ulong Timeout)
        {
            //TODO: Update.
            KThread CurrentThread = Process.GetThread(ThreadState.Tpidr);

            CurrentThread.ArbiterWaitAddress = Address;
            CurrentThread.ArbiterSignaled    = false;

            if (!CurrentThread.ArbiterSignaled)
            {
                return(MakeError(ErrorModule.Kernel, KernelErr.Timeout));
            }

            return(0);
        }
Exemplo n.º 20
0
        private void SvcConnectToNamedPort(AThreadState ThreadState)
        {
            long StackPtr = (long)ThreadState.X0;
            long NamePtr  = (long)ThreadState.X1;

            string Name = AMemoryHelper.ReadAsciiString(Memory, NamePtr, 8);

            //TODO: Validate that app has perms to access the service, and that the service
            //actually exists, return error codes otherwise.

            HSession Session = new HSession(Name);

            ThreadState.X1 = (ulong)Ns.Os.Handles.GenerateId(Session);
            ThreadState.X0 = (int)SvcResult.Success;
        }
Exemplo n.º 21
0
        private void SvcWaitSynchronization(AThreadState ThreadState)
        {
            long HandlesPtr   = (long)ThreadState.X0;
            int  HandlesCount = (int)ThreadState.X2;
            long Timeout      = (long)ThreadState.X3;

            //TODO: Implement events.

            HThread CurrThread = Process.GetThread(ThreadState.Tpidr);

            Process.Scheduler.Suspend(CurrThread.ProcessorId);
            Process.Scheduler.Resume(CurrThread);

            ThreadState.X0 = (int)SvcResult.Success;
        }
Exemplo n.º 22
0
        private void SvcUnmapSharedMemory(AThreadState ThreadState)
        {
            int  Handle   = (int)ThreadState.X0;
            long Position = (long)ThreadState.X1;
            long Size     = (long)ThreadState.X2;

            HSharedMem HndData = Ns.Os.Handles.GetData <HSharedMem>(Handle);

            if (HndData != null)
            {
                ThreadState.X0 = (int)SvcResult.Success;
            }

            //TODO: Error codes.
        }
Exemplo n.º 23
0
        public static ulong BinaryUnsignedSatQSub(ulong op1, ulong op2, AThreadState State)
        {
            ulong Sub = op1 - op2;

            if (op1 < op2)
            {
                SetFpsrQCFlag(State);

                return(ulong.MinValue);
            }
            else
            {
                return(Sub);
            }
        }
Exemplo n.º 24
0
        private void SvcStartThread(AThreadState ThreadState)
        {
            int Handle = (int)ThreadState.X0;

            KThread Thread = Process.HandleTable.GetData <KThread>(Handle);

            if (Thread != null)
            {
                Process.Scheduler.StartThread(Thread);

                ThreadState.X0 = 0;
            }

            //TODO: Error codes.
        }
Exemplo n.º 25
0
        public static ulong BinaryUnsignedSatQAdd(ulong op1, ulong op2, AThreadState State)
        {
            ulong Add = op1 + op2;

            if ((Add < op1) && (Add < op2))
            {
                SetFpsrQCFlag(State);

                return(ulong.MaxValue);
            }
            else
            {
                return(Add);
            }
        }
Exemplo n.º 26
0
        private void SvcSignalProcessWideKey(AThreadState ThreadState)
        {
            long CondVarAddress = (long)ThreadState.X0;
            int  Count          = (int)ThreadState.X1;

            Ns.Log.PrintDebug(LogClass.KernelSvc,
                              "CondVarAddress = " + CondVarAddress.ToString("x16") + ", " +
                              "Count = " + Count.ToString("x8"));

            KThread CurrThread = Process.GetThread(ThreadState.Tpidr);

            CondVarSignal(CurrThread, CondVarAddress, Count);

            ThreadState.X0 = 0;
        }
Exemplo n.º 27
0
        public void Dup_Gp_X([Values(0u)]      uint Rd,
                             [Values(1u, 31u)] uint Rn,
                             [ValueSource("_X_")][Random(RndCnt)] ulong Xn)
        {
            uint Opcode = 0x4E080C00; // DUP V0.2D, X0

            Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);

            ulong             Z  = TestContext.CurrentContext.Random.NextULong();
            Vector128 <float> V0 = MakeVectorE0E1(Z, Z);

            AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, V0: V0);

            CompareAgainstUnicorn();
        }
Exemplo n.º 28
0
        public void Rbit_64bit([Values(0u, 31u)] uint Rd,
                               [Values(1u, 31u)] uint Rn,
                               [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
                                       0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)][Random(RndCnt)] ulong Xn)
        {
            uint Opcode = 0xDAC00000; // RBIT X0, X0

            Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);

            ulong _X31 = TestContext.CurrentContext.Random.NextULong();

            AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);

            CompareAgainstUnicorn();
        }
Exemplo n.º 29
0
        public void Zip2_V(uint Q, uint size, ulong Result_0, ulong Result_1)
        {
            // ZIP2 V0.<T>, V1.<T>, V2.<T>
            uint Opcode = 0x0E027820 | (Q << 30) | (size << 22);
            AVec V1     = new AVec {
                X0 = 0x1716151413121110, X1 = 0x1F1E1D1C1B1A1918
            };
            AVec V2 = new AVec {
                X0 = 0x2726252423222120, X1 = 0x2F2E2D2C2B2A2928
            };
            AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);

            Assert.AreEqual(Result_0, ThreadState.V0.X0);
            Assert.AreEqual(Result_1, ThreadState.V0.X1);
        }
Exemplo n.º 30
0
        public void Clz_32bit([Values(0u, 31u)] uint Rd,
                              [Values(1u, 31u)] uint Rn,
                              [Values(0x00000000u, 0x7FFFFFFFu,
                                      0x80000000u, 0xFFFFFFFFu)][Random(RndCnt)] uint Wn)
        {
            uint Opcode = 0x5AC01000; // CLZ W0, W0

            Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);

            uint _W31 = TestContext.CurrentContext.Random.NextUInt();

            AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);

            CompareAgainstUnicorn();
        }