Basic hacky write watching for texture invalidation. Doesn't scale.
This commit is contained in:
@@ -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_;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user