From b44a7a773054cd9434fcbfab19c6696eb7941db4 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 17 May 2015 13:10:02 -0700 Subject: [PATCH] Allocating stacks in the right place. --- src/xenia/apu/audio_system.cc | 4 +++- src/xenia/cpu/processor.cc | 3 ++- src/xenia/cpu/test/util.h | 6 +++--- src/xenia/cpu/thread_state.cc | 27 ++++++++++++++++++++------- src/xenia/cpu/thread_state.h | 10 +++++++++- src/xenia/kernel/objects/xthread.cc | 3 ++- 6 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/xenia/apu/audio_system.cc b/src/xenia/apu/audio_system.cc index d4e924890..1768592b6 100644 --- a/src/xenia/apu/audio_system.cc +++ b/src/xenia/apu/audio_system.cc @@ -90,7 +90,9 @@ X_STATUS AudioSystem::Setup() { registers_.next_context = 1; // Setup worker thread state. This lets us make calls into guest code. - thread_state_ = new ThreadState(emulator_->processor(), 0, 0, 128 * 1024, 0); + thread_state_ = + new ThreadState(emulator_->processor(), 0, ThreadStackType::kKernelStack, + 0, 128 * 1024, 0); thread_state_->set_name("Audio Worker"); thread_block_ = memory()->SystemHeapAlloc(2048); thread_state_->context()->r[13] = thread_block_; diff --git a/src/xenia/cpu/processor.cc b/src/xenia/cpu/processor.cc index 806ee92a7..6b9994773 100644 --- a/src/xenia/cpu/processor.cc +++ b/src/xenia/cpu/processor.cc @@ -148,7 +148,8 @@ bool Processor::Setup() { backend_ = std::move(backend); frontend_ = std::move(frontend); - interrupt_thread_state_ = new ThreadState(this, 0, 0, 128 * 1024, 0); + interrupt_thread_state_ = + new ThreadState(this, 0, ThreadStackType::kKernelStack, 0, 128 * 1024, 0); interrupt_thread_state_->set_name("Interrupt"); interrupt_thread_block_ = memory_->SystemHeapAlloc(2048); interrupt_thread_state_->context()->r[13] = interrupt_thread_block_; diff --git a/src/xenia/cpu/test/util.h b/src/xenia/cpu/test/util.h index f9f55deb9..c566a906f 100644 --- a/src/xenia/cpu/test/util.h +++ b/src/xenia/cpu/test/util.h @@ -70,9 +70,9 @@ class TestFunction { uint32_t stack_size = 64 * 1024; uint32_t stack_address = memory_size - stack_size; uint32_t thread_state_address = stack_address - 0x1000; - auto thread_state = - std::make_unique(processor.get(), 0x100, stack_address, - stack_size, thread_state_address); + auto thread_state = std::make_unique( + processor.get(), 0x100, ThreadStackType::kUserStack, stack_address, + stack_size, thread_state_address); auto ctx = thread_state->context(); ctx->lr = 0xBEBEBEBE; diff --git a/src/xenia/cpu/thread_state.cc b/src/xenia/cpu/thread_state.cc index 6669436d4..442ba4205 100644 --- a/src/xenia/cpu/thread_state.cc +++ b/src/xenia/cpu/thread_state.cc @@ -27,11 +27,12 @@ using PPCContext = xe::cpu::frontend::PPCContext; thread_local ThreadState* thread_state_ = nullptr; ThreadState::ThreadState(Processor* processor, uint32_t thread_id, - uint32_t stack_address, uint32_t stack_size, - uint32_t pcr_address) + ThreadStackType stack_type, uint32_t stack_address, + uint32_t stack_size, uint32_t pcr_address) : processor_(processor), memory_(processor->memory()), thread_id_(thread_id), + stack_type_(stack_type), name_(""), backend_data_(0), stack_size_(stack_size), @@ -49,12 +50,24 @@ ThreadState::ThreadState(Processor* processor, uint32_t thread_id, uint32_t stack_alignment = (stack_size & 0xF000) ? 0x1000 : 0x10000; uint32_t stack_padding = stack_alignment * 1; uint32_t actual_stack_size = stack_padding + stack_size; + bool top_down; + switch (stack_type) { + case ThreadStackType::kKernelStack: + top_down = true; + break; + case ThreadStackType::kUserStack: + top_down = false; + break; + default: + assert_unhandled_case(stack_type); + break; + } memory() - ->LookupHeapByType(false, stack_alignment) - ->Alloc(actual_stack_size, stack_alignment, - kMemoryAllocationReserve | kMemoryAllocationCommit, - kMemoryProtectRead | kMemoryProtectWrite, true, - &stack_address_); + ->LookupHeap(0x70000000) + ->AllocRange(0x70000000, 0x7FFFFFFF, actual_stack_size, stack_alignment, + kMemoryAllocationReserve | kMemoryAllocationCommit, + kMemoryProtectRead | kMemoryProtectWrite, top_down, + &stack_address_); assert_true(!(stack_address_ & 0xFFF)); // just to be safe stack_allocated_ = true; stack_base_ = stack_address_ + actual_stack_size; diff --git a/src/xenia/cpu/thread_state.h b/src/xenia/cpu/thread_state.h index 49d6f2812..31df73b39 100644 --- a/src/xenia/cpu/thread_state.h +++ b/src/xenia/cpu/thread_state.h @@ -19,15 +19,22 @@ namespace cpu { class Processor; +enum class ThreadStackType { + kKernelStack, + kUserStack, +}; + class ThreadState { public: - ThreadState(Processor* processor, uint32_t thread_id, uint32_t stack_address, + ThreadState(Processor* processor, uint32_t thread_id, + ThreadStackType stack_type, uint32_t stack_address, uint32_t stack_size, uint32_t pcr_address); ~ThreadState(); Processor* processor() const { return processor_; } Memory* memory() const { return memory_; } uint32_t thread_id() const { return thread_id_; } + ThreadStackType stack_type() const { return stack_type_; } const std::string& name() const { return name_; } void set_name(const std::string& value) { name_ = value; } void* backend_data() const { return backend_data_; } @@ -50,6 +57,7 @@ class ThreadState { Processor* processor_; Memory* memory_; uint32_t thread_id_; + ThreadStackType stack_type_; std::string name_; void* backend_data_; uint32_t stack_address_; diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 9bf39be32..639113190 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -171,7 +171,8 @@ X_STATUS XThread::Create() { // Allocate processor thread state. // This is thread safe. - thread_state_ = new ThreadState(kernel_state()->processor(), thread_id_, 0, + thread_state_ = new ThreadState(kernel_state()->processor(), thread_id_, + ThreadStackType::kUserStack, 0, creation_params_.stack_size, pcr_address_); XELOGI("XThread%04X (%X) Stack: %.8X-%.8X", handle(), thread_state_->thread_id(), thread_state_->stack_limit(),