Exemple #1
0
        public Horizon(Switch Device)
        {
            this.Device = Device;

            Processes = new ConcurrentDictionary <int, Process>();

            State = new SystemStateMgr();

            Scheduler = new KScheduler();

            TimeManager = new KTimeManager();

            AddressArbiter = new KAddressArbiter(this);

            Synchronization = new KSynchronization(this);

            CriticalSectionLock = new KRecursiveLock(this);

            if (!Device.Memory.Allocator.TryAllocate(HidSize, out long HidPA) ||
                !Device.Memory.Allocator.TryAllocate(FontSize, out long FontPA))
            {
                throw new InvalidOperationException();
            }

            HidSharedMem  = new KSharedMemory(HidPA, HidSize);
            FontSharedMem = new KSharedMemory(FontPA, FontSize);

            Font = new SharedFontManager(Device, FontSharedMem.PA);

            VsyncEvent = new KEvent(this);
        }
Exemple #2
0
        private KernelResult CreateThread(
            ulong entrypoint,
            ulong argsPtr,
            ulong stackTop,
            int priority,
            int cpuCore,
            out int handle)
        {
            handle = 0;

            KProcess currentProcess = _system.Scheduler.GetCurrentProcess();

            if (cpuCore == -2)
            {
                cpuCore = currentProcess.DefaultCpuCore;
            }

            if ((uint)cpuCore >= KScheduler.CpuCoresCount || !currentProcess.IsCpuCoreAllowed(cpuCore))
            {
                return(KernelResult.InvalidCpuCore);
            }

            if ((uint)priority >= KScheduler.PrioritiesCount || !currentProcess.IsPriorityAllowed(priority))
            {
                return(KernelResult.InvalidPriority);
            }

            long timeout = KTimeManager.ConvertMillisecondsToNanoseconds(100);

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

            KThread thread = new KThread(_system);

            KernelResult result = currentProcess.InitializeThread(
                thread,
                entrypoint,
                argsPtr,
                stackTop,
                priority,
                cpuCore);

            if (result == KernelResult.Success)
            {
                result = _process.HandleTable.GenerateHandle(thread, out handle);
            }
            else
            {
                currentProcess.ResourceLimit?.Release(LimitableResource.Thread, 1);
            }

            thread.DecrementReferenceCount();

            return(result);
        }
