| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- using Ryujinx.Common.Configuration;
- using Ryujinx.Common.Logging;
- using Ryujinx.Cpu;
- using Ryujinx.Cpu.AppleHv;
- using Ryujinx.Cpu.Jit;
- using Ryujinx.Cpu.LightningJit;
- using Ryujinx.Graphics.Gpu;
- using Ryujinx.HLE.HOS.Kernel;
- using Ryujinx.HLE.HOS.Kernel.Process;
- using Ryujinx.Memory;
- using System;
- using System.Runtime.InteropServices;
- namespace Ryujinx.HLE.HOS
- {
- class ArmProcessContextFactory : IProcessContextFactory
- {
- private readonly ITickSource _tickSource;
- private readonly GpuContext _gpu;
- private readonly string _titleIdText;
- private readonly string _displayVersion;
- private readonly bool _diskCacheEnabled;
- private readonly ulong _codeAddress;
- private readonly ulong _codeSize;
- public IDiskCacheLoadState DiskCacheLoadState { get; private set; }
- public ArmProcessContextFactory(
- ITickSource tickSource,
- GpuContext gpu,
- string titleIdText,
- string displayVersion,
- bool diskCacheEnabled,
- ulong codeAddress,
- ulong codeSize)
- {
- _tickSource = tickSource;
- _gpu = gpu;
- _titleIdText = titleIdText;
- _displayVersion = displayVersion;
- _diskCacheEnabled = diskCacheEnabled;
- _codeAddress = codeAddress;
- _codeSize = codeSize;
- }
- public IProcessContext Create(KernelContext context, ulong pid, ulong addressSpaceSize, InvalidAccessHandler invalidAccessHandler, bool for64Bit)
- {
- IArmProcessContext processContext;
- bool isArm64Host = RuntimeInformation.ProcessArchitecture == Architecture.Arm64;
- if (OperatingSystem.IsMacOS() && isArm64Host && for64Bit && context.Device.Configuration.UseHypervisor)
- {
- var cpuEngine = new HvEngine(_tickSource);
- var memoryManager = new HvMemoryManager(context.Memory, addressSpaceSize, invalidAccessHandler);
- processContext = new ArmProcessContext<HvMemoryManager>(pid, cpuEngine, _gpu, memoryManager, addressSpaceSize, for64Bit);
- }
- else
- {
- MemoryManagerMode mode = context.Device.Configuration.MemoryManagerMode;
- if (!MemoryBlock.SupportsFlags(MemoryAllocationFlags.ViewCompatible))
- {
- Logger.Warning?.Print(LogClass.Cpu, "Host system doesn't support views, falling back to software page table");
- mode = MemoryManagerMode.SoftwarePageTable;
- }
- ICpuEngine cpuEngine = isArm64Host && (mode == MemoryManagerMode.HostMapped || mode == MemoryManagerMode.HostMappedUnsafe)
- ? new LightningJitEngine(_tickSource)
- : new JitEngine(_tickSource);
- AddressSpace addressSpace = null;
- // We want to use host tracked mode if the host page size is > 4KB.
- if ((mode == MemoryManagerMode.HostMapped || mode == MemoryManagerMode.HostMappedUnsafe) && MemoryBlock.GetPageSize() <= 0x1000)
- {
- if (!AddressSpace.TryCreate(context.Memory, addressSpaceSize, out addressSpace))
- {
- Logger.Warning?.Print(LogClass.Cpu, "Address space creation failed, falling back to software page table");
- mode = MemoryManagerMode.SoftwarePageTable;
- }
- }
- switch (mode)
- {
- case MemoryManagerMode.SoftwarePageTable:
- var memoryManager = new MemoryManager(context.Memory, addressSpaceSize, invalidAccessHandler);
- processContext = new ArmProcessContext<MemoryManager>(pid, cpuEngine, _gpu, memoryManager, addressSpaceSize, for64Bit);
- break;
- case MemoryManagerMode.HostMapped:
- case MemoryManagerMode.HostMappedUnsafe:
- if (addressSpace == null)
- {
- var memoryManagerHostTracked = new MemoryManagerHostTracked(context.Memory, addressSpaceSize, mode == MemoryManagerMode.HostMappedUnsafe, invalidAccessHandler);
- processContext = new ArmProcessContext<MemoryManagerHostTracked>(pid, cpuEngine, _gpu, memoryManagerHostTracked, addressSpaceSize, for64Bit);
- }
- else
- {
- if (addressSpaceSize != addressSpace.AddressSpaceSize)
- {
- Logger.Warning?.Print(LogClass.Emulation, $"Allocated address space (0x{addressSpace.AddressSpaceSize:X}) is smaller than guest application requirements (0x{addressSpaceSize:X})");
- }
- var memoryManagerHostMapped = new MemoryManagerHostMapped(addressSpace, mode == MemoryManagerMode.HostMappedUnsafe, invalidAccessHandler);
- processContext = new ArmProcessContext<MemoryManagerHostMapped>(pid, cpuEngine, _gpu, memoryManagerHostMapped, addressSpace.AddressSpaceSize, for64Bit);
- }
- break;
- default:
- throw new InvalidOperationException($"{nameof(mode)} contains an invalid value: {mode}");
- }
- }
- DiskCacheLoadState = processContext.Initialize(_titleIdText, _displayVersion, _diskCacheEnabled, _codeAddress, _codeSize);
- return processContext;
- }
- }
- }
|