private void SvcWaitForAddress(CpuThreadState ThreadState) { long Address = (long)ThreadState.X0; ArbitrationType Type = (ArbitrationType)ThreadState.X1; int Value = (int)ThreadState.X2; long Timeout = (long)ThreadState.X3; Logger.PrintDebug(LogClass.KernelSvc, "Address = 0x" + Address.ToString("x16") + ", " + "Type = " + Type.ToString() + ", " + "Value = 0x" + Value.ToString("x8") + ", " + "Timeout = 0x" + Timeout.ToString("x16")); if (IsPointingInsideKernel(Address)) { Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address 0x{Address:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); return; } if (IsAddressNotWordAligned(Address)) { Logger.PrintWarning(LogClass.KernelSvc, $"Unaligned address 0x{Address:x16}!"); ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress); return; } long Result; switch (Type) { case ArbitrationType.WaitIfLessThan: Result = System.AddressArbiter.WaitForAddressIfLessThan(Memory, Address, Value, false, Timeout); break; case ArbitrationType.DecrementAndWaitIfLessThan: Result = System.AddressArbiter.WaitForAddressIfLessThan(Memory, Address, Value, true, Timeout); break; case ArbitrationType.WaitIfEqual: Result = System.AddressArbiter.WaitForAddressIfEqual(Memory, Address, Value, Timeout); break; default: Result = MakeError(ErrorModule.Kernel, KernelErr.InvalidEnumValue); break; } if (Result != 0) { Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{Result:x}!"); } ThreadState.X0 = (ulong)Result; }
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; } }
private void SvcWaitForAddress(CpuThreadState threadState) { long address = (long)threadState.X0; ArbitrationType type = (ArbitrationType)threadState.X1; int value = (int)threadState.X2; long timeout = (long)threadState.X3; Logger.PrintDebug(LogClass.KernelSvc, "Address = 0x" + address.ToString("x16") + ", " + "Type = " + type.ToString() + ", " + "Value = 0x" + value.ToString("x8") + ", " + "Timeout = 0x" + timeout.ToString("x16")); if (IsPointingInsideKernel(address)) { Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address 0x{address:x16}!"); threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm); return; } if (IsAddressNotWordAligned(address)) { Logger.PrintWarning(LogClass.KernelSvc, $"Unaligned address 0x{address:x16}!"); threadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress); return; } KProcess currentProcess = _system.Scheduler.GetCurrentProcess(); long result; switch (type) { case ArbitrationType.WaitIfLessThan: result = currentProcess.AddressArbiter.WaitForAddressIfLessThan(address, value, false, timeout); break; case ArbitrationType.DecrementAndWaitIfLessThan: result = currentProcess.AddressArbiter.WaitForAddressIfLessThan(address, value, true, timeout); break; case ArbitrationType.WaitIfEqual: result = currentProcess.AddressArbiter.WaitForAddressIfEqual(address, value, timeout); break; default: result = MakeError(ErrorModule.Kernel, KernelErr.InvalidEnumValue); break; } if (result != 0) { Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{result:x}!"); } threadState.X0 = (ulong)result; }