Exemple #3
0
        public Horizon(Switch device, ContentManager contentManager)
        {
            ControlData = new BlitStruct <ApplicationControlProperty>(1);

            Device = device;

            State = new SystemStateMgr();

            ResourceLimit = new KResourceLimit(this);

            KernelInit.InitializeResourceLimit(ResourceLimit);

            MemoryRegions = KernelInit.GetMemoryRegions();

            LargeMemoryBlockAllocator = new KMemoryBlockAllocator(MemoryBlockAllocatorSize * 2);
            SmallMemoryBlockAllocator = new KMemoryBlockAllocator(MemoryBlockAllocatorSize);

            UserSlabHeapPages = new KSlabHeap(
                UserSlabHeapBase,
                UserSlabHeapItemSize,
                UserSlabHeapSize);

            CriticalSection = new KCriticalSection(this);

            Scheduler = new KScheduler(this);

            TimeManager = new KTimeManager();

            Synchronization = new KSynchronization(this);

            ContextIdManager = new KContextIdManager();

            _kipId     = InitialKipId;
            _processId = InitialProcessId;

            Scheduler.StartAutoPreemptionThread();

            KernelInitialized = true;

            ThreadCounter = new CountdownEvent(1);

            Processes = new SortedDictionary <long, KProcess>();

            AutoObjectNames = new ConcurrentDictionary <string, KAutoObject>();

            // Note: This is not really correct, but with HLE of services, the only memory
            // region used that is used is Application, so we can use the other ones for anything.
            KMemoryRegionManager region = MemoryRegions[(int)MemoryRegion.NvServices];

            ulong hidPa  = region.Address;
            ulong fontPa = region.Address + HidSize;
            ulong iirsPa = region.Address + HidSize + FontSize;
            ulong timePa = region.Address + HidSize + FontSize + IirsSize;

            HidBaseAddress = (long)(hidPa - DramMemoryMap.DramBase);

            KPageList hidPageList  = new KPageList();
            KPageList fontPageList = new KPageList();
            KPageList iirsPageList = new KPageList();
            KPageList timePageList = new KPageList();

            hidPageList.AddRange(hidPa, HidSize / KMemoryManager.PageSize);
            fontPageList.AddRange(fontPa, FontSize / KMemoryManager.PageSize);
            iirsPageList.AddRange(iirsPa, IirsSize / KMemoryManager.PageSize);
            timePageList.AddRange(timePa, TimeSize / KMemoryManager.PageSize);

            HidSharedMem  = new KSharedMemory(this, hidPageList, 0, 0, MemoryPermission.Read);
            FontSharedMem = new KSharedMemory(this, fontPageList, 0, 0, MemoryPermission.Read);
            IirsSharedMem = new KSharedMemory(this, iirsPageList, 0, 0, MemoryPermission.Read);

            KSharedMemory timeSharedMemory = new KSharedMemory(this, timePageList, 0, 0, MemoryPermission.Read);

            TimeServiceManager.Instance.Initialize(device, this, timeSharedMemory, (long)(timePa - DramMemoryMap.DramBase), TimeSize);

            AppletState = new AppletStateMgr(this);

            AppletState.SetFocus(true);

            Font = new SharedFontManager(device, (long)(fontPa - DramMemoryMap.DramBase));

            IUserInterface.InitializePort(this);

            VsyncEvent = new KEvent(this);

            ContentManager = contentManager;

            // TODO: use set:sys (and get external clock source id from settings)
            // TODO: use "time!standard_steady_clock_rtc_update_interval_minutes" and implement a worker thread to be accurate.
            UInt128 clockSourceId = new UInt128(Guid.NewGuid().ToByteArray());

            IRtcManager.GetExternalRtcValue(out ulong rtcValue);

            // We assume the rtc is system time.
            TimeSpanType systemTime = TimeSpanType.FromSeconds((long)rtcValue);

            // First init the standard steady clock
            TimeServiceManager.Instance.SetupStandardSteadyClock(null, clockSourceId, systemTime, TimeSpanType.Zero, TimeSpanType.Zero, false);
            TimeServiceManager.Instance.SetupStandardLocalSystemClock(null, new SystemClockContext(), systemTime.ToSeconds());

            if (NxSettings.Settings.TryGetValue("time!standard_network_clock_sufficient_accuracy_minutes", out object standardNetworkClockSufficientAccuracyMinutes))
            {
                TimeSpanType standardNetworkClockSufficientAccuracy = new TimeSpanType((int)standardNetworkClockSufficientAccuracyMinutes * 60000000000);

                TimeServiceManager.Instance.SetupStandardNetworkSystemClock(new SystemClockContext(), standardNetworkClockSufficientAccuracy);
            }

            TimeServiceManager.Instance.SetupStandardUserSystemClock(null, false, SteadyClockTimePoint.GetRandom());

            // FIXME: TimeZone shoud be init here but it's actually done in ContentManager

            TimeServiceManager.Instance.SetupEphemeralNetworkSystemClock();
        }
Exemple #4
0
        public Horizon(Switch device)
        {
            Device = device;

            State = new SystemStateMgr();

            ResourceLimit = new KResourceLimit(this);

            KernelInit.InitializeResourceLimit(ResourceLimit);

            MemoryRegions = KernelInit.GetMemoryRegions();

            LargeMemoryBlockAllocator = new KMemoryBlockAllocator(MemoryBlockAllocatorSize * 2);
            SmallMemoryBlockAllocator = new KMemoryBlockAllocator(MemoryBlockAllocatorSize);

            UserSlabHeapPages = new KSlabHeap(
                UserSlabHeapBase,
                UserSlabHeapItemSize,
                UserSlabHeapSize);

            CriticalSection = new KCriticalSection(this);

            Scheduler = new KScheduler(this);

            TimeManager = new KTimeManager();

            Synchronization = new KSynchronization(this);

            ContextIdManager = new KContextIdManager();

            _kipId     = InitialKipId;
            _processId = InitialProcessId;

            Scheduler.StartAutoPreemptionThread();

            KernelInitialized = true;

            ThreadCounter = new CountdownEvent(1);

            Processes = new SortedDictionary <long, KProcess>();

            AutoObjectNames = new ConcurrentDictionary <string, KAutoObject>();

            //Note: This is not really correct, but with HLE of services, the only memory
            //region used that is used is Application, so we can use the other ones for anything.
            KMemoryRegionManager region = MemoryRegions[(int)MemoryRegion.NvServices];

            ulong hidPa  = region.Address;
            ulong fontPa = region.Address + HidSize;

            HidBaseAddress = (long)(hidPa - DramMemoryMap.DramBase);

            KPageList hidPageList  = new KPageList();
            KPageList fontPageList = new KPageList();

            hidPageList.AddRange(hidPa, HidSize / KMemoryManager.PageSize);
            fontPageList.AddRange(fontPa, FontSize / KMemoryManager.PageSize);

            HidSharedMem  = new KSharedMemory(hidPageList, 0, 0, MemoryPermission.Read);
            FontSharedMem = new KSharedMemory(fontPageList, 0, 0, MemoryPermission.Read);

            AppletState = new AppletStateMgr(this);

            AppletState.SetFocus(true);

            Font = new SharedFontManager(device, (long)(fontPa - DramMemoryMap.DramBase));

            VsyncEvent = new KEvent(this);

            LoadKeySet();

            ContentManager = new ContentManager(device);
        }
