mirror of
https://github.com/Lime3DS/Lime3DS
synced 2024-12-28 10:02:31 -06:00
ARM: pass MemorySystem separately in the constructor and make System optional
So that unit test can test CPU without constructing the entire system. Also remove hacks in the System class
This commit is contained in:
parent
9573ee46bd
commit
64f6e5e597
14 changed files with 80 additions and 65 deletions
|
@ -73,7 +73,7 @@ class DynarmicUserCallbacks final : public Dynarmic::A32::UserCallbacks {
|
||||||
public:
|
public:
|
||||||
explicit DynarmicUserCallbacks(ARM_Dynarmic& parent)
|
explicit DynarmicUserCallbacks(ARM_Dynarmic& parent)
|
||||||
: parent(parent), timing(parent.system.CoreTiming()), svc_context(parent.system),
|
: parent(parent), timing(parent.system.CoreTiming()), svc_context(parent.system),
|
||||||
memory(parent.system.Memory()) {}
|
memory(parent.memory) {}
|
||||||
~DynarmicUserCallbacks() = default;
|
~DynarmicUserCallbacks() = default;
|
||||||
|
|
||||||
std::uint8_t MemoryRead8(VAddr vaddr) override {
|
std::uint8_t MemoryRead8(VAddr vaddr) override {
|
||||||
|
@ -163,9 +163,10 @@ public:
|
||||||
Memory::MemorySystem& memory;
|
Memory::MemorySystem& memory;
|
||||||
};
|
};
|
||||||
|
|
||||||
ARM_Dynarmic::ARM_Dynarmic(Core::System& system, PrivilegeMode initial_mode)
|
ARM_Dynarmic::ARM_Dynarmic(Core::System* system, Memory::MemorySystem& memory,
|
||||||
: system(system), cb(std::make_unique<DynarmicUserCallbacks>(*this)) {
|
PrivilegeMode initial_mode)
|
||||||
interpreter_state = std::make_shared<ARMul_State>(system, initial_mode);
|
: system(*system), memory(memory), cb(std::make_unique<DynarmicUserCallbacks>(*this)) {
|
||||||
|
interpreter_state = std::make_shared<ARMul_State>(system, memory, initial_mode);
|
||||||
PageTableChanged();
|
PageTableChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +175,7 @@ ARM_Dynarmic::~ARM_Dynarmic() = default;
|
||||||
MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64));
|
MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64));
|
||||||
|
|
||||||
void ARM_Dynarmic::Run() {
|
void ARM_Dynarmic::Run() {
|
||||||
ASSERT(system.Memory().GetCurrentPageTable() == current_page_table);
|
ASSERT(memory.GetCurrentPageTable() == current_page_table);
|
||||||
MICROPROFILE_SCOPE(ARM_Jit);
|
MICROPROFILE_SCOPE(ARM_Jit);
|
||||||
|
|
||||||
jit->Run();
|
jit->Run();
|
||||||
|
@ -281,7 +282,7 @@ void ARM_Dynarmic::InvalidateCacheRange(u32 start_address, std::size_t length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARM_Dynarmic::PageTableChanged() {
|
void ARM_Dynarmic::PageTableChanged() {
|
||||||
current_page_table = system.Memory().GetCurrentPageTable();
|
current_page_table = memory.GetCurrentPageTable();
|
||||||
|
|
||||||
auto iter = jits.find(current_page_table);
|
auto iter = jits.find(current_page_table);
|
||||||
if (iter != jits.end()) {
|
if (iter != jits.end()) {
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
namespace Memory {
|
namespace Memory {
|
||||||
struct PageTable;
|
struct PageTable;
|
||||||
|
class MemorySystem;
|
||||||
} // namespace Memory
|
} // namespace Memory
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
@ -23,7 +24,7 @@ class DynarmicUserCallbacks;
|
||||||
|
|
||||||
class ARM_Dynarmic final : public ARM_Interface {
|
class ARM_Dynarmic final : public ARM_Interface {
|
||||||
public:
|
public:
|
||||||
ARM_Dynarmic(Core::System& system, PrivilegeMode initial_mode);
|
ARM_Dynarmic(Core::System* system, Memory::MemorySystem& memory, PrivilegeMode initial_mode);
|
||||||
~ARM_Dynarmic();
|
~ARM_Dynarmic();
|
||||||
|
|
||||||
void Run() override;
|
void Run() override;
|
||||||
|
@ -55,6 +56,7 @@ public:
|
||||||
private:
|
private:
|
||||||
friend class DynarmicUserCallbacks;
|
friend class DynarmicUserCallbacks;
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
Memory::MemorySystem& memory;
|
||||||
std::unique_ptr<DynarmicUserCallbacks> cb;
|
std::unique_ptr<DynarmicUserCallbacks> cb;
|
||||||
std::unique_ptr<Dynarmic::A32::Jit> MakeJit();
|
std::unique_ptr<Dynarmic::A32::Jit> MakeJit();
|
||||||
|
|
||||||
|
|
|
@ -68,14 +68,17 @@ private:
|
||||||
u32 fpexc;
|
u32 fpexc;
|
||||||
};
|
};
|
||||||
|
|
||||||
ARM_DynCom::ARM_DynCom(Core::System& system, PrivilegeMode initial_mode) : system(system) {
|
ARM_DynCom::ARM_DynCom(Core::System* system, Memory::MemorySystem& memory,
|
||||||
state = std::make_unique<ARMul_State>(system, initial_mode);
|
PrivilegeMode initial_mode)
|
||||||
|
: system(system) {
|
||||||
|
state = std::make_unique<ARMul_State>(system, memory, initial_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
ARM_DynCom::~ARM_DynCom() {}
|
ARM_DynCom::~ARM_DynCom() {}
|
||||||
|
|
||||||
void ARM_DynCom::Run() {
|
void ARM_DynCom::Run() {
|
||||||
ExecuteInstructions(std::max<s64>(system.CoreTiming().GetDowncount(), 0));
|
DEBUG_ASSERT(system != nullptr);
|
||||||
|
ExecuteInstructions(std::max<s64>(system->CoreTiming().GetDowncount(), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARM_DynCom::Step() {
|
void ARM_DynCom::Step() {
|
||||||
|
@ -146,7 +149,9 @@ 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());
|
||||||
system.CoreTiming().AddTicks(ticks_executed);
|
if (system != nullptr) {
|
||||||
|
system->CoreTiming().AddTicks(ticks_executed);
|
||||||
|
}
|
||||||
state->ServeBreak();
|
state->ServeBreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,14 @@ namespace Core {
|
||||||
struct System;
|
struct System;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Memory {
|
||||||
|
class MemorySystem;
|
||||||
|
}
|
||||||
|
|
||||||
class ARM_DynCom final : public ARM_Interface {
|
class ARM_DynCom final : public ARM_Interface {
|
||||||
public:
|
public:
|
||||||
explicit ARM_DynCom(Core::System& system, PrivilegeMode initial_mode);
|
explicit ARM_DynCom(Core::System* system, Memory::MemorySystem& memory,
|
||||||
|
PrivilegeMode initial_mode);
|
||||||
~ARM_DynCom();
|
~ARM_DynCom();
|
||||||
|
|
||||||
void Run() override;
|
void Run() override;
|
||||||
|
@ -48,6 +53,6 @@ public:
|
||||||
private:
|
private:
|
||||||
void ExecuteInstructions(u64 num_instructions);
|
void ExecuteInstructions(u64 num_instructions);
|
||||||
|
|
||||||
Core::System& system;
|
Core::System* system;
|
||||||
std::unique_ptr<ARMul_State> state;
|
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,
|
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 = cpu->system.Memory().Read32(phys_addr & 0xFFFFFFFC);
|
u32 inst = cpu->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
|
||||||
|
@ -3859,12 +3859,13 @@ 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)) {
|
||||||
|
DEBUG_ASSERT(cpu->system != nullptr);
|
||||||
swi_inst* const inst_cream = (swi_inst*)inst_base->component;
|
swi_inst* const inst_cream = (swi_inst*)inst_base->component;
|
||||||
cpu->system.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{cpu->system}.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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,9 @@
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
ARMul_State::ARMul_State(Core::System& system, PrivilegeMode initial_mode) : system(system) {
|
ARMul_State::ARMul_State(Core::System* system, Memory::MemorySystem& memory,
|
||||||
|
PrivilegeMode initial_mode)
|
||||||
|
: system(system), memory(memory) {
|
||||||
Reset();
|
Reset();
|
||||||
ChangePrivilegeMode(initial_mode);
|
ChangePrivilegeMode(initial_mode);
|
||||||
}
|
}
|
||||||
|
@ -191,13 +193,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 system.Memory().Read8(address);
|
return 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 = system.Memory().Read16(address);
|
u16 data = memory.Read16(address);
|
||||||
|
|
||||||
if (InBigEndianMode())
|
if (InBigEndianMode())
|
||||||
data = Common::swap16(data);
|
data = Common::swap16(data);
|
||||||
|
@ -208,7 +210,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 = system.Memory().Read32(address);
|
u32 data = memory.Read32(address);
|
||||||
|
|
||||||
if (InBigEndianMode())
|
if (InBigEndianMode())
|
||||||
data = Common::swap32(data);
|
data = Common::swap32(data);
|
||||||
|
@ -219,7 +221,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 = system.Memory().Read64(address);
|
u64 data = memory.Read64(address);
|
||||||
|
|
||||||
if (InBigEndianMode())
|
if (InBigEndianMode())
|
||||||
data = Common::swap64(data);
|
data = Common::swap64(data);
|
||||||
|
@ -230,7 +232,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);
|
||||||
|
|
||||||
system.Memory().Write8(address, data);
|
memory.Write8(address, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMul_State::WriteMemory16(u32 address, u16 data) {
|
void ARMul_State::WriteMemory16(u32 address, u16 data) {
|
||||||
|
@ -239,7 +241,7 @@ void ARMul_State::WriteMemory16(u32 address, u16 data) {
|
||||||
if (InBigEndianMode())
|
if (InBigEndianMode())
|
||||||
data = Common::swap16(data);
|
data = Common::swap16(data);
|
||||||
|
|
||||||
system.Memory().Write16(address, data);
|
memory.Write16(address, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMul_State::WriteMemory32(u32 address, u32 data) {
|
void ARMul_State::WriteMemory32(u32 address, u32 data) {
|
||||||
|
@ -248,7 +250,7 @@ void ARMul_State::WriteMemory32(u32 address, u32 data) {
|
||||||
if (InBigEndianMode())
|
if (InBigEndianMode())
|
||||||
data = Common::swap32(data);
|
data = Common::swap32(data);
|
||||||
|
|
||||||
system.Memory().Write32(address, data);
|
memory.Write32(address, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMul_State::WriteMemory64(u32 address, u64 data) {
|
void ARMul_State::WriteMemory64(u32 address, u64 data) {
|
||||||
|
@ -257,7 +259,7 @@ void ARMul_State::WriteMemory64(u32 address, u64 data) {
|
||||||
if (InBigEndianMode())
|
if (InBigEndianMode())
|
||||||
data = Common::swap64(data);
|
data = Common::swap64(data);
|
||||||
|
|
||||||
system.Memory().Write64(address, data);
|
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,8 +605,9 @@ 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 = system.Kernel().GetThreadManager().GetCurrentThread();
|
DEBUG_ASSERT(system != nullptr);
|
||||||
system.CPU().SaveContext(thread->context);
|
Kernel::Thread* thread = system->Kernel().GetThreadManager().GetCurrentThread();
|
||||||
|
system->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();
|
||||||
|
|
|
@ -27,6 +27,10 @@ namespace Core {
|
||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Memory {
|
||||||
|
class MemorySystem;
|
||||||
|
}
|
||||||
|
|
||||||
// Signal levels
|
// Signal levels
|
||||||
enum { LOW = 0, HIGH = 1, LOWHIGH = 1, HIGHLOW = 2 };
|
enum { LOW = 0, HIGH = 1, LOWHIGH = 1, HIGHLOW = 2 };
|
||||||
|
|
||||||
|
@ -143,7 +147,8 @@ enum {
|
||||||
|
|
||||||
struct ARMul_State final {
|
struct ARMul_State final {
|
||||||
public:
|
public:
|
||||||
explicit ARMul_State(Core::System& system, PrivilegeMode initial_mode);
|
explicit ARMul_State(Core::System* system, Memory::MemorySystem& memory,
|
||||||
|
PrivilegeMode initial_mode);
|
||||||
|
|
||||||
void ChangePrivilegeMode(u32 new_mode);
|
void ChangePrivilegeMode(u32 new_mode);
|
||||||
void Reset();
|
void Reset();
|
||||||
|
@ -201,7 +206,8 @@ public:
|
||||||
|
|
||||||
void ServeBreak();
|
void ServeBreak();
|
||||||
|
|
||||||
Core::System& system;
|
Core::System* system;
|
||||||
|
Memory::MemorySystem& memory;
|
||||||
|
|
||||||
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{};
|
||||||
|
|
|
@ -179,13 +179,13 @@ System::ResultStatus System::Init(EmuWindow& emu_window, u32 system_mode) {
|
||||||
|
|
||||||
if (Settings::values.use_cpu_jit) {
|
if (Settings::values.use_cpu_jit) {
|
||||||
#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, *memory, USER32MODE);
|
||||||
#else
|
#else
|
||||||
cpu_core = std::make_unique<ARM_DynCom>(*this, USER32MODE);
|
cpu_core = std::make_unique<ARM_DynCom>(this, *memory, 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>(*this, USER32MODE);
|
cpu_core = std::make_unique<ARM_DynCom>(this, *memory, USER32MODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
kernel->GetThreadManager().SetCPU(*cpu_core);
|
kernel->GetThreadManager().SetCPU(*cpu_core);
|
||||||
|
|
|
@ -270,8 +270,6 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<Service::FS::ArchiveManager> archive_manager;
|
std::unique_ptr<Service::FS::ArchiveManager> archive_manager;
|
||||||
|
|
||||||
public: // HACK: this is temporary exposed for tests,
|
|
||||||
// due to WIP kernel refactor causing desync state in memory
|
|
||||||
std::unique_ptr<Memory::MemorySystem> memory;
|
std::unique_ptr<Memory::MemorySystem> memory;
|
||||||
std::unique_ptr<Kernel::KernelSystem> kernel;
|
std::unique_ptr<Kernel::KernelSystem> kernel;
|
||||||
std::unique_ptr<Timing> timing;
|
std::unique_ptr<Timing> timing;
|
||||||
|
|
|
@ -15,15 +15,9 @@ static Memory::PageTable* page_table = nullptr;
|
||||||
TestEnvironment::TestEnvironment(bool mutable_memory_)
|
TestEnvironment::TestEnvironment(bool mutable_memory_)
|
||||||
: mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) {
|
: mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) {
|
||||||
|
|
||||||
// HACK: some memory functions are currently referring kernel from the global instance,
|
timing = std::make_unique<Core::Timing>();
|
||||||
// so we need to create the kernel object there.
|
memory = std::make_unique<Memory::MemorySystem>();
|
||||||
// Change this when all global states are eliminated.
|
kernel = std::make_unique<Kernel::KernelSystem>(*memory, *timing, [] {}, 0);
|
||||||
Core::System::GetInstance().timing = std::make_unique<Core::Timing>();
|
|
||||||
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, *Core::System::GetInstance().timing, [] {}, 0);
|
|
||||||
kernel = Core::System::GetInstance().kernel.get();
|
|
||||||
|
|
||||||
kernel->SetCurrentProcess(kernel->CreateProcess(kernel->CreateCodeSet("", 0)));
|
kernel->SetCurrentProcess(kernel->CreateProcess(kernel->CreateCodeSet("", 0)));
|
||||||
page_table = &kernel->GetCurrentProcess()->vm_manager.page_table;
|
page_table = &kernel->GetCurrentProcess()->vm_manager.page_table;
|
||||||
|
@ -31,17 +25,15 @@ TestEnvironment::TestEnvironment(bool mutable_memory_)
|
||||||
page_table->pointers.fill(nullptr);
|
page_table->pointers.fill(nullptr);
|
||||||
page_table->attributes.fill(Memory::PageType::Unmapped);
|
page_table->attributes.fill(Memory::PageType::Unmapped);
|
||||||
|
|
||||||
memory.MapIoRegion(*page_table, 0x00000000, 0x80000000, test_memory);
|
memory->MapIoRegion(*page_table, 0x00000000, 0x80000000, test_memory);
|
||||||
memory.MapIoRegion(*page_table, 0x80000000, 0x80000000, test_memory);
|
memory->MapIoRegion(*page_table, 0x80000000, 0x80000000, test_memory);
|
||||||
|
|
||||||
memory.SetCurrentPageTable(page_table);
|
memory->SetCurrentPageTable(page_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
TestEnvironment::~TestEnvironment() {
|
TestEnvironment::~TestEnvironment() {
|
||||||
Memory::MemorySystem& memory = *Core::System::GetInstance().memory;
|
memory->UnmapRegion(*page_table, 0x80000000, 0x80000000);
|
||||||
memory.UnmapRegion(*page_table, 0x80000000, 0x80000000);
|
memory->UnmapRegion(*page_table, 0x00000000, 0x80000000);
|
||||||
memory.UnmapRegion(*page_table, 0x00000000, 0x80000000);
|
|
||||||
Core::System::GetInstance().kernel.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestEnvironment::SetMemory64(VAddr vaddr, u64 value) {
|
void TestEnvironment::SetMemory64(VAddr vaddr, u64 value) {
|
||||||
|
|
|
@ -49,6 +49,10 @@ public:
|
||||||
/// Empties the internal write-record store.
|
/// Empties the internal write-record store.
|
||||||
void ClearWriteRecords();
|
void ClearWriteRecords();
|
||||||
|
|
||||||
|
Memory::MemorySystem& GetMemory() {
|
||||||
|
return *memory;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend struct TestMemory;
|
friend struct TestMemory;
|
||||||
struct TestMemory final : Memory::MMIORegion {
|
struct TestMemory final : Memory::MMIORegion {
|
||||||
|
@ -80,7 +84,9 @@ private:
|
||||||
std::shared_ptr<TestMemory> test_memory;
|
std::shared_ptr<TestMemory> test_memory;
|
||||||
std::vector<WriteRecord> write_records;
|
std::vector<WriteRecord> write_records;
|
||||||
|
|
||||||
Kernel::KernelSystem* kernel;
|
std::unique_ptr<Core::Timing> timing;
|
||||||
|
std::unique_ptr<Memory::MemorySystem> memory;
|
||||||
|
std::unique_ptr<Kernel::KernelSystem> kernel;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ArmTests
|
} // namespace ArmTests
|
||||||
|
|
|
@ -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(Core::System::GetInstance(), USER32MODE);
|
ARM_DynCom dyncom(nullptr, test_env.GetMemory(), USER32MODE);
|
||||||
|
|
||||||
std::vector<VfpTestCase> test_cases{{
|
std::vector<VfpTestCase> test_cases{{
|
||||||
#include "vfp_vadd_f32.inc"
|
#include "vfp_vadd_f32.inc"
|
||||||
|
|
|
@ -21,10 +21,9 @@ 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
|
Core::Timing timing;
|
||||||
Core::System::GetInstance().timing = std::make_unique<Core::Timing>();
|
Memory::MemorySystem memory;
|
||||||
auto memory = std::make_unique<Memory::MemorySystem>();
|
Kernel::KernelSystem kernel(memory, timing, [] {}, 0);
|
||||||
Kernel::KernelSystem kernel(*memory, *Core::System::GetInstance().timing, [] {}, 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));
|
||||||
|
|
||||||
|
@ -234,10 +233,9 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
|
||||||
// HACK: see comments of member timing
|
Core::Timing timing;
|
||||||
Core::System::GetInstance().timing = std::make_unique<Core::Timing>();
|
Memory::MemorySystem memory;
|
||||||
auto memory = std::make_unique<Memory::MemorySystem>();
|
Kernel::KernelSystem kernel(memory, timing, [] {}, 0);
|
||||||
Kernel::KernelSystem kernel(*memory, *Core::System::GetInstance().timing, [] {}, 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));
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,9 @@
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") {
|
TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory]") {
|
||||||
// HACK: see comments of member timing
|
Core::Timing 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, timing, [] {}, 0);
|
||||||
Kernel::KernelSystem kernel(*Core::System::GetInstance().memory,
|
|
||||||
*Core::System::GetInstance().timing, [] {}, 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);
|
||||||
|
|
Loading…
Reference in a new issue