 f77694e4f7
			
		
	
	
		f77694e4f7
		
			
		
	
	
	
	
		
			
			* Implement a new physical memory manager and replace DeviceMemory * Proper generic constraints * Fix debug build * Add memory tests * New CPU memory manager and general code cleanup * Remove host memory management from CPU project, use Ryujinx.Memory instead * Fix tests * Document exceptions on MemoryBlock * Fix leak on unix memory allocation * Proper disposal of some objects on tests * Fix JitCache not being set as initialized * GetRef without checks for 8-bits and 16-bits CAS * Add MemoryBlock destructor * Throw in separate method to improve codegen * Address PR feedback * QueryModified improvements * Fix memory write tracking not marking all pages as modified in some cases * Simplify MarkRegionAsModified * Remove XML doc for ghost param * Add back optimization to avoid useless buffer updates * Add Ryujinx.Cpu project, move MemoryManager there and remove MemoryBlockWrapper * Some nits * Do not perform address translation when size is 0 * Address PR feedback and format NativeInterface class * Remove ghost parameter description * Update Ryujinx.Cpu to .NET Core 3.1 * Address PR feedback * Fix build * Return a well defined value for GetPhysicalAddress with invalid VA, and do not return unmapped ranges as modified * Typo
		
			
				
	
	
		
			106 lines
		
	
	
		
			No EOL
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			No EOL
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Runtime.InteropServices;
 | |
| 
 | |
| namespace Ryujinx.Memory
 | |
| {
 | |
|     static class MemoryManagementWindows
 | |
|     {
 | |
|         [Flags]
 | |
|         private enum AllocationType : uint
 | |
|         {
 | |
|             Commit = 0x1000,
 | |
|             Reserve = 0x2000,
 | |
|             Decommit = 0x4000,
 | |
|             Release = 0x8000,
 | |
|             Reset = 0x80000,
 | |
|             Physical = 0x400000,
 | |
|             TopDown = 0x100000,
 | |
|             WriteWatch = 0x200000,
 | |
|             LargePages = 0x20000000
 | |
|         }
 | |
| 
 | |
|         [Flags]
 | |
|         private enum MemoryProtection : uint
 | |
|         {
 | |
|             NoAccess = 0x01,
 | |
|             ReadOnly = 0x02,
 | |
|             ReadWrite = 0x04,
 | |
|             WriteCopy = 0x08,
 | |
|             Execute = 0x10,
 | |
|             ExecuteRead = 0x20,
 | |
|             ExecuteReadWrite = 0x40,
 | |
|             ExecuteWriteCopy = 0x80,
 | |
|             GuardModifierflag = 0x100,
 | |
|             NoCacheModifierflag = 0x200,
 | |
|             WriteCombineModifierflag = 0x400
 | |
|         }
 | |
| 
 | |
|         [DllImport("kernel32.dll")]
 | |
|         private static extern IntPtr VirtualAlloc(
 | |
|             IntPtr lpAddress,
 | |
|             IntPtr dwSize,
 | |
|             AllocationType flAllocationType,
 | |
|             MemoryProtection flProtect);
 | |
| 
 | |
|         [DllImport("kernel32.dll")]
 | |
|         private static extern bool VirtualProtect(
 | |
|             IntPtr lpAddress,
 | |
|             IntPtr dwSize,
 | |
|             MemoryProtection flNewProtect,
 | |
|             out MemoryProtection lpflOldProtect);
 | |
| 
 | |
|         [DllImport("kernel32.dll")]
 | |
|         private static extern bool VirtualFree(IntPtr lpAddress, IntPtr dwSize, AllocationType dwFreeType);
 | |
| 
 | |
|         public static IntPtr Allocate(IntPtr size)
 | |
|         {
 | |
|             return AllocateInternal(size, AllocationType.Reserve | AllocationType.Commit);
 | |
|         }
 | |
| 
 | |
|         public static IntPtr Reserve(IntPtr size)
 | |
|         {
 | |
|             return AllocateInternal(size, AllocationType.Reserve);
 | |
|         }
 | |
| 
 | |
|         private static IntPtr AllocateInternal(IntPtr size, AllocationType flags = 0)
 | |
|         {
 | |
|             IntPtr ptr = VirtualAlloc(IntPtr.Zero, size, flags, MemoryProtection.ReadWrite);
 | |
| 
 | |
|             if (ptr == IntPtr.Zero)
 | |
|             {
 | |
|                 throw new OutOfMemoryException();
 | |
|             }
 | |
| 
 | |
|             return ptr;
 | |
|         }
 | |
| 
 | |
|         public static bool Commit(IntPtr location, IntPtr size)
 | |
|         {
 | |
|             return VirtualAlloc(location, size, AllocationType.Commit, MemoryProtection.ReadWrite) != IntPtr.Zero;
 | |
|         }
 | |
| 
 | |
|         public static bool Reprotect(IntPtr address, IntPtr size, MemoryPermission permission)
 | |
|         {
 | |
|             return VirtualProtect(address, size, GetProtection(permission), out _);
 | |
|         }
 | |
| 
 | |
|         private static MemoryProtection GetProtection(MemoryPermission permission)
 | |
|         {
 | |
|             return permission switch
 | |
|             {
 | |
|                 MemoryPermission.None => MemoryProtection.NoAccess,
 | |
|                 MemoryPermission.Read => MemoryProtection.ReadOnly,
 | |
|                 MemoryPermission.ReadAndWrite => MemoryProtection.ReadWrite,
 | |
|                 MemoryPermission.ReadAndExecute => MemoryProtection.ExecuteRead,
 | |
|                 MemoryPermission.ReadWriteExecute => MemoryProtection.ExecuteReadWrite,
 | |
|                 MemoryPermission.Execute => MemoryProtection.Execute,
 | |
|                 _ => throw new MemoryProtectionException(permission)
 | |
|             };
 | |
|         }
 | |
| 
 | |
|         public static bool Free(IntPtr address)
 | |
|         {
 | |
|             return VirtualFree(address, IntPtr.Zero, AllocationType.Release);
 | |
|         }
 | |
|     }
 | |
| } |