From 8d4f54e24063cc7b34cf37e5fd624e291164b007 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 May 2015 01:45:56 -0700 Subject: [PATCH] Thread state updates. --- src/xenia/cpu/thread_state.h | 2 +- src/xenia/kernel/objects/xevent.cc | 2 +- src/xenia/kernel/objects/xthread.cc | 54 ++++++++++++++++++++++------- src/xenia/kernel/xobject.cc | 40 ++++++++------------- src/xenia/kernel/xobject.h | 8 ++--- 5 files changed, 61 insertions(+), 45 deletions(-) diff --git a/src/xenia/cpu/thread_state.h b/src/xenia/cpu/thread_state.h index 8a93256b5..542ea4638 100644 --- a/src/xenia/cpu/thread_state.h +++ b/src/xenia/cpu/thread_state.h @@ -32,7 +32,7 @@ class ThreadState { void set_name(const std::string& value) { name_ = value; } void* backend_data() const { return backend_data_; } uint32_t stack_address() const { return stack_address_; } - size_t stack_size() const { return stack_size_; } + uint32_t stack_size() const { return stack_size_; } uint32_t thread_state_address() const { return thread_state_address_; } xe::cpu::frontend::PPCContext* context() const { return context_; } diff --git a/src/xenia/kernel/objects/xevent.cc b/src/xenia/kernel/objects/xevent.cc index 118759f38..6338f4d22 100644 --- a/src/xenia/kernel/objects/xevent.cc +++ b/src/xenia/kernel/objects/xevent.cc @@ -31,7 +31,7 @@ void XEvent::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) { assert_null(handle_); bool manual_reset; - switch (header.type_flags >> 24) { + switch ((header.type_flags >> 24) & 0xFF) { case 0x00: // EventNotificationObject (manual reset) manual_reset = true; break; diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index ab12f53db..7e1d9bde7 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -91,7 +91,7 @@ XThread* XThread::GetCurrentThread() { XThread::EnterCriticalRegion(); thread = shared_kernel_thread_; if (!thread) { - thread = new XThread(KernelState::shared(), 32 * 1024, 0, 0, 0, 0); + thread = new XThread(KernelState::shared(), 256 * 1024, 0, 0, 0, 0); shared_kernel_thread_ = thread; current_thread_tls = thread; } @@ -137,7 +137,7 @@ X_STATUS XThread::Create() { // 0x160: last error // So, at offset 0x100 we have a 4b pointer to offset 200, then have the // structure. - thread_state_address_ = memory()->SystemHeapAlloc(2048); + thread_state_address_ = memory()->SystemHeapAlloc(0xAB0); if (!thread_state_address_) { XELOGW("Unable to allocate thread state block"); return X_STATUS_NO_MEMORY; @@ -169,21 +169,43 @@ X_STATUS XThread::Create() { // Setup the thread state block (last error/etc). uint8_t* p = memory()->TranslateVirtual(thread_state_address_); - xe::store_and_swap(p + 0x000, tls_address_); + xe::store_and_swap(p + 0x000, 6); + xe::store_and_swap(p + 0x008, thread_state_address_ + 0x008); + xe::store_and_swap(p + 0x00C, thread_state_address_ + 0x008); + xe::store_and_swap(p + 0x010, thread_state_address_ + 0x010); + xe::store_and_swap(p + 0x014, thread_state_address_ + 0x010); + xe::store_and_swap(p + 0x040, thread_state_address_ + 0x018 + 8); + xe::store_and_swap(p + 0x044, thread_state_address_ + 0x018 + 8); + xe::store_and_swap(p + 0x048, thread_state_address_); + xe::store_and_swap(p + 0x04C, thread_state_address_ + 0x018); + xe::store_and_swap(p + 0x054, 0x102); + xe::store_and_swap(p + 0x056, 1); + xe::store_and_swap(p + 0x068, tls_address_); + xe::store_and_swap(p + 0x06C, 0); + xe::store_and_swap(p + 0x074, thread_state_address_ + 0x074); + xe::store_and_swap(p + 0x078, thread_state_address_ + 0x074); + xe::store_and_swap(p + 0x07C, thread_state_address_ + 0x07C); + xe::store_and_swap(p + 0x080, thread_state_address_ + 0x07C); + xe::store_and_swap(p + 0x08B, 1); + // D4 = APC + // FC = semaphore (ptr, 0, 2) + // A88 = APC + // 18 = timer + xe::store_and_swap(p + 0x09C, 0xFDFFD7FF); xe::store_and_swap(p + 0x100, thread_state_address_); - FILETIME t; GetSystemTimeAsFileTime(&t); xe::store_and_swap( p + 0x130, ((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime); - xe::store_and_swap(p + 0x144, thread_state_address_ + 0x144); xe::store_and_swap(p + 0x148, thread_state_address_ + 0x144); xe::store_and_swap(p + 0x14C, thread_id_); - xe::store_and_swap(p + 0x150, 0); // ? + xe::store_and_swap(p + 0x150, creation_params_.start_address); xe::store_and_swap(p + 0x154, thread_state_address_ + 0x154); xe::store_and_swap(p + 0x158, thread_state_address_ + 0x154); xe::store_and_swap(p + 0x160, 0); // last error + xe::store_and_swap(p + 0x16C, creation_params_.creation_flags); + xe::store_and_swap(p + 0x17C, 1); // Allocate processor thread state. // This is thread safe. @@ -191,6 +213,14 @@ X_STATUS XThread::Create() { new ThreadState(kernel_state()->processor(), thread_id_, 0, creation_params_.stack_size, thread_state_address_); + xe::store_and_swap( + p + 0x05C, thread_state_->stack_address() + thread_state_->stack_size()); + xe::store_and_swap(p + 0x060, thread_state_->stack_address()); + xe::store_and_swap( + p + 0x0D0, thread_state_->stack_address() + thread_state_->stack_size()); + + SetNativePointer(thread_state_address_); + X_STATUS return_code = PlatformCreate(); if (XFAILED(return_code)) { XELOGW("Unable to create platform thread (%.8X)", return_code); @@ -242,9 +272,8 @@ static uint32_t __stdcall XThreadStartCallbackWin32(void* param) { X_STATUS XThread::PlatformCreate() { bool suspended = creation_params_.creation_flags & 0x1; thread_handle_ = - CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE)XThreadStartCallbackWin32, this, - suspended ? CREATE_SUSPENDED : 0, NULL); + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)XThreadStartCallbackWin32, + this, suspended ? CREATE_SUSPENDED : 0, NULL); if (!thread_handle_) { uint32_t last_error = GetLastError(); // TODO(benvanik): translate? @@ -289,7 +318,7 @@ X_STATUS XThread::PlatformCreate() { pthread_attr_init(&attr); // TODO(benvanik): this shouldn't be necessary - //pthread_attr_setstacksize(&attr, creation_params_.stack_size); + // pthread_attr_setstacksize(&attr, creation_params_.stack_size); int result_code; if (creation_params_.creation_flags & 0x1) { @@ -428,9 +457,8 @@ void XThread::DeliverAPCs(void* data) { // kernel_routine(apc_address, &normal_routine, &normal_context, // &system_arg1, &system_arg2) uint64_t kernel_args[] = { - apc_address, thread->scratch_address_ + 0, - thread->scratch_address_ + 4, thread->scratch_address_ + 8, - thread->scratch_address_ + 12, + apc_address, thread->scratch_address_ + 0, thread->scratch_address_ + 4, + thread->scratch_address_ + 8, thread->scratch_address_ + 12, }; processor->ExecuteInterrupt(0, kernel_routine, kernel_args, xe::countof(kernel_args)); diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index b25ca42ff..88474ed87 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -154,22 +154,16 @@ X_STATUS XObject::WaitMultiple(uint32_t count, XObject** objects, void XObject::SetNativePointer(uint32_t native_ptr) { std::lock_guard lock(kernel_state_->object_mutex()); - auto header_be = + auto header = kernel_state_->memory()->TranslateVirtual(native_ptr); - DISPATCH_HEADER header; - header.type_flags = xe::byte_swap(header_be->type_flags); - header.signal_state = xe::byte_swap(header_be->signal_state); - header.wait_list_flink = xe::byte_swap(header_be->wait_list_flink); - header.wait_list_blink = xe::byte_swap(header_be->wait_list_blink); - assert_true(!(header.wait_list_blink & 0x1)); + assert_true(!(header->wait_list_blink & 0x1)); // Stash pointer in struct. uint64_t object_ptr = reinterpret_cast(this); object_ptr |= 0x1; - header_be->wait_list_flink = xe::byte_swap((uint32_t)(object_ptr >> 32)); - header_be->wait_list_blink = - xe::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF)); + header->wait_list_flink = (uint32_t)(object_ptr >> 32); + header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF); } XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, @@ -185,21 +179,16 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, std::lock_guard lock(kernel_state->object_mutex()); - DISPATCH_HEADER* header_be = (DISPATCH_HEADER*)native_ptr; - DISPATCH_HEADER header; - header.type_flags = xe::byte_swap(header_be->type_flags); - header.signal_state = xe::byte_swap(header_be->signal_state); - header.wait_list_flink = xe::byte_swap(header_be->wait_list_flink); - header.wait_list_blink = xe::byte_swap(header_be->wait_list_blink); + auto header = reinterpret_cast(native_ptr); if (as_type == -1) { - as_type = (header.type_flags >> 24) & 0xFF; + as_type = (header->type_flags >> 24) & 0xFF; } - if (header.wait_list_blink & 0x1) { + if (header->wait_list_blink & 0x1) { // Already initialized. - uint64_t object_ptr = ((uint64_t)header.wait_list_flink << 32) | - ((header.wait_list_blink) & ~0x1); + uint64_t object_ptr = ((uint64_t)header->wait_list_flink << 32) | + ((header->wait_list_blink) & ~0x1); XObject* object = reinterpret_cast(object_ptr); // TODO(benvanik): assert nothing has been changed in the struct. return object; @@ -212,19 +201,19 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, case 1: // EventSynchronizationObject { XEvent* ev = new XEvent(kernel_state); - ev->InitializeNative(native_ptr, header); + ev->InitializeNative(native_ptr, *header); object = ev; } break; case 2: // MutantObject { XMutant* mutant = new XMutant(kernel_state); - mutant->InitializeNative(native_ptr, header); + mutant->InitializeNative(native_ptr, *header); object = mutant; } break; case 5: // SemaphoreObject { XSemaphore* sem = new XSemaphore(kernel_state); - sem->InitializeNative(native_ptr, header); + sem->InitializeNative(native_ptr, *header); object = sem; } break; case 3: // ProcessObject @@ -248,9 +237,8 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, // Stash pointer in struct. uint64_t object_ptr = reinterpret_cast(object); object_ptr |= 0x1; - header_be->wait_list_flink = xe::byte_swap((uint32_t)(object_ptr >> 32)); - header_be->wait_list_blink = - xe::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF)); + header->wait_list_flink = (uint32_t)(object_ptr >> 32); + header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF); return object; } diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index 632907fab..762acc398 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -20,10 +20,10 @@ namespace kernel { // http://www.nirsoft.net/kernel_struct/vista/DISPATCHER_HEADER.html typedef struct { - uint32_t type_flags; - uint32_t signal_state; - uint32_t wait_list_flink; - uint32_t wait_list_blink; + xe::be type_flags; + xe::be signal_state; + xe::be wait_list_flink; + xe::be wait_list_blink; } DISPATCH_HEADER; class XObject {