diff --git a/src/xenia/kernel/xam/xam_task.cc b/src/xenia/kernel/xam/xam_task.cc index facac462c..58f314079 100644 --- a/src/xenia/kernel/xam/xam_task.cc +++ b/src/xenia/kernel/xam/xam_task.cc @@ -11,6 +11,7 @@ #include "xenia/base/string_util.h" #include "xenia/cpu/processor.h" #include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/user_module.h" #include "xenia/kernel/util/shim_utils.h" #include "xenia/kernel/xam/xam_module.h" #include "xenia/kernel/xam/xam_private.h" @@ -40,24 +41,37 @@ static_assert_size(XTASK_MESSAGE, 0x1C); dword_result_t XamTaskSchedule(lpvoid_t callback, pointer_t message, - dword_t unknown, lpdword_t handle_ptr) { - assert_zero(unknown); - + lpdword_t unknown, lpdword_t handle_ptr) { // TODO(gibbed): figure out what this is for *handle_ptr = 12345; - XELOGW("!! Executing scheduled task ({:08X}) synchronously, PROBABLY BAD !! ", + uint32_t stack_size = kernel_state()->GetExecutableModule()->stack_size(); + + // Stack must be aligned to 16kb pages + stack_size = std::max((uint32_t)0x4000, ((stack_size + 0xFFF) & 0xFFFFF000)); + + auto thread = + object_ref(new XThread(kernel_state(), stack_size, 0, callback, + message.guest_address(), 0, true)); + + X_STATUS result = thread->Create(); + + if (XFAILED(result)) { + // Failed! + XELOGE("XAM task creation failed: {:08X}", result); + return result; + } + + XELOGD("XAM task ({:08X}) scheduled asynchronously", callback.guest_address()); - // TODO(gibbed): this is supposed to be async... let's cheat. - auto thread_state = XThread::GetCurrentThread()->thread_state(); - uint64_t args[] = {message.guest_address()}; - auto result = kernel_state()->processor()->Execute(thread_state, callback, - args, xe::countof(args)); return X_STATUS_SUCCESS; } DECLARE_XAM_EXPORT2(XamTaskSchedule, kNone, kImplemented, kSketchy); +dword_result_t XamTaskShouldExit(dword_t r3) { return 0; } +DECLARE_XAM_EXPORT2(XamTaskShouldExit, kNone, kStub, kSketchy); + void RegisterTaskExports(xe::cpu::ExportResolver* export_resolver, KernelState* kernel_state) {}