Move kernel state out of the Horizon class (#1107)

* Move kernel state from Horizon to KernelContext

* Merge syscalls partial classes, split 32 and 64-bit variants

* Sort usings
This commit is contained in:
gdkchan 2020-05-04 00:41:29 -03:00 committed by GitHub
parent cd48576f58
commit 15d1cc806b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 3678 additions and 3570 deletions

View file

@ -4,7 +4,6 @@ using Ryujinx.Cpu;
using Ryujinx.HLE.Exceptions;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Memory;
using Ryujinx.HLE.HOS.Kernel.SupervisorCall;
using Ryujinx.HLE.HOS.Kernel.Threading;
using System;
using System.Collections.Generic;
@ -80,20 +79,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
public MemoryManager CpuMemory { get; private set; }
public CpuContext CpuContext { get; private set; }
private SvcHandler _svcHandler;
private Horizon _system;
public HleProcessDebugger Debugger { get; private set; }
public KProcess(Horizon system) : base(system)
public KProcess(KernelContext context) : base(context)
{
_processLock = new object();
_threadingLock = new object();
_system = system;
AddressArbiter = new KAddressArbiter(system);
AddressArbiter = new KAddressArbiter(context);
_fullTlsPages = new SortedDictionary<ulong, KTlsPageInfo>();
_freeTlsPages = new SortedDictionary<ulong, KTlsPageInfo>();
@ -104,8 +97,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
_threads = new LinkedList<KThread>();
_svcHandler = new SvcHandler(system.Device, this);
Debugger = new HleProcessDebugger(this);
}
@ -130,8 +121,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
ulong codeSize = (ulong)creationInfo.CodePagesCount * KMemoryManager.PageSize;
KMemoryBlockAllocator memoryBlockAllocator = (MmuFlags & 0x40) != 0
? System.LargeMemoryBlockAllocator
: System.SmallMemoryBlockAllocator;
? KernelContext.LargeMemoryBlockAllocator
: KernelContext.SmallMemoryBlockAllocator;
KernelResult result = MemoryManager.InitializeForProcess(
addrSpaceType,
@ -170,9 +161,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return result;
}
Pid = System.GetKipId();
Pid = KernelContext.NewKipId();
if (Pid == 0 || (ulong)Pid >= Horizon.InitialProcessId)
if (Pid == 0 || (ulong)Pid >= KernelConstants.InitialProcessId)
{
throw new InvalidOperationException($"Invalid KIP Id {Pid}.");
}
@ -224,8 +215,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
else
{
memoryBlockAllocator = (MmuFlags & 0x40) != 0
? System.LargeMemoryBlockAllocator
: System.SmallMemoryBlockAllocator;
? KernelContext.LargeMemoryBlockAllocator
: KernelContext.SmallMemoryBlockAllocator;
}
AddressSpaceType addrSpaceType = (AddressSpaceType)((creationInfo.MmuFlags >> 1) & 7);
@ -283,9 +274,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return result;
}
Pid = System.GetProcessId();
Pid = KernelContext.NewProcessId();
if (Pid == -1 || (ulong)Pid < Horizon.InitialProcessId)
if (Pid == -1 || (ulong)Pid < KernelConstants.InitialProcessId)
{
throw new InvalidOperationException($"Invalid Process Id {Pid}.");
}
@ -350,7 +341,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
uint requiredKernelVersionMajor = (uint)Capabilities.KernelReleaseVersion >> 19;
uint requiredKernelVersionMinor = ((uint)Capabilities.KernelReleaseVersion >> 15) & 0xf;
if (System.EnableVersionChecks)
if (KernelContext.EnableVersionChecks)
{
if (requiredKernelVersionMajor > KernelVersionMajor)
{
@ -419,7 +410,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
public KernelResult AllocateThreadLocalStorage(out ulong address)
{
System.CriticalSection.Enter();
KernelContext.CriticalSection.Enter();
KernelResult result;
@ -462,16 +453,16 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
}
}
System.CriticalSection.Leave();
KernelContext.CriticalSection.Leave();
return result;
}
private KernelResult AllocateTlsPage(out KTlsPageInfo pageInfo)
{
pageInfo = default(KTlsPageInfo);
pageInfo = default;
if (!System.UserSlabHeapPages.TryGetItem(out ulong tlsPagePa))
if (!KernelContext.UserSlabHeapPages.TryGetItem(out ulong tlsPagePa))
{
return KernelResult.OutOfMemory;
}
@ -494,7 +485,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
if (result != KernelResult.Success)
{
System.UserSlabHeapPages.Free(tlsPagePa);
KernelContext.UserSlabHeapPages.Free(tlsPagePa);
}
else
{
@ -510,7 +501,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
{
ulong tlsPageAddr = BitUtils.AlignDown(tlsSlotAddr, KMemoryManager.PageSize);
System.CriticalSection.Enter();
KernelContext.CriticalSection.Enter();
KernelResult result = KernelResult.Success;
@ -538,7 +529,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
// from all trees, and free the memory it was using.
_freeTlsPages.Remove(tlsPageAddr);
System.CriticalSection.Leave();
KernelContext.CriticalSection.Leave();
FreeTlsPage(pageInfo);
@ -546,7 +537,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
}
}
System.CriticalSection.Leave();
KernelContext.CriticalSection.Leave();
return result;
}
@ -562,7 +553,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
if (result == KernelResult.Success)
{
System.UserSlabHeapPages.Free(tlsPagePa);
KernelContext.UserSlabHeapPages.Free(tlsPagePa);
}
return result;
@ -692,7 +683,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return result;
}
HandleTable = new KHandleTable(System);
HandleTable = new KHandleTable(KernelContext);
result = HandleTable.Initialize(Capabilities.HandleTableSize);
@ -703,7 +694,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return result;
}
mainThread = new KThread(System);
mainThread = new KThread(KernelContext);
result = mainThread.Initialize(
_entrypoint,
@ -792,25 +783,25 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
public void SubscribeThreadEventHandlers(ARMeilleure.State.ExecutionContext context)
{
context.Interrupt += InterruptHandler;
context.SupervisorCall += _svcHandler.SvcCall;
context.SupervisorCall += KernelContext.SyscallHandler.SvcCall;
context.Undefined += UndefinedInstructionHandler;
}
private void InterruptHandler(object sender, EventArgs e)
{
System.Scheduler.ContextSwitch();
KernelContext.Scheduler.ContextSwitch();
}
public void IncrementThreadCount()
{
Interlocked.Increment(ref _threadCount);
System.ThreadCounter.AddCount();
KernelContext.ThreadCounter.AddCount();
}
public void DecrementThreadCountAndTerminateIfZero()
{
System.ThreadCounter.Signal();
KernelContext.ThreadCounter.Signal();
if (Interlocked.Decrement(ref _threadCount) == 0)
{
@ -820,7 +811,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
public void DecrementToZeroWhileTerminatingCurrent()
{
System.ThreadCounter.Signal();
KernelContext.ThreadCounter.Signal();
while (Interlocked.Decrement(ref _threadCount) != 0)
{
@ -917,7 +908,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
bool shallTerminate = false;
System.CriticalSection.Enter();
KernelContext.CriticalSection.Enter();
lock (_processLock)
{
@ -941,11 +932,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
}
}
System.CriticalSection.Leave();
KernelContext.CriticalSection.Leave();
if (shallTerminate)
{
UnpauseAndTerminateAllThreadsExcept(System.Scheduler.GetCurrentThread());
UnpauseAndTerminateAllThreadsExcept(KernelContext.Scheduler.GetCurrentThread());
HandleTable.Destroy();
@ -960,7 +951,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
{
bool shallTerminate = false;
System.CriticalSection.Enter();
KernelContext.CriticalSection.Enter();
lock (_processLock)
{
@ -977,11 +968,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
}
}
System.CriticalSection.Leave();
KernelContext.CriticalSection.Leave();
if (shallTerminate)
{
UnpauseAndTerminateAllThreadsExcept(System.Scheduler.GetCurrentThread());
UnpauseAndTerminateAllThreadsExcept(KernelContext.Scheduler.GetCurrentThread());
HandleTable.Destroy();
@ -995,7 +986,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
{
lock (_threadingLock)
{
System.CriticalSection.Enter();
KernelContext.CriticalSection.Enter();
foreach (KThread thread in _threads)
{
@ -1005,7 +996,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
}
}
System.CriticalSection.Leave();
KernelContext.CriticalSection.Leave();
}
KThread blockedThread = null;
@ -1048,18 +1039,18 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
ResourceLimit.Release(LimitableResource.Memory, GetMemoryUsage());
}
System.CriticalSection.Enter();
KernelContext.CriticalSection.Enter();
SetState(ProcessState.Exited);
System.CriticalSection.Leave();
KernelContext.CriticalSection.Leave();
}
public KernelResult ClearIfNotExited()
{
KernelResult result;
System.CriticalSection.Enter();
KernelContext.CriticalSection.Enter();
lock (_processLock)
{
@ -1075,7 +1066,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
}
}
System.CriticalSection.Leave();
KernelContext.CriticalSection.Leave();
return result;
}
@ -1086,40 +1077,36 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
{
foreach (KThread thread in _threads)
{
System.Scheduler.ExitThread(thread);
System.Scheduler.CoreManager.Set(thread.HostThread);
KernelContext.Scheduler.ExitThread(thread);
KernelContext.Scheduler.CoreManager.Set(thread.HostThread);
}
}
}
private void InitializeMemoryManager(AddressSpaceType addrSpaceType, MemoryRegion memRegion)
{
int addrSpaceBits;
switch (addrSpaceType)
int addrSpaceBits = addrSpaceType switch
{
case AddressSpaceType.Addr32Bits: addrSpaceBits = 32; break;
case AddressSpaceType.Addr36Bits: addrSpaceBits = 36; break;
case AddressSpaceType.Addr32BitsNoMap: addrSpaceBits = 32; break;
case AddressSpaceType.Addr39Bits: addrSpaceBits = 39; break;
AddressSpaceType.Addr32Bits => 32,
AddressSpaceType.Addr36Bits => 36,
AddressSpaceType.Addr32BitsNoMap => 32,
AddressSpaceType.Addr39Bits => 39,
_ => throw new ArgumentException(nameof(addrSpaceType))
};
default: throw new ArgumentException(nameof(addrSpaceType));
}
CpuMemory = new MemoryManager(_system.Device.Memory, 1UL << addrSpaceBits);
CpuMemory = new MemoryManager(KernelContext.Memory, 1UL << addrSpaceBits);
CpuContext = new CpuContext(CpuMemory);
// TODO: This should eventually be removed.
// The GPU shouldn't depend on the CPU memory manager at all.
_system.Device.Gpu.SetVmm(CpuMemory);
KernelContext.Device.Gpu.SetVmm(CpuMemory);
MemoryManager = new KMemoryManager(_system, CpuMemory);
MemoryManager = new KMemoryManager(KernelContext, CpuMemory);
}
public void PrintCurrentThreadStackTrace()
{
System.Scheduler.GetCurrentThread().PrintGuestStackTrace();
KernelContext.Scheduler.GetCurrentThread().PrintGuestStackTrace();
}
private void UndefinedInstructionHandler(object sender, InstUndefinedEventArgs e)