Interrupts fire on the right 'thread', ringbuffer work,
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <xenia/cpu/jit.h>
|
||||
#include <xenia/cpu/ppc/disasm.h>
|
||||
#include <xenia/cpu/ppc/state.h>
|
||||
#include <xenia/gpu/graphics_system.h>
|
||||
|
||||
|
||||
@@ -67,6 +68,7 @@ Processor::~Processor() {
|
||||
}
|
||||
modules_.clear();
|
||||
|
||||
xe_memory_heap_free(memory_, interrupt_thread_block_, 2048);
|
||||
DeallocThread(interrupt_thread_state_);
|
||||
xe_mutex_free(interrupt_thread_lock_);
|
||||
|
||||
@@ -107,6 +109,9 @@ int Processor::Setup() {
|
||||
|
||||
interrupt_thread_lock_ = xe_mutex_alloc(10000);
|
||||
interrupt_thread_state_ = AllocThread(16 * 1024, 0, 0);
|
||||
interrupt_thread_block_ = xe_memory_heap_alloc(
|
||||
memory_, 0, 2048, 0);
|
||||
interrupt_thread_state_->ppc_state()->r[13] = interrupt_thread_block_;
|
||||
|
||||
sym_table_ = new SymbolTable();
|
||||
|
||||
@@ -259,11 +264,19 @@ uint64_t Processor::Execute(ThreadState* thread_state, uint32_t address,
|
||||
return ppc_state->r[3];
|
||||
}
|
||||
|
||||
uint64_t Processor::ExecuteInterrupt(uint32_t address,
|
||||
uint64_t Processor::ExecuteInterrupt(uint32_t cpu,
|
||||
uint32_t address,
|
||||
uint64_t arg0, uint64_t arg1) {
|
||||
// Acquire lock on interrupt thread (we can only dispatch one at a time).
|
||||
xe_mutex_lock(interrupt_thread_lock_);
|
||||
|
||||
// Set 0x10C(r13) to the current CPU ID.
|
||||
uint8_t* p = xe_memory_addr(memory_, 0);
|
||||
XESETUINT8BE(p + interrupt_thread_block_ + 0x10C, cpu);
|
||||
|
||||
// Execute interrupt.
|
||||
uint64_t result = Execute(interrupt_thread_state_, address, arg0, arg1);
|
||||
|
||||
xe_mutex_unlock(interrupt_thread_lock_);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,8 @@ public:
|
||||
uint64_t Execute(ThreadState* thread_state, uint32_t address,
|
||||
uint64_t arg0, uint64_t arg1);
|
||||
|
||||
uint64_t ExecuteInterrupt(uint32_t address, uint64_t arg0, uint64_t arg1);
|
||||
uint64_t ExecuteInterrupt(
|
||||
uint32_t cpu, uint32_t address, uint64_t arg0, uint64_t arg1);
|
||||
|
||||
sdb::FunctionSymbol* GetFunction(uint32_t address);
|
||||
void* GetFunctionPointer(uint32_t address);
|
||||
@@ -80,6 +81,7 @@ private:
|
||||
|
||||
xe_mutex_t* interrupt_thread_lock_;
|
||||
ThreadState* interrupt_thread_state_;
|
||||
uint32_t interrupt_thread_block_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -26,27 +26,23 @@ ThreadState::ThreadState(
|
||||
|
||||
stack_address_ = xe_memory_heap_alloc(memory_, 0, stack_size, 0);
|
||||
|
||||
xe_zero_struct(&ppc_state_, sizeof(ppc_state_));
|
||||
// Allocate with 64b alignment.
|
||||
ppc_state_ = (xe_ppc_state_t*)xe_malloc_aligned(sizeof(xe_ppc_state_t));
|
||||
XEASSERT(((uint64_t)ppc_state_ & 0xF) == 0);
|
||||
xe_zero_struct(ppc_state_, sizeof(xe_ppc_state_t));
|
||||
|
||||
// Stash pointers to common structures that callbacks may need.
|
||||
ppc_state_.membase = xe_memory_addr(memory_, 0);
|
||||
ppc_state_.processor = processor;
|
||||
ppc_state_.thread_state = this;
|
||||
ppc_state_->membase = xe_memory_addr(memory_, 0);
|
||||
ppc_state_->processor = processor;
|
||||
ppc_state_->thread_state = this;
|
||||
|
||||
// Set initial registers.
|
||||
ppc_state_.r[1] = stack_address_ + stack_size;
|
||||
ppc_state_.r[13] = thread_state_address_;
|
||||
ppc_state_->r[1] = stack_address_ + stack_size;
|
||||
ppc_state_->r[13] = thread_state_address_;
|
||||
}
|
||||
|
||||
ThreadState::~ThreadState() {
|
||||
xe_free_aligned(ppc_state_);
|
||||
xe_memory_heap_free(memory_, stack_address_, 0);
|
||||
xe_memory_release(memory_);
|
||||
}
|
||||
|
||||
uint32_t ThreadState::thread_id() const {
|
||||
return thread_id_;
|
||||
}
|
||||
|
||||
xe_ppc_state_t* ThreadState::ppc_state() {
|
||||
return &ppc_state_;
|
||||
}
|
||||
|
||||
@@ -29,9 +29,8 @@ public:
|
||||
uint32_t thread_id);
|
||||
~ThreadState();
|
||||
|
||||
uint32_t thread_id() const;
|
||||
|
||||
xe_ppc_state_t* ppc_state();
|
||||
uint32_t thread_id() const { return thread_id_; }
|
||||
xe_ppc_state_t* ppc_state() const { return ppc_state_; }
|
||||
|
||||
private:
|
||||
uint32_t stack_size_;
|
||||
@@ -42,7 +41,8 @@ private:
|
||||
uint32_t thread_state_address_;
|
||||
uint32_t thread_id_;
|
||||
|
||||
xe_ppc_state_t ppc_state_;
|
||||
// NOTE: must be 64b aligned for SSE ops.
|
||||
xe_ppc_state_t* ppc_state_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user