diff options
Diffstat (limited to 'src/Ryujinx.Memory/Tracking/RegionHandle.cs')
-rw-r--r-- | src/Ryujinx.Memory/Tracking/RegionHandle.cs | 68 |
1 files changed, 56 insertions, 12 deletions
diff --git a/src/Ryujinx.Memory/Tracking/RegionHandle.cs b/src/Ryujinx.Memory/Tracking/RegionHandle.cs index df3d9c31..a94ffa43 100644 --- a/src/Ryujinx.Memory/Tracking/RegionHandle.cs +++ b/src/Ryujinx.Memory/Tracking/RegionHandle.cs @@ -55,6 +55,8 @@ namespace Ryujinx.Memory.Tracking private RegionSignal _preAction; // Action to perform before a read or write. This will block the memory access. private PreciseRegionSignal _preciseAction; // Action to perform on a precise read or write. private readonly List<VirtualRegion> _regions; + private readonly List<VirtualRegion> _guestRegions; + private readonly List<VirtualRegion> _allRegions; private readonly MemoryTracking _tracking; private bool _disposed; @@ -99,6 +101,7 @@ namespace Ryujinx.Memory.Tracking /// <param name="bitmap">The bitmap the dirty flag for this handle is stored in</param> /// <param name="bit">The bit index representing the dirty flag for this handle</param> /// <param name="id">Handle ID</param> + /// <param name="flags">Region flags</param> /// <param name="mapped">True if the region handle starts mapped</param> internal RegionHandle( MemoryTracking tracking, @@ -109,6 +112,7 @@ namespace Ryujinx.Memory.Tracking ConcurrentBitmap bitmap, int bit, int id, + RegionFlags flags, bool mapped = true) { Bitmap = bitmap; @@ -128,11 +132,12 @@ namespace Ryujinx.Memory.Tracking RealEndAddress = realAddress + realSize; _tracking = tracking; - _regions = tracking.GetVirtualRegionsForHandle(address, size); - foreach (var region in _regions) - { - region.Handles.Add(this); - } + + _regions = tracking.GetVirtualRegionsForHandle(address, size, false); + _guestRegions = GetGuestRegions(tracking, address, size, flags); + _allRegions = new List<VirtualRegion>(_regions.Count + _guestRegions.Count); + + InitializeRegions(); } /// <summary> @@ -145,8 +150,9 @@ namespace Ryujinx.Memory.Tracking /// <param name="realAddress">The real, unaligned address of the handle</param> /// <param name="realSize">The real, unaligned size of the handle</param> /// <param name="id">Handle ID</param> + /// <param name="flags">Region flags</param> /// <param name="mapped">True if the region handle starts mapped</param> - internal RegionHandle(MemoryTracking tracking, ulong address, ulong size, ulong realAddress, ulong realSize, int id, bool mapped = true) + internal RegionHandle(MemoryTracking tracking, ulong address, ulong size, ulong realAddress, ulong realSize, int id, RegionFlags flags, bool mapped = true) { Bitmap = new ConcurrentBitmap(1, mapped); @@ -163,8 +169,37 @@ namespace Ryujinx.Memory.Tracking RealEndAddress = realAddress + realSize; _tracking = tracking; - _regions = tracking.GetVirtualRegionsForHandle(address, size); - foreach (var region in _regions) + + _regions = tracking.GetVirtualRegionsForHandle(address, size, false); + _guestRegions = GetGuestRegions(tracking, address, size, flags); + _allRegions = new List<VirtualRegion>(_regions.Count + _guestRegions.Count); + + InitializeRegions(); + } + + private List<VirtualRegion> GetGuestRegions(MemoryTracking tracking, ulong address, ulong size, RegionFlags flags) + { + ulong guestAddress; + ulong guestSize; + + if (flags.HasFlag(RegionFlags.UnalignedAccess)) + { + (guestAddress, guestSize) = tracking.GetUnalignedSafeRegion(address, size); + } + else + { + (guestAddress, guestSize) = (address, size); + } + + return tracking.GetVirtualRegionsForHandle(guestAddress, guestSize, true); + } + + private void InitializeRegions() + { + _allRegions.AddRange(_regions); + _allRegions.AddRange(_guestRegions); + + foreach (var region in _allRegions) { region.Handles.Add(this); } @@ -321,7 +356,7 @@ namespace Ryujinx.Memory.Tracking lock (_tracking.TrackingLock) { - foreach (VirtualRegion region in _regions) + foreach (VirtualRegion region in _allRegions) { protectionChanged |= region.UpdateProtection(); } @@ -379,7 +414,7 @@ namespace Ryujinx.Memory.Tracking { lock (_tracking.TrackingLock) { - foreach (VirtualRegion region in _regions) + foreach (VirtualRegion region in _allRegions) { region.UpdateProtection(); } @@ -414,7 +449,16 @@ namespace Ryujinx.Memory.Tracking /// <param name="region">Virtual region to add as a child</param> internal void AddChild(VirtualRegion region) { - _regions.Add(region); + if (region.Guest) + { + _guestRegions.Add(region); + } + else + { + _regions.Add(region); + } + + _allRegions.Add(region); } /// <summary> @@ -469,7 +513,7 @@ namespace Ryujinx.Memory.Tracking lock (_tracking.TrackingLock) { - foreach (VirtualRegion region in _regions) + foreach (VirtualRegion region in _allRegions) { region.RemoveHandle(this); } |