diff --git a/Ryujinx.Cpu/MemoryManager.cs b/Ryujinx.Cpu/MemoryManager.cs
index 26cc01c917..3fa08fe752 100644
--- a/Ryujinx.Cpu/MemoryManager.cs
+++ b/Ryujinx.Cpu/MemoryManager.cs
@@ -1,4 +1,4 @@
-using ARMeilleure.Memory;
+using ARMeilleure.Memory;
using Ryujinx.Cpu.Tracking;
using Ryujinx.Memory;
using Ryujinx.Memory.Tracking;
@@ -461,7 +461,32 @@ namespace Ryujinx.Cpu
}
///
- /// Checks if the page at a given CPU virtual address.
+ /// Checks if a memory range is mapped.
+ ///
+ /// Virtual address of the range
+ /// Size of the range in bytes
+ /// True if the entire range is mapped, false otherwise
+ public bool IsRangeMapped(ulong va, ulong size)
+ {
+ ulong endVa = (va + size + PageMask) & ~(ulong)PageMask;
+
+ va &= ~(ulong)PageMask;
+
+ while (va < endVa)
+ {
+ if (!IsMapped(va))
+ {
+ return false;
+ }
+
+ va += PageSize;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Checks if the page at a given CPU virtual address is mapped.
///
/// Virtual address to check
/// True if the address is mapped, false otherwise
diff --git a/Ryujinx.Memory.Tests/MockVirtualMemoryManager.cs b/Ryujinx.Memory.Tests/MockVirtualMemoryManager.cs
index f9692cfcc5..037bedc8cc 100644
--- a/Ryujinx.Memory.Tests/MockVirtualMemoryManager.cs
+++ b/Ryujinx.Memory.Tests/MockVirtualMemoryManager.cs
@@ -15,6 +15,11 @@ namespace Ryujinx.Memory.Tests
return NoMappings ? new (ulong address, ulong size)[0] : new (ulong address, ulong size)[] { (va, size) };
}
+ public bool IsRangeMapped(ulong va, ulong size)
+ {
+ return true;
+ }
+
public void TrackingReprotect(ulong va, ulong size, MemoryPermission protection)
{
diff --git a/Ryujinx.Memory/Tracking/IVirtualMemoryManager.cs b/Ryujinx.Memory/Tracking/IVirtualMemoryManager.cs
index 6b5474e1fd..e6d8e8c98f 100644
--- a/Ryujinx.Memory/Tracking/IVirtualMemoryManager.cs
+++ b/Ryujinx.Memory/Tracking/IVirtualMemoryManager.cs
@@ -4,6 +4,7 @@
{
(ulong address, ulong size)[] GetPhysicalRegions(ulong va, ulong size);
+ bool IsRangeMapped(ulong va, ulong size);
void TrackingReprotect(ulong va, ulong size, MemoryPermission protection);
}
}
diff --git a/Ryujinx.Memory/Tracking/MemoryTracking.cs b/Ryujinx.Memory/Tracking/MemoryTracking.cs
index 779166c44e..aff223e802 100644
--- a/Ryujinx.Memory/Tracking/MemoryTracking.cs
+++ b/Ryujinx.Memory/Tracking/MemoryTracking.cs
@@ -75,6 +75,7 @@ namespace Ryujinx.Memory.Tracking
{
VirtualRegion region = results[i];
region.RecalculatePhysicalChildren();
+ region.UpdateProtection();
}
}
}
@@ -200,7 +201,7 @@ namespace Ryujinx.Memory.Tracking
lock (TrackingLock)
{
- RegionHandle handle = new RegionHandle(this, address, size);
+ RegionHandle handle = new RegionHandle(this, address, size, _memoryManager.IsRangeMapped(address, size));
return handle;
}
diff --git a/Ryujinx.Memory/Tracking/RegionHandle.cs b/Ryujinx.Memory/Tracking/RegionHandle.cs
index c00d039b25..96898c214f 100644
--- a/Ryujinx.Memory/Tracking/RegionHandle.cs
+++ b/Ryujinx.Memory/Tracking/RegionHandle.cs
@@ -10,7 +10,7 @@ namespace Ryujinx.Memory.Tracking
///
public class RegionHandle : IRegionHandle, IRange
{
- public bool Dirty { get; private set; } = true;
+ public bool Dirty { get; private set; }
public ulong Address { get; }
public ulong Size { get; }
@@ -32,8 +32,10 @@ namespace Ryujinx.Memory.Tracking
/// Tracking object for the target memory block
/// Virtual address of the region to track
/// Size of the region to track
- internal RegionHandle(MemoryTracking tracking, ulong address, ulong size)
+ /// Initial value of the dirty flag
+ internal RegionHandle(MemoryTracking tracking, ulong address, ulong size, bool dirty = true)
{
+ Dirty = dirty;
Address = address;
Size = size;
EndAddress = address + size;