public void Add() { // ADD X0, X1, X2 ARegisters Registers = SingleOpcode(0x8B020020, X1: 1, X2: 2); Assert.AreEqual(3, Registers.X0); }
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. }
public void RevX0X0() { // REV X0, X0 ARegisters Registers = SingleOpcode(0xDAC00C00, X0: 0xAABBCCDDEEFF1100); Assert.AreEqual(0x0011FFEEDDCCBBAA, Registers.X0); }
public void RevW1W1() { // REV W1, W1 ARegisters Registers = SingleOpcode(0x5AC00821, X1: 0x12345678); Assert.AreEqual(0x78563412, Registers.X1); }
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; }
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; }
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)); }
private static void SvcResetSignal(Switch Ns, ARegisters Registers, AMemory Memory) { int Handle = (int)Registers.X0; //TODO: Implement events. Registers.X0 = (int)SvcResult.Success; }
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}"); }
private static void SvcCloseHandle(Switch Ns, ARegisters Registers, AMemory Memory) { int Handle = (int)Registers.X0; Ns.Os.CloseHandle(Handle); Registers.X0 = (int)SvcResult.Success; }
private void SvcResetSignal(ARegisters Registers) { int Handle = (int)Registers.X0; //TODO: Implement events. Registers.X0 = (int)SvcResult.Success; }
private void SvcBreak(ARegisters Registers) { long Reason = (long)Registers.X0; long Unknown = (long)Registers.X1; long Info = (long)Registers.X2; throw new GuestBrokeExecutionException(); }
private void SvcCloseHandle(ARegisters Registers) { int Handle = (int)Registers.X0; Ns.Os.CloseHandle(Handle); Registers.X0 = (int)SvcResult.Success; }
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; }
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; }
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); }
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; }
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; }
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(); }
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; }
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; }
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; }
public void ClearExclusive(ARegisters Registers) { lock (Monitors) { if (Monitors.TryGetValue(Registers.ThreadId, out ExMonitor Monitor)) { Monitor.Reset(); ExAddrs.Remove(Monitor.Position); } } }
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; }
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; }
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; }
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; }
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")); } }
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)); } }
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. }