aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.HLE/HOS/Horizon.cs4
-rw-r--r--Ryujinx.HLE/HOS/Kernel/KernelConstants.cs4
-rw-r--r--Ryujinx.HLE/HOS/Kernel/KernelStatic.cs2
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/CapabilityExtensions.cs22
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/CapabilityType.cs19
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/KHandleTable.cs6
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs12
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs109
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationFlags.cs5
-rw-r--r--Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs4
-rw-r--r--Ryujinx.HLE/HOS/ProgramLoader.cs8
-rw-r--r--Ryujinx.HLE/HOS/Services/ServerBase.cs2
-rw-r--r--Ryujinx.HLE/Loaders/Executables/KipExecutable.cs6
13 files changed, 128 insertions, 75 deletions
diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs
index 9908cbba..2b77a7c2 100644
--- a/Ryujinx.HLE/HOS/Horizon.cs
+++ b/Ryujinx.HLE/HOS/Horizon.cs
@@ -338,7 +338,7 @@ namespace Ryujinx.HLE.HOS
ProcessCreationInfo creationInfo = new ProcessCreationInfo("Service", 1, 0, 0x8000000, 1, flags, 0, 0);
- int[] defaultCapabilities = new int[]
+ uint[] defaultCapabilities = new uint[]
{
0x030363F7,
0x1FFFFFCF,
@@ -552,4 +552,4 @@ namespace Ryujinx.HLE.HOS
IsPaused = pause;
}
}
-}
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/KernelConstants.cs b/Ryujinx.HLE/HOS/Kernel/KernelConstants.cs
index 3817b0aa..28db750c 100644
--- a/Ryujinx.HLE/HOS/Kernel/KernelConstants.cs
+++ b/Ryujinx.HLE/HOS/Kernel/KernelConstants.cs
@@ -7,6 +7,8 @@ namespace Ryujinx.HLE.HOS.Kernel
public const int InitialKipId = 1;
public const int InitialProcessId = 0x51;
+ public const int SupervisorCallCount = 0xC0;
+
public const int MemoryBlockAllocatorSize = 0x2710;
public const ulong UserSlabHeapBase = DramMemoryMap.SlabHeapBase;
@@ -15,4 +17,4 @@ namespace Ryujinx.HLE.HOS.Kernel
public const ulong CounterFrequency = 19200000;
}
-}
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/KernelStatic.cs b/Ryujinx.HLE/HOS/Kernel/KernelStatic.cs
index 21d7d90c..c66f4b57 100644
--- a/Ryujinx.HLE/HOS/Kernel/KernelStatic.cs
+++ b/Ryujinx.HLE/HOS/Kernel/KernelStatic.cs
@@ -18,7 +18,7 @@ namespace Ryujinx.HLE.HOS.Kernel
public static Result StartInitialProcess(
KernelContext context,
ProcessCreationInfo creationInfo,
- ReadOnlySpan<int> capabilities,
+ ReadOnlySpan<uint> capabilities,
int mainThreadPriority,
ThreadStart customThreadStart)
{
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/CapabilityExtensions.cs b/Ryujinx.HLE/HOS/Kernel/Process/CapabilityExtensions.cs
new file mode 100644
index 00000000..66d56fe3
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Kernel/Process/CapabilityExtensions.cs
@@ -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());
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/CapabilityType.cs b/Ryujinx.HLE/HOS/Kernel/Process/CapabilityType.cs
new file mode 100644
index 00000000..51d92316
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Kernel/Process/CapabilityType.cs
@@ -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
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/KHandleTable.cs b/Ryujinx.HLE/HOS/Kernel/Process/KHandleTable.cs
index c15ebef5..50f04e90 100644
--- a/Ryujinx.HLE/HOS/Kernel/Process/KHandleTable.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/KHandleTable.cs
@@ -19,7 +19,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
private int _activeSlotsCount;
- private int _size;
+ private uint _size;
private ushort _idCounter;
@@ -28,9 +28,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
_context = context;
}
- public Result Initialize(int size)
+ public Result Initialize(uint size)
{
- if ((uint)size > 1024)
+ if (size > 1024)
{
return KernelResult.OutOfMemory;
}
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
index 8d9cd242..21e89944 100644
--- a/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
@@ -16,11 +16,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
{
class KProcess : KSynchronizationObject
{
- public const int KernelVersionMajor = 10;
- public const int KernelVersionMinor = 4;
- public const int KernelVersionRevision = 0;
+ public const uint KernelVersionMajor = 10;
+ public const uint KernelVersionMinor = 4;
+ public const uint KernelVersionRevision = 0;
- public const int KernelVersionPacked =
+ public const uint KernelVersionPacked =
(KernelVersionMajor << 19) |
(KernelVersionMinor << 15) |
(KernelVersionRevision << 0);
@@ -119,7 +119,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
public Result InitializeKip(
ProcessCreationInfo creationInfo,
- ReadOnlySpan<int> capabilities,
+ ReadOnlySpan<uint> capabilities,
KPageList pageList,
KResourceLimit resourceLimit,
MemoryRegion memRegion,
@@ -190,7 +190,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
public Result Initialize(
ProcessCreationInfo creationInfo,
- ReadOnlySpan<int> capabilities,
+ ReadOnlySpan<uint> capabilities,
KResourceLimit resourceLimit,
MemoryRegion memRegion,
IProcessContextFactory contextFactory,
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs b/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs
index ef55a165..c99e3112 100644
--- a/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs
@@ -1,4 +1,3 @@
-using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Memory;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.Horizon.Common;
@@ -9,48 +8,49 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
{
class KProcessCapabilities
{
- public byte[] SvcAccessMask { get; private set; }
- public byte[] IrqAccessMask { get; private set; }
+ public byte[] SvcAccessMask { get; }
+ public byte[] IrqAccessMask { get; }
public ulong AllowedCpuCoresMask { get; private set; }
public ulong AllowedThreadPriosMask { get; private set; }
- public int DebuggingFlags { get; private set; }
- public int HandleTableSize { get; private set; }
- public int KernelReleaseVersion { get; private set; }
- public int ApplicationType { get; private set; }
+ public uint DebuggingFlags { get; private set; }
+ public uint HandleTableSize { get; private set; }
+ public uint KernelReleaseVersion { get; private set; }
+ public uint ApplicationType { get; private set; }
public KProcessCapabilities()
{
- SvcAccessMask = new byte[0x10];
+ // length / number of bits of the underlying type
+ SvcAccessMask = new byte[KernelConstants.SupervisorCallCount / 8];
IrqAccessMask = new byte[0x80];
}
- public Result InitializeForKernel(ReadOnlySpan<int> capabilities, KPageTableBase memoryManager)
+ public Result InitializeForKernel(ReadOnlySpan<uint> capabilities, KPageTableBase memoryManager)
{
AllowedCpuCoresMask = 0xf;
AllowedThreadPriosMask = ulong.MaxValue;
- DebuggingFlags &= ~3;
+ DebuggingFlags &= ~3u;
KernelReleaseVersion = KProcess.KernelVersionPacked;
return Parse(capabilities, memoryManager);
}
- public Result InitializeForUser(ReadOnlySpan<int> capabilities, KPageTableBase memoryManager)
+ public Result InitializeForUser(ReadOnlySpan<uint> capabilities, KPageTableBase 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 mask1 = 0;
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);
@@ -66,7 +66,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return KernelResult.InvalidCombination;
}
- int prevCap = cap;
+ uint prevCap = cap;
cap = capabilities[++index];
@@ -85,8 +85,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return KernelResult.InvalidSize;
}
- long address = ((long)(uint)prevCap << 5) & 0xffffff000;
- long size = ((long)(uint)cap << 5) & 0xfffff000;
+ long address = ((long)prevCap << 5) & 0xffffff000;
+ long size = ((long)cap << 5) & 0xfffff000;
if (((ulong)(address + size - 1) >> 36) != 0)
{
@@ -118,20 +118,20 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
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;
}
- else if (code == 0)
+ else if (code == CapabilityType.Padding)
{
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.
if (((mask0 & codeMask) & 0x1e008) != 0)
@@ -143,23 +143,23 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
switch (code)
{
- case 8:
+ case CapabilityType.CorePriority:
{
if (AllowedCpuCoresMask != 0 || AllowedThreadPriosMask != 0)
{
return KernelResult.InvalidCapability;
}
- int lowestCpuCore = (cap >> 16) & 0xff;
- int highestCpuCore = (cap >> 24) & 0xff;
+ uint lowestCpuCore = (cap >> 16) & 0xff;
+ uint highestCpuCore = (cap >> 24) & 0xff;
if (lowestCpuCore > highestCpuCore)
{
return KernelResult.InvalidCombination;
}
- int highestThreadPrio = (cap >> 4) & 0x3f;
- int lowestThreadPrio = (cap >> 10) & 0x3f;
+ uint highestThreadPrio = (cap >> 4) & 0x3f;
+ uint lowestThreadPrio = (cap >> 10) & 0x3f;
if (lowestThreadPrio > highestThreadPrio)
{
@@ -177,9 +177,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
break;
}
- case 0x10:
+ case CapabilityType.SyscallMask:
{
- int slot = (cap >> 29) & 7;
+ int slot = ((int)cap >> 29) & 7;
int svcSlotMask = 1 << slot;
@@ -190,7 +190,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
mask1 |= svcSlotMask;
- int svcMask = (cap >> 5) & 0xffffff;
+ uint svcMask = (cap >> 5) & 0xffffff;
int baseSvc = slot * 24;
@@ -203,7 +203,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
int svcId = baseSvc + index;
- if (svcId > 0x7f)
+ if (svcId >= KernelConstants.SupervisorCallCount)
{
return KernelResult.MaximumExceeded;
}
@@ -214,20 +214,27 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
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);
break;
}
- case 0x800:
+ case CapabilityType.MapRegion:
+ {
+ // TODO: Implement capabilities for MapRegion
+
+ break;
+ }
+
+ case CapabilityType.InterruptPair:
{
// TODO: GIC distributor check.
- int irq0 = (cap >> 12) & 0x3ff;
- int irq1 = (cap >> 22) & 0x3ff;
+ int irq0 = ((int)cap >> 12) & 0x3ff;
+ int irq1 = ((int)cap >> 22) & 0x3ff;
if (irq0 != 0x3ff)
{
@@ -242,11 +249,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
break;
}
- case 0x2000:
+ case CapabilityType.ProgramType:
{
- int applicationType = cap >> 14;
+ uint applicationType = (cap >> 14);
- if ((uint)applicationType > 7)
+ if (applicationType > 7)
{
return KernelResult.ReservedValue;
}
@@ -256,7 +263,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
break;
}
- case 0x4000:
+ case CapabilityType.KernelVersion:
{
// Note: This check is bugged on kernel too, we are just replicating the bug here.
if ((KernelReleaseVersion >> 17) != 0 || cap < 0x80000)
@@ -269,11 +276,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
break;
}
- case 0x8000:
+ case CapabilityType.HandleTable:
{
- int handleTableSize = cap >> 26;
+ uint handleTableSize = cap >> 26;
- if ((uint)handleTableSize > 0x3ff)
+ if (handleTableSize > 0x3ff)
{
return KernelResult.ReservedValue;
}
@@ -283,16 +290,16 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
break;
}
- case 0x10000:
+ case CapabilityType.DebugFlags:
{
- int debuggingFlags = cap >> 19;
+ uint debuggingFlags = cap >> 19;
- if ((uint)debuggingFlags > 3)
+ if (debuggingFlags > 3)
{
return KernelResult.ReservedValue;
}
- DebuggingFlags &= ~3;
+ DebuggingFlags &= ~3u;
DebuggingFlags |= debuggingFlags;
break;
@@ -304,18 +311,18 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
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)
{
return ulong.MaxValue;
}
- ulong mask = (1UL << range) - 1;
+ ulong mask = (1UL << (int)range) - 1;
- return mask << min;
+ return mask << (int)min;
}
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationFlags.cs b/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationFlags.cs
index a34481e5..a79978ac 100644
--- a/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationFlags.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/ProcessCreationFlags.cs
@@ -1,5 +1,8 @@
-namespace Ryujinx.HLE.HOS.Kernel.Process
+using System;
+
+namespace Ryujinx.HLE.HOS.Kernel.Process
{
+ [Flags]
enum ProcessCreationFlags
{
Is64Bit = 1 << 0,
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs
index e23274eb..eef78e18 100644
--- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs
+++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs
@@ -54,7 +54,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
public Result CreateProcess(
out int handle,
ProcessCreationInfo info,
- ReadOnlySpan<int> capabilities,
+ ReadOnlySpan<uint> capabilities,
IProcessContextFactory contextFactory,
ThreadStart customThreadStart = null)
{
@@ -3002,4 +3002,4 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return (address & 3) != 0;
}
}
-}
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/ProgramLoader.cs b/Ryujinx.HLE/HOS/ProgramLoader.cs
index 158ab701..4ebcb7e7 100644
--- a/Ryujinx.HLE/HOS/ProgramLoader.cs
+++ b/Ryujinx.HLE/HOS/ProgramLoader.cs
@@ -80,7 +80,7 @@ namespace Ryujinx.HLE.HOS
ulong codeBaseAddress = kip.Is64BitAddressSpace ? 0x8000000UL : 0x200000UL;
- ulong codeAddress = codeBaseAddress + (ulong)kip.TextOffset;
+ ulong codeAddress = codeBaseAddress + kip.TextOffset;
ProcessCreationFlags flags = 0;
@@ -231,13 +231,13 @@ namespace Ryujinx.HLE.HOS
nsoSize = BitUtils.AlignUp<uint>(nsoSize, KPageTableBase.PageSize);
- nsoBase[index] = codeStart + (ulong)codeSize;
+ nsoBase[index] = codeStart + codeSize;
codeSize += nsoSize;
if (arguments != null && argsSize == 0)
{
- argsStart = (ulong)codeSize;
+ argsStart = codeSize;
argsSize = (uint)BitUtils.AlignDown(arguments.Length * 2 + ArgsTotalSize - 1, KPageTableBase.PageSize);
@@ -318,7 +318,7 @@ namespace Ryujinx.HLE.HOS
result = process.Initialize(
creationInfo,
- MemoryMarshal.Cast<byte, int>(npdm.KernelCapabilityData).ToArray(),
+ MemoryMarshal.Cast<byte, uint>(npdm.KernelCapabilityData),
resourceLimit,
memoryRegion,
processContextFactory);
diff --git a/Ryujinx.HLE/HOS/Services/ServerBase.cs b/Ryujinx.HLE/HOS/Services/ServerBase.cs
index 50f6c99e..d4382a64 100644
--- a/Ryujinx.HLE/HOS/Services/ServerBase.cs
+++ b/Ryujinx.HLE/HOS/Services/ServerBase.cs
@@ -19,7 +19,7 @@ namespace Ryujinx.HLE.HOS.Services
// not large enough.
private const int PointerBufferSize = 0x8000;
- private readonly static int[] DefaultCapabilities = new int[]
+ private readonly static uint[] DefaultCapabilities = new uint[]
{
0x030363F7,
0x1FFFFFCF,
diff --git a/Ryujinx.HLE/Loaders/Executables/KipExecutable.cs b/Ryujinx.HLE/Loaders/Executables/KipExecutable.cs
index 2073a7e2..ad2b681c 100644
--- a/Ryujinx.HLE/Loaders/Executables/KipExecutable.cs
+++ b/Ryujinx.HLE/Loaders/Executables/KipExecutable.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.HLE.Loaders.Executables
public uint DataSize { get; }
public uint BssSize { get; }
- public int[] Capabilities { get; }
+ public uint[] Capabilities { get; }
public bool UsesSecureMemory { get; }
public bool Is64BitAddressSpace { get; }
public bool Is64Bit { get; }
@@ -57,11 +57,11 @@ namespace Ryujinx.HLE.Loaders.Executables
Version = reader.Version;
Name = reader.Name.ToString();
- Capabilities = new int[32];
+ Capabilities = new uint[32];
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();