示例#1
0
        public void Add()
        {
            // ADD X0, X1, X2
            ARegisters Registers = SingleOpcode(0x8B020020, X1: 1, X2: 2);

            Assert.AreEqual(3, Registers.X0);
        }
示例#2
0
        private void SvcCreateThread(ARegisters Registers)
        {
            long EntryPoint  = (long)Registers.X1;
            long ArgsPtr     = (long)Registers.X2;
            long StackTop    = (long)Registers.X3;
            int  Priority    = (int)Registers.X4;
            int  ProcessorId = (int)Registers.X5;

            if (Ns.Os.TryGetProcess(Registers.ProcessId, out Process Process))
            {
                if (ProcessorId == -2)
                {
                    ProcessorId = 0;
                }

                int Handle = Process.MakeThread(
                    EntryPoint,
                    StackTop,
                    ArgsPtr,
                    Priority,
                    ProcessorId);

                Registers.X0 = (int)SvcResult.Success;
                Registers.X1 = (ulong)Handle;
            }

            //TODO: Error codes.
        }
示例#3
0
        public void RevX0X0()
        {
            // REV X0, X0
            ARegisters Registers = SingleOpcode(0xDAC00C00, X0: 0xAABBCCDDEEFF1100);

            Assert.AreEqual(0x0011FFEEDDCCBBAA, Registers.X0);
        }
示例#4
0
        public void RevW1W1()
        {
            // REV W1, W1
            ARegisters Registers = SingleOpcode(0x5AC00821, X1: 0x12345678);

            Assert.AreEqual(0x78563412, Registers.X1);
        }
示例#5
0
        private static void SvcWaitProcessWideKeyAtomic(Switch Ns, ARegisters Registers, AMemory Memory)
        {
            long MutexAddress   = (long)Registers.X0;
            long CondVarAddress = (long)Registers.X1;
            int  ThreadHandle   = (int)Registers.X2;
            long Timeout        = (long)Registers.X3;

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

            if (Ns.Os.Mutexes.TryGetValue(MutexAddress, out Mutex M))
            {
                M.GiveUpLock(ThreadHandle);
            }

            CondVar Signal = new CondVar(Memory, CondVarAddress, Timeout);

            Signal = Ns.Os.CondVars.GetOrAdd(CondVarAddress, Signal);

            Signal.WaitForSignal(ThreadHandle);

            M = new Mutex(Memory, MutexAddress);

            M = Ns.Os.Mutexes.GetOrAdd(MutexAddress, M);

            //FIXME
            //M.WaitForLock(Thread, ThreadHandle);

            Memory.WriteInt32(MutexAddress, 0);

            Registers.X0 = (int)SvcResult.Success;
        }
示例#6
0
        private void SvcWaitProcessWideKeyAtomic(ARegisters Registers)
        {
            long MutexAddress   = (long)Registers.X0;
            long CondVarAddress = (long)Registers.X1;
            int  ThreadHandle   = (int)Registers.X2;
            long Timeout        = (long)Registers.X3;

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

            if (Ns.Os.Mutexes.TryGetValue(MutexAddress, out Mutex M))
            {
                M.GiveUpLock(ThreadHandle);
            }

            CondVar Cv = new CondVar(Process, CondVarAddress, Timeout);

            Cv = Ns.Os.CondVars.GetOrAdd(CondVarAddress, Cv);

            Cv.WaitForSignal(Thread);

            M = new Mutex(Process, MutexAddress, ThreadHandle);

            M = Ns.Os.Mutexes.GetOrAdd(MutexAddress, M);

            M.WaitForLock(Thread, ThreadHandle);

            Registers.X0 = (int)SvcResult.Success;
        }
示例#7
0
        public long Execute(ARegisters Registers, 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(RegistersArgIdx);

                    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(Registers, Memory));
        }
示例#8
0
        private static void SvcResetSignal(Switch Ns, ARegisters Registers, AMemory Memory)
        {
            int Handle = (int)Registers.X0;

            //TODO: Implement events.

            Registers.X0 = (int)SvcResult.Success;
        }
示例#9
0
        private static void SvcBreak(Switch Ns, ARegisters Registers, AMemory Memory)
        {
            long Reason  = (long)Registers.X0;
            long Unknown = (long)Registers.X1;
            long Info    = (long)Registers.X2;

            throw new Exception($"SvcBreak: {Reason} {Unknown} {Info}");
        }
示例#10
0
        private static void SvcCloseHandle(Switch Ns, ARegisters Registers, AMemory Memory)
        {
            int Handle = (int)Registers.X0;

            Ns.Os.CloseHandle(Handle);

            Registers.X0 = (int)SvcResult.Success;
        }
示例#11
0
        private void SvcResetSignal(ARegisters Registers)
        {
            int Handle = (int)Registers.X0;

            //TODO: Implement events.

            Registers.X0 = (int)SvcResult.Success;
        }
示例#12
0
        private void SvcBreak(ARegisters Registers)
        {
            long Reason  = (long)Registers.X0;
            long Unknown = (long)Registers.X1;
            long Info    = (long)Registers.X2;

            throw new GuestBrokeExecutionException();
        }
示例#13
0
        private void SvcCloseHandle(ARegisters Registers)
        {
            int Handle = (int)Registers.X0;

            Ns.Os.CloseHandle(Handle);

            Registers.X0 = (int)SvcResult.Success;
        }
示例#14
0
        private void SvcSetHeapSize(ARegisters Registers)
        {
            uint Size = (uint)Registers.X1;

            Memory.Manager.SetHeapSize(Size, (int)MemoryType.Heap);

            Registers.X0 = (int)SvcResult.Success;
            Registers.X1 = (ulong)Memory.Manager.HeapAddr;
        }
