public void SubscribeThreadEventHandlers(ARMeilleure.State.ExecutionContext context) { context.Interrupt += InterruptHandler; context.SupervisorCall += KernelContext.SyscallHandler.SvcCall; context.Undefined += UndefinedInstructionHandler; }
public KernelResult Initialize( ulong entrypoint, ulong argsPtr, ulong stackTop, int priority, int defaultCpuCore, KProcess owner, ThreadType type = ThreadType.User) { if ((uint)type > 3) { throw new ArgumentException($"Invalid thread type \"{type}\"."); } PreferredCore = defaultCpuCore; AffinityMask |= 1L << defaultCpuCore; SchedFlags = type == ThreadType.Dummy ? ThreadSchedState.Running : ThreadSchedState.None; CurrentCore = PreferredCore; DynamicPriority = priority; BasePriority = priority; ObjSyncResult = KernelResult.ThreadNotStarted; _entrypoint = entrypoint; if (type == ThreadType.User) { if (owner.AllocateThreadLocalStorage(out _tlsAddress) != KernelResult.Success) { return(KernelResult.OutOfMemory); } TlsDramAddress = owner.MemoryManager.GetDramAddressFromVa(_tlsAddress); MemoryHelper.FillWithZeros(owner.CpuMemory, (long)_tlsAddress, KTlsPageInfo.TlsEntrySize); } bool is64Bits; if (owner != null) { Owner = owner; owner.IncrementReferenceCount(); owner.IncrementThreadCount(); is64Bits = (owner.MmuFlags & 1) != 0; } else { is64Bits = true; } HostThread = new Thread(() => ThreadStart(entrypoint)); if (System.UseLegacyJit) { Context = new ChocolArm64.State.CpuThreadState(); } else { Context = new ARMeilleure.State.ExecutionContext(); } bool isAarch32 = (Owner.MmuFlags & 1) == 0; Context.SetX(0, argsPtr); if (isAarch32) { Context.SetX(13, (uint)stackTop); } else { Context.SetX(31, stackTop); } Context.CntfrqEl0 = 19200000; Context.Tpidr = (long)_tlsAddress; owner.SubscribeThreadEventHandlers(Context); ThreadUid = System.GetThreadUid(); _hasBeenInitialized = true; if (owner != null) { owner.AddThread(this); if (owner.IsPaused) { System.CriticalSection.Enter(); if (ShallBeTerminated || SchedFlags == ThreadSchedState.TerminationPending) { System.CriticalSection.Leave(); return(KernelResult.Success); } _forcePauseFlags |= ThreadSchedState.ProcessPauseFlag; CombineForcePauseFlags(); System.CriticalSection.Leave(); } } return(KernelResult.Success); }