Example #1
0
        private KernelResult GetInfo(uint Id, int Handle, long SubId, out long Value)
        {
            Value = 0;

            switch (Id)
            {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
            case 12:
            case 13:
            case 14:
            case 15:
            case 16:
            case 17:
            case 18:
            case 20:
            case 21:
            case 22:
            {
                if (SubId != 0)
                {
                    return(KernelResult.InvalidCombination);
                }

                KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();

                KProcess Process = CurrentProcess.HandleTable.GetKProcess(Handle);

                if (Process == null)
                {
                    return(KernelResult.InvalidHandle);
                }

                switch (Id)
                {
                case 0: Value = Process.Capabilities.AllowedCpuCoresMask;    break;

                case 1: Value = Process.Capabilities.AllowedThreadPriosMask; break;

                case 2: Value = (long)Process.MemoryManager.AliasRegionStart; break;

                case 3: Value = (long)(Process.MemoryManager.AliasRegionEnd -
                                       Process.MemoryManager.AliasRegionStart); break;

                case 4: Value = (long)Process.MemoryManager.HeapRegionStart; break;

                case 5: Value = (long)(Process.MemoryManager.HeapRegionEnd -
                                       Process.MemoryManager.HeapRegionStart); break;

                case 6: Value = (long)Process.GetMemoryCapacity(); break;

                case 7: Value = (long)Process.GetMemoryUsage(); break;

                case 12: Value = (long)Process.MemoryManager.GetAddrSpaceBaseAddr(); break;

                case 13: Value = (long)Process.MemoryManager.GetAddrSpaceSize(); break;

                case 14: Value = (long)Process.MemoryManager.StackRegionStart; break;

                case 15: Value = (long)(Process.MemoryManager.StackRegionEnd -
                                        Process.MemoryManager.StackRegionStart); break;

                case 16: Value = (long)Process.PersonalMmHeapPagesCount * KMemoryManager.PageSize; break;

                case 17:
                    if (Process.PersonalMmHeapPagesCount != 0)
                    {
                        Value = Process.MemoryManager.GetMmUsedPages() * KMemoryManager.PageSize;
                    }

                    break;

                case 18: Value = Process.TitleId; break;

                case 20: Value = (long)Process.UserExceptionContextAddress; break;

                case 21: Value = (long)Process.GetMemoryCapacityWithoutPersonalMmHeap(); break;

                case 22: Value = (long)Process.GetMemoryUsageWithoutPersonalMmHeap(); break;
                }

                break;
            }

            case 8:
            {
                if (Handle != 0)
                {
                    return(KernelResult.InvalidHandle);
                }

                if (SubId != 0)
                {
                    return(KernelResult.InvalidCombination);
                }

                Value = System.Scheduler.GetCurrentProcess().Debug ? 1 : 0;

                break;
            }

            case 9:
            {
                if (Handle != 0)
                {
                    return(KernelResult.InvalidHandle);
                }

                if (SubId != 0)
                {
                    return(KernelResult.InvalidCombination);
                }

                KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();

                if (CurrentProcess.ResourceLimit != null)
                {
                    KHandleTable   HandleTable   = CurrentProcess.HandleTable;
                    KResourceLimit ResourceLimit = CurrentProcess.ResourceLimit;

                    KernelResult Result = HandleTable.GenerateHandle(ResourceLimit, out int ResLimHandle);

                    if (Result != KernelResult.Success)
                    {
                        return(Result);
                    }

                    Value = (uint)ResLimHandle;
                }

                break;
            }

            case 10:
            {
                if (Handle != 0)
                {
                    return(KernelResult.InvalidHandle);
                }

                int CurrentCore = System.Scheduler.GetCurrentThread().CurrentCore;

                if (SubId != -1 && SubId != CurrentCore)
                {
                    return(KernelResult.InvalidCombination);
                }

                Value = System.Scheduler.CoreContexts[CurrentCore].TotalIdleTimeTicks;

                break;
            }

            case 11:
            {
                if (Handle != 0)
                {
                    return(KernelResult.InvalidHandle);
                }

                if ((ulong)SubId > 3)
                {
                    return(KernelResult.InvalidCombination);
                }

                KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();


                Value = CurrentProcess.RandomEntropy[SubId];

                break;
            }

            case 0xf0000002u:
            {
                if (SubId < -1 || SubId > 3)
                {
                    return(KernelResult.InvalidCombination);
                }

                KThread Thread = System.Scheduler.GetCurrentProcess().HandleTable.GetKThread(Handle);

                if (Thread == null)
                {
                    return(KernelResult.InvalidHandle);
                }

                KThread CurrentThread = System.Scheduler.GetCurrentThread();

                int CurrentCore = CurrentThread.CurrentCore;

                if (SubId != -1 && SubId != CurrentCore)
                {
                    return(KernelResult.Success);
                }

                KCoreContext CoreContext = System.Scheduler.CoreContexts[CurrentCore];

                long TimeDelta = PerformanceCounter.ElapsedMilliseconds - CoreContext.LastContextSwitchTime;

                if (SubId != -1)
                {
                    Value = KTimeManager.ConvertMillisecondsToTicks(TimeDelta);
                }
                else
                {
                    long TotalTimeRunning = Thread.TotalTimeRunning;

                    if (Thread == CurrentThread)
                    {
                        TotalTimeRunning += TimeDelta;
                    }

                    Value = KTimeManager.ConvertMillisecondsToTicks(TotalTimeRunning);
                }

                break;
            }

            default: return(KernelResult.InvalidEnumValue);
            }

            return(KernelResult.Success);
        }
