diff --git a/src/xenia/kernel/modules/xboxkrnl/objects/xthread.cc b/src/xenia/kernel/modules/xboxkrnl/objects/xthread.cc index a3efeaad8..56a0b7b12 100644 --- a/src/xenia/kernel/modules/xboxkrnl/objects/xthread.cc +++ b/src/xenia/kernel/modules/xboxkrnl/objects/xthread.cc @@ -102,6 +102,10 @@ uint32_t XThread::GetCurrentThreadId(const uint8_t* thread_state_block) { return XEGETUINT32BE(thread_state_block + 0x14C); } +uint32_t XThread::thread_state() { + return thread_state_address_; +} + uint32_t XThread::thread_id() { return thread_id_; } @@ -135,6 +139,9 @@ X_STATUS XThread::Create() { return X_STATUS_NO_MEMORY; } + // Set native info. + SetNativePointer(thread_state_address_); + XModule* module = kernel_state()->GetExecutableModule(); // Allocate TLS block. diff --git a/src/xenia/kernel/modules/xboxkrnl/objects/xthread.h b/src/xenia/kernel/modules/xboxkrnl/objects/xthread.h index 52b3e8271..c83d4fe51 100644 --- a/src/xenia/kernel/modules/xboxkrnl/objects/xthread.h +++ b/src/xenia/kernel/modules/xboxkrnl/objects/xthread.h @@ -43,6 +43,7 @@ public: static uint32_t GetCurrentThreadHandle(); static uint32_t GetCurrentThreadId(const uint8_t* thread_state_block); + uint32_t thread_state(); uint32_t thread_id(); uint32_t last_error(); void set_last_error(uint32_t error_code); diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_ob.cc b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_ob.cc index 45b0b7086..fcf8f18cc 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_ob.cc +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_ob.cc @@ -13,6 +13,7 @@ #include #include #include +#include using namespace xe; @@ -46,6 +47,14 @@ SHIM_CALL ObReferenceObjectByHandle_shim( // TODO(benvanik): get native value, if supported. uint32_t native_ptr = 0xDEADF00D; + switch (object_type_ptr) { + case 0xD01BBEEF: // ExThreadObjectType + { + XThread* thread = (XThread*)object; + native_ptr = thread->thread_state(); + } + break; + } if (out_object_ptr) { SHIM_SET_MEM_32(out_object_ptr, native_ptr); diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.cc b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.cc index 8224787b5..67922c3d6 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.cc +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.cc @@ -28,6 +28,7 @@ namespace xboxkrnl { // r13 + 0x100: pointer to thread local state // Thread local state: +// 0x058: kernel time // 0x14C: thread id // 0x150: if >0 then error states don't get set // 0x160: last error @@ -136,7 +137,14 @@ SHIM_CALL ExCreateThread_shim( uint32_t xeKeSetAffinityThread(void* thread_ptr, uint32_t affinity) { - // TODO(benvanik): implement. + KernelState* state = shared_kernel_state_; + XEASSERTNOTNULL(state); + + XThread* thread = (XThread*)XObject::GetObject(state, thread_ptr); + if (thread) { + // TODO(benvanik): implement. + } + return affinity; } @@ -151,9 +159,6 @@ SHIM_CALL KeSetAffinityThread_shim( thread, affinity); - // TODO(benvanik): expecting dummy values from ObReferenceObjectByHandle. - XEASSERT(thread == 0xDEADF00D); - void* thread_ptr = SHIM_MEM_ADDR(thread); uint32_t result = xeKeSetAffinityThread(thread_ptr, affinity); SHIM_SET_RETURN(result); diff --git a/src/xenia/kernel/modules/xboxkrnl/xobject.cc b/src/xenia/kernel/modules/xboxkrnl/xobject.cc index f6539cab7..dc1cfc75e 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xobject.cc +++ b/src/xenia/kernel/modules/xboxkrnl/xobject.cc @@ -90,6 +90,28 @@ void XObject::UnlockType() { xe_mutex_unlock(shared_kernel_state_->object_mutex_); } +void XObject::SetNativePointer(uint32_t native_ptr) { + XObject::LockType(); + + DISPATCH_HEADER* header_be = + (DISPATCH_HEADER*)xe_memory_addr(kernel_state_->memory(), native_ptr); + DISPATCH_HEADER header; + header.type_flags = XESWAP32(header_be->type_flags); + header.signal_state = XESWAP32(header_be->signal_state); + header.wait_list_flink = XESWAP32(header_be->wait_list_flink); + header.wait_list_blink = XESWAP32(header_be->wait_list_blink); + + XEASSERT(!(header.wait_list_blink & 0x1)); + + // Stash pointer in struct. + uint64_t object_ptr = reinterpret_cast(this); + object_ptr |= 0x1; + header_be->wait_list_flink = XESWAP32((uint32_t)(object_ptr >> 32)); + header_be->wait_list_blink = XESWAP32((uint32_t)(object_ptr & 0xFFFFFFFF)); + + XObject::UnlockType(); +} + XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr) { // Unfortunately the XDK seems to inline some KeInitialize calls, meaning // we never see it and just randomly start getting passed events/timers/etc. diff --git a/src/xenia/kernel/modules/xboxkrnl/xobject.h b/src/xenia/kernel/modules/xboxkrnl/xobject.h index 31c9d9389..41b981715 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xobject.h +++ b/src/xenia/kernel/modules/xboxkrnl/xobject.h @@ -72,6 +72,7 @@ public: protected: Runtime* runtime(); xe_memory_ref memory(); // unretained + void SetNativePointer(uint32_t native_ptr); private: KernelState* kernel_state_;