ArmProcessContext.cs
1 using ARMeilleure.Memory; 2 using Ryujinx.Cpu; 3 using Ryujinx.Graphics.Gpu; 4 using Ryujinx.HLE.HOS.Kernel.Process; 5 using Ryujinx.Memory; 6 7 namespace Ryujinx.HLE.HOS 8 { 9 interface IArmProcessContext : IProcessContext 10 { 11 IDiskCacheLoadState Initialize( 12 string titleIdText, 13 string displayVersion, 14 bool diskCacheEnabled, 15 ulong codeAddress, 16 ulong codeSize); 17 } 18 19 class ArmProcessContext<T> : IArmProcessContext where T : class, IVirtualMemoryManagerTracked, IMemoryManager 20 { 21 private readonly ulong _pid; 22 private readonly GpuContext _gpuContext; 23 private readonly ICpuContext _cpuContext; 24 private T _memoryManager; 25 26 public IVirtualMemoryManager AddressSpace => _memoryManager; 27 28 public ulong AddressSpaceSize { get; } 29 30 public ArmProcessContext( 31 ulong pid, 32 ICpuEngine cpuEngine, 33 GpuContext gpuContext, 34 T memoryManager, 35 ulong addressSpaceSize, 36 bool for64Bit) 37 { 38 if (memoryManager is IRefCounted rc) 39 { 40 rc.IncrementReferenceCount(); 41 } 42 43 gpuContext.RegisterProcess(pid, memoryManager); 44 45 _pid = pid; 46 _gpuContext = gpuContext; 47 _cpuContext = cpuEngine.CreateCpuContext(memoryManager, for64Bit); 48 _memoryManager = memoryManager; 49 50 AddressSpaceSize = addressSpaceSize; 51 } 52 53 public IExecutionContext CreateExecutionContext(ExceptionCallbacks exceptionCallbacks) 54 { 55 return _cpuContext.CreateExecutionContext(exceptionCallbacks); 56 } 57 58 public void Execute(IExecutionContext context, ulong codeAddress) 59 { 60 // We must wait until shader cache is loaded, among other things, before executing CPU code. 61 _gpuContext.WaitUntilGpuReady(); 62 _cpuContext.Execute(context, codeAddress); 63 } 64 65 public IDiskCacheLoadState Initialize( 66 string titleIdText, 67 string displayVersion, 68 bool diskCacheEnabled, 69 ulong codeAddress, 70 ulong codeSize) 71 { 72 _cpuContext.PrepareCodeRange(codeAddress, codeSize); 73 return _cpuContext.LoadDiskCache(titleIdText, displayVersion, diskCacheEnabled); 74 } 75 76 public void InvalidateCacheRegion(ulong address, ulong size) 77 { 78 _cpuContext.InvalidateCacheRegion(address, size); 79 } 80 81 public void Dispose() 82 { 83 if (_memoryManager is IRefCounted rc) 84 { 85 rc.DecrementReferenceCount(); 86 87 _memoryManager = null; 88 _gpuContext.UnregisterProcess(_pid); 89 } 90 91 _cpuContext.Dispose(); 92 } 93 } 94 }