Example #2
0
        private KernelResult GetInfo(uint id, int handle, long subId, out long value)
        {
            value = 0;

            switch (id)
            {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
            case 12:
            case 13:
            case 14:
            case 15:
            case 16:
            case 17:
            case 18:
            case 20:
            case 21:
            case 22:
            {
                if (subId != 0)
                {
                    return(KernelResult.InvalidCombination);
                }

                KProcess currentProcess = _system.Scheduler.GetCurrentProcess();

                KProcess process = currentProcess.HandleTable.GetKProcess(handle);

                if (process == null)
                {
                    return(KernelResult.InvalidHandle);
                }

                switch (id)
                {
                case 0: value = process.Capabilities.AllowedCpuCoresMask;    break;

                case 1: value = process.Capabilities.AllowedThreadPriosMask; break;

                case 2: value = (long)process.MemoryManager.AliasRegionStart; break;

                case 3: value = (long)(process.MemoryManager.AliasRegionEnd -
                                       process.MemoryManager.AliasRegionStart); break;

                case 4: value = (long)process.MemoryManager.HeapRegionStart; break;

                case 5: value = (long)(process.MemoryManager.HeapRegionEnd -
                                       process.MemoryManager.HeapRegionStart); break;

                case 6: value = (long)process.GetMemoryCapacity(); break;

                case 7: value = (long)process.GetMemoryUsage(); break;

                case 12: value = (long)process.MemoryManager.GetAddrSpaceBaseAddr(); break;

                case 13: value = (long)process.MemoryManager.GetAddrSpaceSize(); break;

                case 14: value = (long)process.MemoryManager.StackRegionStart; break;

                case 15: value = (long)(process.MemoryManager.StackRegionEnd -
                                        process.MemoryManager.StackRegionStart); break;

                case 16: value = (long)process.PersonalMmHeapPagesCount * KMemoryManager.PageSize; break;

                case 17:
                    if (process.PersonalMmHeapPagesCount != 0)
                    {
                        value = process.MemoryManager.GetMmUsedPages() * KMemoryManager.PageSize;
                    }

                    break;

                case 18: value = process.TitleId; break;

                case 20: value = (long)process.UserExceptionContextAddress; break;

                case 21: value = (long)process.GetMemoryCapacityWithoutPersonalMmHeap(); break;

                case 22: value = (long)process.GetMemoryUsageWithoutPersonalMmHeap(); break;
                }

                break;
            }

            case 8:
            {
                if (handle != 0)
                {
                    return(KernelResult.InvalidHandle);
                }

                if (subId != 0)
                {
                    return(KernelResult.InvalidCombination);
                }

                value = _system.Scheduler.GetCurrentProcess().Debug ? 1 : 0;

                break;
            }

            case 9:
            {
                if (handle != 0)
                {
                    return(KernelResult.InvalidHandle);
                }

                if (subId != 0)
                {
                    return(KernelResult.InvalidCombination);
                }

                KProcess currentProcess = _system.Scheduler.GetCurrentProcess();

                if (currentProcess.ResourceLimit != null)
                {
                    KHandleTable   handleTable   = currentProcess.HandleTable;
                    KResourceLimit resourceLimit = currentProcess.ResourceLimit;

                    KernelResult result = handleTable.GenerateHandle(resourceLimit, out int resLimHandle);

                    if (result != KernelResult.Success)
                    {
                        return(result);
                    }

                    value = (uint)resLimHandle;
                }

                break;
            }

            case 10:
            {
                if (handle != 0)
                {
                    return(KernelResult.InvalidHandle);
                }

                int currentCore = _system.Scheduler.GetCurrentThread().CurrentCore;

                if (subId != -1 && subId != currentCore)
                {
                    return(KernelResult.InvalidCombination);
                }

                value = _system.Scheduler.CoreContexts[currentCore].TotalIdleTimeTicks;

                break;
            }

            case 11:
            {
                if (handle != 0)
                {
                    return(KernelResult.InvalidHandle);
                }

                if ((ulong)subId > 3)
                {
                    return(KernelResult.InvalidCombination);
                }

                KProcess currentProcess = _system.Scheduler.GetCurrentProcess();


                value = currentProcess.RandomEntropy[subId];

                break;
            }

            case 0xf0000002u:
            {
                if (subId < -1 || subId > 3)
                {
                    return(KernelResult.InvalidCombination);
                }

                KThread thread = _system.Scheduler.GetCurrentProcess().HandleTable.GetKThread(handle);

                if (thread == null)
                {
                    return(KernelResult.InvalidHandle);
                }

                KThread currentThread = _system.Scheduler.GetCurrentThread();

                int currentCore = currentThread.CurrentCore;

                if (subId != -1 && subId != currentCore)
                {
                    return(KernelResult.Success);
                }

                KCoreContext coreContext = _system.Scheduler.CoreContexts[currentCore];

                long timeDelta = PerformanceCounter.ElapsedMilliseconds - coreContext.LastContextSwitchTime;

                if (subId != -1)
                {
                    value = KTimeManager.ConvertMillisecondsToTicks(timeDelta);
                }
                else
                {
                    long totalTimeRunning = thread.TotalTimeRunning;

                    if (thread == currentThread)
                    {
                        totalTimeRunning += timeDelta;
                    }

                    value = KTimeManager.ConvertMillisecondsToTicks(totalTimeRunning);
                }

                break;
            }

            default: return(KernelResult.InvalidEnumValue);
            }

            return(KernelResult.Success);
        }
