Allocating stacks in the right place.
This commit is contained in:
parent
37804d692c
commit
b44a7a7730
|
@ -90,7 +90,9 @@ X_STATUS AudioSystem::Setup() {
|
||||||
registers_.next_context = 1;
|
registers_.next_context = 1;
|
||||||
|
|
||||||
// Setup worker thread state. This lets us make calls into guest code.
|
// 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_state_->set_name("Audio Worker");
|
||||||
thread_block_ = memory()->SystemHeapAlloc(2048);
|
thread_block_ = memory()->SystemHeapAlloc(2048);
|
||||||
thread_state_->context()->r[13] = thread_block_;
|
thread_state_->context()->r[13] = thread_block_;
|
||||||
|
|
|
@ -148,7 +148,8 @@ bool Processor::Setup() {
|
||||||
backend_ = std::move(backend);
|
backend_ = std::move(backend);
|
||||||
frontend_ = std::move(frontend);
|
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_state_->set_name("Interrupt");
|
||||||
interrupt_thread_block_ = memory_->SystemHeapAlloc(2048);
|
interrupt_thread_block_ = memory_->SystemHeapAlloc(2048);
|
||||||
interrupt_thread_state_->context()->r[13] = interrupt_thread_block_;
|
interrupt_thread_state_->context()->r[13] = interrupt_thread_block_;
|
||||||
|
|
|
@ -70,9 +70,9 @@ class TestFunction {
|
||||||
uint32_t stack_size = 64 * 1024;
|
uint32_t stack_size = 64 * 1024;
|
||||||
uint32_t stack_address = memory_size - stack_size;
|
uint32_t stack_address = memory_size - stack_size;
|
||||||
uint32_t thread_state_address = stack_address - 0x1000;
|
uint32_t thread_state_address = stack_address - 0x1000;
|
||||||
auto thread_state =
|
auto thread_state = std::make_unique<ThreadState>(
|
||||||
std::make_unique<ThreadState>(processor.get(), 0x100, stack_address,
|
processor.get(), 0x100, ThreadStackType::kUserStack, stack_address,
|
||||||
stack_size, thread_state_address);
|
stack_size, thread_state_address);
|
||||||
auto ctx = thread_state->context();
|
auto ctx = thread_state->context();
|
||||||
ctx->lr = 0xBEBEBEBE;
|
ctx->lr = 0xBEBEBEBE;
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,12 @@ using PPCContext = xe::cpu::frontend::PPCContext;
|
||||||
thread_local ThreadState* thread_state_ = nullptr;
|
thread_local ThreadState* thread_state_ = nullptr;
|
||||||
|
|
||||||
ThreadState::ThreadState(Processor* processor, uint32_t thread_id,
|
ThreadState::ThreadState(Processor* processor, uint32_t thread_id,
|
||||||
uint32_t stack_address, uint32_t stack_size,
|
ThreadStackType stack_type, uint32_t stack_address,
|
||||||
uint32_t pcr_address)
|
uint32_t stack_size, uint32_t pcr_address)
|
||||||
: processor_(processor),
|
: processor_(processor),
|
||||||
memory_(processor->memory()),
|
memory_(processor->memory()),
|
||||||
thread_id_(thread_id),
|
thread_id_(thread_id),
|
||||||
|
stack_type_(stack_type),
|
||||||
name_(""),
|
name_(""),
|
||||||
backend_data_(0),
|
backend_data_(0),
|
||||||
stack_size_(stack_size),
|
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_alignment = (stack_size & 0xF000) ? 0x1000 : 0x10000;
|
||||||
uint32_t stack_padding = stack_alignment * 1;
|
uint32_t stack_padding = stack_alignment * 1;
|
||||||
uint32_t actual_stack_size = stack_padding + stack_size;
|
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()
|
memory()
|
||||||
->LookupHeapByType(false, stack_alignment)
|
->LookupHeap(0x70000000)
|
||||||
->Alloc(actual_stack_size, stack_alignment,
|
->AllocRange(0x70000000, 0x7FFFFFFF, actual_stack_size, stack_alignment,
|
||||||
kMemoryAllocationReserve | kMemoryAllocationCommit,
|
kMemoryAllocationReserve | kMemoryAllocationCommit,
|
||||||
kMemoryProtectRead | kMemoryProtectWrite, true,
|
kMemoryProtectRead | kMemoryProtectWrite, top_down,
|
||||||
&stack_address_);
|
&stack_address_);
|
||||||
assert_true(!(stack_address_ & 0xFFF)); // just to be safe
|
assert_true(!(stack_address_ & 0xFFF)); // just to be safe
|
||||||
stack_allocated_ = true;
|
stack_allocated_ = true;
|
||||||
stack_base_ = stack_address_ + actual_stack_size;
|
stack_base_ = stack_address_ + actual_stack_size;
|
||||||
|
|
|
@ -19,15 +19,22 @@ namespace cpu {
|
||||||
|
|
||||||
class Processor;
|
class Processor;
|
||||||
|
|
||||||
|
enum class ThreadStackType {
|
||||||
|
kKernelStack,
|
||||||
|
kUserStack,
|
||||||
|
};
|
||||||
|
|
||||||
class ThreadState {
|
class ThreadState {
|
||||||
public:
|
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);
|
uint32_t stack_size, uint32_t pcr_address);
|
||||||
~ThreadState();
|
~ThreadState();
|
||||||
|
|
||||||
Processor* processor() const { return processor_; }
|
Processor* processor() const { return processor_; }
|
||||||
Memory* memory() const { return memory_; }
|
Memory* memory() const { return memory_; }
|
||||||
uint32_t thread_id() const { return thread_id_; }
|
uint32_t thread_id() const { return thread_id_; }
|
||||||
|
ThreadStackType stack_type() const { return stack_type_; }
|
||||||
const std::string& name() const { return name_; }
|
const std::string& name() const { return name_; }
|
||||||
void set_name(const std::string& value) { name_ = value; }
|
void set_name(const std::string& value) { name_ = value; }
|
||||||
void* backend_data() const { return backend_data_; }
|
void* backend_data() const { return backend_data_; }
|
||||||
|
@ -50,6 +57,7 @@ class ThreadState {
|
||||||
Processor* processor_;
|
Processor* processor_;
|
||||||
Memory* memory_;
|
Memory* memory_;
|
||||||
uint32_t thread_id_;
|
uint32_t thread_id_;
|
||||||
|
ThreadStackType stack_type_;
|
||||||
std::string name_;
|
std::string name_;
|
||||||
void* backend_data_;
|
void* backend_data_;
|
||||||
uint32_t stack_address_;
|
uint32_t stack_address_;
|
||||||
|
|
|
@ -171,7 +171,8 @@ X_STATUS XThread::Create() {
|
||||||
|
|
||||||
// Allocate processor thread state.
|
// Allocate processor thread state.
|
||||||
// This is thread safe.
|
// 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_);
|
creation_params_.stack_size, pcr_address_);
|
||||||
XELOGI("XThread%04X (%X) Stack: %.8X-%.8X", handle(),
|
XELOGI("XThread%04X (%X) Stack: %.8X-%.8X", handle(),
|
||||||
thread_state_->thread_id(), thread_state_->stack_limit(),
|
thread_state_->thread_id(), thread_state_->stack_limit(),
|
||||||
|
|
Loading…
Reference in New Issue