From e87dc17da2dc32d128ee72b65b602d27cf46a8a7 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Wed, 21 Nov 2018 17:14:42 -0500 Subject: [PATCH] Pass system into arm interpreter; fix tests --- src/core/arm/dynarmic/arm_dynarmic.cpp | 4 ++-- src/core/arm/dyncom/arm_dyncom.cpp | 8 +++---- src/core/arm/dyncom/arm_dyncom.h | 7 +++++- .../arm/dyncom/arm_dyncom_interpreter.cpp | 6 ++--- src/core/arm/skyeye_common/armstate.cpp | 23 +++++++++---------- src/core/arm/skyeye_common/armstate.h | 8 ++++++- src/core/core.cpp | 4 ++-- src/core/core.h | 5 ++-- src/tests/core/arm/arm_test_common.cpp | 3 ++- .../core/arm/dyncom/arm_dyncom_vfp_tests.cpp | 6 ++--- src/tests/core/hle/kernel/hle_ipc.cpp | 8 +++---- src/tests/core/memory/memory.cpp | 4 ++-- 12 files changed, 48 insertions(+), 38 deletions(-) diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 2c60dbac9..62c63f9ac 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -137,7 +137,7 @@ public: parent.jit->HaltExecution(); parent.SetPC(pc); Kernel::Thread* thread = - Core::System::GetInstance().Kernel().GetThreadManager().GetCurrentThread(); + parent.system.Kernel().GetThreadManager().GetCurrentThread(); parent.SaveContext(thread->context); GDBStub::Break(); GDBStub::SendTrap(thread, 5); @@ -165,7 +165,7 @@ public: ARM_Dynarmic::ARM_Dynarmic(Core::System& system, PrivilegeMode initial_mode) : system(system), cb(std::make_unique(*this)) { - interpreter_state = std::make_shared(initial_mode); + interpreter_state = std::make_shared(system, initial_mode); PageTableChanged(); } diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index d3113632c..4ee22dfdd 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp @@ -68,14 +68,14 @@ private: u32 fpexc; }; -ARM_DynCom::ARM_DynCom(PrivilegeMode initial_mode) { - state = std::make_unique(initial_mode); +ARM_DynCom::ARM_DynCom(Core::System& system, PrivilegeMode initial_mode) : system(system) { + state = std::make_unique(system, initial_mode); } ARM_DynCom::~ARM_DynCom() {} void ARM_DynCom::Run() { - ExecuteInstructions(std::max(Core::System::GetInstance().CoreTiming().GetDowncount(), 0)); + ExecuteInstructions(std::max(system.CoreTiming().GetDowncount(), 0)); } void ARM_DynCom::Step() { @@ -146,7 +146,7 @@ void ARM_DynCom::SetCP15Register(CP15Register reg, u32 value) { void ARM_DynCom::ExecuteInstructions(u64 num_instructions) { state->NumInstrsToExecute = num_instructions; unsigned ticks_executed = InterpreterMainLoop(state.get()); - Core::System::GetInstance().CoreTiming().AddTicks(ticks_executed); + system.CoreTiming().AddTicks(ticks_executed); state->ServeBreak(); } diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index 38d6a33c7..83366e09d 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h @@ -10,9 +10,13 @@ #include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/armstate.h" +namespace Core { +struct System; +} + class ARM_DynCom final : public ARM_Interface { public: - explicit ARM_DynCom(PrivilegeMode initial_mode); + explicit ARM_DynCom(Core::System& system, PrivilegeMode initial_mode); ~ARM_DynCom(); void Run() override; @@ -44,5 +48,6 @@ public: private: void ExecuteInstructions(u64 num_instructions); + Core::System& system; std::unique_ptr state; }; diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index adb126b95..0a50d31b6 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp @@ -811,7 +811,7 @@ MICROPROFILE_DEFINE(DynCom_Decode, "DynCom", "Decode", MP_RGB(255, 64, 64)); static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, const u32 phys_addr, ARM_INST_PTR& inst_base) { u32 inst_size = 4; - u32 inst = Core::System::GetInstance().Memory().Read32(phys_addr & 0xFFFFFFFC); + u32 inst = cpu->system.Memory().Read32(phys_addr & 0xFFFFFFFC); // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM // instruction @@ -3860,11 +3860,11 @@ SUB_INST : { SWI_INST : { if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { swi_inst* const inst_cream = (swi_inst*)inst_base->component; - Core::System::GetInstance().CoreTiming().AddTicks(num_instrs); + cpu->system.CoreTiming().AddTicks(num_instrs); cpu->NumInstrsToExecute = num_instrs >= cpu->NumInstrsToExecute ? 0 : cpu->NumInstrsToExecute - num_instrs; num_instrs = 0; - Kernel::SVCContext{Core::System::GetInstance()}.CallSVC(inst_cream->num & 0xFFFF); + Kernel::SVCContext{cpu->system}.CallSVC(inst_cream->num & 0xFFFF); // The kernel would call ERET to get here, which clears exclusive memory state. cpu->UnsetExclusiveMemoryAddress(); } diff --git a/src/core/arm/skyeye_common/armstate.cpp b/src/core/arm/skyeye_common/armstate.cpp index 9c29783fc..27a7540cc 100644 --- a/src/core/arm/skyeye_common/armstate.cpp +++ b/src/core/arm/skyeye_common/armstate.cpp @@ -10,7 +10,7 @@ #include "core/core.h" #include "core/memory.h" -ARMul_State::ARMul_State(PrivilegeMode initial_mode) { +ARMul_State::ARMul_State(Core::System& system, PrivilegeMode initial_mode) : system(system) { Reset(); ChangePrivilegeMode(initial_mode); } @@ -191,13 +191,13 @@ static void CheckMemoryBreakpoint(u32 address, GDBStub::BreakpointType type) { u8 ARMul_State::ReadMemory8(u32 address) const { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); - return Core::System::GetInstance().Memory().Read8(address); + return system.Memory().Read8(address); } u16 ARMul_State::ReadMemory16(u32 address) const { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); - u16 data = Core::System::GetInstance().Memory().Read16(address); + u16 data = system.Memory().Read16(address); if (InBigEndianMode()) data = Common::swap16(data); @@ -208,7 +208,7 @@ u16 ARMul_State::ReadMemory16(u32 address) const { u32 ARMul_State::ReadMemory32(u32 address) const { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); - u32 data = Core::System::GetInstance().Memory().Read32(address); + u32 data = system.Memory().Read32(address); if (InBigEndianMode()) data = Common::swap32(data); @@ -219,7 +219,7 @@ u32 ARMul_State::ReadMemory32(u32 address) const { u64 ARMul_State::ReadMemory64(u32 address) const { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); - u64 data = Core::System::GetInstance().Memory().Read64(address); + u64 data = system.Memory().Read64(address); if (InBigEndianMode()) data = Common::swap64(data); @@ -230,7 +230,7 @@ u64 ARMul_State::ReadMemory64(u32 address) const { void ARMul_State::WriteMemory8(u32 address, u8 data) { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write); - Core::System::GetInstance().Memory().Write8(address, data); + system.Memory().Write8(address, data); } void ARMul_State::WriteMemory16(u32 address, u16 data) { @@ -239,7 +239,7 @@ void ARMul_State::WriteMemory16(u32 address, u16 data) { if (InBigEndianMode()) data = Common::swap16(data); - Core::System::GetInstance().Memory().Write16(address, data); + system.Memory().Write16(address, data); } void ARMul_State::WriteMemory32(u32 address, u32 data) { @@ -248,7 +248,7 @@ void ARMul_State::WriteMemory32(u32 address, u32 data) { if (InBigEndianMode()) data = Common::swap32(data); - Core::System::GetInstance().Memory().Write32(address, data); + system.Memory().Write32(address, data); } void ARMul_State::WriteMemory64(u32 address, u64 data) { @@ -257,7 +257,7 @@ void ARMul_State::WriteMemory64(u32 address, u64 data) { if (InBigEndianMode()) data = Common::swap64(data); - Core::System::GetInstance().Memory().Write64(address, data); + system.Memory().Write64(address, data); } // Reads from the CP15 registers. Used with implementation of the MRC instruction. @@ -603,9 +603,8 @@ void ARMul_State::ServeBreak() { if (last_bkpt_hit) { Reg[15] = last_bkpt.address; } - Kernel::Thread* thread = - Core::System::GetInstance().Kernel().GetThreadManager().GetCurrentThread(); - Core::CPU().SaveContext(thread->context); + Kernel::Thread* thread = system.Kernel().GetThreadManager().GetCurrentThread(); + system.CPU().SaveContext(thread->context); if (last_bkpt_hit || GDBStub::GetCpuStepFlag()) { last_bkpt_hit = false; GDBStub::Break(); diff --git a/src/core/arm/skyeye_common/armstate.h b/src/core/arm/skyeye_common/armstate.h index 2f99b738b..9327dc88c 100644 --- a/src/core/arm/skyeye_common/armstate.h +++ b/src/core/arm/skyeye_common/armstate.h @@ -23,6 +23,10 @@ #include "core/arm/skyeye_common/arm_regformat.h" #include "core/gdbstub/gdbstub.h" +namespace Core { +class System; +} + // Signal levels enum { LOW = 0, HIGH = 1, LOWHIGH = 1, HIGHLOW = 2 }; @@ -139,7 +143,7 @@ enum { struct ARMul_State final { public: - explicit ARMul_State(PrivilegeMode initial_mode); + explicit ARMul_State(Core::System& system, PrivilegeMode initial_mode); void ChangePrivilegeMode(u32 new_mode); void Reset(); @@ -197,6 +201,8 @@ public: void ServeBreak(); + Core::System& system; + std::array Reg{}; // The current register file std::array Reg_usr{}; std::array Reg_svc{}; // R13_SVC R14_SVC diff --git a/src/core/core.cpp b/src/core/core.cpp index dc5c6236f..c5c56d11a 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -182,11 +182,11 @@ System::ResultStatus System::Init(EmuWindow& emu_window, u32 system_mode) { #ifdef ARCHITECTURE_x86_64 cpu_core = std::make_unique(*this, USER32MODE); #else - cpu_core = std::make_unique(USER32MODE); + cpu_core = std::make_unique(*this, USER32MODE); LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); #endif } else { - cpu_core = std::make_unique(USER32MODE); + cpu_core = std::make_unique(*this, USER32MODE); } dsp_core = std::make_unique(*memory); diff --git a/src/core/core.h b/src/core/core.h index aba5a2faa..be9a303f9 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -246,9 +246,6 @@ private: /// AppLoader used to load the current executing application std::unique_ptr app_loader; - /// Memory system - std::unique_ptr memory; - /// ARM11 CPU core std::unique_ptr cpu_core; @@ -281,6 +278,8 @@ public: // HACK: this is temporary exposed for tests, // due to WIP kernel refactor causing desync state in memory std::unique_ptr kernel; std::unique_ptr timing; + /// Memory system + std::unique_ptr memory; private: static System s_instance; diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp index bdd158dd0..c316f8f36 100644 --- a/src/tests/core/arm/arm_test_common.cpp +++ b/src/tests/core/arm/arm_test_common.cpp @@ -20,7 +20,8 @@ TestEnvironment::TestEnvironment(bool mutable_memory_) // so we need to create the kernel object there. // Change this when all global states are eliminated. Core::System::GetInstance().timing = std::make_unique(); - Memory::MemorySystem memory; + Core::System::GetInstance().memory = std::make_unique(); + Memory::MemorySystem& memory = *Core::System::GetInstance().memory; Core::System::GetInstance().kernel = std::make_unique(memory, 0); kernel = Core::System::GetInstance().kernel.get(); diff --git a/src/tests/core/arm/dyncom/arm_dyncom_vfp_tests.cpp b/src/tests/core/arm/dyncom/arm_dyncom_vfp_tests.cpp index 848ed2c3c..6eb1a3b7f 100644 --- a/src/tests/core/arm/dyncom/arm_dyncom_vfp_tests.cpp +++ b/src/tests/core/arm/dyncom/arm_dyncom_vfp_tests.cpp @@ -3,8 +3,8 @@ // Refer to the license.txt file included. #include - #include "core/arm/dyncom/arm_dyncom.h" +#include "core/core.h" #include "core/core_timing.h" #include "tests/core/arm/arm_test_common.h" @@ -23,7 +23,7 @@ TEST_CASE("ARM_DynCom (vfp): vadd", "[arm_dyncom]") { test_env.SetMemory32(0, 0xEE321A03); // vadd.f32 s2, s4, s6 test_env.SetMemory32(4, 0xEAFFFFFE); // b +#0 - ARM_DynCom dyncom(USER32MODE); + ARM_DynCom dyncom(Core::System::GetInstance(), USER32MODE); std::vector test_cases{{ #include "vfp_vadd_f32.inc" @@ -47,4 +47,4 @@ TEST_CASE("ARM_DynCom (vfp): vadd", "[arm_dyncom]") { } } -} // namespace ArmTests \ No newline at end of file +} // namespace ArmTests diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index 1167cd126..c22c66837 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -23,8 +23,8 @@ static SharedPtr MakeObject(Kernel::KernelSystem& kernel) { TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") { // HACK: see comments of member timing Core::System::GetInstance().timing = std::make_unique(); - Memory::MemorySystem memory; - Kernel::KernelSystem kernel(memory, 0); + auto memory = std::make_unique(); + Kernel::KernelSystem kernel(*memory, 0); auto session = std::get>(kernel.CreateSessionPair()); HLERequestContext context(std::move(session)); @@ -236,8 +236,8 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { // HACK: see comments of member timing Core::System::GetInstance().timing = std::make_unique(); - Memory::MemorySystem memory; - Kernel::KernelSystem kernel(memory, 0); + auto memory = std::make_unique(); + Kernel::KernelSystem kernel(*memory, 0); auto session = std::get>(kernel.CreateSessionPair()); HLERequestContext context(std::move(session)); diff --git a/src/tests/core/memory/memory.cpp b/src/tests/core/memory/memory.cpp index 376eb283a..ee795e63d 100644 --- a/src/tests/core/memory/memory.cpp +++ b/src/tests/core/memory/memory.cpp @@ -13,8 +13,8 @@ TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") { // HACK: see comments of member timing Core::System::GetInstance().timing = std::make_unique(); - Memory::MemorySystem memory; - Kernel::KernelSystem kernel(memory, 0); + Core::System::GetInstance().memory = std::make_unique(); + Kernel::KernelSystem kernel(*Core::System::GetInstance().memory, 0); SECTION("these regions should not be mapped on an empty process") { auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false);