Exemple #5
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);
        }
Exemple #6
0
        public Horizon(Switch device)
        {
            ControlData = new Nacp();

            Device = device;

            State = new SystemStateMgr();

            ResourceLimit = new KResourceLimit(this);

            KernelInit.InitializeResourceLimit(ResourceLimit);

            MemoryRegions = KernelInit.GetMemoryRegions();

            LargeMemoryBlockAllocator = new KMemoryBlockAllocator(MemoryBlockAllocatorSize * 2);
            SmallMemoryBlockAllocator = new KMemoryBlockAllocator(MemoryBlockAllocatorSize);

            UserSlabHeapPages = new KSlabHeap(
                UserSlabHeapBase,
                UserSlabHeapItemSize,
                UserSlabHeapSize);

            CriticalSection = new KCriticalSection(this);

            Scheduler = new KScheduler(this);

            TimeManager = new KTimeManager();

            Synchronization = new KSynchronization(this);

            ContextIdManager = new KContextIdManager();

            _kipId     = InitialKipId;
            _processId = InitialProcessId;

            Scheduler.StartAutoPreemptionThread();

            KernelInitialized = true;

            ThreadCounter = new CountdownEvent(1);

            Processes = new SortedDictionary <long, KProcess>();

            AutoObjectNames = new ConcurrentDictionary <string, KAutoObject>();

            // Note: This is not really correct, but with HLE of services, the only memory
            // region used that is used is Application, so we can use the other ones for anything.
            KMemoryRegionManager region = MemoryRegions[(int)MemoryRegion.NvServices];

            ulong hidPa  = region.Address;
            ulong fontPa = region.Address + HidSize;
            ulong iirsPa = region.Address + HidSize + FontSize;
            ulong timePa = region.Address + HidSize + FontSize + IirsSize;

            HidBaseAddress = (long)(hidPa - DramMemoryMap.DramBase);

            KPageList hidPageList  = new KPageList();
            KPageList fontPageList = new KPageList();
            KPageList iirsPageList = new KPageList();
            KPageList timePageList = new KPageList();

            hidPageList.AddRange(hidPa, HidSize / KMemoryManager.PageSize);
            fontPageList.AddRange(fontPa, FontSize / KMemoryManager.PageSize);
            iirsPageList.AddRange(iirsPa, IirsSize / KMemoryManager.PageSize);
            timePageList.AddRange(timePa, TimeSize / KMemoryManager.PageSize);

            HidSharedMem  = new KSharedMemory(this, hidPageList, 0, 0, MemoryPermission.Read);
            FontSharedMem = new KSharedMemory(this, fontPageList, 0, 0, MemoryPermission.Read);
            IirsSharedMem = new KSharedMemory(this, iirsPageList, 0, 0, MemoryPermission.Read);
            TimeSharedMem = new KSharedMemory(this, timePageList, 0, 0, MemoryPermission.Read);

            AppletState = new AppletStateMgr(this);

            AppletState.SetFocus(true);

            Font = new SharedFontManager(device, (long)(fontPa - DramMemoryMap.DramBase));

            IUserInterface.InitializePort(this);

            VsyncEvent = new KEvent(this);

            LoadKeySet();

            ContentManager = new ContentManager(device);

            // TODO: use set:sys (and set external clock source id from settings)
            // TODO: use "time!standard_steady_clock_rtc_update_interval_minutes" and implement a worker thread to be accurate.
            SteadyClockCore.Instance.ConfigureSetupValue();

            if (Services.Set.NxSettings.Settings.TryGetValue("time!standard_network_clock_sufficient_accuracy_minutes", out object standardNetworkClockSufficientAccuracyMinutes))
            {
                TimeSpanType standardNetworkClockSufficientAccuracy = new TimeSpanType((int)standardNetworkClockSufficientAccuracyMinutes * 60000000000);

                StandardNetworkSystemClockCore.Instance.SetStandardNetworkClockSufficientAccuracy(standardNetworkClockSufficientAccuracy);
            }
        }