mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2026-05-25 10:52:33 +00:00
This should probably improve current fix unless somehow this doesn't
This commit is contained in:
parent
442caebc9e
commit
3943449f7c
1 changed files with 75 additions and 50 deletions
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
[SupportedOSPlatform("macos")]
|
||||
|
|
@ -17,23 +18,26 @@ namespace Ryujinx.Cpu.AppleHv
|
|||
|
||||
public ulong ThreadUid { get; set; }
|
||||
|
||||
// Shadow cache
|
||||
// Full shadow state
|
||||
private readonly ulong[] _x = new ulong[32];
|
||||
private readonly V128[] _v = new V128[32];
|
||||
|
||||
private ulong _pc;
|
||||
private uint _pstate;
|
||||
private ulong _elrEl1;
|
||||
private ulong _esrEl1;
|
||||
private ulong _tpidrEl0;
|
||||
private ulong _tpidrroEl0;
|
||||
private ulong _fpcr;
|
||||
private ulong _fpsr;
|
||||
private uint _pstate;
|
||||
|
||||
private bool _cacheInitialized;
|
||||
private long _lastWarningTicks;
|
||||
private long _fallbackCount;
|
||||
private long _lastWarningTicks;
|
||||
private const long WarningCooldownTicks = 1_000_000_000; // 1 second
|
||||
|
||||
private readonly ulong _vcpu;
|
||||
private int _interruptRequested;
|
||||
|
||||
static HvExecutionContextVcpu()
|
||||
{
|
||||
_setSimdFpRegFuncMem = new MemoryBlock(MemoryBlock.GetPageSize());
|
||||
|
|
@ -49,9 +53,6 @@ namespace Ryujinx.Cpu.AppleHv
|
|||
}
|
||||
}
|
||||
|
||||
private readonly ulong _vcpu;
|
||||
private int _interruptRequested;
|
||||
|
||||
public HvExecutionContextVcpu(ulong vcpu)
|
||||
{
|
||||
_vcpu = vcpu;
|
||||
|
|
@ -63,12 +64,15 @@ namespace Ryujinx.Cpu.AppleHv
|
|||
InitializeCacheDefaults();
|
||||
_fallbackCount = 0;
|
||||
_lastWarningTicks = 0;
|
||||
_interruptRequested = 0;
|
||||
}
|
||||
|
||||
private void InitializeCacheDefaults()
|
||||
{
|
||||
_pstate = 0x80000000;
|
||||
_cacheInitialized = true;
|
||||
_pc = 0;
|
||||
Array.Clear(_x, 0, _x.Length);
|
||||
Array.Clear(_v, 0, _v.Length);
|
||||
}
|
||||
|
||||
private void LogHvWarning(string message)
|
||||
|
|
@ -115,16 +119,19 @@ namespace Ryujinx.Cpu.AppleHv
|
|||
{
|
||||
get
|
||||
{
|
||||
var resP = HvApi.hv_vcpu_get_reg(_vcpu, HvReg.CPSR, out ulong valP);
|
||||
if (resP == HvResult.BadArgument) { _fallbackCount++; return _pstate; }
|
||||
resP.ThrowOnError();
|
||||
_pstate = (uint)valP;
|
||||
return _pstate;
|
||||
var res = HvApi.hv_vcpu_get_reg(_vcpu, HvReg.CPSR, out ulong val);
|
||||
if (res == HvResult.BadArgument)
|
||||
{
|
||||
_fallbackCount++;
|
||||
return _pstate;
|
||||
}
|
||||
res.ThrowOnError();
|
||||
return _pstate = (uint)val;
|
||||
}
|
||||
set
|
||||
{
|
||||
var resP = HvApi.hv_vcpu_set_reg(_vcpu, HvReg.CPSR, value);
|
||||
if (resP != HvResult.BadArgument) resP.ThrowOnError();
|
||||
var res = HvApi.hv_vcpu_set_reg(_vcpu, HvReg.CPSR, value);
|
||||
if (res != HvResult.BadArgument) res.ThrowOnError();
|
||||
_pstate = value;
|
||||
}
|
||||
}
|
||||
|
|
@ -145,34 +152,43 @@ namespace Ryujinx.Cpu.AppleHv
|
|||
{
|
||||
if (index == 31)
|
||||
{
|
||||
var resSp = HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.SP_EL0, out ulong valSp);
|
||||
if (resSp == HvResult.BadArgument) { _fallbackCount++; return _x[31]; }
|
||||
resSp.ThrowOnError();
|
||||
_x[31] = valSp;
|
||||
return valSp;
|
||||
var res = HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.SP_EL0, out ulong val);
|
||||
if (res == HvResult.BadArgument)
|
||||
{
|
||||
_fallbackCount++;
|
||||
LogHvWarning("PAC failure on SP_EL0");
|
||||
return _x[31];
|
||||
}
|
||||
res.ThrowOnError();
|
||||
return _x[31] = val;
|
||||
}
|
||||
|
||||
if (index < 0 || index > 30) return 0;
|
||||
|
||||
var resX = HvApi.hv_vcpu_get_reg(_vcpu, HvReg.X0 + (uint)index, out ulong valX);
|
||||
if (resX == HvResult.BadArgument) { _fallbackCount++; return _x[index]; }
|
||||
if (resX == HvResult.BadArgument)
|
||||
{
|
||||
_fallbackCount++;
|
||||
if (_fallbackCount % 128 == 0)
|
||||
LogHvWarning($"PAC failure on X{index}");
|
||||
return _x[index];
|
||||
}
|
||||
resX.ThrowOnError();
|
||||
_x[index] = valX;
|
||||
return valX;
|
||||
return _x[index] = valX;
|
||||
}
|
||||
|
||||
public void SetX(int index, ulong value)
|
||||
{
|
||||
if (index == 31)
|
||||
{
|
||||
var resSp = HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.SP_EL0, value);
|
||||
if (resSp != HvResult.BadArgument) resSp.ThrowOnError();
|
||||
var res = HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.SP_EL0, value);
|
||||
if (res != HvResult.BadArgument) res.ThrowOnError();
|
||||
_x[31] = value;
|
||||
}
|
||||
else if (index >= 0 && index <= 30)
|
||||
{
|
||||
var resX = HvApi.hv_vcpu_set_reg(_vcpu, HvReg.X0 + (uint)index, value);
|
||||
if (resX != HvResult.BadArgument) resX.ThrowOnError();
|
||||
var res = HvApi.hv_vcpu_set_reg(_vcpu, HvReg.X0 + (uint)index, value);
|
||||
if (res != HvResult.BadArgument) res.ThrowOnError();
|
||||
_x[index] = value;
|
||||
}
|
||||
}
|
||||
|
|
@ -181,53 +197,60 @@ namespace Ryujinx.Cpu.AppleHv
|
|||
{
|
||||
if (index < 0 || index > 31) return V128.Zero;
|
||||
|
||||
var resV = HvApi.hv_vcpu_get_simd_fp_reg(_vcpu, HvSimdFPReg.Q0 + (uint)index, out HvSimdFPUchar16 simdVal);
|
||||
if (resV == HvResult.BadArgument) { _fallbackCount++; return _v[index]; }
|
||||
if (resV != HvResult.Success) resV.ThrowOnError();
|
||||
|
||||
var vec = new V128(simdVal.Low, simdVal.High);
|
||||
_v[index] = vec;
|
||||
return vec;
|
||||
var res = HvApi.hv_vcpu_get_simd_fp_reg(_vcpu, HvSimdFPReg.Q0 + (uint)index, out HvSimdFPUchar16 val);
|
||||
if (res == HvResult.BadArgument)
|
||||
{
|
||||
_fallbackCount++;
|
||||
return _v[index];
|
||||
}
|
||||
res.ThrowOnError();
|
||||
return _v[index] = new V128(val.Low, val.High);
|
||||
}
|
||||
|
||||
public void SetV(int index, V128 value)
|
||||
{
|
||||
if (index < 0 || index > 31) return;
|
||||
|
||||
var resV = _setSimdFpReg(_vcpu, HvSimdFPReg.Q0 + (uint)index, value, _setSimdFpRegNativePtr);
|
||||
if (resV != HvResult.BadArgument) resV.ThrowOnError();
|
||||
var res = _setSimdFpReg(_vcpu, HvSimdFPReg.Q0 + (uint)index, value, _setSimdFpRegNativePtr);
|
||||
if (res != HvResult.BadArgument) res.ThrowOnError();
|
||||
_v[index] = value;
|
||||
}
|
||||
|
||||
private ulong GetRegCached(HvReg reg, ref ulong cached)
|
||||
{
|
||||
var resG = HvApi.hv_vcpu_get_reg(_vcpu, reg, out ulong valG);
|
||||
if (resG == HvResult.BadArgument) { _fallbackCount++; return cached; }
|
||||
resG.ThrowOnError();
|
||||
cached = valG;
|
||||
return valG;
|
||||
var res = HvApi.hv_vcpu_get_reg(_vcpu, reg, out ulong val);
|
||||
if (res == HvResult.BadArgument)
|
||||
{
|
||||
_fallbackCount++;
|
||||
return cached;
|
||||
}
|
||||
res.ThrowOnError();
|
||||
return cached = val;
|
||||
}
|
||||
|
||||
private void SetRegCached(HvReg reg, ulong value, ref ulong cached)
|
||||
{
|
||||
var resS = HvApi.hv_vcpu_set_reg(_vcpu, reg, value);
|
||||
if (resS != HvResult.BadArgument) resS.ThrowOnError();
|
||||
var res = HvApi.hv_vcpu_set_reg(_vcpu, reg, value);
|
||||
if (res != HvResult.BadArgument) res.ThrowOnError();
|
||||
cached = value;
|
||||
}
|
||||
|
||||
private ulong GetSysRegCached(HvSysReg reg, ref ulong cached)
|
||||
{
|
||||
var resSys = HvApi.hv_vcpu_get_sys_reg(_vcpu, reg, out ulong valSys);
|
||||
if (resSys == HvResult.BadArgument) { _fallbackCount++; return cached; }
|
||||
resSys.ThrowOnError();
|
||||
cached = valSys;
|
||||
return valSys;
|
||||
var res = HvApi.hv_vcpu_get_sys_reg(_vcpu, reg, out ulong val);
|
||||
if (res == HvResult.BadArgument)
|
||||
{
|
||||
_fallbackCount++;
|
||||
return cached;
|
||||
}
|
||||
res.ThrowOnError();
|
||||
return cached = val;
|
||||
}
|
||||
|
||||
private void SetSysRegCached(HvSysReg reg, ulong value, ref ulong cached)
|
||||
{
|
||||
var resSys = HvApi.hv_vcpu_set_sys_reg(_vcpu, reg, value);
|
||||
if (resSys != HvResult.BadArgument) resSys.ThrowOnError();
|
||||
var res = HvApi.hv_vcpu_set_sys_reg(_vcpu, reg, value);
|
||||
if (res != HvResult.BadArgument) res.ThrowOnError();
|
||||
cached = value;
|
||||
}
|
||||
|
||||
|
|
@ -244,5 +267,7 @@ namespace Ryujinx.Cpu.AppleHv
|
|||
{
|
||||
return Interlocked.Exchange(ref _interruptRequested, 0) != 0;
|
||||
}
|
||||
|
||||
public long GetFallbackCount() => _fallbackCount;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue