|
|
@@ -1,6 +1,5 @@
|
|
|
using ARMeilleure.Memory;
|
|
|
using System;
|
|
|
-using System.Diagnostics;
|
|
|
|
|
|
namespace ARMeilleure.State
|
|
|
{
|
|
|
@@ -14,34 +13,22 @@ namespace ARMeilleure.State
|
|
|
|
|
|
private bool _interrupted;
|
|
|
|
|
|
- private static Stopwatch _tickCounter;
|
|
|
+ private readonly ICounter _counter;
|
|
|
|
|
|
- private static double _hostTickFreq;
|
|
|
+ public ulong Pc => _nativeContext.GetPc();
|
|
|
|
|
|
- public uint CtrEl0 => 0x8444c004;
|
|
|
+ public uint CtrEl0 => 0x8444c004;
|
|
|
public uint DczidEl0 => 0x00000004;
|
|
|
|
|
|
- public ulong CntfrqEl0 { get; set; }
|
|
|
- public ulong CntpctEl0
|
|
|
- {
|
|
|
- get
|
|
|
- {
|
|
|
- double ticks = _tickCounter.ElapsedTicks * _hostTickFreq;
|
|
|
-
|
|
|
- return (ulong)(ticks * CntfrqEl0);
|
|
|
- }
|
|
|
- }
|
|
|
+ public ulong CntfrqEl0 => _counter.Frequency;
|
|
|
+ public ulong CntpctEl0 => _counter.Counter;
|
|
|
|
|
|
// CNTVCT_EL0 = CNTPCT_EL0 - CNTVOFF_EL2
|
|
|
// Since EL2 isn't implemented, CNTVOFF_EL2 = 0
|
|
|
public ulong CntvctEl0 => CntpctEl0;
|
|
|
|
|
|
- public static TimeSpan ElapsedTime => _tickCounter.Elapsed;
|
|
|
- public static long ElapsedTicks => _tickCounter.ElapsedTicks;
|
|
|
- public static double TickFrequency => _hostTickFreq;
|
|
|
-
|
|
|
public long TpidrEl0 { get; set; }
|
|
|
- public long Tpidr { get; set; }
|
|
|
+ public long TpidrroEl0 { get; set; }
|
|
|
|
|
|
public uint Pstate
|
|
|
{
|
|
|
@@ -78,35 +65,38 @@ namespace ARMeilleure.State
|
|
|
private set => _nativeContext.SetRunning(value);
|
|
|
}
|
|
|
|
|
|
- public event EventHandler<EventArgs> Interrupt;
|
|
|
- public event EventHandler<InstExceptionEventArgs> Break;
|
|
|
- public event EventHandler<InstExceptionEventArgs> SupervisorCall;
|
|
|
- public event EventHandler<InstUndefinedEventArgs> Undefined;
|
|
|
-
|
|
|
- static ExecutionContext()
|
|
|
- {
|
|
|
- _hostTickFreq = 1.0 / Stopwatch.Frequency;
|
|
|
-
|
|
|
- _tickCounter = new Stopwatch();
|
|
|
- _tickCounter.Start();
|
|
|
- }
|
|
|
-
|
|
|
- public ExecutionContext(IJitMemoryAllocator allocator)
|
|
|
+ private readonly ExceptionCallbackNoArgs _interruptCallback;
|
|
|
+ private readonly ExceptionCallback _breakCallback;
|
|
|
+ private readonly ExceptionCallback _supervisorCallback;
|
|
|
+ private readonly ExceptionCallback _undefinedCallback;
|
|
|
+
|
|
|
+ public ExecutionContext(
|
|
|
+ IJitMemoryAllocator allocator,
|
|
|
+ ICounter counter,
|
|
|
+ ExceptionCallbackNoArgs interruptCallback = null,
|
|
|
+ ExceptionCallback breakCallback = null,
|
|
|
+ ExceptionCallback supervisorCallback = null,
|
|
|
+ ExceptionCallback undefinedCallback = null)
|
|
|
{
|
|
|
_nativeContext = new NativeContext(allocator);
|
|
|
+ _counter = counter;
|
|
|
+ _interruptCallback = interruptCallback;
|
|
|
+ _breakCallback = breakCallback;
|
|
|
+ _supervisorCallback = supervisorCallback;
|
|
|
+ _undefinedCallback = undefinedCallback;
|
|
|
|
|
|
Running = true;
|
|
|
|
|
|
_nativeContext.SetCounter(MinCountForCheck);
|
|
|
}
|
|
|
|
|
|
- public ulong GetX(int index) => _nativeContext.GetX(index);
|
|
|
- public void SetX(int index, ulong value) => _nativeContext.SetX(index, value);
|
|
|
+ public ulong GetX(int index) => _nativeContext.GetX(index);
|
|
|
+ public void SetX(int index, ulong value) => _nativeContext.SetX(index, value);
|
|
|
|
|
|
- public V128 GetV(int index) => _nativeContext.GetV(index);
|
|
|
+ public V128 GetV(int index) => _nativeContext.GetV(index);
|
|
|
public void SetV(int index, V128 value) => _nativeContext.SetV(index, value);
|
|
|
|
|
|
- public bool GetPstateFlag(PState flag) => _nativeContext.GetPstateFlag(flag);
|
|
|
+ public bool GetPstateFlag(PState flag) => _nativeContext.GetPstateFlag(flag);
|
|
|
public void SetPstateFlag(PState flag, bool value) => _nativeContext.SetPstateFlag(flag, value);
|
|
|
|
|
|
public bool GetFPstateFlag(FPState flag) => _nativeContext.GetFPStateFlag(flag);
|
|
|
@@ -118,7 +108,7 @@ namespace ARMeilleure.State
|
|
|
{
|
|
|
_interrupted = false;
|
|
|
|
|
|
- Interrupt?.Invoke(this, EventArgs.Empty);
|
|
|
+ _interruptCallback?.Invoke(this);
|
|
|
}
|
|
|
|
|
|
_nativeContext.SetCounter(MinCountForCheck);
|
|
|
@@ -131,17 +121,17 @@ namespace ARMeilleure.State
|
|
|
|
|
|
internal void OnBreak(ulong address, int imm)
|
|
|
{
|
|
|
- Break?.Invoke(this, new InstExceptionEventArgs(address, imm));
|
|
|
+ _breakCallback?.Invoke(this, address, imm);
|
|
|
}
|
|
|
|
|
|
internal void OnSupervisorCall(ulong address, int imm)
|
|
|
{
|
|
|
- SupervisorCall?.Invoke(this, new InstExceptionEventArgs(address, imm));
|
|
|
+ _supervisorCallback?.Invoke(this, address, imm);
|
|
|
}
|
|
|
|
|
|
internal void OnUndefined(ulong address, int opCode)
|
|
|
{
|
|
|
- Undefined?.Invoke(this, new InstUndefinedEventArgs(address, opCode));
|
|
|
+ _undefinedCallback?.Invoke(this, address, opCode);
|
|
|
}
|
|
|
|
|
|
public void StopRunning()
|
|
|
@@ -151,16 +141,6 @@ namespace ARMeilleure.State
|
|
|
_nativeContext.SetCounter(0);
|
|
|
}
|
|
|
|
|
|
- public static void SuspendCounter()
|
|
|
- {
|
|
|
- _tickCounter.Stop();
|
|
|
- }
|
|
|
-
|
|
|
- public static void ResumeCounter()
|
|
|
- {
|
|
|
- _tickCounter.Start();
|
|
|
- }
|
|
|
-
|
|
|
public void Dispose()
|
|
|
{
|
|
|
_nativeContext.Dispose();
|