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 }