[Ryujinx.Cpu] Address dotnet-format issues (#5365)

* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format IDE1006 warnings

* Address dotnet format CA1816 warnings

* Address most dotnet format whitespace warnings

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Remove a few unused parameters

* Adjust namespaces

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Address review feedback

* Remove redundant unsafe modifiers

* Fix build issues

* Add GC.SuppressFinalize() call

* Add trailing commas and fix naming rule violations

* Remove unused members and assignments
This commit is contained in:
TSRBerry 2023-07-01 04:18:52 +02:00 committed by GitHub
parent e9848339dd
commit 79a1314ee4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 383 additions and 394 deletions

View file

@ -7,15 +7,13 @@ namespace Ryujinx.Cpu
{ {
public class AddressSpace : IDisposable public class AddressSpace : IDisposable
{ {
private const ulong PageSize = 0x1000;
private const int DefaultBlockAlignment = 1 << 20; private const int DefaultBlockAlignment = 1 << 20;
private enum MappingType : byte private enum MappingType : byte
{ {
None, None,
Private, Private,
Shared Shared,
} }
private class Mapping : IntrusiveRedBlackTreeNode<Mapping>, IComparable<Mapping> private class Mapping : IntrusiveRedBlackTreeNode<Mapping>, IComparable<Mapping>
@ -37,7 +35,7 @@ namespace Ryujinx.Cpu
ulong leftSize = splitAddress - Address; ulong leftSize = splitAddress - Address;
ulong rightSize = EndAddress - splitAddress; ulong rightSize = EndAddress - splitAddress;
Mapping left = new Mapping(Address, leftSize, Type); Mapping left = new(Address, leftSize, Type);
Address = splitAddress; Address = splitAddress;
Size = rightSize; Size = rightSize;
@ -93,7 +91,7 @@ namespace Ryujinx.Cpu
(var leftAllocation, PrivateAllocation) = PrivateAllocation.Split(leftSize); (var leftAllocation, PrivateAllocation) = PrivateAllocation.Split(leftSize);
PrivateMapping left = new PrivateMapping(Address, leftSize, leftAllocation); PrivateMapping left = new(Address, leftSize, leftAllocation);
Address = splitAddress; Address = splitAddress;
Size = rightSize; Size = rightSize;
@ -181,7 +179,7 @@ namespace Ryujinx.Cpu
{ {
addressSpace = null; addressSpace = null;
MemoryAllocationFlags asFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible; const MemoryAllocationFlags asFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible;
ulong minAddressSpaceSize = Math.Min(asSize, 1UL << 36); ulong minAddressSpaceSize = Math.Min(asSize, 1UL << 36);
@ -391,8 +389,6 @@ namespace Ryujinx.Cpu
ulong vaAligned = BitUtils.AlignDown(va, alignment); ulong vaAligned = BitUtils.AlignDown(va, alignment);
ulong endAddressAligned = BitUtils.AlignUp(endAddress, alignment); ulong endAddressAligned = BitUtils.AlignUp(endAddress, alignment);
ulong sizeAligned = endAddressAligned - vaAligned;
PrivateMapping map = _privateTree.GetNode(new PrivateMapping(va, 1UL, default)); PrivateMapping map = _privateTree.GetNode(new PrivateMapping(va, 1UL, default));
for (; map != null; map = map.Successor) for (; map != null; map = map.Successor)
@ -436,8 +432,6 @@ namespace Ryujinx.Cpu
return; return;
} }
ulong alignedSize = endAddressAligned - vaAligned;
PrivateMapping map = _privateTree.GetNode(new PrivateMapping(va, 1UL, default)); PrivateMapping map = _privateTree.GetNode(new PrivateMapping(va, 1UL, default));
for (; map != null; map = map.Successor) for (; map != null; map = map.Successor)
@ -495,6 +489,8 @@ namespace Ryujinx.Cpu
public void Dispose() public void Dispose()
{ {
GC.SuppressFinalize(this);
_privateMemoryAllocator?.Dispose(); _privateMemoryAllocator?.Dispose();
Base.Dispose(); Base.Dispose();
Mirror.Dispose(); Mirror.Dispose();

View file

@ -42,6 +42,6 @@ namespace Ryujinx.Cpu.AppleHv.Arm
WatchpointSameEl = 0b110101, WatchpointSameEl = 0b110101,
BkptAarch32 = 0b111000, BkptAarch32 = 0b111000,
VectorCatchAarch32 = 0b111010, VectorCatchAarch32 = 0b111010,
BrkAarch64 = 0b111100 BrkAarch64 = 0b111100,
} }
} }

View file

@ -4,7 +4,7 @@ namespace Ryujinx.Cpu.AppleHv
{ {
public class DummyDiskCacheLoadState : IDiskCacheLoadState public class DummyDiskCacheLoadState : IDiskCacheLoadState
{ {
#pragma warning disable CS0067 #pragma warning disable CS0067 // The event is never used
/// <inheritdoc/> /// <inheritdoc/>
public event Action<LoadState, int, int> StateChanged; public event Action<LoadState, int, int> StateChanged;
#pragma warning restore CS0067 #pragma warning restore CS0067

View file

@ -18,18 +18,16 @@ namespace Ryujinx.Cpu.AppleHv
private const ulong AllocationGranule = 1UL << 14; private const ulong AllocationGranule = 1UL << 14;
private readonly ulong _asBase; private readonly ulong _asBase;
private readonly ulong _asSize;
private readonly ulong _backingSize; private readonly ulong _backingSize;
private readonly HvAddressSpaceRange _userRange; private readonly HvAddressSpaceRange _userRange;
private readonly HvAddressSpaceRange _kernelRange; private readonly HvAddressSpaceRange _kernelRange;
private MemoryBlock _kernelCodeBlock; private readonly MemoryBlock _kernelCodeBlock;
public HvAddressSpace(MemoryBlock backingMemory, ulong asSize) public HvAddressSpace(MemoryBlock backingMemory, ulong asSize)
{ {
(_asBase, var ipaAllocator) = HvVm.CreateAddressSpace(backingMemory); (_asBase, var ipaAllocator) = HvVm.CreateAddressSpace(backingMemory);
_asSize = asSize;
_backingSize = backingMemory.Size; _backingSize = backingMemory.Size;
_userRange = new HvAddressSpaceRange(ipaAllocator); _userRange = new HvAddressSpaceRange(ipaAllocator);
@ -58,20 +56,20 @@ namespace Ryujinx.Cpu.AppleHv
_kernelCodeBlock.Write(KernelRegionEretOffset, 0xD69F03E0u); // ERET _kernelCodeBlock.Write(KernelRegionEretOffset, 0xD69F03E0u); // ERET
ulong kernelCodePa = ipaAllocator.Allocate(AllocationGranule); ulong kernelCodePa = ipaAllocator.Allocate(AllocationGranule);
HvApi.hv_vm_map((ulong)_kernelCodeBlock.Pointer, kernelCodePa, AllocationGranule, hv_memory_flags_t.HV_MEMORY_READ | hv_memory_flags_t.HV_MEMORY_EXEC).ThrowOnError(); HvApi.hv_vm_map((ulong)_kernelCodeBlock.Pointer, kernelCodePa, AllocationGranule, HvMemoryFlags.Read | HvMemoryFlags.Exec).ThrowOnError();
_kernelRange.Map(KernelRegionCodeOffset, kernelCodePa, KernelRegionCodeSize, ApFlags.UserNoneKernelReadExecute); _kernelRange.Map(KernelRegionCodeOffset, kernelCodePa, KernelRegionCodeSize, ApFlags.UserNoneKernelReadExecute);
} }
public void InitializeMmu(ulong vcpu) public void InitializeMmu(ulong vcpu)
{ {
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_VBAR_EL1, KernelRegionBase + KernelRegionCodeOffset); HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.VBAR_EL1, KernelRegionBase + KernelRegionCodeOffset);
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_TTBR0_EL1, _userRange.GetIpaBase()); HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.TTBR0_EL1, _userRange.GetIpaBase());
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_TTBR1_EL1, _kernelRange.GetIpaBase()); HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.TTBR1_EL1, _kernelRange.GetIpaBase());
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_MAIR_EL1, 0xffUL); HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.MAIR_EL1, 0xffUL);
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_TCR_EL1, 0x00000011B5193519UL); HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.TCR_EL1, 0x00000011B5193519UL);
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_SCTLR_EL1, 0x0000000034D5D925UL); HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.SCTLR_EL1, 0x0000000034D5D925UL);
} }
public bool GetAndClearUserTlbInvalidationPending() public bool GetAndClearUserTlbInvalidationPending()
@ -115,7 +113,7 @@ namespace Ryujinx.Cpu.AppleHv
MemoryPermission.ReadAndWrite => ApFlags.UserReadWriteKernelReadWrite, MemoryPermission.ReadAndWrite => ApFlags.UserReadWriteKernelReadWrite,
MemoryPermission.ReadAndExecute => ApFlags.UserReadExecuteKernelRead, MemoryPermission.ReadAndExecute => ApFlags.UserReadExecuteKernelRead,
MemoryPermission.ReadWriteExecute => ApFlags.UserReadWriteExecuteKernelReadWrite, MemoryPermission.ReadWriteExecute => ApFlags.UserReadWriteExecuteKernelReadWrite,
_ => throw new ArgumentException($"Permission \"{permission}\" is invalid.") _ => throw new ArgumentException($"Permission \"{permission}\" is invalid."),
}; };
} }

