Пример #1
0
        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;
        }
Пример #2
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;
            }
        }
Пример #3
0
        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;
        }