mirror of
https://github.com/citra-emu/citra.git
synced 2024-12-19 17:31:05 +00:00
Pass system into arm interpreter; fix tests
This commit is contained in:
parent
c6b3186475
commit
e87dc17da2
@ -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<DynarmicUserCallbacks>(*this)) {
|
||||
interpreter_state = std::make_shared<ARMul_State>(initial_mode);
|
||||
interpreter_state = std::make_shared<ARMul_State>(system, initial_mode);
|
||||
PageTableChanged();
|
||||
}
|
||||
|
||||
|
@ -68,14 +68,14 @@ private:
|
||||
u32 fpexc;
|
||||
};
|
||||
|
||||
ARM_DynCom::ARM_DynCom(PrivilegeMode initial_mode) {
|
||||
state = std::make_unique<ARMul_State>(initial_mode);
|
||||
ARM_DynCom::ARM_DynCom(Core::System& system, PrivilegeMode initial_mode) : system(system) {
|
||||
state = std::make_unique<ARMul_State>(system, initial_mode);
|
||||
}
|
||||
|
||||
ARM_DynCom::~ARM_DynCom() {}
|
||||
|
||||
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() {
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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<ARMul_State> state;
|
||||
};
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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<u32, 16> Reg{}; // The current register file
|
||||
std::array<u32, 2> Reg_usr{};
|
||||
std::array<u32, 2> Reg_svc{}; // R13_SVC R14_SVC
|
||||
|
@ -182,11 +182,11 @@ System::ResultStatus System::Init(EmuWindow& emu_window, u32 system_mode) {
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
cpu_core = std::make_unique<ARM_Dynarmic>(*this, USER32MODE);
|
||||
#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");
|
||||
#endif
|
||||
} 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);
|
||||
|
@ -246,9 +246,6 @@ private:
|
||||
/// AppLoader used to load the current executing application
|
||||
std::unique_ptr<Loader::AppLoader> app_loader;
|
||||
|
||||
/// Memory system
|
||||
std::unique_ptr<Memory::MemorySystem> memory;
|
||||
|
||||
/// ARM11 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
|
||||
std::unique_ptr<Kernel::KernelSystem> kernel;
|
||||
std::unique_ptr<Timing> timing;
|
||||
/// Memory system
|
||||
std::unique_ptr<Memory::MemorySystem> memory;
|
||||
|
||||
private:
|
||||
static System s_instance;
|
||||
|
@ -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<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);
|
||||
kernel = Core::System::GetInstance().kernel.get();
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
#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<VfpTestCase> test_cases{{
|
||||
#include "vfp_vadd_f32.inc"
|
||||
@ -47,4 +47,4 @@ TEST_CASE("ARM_DynCom (vfp): vadd", "[arm_dyncom]") {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ArmTests
|
||||
} // namespace ArmTests
|
||||
|
@ -23,8 +23,8 @@ static SharedPtr<Object> MakeObject(Kernel::KernelSystem& kernel) {
|
||||
TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") {
|
||||
// HACK: see comments of member timing
|
||||
Core::System::GetInstance().timing = std::make_unique<Core::Timing>();
|
||||
Memory::MemorySystem memory;
|
||||
Kernel::KernelSystem kernel(memory, 0);
|
||||
auto memory = std::make_unique<Memory::MemorySystem>();
|
||||
Kernel::KernelSystem kernel(*memory, 0);
|
||||
auto session = std::get<SharedPtr<ServerSession>>(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<Core::Timing>();
|
||||
Memory::MemorySystem memory;
|
||||
Kernel::KernelSystem kernel(memory, 0);
|
||||
auto memory = std::make_unique<Memory::MemorySystem>();
|
||||
Kernel::KernelSystem kernel(*memory, 0);
|
||||
auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair());
|
||||
HLERequestContext context(std::move(session));
|
||||
|
||||
|
@ -13,8 +13,8 @@
|
||||
TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") {
|
||||
// HACK: see comments of member timing
|
||||
Core::System::GetInstance().timing = std::make_unique<Core::Timing>();
|
||||
Memory::MemorySystem memory;
|
||||
Kernel::KernelSystem kernel(memory, 0);
|
||||
Core::System::GetInstance().memory = std::make_unique<Memory::MemorySystem>();
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user