View file

@ -34,7 +34,7 @@ namespace Ryujinx.Cpu.AppleHv
ulong size = (ulong)count * sizeof(ulong); ulong size = (ulong)count * sizeof(ulong);
Allocation = blockAllocator.Allocate(size, PageSize); Allocation = blockAllocator.Allocate(size, PageSize);
AsSpan().Fill(0UL); AsSpan().Clear();
if (hasNext) if (hasNext)
{ {
@ -42,7 +42,7 @@ namespace Ryujinx.Cpu.AppleHv
} }
} }
public unsafe Span<ulong> AsSpan() public Span<ulong> AsSpan()
{ {
return MemoryMarshal.Cast<byte, ulong>(Allocation.Memory.GetSpan(Allocation.Offset, (int)Allocation.Size)); return MemoryMarshal.Cast<byte, ulong>(Allocation.Memory.GetSpan(Allocation.Offset, (int)Allocation.Size));
} }
@ -52,12 +52,10 @@ namespace Ryujinx.Cpu.AppleHv
private int _tlbInvalidationPending; private int _tlbInvalidationPending;
private readonly HvIpaAllocator _ipaAllocator;
private readonly HvMemoryBlockAllocator _blockAllocator; private readonly HvMemoryBlockAllocator _blockAllocator;
public HvAddressSpaceRange(HvIpaAllocator ipaAllocator) public HvAddressSpaceRange(HvIpaAllocator ipaAllocator)
{ {
_ipaAllocator = ipaAllocator;
_blockAllocator = new HvMemoryBlockAllocator(ipaAllocator, (int)AllocationGranule); _blockAllocator = new HvMemoryBlockAllocator(ipaAllocator, (int)AllocationGranule);
} }
@ -129,7 +127,7 @@ namespace Ryujinx.Cpu.AppleHv
ulong endVa = (va + size + PageMask) & ~((ulong)PageMask); ulong endVa = (va + size + PageMask) & ~((ulong)PageMask);
va &= ~((ulong)PageMask); va &= ~((ulong)PageMask);
(ulong blockSize, int blockShift) = GetBlockSizeAndShift(depth); (ulong blockSize, _) = GetBlockSizeAndShift(depth);
while (va < endVa) while (va < endVa)
{ {
@ -138,7 +136,7 @@ namespace Ryujinx.Cpu.AppleHv
int l = (int)(va >> (PageBits + (2 - depth) * LevelBits)) & LevelMask; int l = (int)(va >> (PageBits + (2 - depth) * LevelBits)) & LevelMask;
PtLevel nextTable = level.Next != null ? level.Next[l] : null; PtLevel nextTable = level.Next?[l];
if (nextTable != null) if (nextTable != null)
{ {
@ -190,7 +188,7 @@ namespace Ryujinx.Cpu.AppleHv
ulong endVa = (va + size + PageSize - 1) & ~((ulong)PageSize - 1); ulong endVa = (va + size + PageSize - 1) & ~((ulong)PageSize - 1);
va &= ~((ulong)PageSize - 1); va &= ~((ulong)PageSize - 1);
(ulong blockSize, int blockShift) = GetBlockSizeAndShift(depth); (ulong blockSize, _) = GetBlockSizeAndShift(depth);
while (va < endVa) while (va < endVa)
{ {
@ -204,7 +202,7 @@ namespace Ryujinx.Cpu.AppleHv
// First check if the region is mapped. // First check if the region is mapped.
if ((pte & 3) != 0) if ((pte & 3) != 0)
{ {
PtLevel nextTable = level.Next != null ? level.Next[l] : null; PtLevel nextTable = level.Next?[l];
if (nextTable != null) if (nextTable != null)
{ {
@ -240,10 +238,10 @@ namespace Ryujinx.Cpu.AppleHv
pte &= ~3UL; pte &= ~3UL;
pte |= (depth == 2 ? 3UL : 1UL); pte |= (depth == 2 ? 3UL : 1UL);
PtLevel level = new PtLevel(_blockAllocator, LevelCount, depth < 2); PtLevel level = new(_blockAllocator, LevelCount, depth < 2);
Span<ulong> currentLevel = level.AsSpan(); Span<ulong> currentLevel = level.AsSpan();
(ulong blockSize, int blockShift) = GetBlockSizeAndShift(depth); (_, int blockShift) = GetBlockSizeAndShift(depth);
// Fill in the blocks. // Fill in the blocks.
for (int i = 0; i < LevelCount; i++) for (int i = 0; i < LevelCount; i++)
@ -334,7 +332,7 @@ namespace Ryujinx.Cpu.AppleHv
if ((currentTable[index] & 1) == 0) if ((currentTable[index] & 1) == 0)
{ {
PtLevel nextLevel = new PtLevel(_blockAllocator, LevelCount, hasNext); PtLevel nextLevel = new(_blockAllocator, LevelCount, hasNext);
currentTable[index] = (nextLevel.Address & ~(ulong)PageMask) | 3UL; currentTable[index] = (nextLevel.Address & ~(ulong)PageMask) | 3UL;
level.Next[index] = nextLevel; level.Next[index] = nextLevel;
@ -347,7 +345,7 @@ namespace Ryujinx.Cpu.AppleHv
} }
} }
private void WriteBlock(PtLevel level, int index, int depth, ulong pa, ulong attr) private static void WriteBlock(PtLevel level, int index, int depth, ulong pa, ulong attr)
{ {
Span<ulong> currentTable = level.AsSpan(); Span<ulong> currentTable = level.AsSpan();

View file

@ -1,245 +1,244 @@
using ARMeilleure.State;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Ryujinx.Cpu.AppleHv namespace Ryujinx.Cpu.AppleHv
{ {
struct hv_vcpu_exit_exception_t struct HvVcpuExitException
{ {
#pragma warning disable CS0649 #pragma warning disable CS0649 // Field is never assigned to
public ulong syndrome; public ulong Syndrome;
public ulong virtual_address; public ulong VirtualAddress;
public ulong physical_address; public ulong PhysicalAddress;
#pragma warning restore CS0649 #pragma warning restore CS0649
} }
struct hv_vcpu_exit_t struct HvVcpuExit
{ {
#pragma warning disable CS0649 #pragma warning disable CS0649 // Field is never assigned to
public uint reason; public uint Reason;
public hv_vcpu_exit_exception_t exception; public HvVcpuExitException Exception;
#pragma warning restore CS0649 #pragma warning restore CS0649
} }
enum hv_reg_t : uint enum HvReg : uint
{ {
HV_REG_X0, X0,
HV_REG_X1, X1,
HV_REG_X2, X2,
HV_REG_X3, X3,
HV_REG_X4, X4,
HV_REG_X5, X5,
HV_REG_X6, X6,
HV_REG_X7, X7,
HV_REG_X8, X8,
HV_REG_X9, X9,
HV_REG_X10, X10,
HV_REG_X11, X11,
HV_REG_X12, X12,
HV_REG_X13, X13,
HV_REG_X14, X14,
HV_REG_X15, X15,
HV_REG_X16, X16,
HV_REG_X17, X17,
HV_REG_X18, X18,
HV_REG_X19, X19,
HV_REG_X20, X20,
HV_REG_X21, X21,
HV_REG_X22, X22,
HV_REG_X23, X23,
HV_REG_X24, X24,
HV_REG_X25, X25,
HV_REG_X26, X26,
HV_REG_X27, X27,
HV_REG_X28, X28,
HV_REG_X29, X29,
HV_REG_FP = HV_REG_X29, FP = X29,
HV_REG_X30, X30,
HV_REG_LR = HV_REG_X30, LR = X30,
HV_REG_PC, PC,
HV_REG_FPCR, FPCR,
HV_REG_FPSR, FPSR,
HV_REG_CPSR, CPSR,
} }
enum hv_simd_fp_reg_t : uint enum HvSimdFPReg : uint
{ {
HV_SIMD_FP_REG_Q0, Q0,
HV_SIMD_FP_REG_Q1, Q1,
HV_SIMD_FP_REG_Q2, Q2,
HV_SIMD_FP_REG_Q3, Q3,
HV_SIMD_FP_REG_Q4, Q4,
HV_SIMD_FP_REG_Q5, Q5,
HV_SIMD_FP_REG_Q6, Q6,
HV_SIMD_FP_REG_Q7, Q7,
HV_SIMD_FP_REG_Q8, Q8,
HV_SIMD_FP_REG_Q9, Q9,
HV_SIMD_FP_REG_Q10, Q10,
HV_SIMD_FP_REG_Q11, Q11,
HV_SIMD_FP_REG_Q12, Q12,
HV_SIMD_FP_REG_Q13, Q13,
HV_SIMD_FP_REG_Q14, Q14,
HV_SIMD_FP_REG_Q15, Q15,
HV_SIMD_FP_REG_Q16, Q16,
HV_SIMD_FP_REG_Q17, Q17,
HV_SIMD_FP_REG_Q18, Q18,
HV_SIMD_FP_REG_Q19, Q19,
HV_SIMD_FP_REG_Q20, Q20,
HV_SIMD_FP_REG_Q21, Q21,
HV_SIMD_FP_REG_Q22, Q22,
HV_SIMD_FP_REG_Q23, Q23,
HV_SIMD_FP_REG_Q24, Q24,
HV_SIMD_FP_REG_Q25, Q25,
HV_SIMD_FP_REG_Q26, Q26,
HV_SIMD_FP_REG_Q27, Q27,
HV_SIMD_FP_REG_Q28, Q28,
HV_SIMD_FP_REG_Q29, Q29,
HV_SIMD_FP_REG_Q30, Q30,
HV_SIMD_FP_REG_Q31, Q31,
} }
enum hv_sys_reg_t : ushort enum HvSysReg : ushort
{ {
HV_SYS_REG_DBGBVR0_EL1 = 0x8004, DBGBVR0_EL1 = 0x8004,
HV_SYS_REG_DBGBCR0_EL1 = 0x8005, DBGBCR0_EL1 = 0x8005,
HV_SYS_REG_DBGWVR0_EL1 = 0x8006, DBGWVR0_EL1 = 0x8006,
HV_SYS_REG_DBGWCR0_EL1 = 0x8007, DBGWCR0_EL1 = 0x8007,
HV_SYS_REG_DBGBVR1_EL1 = 0x800c, DBGBVR1_EL1 = 0x800c,
HV_SYS_REG_DBGBCR1_EL1 = 0x800d, DBGBCR1_EL1 = 0x800d,
HV_SYS_REG_DBGWVR1_EL1 = 0x800e, DBGWVR1_EL1 = 0x800e,
HV_SYS_REG_DBGWCR1_EL1 = 0x800f, DBGWCR1_EL1 = 0x800f,
HV_SYS_REG_MDCCINT_EL1 = 0x8010, MDCCINT_EL1 = 0x8010,
HV_SYS_REG_MDSCR_EL1 = 0x8012, MDSCR_EL1 = 0x8012,
HV_SYS_REG_DBGBVR2_EL1 = 0x8014, DBGBVR2_EL1 = 0x8014,
HV_SYS_REG_DBGBCR2_EL1 = 0x8015, DBGBCR2_EL1 = 0x8015,
HV_SYS_REG_DBGWVR2_EL1 = 0x8016, DBGWVR2_EL1 = 0x8016,
HV_SYS_REG_DBGWCR2_EL1 = 0x8017, DBGWCR2_EL1 = 0x8017,
HV_SYS_REG_DBGBVR3_EL1 = 0x801c, DBGBVR3_EL1 = 0x801c,
HV_SYS_REG_DBGBCR3_EL1 = 0x801d, DBGBCR3_EL1 = 0x801d,
HV_SYS_REG_DBGWVR3_EL1 = 0x801e, DBGWVR3_EL1 = 0x801e,
HV_SYS_REG_DBGWCR3_EL1 = 0x801f, DBGWCR3_EL1 = 0x801f,
HV_SYS_REG_DBGBVR4_EL1 = 0x8024, DBGBVR4_EL1 = 0x8024,
HV_SYS_REG_DBGBCR4_EL1 = 0x8025, DBGBCR4_EL1 = 0x8025,
HV_SYS_REG_DBGWVR4_EL1 = 0x8026, DBGWVR4_EL1 = 0x8026,
HV_SYS_REG_DBGWCR4_EL1 = 0x8027, DBGWCR4_EL1 = 0x8027,
HV_SYS_REG_DBGBVR5_EL1 = 0x802c, DBGBVR5_EL1 = 0x802c,
HV_SYS_REG_DBGBCR5_EL1 = 0x802d, DBGBCR5_EL1 = 0x802d,
HV_SYS_REG_DBGWVR5_EL1 = 0x802e, DBGWVR5_EL1 = 0x802e,
HV_SYS_REG_DBGWCR5_EL1 = 0x802f, DBGWCR5_EL1 = 0x802f,
HV_SYS_REG_DBGBVR6_EL1 = 0x8034, DBGBVR6_EL1 = 0x8034,
HV_SYS_REG_DBGBCR6_EL1 = 0x8035, DBGBCR6_EL1 = 0x8035,
HV_SYS_REG_DBGWVR6_EL1 = 0x8036, DBGWVR6_EL1 = 0x8036,
HV_SYS_REG_DBGWCR6_EL1 = 0x8037, DBGWCR6_EL1 = 0x8037,
HV_SYS_REG_DBGBVR7_EL1 = 0x803c, DBGBVR7_EL1 = 0x803c,
HV_SYS_REG_DBGBCR7_EL1 = 0x803d, DBGBCR7_EL1 = 0x803d,
HV_SYS_REG_DBGWVR7_EL1 = 0x803e, DBGWVR7_EL1 = 0x803e,
HV_SYS_REG_DBGWCR7_EL1 = 0x803f, DBGWCR7_EL1 = 0x803f,
HV_SYS_REG_DBGBVR8_EL1 = 0x8044, DBGBVR8_EL1 = 0x8044,
HV_SYS_REG_DBGBCR8_EL1 = 0x8045, DBGBCR8_EL1 = 0x8045,
HV_SYS_REG_DBGWVR8_EL1 = 0x8046, DBGWVR8_EL1 = 0x8046,
HV_SYS_REG_DBGWCR8_EL1 = 0x8047, DBGWCR8_EL1 = 0x8047,
HV_SYS_REG_DBGBVR9_EL1 = 0x804c, DBGBVR9_EL1 = 0x804c,
HV_SYS_REG_DBGBCR9_EL1 = 0x804d, DBGBCR9_EL1 = 0x804d,
HV_SYS_REG_DBGWVR9_EL1 = 0x804e, DBGWVR9_EL1 = 0x804e,
HV_SYS_REG_DBGWCR9_EL1 = 0x804f, DBGWCR9_EL1 = 0x804f,
HV_SYS_REG_DBGBVR10_EL1 = 0x8054, DBGBVR10_EL1 = 0x8054,
HV_SYS_REG_DBGBCR10_EL1 = 0x8055, DBGBCR10_EL1 = 0x8055,
HV_SYS_REG_DBGWVR10_EL1 = 0x8056, DBGWVR10_EL1 = 0x8056,
HV_SYS_REG_DBGWCR10_EL1 = 0x8057, DBGWCR10_EL1 = 0x8057,
HV_SYS_REG_DBGBVR11_EL1 = 0x805c, DBGBVR11_EL1 = 0x805c,
HV_SYS_REG_DBGBCR11_EL1 = 0x805d, DBGBCR11_EL1 = 0x805d,
HV_SYS_REG_DBGWVR11_EL1 = 0x805e, DBGWVR11_EL1 = 0x805e,
HV_SYS_REG_DBGWCR11_EL1 = 0x805f, DBGWCR11_EL1 = 0x805f,
HV_SYS_REG_DBGBVR12_EL1 = 0x8064, DBGBVR12_EL1 = 0x8064,
HV_SYS_REG_DBGBCR12_EL1 = 0x8065, DBGBCR12_EL1 = 0x8065,
HV_SYS_REG_DBGWVR12_EL1 = 0x8066, DBGWVR12_EL1 = 0x8066,
HV_SYS_REG_DBGWCR12_EL1 = 0x8067, DBGWCR12_EL1 = 0x8067,
HV_SYS_REG_DBGBVR13_EL1 = 0x806c, DBGBVR13_EL1 = 0x806c,
HV_SYS_REG_DBGBCR13_EL1 = 0x806d, DBGBCR13_EL1 = 0x806d,
HV_SYS_REG_DBGWVR13_EL1 = 0x806e, DBGWVR13_EL1 = 0x806e,
HV_SYS_REG_DBGWCR13_EL1 = 0x806f, DBGWCR13_EL1 = 0x806f,
HV_SYS_REG_DBGBVR14_EL1 = 0x8074, DBGBVR14_EL1 = 0x8074,
HV_SYS_REG_DBGBCR14_EL1 = 0x8075, DBGBCR14_EL1 = 0x8075,
HV_SYS_REG_DBGWVR14_EL1 = 0x8076, DBGWVR14_EL1 = 0x8076,
HV_SYS_REG_DBGWCR14_EL1 = 0x8077, DBGWCR14_EL1 = 0x8077,
HV_SYS_REG_DBGBVR15_EL1 = 0x807c, DBGBVR15_EL1 = 0x807c,
HV_SYS_REG_DBGBCR15_EL1 = 0x807d, DBGBCR15_EL1 = 0x807d,
HV_SYS_REG_DBGWVR15_EL1 = 0x807e, DBGWVR15_EL1 = 0x807e,
HV_SYS_REG_DBGWCR15_EL1 = 0x807f, DBGWCR15_EL1 = 0x807f,
HV_SYS_REG_MIDR_EL1 = 0xc000, MIDR_EL1 = 0xc000,
HV_SYS_REG_MPIDR_EL1 = 0xc005, MPIDR_EL1 = 0xc005,
HV_SYS_REG_ID_AA64PFR0_EL1 = 0xc020, ID_AA64PFR0_EL1 = 0xc020,
HV_SYS_REG_ID_AA64PFR1_EL1 = 0xc021, ID_AA64PFR1_EL1 = 0xc021,
HV_SYS_REG_ID_AA64DFR0_EL1 = 0xc028, ID_AA64DFR0_EL1 = 0xc028,
HV_SYS_REG_ID_AA64DFR1_EL1 = 0xc029, ID_AA64DFR1_EL1 = 0xc029,
HV_SYS_REG_ID_AA64ISAR0_EL1 = 0xc030, ID_AA64ISAR0_EL1 = 0xc030,
HV_SYS_REG_ID_AA64ISAR1_EL1 = 0xc031, ID_AA64ISAR1_EL1 = 0xc031,
HV_SYS_REG_ID_AA64MMFR0_EL1 = 0xc038, ID_AA64MMFR0_EL1 = 0xc038,
HV_SYS_REG_ID_AA64MMFR1_EL1 = 0xc039, ID_AA64MMFR1_EL1 = 0xc039,
HV_SYS_REG_ID_AA64MMFR2_EL1 = 0xc03a, ID_AA64MMFR2_EL1 = 0xc03a,
HV_SYS_REG_SCTLR_EL1 = 0xc080, SCTLR_EL1 = 0xc080,
HV_SYS_REG_CPACR_EL1 = 0xc082, CPACR_EL1 = 0xc082,
HV_SYS_REG_TTBR0_EL1 = 0xc100, TTBR0_EL1 = 0xc100,
HV_SYS_REG_TTBR1_EL1 = 0xc101, TTBR1_EL1 = 0xc101,
HV_SYS_REG_TCR_EL1 = 0xc102, TCR_EL1 = 0xc102,
HV_SYS_REG_APIAKEYLO_EL1 = 0xc108, APIAKEYLO_EL1 = 0xc108,
HV_SYS_REG_APIAKEYHI_EL1 = 0xc109, APIAKEYHI_EL1 = 0xc109,
HV_SYS_REG_APIBKEYLO_EL1 = 0xc10a, APIBKEYLO_EL1 = 0xc10a,
HV_SYS_REG_APIBKEYHI_EL1 = 0xc10b, APIBKEYHI_EL1 = 0xc10b,
HV_SYS_REG_APDAKEYLO_EL1 = 0xc110, APDAKEYLO_EL1 = 0xc110,
HV_SYS_REG_APDAKEYHI_EL1 = 0xc111, APDAKEYHI_EL1 = 0xc111,
HV_SYS_REG_APDBKEYLO_EL1 = 0xc112, APDBKEYLO_EL1 = 0xc112,
HV_SYS_REG_APDBKEYHI_EL1 = 0xc113, APDBKEYHI_EL1 = 0xc113,
HV_SYS_REG_APGAKEYLO_EL1 = 0xc118, APGAKEYLO_EL1 = 0xc118,
HV_SYS_REG_APGAKEYHI_EL1 = 0xc119, APGAKEYHI_EL1 = 0xc119,
HV_SYS_REG_SPSR_EL1 = 0xc200, SPSR_EL1 = 0xc200,
HV_SYS_REG_ELR_EL1 = 0xc201, ELR_EL1 = 0xc201,
HV_SYS_REG_SP_EL0 = 0xc208, SP_EL0 = 0xc208,
HV_SYS_REG_AFSR0_EL1 = 0xc288, AFSR0_EL1 = 0xc288,
HV_SYS_REG_AFSR1_EL1 = 0xc289, AFSR1_EL1 = 0xc289,
HV_SYS_REG_ESR_EL1 = 0xc290, ESR_EL1 = 0xc290,
HV_SYS_REG_FAR_EL1 = 0xc300, FAR_EL1 = 0xc300,
HV_SYS_REG_PAR_EL1 = 0xc3a0, PAR_EL1 = 0xc3a0,
HV_SYS_REG_MAIR_EL1 = 0xc510, MAIR_EL1 = 0xc510,
HV_SYS_REG_AMAIR_EL1 = 0xc518, AMAIR_EL1 = 0xc518,
HV_SYS_REG_VBAR_EL1 = 0xc600, VBAR_EL1 = 0xc600,
HV_SYS_REG_CONTEXTIDR_EL1 = 0xc681, CONTEXTIDR_EL1 = 0xc681,
HV_SYS_REG_TPIDR_EL1 = 0xc684, TPIDR_EL1 = 0xc684,
HV_SYS_REG_CNTKCTL_EL1 = 0xc708, CNTKCTL_EL1 = 0xc708,
HV_SYS_REG_CSSELR_EL1 = 0xd000, CSSELR_EL1 = 0xd000,
HV_SYS_REG_TPIDR_EL0 = 0xde82, TPIDR_EL0 = 0xde82,
HV_SYS_REG_TPIDRRO_EL0 = 0xde83, TPIDRRO_EL0 = 0xde83,
HV_SYS_REG_CNTV_CTL_EL0 = 0xdf19, CNTV_CTL_EL0 = 0xdf19,
HV_SYS_REG_CNTV_CVAL_EL0 = 0xdf1a, CNTV_CVAL_EL0 = 0xdf1a,
HV_SYS_REG_SP_EL1 = 0xe208, SP_EL1 = 0xe208,
} }
enum hv_memory_flags_t : ulong enum HvMemoryFlags : ulong
{ {
HV_MEMORY_READ = 1UL << 0, Read = 1UL << 0,
HV_MEMORY_WRITE = 1UL << 1, Write = 1UL << 1,
HV_MEMORY_EXEC = 1UL << 2 Exec = 1UL << 2,
} }
enum hv_result_t : uint enum HvResult : uint
{ {
HV_SUCCESS = 0, Success = 0,
HV_ERROR = 0xfae94001, Error = 0xfae94001,
HV_BUSY = 0xfae94002, Busy = 0xfae94002,
HV_BAD_ARGUMENT = 0xfae94003, BadArgument = 0xfae94003,
HV_NO_RESOURCES = 0xfae94005, NoResources = 0xfae94005,
HV_NO_DEVICE = 0xfae94006, NoDevice = 0xfae94006,
HV_DENIED = 0xfae94007, Denied = 0xfae94007,
HV_UNSUPPORTED = 0xfae9400f Unsupported = 0xfae9400f,
} }
enum hv_interrupt_type_t : uint enum HvInterruptType : uint
{ {
HV_INTERRUPT_TYPE_IRQ, IRQ,
HV_INTERRUPT_TYPE_FIQ FIQ,
} }
struct hv_simd_fp_uchar16_t struct HvSimdFPUchar16
{ {
public ulong Low; public ulong Low;
public ulong High; public ulong High;
@ -247,9 +246,9 @@ namespace Ryujinx.Cpu.AppleHv
static class HvResultExtensions static class HvResultExtensions
{ {
public static void ThrowOnError(this hv_result_t result) public static void ThrowOnError(this HvResult result)
{ {
if (result != hv_result_t.HV_SUCCESS) if (result != HvResult.Success)
{ {
throw new Exception($"Unexpected result \"{result}\"."); throw new Exception($"Unexpected result \"{result}\".");
} }
@ -261,60 +260,60 @@ namespace Ryujinx.Cpu.AppleHv
public const string LibraryName = "/System/Library/Frameworks/Hypervisor.framework/Hypervisor"; public const string LibraryName = "/System/Library/Frameworks/Hypervisor.framework/Hypervisor";
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_get_max_vcpu_count(out uint max_vcpu_count); public static partial HvResult hv_vm_get_max_vcpu_count(out uint max_vcpu_count);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_create(IntPtr config); public static partial HvResult hv_vm_create(IntPtr config);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_destroy(); public static partial HvResult hv_vm_destroy();
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_map(ulong addr, ulong ipa, ulong size, hv_memory_flags_t flags); public static partial HvResult hv_vm_map(ulong addr, ulong ipa, ulong size, HvMemoryFlags flags);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_unmap(ulong ipa, ulong size); public static partial HvResult hv_vm_unmap(ulong ipa, ulong size);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_protect(ulong ipa, ulong size, hv_memory_flags_t flags); public static partial HvResult hv_vm_protect(ulong ipa, ulong size, HvMemoryFlags flags);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public unsafe static partial hv_result_t hv_vcpu_create(out ulong vcpu, ref hv_vcpu_exit_t* exit, IntPtr config); public unsafe static partial HvResult hv_vcpu_create(out ulong vcpu, ref HvVcpuExit* exit, IntPtr config);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public unsafe static partial hv_result_t hv_vcpu_destroy(ulong vcpu); public unsafe static partial HvResult hv_vcpu_destroy(ulong vcpu);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_run(ulong vcpu); public static partial HvResult hv_vcpu_run(ulong vcpu);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpus_exit(ref ulong vcpus, uint vcpu_count); public static partial HvResult hv_vcpus_exit(ref ulong vcpus, uint vcpu_count);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_vtimer_mask(ulong vcpu, [MarshalAs(UnmanagedType.Bool)] bool vtimer_is_masked); public static partial HvResult hv_vcpu_set_vtimer_mask(ulong vcpu, [MarshalAs(UnmanagedType.Bool)] bool vtimer_is_masked);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_reg(ulong vcpu, hv_reg_t reg, out ulong value); public static partial HvResult hv_vcpu_get_reg(ulong vcpu, HvReg reg, out ulong value);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_reg(ulong vcpu, hv_reg_t reg, ulong value); public static partial HvResult hv_vcpu_set_reg(ulong vcpu, HvReg reg, ulong value);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_simd_fp_reg(ulong vcpu, hv_simd_fp_reg_t reg, out hv_simd_fp_uchar16_t value); public static partial HvResult hv_vcpu_get_simd_fp_reg(ulong vcpu, HvSimdFPReg reg, out HvSimdFPUchar16 value);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_simd_fp_reg(ulong vcpu, hv_simd_fp_reg_t reg, hv_simd_fp_uchar16_t value); // DO NOT USE DIRECTLY! public static partial HvResult hv_vcpu_set_simd_fp_reg(ulong vcpu, HvSimdFPReg reg, HvSimdFPUchar16 value); // DO NOT USE DIRECTLY!
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_sys_reg(ulong vcpu, hv_sys_reg_t reg, out ulong value); public static partial HvResult hv_vcpu_get_sys_reg(ulong vcpu, HvSysReg reg, out ulong value);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_sys_reg(ulong vcpu, hv_sys_reg_t reg, ulong value); public static partial HvResult hv_vcpu_set_sys_reg(ulong vcpu, HvSysReg reg, ulong value);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_pending_interrupt(ulong vcpu, hv_interrupt_type_t type, [MarshalAs(UnmanagedType.Bool)] out bool pending); public static partial HvResult hv_vcpu_get_pending_interrupt(ulong vcpu, HvInterruptType type, [MarshalAs(UnmanagedType.Bool)] out bool pending);
[LibraryImport(LibraryName, SetLastError = true)] [LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_pending_interrupt(ulong vcpu, hv_interrupt_type_t type, [MarshalAs(UnmanagedType.Bool)] bool pending); public static partial HvResult hv_vcpu_set_pending_interrupt(ulong vcpu, HvInterruptType type, [MarshalAs(UnmanagedType.Bool)] bool pending);
} }
} }

View file

@ -1,5 +1,4 @@
using ARMeilleure.Memory; using ARMeilleure.Memory;
using System;
namespace Ryujinx.Cpu.AppleHv namespace Ryujinx.Cpu.AppleHv
{ {
@ -14,10 +13,6 @@ namespace Ryujinx.Cpu.AppleHv
_memoryManager = (HvMemoryManager)memory; _memoryManager = (HvMemoryManager)memory;
} }
private void UnmapHandler(ulong address, ulong size)
{
}
/// <inheritdoc/> /// <inheritdoc/>
public IExecutionContext CreateExecutionContext(ExceptionCallbacks exceptionCallbacks) public IExecutionContext CreateExecutionContext(ExceptionCallbacks exceptionCallbacks)
{ {

View file

@ -125,17 +125,17 @@ namespace Ryujinx.Cpu.AppleHv
{ {
HvVcpu vcpu = HvVcpuPool.Instance.Create(memoryManager.AddressSpace, _shadowContext, SwapContext); HvVcpu vcpu = HvVcpuPool.Instance.Create(memoryManager.AddressSpace, _shadowContext, SwapContext);
HvApi.hv_vcpu_set_reg(vcpu.Handle, hv_reg_t.HV_REG_PC, address).ThrowOnError(); HvApi.hv_vcpu_set_reg(vcpu.Handle, HvReg.PC, address).ThrowOnError();
while (Running) while (Running)
{ {
HvApi.hv_vcpu_run(vcpu.Handle).ThrowOnError(); HvApi.hv_vcpu_run(vcpu.Handle).ThrowOnError();
uint reason = vcpu.ExitInfo->reason; uint reason = vcpu.ExitInfo->Reason;
if (reason == 1) if (reason == 1)
{ {
uint hvEsr = (uint)vcpu.ExitInfo->exception.syndrome; uint hvEsr = (uint)vcpu.ExitInfo->Exception.Syndrome;
ExceptionClass hvEc = (ExceptionClass)(hvEsr >> 26); ExceptionClass hvEc = (ExceptionClass)(hvEsr >> 26);
if (hvEc != ExceptionClass.HvcAarch64) if (hvEc != ExceptionClass.HvcAarch64)
@ -144,7 +144,7 @@ namespace Ryujinx.Cpu.AppleHv
} }
address = SynchronousException(memoryManager, ref vcpu); address = SynchronousException(memoryManager, ref vcpu);
HvApi.hv_vcpu_set_reg(vcpu.Handle, hv_reg_t.HV_REG_PC, address).ThrowOnError(); HvApi.hv_vcpu_set_reg(vcpu.Handle, HvReg.PC, address).ThrowOnError();
} }
else if (reason == 0) else if (reason == 0)
{ {
@ -168,8 +168,8 @@ namespace Ryujinx.Cpu.AppleHv
{ {
ulong vcpuHandle = vcpu.Handle; ulong vcpuHandle = vcpu.Handle;
HvApi.hv_vcpu_get_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, out ulong elr).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(vcpuHandle, HvSysReg.ELR_EL1, out ulong elr).ThrowOnError();
HvApi.hv_vcpu_get_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_ESR_EL1, out ulong esr).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(vcpuHandle, HvSysReg.ESR_EL1, out ulong esr).ThrowOnError();
ExceptionClass ec = (ExceptionClass)((uint)esr >> 26); ExceptionClass ec = (ExceptionClass)((uint)esr >> 26);
@ -180,7 +180,7 @@ namespace Ryujinx.Cpu.AppleHv
break; break;
case ExceptionClass.TrappedMsrMrsSystem: case ExceptionClass.TrappedMsrMrsSystem:
InstructionTrap((uint)esr); InstructionTrap((uint)esr);
HvApi.hv_vcpu_set_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, elr + 4UL).ThrowOnError(); HvApi.hv_vcpu_set_sys_reg(vcpuHandle, HvSysReg.ELR_EL1, elr + 4UL).ThrowOnError();
break; break;
case ExceptionClass.SvcAarch64: case ExceptionClass.SvcAarch64:
ReturnToPool(vcpu); ReturnToPool(vcpu);
@ -204,7 +204,7 @@ namespace Ryujinx.Cpu.AppleHv
} }
} }
private void DataAbort(MemoryTracking tracking, ulong vcpu, uint esr) private static void DataAbort(MemoryTracking tracking, ulong vcpu, uint esr)
{ {
bool write = (esr & (1u << 6)) != 0; bool write = (esr & (1u << 6)) != 0;
bool farValid = (esr & (1u << 10)) == 0; bool farValid = (esr & (1u << 10)) == 0;
@ -212,7 +212,7 @@ namespace Ryujinx.Cpu.AppleHv
if (farValid) if (farValid)
{ {
HvApi.hv_vcpu_get_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_FAR_EL1, out ulong far).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(vcpu, HvSysReg.FAR_EL1, out ulong far).ThrowOnError();
ulong size = 1UL << accessSizeLog2; ulong size = 1UL << accessSizeLog2;

View file

@ -2,7 +2,7 @@ using ARMeilleure.State;
namespace Ryujinx.Cpu.AppleHv namespace Ryujinx.Cpu.AppleHv
{ {
unsafe class HvExecutionContextShadow : IHvExecutionContext class HvExecutionContextShadow : IHvExecutionContext
{ {
public ulong Pc { get; set; } public ulong Pc { get; set; }
public ulong ElrEl1 { get; set; } public ulong ElrEl1 { get; set; }

View file

@ -8,10 +8,10 @@ namespace Ryujinx.Cpu.AppleHv
{ {
class HvExecutionContextVcpu : IHvExecutionContext class HvExecutionContextVcpu : IHvExecutionContext
{ {
private static MemoryBlock _setSimdFpRegFuncMem; private static readonly MemoryBlock _setSimdFpRegFuncMem;
private delegate hv_result_t SetSimdFpReg(ulong vcpu, hv_simd_fp_reg_t reg, in V128 value, IntPtr funcPtr); private delegate HvResult SetSimdFpReg(ulong vcpu, HvSimdFPReg reg, in V128 value, IntPtr funcPtr);
private static SetSimdFpReg _setSimdFpReg; private static readonly SetSimdFpReg _setSimdFpReg;
private static IntPtr _setSimdFpRegNativePtr; private static readonly IntPtr _setSimdFpRegNativePtr;
static HvExecutionContextVcpu() static HvExecutionContextVcpu()
{ {
@ -34,12 +34,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_PC, out ulong pc).ThrowOnError(); HvApi.hv_vcpu_get_reg(_vcpu, HvReg.PC, out ulong pc).ThrowOnError();
return pc; return pc;
} }
set set
{ {
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_PC, value).ThrowOnError(); HvApi.hv_vcpu_set_reg(_vcpu, HvReg.PC, value).ThrowOnError();
} }
} }
@ -47,12 +47,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, out ulong elr).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.ELR_EL1, out ulong elr).ThrowOnError();
return elr; return elr;
} }
set set
{ {
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, value).ThrowOnError(); HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.ELR_EL1, value).ThrowOnError();
} }
} }
@ -60,12 +60,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ESR_EL1, out ulong esr).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.ESR_EL1, out ulong esr).ThrowOnError();
return esr; return esr;
} }
set set
{ {
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ESR_EL1, value).ThrowOnError(); HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.ESR_EL1, value).ThrowOnError();
} }
} }
@ -73,12 +73,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDR_EL0, out ulong tpidrEl0).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.TPIDR_EL0, out ulong tpidrEl0).ThrowOnError();
return (long)tpidrEl0; return (long)tpidrEl0;
} }
set set
{ {
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDR_EL0, (ulong)value).ThrowOnError(); HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.TPIDR_EL0, (ulong)value).ThrowOnError();
} }
} }
@ -86,12 +86,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDRRO_EL0, out ulong tpidrroEl0).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.TPIDRRO_EL0, out ulong tpidrroEl0).ThrowOnError();
return (long)tpidrroEl0; return (long)tpidrroEl0;
} }
set set
{ {
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDRRO_EL0, (ulong)value).ThrowOnError(); HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.TPIDRRO_EL0, (ulong)value).ThrowOnError();
} }
} }
@ -99,12 +99,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_CPSR, out ulong cpsr).ThrowOnError(); HvApi.hv_vcpu_get_reg(_vcpu, HvReg.CPSR, out ulong cpsr).ThrowOnError();
return (uint)cpsr; return (uint)cpsr;
} }
set set
{ {
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_CPSR, (ulong)value).ThrowOnError(); HvApi.hv_vcpu_set_reg(_vcpu, HvReg.CPSR, (ulong)value).ThrowOnError();
} }
} }
@ -112,12 +112,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_FPCR, out ulong fpcr).ThrowOnError(); HvApi.hv_vcpu_get_reg(_vcpu, HvReg.FPCR, out ulong fpcr).ThrowOnError();
return (uint)fpcr; return (uint)fpcr;
} }
set set
{ {
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_FPCR, (ulong)value).ThrowOnError(); HvApi.hv_vcpu_set_reg(_vcpu, HvReg.FPCR, (ulong)value).ThrowOnError();
} }
} }
@ -125,16 +125,16 @@ namespace Ryujinx.Cpu.AppleHv
{ {
get get
{ {
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_FPSR, out ulong fpsr).ThrowOnError(); HvApi.hv_vcpu_get_reg(_vcpu, HvReg.FPSR, out ulong fpsr).ThrowOnError();
return (uint)fpsr; return (uint)fpsr;
} }
set set
{ {
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_FPSR, (ulong)value).ThrowOnError(); HvApi.hv_vcpu_set_reg(_vcpu, HvReg.FPSR, (ulong)value).ThrowOnError();
} }
} }
private ulong _vcpu; private readonly ulong _vcpu;
private int _interruptRequested; private int _interruptRequested;
public HvExecutionContextVcpu(ulong vcpu) public HvExecutionContextVcpu(ulong vcpu)
@ -146,12 +146,12 @@ namespace Ryujinx.Cpu.AppleHv
{ {
if (index == 31) if (index == 31)
{ {
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_SP_EL0, out ulong value).ThrowOnError(); HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.SP_EL0, out ulong value).ThrowOnError();
return value; return value;
} }
else else
{ {
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_X0 + (uint)index, out ulong value).ThrowOnError(); HvApi.hv_vcpu_get_reg(_vcpu, HvReg.X0 + (uint)index, out ulong value).ThrowOnError();
return value; return value;
} }
} }
@ -160,23 +160,23 @@ namespace Ryujinx.Cpu.AppleHv
{ {
if (index == 31) if (index == 31)
{ {
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_SP_EL0, value).ThrowOnError(); HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.SP_EL0, value).ThrowOnError();
} }
else else
{ {
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_X0 + (uint)index, value).ThrowOnError(); HvApi.hv_vcpu_set_reg(_vcpu, HvReg.X0 + (uint)index, value).ThrowOnError();
} }
} }
public V128 GetV(int index) public V128 GetV(int index)
{ {
HvApi.hv_vcpu_get_simd_fp_reg(_vcpu, hv_simd_fp_reg_t.HV_SIMD_FP_REG_Q0 + (uint)index, out hv_simd_fp_uchar16_t value).ThrowOnError(); HvApi.hv_vcpu_get_simd_fp_reg(_vcpu, HvSimdFPReg.Q0 + (uint)index, out HvSimdFPUchar16 value).ThrowOnError();
return new V128(value.Low, value.High); return new V128(value.Low, value.High);
} }
public void SetV(int index, V128 value) public void SetV(int index, V128 value)
{ {
_setSimdFpReg(_vcpu, hv_simd_fp_reg_t.HV_SIMD_FP_REG_Q0 + (uint)index, value, _setSimdFpRegNativePtr).ThrowOnError(); _setSimdFpReg(_vcpu, HvSimdFPReg.Q0 + (uint)index, value, _setSimdFpRegNativePtr).ThrowOnError();
} }
public void RequestInterrupt() public void RequestInterrupt()

