IPC refactor part 3+4: New server HIPC message processor (#4188)
* IPC refactor part 3 + 4: New server HIPC message processor with source generator based serialization * Make types match on calls to AlignUp/AlignDown * Formatting * Address some PR feedback * Move BitfieldExtensions to Ryujinx.Common.Utilities and consolidate implementations * Rename Reader/Writer to SpanReader/SpanWriter and move to Ryujinx.Common.Memory * Implement EventType * Address more PR feedback * Log request processing errors since they are not normal * Rename waitable to multiwait and add missing lock * PR feedback * Ac_K PR feedback
This commit is contained in:
parent
c6a139a6e7
commit
08831eecf7
213 changed files with 9762 additions and 1010 deletions
|
@ -1,5 +1,6 @@
|
|||
using Ryujinx.HLE.HOS.Kernel.Common;
|
||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||
using Ryujinx.Horizon.Common;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
|
@ -27,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
_context = context;
|
||||
}
|
||||
|
||||
public KernelResult Initialize(int size)
|
||||
public Result Initialize(int size)
|
||||
{
|
||||
if ((uint)size > 1024)
|
||||
{
|
||||
|
@ -62,10 +63,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
_nextFreeEntry = _tableHead;
|
||||
|
||||
return KernelResult.Success;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public KernelResult GenerateHandle(KAutoObject obj, out int handle)
|
||||
public Result GenerateHandle(KAutoObject obj, out int handle)
|
||||
{
|
||||
handle = 0;
|
||||
|
||||
|
@ -99,10 +100,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
}
|
||||
}
|
||||
|
||||
return KernelResult.Success;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public KernelResult ReserveHandle(out int handle)
|
||||
public Result ReserveHandle(out int handle)
|
||||
{
|
||||
handle = 0;
|
||||
|
||||
|
@ -131,7 +132,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
}
|
||||
}
|
||||
|
||||
return KernelResult.Success;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public void CancelHandleReservation(int handle)
|
||||
|
|
|
@ -5,6 +5,7 @@ using Ryujinx.HLE.Exceptions;
|
|||
using Ryujinx.HLE.HOS.Kernel.Common;
|
||||
using Ryujinx.HLE.HOS.Kernel.Memory;
|
||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||
using Ryujinx.Horizon.Common;
|
||||
using Ryujinx.Memory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -116,7 +117,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
Debugger = new HleProcessDebugger(this);
|
||||
}
|
||||
|
||||
public KernelResult InitializeKip(
|
||||
public Result InitializeKip(
|
||||
ProcessCreationInfo creationInfo,
|
||||
ReadOnlySpan<int> capabilities,
|
||||
KPageList pageList,
|
||||
|
@ -151,7 +152,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
? KernelContext.LargeMemoryBlockSlabManager
|
||||
: KernelContext.SmallMemoryBlockSlabManager;
|
||||
|
||||
KernelResult result = MemoryManager.InitializeForProcess(
|
||||
Result result = MemoryManager.InitializeForProcess(
|
||||
addrSpaceType,
|
||||
aslrEnabled,
|
||||
!aslrEnabled,
|
||||
|
@ -160,7 +161,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
codeSize,
|
||||
slabManager);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
@ -172,14 +173,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
result = MemoryManager.MapPages(codeAddress, pageList, MemoryState.CodeStatic, KMemoryPermission.None);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = Capabilities.InitializeForKernel(capabilities, MemoryManager);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
@ -187,7 +188,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
return ParseProcessInfo(creationInfo);
|
||||
}
|
||||
|
||||
public KernelResult Initialize(
|
||||
public Result Initialize(
|
||||
ProcessCreationInfo creationInfo,
|
||||
ReadOnlySpan<int> capabilities,
|
||||
KResourceLimit resourceLimit,
|
||||
|
@ -255,7 +256,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
ulong codeSize = codePagesCount * KPageTableBase.PageSize;
|
||||
|
||||
KernelResult result = MemoryManager.InitializeForProcess(
|
||||
Result result = MemoryManager.InitializeForProcess(
|
||||
addrSpaceType,
|
||||
aslrEnabled,
|
||||
!aslrEnabled,
|
||||
|
@ -264,7 +265,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
codeSize,
|
||||
slabManager);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
CleanUpForError();
|
||||
|
||||
|
@ -284,7 +285,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
MemoryState.CodeStatic,
|
||||
KMemoryPermission.None);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
CleanUpForError();
|
||||
|
||||
|
@ -293,7 +294,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
result = Capabilities.InitializeForUser(capabilities, MemoryManager);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
CleanUpForError();
|
||||
|
||||
|
@ -302,7 +303,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
result = ParseProcessInfo(creationInfo);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
CleanUpForError();
|
||||
}
|
||||
|
@ -310,7 +311,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
return result;
|
||||
}
|
||||
|
||||
private KernelResult ParseProcessInfo(ProcessCreationInfo creationInfo)
|
||||
private Result ParseProcessInfo(ProcessCreationInfo creationInfo)
|
||||
{
|
||||
// Ensure that the current kernel version is equal or above to the minimum required.
|
||||
uint requiredKernelVersionMajor = (uint)Capabilities.KernelReleaseVersion >> 19;
|
||||
|
@ -334,9 +335,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
}
|
||||
}
|
||||
|
||||
KernelResult result = AllocateThreadLocalStorage(out ulong userExceptionContextAddress);
|
||||
Result result = AllocateThreadLocalStorage(out ulong userExceptionContextAddress);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
@ -378,14 +379,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
GenerateRandomEntropy();
|
||||
|
||||
return KernelResult.Success;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public KernelResult AllocateThreadLocalStorage(out ulong address)
|
||||
public Result AllocateThreadLocalStorage(out ulong address)
|
||||
{
|
||||
KernelContext.CriticalSection.Enter();
|
||||
|
||||
KernelResult result;
|
||||
Result result;
|
||||
|
||||
if (_freeTlsPages.Count > 0)
|
||||
{
|
||||
|
@ -404,14 +405,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
_fullTlsPages.Add(pageInfo.PageVirtualAddress, pageInfo);
|
||||
}
|
||||
|
||||
result = KernelResult.Success;
|
||||
result = Result.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, we need to create a new one.
|
||||
result = AllocateTlsPage(out KTlsPageInfo pageInfo);
|
||||
|
||||
if (result == KernelResult.Success)
|
||||
if (result == Result.Success)
|
||||
{
|
||||
if (!pageInfo.TryGetFreePage(out address))
|
||||
{
|
||||
|
@ -431,7 +432,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
return result;
|
||||
}
|
||||
|
||||
private KernelResult AllocateTlsPage(out KTlsPageInfo pageInfo)
|
||||
private Result AllocateTlsPage(out KTlsPageInfo pageInfo)
|
||||
{
|
||||
pageInfo = default;
|
||||
|
||||
|
@ -445,7 +446,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
ulong regionPagesCount = regionSize / KPageTableBase.PageSize;
|
||||
|
||||
KernelResult result = MemoryManager.MapPages(
|
||||
Result result = MemoryManager.MapPages(
|
||||
1,
|
||||
KPageTableBase.PageSize,
|
||||
tlsPagePa,
|
||||
|
@ -456,7 +457,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
KMemoryPermission.ReadAndWrite,
|
||||
out ulong tlsPageVa);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
KernelContext.UserSlabHeapPages.Free(tlsPagePa);
|
||||
}
|
||||
|
@ -470,13 +471,13 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
return result;
|
||||
}
|
||||
|
||||
public KernelResult FreeThreadLocalStorage(ulong tlsSlotAddr)
|
||||
public Result FreeThreadLocalStorage(ulong tlsSlotAddr)
|
||||
{
|
||||
ulong tlsPageAddr = BitUtils.AlignDown<ulong>(tlsSlotAddr, KPageTableBase.PageSize);
|
||||
|
||||
KernelContext.CriticalSection.Enter();
|
||||
|
||||
KernelResult result = KernelResult.Success;
|
||||
Result result = Result.Success;
|
||||
|
||||
KTlsPageInfo pageInfo;
|
||||
|
||||
|
@ -506,7 +507,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
FreeTlsPage(pageInfo);
|
||||
|
||||
return KernelResult.Success;
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -515,11 +516,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
return result;
|
||||
}
|
||||
|
||||
private KernelResult FreeTlsPage(KTlsPageInfo pageInfo)
|
||||
private Result FreeTlsPage(KTlsPageInfo pageInfo)
|
||||
{
|
||||
KernelResult result = MemoryManager.UnmapForKernel(pageInfo.PageVirtualAddress, 1, MemoryState.ThreadLocal);
|
||||
Result result = MemoryManager.UnmapForKernel(pageInfo.PageVirtualAddress, 1, MemoryState.ThreadLocal);
|
||||
|
||||
if (result == KernelResult.Success)
|
||||
if (result == Result.Success)
|
||||
{
|
||||
KernelContext.UserSlabHeapPages.Free(pageInfo.PagePhysicalAddress);
|
||||
}
|
||||
|
@ -532,7 +533,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
// TODO.
|
||||
}
|
||||
|
||||
public KernelResult Start(int mainThreadPriority, ulong stackSize)
|
||||
public Result Start(int mainThreadPriority, ulong stackSize)
|
||||
{
|
||||
lock (_processLock)
|
||||
{
|
||||
|
@ -580,7 +581,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
}
|
||||
}
|
||||
|
||||
KernelResult result;
|
||||
Result result;
|
||||
|
||||
KThread mainThread = null;
|
||||
|
||||
|
@ -627,7 +628,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
KMemoryPermission.ReadAndWrite,
|
||||
out ulong stackBottom);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
CleanUpForError();
|
||||
|
||||
|
@ -643,7 +644,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
result = MemoryManager.SetHeapCapacity(heapCapacity);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
CleanUpForError();
|
||||
|
||||
|
@ -654,7 +655,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
result = HandleTable.Initialize(Capabilities.HandleTableSize);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
CleanUpForError();
|
||||
|
||||
|
@ -673,7 +674,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
ThreadType.User,
|
||||
_customThreadStart);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
CleanUpForError();
|
||||
|
||||
|
@ -682,7 +683,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
result = HandleTable.GenerateHandle(mainThread, out int mainThreadHandle);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
CleanUpForError();
|
||||
|
||||
|
@ -700,14 +701,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
result = mainThread.Start();
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
SetState(oldState);
|
||||
|
||||
CleanUpForError();
|
||||
}
|
||||
|
||||
if (result == KernelResult.Success)
|
||||
if (result == Result.Success)
|
||||
{
|
||||
mainThread.IncrementReferenceCount();
|
||||
}
|
||||
|
@ -729,7 +730,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
}
|
||||
}
|
||||
|
||||
public KernelResult InitializeThread(
|
||||
public Result InitializeThread(
|
||||
KThread thread,
|
||||
ulong entrypoint,
|
||||
ulong argsPtr,
|
||||
|
@ -888,9 +889,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
return _signaled;
|
||||
}
|
||||
|
||||
public KernelResult Terminate()
|
||||
public Result Terminate()
|
||||
{
|
||||
KernelResult result;
|
||||
Result result;
|
||||
|
||||
bool shallTerminate = false;
|
||||
|
||||
|
@ -910,7 +911,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
shallTerminate = true;
|
||||
}
|
||||
|
||||
result = KernelResult.Success;
|
||||
result = Result.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1044,9 +1045,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
KernelContext.CriticalSection.Leave();
|
||||
}
|
||||
|
||||
public KernelResult ClearIfNotExited()
|
||||
public Result ClearIfNotExited()
|
||||
{
|
||||
KernelResult result;
|
||||
Result result;
|
||||
|
||||
KernelContext.CriticalSection.Enter();
|
||||
|
||||
|
@ -1056,7 +1057,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
{
|
||||
_signaled = false;
|
||||
|
||||
result = KernelResult.Success;
|
||||
result = Result.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1107,7 +1108,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
protected override void Destroy() => Context.Dispose();
|
||||
|
||||
public KernelResult SetActivity(bool pause)
|
||||
public Result SetActivity(bool pause)
|
||||
{
|
||||
KernelContext.CriticalSection.Enter();
|
||||
|
||||
|
@ -1154,7 +1155,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
KernelContext.CriticalSection.Leave();
|
||||
|
||||
return KernelResult.Success;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
KernelContext.CriticalSection.Leave();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using Ryujinx.HLE.HOS.Kernel.Common;
|
||||
using Ryujinx.HLE.HOS.Kernel.Memory;
|
||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||
using Ryujinx.Horizon.Common;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
|
@ -25,7 +26,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
IrqAccessMask = new byte[0x80];
|
||||
}
|
||||
|
||||
public KernelResult InitializeForKernel(ReadOnlySpan<int> capabilities, KPageTableBase memoryManager)
|
||||
public Result InitializeForKernel(ReadOnlySpan<int> capabilities, KPageTableBase memoryManager)
|
||||
{
|
||||
AllowedCpuCoresMask = 0xf;
|
||||
AllowedThreadPriosMask = ulong.MaxValue;
|
||||
|
@ -35,12 +36,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
return Parse(capabilities, memoryManager);
|
||||
}
|
||||
|
||||
public KernelResult InitializeForUser(ReadOnlySpan<int> capabilities, KPageTableBase memoryManager)
|
||||
public Result InitializeForUser(ReadOnlySpan<int> capabilities, KPageTableBase memoryManager)
|
||||
{
|
||||
return Parse(capabilities, memoryManager);
|
||||
}
|
||||
|
||||
private KernelResult Parse(ReadOnlySpan<int> capabilities, KPageTableBase memoryManager)
|
||||
private Result Parse(ReadOnlySpan<int> capabilities, KPageTableBase memoryManager)
|
||||
{
|
||||
int mask0 = 0;
|
||||
int mask1 = 0;
|
||||
|
@ -51,9 +52,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
if (((cap + 1) & ~cap) != 0x40)
|
||||
{
|
||||
KernelResult result = ParseCapability(cap, ref mask0, ref mask1, memoryManager);
|
||||
Result result = ParseCapability(cap, ref mask0, ref mask1, memoryManager);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
@ -96,7 +97,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
? KMemoryPermission.Read
|
||||
: KMemoryPermission.ReadAndWrite;
|
||||
|
||||
KernelResult result;
|
||||
Result result;
|
||||
|
||||
if ((cap >> 31) != 0)
|
||||
{
|
||||
|
@ -107,17 +108,17 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
result = memoryManager.MapIoMemory(address, size, perm);
|
||||
}
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
if (result != Result.Success)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return KernelResult.Success;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
private KernelResult ParseCapability(int cap, ref int mask0, ref int mask1, KPageTableBase memoryManager)
|
||||
private Result ParseCapability(int cap, ref int mask0, ref int mask1, KPageTableBase memoryManager)
|
||||
{
|
||||
int code = (cap + 1) & ~cap;
|
||||
|
||||
|
@ -127,7 +128,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
}
|
||||
else if (code == 0)
|
||||
{
|
||||
return KernelResult.Success;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
int codeMask = 1 << (32 - BitOperations.LeadingZeroCount((uint)code + 1));
|
||||
|
@ -300,7 +301,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
default: return KernelResult.InvalidCapability;
|
||||
}
|
||||
|
||||
return KernelResult.Success;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
private static ulong GetMaskFromMinMax(int min, int max)
|
||||
|
|
|
@ -7,23 +7,25 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
{
|
||||
public ulong Pc => 0UL;
|
||||
|
||||
public ulong CntfrqEl0 { get => 0; set { } }
|
||||
public ulong CntfrqEl0 { get; set; }
|
||||
public ulong CntpctEl0 => 0UL;
|
||||
|
||||
public long TpidrEl0 { get => 0; set { } }
|
||||
public long TpidrroEl0 { get => 0; set { } }
|
||||
public long TpidrEl0 { get; set; }
|
||||
public long TpidrroEl0 { get; set; }
|
||||
|
||||
public uint Pstate { get => 0; set { } }
|
||||
public uint Pstate { get; set; }
|
||||
|
||||
public uint Fpcr { get => 0; set { } }
|
||||
public uint Fpsr { get => 0; set { } }
|
||||
public uint Fpcr { get; set; }
|
||||
public uint Fpsr { get; set; }
|
||||
|
||||
public bool IsAarch32 { get => false; set { } }
|
||||
|
||||
public bool Running { get; private set; } = true;
|
||||
|
||||
public ulong GetX(int index) => 0UL;
|
||||
public void SetX(int index, ulong value) { }
|
||||
private readonly ulong[] _x = new ulong[32];
|
||||
|
||||
public ulong GetX(int index) => _x[index];
|
||||
public void SetX(int index, ulong value) => _x[index] = value;
|
||||
|
||||
public V128 GetV(int index) => default;
|
||||
public void SetV(int index, V128 value) { }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue