diff --git a/src/poly/debugging_win.cc b/src/poly/debugging_win.cc index 419547f34..05916f700 100644 --- a/src/poly/debugging_win.cc +++ b/src/poly/debugging_win.cc @@ -9,6 +9,8 @@ #include +#include + namespace poly { namespace debugging { diff --git a/src/xenia/cpu/mmio_handler.cc b/src/xenia/cpu/mmio_handler.cc index 5408f9890..299d2704e 100644 --- a/src/xenia/cpu/mmio_handler.cc +++ b/src/xenia/cpu/mmio_handler.cc @@ -21,9 +21,9 @@ namespace cpu { MMIOHandler* MMIOHandler::global_handler_ = nullptr; // Implemented in the platform cc file. -std::unique_ptr CreateMMIOHandler(); +std::unique_ptr CreateMMIOHandler(uint8_t* mapping_base); -std::unique_ptr MMIOHandler::Install() { +std::unique_ptr MMIOHandler::Install(uint8_t* mapping_base) { // There can be only one handler at a time. assert_null(global_handler_); if (global_handler_) { @@ -31,7 +31,7 @@ std::unique_ptr MMIOHandler::Install() { } // Create the platform-specific handler. - auto handler = CreateMMIOHandler(); + auto handler = CreateMMIOHandler(mapping_base); // Platform-specific initialization for the handler. if (!handler->Initialize()) { @@ -45,19 +45,17 @@ std::unique_ptr MMIOHandler::Install() { MMIOHandler::~MMIOHandler() { assert_true(global_handler_ == this); global_handler_ = nullptr; - - // Platform-specific handler uninstall. - Uninstall(); } bool MMIOHandler::RegisterRange(uint64_t address, uint64_t mask, uint64_t size, void* context, MMIOReadCallback read_callback, MMIOWriteCallback write_callback) { - mapped_ranges_.emplace_back({ + mapped_ranges_.push_back({ reinterpret_cast(mapping_base_) | address, 0xFFFFFFFF00000000ull | mask, size, context, read_callback, write_callback, }); + return true; } bool MMIOHandler::CheckLoad(uint64_t address, uint64_t* out_value) { @@ -153,7 +151,7 @@ bool MMIOHandler::HandleAccessFault(void* thread_state, if (!poly::bit_scan_forward(arg2_type & 0xFFFF, &be_reg_index)) { be_reg_index = 0; } - uint64_t* reg_ptr = GetThreadStateRegPtr(thread_state, arg2_type); + uint64_t* reg_ptr = GetThreadStateRegPtr(thread_state, be_reg_index); value = *reg_ptr; } else if ((arg2_type & BE::CONSTANT_TYPE) == BE::CONSTANT_TYPE) { value = disasm.Instruction.Immediat; diff --git a/src/xenia/cpu/mmio_handler.h b/src/xenia/cpu/mmio_handler.h index 44eeea985..586c04840 100644 --- a/src/xenia/cpu/mmio_handler.h +++ b/src/xenia/cpu/mmio_handler.h @@ -24,7 +24,7 @@ class MMIOHandler { public: virtual ~MMIOHandler(); - static std::unique_ptr Install(); + static std::unique_ptr Install(uint8_t* mapping_base); static MMIOHandler* global_handler() { return global_handler_; } bool RegisterRange(uint64_t address, uint64_t mask, uint64_t size, @@ -38,16 +38,17 @@ class MMIOHandler { bool HandleAccessFault(void* thread_state, uint64_t fault_address); protected: - MMIOHandler() = default; + MMIOHandler(uint8_t* mapping_base) : mapping_base_(mapping_base) {} virtual bool Initialize() = 0; - virtual void Uninstall() = 0; virtual uint64_t GetThreadStateRip(void* thread_state_ptr) = 0; virtual void SetThreadStateRip(void* thread_state_ptr, uint64_t rip) = 0; virtual uint64_t* GetThreadStateRegPtr(void* thread_state_ptr, int32_t be_reg_index) = 0; + uint8_t* mapping_base_; + struct MMIORange { uint64_t address; uint64_t mask; diff --git a/src/xenia/cpu/mmio_handler_mac.cc b/src/xenia/cpu/mmio_handler_mac.cc index 193bd3f5c..9e540ffa2 100644 --- a/src/xenia/cpu/mmio_handler_mac.cc +++ b/src/xenia/cpu/mmio_handler_mac.cc @@ -34,11 +34,11 @@ namespace cpu { class MachMMIOHandler : public MMIOHandler { public: - MachMMIOHandler(); + MachMMIOHandler(uint8_t* mapping_base); + ~MachMMIOHandler() override; protected: bool Initialize() override; - void Uninstall() override; uint64_t GetThreadStateRip(void* thread_state_ptr) override; void SetThreadStateRip(void* thread_state_ptr, uint64_t rip) override; @@ -54,11 +54,12 @@ class MachMMIOHandler : public MMIOHandler { mach_port_t listen_port_; }; -std::unique_ptr CreateMMIOHandler() { - return std::make_unique(); +std::unique_ptr CreateMMIOHandler(uint8_t* mapping_base) { + return std::make_unique(mapping_base); } -MachMMIOHandler::MachMMIOHandler() : listen_port_(0) {} +MachMMIOHandler::MachMMIOHandler(uint8_t* mapping_base) + : MMIOHandler(mapping_base), listen_port_(0) {} bool MachMMIOHandler::Initialize() { // Allocates the port that listens for exceptions. @@ -93,7 +94,7 @@ bool MachMMIOHandler::Initialize() { return true; } -void MachMMIOHandler::Uninstall() { +MachMMIOHandler::~MachMMIOHandler() { task_set_exception_ports(mach_task_self(), EXC_MASK_BAD_ACCESS, 0, EXCEPTION_DEFAULT, 0); mach_port_deallocate(mach_task_self(), listen_port_); diff --git a/src/xenia/cpu/mmio_handler_win.cc b/src/xenia/cpu/mmio_handler_win.cc index 31647ab18..e645c0a64 100644 --- a/src/xenia/cpu/mmio_handler_win.cc +++ b/src/xenia/cpu/mmio_handler_win.cc @@ -9,6 +9,8 @@ #include +#include + namespace xe { namespace cpu { @@ -16,11 +18,11 @@ LONG CALLBACK MMIOExceptionHandler(PEXCEPTION_POINTERS ex_info); class WinMMIOHandler : public MMIOHandler { public: - WinMMIOHandler() = default; + WinMMIOHandler(uint8_t* mapping_base) : MMIOHandler(mapping_base) {} + ~WinMMIOHandler() override; protected: bool Initialize() override; - void Uninstall() override; uint64_t GetThreadStateRip(void* thread_state_ptr) override; void SetThreadStateRip(void* thread_state_ptr, uint64_t rip) override; @@ -28,8 +30,8 @@ class WinMMIOHandler : public MMIOHandler { int32_t be_reg_index) override; }; -std::unique_ptr CreateMMIOHandler() { - return std::make_unique(); +std::unique_ptr CreateMMIOHandler(uint8_t* mapping_base) { + return std::make_unique(mapping_base); } bool WinMMIOHandler::Initialize() { @@ -43,7 +45,7 @@ bool WinMMIOHandler::Initialize() { return true; } -void WinMMIOHandler::Uninstall() { +WinMMIOHandler::~WinMMIOHandler() { // Remove exception handlers. RemoveVectoredExceptionHandler(MMIOExceptionHandler); RemoveVectoredContinueHandler(MMIOExceptionHandler); @@ -58,7 +60,8 @@ LONG CALLBACK MMIOExceptionHandler(PEXCEPTION_POINTERS ex_info) { auto code = ex_info->ExceptionRecord->ExceptionCode; if (code == STATUS_ACCESS_VIOLATION) { auto fault_address = ex_info->ExceptionRecord->ExceptionInformation[1]; - if (HandleAccessFault(ex_info->ContextRecord, fault_address)) { + if (MMIOHandler::global_handler()->HandleAccessFault(ex_info->ContextRecord, + fault_address)) { // Handled successfully - RIP has been updated and we can continue. return EXCEPTION_CONTINUE_EXECUTION; } else { diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index e9dcd9b79..9e3942649 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -130,13 +130,6 @@ XenonMemory::~XenonMemory() { // requests. mmio_handler_.reset(); - // Unallocate mapped ranges. - for (int i = 0; i < g_mapped_range_count_; ++i) { - const auto& range = g_mapped_ranges_[i]; - VirtualFree(reinterpret_cast(range.address), range.size, - MEM_DECOMMIT); - } - if (mapping_base_) { // GPU writeback. VirtualFree( @@ -208,7 +201,7 @@ int XenonMemory::Initialize() { MEM_COMMIT, PAGE_READWRITE); // Add handlers for MMIO. - mmio_handler_ = MMIOHandler::Install(); + mmio_handler_ = MMIOHandler::Install(mapping_base_); if (!mmio_handler_) { XELOGE("Unable to install MMIO handlers"); assert_always();