/ src / Ryujinx.Memory / IVirtualMemoryManager.cs
IVirtualMemoryManager.cs
  1  using Ryujinx.Memory.Range;
  2  using System;
  3  using System.Buffers;
  4  using System.Collections.Generic;
  5  
  6  namespace Ryujinx.Memory
  7  {
  8      public interface IVirtualMemoryManager
  9      {
 10          /// <summary>
 11          /// Indicates whether the memory manager creates private allocations when the <see cref="MemoryMapFlags.Private"/> flag is set on map.
 12          /// </summary>
 13          /// <returns>True if private mappings might be used, false otherwise</returns>
 14          bool UsesPrivateAllocations { get; }
 15  
 16          /// <summary>
 17          /// Maps a virtual memory range into a physical memory range.
 18          /// </summary>
 19          /// <remarks>
 20          /// Addresses and size must be page aligned.
 21          /// </remarks>
 22          /// <param name="va">Virtual memory address</param>
 23          /// <param name="pa">Physical memory address where the region should be mapped to</param>
 24          /// <param name="size">Size to be mapped</param>
 25          /// <param name="flags">Flags controlling memory mapping</param>
 26          void Map(ulong va, ulong pa, ulong size, MemoryMapFlags flags);
 27  
 28          /// <summary>
 29          /// Maps a virtual memory range into an arbitrary host memory range.
 30          /// </summary>
 31          /// <remarks>
 32          /// Addresses and size must be page aligned.
 33          /// Not all memory managers supports this feature.
 34          /// </remarks>
 35          /// <param name="va">Virtual memory address</param>
 36          /// <param name="hostPointer">Host pointer where the virtual region should be mapped</param>
 37          /// <param name="size">Size to be mapped</param>
 38          void MapForeign(ulong va, nuint hostPointer, ulong size);
 39  
 40          /// <summary>
 41          /// Unmaps a previously mapped range of virtual memory.
 42          /// </summary>
 43          /// <param name="va">Virtual address of the range to be unmapped</param>
 44          /// <param name="size">Size of the range to be unmapped</param>
 45          void Unmap(ulong va, ulong size);
 46  
 47          /// <summary>
 48          /// Reads data from CPU mapped memory.
 49          /// </summary>
 50          /// <typeparam name="T">Type of the data being read</typeparam>
 51          /// <param name="va">Virtual address of the data in memory</param>
 52          /// <returns>The data</returns>
 53          /// <exception cref="InvalidMemoryRegionException">Throw for unhandled invalid or unmapped memory accesses</exception>
 54          T Read<T>(ulong va) where T : unmanaged;
 55  
 56          /// <summary>
 57          /// Reads data from CPU mapped memory.
 58          /// </summary>
 59          /// <param name="va">Virtual address of the data in memory</param>
 60          /// <param name="data">Span to store the data being read into</param>
 61          /// <exception cref="InvalidMemoryRegionException">Throw for unhandled invalid or unmapped memory accesses</exception>
 62          void Read(ulong va, Span<byte> data);
 63  
 64          /// <summary>
 65          /// Writes data to CPU mapped memory.
 66          /// </summary>
 67          /// <typeparam name="T">Type of the data being written</typeparam>
 68          /// <param name="va">Virtual address to write the data into</param>
 69          /// <param name="value">Data to be written</param>
 70          /// <exception cref="InvalidMemoryRegionException">Throw for unhandled invalid or unmapped memory accesses</exception>
 71          void Write<T>(ulong va, T value) where T : unmanaged;
 72  
 73          /// <summary>
 74          /// Writes data to CPU mapped memory, with write tracking.
 75          /// </summary>
 76          /// <param name="va">Virtual address to write the data into</param>
 77          /// <param name="data">Data to be written</param>
 78          /// <exception cref="InvalidMemoryRegionException">Throw for unhandled invalid or unmapped memory accesses</exception>
 79          void Write(ulong va, ReadOnlySpan<byte> data);
 80  
 81          /// <summary>
 82          /// Writes data to CPU mapped memory, with write tracking.
 83          /// </summary>
 84          /// <param name="va">Virtual address to write the data into</param>
 85          /// <param name="data">Data to be written</param>
 86          /// <exception cref="InvalidMemoryRegionException">Throw for unhandled invalid or unmapped memory accesses</exception>
 87          public void Write(ulong va, ReadOnlySequence<byte> data)
 88          {
 89              foreach (ReadOnlyMemory<byte> segment in data)
 90              {
 91                  Write(va, segment.Span);
 92                  va += (ulong)segment.Length;
 93              }
 94          }
 95  
 96          /// <summary>
 97          /// Writes data to the application process, returning false if the data was not changed.
 98          /// This triggers read memory tracking, as a redundancy check would be useless if the data is not up to date.
 99          /// </summary>
100          /// <remarks>The memory manager can return that memory has changed when it hasn't to avoid expensive data copies.</remarks>
101          /// <param name="va">Virtual address to write the data into</param>
102          /// <param name="data">Data to be written</param>
103          /// <exception cref="InvalidMemoryRegionException">Throw for unhandled invalid or unmapped memory accesses</exception>
104          /// <returns>True if the data was changed, false otherwise</returns>
105          bool WriteWithRedundancyCheck(ulong va, ReadOnlySpan<byte> data);
106  
107          /// <summary>
108          /// Fills the specified memory region with the value specified in <paramref name="value"/>.
109          /// </summary>
110          /// <param name="va">Virtual address to fill the value into</param>
111          /// <param name="size">Size of the memory region to fill</param>
112          /// <param name="value">Value to fill with</param>
113          void Fill(ulong va, ulong size, byte value)
114          {
115              const int MaxChunkSize = 1 << 24;
116  
117              for (ulong subOffset = 0; subOffset < size; subOffset += MaxChunkSize)
118              {
119                  int copySize = (int)Math.Min(MaxChunkSize, size - subOffset);
120  
121                  using var writableRegion = GetWritableRegion(va + subOffset, copySize);
122  
123                  writableRegion.Memory.Span.Fill(value);
124              }
125          }
126  
127          /// <summary>
128          /// Gets a read-only sequence of read-only memory blocks from CPU mapped memory.
129          /// </summary>
130          /// <param name="va">Virtual address of the data</param>
131          /// <param name="size">Size of the data</param>
132          /// <param name="tracked">True if read tracking is triggered on the memory</param>
133          /// <returns>A read-only sequence of read-only memory of the data</returns>
134          /// <exception cref="InvalidMemoryRegionException">Throw for unhandled invalid or unmapped memory accesses</exception>
135          ReadOnlySequence<byte> GetReadOnlySequence(ulong va, int size, bool tracked = false);
136  
137          /// <summary>
138          /// Gets a read-only span of data from CPU mapped memory.
139          /// </summary>
140          /// <param name="va">Virtual address of the data</param>
141          /// <param name="size">Size of the data</param>
142          /// <param name="tracked">True if read tracking is triggered on the span</param>
143          /// <returns>A read-only span of the data</returns>
144          /// <exception cref="InvalidMemoryRegionException">Throw for unhandled invalid or unmapped memory accesses</exception>
145          ReadOnlySpan<byte> GetSpan(ulong va, int size, bool tracked = false);
146  
147          /// <summary>
148          /// Gets a region of memory that can be written to.
149          /// </summary>
150          /// <param name="va">Virtual address of the data</param>
151          /// <param name="size">Size of the data</param>
152          /// <param name="tracked">True if write tracking is triggered on the span</param>
153          /// <returns>A writable region of memory containing the data</returns>
154          /// <exception cref="InvalidMemoryRegionException">Throw for unhandled invalid or unmapped memory accesses</exception>
155          WritableRegion GetWritableRegion(ulong va, int size, bool tracked = false);
156  
157          /// <summary>
158          /// Gets a reference for the given type at the specified virtual memory address.
159          /// </summary>
160          /// <remarks>
161          /// The data must be located at a contiguous memory region.
162          /// </remarks>
163          /// <typeparam name="T">Type of the data to get the reference</typeparam>
164          /// <param name="va">Virtual address of the data</param>
165          /// <returns>A reference to the data in memory</returns>
166          /// <exception cref="MemoryNotContiguousException">Throw if the specified memory region is not contiguous in physical memory</exception>
167          ref T GetRef<T>(ulong va) where T : unmanaged;
168  
169          /// <summary>
170          /// Gets the host regions that make up the given virtual address region.
171          /// If any part of the virtual region is unmapped, null is returned.
172          /// </summary>
173          /// <param name="va">Virtual address of the range</param>
174          /// <param name="size">Size of the range</param>
175          /// <returns>Array of host regions</returns>
176          IEnumerable<HostMemoryRange> GetHostRegions(ulong va, ulong size);
177  
178          /// <summary>
179          /// Gets the physical regions that make up the given virtual address region.
180          /// If any part of the virtual region is unmapped, null is returned.
181          /// </summary>
182          /// <param name="va">Virtual address of the range</param>
183          /// <param name="size">Size of the range</param>
184          /// <returns>Array of physical regions</returns>
185          IEnumerable<MemoryRange> GetPhysicalRegions(ulong va, ulong size);
186  
187          /// <summary>
188          /// Checks if the page at a given CPU virtual address is mapped.
189          /// </summary>
190          /// <param name="va">Virtual address to check</param>
191          /// <returns>True if the address is mapped, false otherwise</returns>
192          bool IsMapped(ulong va);
193  
194          /// <summary>
195          /// Checks if a memory range is mapped.
196          /// </summary>
197          /// <param name="va">Virtual address of the range</param>
198          /// <param name="size">Size of the range in bytes</param>
199          /// <returns>True if the entire range is mapped, false otherwise</returns>
200          bool IsRangeMapped(ulong va, ulong size);
201  
202          /// <summary>
203          /// Alerts the memory tracking that a given region has been read from or written to.
204          /// This should be called before read/write is performed.
205          /// </summary>
206          /// <param name="va">Virtual address of the region</param>
207          /// <param name="size">Size of the region</param>
208          /// <param name="write">True if the region was written, false if read</param>
209          /// <param name="precise">True if the access is precise, false otherwise</param>
210          /// <param name="exemptId">Optional ID of the handles that should not be signalled</param>
211          void SignalMemoryTracking(ulong va, ulong size, bool write, bool precise = false, int? exemptId = null);
212  
213          /// <summary>
214          /// Reprotect a region of virtual memory for guest access.
215          /// </summary>
216          /// <param name="va">Virtual address base</param>
217          /// <param name="size">Size of the region to protect</param>
218          /// <param name="protection">Memory protection to set</param>
219          void Reprotect(ulong va, ulong size, MemoryPermission protection);
220  
221          /// <summary>
222          /// Reprotect a region of virtual memory for tracking.
223          /// </summary>
224          /// <param name="va">Virtual address base</param>
225          /// <param name="size">Size of the region to protect</param>
226          /// <param name="protection">Memory protection to set</param>
227          /// <param name="guest">True if the protection is for guest access, false otherwise</param>
228          void TrackingReprotect(ulong va, ulong size, MemoryPermission protection, bool guest);
229      }
230  }