diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.cc b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.cc index 442e9c94b..2c3ca25fd 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.cc +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.cc @@ -58,8 +58,13 @@ namespace xboxkrnl { // } -SHIM_CALL ExCreateThread_shim( - xe_ppc_state_t* ppc_state, KernelState* state) { +X_STATUS xeExCreateThread( + uint32_t* handle_ptr, uint32_t stack_size, uint32_t* thread_id_ptr, + uint32_t xapi_thread_startup, + uint32_t start_address, uint32_t start_context, uint32_t creation_flags) { + KernelState* state = shared_kernel_state_; + XEASSERTNOTNULL(state); + // DWORD // LPHANDLE Handle, // DWORD StackSize, @@ -69,6 +74,30 @@ SHIM_CALL ExCreateThread_shim( // LPVOID StartContext, // DWORD CreationFlags // 0x80? + XThread* thread = new XThread( + state, stack_size, xapi_thread_startup, start_address, start_context, + creation_flags); + + X_STATUS result_code = thread->Create(); + if (XFAILED(result_code)) { + // Failed! + thread->Release(); + XELOGE("Thread creation failed: %.8X", result_code); + return result_code; + } + + if (handle_ptr) { + *handle_ptr = thread->handle(); + } + if (thread_id_ptr) { + *thread_id_ptr = thread->thread_id(); + } + return result_code; +} + + +SHIM_CALL ExCreateThread_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { uint32_t handle_ptr = SHIM_GET_ARG_32(0); uint32_t stack_size = SHIM_GET_ARG_32(1); uint32_t thread_id_ptr = SHIM_GET_ARG_32(2); @@ -87,37 +116,44 @@ SHIM_CALL ExCreateThread_shim( start_context, creation_flags); - XThread* thread = new XThread( - state, stack_size, xapi_thread_startup, start_address, start_context, - creation_flags); + uint32_t handle; + uint32_t thread_id; + X_STATUS result = xeExCreateThread( + &handle, stack_size, &thread_id, xapi_thread_startup, + start_address, start_context, creation_flags); - X_STATUS result_code = thread->Create(); - if (XFAILED(result_code)) { - // Failed! - thread->Release(); - XELOGE("Thread creation failed: %.8X", result_code); - SHIM_SET_RETURN(result_code); - return; + if (XSUCCEEDED(result)) { + if (handle_ptr) { + SHIM_SET_MEM_32(handle_ptr, handle); + } + if (thread_id_ptr) { + SHIM_SET_MEM_32(thread_id_ptr, thread_id); + } } - - if (handle_ptr) { - SHIM_SET_MEM_32(handle_ptr, thread->handle()); - } - if (thread_id_ptr) { - SHIM_SET_MEM_32(thread_id_ptr, thread->thread_id()); - } - SHIM_SET_RETURN(result_code); + SHIM_SET_RETURN(result); } -SHIM_CALL KeGetCurrentProcessType_shim( - xe_ppc_state_t* ppc_state, KernelState* state) { +uint32_t xeKeGetCurrentProcessType() { + KernelState* state = shared_kernel_state_; + XEASSERTNOTNULL(state); + // DWORD XELOGD( "KeGetCurrentProcessType()"); - SHIM_SET_RETURN(X_PROCTYPE_USER); + return X_PROCTYPE_USER; +} + + +SHIM_CALL KeGetCurrentProcessType_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + XELOGD( + "KeGetCurrentProcessType()"); + + int result = xeKeGetCurrentProcessType(); + SHIM_SET_RETURN(result); } @@ -128,12 +164,11 @@ SHIM_CALL KeGetCurrentProcessType_shim( // http://msdn.microsoft.com/en-us/library/ms686801 -SHIM_CALL KeTlsAlloc_shim( - xe_ppc_state_t* ppc_state, KernelState* state) { - // DWORD +uint32_t xeKeTlsAlloc() { + KernelState* state = shared_kernel_state_; + XEASSERTNOTNULL(state); - XELOGD( - "KeTlsAlloc()"); + // DWORD uint32_t tls_index; @@ -148,25 +183,30 @@ SHIM_CALL KeTlsAlloc_shim( } #endif // WIN32 - SHIM_SET_RETURN(tls_index); + return tls_index; +} + + +SHIM_CALL KeTlsAlloc_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + XELOGD( + "KeTlsAlloc()"); + + uint32_t result = xeKeTlsAlloc(); + SHIM_SET_RETURN(result); } // http://msdn.microsoft.com/en-us/library/ms686804 -SHIM_CALL KeTlsFree_shim( - xe_ppc_state_t* ppc_state, KernelState* state) { +int KeTlsFree(uint32_t tls_index) { + KernelState* state = shared_kernel_state_; + XEASSERTNOTNULL(state); + // BOOL // _In_ DWORD dwTlsIndex - uint32_t tls_index = SHIM_GET_ARG_32(0); - - XELOGD( - "KeTlsFree(%.8X)", - tls_index); - if (tls_index == X_TLS_OUT_OF_INDEXES) { - SHIM_SET_RETURN(0); - return; + return 0; } int result_code = 0; @@ -177,22 +217,31 @@ SHIM_CALL KeTlsFree_shim( result_code = pthread_key_delete(tls_index) == 0; #endif // WIN32 - SHIM_SET_RETURN(result_code); + return result_code; +} + + +SHIM_CALL KeTlsFree_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + uint32_t tls_index = SHIM_GET_ARG_32(0); + + XELOGD( + "KeTlsFree(%.8X)", + tls_index); + + int result = xeKeTlsAlloc(); + SHIM_SET_RETURN(result); } // http://msdn.microsoft.com/en-us/library/ms686812 -SHIM_CALL KeTlsGetValue_shim( - xe_ppc_state_t* ppc_state, KernelState* state) { +uint32_t xeKeTlsGetValue(uint32_t tls_index) { + KernelState* state = shared_kernel_state_; + XEASSERTNOTNULL(state); + // LPVOID // _In_ DWORD dwTlsIndex - uint32_t tls_index = SHIM_GET_ARG_32(0); - - XELOGD( - "KeTlsGetValue(%.8X)", - tls_index); - uint32_t value = 0; #if XE_PLATFORM(WIN32) @@ -206,24 +255,32 @@ SHIM_CALL KeTlsGetValue_shim( // TODO(benvanik): SetLastError } - SHIM_SET_RETURN(value); + return value; +} + + +SHIM_CALL KeTlsGetValue_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + uint32_t tls_index = SHIM_GET_ARG_32(0); + + XELOGD( + "KeTlsGetValue(%.8X)", + tls_index); + + uint32_t result = xeKeTlsGetValue(tls_index); + SHIM_SET_RETURN(result); } // http://msdn.microsoft.com/en-us/library/ms686818 -SHIM_CALL KeTlsSetValue_shim( - xe_ppc_state_t* ppc_state, KernelState* state) { +int xeKeTlsSetValue(uint32_t tls_index, uint32_t tls_value) { + KernelState* state = shared_kernel_state_; + XEASSERTNOTNULL(state); + // BOOL // _In_ DWORD dwTlsIndex, // _In_opt_ LPVOID lpTlsValue - uint32_t tls_index = SHIM_GET_ARG_32(0); - uint32_t tls_value = SHIM_GET_ARG_32(1); - - XELOGD( - "KeTlsSetValue(%.8X, %.8X)", - tls_index, tls_value); - int result_code = 0; #if XE_PLATFORM(WIN32) @@ -232,7 +289,21 @@ SHIM_CALL KeTlsSetValue_shim( result_code = pthread_setspecific(tls_index, (void*)tls_value) == 0; #endif // WIN32 - SHIM_SET_RETURN(result_code); + return result_code; +} + + +SHIM_CALL KeTlsSetValue_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + uint32_t tls_index = SHIM_GET_ARG_32(0); + uint32_t tls_value = SHIM_GET_ARG_32(1); + + XELOGD( + "KeTlsSetValue(%.8X, %.8X)", + tls_index, tls_value); + + int result = xeKeTlsSetValue(tls_index, tls_value); + SHIM_SET_RETURN(result); } diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.h b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.h index 66dac14ac..758a78e15 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.h +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.h @@ -21,7 +21,17 @@ namespace kernel { namespace xboxkrnl { +X_STATUS xeExCreateThread( + uint32_t* handle_ptr, uint32_t stack_size, uint32_t* thread_id_ptr, + uint32_t xapi_thread_startup, + uint32_t start_address, uint32_t start_context, uint32_t creation_flags); +uint32_t xeKeGetCurrentProcessType(); + +uint32_t xeKeTlsAlloc(); +int KeTlsFree(uint32_t tls_index); +uint32_t xeKeTlsGetValue(uint32_t tls_index); +int xeKeTlsSetValue(uint32_t tls_index, uint32_t tls_value); } // namespace xboxkrnl diff --git a/src/xenia/kernel/shim_utils.h b/src/xenia/kernel/shim_utils.h index ba895ed5f..d35f93813 100644 --- a/src/xenia/kernel/shim_utils.h +++ b/src/xenia/kernel/shim_utils.h @@ -30,7 +30,7 @@ namespace kernel { (xe_kernel_export_shim_fn)export_name##_shim, \ NULL); -#define SHIM_MEM_ADDR(a) (a==NULL?NULL:(ppc_state->membase + a)) +#define SHIM_MEM_ADDR(a) (a ? (ppc_state->membase + a) : NULL) #define SHIM_MEM_16(a) (uint16_t)XEGETUINT16BE(SHIM_MEM_ADDR(a)); #define SHIM_MEM_32(a) (uint32_t)XEGETUINT32BE(SHIM_MEM_ADDR(a)); @@ -47,7 +47,7 @@ namespace kernel { #define SHIM_SET_RETURN(v) SHIM_SET_GPR_64(3, v) -#define IMPL_MEM_ADDR(a) (a==0?NULL:xe_memory_addr(state->memory(), a)) +#define IMPL_MEM_ADDR(a) (a ? xe_memory_addr(state->memory(), a) : NULL) #define IMPL_MEM_16(a) (uint16_t)XEGETUINT16BE(IMPL_MEM_ADDR(a)); #define IMPL_MEM_32(a) (uint32_t)XEGETUINT32BE(IMPL_MEM_ADDR(a));