/ src / Ryujinx.HLE / HOS / ArmProcessContext.cs
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  }