Fixing MMIO build on Windows.

This commit is contained in:
Ben Vanik 2014-08-01 20:29:57 -07:00
parent 12f734d7a0
commit 4ad7662ef7
6 changed files with 29 additions and 31 deletions

View File

@ -9,6 +9,8 @@
#include <poly/debugging.h>
#include <Windows.h>
namespace poly {
namespace debugging {

View File

@ -21,9 +21,9 @@ namespace cpu {
MMIOHandler* MMIOHandler::global_handler_ = nullptr;
// Implemented in the platform cc file.
std::unique_ptr<MMIOHandler> CreateMMIOHandler();
std::unique_ptr<MMIOHandler> CreateMMIOHandler(uint8_t* mapping_base);
std::unique_ptr<MMIOHandler> MMIOHandler::Install() {
std::unique_ptr<MMIOHandler> 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> 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> 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<uint64_t>(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;

View File

@ -24,7 +24,7 @@ class MMIOHandler {
public:
virtual ~MMIOHandler();
static std::unique_ptr<MMIOHandler> Install();
static std::unique_ptr<MMIOHandler> 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;

View File

@ -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<MMIOHandler> CreateMMIOHandler() {
return std::make_unique<MachMMIOHandler>();
std::unique_ptr<MMIOHandler> CreateMMIOHandler(uint8_t* mapping_base) {
return std::make_unique<MachMMIOHandler>(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_);

View File

@ -9,6 +9,8 @@
#include <xenia/cpu/mmio_handler.h>
#include <Windows.h>
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<MMIOHandler> CreateMMIOHandler() {
return std::make_unique<WinMMIOHandler>();
std::unique_ptr<MMIOHandler> CreateMMIOHandler(uint8_t* mapping_base) {
return std::make_unique<WinMMIOHandler>(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 {

View File

@ -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<LPVOID>(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();