Pass system into arm interpreter; fix tests

This commit is contained in:
Weiyi Wang 2018-11-21 17:14:42 -05:00
parent c6b3186475
commit e87dc17da2
12 changed files with 48 additions and 38 deletions

View file

@ -137,7 +137,7 @@ public:
parent.jit->HaltExecution(); parent.jit->HaltExecution();
parent.SetPC(pc); parent.SetPC(pc);
Kernel::Thread* thread = Kernel::Thread* thread =
Core::System::GetInstance().Kernel().GetThreadManager().GetCurrentThread(); parent.system.Kernel().GetThreadManager().GetCurrentThread();
parent.SaveContext(thread->context); parent.SaveContext(thread->context);
GDBStub::Break(); GDBStub::Break();
GDBStub::SendTrap(thread, 5); GDBStub::SendTrap(thread, 5);
@ -165,7 +165,7 @@ public:
ARM_Dynarmic::ARM_Dynarmic(Core::System& system, PrivilegeMode initial_mode) ARM_Dynarmic::ARM_Dynarmic(Core::System& system, PrivilegeMode initial_mode)
: system(system), cb(std::make_unique<DynarmicUserCallbacks>(*this)) { : system(system), cb(std::make_unique<DynarmicUserCallbacks>(*this)) {
interpreter_state = std::make_shared<ARMul_State>(initial_mode); interpreter_state = std::make_shared<ARMul_State>(system, initial_mode);
PageTableChanged(); PageTableChanged();
} }

View file

@ -68,14 +68,14 @@ private:
u32 fpexc; u32 fpexc;
}; };
ARM_DynCom::ARM_DynCom(PrivilegeMode initial_mode) { ARM_DynCom::ARM_DynCom(Core::System& system, PrivilegeMode initial_mode) : system(system) {
state = std::make_unique<ARMul_State>(initial_mode); state = std::make_unique<ARMul_State>(system, initial_mode);
} }
ARM_DynCom::~ARM_DynCom() {} ARM_DynCom::~ARM_DynCom() {}
void ARM_DynCom::Run() { void ARM_DynCom::Run() {
ExecuteInstructions(std::max<s64>(Core::System::GetInstance().CoreTiming().GetDowncount(), 0)); ExecuteInstructions(std::max<s64>(system.CoreTiming().GetDowncount(), 0));
} }
void ARM_DynCom::Step() { void ARM_DynCom::Step() {
@ -146,7 +146,7 @@ void ARM_DynCom::SetCP15Register(CP15Register reg, u32 value) {
void ARM_DynCom::ExecuteInstructions(u64 num_instructions) { void ARM_DynCom::ExecuteInstructions(u64 num_instructions) {
state->NumInstrsToExecute = num_instructions; state->NumInstrsToExecute = num_instructions;
unsigned ticks_executed = InterpreterMainLoop(state.get()); unsigned ticks_executed = InterpreterMainLoop(state.get());
Core::System::GetInstance().CoreTiming().AddTicks(ticks_executed); system.CoreTiming().AddTicks(ticks_executed);
state->ServeBreak(); state->ServeBreak();
} }

View file

@ -10,9 +10,13 @@
#include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/arm_regformat.h"
#include "core/arm/skyeye_common/armstate.h" #include "core/arm/skyeye_common/armstate.h"
namespace Core {
struct System;
}
class ARM_DynCom final : public ARM_Interface { class ARM_DynCom final : public ARM_Interface {
public: public:
explicit ARM_DynCom(PrivilegeMode initial_mode); explicit ARM_DynCom(Core::System& system, PrivilegeMode initial_mode);
~ARM_DynCom(); ~ARM_DynCom();
void Run() override; void Run() override;
@ -44,5 +48,6 @@ public:
private: private:
void ExecuteInstructions(u64 num_instructions); void ExecuteInstructions(u64 num_instructions);
Core::System& system;
std::unique_ptr<ARMul_State> state; std::unique_ptr<ARMul_State> state;
}; };

View file

@ -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, static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, const u32 phys_addr,
ARM_INST_PTR& inst_base) { ARM_INST_PTR& inst_base) {
u32 inst_size = 4; 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 // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM
// instruction // instruction
@ -3860,11 +3860,11 @@ SUB_INST : {
SWI_INST : { SWI_INST : {
if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
swi_inst* const inst_cream = (swi_inst*)inst_base->component; 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 = cpu->NumInstrsToExecute =
num_instrs >= cpu->NumInstrsToExecute ? 0 : cpu->NumInstrsToExecute - num_instrs; num_instrs >= cpu->NumInstrsToExecute ? 0 : cpu->NumInstrsToExecute - num_instrs;
num_instrs = 0; 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. // The kernel would call ERET to get here, which clears exclusive memory state.
cpu->UnsetExclusiveMemoryAddress(); cpu->UnsetExclusiveMemoryAddress();
} }

View file

@ -10,7 +10,7 @@
#include "core/core.h" #include "core/core.h"
#include "core/memory.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(); Reset();
ChangePrivilegeMode(initial_mode); ChangePrivilegeMode(initial_mode);
} }
@ -191,13 +191,13 @@ static void CheckMemoryBreakpoint(u32 address, GDBStub::BreakpointType type) {
u8 ARMul_State::ReadMemory8(u32 address) const { u8 ARMul_State::ReadMemory8(u32 address) const {
CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read);
return Core::System::GetInstance().Memory().Read8(address); return system.Memory().Read8(address);
} }
u16 ARMul_State::ReadMemory16(u32 address) const { u16 ARMul_State::ReadMemory16(u32 address) const {
CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read);
u16 data = Core::System::GetInstance().Memory().Read16(address); u16 data = system.Memory().Read16(address);
if (InBigEndianMode()) if (InBigEndianMode())
data = Common::swap16(data); data = Common::swap16(data);
@ -208,7 +208,7 @@ u16 ARMul_State::ReadMemory16(u32 address) const {
u32 ARMul_State::ReadMemory32(u32 address) const { u32 ARMul_State::ReadMemory32(u32 address) const {
CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read);
u32 data = Core::System::GetInstance().Memory().Read32(address); u32 data = system.Memory().Read32(address);
if (InBigEndianMode()) if (InBigEndianMode())
data = Common::swap32(data); data = Common::swap32(data);
@ -219,7 +219,7 @@ u32 ARMul_State::ReadMemory32(u32 address) const {
u64 ARMul_State::ReadMemory64(u32 address) const { u64 ARMul_State::ReadMemory64(u32 address) const {
CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read);
u64 data = Core::System::GetInstance().Memory().Read64(address); u64 data = system.Memory().Read64(address);
if (InBigEndianMode()) if (InBigEndianMode())
data = Common::swap64(data); data = Common::swap64(data);
@ -230,7 +230,7 @@ u64 ARMul_State::ReadMemory64(u32 address) const {
void ARMul_State::WriteMemory8(u32 address, u8 data) { void ARMul_State::WriteMemory8(u32 address, u8 data) {
CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write); 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) { void ARMul_State::WriteMemory16(u32 address, u16 data) {
@ -239,7 +239,7 @@ void ARMul_State::WriteMemory16(u32 address, u16 data) {
if (InBigEndianMode()) if (InBigEndianMode())
data = Common::swap16(data); data = Common::swap16(data);
Core::System::GetInstance().Memory().Write16(address, data); system.Memory().Write16(address, data);
} }
void ARMul_State::WriteMemory32(u32 address, u32 data) { void ARMul_State::WriteMemory32(u32 address, u32 data) {
@ -248,7 +248,7 @@ void ARMul_State::WriteMemory32(u32 address, u32 data) {
if (InBigEndianMode()) if (InBigEndianMode())
data = Common::swap32(data); data = Common::swap32(data);
Core::System::GetInstance().Memory().Write32(address, data); system.Memory().Write32(address, data);
} }
void ARMul_State::WriteMemory64(u32 address, u64 data) { void ARMul_State::WriteMemory64(u32 address, u64 data) {
@ -257,7 +257,7 @@ void ARMul_State::WriteMemory64(u32 address, u64 data) {
if (InBigEndianMode()) if (InBigEndianMode())
data = Common::swap64(data); 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. // Reads from the CP15 registers. Used with implementation of the MRC instruction.
@ -603,9 +603,8 @@ void ARMul_State::ServeBreak() {
if (last_bkpt_hit) { if (last_bkpt_hit) {
Reg[15] = last_bkpt.address; Reg[15] = last_bkpt.address;
} }
Kernel::Thread* thread = Kernel::Thread* thread = system.Kernel().GetThreadManager().GetCurrentThread();
Core::System::GetInstance().Kernel().GetThreadManager().GetCurrentThread(); system.CPU().SaveContext(thread->context);
Core::CPU().SaveContext(thread->context);
if (last_bkpt_hit || GDBStub::GetCpuStepFlag()) { if (last_bkpt_hit || GDBStub::GetCpuStepFlag()) {
last_bkpt_hit = false; last_bkpt_hit = false;
GDBStub::Break(); GDBStub::Break();

View file

@ -23,6 +23,10 @@
#include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/arm_regformat.h"
#include "core/gdbstub/gdbstub.h" #include "core/gdbstub/gdbstub.h"
namespace Core {
class System;
}
// Signal levels // Signal levels
enum { LOW = 0, HIGH = 1, LOWHIGH = 1, HIGHLOW = 2 }; enum { LOW = 0, HIGH = 1, LOWHIGH = 1, HIGHLOW = 2 };
@ -139,7 +143,7 @@ enum {
struct ARMul_State final { struct ARMul_State final {
public: public:
explicit ARMul_State(PrivilegeMode initial_mode); explicit ARMul_State(Core::System& system, PrivilegeMode initial_mode);
void ChangePrivilegeMode(u32 new_mode); void ChangePrivilegeMode(u32 new_mode);
void Reset(); void Reset();
@ -197,6 +201,8 @@ public:
void ServeBreak(); void ServeBreak();
Core::System& system;
std::array<u32, 16> Reg{}; // The current register file std::array<u32, 16> Reg{}; // The current register file
std::array<u32, 2> Reg_usr{}; std::array<u32, 2> Reg_usr{};
std::array<u32, 2> Reg_svc{}; // R13_SVC R14_SVC std::array<u32, 2> Reg_svc{}; // R13_SVC R14_SVC

View file

@ -182,11 +182,11 @@ System::ResultStatus System::Init(EmuWindow& emu_window, u32 system_mode) {
#ifdef ARCHITECTURE_x86_64 #ifdef ARCHITECTURE_x86_64
cpu_core = std::make_unique<ARM_Dynarmic>(*this, USER32MODE); cpu_core = std::make_unique<ARM_Dynarmic>(*this, USER32MODE);
#else #else
cpu_core = std::make_unique<ARM_DynCom>(USER32MODE); cpu_core = std::make_unique<ARM_DynCom>(*this, USER32MODE);
LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
#endif #endif
} else { } else {
cpu_core = std::make_unique<ARM_DynCom>(USER32MODE); cpu_core = std::make_unique<ARM_DynCom>(*this, USER32MODE);
} }
dsp_core = std::make_unique<AudioCore::DspHle>(*memory); dsp_core = std::make_unique<AudioCore::DspHle>(*memory);

View file

@ -246,9 +246,6 @@ private:
/// AppLoader used to load the current executing application /// AppLoader used to load the current executing application
std::unique_ptr<Loader::AppLoader> app_loader; std::unique_ptr<Loader::AppLoader> app_loader;
/// Memory system
std::unique_ptr<Memory::MemorySystem> memory;
/// ARM11 CPU core /// ARM11 CPU core
std::unique_ptr<ARM_Interface> cpu_core; std::unique_ptr<ARM_Interface> cpu_core;
@ -281,6 +278,8 @@ public: // HACK: this is temporary exposed for tests,
// due to WIP kernel refactor causing desync state in memory // due to WIP kernel refactor causing desync state in memory
std::unique_ptr<Kernel::KernelSystem> kernel; std::unique_ptr<Kernel::KernelSystem> kernel;
std::unique_ptr<Timing> timing; std::unique_ptr<Timing> timing;
/// Memory system
std::unique_ptr<Memory::MemorySystem> memory;
private: private:
static System s_instance; static System s_instance;

View file

@ -20,7 +20,8 @@ TestEnvironment::TestEnvironment(bool mutable_memory_)
// so we need to create the kernel object there. // so we need to create the kernel object there.
// Change this when all global states are eliminated. // Change this when all global states are eliminated.
Core::System::GetInstance().timing = std::make_unique<Core::Timing>(); Core::System::GetInstance().timing = std::make_unique<Core::Timing>();
Memory::MemorySystem memory; Core::System::GetInstance().memory = std::make_unique<Memory::MemorySystem>();
Memory::MemorySystem& memory = *Core::System::GetInstance().memory;
Core::System::GetInstance().kernel = std::make_unique<Kernel::KernelSystem>(memory, 0); Core::System::GetInstance().kernel = std::make_unique<Kernel::KernelSystem>(memory, 0);
kernel = Core::System::GetInstance().kernel.get(); kernel = Core::System::GetInstance().kernel.get();

View file

@ -3,8 +3,8 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <catch2/catch.hpp> #include <catch2/catch.hpp>
#include "core/arm/dyncom/arm_dyncom.h" #include "core/arm/dyncom/arm_dyncom.h"
#include "core/core.h"
#include "core/core_timing.h" #include "core/core_timing.h"
#include "tests/core/arm/arm_test_common.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(0, 0xEE321A03); // vadd.f32 s2, s4, s6
test_env.SetMemory32(4, 0xEAFFFFFE); // b +#0 test_env.SetMemory32(4, 0xEAFFFFFE); // b +#0
ARM_DynCom dyncom(USER32MODE); ARM_DynCom dyncom(Core::System::GetInstance(), USER32MODE);
std::vector<VfpTestCase> test_cases{{ std::vector<VfpTestCase> test_cases{{
#include "vfp_vadd_f32.inc" #include "vfp_vadd_f32.inc"

View file

@ -23,8 +23,8 @@ static SharedPtr<Object> MakeObject(Kernel::KernelSystem& kernel) {
TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") { TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") {
// HACK: see comments of member timing // HACK: see comments of member timing
Core::System::GetInstance().timing = std::make_unique<Core::Timing>(); Core::System::GetInstance().timing = std::make_unique<Core::Timing>();
Memory::MemorySystem memory; auto memory = std::make_unique<Memory::MemorySystem>();
Kernel::KernelSystem kernel(memory, 0); Kernel::KernelSystem kernel(*memory, 0);
auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair()); auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair());
HLERequestContext context(std::move(session)); HLERequestContext context(std::move(session));
@ -236,8 +236,8 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
// HACK: see comments of member timing // HACK: see comments of member timing
Core::System::GetInstance().timing = std::make_unique<Core::Timing>(); Core::System::GetInstance().timing = std::make_unique<Core::Timing>();
Memory::MemorySystem memory; auto memory = std::make_unique<Memory::MemorySystem>();
Kernel::KernelSystem kernel(memory, 0); Kernel::KernelSystem kernel(*memory, 0);
auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair()); auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair());
HLERequestContext context(std::move(session)); HLERequestContext context(std::move(session));

View file

@ -13,8 +13,8 @@
TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") { TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") {
// HACK: see comments of member timing // HACK: see comments of member timing
Core::System::GetInstance().timing = std::make_unique<Core::Timing>(); Core::System::GetInstance().timing = std::make_unique<Core::Timing>();
Memory::MemorySystem memory; Core::System::GetInstance().memory = std::make_unique<Memory::MemorySystem>();
Kernel::KernelSystem kernel(memory, 0); Kernel::KernelSystem kernel(*Core::System::GetInstance().memory, 0);
SECTION("these regions should not be mapped on an empty process") { SECTION("these regions should not be mapped on an empty process") {
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false); CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false);