aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Cpu/MemoryEhMeilleure.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Cpu/MemoryEhMeilleure.cs')
-rw-r--r--src/Ryujinx.Cpu/MemoryEhMeilleure.cs32
1 files changed, 28 insertions, 4 deletions
diff --git a/src/Ryujinx.Cpu/MemoryEhMeilleure.cs b/src/Ryujinx.Cpu/MemoryEhMeilleure.cs
index f3a5b056..379ace94 100644
--- a/src/Ryujinx.Cpu/MemoryEhMeilleure.cs
+++ b/src/Ryujinx.Cpu/MemoryEhMeilleure.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Common;
using Ryujinx.Cpu.Signal;
using Ryujinx.Memory;
using Ryujinx.Memory.Tracking;
@@ -8,19 +9,27 @@ namespace Ryujinx.Cpu
{
public class MemoryEhMeilleure : IDisposable
{
- private delegate bool TrackingEventDelegate(ulong address, ulong size, bool write);
+ public delegate ulong TrackingEventDelegate(ulong address, ulong size, bool write);
+ private readonly MemoryTracking _tracking;
private readonly TrackingEventDelegate _trackingEvent;
+ private readonly ulong _pageSize;
+
private readonly ulong _baseAddress;
private readonly ulong _mirrorAddress;
- public MemoryEhMeilleure(MemoryBlock addressSpace, MemoryBlock addressSpaceMirror, MemoryTracking tracking)
+ public MemoryEhMeilleure(MemoryBlock addressSpace, MemoryBlock addressSpaceMirror, MemoryTracking tracking, TrackingEventDelegate trackingEvent = null)
{
_baseAddress = (ulong)addressSpace.Pointer;
+
ulong endAddress = _baseAddress + addressSpace.Size;
- _trackingEvent = tracking.VirtualMemoryEvent;
+ _tracking = tracking;
+ _trackingEvent = trackingEvent ?? VirtualMemoryEvent;
+
+ _pageSize = MemoryBlock.GetPageSize();
+
bool added = NativeSignalHandler.AddTrackedRegion((nuint)_baseAddress, (nuint)endAddress, Marshal.GetFunctionPointerForDelegate(_trackingEvent));
if (!added)
@@ -28,7 +37,7 @@ namespace Ryujinx.Cpu
throw new InvalidOperationException("Number of allowed tracked regions exceeded.");
}
- if (OperatingSystem.IsWindows())
+ if (OperatingSystem.IsWindows() && addressSpaceMirror != null)
{
// Add a tracking event with no signal handler for the mirror on Windows.
// The native handler has its own code to check for the partial overlap race when regions are protected by accident,
@@ -46,6 +55,21 @@ namespace Ryujinx.Cpu
}
}
+ private ulong VirtualMemoryEvent(ulong address, ulong size, bool write)
+ {
+ ulong pageSize = _pageSize;
+ ulong addressAligned = BitUtils.AlignDown(address, pageSize);
+ ulong endAddressAligned = BitUtils.AlignUp(address + size, pageSize);
+ ulong sizeAligned = endAddressAligned - addressAligned;
+
+ if (_tracking.VirtualMemoryEvent(addressAligned, sizeAligned, write))
+ {
+ return _baseAddress + address;
+ }
+
+ return 0;
+ }
+
public void Dispose()
{
GC.SuppressFinalize(this);