Basic hacky write watching for texture invalidation. Doesn't scale.

This commit is contained in:
Ben Vanik
2015-01-04 16:28:42 -08:00
parent 55c4488ab2
commit 0529fdb84d
7 changed files with 207 additions and 41 deletions

View File

@@ -10,7 +10,9 @@
#ifndef XENIA_CPU_MMIO_HANDLER_H_
#define XENIA_CPU_MMIO_HANDLER_H_
#include <list>
#include <memory>
#include <mutex>
#include <vector>
namespace xe {
@@ -19,6 +21,9 @@ namespace cpu {
typedef uint64_t (*MMIOReadCallback)(void* context, uint64_t addr);
typedef void (*MMIOWriteCallback)(void* context, uint64_t addr, uint64_t value);
typedef void (*WriteWatchCallback)(void* context_ptr, void* data_ptr,
uint32_t address);
// NOTE: only one can exist at a time!
class MMIOHandler {
public:
@@ -34,14 +39,30 @@ class MMIOHandler {
bool CheckLoad(uint64_t address, uint64_t* out_value);
bool CheckStore(uint64_t address, uint64_t value);
uintptr_t AddWriteWatch(uint32_t guest_address, size_t length,
WriteWatchCallback callback, void* callback_context,
void* callback_data);
void CancelWriteWatch(uintptr_t watch_handle);
public:
bool HandleAccessFault(void* thread_state, uint64_t fault_address);
protected:
struct WriteWatchEntry {
uint32_t address;
uint32_t length;
WriteWatchCallback callback;
void* callback_context;
void* callback_data;
};
MMIOHandler(uint8_t* mapping_base) : mapping_base_(mapping_base) {}
virtual bool Initialize() = 0;
void ClearWriteWatch(WriteWatchEntry* entry);
bool CheckWriteWatch(void* thread_state, uint64_t fault_address);
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,
@@ -59,6 +80,10 @@ class MMIOHandler {
};
std::vector<MMIORange> mapped_ranges_;
// TODO(benvanik): data structure magic.
std::mutex write_watch_mutex_;
std::list<WriteWatchEntry*> write_watches_;
static MMIOHandler* global_handler_;
};