forked from Mirror/Ryujinx
Update syscall capabilites to include SVCs from FW 15.0.0 (#4530)
* Add CapabilityType enum * Add SupervisorCallCount * kernel: Add CapabilityExtensions & Change type of capabilities to uint * Remove private setter from Mask arrays * Pass ReadOnlySpan directly & Remove redundant type casts
This commit is contained in:
parent
b72916fbc1
commit
7870423671
13 changed files with 128 additions and 75 deletions
|
@ -338,7 +338,7 @@ namespace Ryujinx.HLE.HOS
|
||||||
|
|
||||||
ProcessCreationInfo creationInfo = new ProcessCreationInfo("Service", 1, 0, 0x8000000, 1, flags, 0, 0);
|
ProcessCreationInfo creationInfo = new ProcessCreationInfo("Service", 1, 0, 0x8000000, 1, flags, 0, 0);
|
||||||
|
|
||||||
int[] defaultCapabilities = new int[]
|
uint[] defaultCapabilities = new uint[]
|
||||||
{
|
{
|
||||||
0x030363F7,
|
0x030363F7,
|
||||||
0x1FFFFFCF,
|
0x1FFFFFCF,
|
||||||
|
|
|
@ -7,6 +7,8 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
public const int InitialKipId = 1;
|
public const int InitialKipId = 1;
|
||||||
public const int InitialProcessId = 0x51;
|
public const int InitialProcessId = 0x51;
|
||||||
|
|
||||||
|
public const int SupervisorCallCount = 0xC0;
|
||||||
|
|
||||||
public const int MemoryBlockAllocatorSize = 0x2710;
|
public const int MemoryBlockAllocatorSize = 0x2710;
|
||||||
|
|
||||||
public const ulong UserSlabHeapBase = DramMemoryMap.SlabHeapBase;
|
public const ulong UserSlabHeapBase = DramMemoryMap.SlabHeapBase;
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
||||||
public static Result StartInitialProcess(
|
public static Result StartInitialProcess(
|
||||||
KernelContext context,
|
KernelContext context,
|
||||||
ProcessCreationInfo creationInfo,
|
ProcessCreationInfo creationInfo,
|
||||||
ReadOnlySpan<int> capabilities,
|
ReadOnlySpan<uint> capabilities,
|
||||||
int mainThreadPriority,
|
int mainThreadPriority,
|
||||||
ThreadStart customThreadStart)
|
ThreadStart customThreadStart)
|
||||||
{
|
{
|
||||||
|
|
22
Ryujinx.HLE/HOS/Kernel/Process/CapabilityExtensions.cs
Normal file
22
Ryujinx.HLE/HOS/Kernel/Process/CapabilityExtensions.cs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
|
{
|
||||||
|
static class CapabilityExtensions
|
||||||
|
{
|
||||||
|
public static CapabilityType GetCapabilityType(this uint cap)
|
||||||
|
{
|
||||||
|
return (CapabilityType)(((cap + 1) & ~cap) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static uint GetFlag(this CapabilityType type)
|
||||||
|
{
|
||||||
|
return (uint)type + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static uint GetId(this CapabilityType type)
|
||||||
|
{
|
||||||
|
return (uint)BitOperations.TrailingZeroCount(type.GetFlag());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
Ryujinx.HLE/HOS/Kernel/Process/CapabilityType.cs
Normal file
19
Ryujinx.HLE/HOS/Kernel/Process/CapabilityType.cs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
|
{
|
||||||
|
enum CapabilityType : uint
|
||||||
|
{
|
||||||
|
CorePriority = (1u << 3) - 1,
|
||||||
|
SyscallMask = (1u << 4) - 1,
|
||||||
|
MapRange = (1u << 6) - 1,
|
||||||
|
MapIoPage = (1u << 7) - 1,
|
||||||
|
MapRegion = (1u << 10) - 1,
|
||||||
|
InterruptPair = (1u << 11) - 1,
|
||||||
|
ProgramType = (1u << 13) - 1,
|
||||||
|
KernelVersion = (1u << 14) - 1,
|
||||||
|
HandleTable = (1u << 15) - 1,
|
||||||
|
DebugFlags = (1u << 16) - 1,
|
||||||
|
|
||||||
|
Invalid = 0u,
|
||||||
|
Padding = ~0u
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
|
|
||||||
private int _activeSlotsCount;
|
private int _activeSlotsCount;
|
||||||
|
|
||||||
private int _size;
|
private uint _size;
|
||||||
|
|
||||||
private ushort _idCounter;
|
private ushort _idCounter;
|
||||||
|
|
||||||
|
@ -28,9 +28,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
_context = context;
|
_context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result Initialize(int size)
|
public Result Initialize(uint size)
|
||||||
{
|
{
|
||||||
if ((uint)size > 1024)
|
if (size > 1024)
|
||||||
{
|
{
|
||||||
return KernelResult.OutOfMemory;
|
return KernelResult.OutOfMemory;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
{
|
{
|
||||||
class KProcess : KSynchronizationObject
|
class KProcess : KSynchronizationObject
|
||||||
{
|
{
|
||||||
public const int KernelVersionMajor = 10;
|
public const uint KernelVersionMajor = 10;
|
||||||
public const int KernelVersionMinor = 4;
|
public const uint KernelVersionMinor = 4;
|
||||||
public const int KernelVersionRevision = 0;
|
public const uint KernelVersionRevision = 0;
|
||||||
|
|
||||||
public const int KernelVersionPacked =
|
public const uint KernelVersionPacked =
|
||||||
(KernelVersionMajor << 19) |
|
(KernelVersionMajor << 19) |
|
||||||
(KernelVersionMinor << 15) |
|
(KernelVersionMinor << 15) |
|
||||||
(KernelVersionRevision << 0);
|
(KernelVersionRevision << 0);
|
||||||
|
@ -119,7 +119,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
|
|
||||||
public Result InitializeKip(
|
public Result InitializeKip(
|
||||||
ProcessCreationInfo creationInfo,
|
ProcessCreationInfo creationInfo,
|
||||||
ReadOnlySpan<int> capabilities,
|
ReadOnlySpan<uint> capabilities,
|
||||||
KPageList pageList,
|
KPageList pageList,
|
||||||
KResourceLimit resourceLimit,
|
KResourceLimit resourceLimit,
|
||||||
MemoryRegion memRegion,
|
MemoryRegion memRegion,
|
||||||
|
@ -190,7 +190,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
|
|
||||||
public Result Initialize(
|
public Result Initialize(
|
||||||
ProcessCreationInfo creationInfo,
|
ProcessCreationInfo creationInfo,
|
||||||
ReadOnlySpan<int> capabilities,
|
ReadOnlySpan<uint> capabilities,
|
||||||
KResourceLimit resourceLimit,
|
KResourceLimit resourceLimit,
|
||||||
MemoryRegion memRegion,
|
MemoryRegion memRegion,
|
||||||
IProcessContextFactory contextFactory,
|
IProcessContextFactory contextFactory,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using Ryujinx.HLE.HOS.Kernel.Common;
|
|
||||||
using Ryujinx.HLE.HOS.Kernel.Memory;
|
using Ryujinx.HLE.HOS.Kernel.Memory;
|
||||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||||
using Ryujinx.Horizon.Common;
|
using Ryujinx.Horizon.Common;
|
||||||
|
@ -9,48 +8,49 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
{
|
{
|
||||||
class KProcessCapabilities
|
class KProcessCapabilities
|
||||||
{
|
{
|
||||||
public byte[] SvcAccessMask { get; private set; }
|
public byte[] SvcAccessMask { get; }
|
||||||
public byte[] IrqAccessMask { get; private set; }
|
public byte[] IrqAccessMask { get; }
|
||||||
|
|
||||||
public ulong AllowedCpuCoresMask { get; private set; }
|
public ulong AllowedCpuCoresMask { get; private set; }
|
||||||
public ulong AllowedThreadPriosMask { get; private set; }
|
public ulong AllowedThreadPriosMask { get; private set; }
|
||||||
|
|
||||||
public int DebuggingFlags { get; private set; }
|
public uint DebuggingFlags { get; private set; }
|
||||||
public int HandleTableSize { get; private set; }
|
public uint HandleTableSize { get; private set; }
|
||||||
public int KernelReleaseVersion { get; private set; }
|
public uint KernelReleaseVersion { get; private set; }
|
||||||
public int ApplicationType { get; private set; }
|
public uint ApplicationType { get; private set; }
|
||||||
|
|
||||||
public KProcessCapabilities()
|
public KProcessCapabilities()
|
||||||
{
|
{
|
||||||
SvcAccessMask = new byte[0x10];
|
// length / number of bits of the underlying type
|
||||||
|
SvcAccessMask = new byte[KernelConstants.SupervisorCallCount / 8];
|
||||||
IrqAccessMask = new byte[0x80];
|
IrqAccessMask = new byte[0x80];
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result InitializeForKernel(ReadOnlySpan<int> capabilities, KPageTableBase memoryManager)
|
public Result InitializeForKernel(ReadOnlySpan<uint> capabilities, KPageTableBase memoryManager)
|
||||||
{
|
{
|
||||||
AllowedCpuCoresMask = 0xf;
|
AllowedCpuCoresMask = 0xf;
|
||||||
AllowedThreadPriosMask = ulong.MaxValue;
|
AllowedThreadPriosMask = ulong.MaxValue;
|
||||||
DebuggingFlags &= ~3;
|
DebuggingFlags &= ~3u;
|
||||||
KernelReleaseVersion = KProcess.KernelVersionPacked;
|
KernelReleaseVersion = KProcess.KernelVersionPacked;
|
||||||
|
|
||||||
return Parse(capabilities, memoryManager);
|
return Parse(capabilities, memoryManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result InitializeForUser(ReadOnlySpan<int> capabilities, KPageTableBase memoryManager)
|
public Result InitializeForUser(ReadOnlySpan<uint> capabilities, KPageTableBase memoryManager)
|
||||||
{
|
{
|
||||||
return Parse(capabilities, memoryManager);
|
return Parse(capabilities, memoryManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result Parse(ReadOnlySpan<int> capabilities, KPageTableBase memoryManager)
|
private Result Parse(ReadOnlySpan<uint> capabilities, KPageTableBase memoryManager)
|
||||||
{
|
{
|
||||||
int mask0 = 0;
|
int mask0 = 0;
|
||||||
int mask1 = 0;
|
int mask1 = 0;
|
||||||
|
|
||||||
for (int index = 0; index < capabilities.Length; index++)
|
for (int index = 0; index < capabilities.Length; index++)
|
||||||
{
|
{
|
||||||
int cap = capabilities[index];
|
uint cap = capabilities[index];
|
||||||
|
|
||||||
if (((cap + 1) & ~cap) != 0x40)
|
if (cap.GetCapabilityType() != CapabilityType.MapRange)
|
||||||
{
|
{
|
||||||
Result result = ParseCapability(cap, ref mask0, ref mask1, memoryManager);
|
Result result = ParseCapability(cap, ref mask0, ref mask1, memoryManager);
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
return KernelResult.InvalidCombination;
|
return KernelResult.InvalidCombination;
|
||||||
}
|
}
|
||||||
|
|
||||||
int prevCap = cap;
|
uint prevCap = cap;
|
||||||
|
|
||||||
cap = capabilities[++index];
|
cap = capabilities[++index];
|
||||||
|
|
||||||
|
@ -85,8 +85,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
return KernelResult.InvalidSize;
|
return KernelResult.InvalidSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
long address = ((long)(uint)prevCap << 5) & 0xffffff000;
|
long address = ((long)prevCap << 5) & 0xffffff000;
|
||||||
long size = ((long)(uint)cap << 5) & 0xfffff000;
|
long size = ((long)cap << 5) & 0xfffff000;
|
||||||
|
|
||||||
if (((ulong)(address + size - 1) >> 36) != 0)
|
if (((ulong)(address + size - 1) >> 36) != 0)
|
||||||
{
|
{
|
||||||
|
@ -118,20 +118,20 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result ParseCapability(int cap, ref int mask0, ref int mask1, KPageTableBase memoryManager)
|
private Result ParseCapability(uint cap, ref int mask0, ref int mask1, KPageTableBase memoryManager)
|
||||||
{
|
{
|
||||||
int code = (cap + 1) & ~cap;
|
CapabilityType code = cap.GetCapabilityType();
|
||||||
|
|
||||||
if (code == 1)
|
if (code == CapabilityType.Invalid)
|
||||||
{
|
{
|
||||||
return KernelResult.InvalidCapability;
|
return KernelResult.InvalidCapability;
|
||||||
}
|
}
|
||||||
else if (code == 0)
|
else if (code == CapabilityType.Padding)
|
||||||
{
|
{
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
int codeMask = 1 << (32 - BitOperations.LeadingZeroCount((uint)code + 1));
|
int codeMask = 1 << (32 - BitOperations.LeadingZeroCount(code.GetFlag() + 1));
|
||||||
|
|
||||||
// Check if the property was already set.
|
// Check if the property was already set.
|
||||||
if (((mask0 & codeMask) & 0x1e008) != 0)
|
if (((mask0 & codeMask) & 0x1e008) != 0)
|
||||||
|
@ -143,23 +143,23 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
|
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case 8:
|
case CapabilityType.CorePriority:
|
||||||
{
|
{
|
||||||
if (AllowedCpuCoresMask != 0 || AllowedThreadPriosMask != 0)
|
if (AllowedCpuCoresMask != 0 || AllowedThreadPriosMask != 0)
|
||||||
{
|
{
|
||||||
return KernelResult.InvalidCapability;
|
return KernelResult.InvalidCapability;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lowestCpuCore = (cap >> 16) & 0xff;
|
uint lowestCpuCore = (cap >> 16) & 0xff;
|
||||||
int highestCpuCore = (cap >> 24) & 0xff;
|
uint highestCpuCore = (cap >> 24) & 0xff;
|
||||||
|
|
||||||
if (lowestCpuCore > highestCpuCore)
|
if (lowestCpuCore > highestCpuCore)
|
||||||
{
|
{
|
||||||
return KernelResult.InvalidCombination;
|
return KernelResult.InvalidCombination;
|
||||||
}
|
}
|
||||||
|
|
||||||
int highestThreadPrio = (cap >> 4) & 0x3f;
|
uint highestThreadPrio = (cap >> 4) & 0x3f;
|
||||||
int lowestThreadPrio = (cap >> 10) & 0x3f;
|
uint lowestThreadPrio = (cap >> 10) & 0x3f;
|
||||||
|
|
||||||
if (lowestThreadPrio > highestThreadPrio)
|
if (lowestThreadPrio > highestThreadPrio)
|
||||||
{
|
{
|
||||||
|
@ -177,9 +177,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x10:
|
case CapabilityType.SyscallMask:
|
||||||
{
|
{
|
||||||
int slot = (cap >> 29) & 7;
|
int slot = ((int)cap >> 29) & 7;
|
||||||
|
|
||||||
int svcSlotMask = 1 << slot;
|
int svcSlotMask = 1 << slot;
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
|
|
||||||
mask1 |= svcSlotMask;
|
mask1 |= svcSlotMask;
|
||||||
|
|
||||||
int svcMask = (cap >> 5) & 0xffffff;
|
uint svcMask = (cap >> 5) & 0xffffff;
|
||||||
|
|
||||||
int baseSvc = slot * 24;
|
int baseSvc = slot * 24;
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
|
|
||||||
int svcId = baseSvc + index;
|
int svcId = baseSvc + index;
|
||||||
|
|
||||||
if (svcId > 0x7f)
|
if (svcId >= KernelConstants.SupervisorCallCount)
|
||||||
{
|
{
|
||||||
return KernelResult.MaximumExceeded;
|
return KernelResult.MaximumExceeded;
|
||||||
}
|
}
|
||||||
|
@ -214,20 +214,27 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x80:
|
case CapabilityType.MapIoPage:
|
||||||
{
|
{
|
||||||
long address = ((long)(uint)cap << 4) & 0xffffff000;
|
long address = ((long)cap << 4) & 0xffffff000;
|
||||||
|
|
||||||
memoryManager.MapIoMemory(address, KPageTableBase.PageSize, KMemoryPermission.ReadAndWrite);
|
memoryManager.MapIoMemory(address, KPageTableBase.PageSize, KMemoryPermission.ReadAndWrite);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x800:
|
case CapabilityType.MapRegion:
|
||||||
|
{
|
||||||
|
// TODO: Implement capabilities for MapRegion
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CapabilityType.InterruptPair:
|
||||||
{
|
{
|
||||||
// TODO: GIC distributor check.
|
// TODO: GIC distributor check.
|
||||||
int irq0 = (cap >> 12) & 0x3ff;
|
int irq0 = ((int)cap >> 12) & 0x3ff;
|
||||||
int irq1 = (cap >> 22) & 0x3ff;
|
int irq1 = ((int)cap >> 22) & 0x3ff;
|
||||||
|
|
||||||
if (irq0 != 0x3ff)
|
if (irq0 != 0x3ff)
|
||||||
{
|
{
|
||||||
|
@ -242,11 +249,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x2000:
|
case CapabilityType.ProgramType:
|
||||||
{
|
{
|
||||||
int applicationType = cap >> 14;
|
uint applicationType = (cap >> 14);
|
||||||
|
|
||||||
if ((uint)applicationType > 7)
|
if (applicationType > 7)
|
||||||
{
|
{
|
||||||
return KernelResult.ReservedValue;
|
return KernelResult.ReservedValue;
|
||||||
}
|
}
|
||||||
|
@ -256,7 +263,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x4000:
|
case CapabilityType.KernelVersion:
|
||||||
{
|
{
|
||||||
// Note: This check is bugged on kernel too, we are just replicating the bug here.
|
// Note: This check is bugged on kernel too, we are just replicating the bug here.
|
||||||
if ((KernelReleaseVersion >> 17) != 0 || cap < 0x80000)
|
if ((KernelReleaseVersion >> 17) != 0 || cap < 0x80000)
|
||||||
|
@ -269,11 +276,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x8000:
|
case CapabilityType.HandleTable:
|
||||||
{
|
{
|
||||||
int handleTableSize = cap >> 26;
|
uint handleTableSize = cap >> 26;
|
||||||
|
|
||||||
if ((uint)handleTableSize > 0x3ff)
|
if (handleTableSize > 0x3ff)
|
||||||
{
|
{
|
||||||
return KernelResult.ReservedValue;
|
return KernelResult.ReservedValue;
|
||||||
}
|
}
|
||||||
|
@ -283,16 +290,16 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x10000:
|
case CapabilityType.DebugFlags:
|
||||||
{
|
{
|
||||||
int debuggingFlags = cap >> 19;
|
uint debuggingFlags = cap >> 19;
|
||||||
|
|
||||||
if ((uint)debuggingFlags > 3)
|
if (debuggingFlags > 3)
|
||||||
{
|
{
|
||||||
return KernelResult.ReservedValue;
|
return KernelResult.ReservedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggingFlags &= ~3;
|
DebuggingFlags &= ~3u;
|
||||||
DebuggingFlags |= debuggingFlags;
|
DebuggingFlags |= debuggingFlags;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -304,18 +311,18 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ulong GetMaskFromMinMax(int min, int max)
|
private static ulong GetMaskFromMinMax(uint min, uint max)
|
||||||
{
|
{
|
||||||
int range = max - min + 1;
|
uint range = max - min + 1;
|
||||||
|
|
||||||
if (range == 64)
|
if (range == 64)
|
||||||
{
|
{
|
||||||
return ulong.MaxValue;
|
return ulong.MaxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong mask = (1UL << range) - 1;
|
ulong mask = (1UL << (int)range) - 1;
|
||||||
|
|
||||||
return mask << min;
|
return mask << (int)min;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,8 @@
|
||||||
namespace Ryujinx.HLE.HOS.Kernel.Process
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
{
|
{
|
||||||
|
[Flags]
|
||||||
enum ProcessCreationFlags
|
enum ProcessCreationFlags
|
||||||
{
|
{
|
||||||
Is64Bit = 1 << 0,
|
Is64Bit = 1 << 0,
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||||
public Result CreateProcess(
|
public Result CreateProcess(
|
||||||
out int handle,
|
out int handle,
|
||||||
ProcessCreationInfo info,
|
ProcessCreationInfo info,
|
||||||
ReadOnlySpan<int> capabilities,
|
ReadOnlySpan<uint> capabilities,
|
||||||
IProcessContextFactory contextFactory,
|
IProcessContextFactory contextFactory,
|
||||||
ThreadStart customThreadStart = null)
|
ThreadStart customThreadStart = null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,7 +80,7 @@ namespace Ryujinx.HLE.HOS
|
||||||
|
|
||||||
ulong codeBaseAddress = kip.Is64BitAddressSpace ? 0x8000000UL : 0x200000UL;
|
ulong codeBaseAddress = kip.Is64BitAddressSpace ? 0x8000000UL : 0x200000UL;
|
||||||
|
|
||||||
ulong codeAddress = codeBaseAddress + (ulong)kip.TextOffset;
|
ulong codeAddress = codeBaseAddress + kip.TextOffset;
|
||||||
|
|
||||||
ProcessCreationFlags flags = 0;
|
ProcessCreationFlags flags = 0;
|
||||||
|
|
||||||
|
@ -231,13 +231,13 @@ namespace Ryujinx.HLE.HOS
|
||||||
|
|
||||||
nsoSize = BitUtils.AlignUp<uint>(nsoSize, KPageTableBase.PageSize);
|
nsoSize = BitUtils.AlignUp<uint>(nsoSize, KPageTableBase.PageSize);
|
||||||
|
|
||||||
nsoBase[index] = codeStart + (ulong)codeSize;
|
nsoBase[index] = codeStart + codeSize;
|
||||||
|
|
||||||
codeSize += nsoSize;
|
codeSize += nsoSize;
|
||||||
|
|
||||||
if (arguments != null && argsSize == 0)
|
if (arguments != null && argsSize == 0)
|
||||||
{
|
{
|
||||||
argsStart = (ulong)codeSize;
|
argsStart = codeSize;
|
||||||
|
|
||||||
argsSize = (uint)BitUtils.AlignDown(arguments.Length * 2 + ArgsTotalSize - 1, KPageTableBase.PageSize);
|
argsSize = (uint)BitUtils.AlignDown(arguments.Length * 2 + ArgsTotalSize - 1, KPageTableBase.PageSize);
|
||||||
|
|
||||||
|
@ -318,7 +318,7 @@ namespace Ryujinx.HLE.HOS
|
||||||
|
|
||||||
result = process.Initialize(
|
result = process.Initialize(
|
||||||
creationInfo,
|
creationInfo,
|
||||||
MemoryMarshal.Cast<byte, int>(npdm.KernelCapabilityData).ToArray(),
|
MemoryMarshal.Cast<byte, uint>(npdm.KernelCapabilityData),
|
||||||
resourceLimit,
|
resourceLimit,
|
||||||
memoryRegion,
|
memoryRegion,
|
||||||
processContextFactory);
|
processContextFactory);
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace Ryujinx.HLE.HOS.Services
|
||||||
// not large enough.
|
// not large enough.
|
||||||
private const int PointerBufferSize = 0x8000;
|
private const int PointerBufferSize = 0x8000;
|
||||||
|
|
||||||
private readonly static int[] DefaultCapabilities = new int[]
|
private readonly static uint[] DefaultCapabilities = new uint[]
|
||||||
{
|
{
|
||||||
0x030363F7,
|
0x030363F7,
|
||||||
0x1FFFFFCF,
|
0x1FFFFFCF,
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace Ryujinx.HLE.Loaders.Executables
|
||||||
public uint DataSize { get; }
|
public uint DataSize { get; }
|
||||||
public uint BssSize { get; }
|
public uint BssSize { get; }
|
||||||
|
|
||||||
public int[] Capabilities { get; }
|
public uint[] Capabilities { get; }
|
||||||
public bool UsesSecureMemory { get; }
|
public bool UsesSecureMemory { get; }
|
||||||
public bool Is64BitAddressSpace { get; }
|
public bool Is64BitAddressSpace { get; }
|
||||||
public bool Is64Bit { get; }
|
public bool Is64Bit { get; }
|
||||||
|
@ -57,11 +57,11 @@ namespace Ryujinx.HLE.Loaders.Executables
|
||||||
Version = reader.Version;
|
Version = reader.Version;
|
||||||
Name = reader.Name.ToString();
|
Name = reader.Name.ToString();
|
||||||
|
|
||||||
Capabilities = new int[32];
|
Capabilities = new uint[32];
|
||||||
|
|
||||||
for (int index = 0; index < Capabilities.Length; index++)
|
for (int index = 0; index < Capabilities.Length; index++)
|
||||||
{
|
{
|
||||||
Capabilities[index] = (int)reader.Capabilities[index];
|
Capabilities[index] = reader.Capabilities[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.GetSegmentSize(KipReader.SegmentType.Data, out int uncompressedSize).ThrowIfFailure();
|
reader.GetSegmentSize(KipReader.SegmentType.Data, out int uncompressedSize).ThrowIfFailure();
|
||||||
|
|
Loading…
Reference in a new issue