示例#15
0
        private static void SvcSetHeapSize(Switch Ns, ARegisters Registers, AMemory Memory)
        {
            uint Size = (uint)Registers.X1;

            Memory.Manager.SetHeapSize(Size, (int)MemoryType.Heap);

            Registers.X0 = (int)SvcResult.Success;
            Registers.X1 = (ulong)Memory.Manager.HeapAddr;
        }
示例#16
0
        public AThread(AMemory Memory, long EntryPoint = 0, int Priority = 0)
        {
            this.Memory     = Memory;
            this.EntryPoint = EntryPoint;
            this.Priority   = Priority;

            Registers  = new ARegisters();
            Translator = new ATranslator(this);
        }
示例#17
0
        private static void SvcMapMemory(Switch Ns, ARegisters Registers, AMemory Memory)
        {
            long Dst  = (long)Registers.X0;
            long Src  = (long)Registers.X1;
            long Size = (long)Registers.X2;

            Memory.Manager.MapMirror(Src, Dst, Size, (int)MemoryType.MappedMemory);

            Registers.X0 = (int)SvcResult.Success;
        }
示例#18
0
        private static void SvcWaitSynchronization(Switch Ns, ARegisters Registers, AMemory Memory)
        {
            long HandlesPtr   = (long)Registers.X0;
            int  HandlesCount = (int)Registers.X2;
            long Timeout      = (long)Registers.X3;

            //TODO: Implement events.

            Registers.X0 = (int)SvcResult.Success;
        }
示例#19
0
        public AThread(AMemory Memory, ThreadPriority Priority, long EntryPoint)
        {
            this.Memory     = Memory;
            this.Priority   = Priority;
            this.EntryPoint = EntryPoint;

            Registers   = new ARegisters();
            Translator  = new ATranslator(this);
            ExecuteLock = new object();
        }
示例#20
0
        private void SvcOutputDebugString(ARegisters Registers)
        {
            long Position = (long)Registers.X0;
            long Size     = (long)Registers.X1;

            string Str = AMemoryHelper.ReadAsciiString(Memory, Position, (int)Size);

            Logging.Info($"SvcOutputDebugString: {Str}");

            Registers.X0 = (int)SvcResult.Success;
        }
示例#21
0
        private void SvcSetMemoryAttribute(ARegisters Registers)
        {
            long Position = (long)Registers.X0;
            long Size     = (long)Registers.X1;
            int  State0   = (int)Registers.X2;
            int  State1   = (int)Registers.X3;

            //TODO

            Registers.X0 = (int)SvcResult.Success;
        }
示例#22
0
        private void SvcArbitrateUnlock(ARegisters Registers)
        {
            long MutexAddress = (long)Registers.X0;

            if (Ns.Os.Mutexes.TryGetValue(MutexAddress, out Mutex M))
            {
                M.Unlock();
            }

            Registers.X0 = (int)SvcResult.Success;
        }
示例#23
0
 public void ClearExclusive(ARegisters Registers)
 {
     lock (Monitors)
     {
         if (Monitors.TryGetValue(Registers.ThreadId, out ExMonitor Monitor))
         {
             Monitor.Reset();
             ExAddrs.Remove(Monitor.Position);
         }
     }
 }
示例#24
0
        private static void SvcArbitrateUnlock(Switch Ns, ARegisters Registers, AMemory Memory)
        {
            long MutexAddress = (long)Registers.X0;

            if (Ns.Os.Mutexes.TryGetValue(MutexAddress, out Mutex M))
            {
                M.Unlock();
            }

            Registers.X0 = (int)SvcResult.Success;
        }
示例#25
0
        private static void SvcSetMemoryAttribute(Switch Ns, ARegisters Registers, AMemory Memory)
        {
            long Position = (long)Registers.X0;
            long Size     = (long)Registers.X1;
            int  State0   = (int)Registers.X2;
            int  State1   = (int)Registers.X3;

            //TODO

            Registers.X0 = (int)SvcResult.Success;
        }
示例#26
0
        private static void SvcOutputDebugString(Switch Ns, ARegisters Registers, AMemory Memory)
        {
            long Position = (long)Registers.X0;
            long Size     = (long)Registers.X1;

            string Str = AMemoryHelper.ReadAsciiString(Memory, Position, (int)Size);

            Console.WriteLine($"SvcOutputDebugString: {Str}");

            Registers.X0 = (int)SvcResult.Success;
        }
示例#27
0
        private void SvcSignalProcessWideKey(ARegisters Registers)
        {
            long CondVarAddress = (long)Registers.X0;
            int  Count          = (int)Registers.X1;

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

            Registers.X0 = (int)SvcResult.Success;
        }
示例#28
0
        public void SvcCall(object sender, SvcEventArgs e)
        {
            ARegisters Registers = (ARegisters)sender;

            if (SvcFuncs.TryGetValue(e.Id, out SvcFunc Func))
            {
                Func(Ns, Registers, Memory);
            }
            else
            {
                throw new NotImplementedException(e.Id.ToString("x3"));
            }
        }
示例#29
0
        private static void SvcSleepThread(Switch Ns, ARegisters Registers, AMemory Memory)
        {
            ulong NanoSecs = Registers.X0;

            if (NanoSecs == 0)
            {
                Thread.Yield();
            }
            else
            {
                Thread.Sleep((int)(NanoSecs / 1000000));
            }
        }
示例#30
0
        private void SvcGetThreadPriority(ARegisters Registers)
        {
            int Handle = (int)Registers.X1;

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

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

            //TODO: Error codes.
        }