mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Core timing 2.0 (#4913)
* Core::Timing: Add multiple timer, one for each core * revert clang-format; work on tests for CoreTiming * Kernel:: Add support for multiple cores, asserts in HandleSyncRequest because Thread->status == WaitIPC * Add some TRACE_LOGs * fix tests * make some adjustments to qt-debugger, cheats and gdbstub(probably still broken) * Make ARM_Interface::id private, rework ARM_Interface ctor * ReRename TimingManager to Timing for smaler diff * addressed review comments
This commit is contained in:
		
							parent
							
								
									e3dbdcbdff
								
							
						
					
					
						commit
						55ec7031cc
					
				
					 32 changed files with 760 additions and 535 deletions
				
			
		|  | @ -9,10 +9,13 @@ | |||
| #include "common/common_types.h" | ||||
| #include "core/arm/skyeye_common/arm_regformat.h" | ||||
| #include "core/arm/skyeye_common/vfp/asm_vfp.h" | ||||
| #include "core/core_timing.h" | ||||
| 
 | ||||
| /// Generic ARM11 CPU interface
 | ||||
| class ARM_Interface : NonCopyable { | ||||
| public: | ||||
|     explicit ARM_Interface(u32 id, std::shared_ptr<Core::Timing::Timer> timer) | ||||
|         : timer(timer), id(id){}; | ||||
|     virtual ~ARM_Interface() {} | ||||
| 
 | ||||
|     class ThreadContext { | ||||
|  | @ -172,4 +175,18 @@ public: | |||
| 
 | ||||
|     /// Prepare core for thread reschedule (if needed to correctly handle state)
 | ||||
|     virtual void PrepareReschedule() = 0; | ||||
| 
 | ||||
|     std::shared_ptr<Core::Timing::Timer> GetTimer() { | ||||
|         return timer; | ||||
|     } | ||||
| 
 | ||||
|     u32 GetID() const { | ||||
|         return id; | ||||
|     } | ||||
| 
 | ||||
| protected: | ||||
|     std::shared_ptr<Core::Timing::Timer> timer; | ||||
| 
 | ||||
| private: | ||||
|     u32 id; | ||||
| }; | ||||
|  |  | |||
|  | @ -72,8 +72,7 @@ private: | |||
| class DynarmicUserCallbacks final : public Dynarmic::A32::UserCallbacks { | ||||
| public: | ||||
|     explicit DynarmicUserCallbacks(ARM_Dynarmic& parent) | ||||
|         : parent(parent), timing(parent.system.CoreTiming()), svc_context(parent.system), | ||||
|           memory(parent.memory) {} | ||||
|         : parent(parent), svc_context(parent.system), memory(parent.memory) {} | ||||
|     ~DynarmicUserCallbacks() = default; | ||||
| 
 | ||||
|     std::uint8_t MemoryRead8(VAddr vaddr) override { | ||||
|  | @ -137,7 +136,7 @@ public: | |||
|                 parent.jit->HaltExecution(); | ||||
|                 parent.SetPC(pc); | ||||
|                 Kernel::Thread* thread = | ||||
|                     parent.system.Kernel().GetThreadManager().GetCurrentThread(); | ||||
|                     parent.system.Kernel().GetCurrentThreadManager().GetCurrentThread(); | ||||
|                 parent.SaveContext(thread->context); | ||||
|                 GDBStub::Break(); | ||||
|                 GDBStub::SendTrap(thread, 5); | ||||
|  | @ -150,22 +149,23 @@ public: | |||
|     } | ||||
| 
 | ||||
|     void AddTicks(std::uint64_t ticks) override { | ||||
|         timing.AddTicks(ticks); | ||||
|         parent.GetTimer()->AddTicks(ticks); | ||||
|     } | ||||
|     std::uint64_t GetTicksRemaining() override { | ||||
|         s64 ticks = timing.GetDowncount(); | ||||
|         s64 ticks = parent.GetTimer()->GetDowncount(); | ||||
|         return static_cast<u64>(ticks <= 0 ? 0 : ticks); | ||||
|     } | ||||
| 
 | ||||
|     ARM_Dynarmic& parent; | ||||
|     Core::Timing& timing; | ||||
|     Kernel::SVCContext svc_context; | ||||
|     Memory::MemorySystem& memory; | ||||
| }; | ||||
| 
 | ||||
| ARM_Dynarmic::ARM_Dynarmic(Core::System* system, Memory::MemorySystem& memory, | ||||
|                            PrivilegeMode initial_mode) | ||||
|     : system(*system), memory(memory), cb(std::make_unique<DynarmicUserCallbacks>(*this)) { | ||||
|                            PrivilegeMode initial_mode, u32 id, | ||||
|                            std::shared_ptr<Core::Timing::Timer> timer) | ||||
|     : ARM_Interface(id, timer), system(*system), memory(memory), | ||||
|       cb(std::make_unique<DynarmicUserCallbacks>(*this)) { | ||||
|     interpreter_state = std::make_shared<ARMul_State>(system, memory, initial_mode); | ||||
|     PageTableChanged(); | ||||
| } | ||||
|  |  | |||
|  | @ -24,7 +24,8 @@ class DynarmicUserCallbacks; | |||
| 
 | ||||
| class ARM_Dynarmic final : public ARM_Interface { | ||||
| public: | ||||
|     ARM_Dynarmic(Core::System* system, Memory::MemorySystem& memory, PrivilegeMode initial_mode); | ||||
|     ARM_Dynarmic(Core::System* system, Memory::MemorySystem& memory, PrivilegeMode initial_mode, | ||||
|                  u32 id, std::shared_ptr<Core::Timing::Timer> timer); | ||||
|     ~ARM_Dynarmic() override; | ||||
| 
 | ||||
|     void Run() override; | ||||
|  |  | |||
|  | @ -69,8 +69,9 @@ private: | |||
| }; | ||||
| 
 | ||||
| ARM_DynCom::ARM_DynCom(Core::System* system, Memory::MemorySystem& memory, | ||||
|                        PrivilegeMode initial_mode) | ||||
|     : system(system) { | ||||
|                        PrivilegeMode initial_mode, u32 id, | ||||
|                        std::shared_ptr<Core::Timing::Timer> timer) | ||||
|     : ARM_Interface(id, timer), system(system) { | ||||
|     state = std::make_unique<ARMul_State>(system, memory, initial_mode); | ||||
| } | ||||
| 
 | ||||
|  | @ -78,7 +79,7 @@ ARM_DynCom::~ARM_DynCom() {} | |||
| 
 | ||||
| void ARM_DynCom::Run() { | ||||
|     DEBUG_ASSERT(system != nullptr); | ||||
|     ExecuteInstructions(std::max<s64>(system->CoreTiming().GetDowncount(), 0)); | ||||
|     ExecuteInstructions(std::max<s64>(timer->GetDowncount(), 0)); | ||||
| } | ||||
| 
 | ||||
| void ARM_DynCom::Step() { | ||||
|  | @ -150,7 +151,7 @@ void ARM_DynCom::ExecuteInstructions(u64 num_instructions) { | |||
|     state->NumInstrsToExecute = num_instructions; | ||||
|     unsigned ticks_executed = InterpreterMainLoop(state.get()); | ||||
|     if (system != nullptr) { | ||||
|         system->CoreTiming().AddTicks(ticks_executed); | ||||
|         timer->AddTicks(ticks_executed); | ||||
|     } | ||||
|     state->ServeBreak(); | ||||
| } | ||||
|  |  | |||
|  | @ -21,7 +21,8 @@ class MemorySystem; | |||
| class ARM_DynCom final : public ARM_Interface { | ||||
| public: | ||||
|     explicit ARM_DynCom(Core::System* system, Memory::MemorySystem& memory, | ||||
|                         PrivilegeMode initial_mode); | ||||
|                         PrivilegeMode initial_mode, u32 id, | ||||
|                         std::shared_ptr<Core::Timing::Timer> timer); | ||||
|     ~ARM_DynCom() override; | ||||
| 
 | ||||
|     void Run() override; | ||||
|  |  | |||
|  | @ -3865,7 +3865,7 @@ SWI_INST : { | |||
|     if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { | ||||
|         DEBUG_ASSERT(cpu->system != nullptr); | ||||
|         swi_inst* const inst_cream = (swi_inst*)inst_base->component; | ||||
|         cpu->system->CoreTiming().AddTicks(num_instrs); | ||||
|         cpu->system->GetRunningCore().GetTimer()->AddTicks(num_instrs); | ||||
|         cpu->NumInstrsToExecute = | ||||
|             num_instrs >= cpu->NumInstrsToExecute ? 0 : cpu->NumInstrsToExecute - num_instrs; | ||||
|         num_instrs = 0; | ||||
|  |  | |||
|  | @ -607,8 +607,8 @@ void ARMul_State::ServeBreak() { | |||
|     } | ||||
| 
 | ||||
|     DEBUG_ASSERT(system != nullptr); | ||||
|     Kernel::Thread* thread = system->Kernel().GetThreadManager().GetCurrentThread(); | ||||
|     system->CPU().SaveContext(thread->context); | ||||
|     Kernel::Thread* thread = system->Kernel().GetCurrentThreadManager().GetCurrentThread(); | ||||
|     system->GetRunningCore().SaveContext(thread->context); | ||||
| 
 | ||||
|     if (last_bkpt_hit || GDBStub::IsMemoryBreak() || GDBStub::GetCpuStepFlag()) { | ||||
|         last_bkpt_hit = false; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue