diff options
author | TSR Berry <20988865+TSRBerry@users.noreply.github.com> | 2023-04-08 01:22:00 +0200 |
---|---|---|
committer | Mary <thog@protonmail.com> | 2023-04-27 23:51:14 +0200 |
commit | cee712105850ac3385cd0091a923438167433f9f (patch) | |
tree | 4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs | |
parent | cd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff) |
Move solution and projects to src
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs')
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs | 328 |
1 files changed, 0 insertions, 328 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs b/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs deleted file mode 100644 index c99e3112..00000000 --- a/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs +++ /dev/null @@ -1,328 +0,0 @@ -using Ryujinx.HLE.HOS.Kernel.Memory; -using Ryujinx.HLE.HOS.Kernel.Threading; -using Ryujinx.Horizon.Common; -using System; -using System.Numerics; - -namespace Ryujinx.HLE.HOS.Kernel.Process -{ - class KProcessCapabilities - { - public byte[] SvcAccessMask { get; } - public byte[] IrqAccessMask { get; } - - public ulong AllowedCpuCoresMask { get; private set; } - public ulong AllowedThreadPriosMask { 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() - { - // length / number of bits of the underlying type - SvcAccessMask = new byte[KernelConstants.SupervisorCallCount / 8]; - IrqAccessMask = new byte[0x80]; - } - - public Result InitializeForKernel(ReadOnlySpan<uint> capabilities, KPageTableBase memoryManager) - { - AllowedCpuCoresMask = 0xf; - AllowedThreadPriosMask = ulong.MaxValue; - DebuggingFlags &= ~3u; - KernelReleaseVersion = KProcess.KernelVersionPacked; - - return Parse(capabilities, memoryManager); - } - - public Result InitializeForUser(ReadOnlySpan<uint> capabilities, KPageTableBase memoryManager) - { - return Parse(capabilities, memoryManager); - } - - private Result Parse(ReadOnlySpan<uint> capabilities, KPageTableBase memoryManager) - { - int mask0 = 0; - int mask1 = 0; - - for (int index = 0; index < capabilities.Length; index++) - { - uint cap = capabilities[index]; - - if (cap.GetCapabilityType() != CapabilityType.MapRange) - { - Result result = ParseCapability(cap, ref mask0, ref mask1, memoryManager); - - if (result != Result.Success) - { - return result; - } - } - else - { - if ((uint)index + 1 >= capabilities.Length) - { - return KernelResult.InvalidCombination; - } - - uint prevCap = cap; - - cap = capabilities[++index]; - - if (((cap + 1) & ~cap) != 0x40) - { - return KernelResult.InvalidCombination; - } - - if ((cap & 0x78000000) != 0) - { - return KernelResult.MaximumExceeded; - } - - if ((cap & 0x7ffff80) == 0) - { - return KernelResult.InvalidSize; - } - - long address = ((long)prevCap << 5) & 0xffffff000; - long size = ((long)cap << 5) & 0xfffff000; - - if (((ulong)(address + size - 1) >> 36) != 0) - { - return KernelResult.InvalidAddress; - } - - KMemoryPermission perm = (prevCap >> 31) != 0 - ? KMemoryPermission.Read - : KMemoryPermission.ReadAndWrite; - - Result result; - - if ((cap >> 31) != 0) - { - result = memoryManager.MapNormalMemory(address, size, perm); - } - else - { - result = memoryManager.MapIoMemory(address, size, perm); - } - - if (result != Result.Success) - { - return result; - } - } - } - - return Result.Success; - } - - private Result ParseCapability(uint cap, ref int mask0, ref int mask1, KPageTableBase memoryManager) - { - CapabilityType code = cap.GetCapabilityType(); - - if (code == CapabilityType.Invalid) - { - return KernelResult.InvalidCapability; - } - else if (code == CapabilityType.Padding) - { - return Result.Success; - } - - int codeMask = 1 << (32 - BitOperations.LeadingZeroCount(code.GetFlag() + 1)); - - // Check if the property was already set. - if (((mask0 & codeMask) & 0x1e008) != 0) - { - return KernelResult.InvalidCombination; - } - - mask0 |= codeMask; - - switch (code) - { - case CapabilityType.CorePriority: - { - if (AllowedCpuCoresMask != 0 || AllowedThreadPriosMask != 0) - { - return KernelResult.InvalidCapability; - } - - uint lowestCpuCore = (cap >> 16) & 0xff; - uint highestCpuCore = (cap >> 24) & 0xff; - - if (lowestCpuCore > highestCpuCore) - { - return KernelResult.InvalidCombination; - } - - uint highestThreadPrio = (cap >> 4) & 0x3f; - uint lowestThreadPrio = (cap >> 10) & 0x3f; - - if (lowestThreadPrio > highestThreadPrio) - { - return KernelResult.InvalidCombination; - } - - if (highestCpuCore >= KScheduler.CpuCoresCount) - { - return KernelResult.InvalidCpuCore; - } - - AllowedCpuCoresMask = GetMaskFromMinMax(lowestCpuCore, highestCpuCore); - AllowedThreadPriosMask = GetMaskFromMinMax(lowestThreadPrio, highestThreadPrio); - - break; - } - - case CapabilityType.SyscallMask: - { - int slot = ((int)cap >> 29) & 7; - - int svcSlotMask = 1 << slot; - - if ((mask1 & svcSlotMask) != 0) - { - return KernelResult.InvalidCombination; - } - - mask1 |= svcSlotMask; - - uint svcMask = (cap >> 5) & 0xffffff; - - int baseSvc = slot * 24; - - for (int index = 0; index < 24; index++) - { - if (((svcMask >> index) & 1) == 0) - { - continue; - } - - int svcId = baseSvc + index; - - if (svcId >= KernelConstants.SupervisorCallCount) - { - return KernelResult.MaximumExceeded; - } - - SvcAccessMask[svcId / 8] |= (byte)(1 << (svcId & 7)); - } - - break; - } - - case CapabilityType.MapIoPage: - { - long address = ((long)cap << 4) & 0xffffff000; - - memoryManager.MapIoMemory(address, KPageTableBase.PageSize, KMemoryPermission.ReadAndWrite); - - break; - } - - case CapabilityType.MapRegion: - { - // TODO: Implement capabilities for MapRegion - - break; - } - - case CapabilityType.InterruptPair: - { - // TODO: GIC distributor check. - int irq0 = ((int)cap >> 12) & 0x3ff; - int irq1 = ((int)cap >> 22) & 0x3ff; - - if (irq0 != 0x3ff) - { - IrqAccessMask[irq0 / 8] |= (byte)(1 << (irq0 & 7)); - } - - if (irq1 != 0x3ff) - { - IrqAccessMask[irq1 / 8] |= (byte)(1 << (irq1 & 7)); - } - - break; - } - - case CapabilityType.ProgramType: - { - uint applicationType = (cap >> 14); - - if (applicationType > 7) - { - return KernelResult.ReservedValue; - } - - ApplicationType = applicationType; - - break; - } - - case CapabilityType.KernelVersion: - { - // Note: This check is bugged on kernel too, we are just replicating the bug here. - if ((KernelReleaseVersion >> 17) != 0 || cap < 0x80000) - { - return KernelResult.ReservedValue; - } - - KernelReleaseVersion = cap; - - break; - } - - case CapabilityType.HandleTable: - { - uint handleTableSize = cap >> 26; - - if (handleTableSize > 0x3ff) - { - return KernelResult.ReservedValue; - } - - HandleTableSize = handleTableSize; - - break; - } - - case CapabilityType.DebugFlags: - { - uint debuggingFlags = cap >> 19; - - if (debuggingFlags > 3) - { - return KernelResult.ReservedValue; - } - - DebuggingFlags &= ~3u; - DebuggingFlags |= debuggingFlags; - - break; - } - - default: return KernelResult.InvalidCapability; - } - - return Result.Success; - } - - private static ulong GetMaskFromMinMax(uint min, uint max) - { - uint range = max - min + 1; - - if (range == 64) - { - return ulong.MaxValue; - } - - ulong mask = (1UL << (int)range) - 1; - - return mask << (int)min; - } - } -}
\ No newline at end of file |