Example #3
0
        public KernelResult Start(int mainThreadPriority, ulong stackSize)
        {
            lock (_processLock)
            {
                if (_state > ProcessState.CreatedAttached)
                {
                    return(KernelResult.InvalidState);
                }

                if (ResourceLimit != null && !ResourceLimit.Reserve(LimitableResource.Thread, 1))
                {
                    return(KernelResult.ResLimitExceeded);
                }

                KResourceLimit threadResourceLimit = ResourceLimit;
                KResourceLimit memoryResourceLimit = null;

                if (_mainThreadStackSize != 0)
                {
                    throw new InvalidOperationException("Trying to start a process with a invalid state!");
                }

                ulong stackSizeRounded = BitUtils.AlignUp(stackSize, KMemoryManager.PageSize);

                ulong neededSize = stackSizeRounded + _imageSize;

                //Check if the needed size for the code and the stack will fit on the
                //memory usage capacity of this Process. Also check for possible overflow
                //on the above addition.
                if (neededSize > _memoryUsageCapacity ||
                    neededSize < stackSizeRounded)
                {
                    threadResourceLimit?.Release(LimitableResource.Thread, 1);

                    return(KernelResult.OutOfMemory);
                }

                if (stackSizeRounded != 0 && ResourceLimit != null)
                {
                    memoryResourceLimit = ResourceLimit;

                    if (!memoryResourceLimit.Reserve(LimitableResource.Memory, stackSizeRounded))
                    {
                        threadResourceLimit?.Release(LimitableResource.Thread, 1);

                        return(KernelResult.ResLimitExceeded);
                    }
                }

                KernelResult result;

                KThread mainThread = null;

                ulong stackTop = 0;

                void CleanUpForError()
                {
                    mainThread?.Terminate();
                    HandleTable.Destroy();

                    if (_mainThreadStackSize != 0)
                    {
                        ulong stackBottom = stackTop - _mainThreadStackSize;

                        ulong stackPagesCount = _mainThreadStackSize / KMemoryManager.PageSize;

                        MemoryManager.UnmapForKernel(stackBottom, stackPagesCount, MemoryState.Stack);
                    }

                    memoryResourceLimit?.Release(LimitableResource.Memory, stackSizeRounded);
                    threadResourceLimit?.Release(LimitableResource.Thread, 1);
                }

                if (stackSizeRounded != 0)
                {
                    ulong stackPagesCount = stackSizeRounded / KMemoryManager.PageSize;

                    ulong regionStart = MemoryManager.StackRegionStart;
                    ulong regionSize  = MemoryManager.StackRegionEnd - regionStart;

                    ulong regionPagesCount = regionSize / KMemoryManager.PageSize;

                    result = MemoryManager.AllocateOrMapPa(
                        stackPagesCount,
                        KMemoryManager.PageSize,
                        0,
                        false,
                        regionStart,
                        regionPagesCount,
                        MemoryState.Stack,
                        MemoryPermission.ReadAndWrite,
                        out ulong stackBottom);

                    if (result != KernelResult.Success)
                    {
                        CleanUpForError();

                        return(result);
                    }

                    _mainThreadStackSize += stackSizeRounded;

                    stackTop = stackBottom + stackSizeRounded;
                }

                ulong heapCapacity = _memoryUsageCapacity - _mainThreadStackSize - _imageSize;

                result = MemoryManager.SetHeapCapacity(heapCapacity);

                if (result != KernelResult.Success)
                {
                    CleanUpForError();

                    return(result);
                }

                HandleTable = new KHandleTable(System);

                result = HandleTable.Initialize(Capabilities.HandleTableSize);

                if (result != KernelResult.Success)
                {
                    CleanUpForError();

                    return(result);
                }

                mainThread = new KThread(System);

                result = mainThread.Initialize(
                    _entrypoint,
                    0,
                    stackTop,
                    mainThreadPriority,
                    DefaultCpuCore,
                    this);

                if (result != KernelResult.Success)
                {
                    CleanUpForError();

                    return(result);
                }

                result = HandleTable.GenerateHandle(mainThread, out int mainThreadHandle);

                if (result != KernelResult.Success)
                {
                    CleanUpForError();

                    return(result);
                }

                mainThread.SetEntryArguments(0, mainThreadHandle);

                ProcessState oldState = _state;
                ProcessState newState = _state != ProcessState.Created
                    ? ProcessState.Attached
                    : ProcessState.Started;

                SetState(newState);

                //TODO: We can't call KThread.Start from a non-guest thread.
                //We will need to make some changes to allow the creation of
                //dummy threads that will be used to initialize the current
                //thread on KCoreContext so that GetCurrentThread doesn't fail.

                /* Result = MainThread.Start();
                 *
                 * if (Result != KernelResult.Success)
                 * {
                 *  SetState(OldState);
                 *
                 *  CleanUpForError();
                 * } */

                mainThread.Reschedule(ThreadSchedState.Running);

                return(result);
            }
        }