Explorar o código

Merge pull request #6371 from degasus/drop_ExceptionalExit

core/arm_interface: Call SVC after end of dynarmic block.
bunnei %!s(int64=5) %!d(string=hai) anos
pai
achega
420b1f89d3

+ 0 - 3
src/core/arm/arm_interface.h

@@ -65,9 +65,6 @@ public:
     /// Step CPU by one instruction
     virtual void Step() = 0;
 
-    /// Exits execution from a callback, the callback must rewind the stack
-    virtual void ExceptionalExit() = 0;
-
     /// Clear all instruction cache
     virtual void ClearInstructionCache() = 0;
 

+ 15 - 6
src/core/arm/dynarmic/arm_dynarmic_32.cpp

@@ -78,7 +78,9 @@ public:
     }
 
     void CallSVC(u32 swi) override {
-        Kernel::Svc::Call(parent.system, swi);
+        parent.svc_called = true;
+        parent.svc_swi = swi;
+        parent.jit->HaltExecution();
     }
 
     void AddTicks(u64 ticks) override {
@@ -187,11 +189,17 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
 }
 
 void ARM_Dynarmic_32::Run() {
-    jit->Run();
-}
-
-void ARM_Dynarmic_32::ExceptionalExit() {
-    jit->ExceptionalExit();
+    while (true) {
+        jit->Run();
+        if (!svc_called) {
+            break;
+        }
+        svc_called = false;
+        Kernel::Svc::Call(system, svc_swi);
+        if (shutdown) {
+            break;
+        }
+    }
 }
 
 void ARM_Dynarmic_32::Step() {
@@ -275,6 +283,7 @@ void ARM_Dynarmic_32::LoadContext(const ThreadContext32& ctx) {
 
 void ARM_Dynarmic_32::PrepareReschedule() {
     jit->HaltExecution();
+    shutdown = true;
 }
 
 void ARM_Dynarmic_32::ClearInstructionCache() {

+ 6 - 1
src/core/arm/dynarmic/arm_dynarmic_32.h

@@ -42,7 +42,6 @@ public:
     u32 GetPSTATE() const override;
     void SetPSTATE(u32 pstate) override;
     void Run() override;
-    void ExceptionalExit() override;
     void Step() override;
     VAddr GetTlsAddress() const override;
     void SetTlsAddress(VAddr address) override;
@@ -82,6 +81,12 @@ private:
     std::size_t core_index;
     DynarmicExclusiveMonitor& exclusive_monitor;
     std::shared_ptr<Dynarmic::A32::Jit> jit;
+
+    // SVC callback
+    u32 svc_swi{};
+    bool svc_called{};
+
+    bool shutdown{};
 };
 
 } // namespace Core

+ 15 - 6
src/core/arm/dynarmic/arm_dynarmic_64.cpp

@@ -102,7 +102,9 @@ public:
     }
 
     void CallSVC(u32 swi) override {
-        Kernel::Svc::Call(parent.system, swi);
+        parent.svc_called = true;
+        parent.svc_swi = swi;
+        parent.jit->HaltExecution();
     }
 
     void AddTicks(u64 ticks) override {
@@ -227,11 +229,17 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
 }
 
 void ARM_Dynarmic_64::Run() {
-    jit->Run();
-}
-
-void ARM_Dynarmic_64::ExceptionalExit() {
-    jit->ExceptionalExit();
+    while (true) {
+        jit->Run();
+        if (!svc_called) {
+            break;
+        }
+        svc_called = false;
+        Kernel::Svc::Call(system, svc_swi);
+        if (shutdown) {
+            break;
+        }
+    }
 }
 
 void ARM_Dynarmic_64::Step() {
@@ -320,6 +328,7 @@ void ARM_Dynarmic_64::LoadContext(const ThreadContext64& ctx) {
 
 void ARM_Dynarmic_64::PrepareReschedule() {
     jit->HaltExecution();
+    shutdown = true;
 }
 
 void ARM_Dynarmic_64::ClearInstructionCache() {

+ 6 - 1
src/core/arm/dynarmic/arm_dynarmic_64.h

@@ -40,7 +40,6 @@ public:
     void SetPSTATE(u32 pstate) override;
     void Run() override;
     void Step() override;
-    void ExceptionalExit() override;
     VAddr GetTlsAddress() const override;
     void SetTlsAddress(VAddr address) override;
     void SetTPIDR_EL0(u64 value) override;
@@ -75,6 +74,12 @@ private:
     DynarmicExclusiveMonitor& exclusive_monitor;
 
     std::shared_ptr<Dynarmic::A64::Jit> jit;
+
+    // SVC callback
+    u32 svc_swi{};
+    bool svc_called{};
+
+    bool shutdown{};
 };
 
 } // namespace Core

+ 0 - 1
src/core/hle/kernel/k_scheduler.cpp

@@ -659,7 +659,6 @@ void KScheduler::Unload(KThread* thread) {
 
     if (thread) {
         if (thread->IsCallingSvc()) {
-            system.ArmInterface(core_id).ExceptionalExit();
             thread->ClearIsCallingSvc();
         }
         if (!thread->IsTerminationRequested()) {