|
|
@ -26,6 +26,9 @@ namespace Core {
|
|
|
|
using Vector = Dynarmic::A64::Vector;
|
|
|
|
using Vector = Dynarmic::A64::Vector;
|
|
|
|
using namespace Common::Literals;
|
|
|
|
using namespace Common::Literals;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
constexpr Dynarmic::HaltReason break_loop = Dynarmic::HaltReason::UserDefined2;
|
|
|
|
|
|
|
|
constexpr Dynarmic::HaltReason svc_call = Dynarmic::HaltReason::UserDefined3;
|
|
|
|
|
|
|
|
|
|
|
|
class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks {
|
|
|
|
class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks {
|
|
|
|
public:
|
|
|
|
public:
|
|
|
|
explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_)
|
|
|
|
explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_)
|
|
|
@ -106,7 +109,7 @@ public:
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
parent.jit->HaltExecution();
|
|
|
|
parent.jit->HaltExecution(Dynarmic::HaltReason::CacheInvalidation);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override {
|
|
|
|
void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override {
|
|
|
@ -126,15 +129,12 @@ public:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CallSVC(u32 swi) override {
|
|
|
|
void CallSVC(u32 swi) override {
|
|
|
|
parent.svc_called = true;
|
|
|
|
|
|
|
|
parent.svc_swi = swi;
|
|
|
|
parent.svc_swi = swi;
|
|
|
|
parent.jit->HaltExecution();
|
|
|
|
parent.jit->HaltExecution(svc_call);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AddTicks(u64 ticks) override {
|
|
|
|
void AddTicks(u64 ticks) override {
|
|
|
|
if (parent.uses_wall_clock) {
|
|
|
|
ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled");
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a
|
|
|
|
// Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a
|
|
|
|
// rough approximation of the amount of executed ticks in the system, it may be thrown off
|
|
|
|
// rough approximation of the amount of executed ticks in the system, it may be thrown off
|
|
|
@ -149,12 +149,8 @@ public:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
u64 GetTicksRemaining() override {
|
|
|
|
u64 GetTicksRemaining() override {
|
|
|
|
if (parent.uses_wall_clock) {
|
|
|
|
ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled");
|
|
|
|
if (!parent.interrupt_handlers[parent.core_index].IsInterrupted()) {
|
|
|
|
|
|
|
|
return minimum_run_cycles;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0U;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::max<s64>(parent.system.CoreTiming().GetDowncount(), 0);
|
|
|
|
return std::max<s64>(parent.system.CoreTiming().GetDowncount(), 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -210,6 +206,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
|
|
|
|
|
|
|
|
|
|
|
|
// Timing
|
|
|
|
// Timing
|
|
|
|
config.wall_clock_cntpct = uses_wall_clock;
|
|
|
|
config.wall_clock_cntpct = uses_wall_clock;
|
|
|
|
|
|
|
|
config.enable_cycle_counting = !uses_wall_clock;
|
|
|
|
|
|
|
|
|
|
|
|
// Code cache size
|
|
|
|
// Code cache size
|
|
|
|
config.code_cache_size = 512_MiB;
|
|
|
|
config.code_cache_size = 512_MiB;
|
|
|
@ -292,13 +289,11 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
|
|
|
|
|
|
|
|
|
|
|
|
void ARM_Dynarmic_64::Run() {
|
|
|
|
void ARM_Dynarmic_64::Run() {
|
|
|
|
while (true) {
|
|
|
|
while (true) {
|
|
|
|
jit->Run();
|
|
|
|
const auto hr = jit->Run();
|
|
|
|
if (!svc_called) {
|
|
|
|
if (Has(hr, svc_call)) {
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
svc_called = false;
|
|
|
|
|
|
|
|
Kernel::Svc::Call(system, svc_swi);
|
|
|
|
Kernel::Svc::Call(system, svc_swi);
|
|
|
|
if (shutdown) {
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Has(hr, break_loop)) {
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -389,8 +384,11 @@ void ARM_Dynarmic_64::LoadContext(const ThreadContext64& ctx) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ARM_Dynarmic_64::PrepareReschedule() {
|
|
|
|
void ARM_Dynarmic_64::PrepareReschedule() {
|
|
|
|
jit->HaltExecution();
|
|
|
|
jit->HaltExecution(break_loop);
|
|
|
|
shutdown = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ARM_Dynarmic_64::SignalInterrupt() {
|
|
|
|
|
|
|
|
jit->HaltExecution(break_loop);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ARM_Dynarmic_64::ClearInstructionCache() {
|
|
|
|
void ARM_Dynarmic_64::ClearInstructionCache() {
|
|
|
|