View file

@ -3,7 +3,7 @@ using System;
namespace Ryujinx.Cpu.AppleHv namespace Ryujinx.Cpu.AppleHv
{ {
struct HvMemoryBlockAllocation : IDisposable readonly struct HvMemoryBlockAllocation : IDisposable
{ {
private readonly HvMemoryBlockAllocator _owner; private readonly HvMemoryBlockAllocator _owner;
private readonly HvMemoryBlockAllocator.Block _block; private readonly HvMemoryBlockAllocator.Block _block;

View file

@ -1,12 +1,9 @@
using Ryujinx.Memory; using Ryujinx.Memory;
using System.Collections.Generic;
namespace Ryujinx.Cpu.AppleHv namespace Ryujinx.Cpu.AppleHv
{ {
class HvMemoryBlockAllocator : PrivateMemoryAllocatorImpl<HvMemoryBlockAllocator.Block> class HvMemoryBlockAllocator : PrivateMemoryAllocatorImpl<HvMemoryBlockAllocator.Block>
{ {
private const ulong InvalidOffset = ulong.MaxValue;
public class Block : PrivateMemoryAllocator.Block public class Block : PrivateMemoryAllocator.Block
{ {
private readonly HvIpaAllocator _ipaAllocator; private readonly HvIpaAllocator _ipaAllocator;
@ -21,7 +18,7 @@ namespace Ryujinx.Cpu.AppleHv
Ipa = ipaAllocator.Allocate(size); Ipa = ipaAllocator.Allocate(size);
} }
HvApi.hv_vm_map((ulong)Memory.Pointer, Ipa, size, hv_memory_flags_t.HV_MEMORY_READ | hv_memory_flags_t.HV_MEMORY_WRITE).ThrowOnError(); HvApi.hv_vm_map((ulong)Memory.Pointer, Ipa, size, HvMemoryFlags.Read | HvMemoryFlags.Write).ThrowOnError();
} }
public override void Destroy() public override void Destroy()
@ -44,7 +41,7 @@ namespace Ryujinx.Cpu.AppleHv
_ipaAllocator = ipaAllocator; _ipaAllocator = ipaAllocator;
} }
public unsafe HvMemoryBlockAllocation Allocate(ulong size, ulong alignment) public HvMemoryBlockAllocation Allocate(ulong size, ulong alignment)
{ {
var allocation = Allocate(size, alignment, CreateBlock); var allocation = Allocate(size, alignment, CreateBlock);

View file

@ -32,7 +32,7 @@ namespace Ryujinx.Cpu.AppleHv
MappedReplicated = 0x5555555555555555, MappedReplicated = 0x5555555555555555,
WriteTrackedReplicated = 0xaaaaaaaaaaaaaaaa, WriteTrackedReplicated = 0xaaaaaaaaaaaaaaaa,
ReadWriteTrackedReplicated = ulong.MaxValue ReadWriteTrackedReplicated = ulong.MaxValue,
} }
private readonly InvalidAccessHandler _invalidAccessHandler; private readonly InvalidAccessHandler _invalidAccessHandler;
@ -126,6 +126,7 @@ namespace Ryujinx.Cpu.AppleHv
} }
} }
#pragma warning disable IDE0051 // Remove unused private member
/// <summary> /// <summary>
/// Ensures the combination of virtual address and size is part of the addressable space and fully mapped. /// Ensures the combination of virtual address and size is part of the addressable space and fully mapped.
/// </summary> /// </summary>
@ -138,6 +139,7 @@ namespace Ryujinx.Cpu.AppleHv
throw new InvalidMemoryRegionException($"Not mapped: va=0x{va:X16}, size=0x{size:X16}"); throw new InvalidMemoryRegionException($"Not mapped: va=0x{va:X16}, size=0x{size:X16}");
} }
} }
#pragma warning restore IDE0051
/// <inheritdoc/> /// <inheritdoc/>
public void Map(ulong va, ulong pa, ulong size, MemoryMapFlags flags) public void Map(ulong va, ulong pa, ulong size, MemoryMapFlags flags)
@ -306,7 +308,7 @@ namespace Ryujinx.Cpu.AppleHv
size = Math.Min(data.Length, PageSize - (int)(va & PageMask)); size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
data.Slice(0, size).CopyTo(_backingMemory.GetSpan(pa, size)); data[..size].CopyTo(_backingMemory.GetSpan(pa, size));
offset += size; offset += size;
} }
@ -428,7 +430,7 @@ namespace Ryujinx.Cpu.AppleHv
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex) private static void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex)
{ {
startMask = ulong.MaxValue << ((int)(pageStart & 31) << 1); startMask = ulong.MaxValue << ((int)(pageStart & 31) << 1);
endMask = ulong.MaxValue >> (64 - ((int)(pageEnd & 31) << 1)); endMask = ulong.MaxValue >> (64 - ((int)(pageEnd & 31) << 1));
@ -606,7 +608,7 @@ namespace Ryujinx.Cpu.AppleHv
size = Math.Min(data.Length, PageSize - (int)(va & PageMask)); size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
_backingMemory.GetSpan(pa, size).CopyTo(data.Slice(0, size)); _backingMemory.GetSpan(pa, size).CopyTo(data[..size]);
offset += size; offset += size;
} }
@ -723,7 +725,7 @@ namespace Ryujinx.Cpu.AppleHv
/// <param name="startVa">The virtual address of the beginning of the first page</param> /// <param name="startVa">The virtual address of the beginning of the first page</param>
/// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks> /// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetPagesCount(ulong va, ulong size, out ulong startVa) private static int GetPagesCount(ulong va, ulong size, out ulong startVa)
{ {
// WARNING: Always check if ulong does not overflow during the operations. // WARNING: Always check if ulong does not overflow during the operations.
startVa = va & ~(ulong)PageMask; startVa = va & ~(ulong)PageMask;
@ -814,7 +816,7 @@ namespace Ryujinx.Cpu.AppleHv
{ {
MemoryPermission.None => MemoryPermission.ReadAndWrite, MemoryPermission.None => MemoryPermission.ReadAndWrite,
MemoryPermission.Write => MemoryPermission.Read, MemoryPermission.Write => MemoryPermission.Read,
_ => MemoryPermission.None _ => MemoryPermission.None,
}; };
_addressSpace.ReprotectUser(va, size, protection); _addressSpace.ReprotectUser(va, size, protection);

View file

@ -3,14 +3,14 @@ namespace Ryujinx.Cpu.AppleHv
unsafe class HvVcpu unsafe class HvVcpu
{ {
public readonly ulong Handle; public readonly ulong Handle;
public readonly hv_vcpu_exit_t* ExitInfo; public readonly HvVcpuExit* ExitInfo;
public readonly IHvExecutionContext ShadowContext; public readonly IHvExecutionContext ShadowContext;
public readonly IHvExecutionContext NativeContext; public readonly IHvExecutionContext NativeContext;
public readonly bool IsEphemeral; public readonly bool IsEphemeral;
public HvVcpu( public HvVcpu(
ulong handle, ulong handle,
hv_vcpu_exit_t* exitInfo, HvVcpuExit* exitInfo,
IHvExecutionContext shadowContext, IHvExecutionContext shadowContext,
IHvExecutionContext nativeContext, IHvExecutionContext nativeContext,
bool isEphemeral) bool isEphemeral)

View file

@ -17,10 +17,10 @@ namespace Ryujinx.Cpu.AppleHv
private const int MaxActiveVcpus = 4; private const int MaxActiveVcpus = 4;
public static readonly HvVcpuPool Instance = new HvVcpuPool(); public static readonly HvVcpuPool Instance = new();
private int _totalVcpus; private int _totalVcpus;
private int _maxVcpus; private readonly int _maxVcpus;
public HvVcpuPool() public HvVcpuPool()
{ {
@ -69,17 +69,17 @@ namespace Ryujinx.Cpu.AppleHv
bool isEphemeral = newCount > _maxVcpus - MaxActiveVcpus; bool isEphemeral = newCount > _maxVcpus - MaxActiveVcpus;
// Create VCPU. // Create VCPU.
hv_vcpu_exit_t* exitInfo = null; HvVcpuExit* exitInfo = null;
HvApi.hv_vcpu_create(out ulong vcpuHandle, ref exitInfo, IntPtr.Zero).ThrowOnError(); HvApi.hv_vcpu_create(out ulong vcpuHandle, ref exitInfo, IntPtr.Zero).ThrowOnError();
// Enable FP and SIMD instructions. // Enable FP and SIMD instructions.
HvApi.hv_vcpu_set_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_CPACR_EL1, 0b11 << 20).ThrowOnError(); HvApi.hv_vcpu_set_sys_reg(vcpuHandle, HvSysReg.CPACR_EL1, 0b11 << 20).ThrowOnError();
addressSpace.InitializeMmu(vcpuHandle); addressSpace.InitializeMmu(vcpuHandle);
HvExecutionContextVcpu nativeContext = new HvExecutionContextVcpu(vcpuHandle); HvExecutionContextVcpu nativeContext = new(vcpuHandle);
HvVcpu vcpu = new HvVcpu(vcpuHandle, exitInfo, shadowContext, nativeContext, isEphemeral); HvVcpu vcpu = new(vcpuHandle, exitInfo, shadowContext, nativeContext, isEphemeral);
return vcpu; return vcpu;
} }

View file

@ -10,7 +10,7 @@ namespace Ryujinx.Cpu.AppleHv
private static int _addressSpaces; private static int _addressSpaces;
private static HvIpaAllocator _ipaAllocator; private static HvIpaAllocator _ipaAllocator;
private static object _lock = new object(); private static readonly object _lock = new();
public static (ulong, HvIpaAllocator) CreateAddressSpace(MemoryBlock block) public static (ulong, HvIpaAllocator) CreateAddressSpace(MemoryBlock block)
{ {
@ -36,7 +36,7 @@ namespace Ryujinx.Cpu.AppleHv
baseAddress = ipaAllocator.Allocate(block.Size, AsIpaAlignment); baseAddress = ipaAllocator.Allocate(block.Size, AsIpaAlignment);
} }
var rwx = hv_memory_flags_t.HV_MEMORY_READ | hv_memory_flags_t.HV_MEMORY_WRITE | hv_memory_flags_t.HV_MEMORY_EXEC; var rwx = HvMemoryFlags.Read | HvMemoryFlags.Write | HvMemoryFlags.Exec;
HvApi.hv_vm_map((ulong)block.Pointer, baseAddress, block.Size, rwx).ThrowOnError(); HvApi.hv_vm_map((ulong)block.Pointer, baseAddress, block.Size, rwx).ThrowOnError();

View file

@ -23,7 +23,7 @@ namespace Ryujinx.Cpu.Jit
PtcLoadingState.Start => LoadState.Unloaded, PtcLoadingState.Start => LoadState.Unloaded,
PtcLoadingState.Loading => LoadState.Loading, PtcLoadingState.Loading => LoadState.Loading,
PtcLoadingState.Loaded => LoadState.Loaded, PtcLoadingState.Loaded => LoadState.Loaded,
_ => throw new ArgumentException($"Invalid load state \"{newState}\".") _ => throw new ArgumentException($"Invalid load state \"{newState}\"."),
}; };
StateChanged?.Invoke(state, current, total); StateChanged?.Invoke(state, current, total);

View file

@ -19,6 +19,10 @@ namespace Ryujinx.Cpu.Jit
public void MapAsRx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadAndExecute); public void MapAsRx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadAndExecute);
public void MapAsRwx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadWriteExecute); public void MapAsRwx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadWriteExecute);
public void Dispose() => _impl.Dispose(); public void Dispose()
{
GC.SuppressFinalize(this);
_impl.Dispose();
}
} }
} }

View file

@ -84,7 +84,6 @@ namespace Ryujinx.Cpu.Jit
ulong remainingSize = size; ulong remainingSize = size;
ulong oVa = va; ulong oVa = va;
ulong oPa = pa;
while (remainingSize != 0) while (remainingSize != 0)
{ {
_pageTable.Write((va / PageSize) * PteSize, PaToPte(pa)); _pageTable.Write((va / PageSize) * PteSize, PaToPte(pa));
@ -246,7 +245,7 @@ namespace Ryujinx.Cpu.Jit
size = Math.Min(data.Length, PageSize - (int)(va & PageMask)); size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
data.Slice(0, size).CopyTo(_backingMemory.GetSpan(pa, size)); data[..size].CopyTo(_backingMemory.GetSpan(pa, size));
offset += size; offset += size;
} }
@ -298,7 +297,7 @@ namespace Ryujinx.Cpu.Jit
} }
/// <inheritdoc/> /// <inheritdoc/>
public unsafe WritableRegion GetWritableRegion(ulong va, int size, bool tracked = false) public WritableRegion GetWritableRegion(ulong va, int size, bool tracked = false)
{ {
if (size == 0) if (size == 0)
{ {
@ -345,7 +344,7 @@ namespace Ryujinx.Cpu.Jit
/// <param name="startVa">The virtual address of the beginning of the first page</param> /// <param name="startVa">The virtual address of the beginning of the first page</param>
/// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks> /// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetPagesCount(ulong va, uint size, out ulong startVa) private static int GetPagesCount(ulong va, uint size, out ulong startVa)
{ {
// WARNING: Always check if ulong does not overflow during the operations. // WARNING: Always check if ulong does not overflow during the operations.
startVa = va & ~(ulong)PageMask; startVa = va & ~(ulong)PageMask;
@ -482,7 +481,7 @@ namespace Ryujinx.Cpu.Jit
size = Math.Min(data.Length, PageSize - (int)(va & PageMask)); size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
_backingMemory.GetSpan(pa, size).CopyTo(data.Slice(0, size)); _backingMemory.GetSpan(pa, size).CopyTo(data[..size]);
offset += size; offset += size;
} }
@ -576,6 +575,7 @@ namespace Ryujinx.Cpu.Jit
} }
} }
#pragma warning disable IDE0051 // Remove unused private member
private ulong GetPhysicalAddress(ulong va) private ulong GetPhysicalAddress(ulong va)
{ {
// We return -1L if the virtual address is invalid or unmapped. // We return -1L if the virtual address is invalid or unmapped.
@ -586,6 +586,7 @@ namespace Ryujinx.Cpu.Jit
return GetPhysicalAddressInternal(va); return GetPhysicalAddressInternal(va);
} }
#pragma warning restore IDE0051
private ulong GetPhysicalAddressInternal(ulong va) private ulong GetPhysicalAddressInternal(ulong va)
{ {
@ -604,7 +605,7 @@ namespace Ryujinx.Cpu.Jit
{ {
MemoryPermission.None => 0L, MemoryPermission.None => 0L,
MemoryPermission.Write => 2L << PointerTagBit, MemoryPermission.Write => 2L << PointerTagBit,
_ => 3L << PointerTagBit _ => 3L << PointerTagBit,
}; };
int pages = GetPagesCount(va, (uint)size, out va); int pages = GetPagesCount(va, (uint)size, out va);
@ -698,6 +699,8 @@ namespace Ryujinx.Cpu.Jit
/// </summary> /// </summary>
protected override void Destroy() => _pageTable.Dispose(); protected override void Destroy() => _pageTable.Dispose();
private void ThrowInvalidMemoryRegionException(string message) => throw new InvalidMemoryRegionException(message); #pragma warning disable IDE0051 // Remove unused private member
private static void ThrowInvalidMemoryRegionException(string message) => throw new InvalidMemoryRegionException(message);
#pragma warning restore IDE0051
} }
} }

View file

@ -31,7 +31,7 @@ namespace Ryujinx.Cpu.Jit
MappedReplicated = 0x5555555555555555, MappedReplicated = 0x5555555555555555,
WriteTrackedReplicated = 0xaaaaaaaaaaaaaaaa, WriteTrackedReplicated = 0xaaaaaaaaaaaaaaaa,
ReadWriteTrackedReplicated = ulong.MaxValue ReadWriteTrackedReplicated = ulong.MaxValue,
} }
private readonly InvalidAccessHandler _invalidAccessHandler; private readonly InvalidAccessHandler _invalidAccessHandler;
@ -404,7 +404,7 @@ namespace Ryujinx.Cpu.Jit
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex) private static void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex)
{ {
startMask = ulong.MaxValue << ((int)(pageStart & 31) << 1); startMask = ulong.MaxValue << ((int)(pageStart & 31) << 1);
endMask = ulong.MaxValue >> (64 - ((int)(pageEnd & 31) << 1)); endMask = ulong.MaxValue >> (64 - ((int)(pageEnd & 31) << 1));
@ -606,7 +606,7 @@ namespace Ryujinx.Cpu.Jit
/// <param name="startVa">The virtual address of the beginning of the first page</param> /// <param name="startVa">The virtual address of the beginning of the first page</param>
/// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks> /// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetPagesCount(ulong va, ulong size, out ulong startVa) private static int GetPagesCount(ulong va, ulong size, out ulong startVa)
{ {
// WARNING: Always check if ulong does not overflow during the operations. // WARNING: Always check if ulong does not overflow during the operations.
startVa = va & ~(ulong)PageMask; startVa = va & ~(ulong)PageMask;
@ -697,7 +697,7 @@ namespace Ryujinx.Cpu.Jit
{ {
MemoryPermission.None => MemoryPermission.ReadAndWrite, MemoryPermission.None => MemoryPermission.ReadAndWrite,
MemoryPermission.Write => MemoryPermission.Read, MemoryPermission.Write => MemoryPermission.Read,
_ => MemoryPermission.None _ => MemoryPermission.None,
}; };
_addressSpace.Base.Reprotect(va, size, protection, false); _addressSpace.Base.Reprotect(va, size, protection, false);

View file

@ -7,6 +7,6 @@ namespace Ryujinx.Cpu
{ {
Unloaded, Unloaded,
Loading, Loading,
Loaded Loaded,
} }
} }

View file

@ -10,7 +10,6 @@ namespace Ryujinx.Cpu
{ {
private delegate bool TrackingEventDelegate(ulong address, ulong size, bool write); private delegate bool TrackingEventDelegate(ulong address, ulong size, bool write);
private readonly MemoryTracking _tracking;
private readonly TrackingEventDelegate _trackingEvent; private readonly TrackingEventDelegate _trackingEvent;
private readonly ulong _baseAddress; private readonly ulong _baseAddress;
@ -18,12 +17,10 @@ namespace Ryujinx.Cpu
public MemoryEhMeilleure(MemoryBlock addressSpace, MemoryBlock addressSpaceMirror, MemoryTracking tracking) public MemoryEhMeilleure(MemoryBlock addressSpace, MemoryBlock addressSpaceMirror, MemoryTracking tracking)
{ {
_tracking = tracking;
_baseAddress = (ulong)addressSpace.Pointer; _baseAddress = (ulong)addressSpace.Pointer;
ulong endAddress = _baseAddress + addressSpace.Size; ulong endAddress = _baseAddress + addressSpace.Size;
_trackingEvent = new TrackingEventDelegate(tracking.VirtualMemoryEvent); _trackingEvent = tracking.VirtualMemoryEvent;
bool added = NativeSignalHandler.AddTrackedRegion((nuint)_baseAddress, (nuint)endAddress, Marshal.GetFunctionPointerForDelegate(_trackingEvent)); bool added = NativeSignalHandler.AddTrackedRegion((nuint)_baseAddress, (nuint)endAddress, Marshal.GetFunctionPointerForDelegate(_trackingEvent));
if (!added) if (!added)
@ -51,6 +48,8 @@ namespace Ryujinx.Cpu
public void Dispose() public void Dispose()
{ {
GC.SuppressFinalize(this);
NativeSignalHandler.RemoveTrackedRegion((nuint)_baseAddress); NativeSignalHandler.RemoveTrackedRegion((nuint)_baseAddress);
if (_mirrorAddress != 0) if (_mirrorAddress != 0)

View file

@ -2,7 +2,6 @@
using Ryujinx.Common.Memory; using Ryujinx.Common.Memory;
using Ryujinx.Memory; using Ryujinx.Memory;
using System; using System;
using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
@ -26,12 +25,12 @@ namespace Ryujinx.Cpu
} }
} }
public unsafe static T Read<T>(IVirtualMemoryManager memory, ulong position) where T : unmanaged public static T Read<T>(IVirtualMemoryManager memory, ulong position) where T : unmanaged
{ {
return MemoryMarshal.Cast<byte, T>(memory.GetSpan(position, Unsafe.SizeOf<T>()))[0]; return MemoryMarshal.Cast<byte, T>(memory.GetSpan(position, Unsafe.SizeOf<T>()))[0];
} }
public unsafe static ulong Write<T>(IVirtualMemoryManager memory, ulong position, T value) where T : unmanaged public static ulong Write<T>(IVirtualMemoryManager memory, ulong position, T value) where T : unmanaged
{ {
ReadOnlySpan<byte> data = MemoryMarshal.Cast<T, byte>(MemoryMarshal.CreateReadOnlySpan(ref value, 1)); ReadOnlySpan<byte> data = MemoryMarshal.Cast<T, byte>(MemoryMarshal.CreateReadOnlySpan(ref value, 1));
@ -42,22 +41,21 @@ namespace Ryujinx.Cpu
public static string ReadAsciiString(IVirtualMemoryManager memory, ulong position, long maxSize = -1) public static string ReadAsciiString(IVirtualMemoryManager memory, ulong position, long maxSize = -1)
{ {
using (RecyclableMemoryStream ms = MemoryStreamManager.Shared.GetStream()) using RecyclableMemoryStream ms = MemoryStreamManager.Shared.GetStream();
for (long offs = 0; offs < maxSize || maxSize == -1; offs++)
{ {
for (long offs = 0; offs < maxSize || maxSize == -1; offs++) byte value = memory.Read<byte>(position + (ulong)offs);
if (value == 0)
{ {
byte value = memory.Read<byte>(position + (ulong)offs); break;
if (value == 0)
{
break;
}
ms.WriteByte(value);
} }
return Encoding.ASCII.GetString(ms.GetReadOnlySequence()); ms.WriteByte(value);
} }
return Encoding.ASCII.GetString(ms.GetReadOnlySequence());
} }
} }
} }

View file

@ -3,7 +3,7 @@ using System;
namespace Ryujinx.Cpu namespace Ryujinx.Cpu
{ {
struct PrivateMemoryAllocation : IDisposable readonly struct PrivateMemoryAllocation : IDisposable
{ {
private readonly PrivateMemoryAllocator _owner; private readonly PrivateMemoryAllocator _owner;
private readonly PrivateMemoryAllocator.Block _block; private readonly PrivateMemoryAllocator.Block _block;
@ -27,8 +27,8 @@ namespace Ryujinx.Cpu
public (PrivateMemoryAllocation, PrivateMemoryAllocation) Split(ulong splitOffset) public (PrivateMemoryAllocation, PrivateMemoryAllocation) Split(ulong splitOffset)
{ {
PrivateMemoryAllocation left = new PrivateMemoryAllocation(_owner, _block, Offset, splitOffset); PrivateMemoryAllocation left = new(_owner, _block, Offset, splitOffset);
PrivateMemoryAllocation right = new PrivateMemoryAllocation(_owner, _block, Offset + splitOffset, Size - splitOffset); PrivateMemoryAllocation right = new(_owner, _block, Offset + splitOffset, Size - splitOffset);
return (left, right); return (left, right);
} }

View file

@ -15,7 +15,7 @@ namespace Ryujinx.Cpu
public MemoryBlock Memory { get; private set; } public MemoryBlock Memory { get; private set; }
public ulong Size { get; } public ulong Size { get; }
private struct Range : IComparable<Range> private readonly struct Range : IComparable<Range>
{ {
public ulong Offset { get; } public ulong Offset { get; }
public ulong Size { get; } public ulong Size { get; }
@ -40,7 +40,7 @@ namespace Ryujinx.Cpu
Size = size; Size = size;
_freeRanges = new List<Range> _freeRanges = new List<Range>
{ {
new Range(0, size) new Range(0, size),
}; };
} }
@ -164,7 +164,7 @@ namespace Ryujinx.Cpu
{ {
private const ulong InvalidOffset = ulong.MaxValue; private const ulong InvalidOffset = ulong.MaxValue;
public struct Allocation public readonly struct Allocation
{ {
public T Block { get; } public T Block { get; }
public ulong Offset { get; } public ulong Offset { get; }