diff options
| -rw-r--r-- | src/core/hle/kernel/errors.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 32 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc_wrap.h | 5 |
3 files changed, 37 insertions, 2 deletions
diff --git a/src/core/hle/kernel/errors.h b/src/core/hle/kernel/errors.h index 8c2be2681..e5fa67ae8 100644 --- a/src/core/hle/kernel/errors.h +++ b/src/core/hle/kernel/errors.h | |||
| @@ -31,6 +31,7 @@ enum { | |||
| 31 | TooLarge = 119, | 31 | TooLarge = 119, |
| 32 | InvalidEnumValue = 120, | 32 | InvalidEnumValue = 120, |
| 33 | NoSuchEntry = 121, | 33 | NoSuchEntry = 121, |
| 34 | AlreadyRegistered = 122, | ||
| 34 | InvalidState = 125, | 35 | InvalidState = 125, |
| 35 | ResourceLimitExceeded = 132, | 36 | ResourceLimitExceeded = 132, |
| 36 | }; | 37 | }; |
| @@ -58,6 +59,7 @@ constexpr ResultCode ERR_INVALID_MEMORY_PERMISSIONS(ErrorModule::Kernel, | |||
| 58 | constexpr ResultCode ERR_INVALID_HANDLE(ErrorModule::Kernel, ErrCodes::InvalidHandle); | 59 | constexpr ResultCode ERR_INVALID_HANDLE(ErrorModule::Kernel, ErrCodes::InvalidHandle); |
| 59 | constexpr ResultCode ERR_INVALID_PROCESSOR_ID(ErrorModule::Kernel, ErrCodes::InvalidProcessorId); | 60 | constexpr ResultCode ERR_INVALID_PROCESSOR_ID(ErrorModule::Kernel, ErrCodes::InvalidProcessorId); |
| 60 | constexpr ResultCode ERR_INVALID_SIZE(ErrorModule::Kernel, ErrCodes::InvalidSize); | 61 | constexpr ResultCode ERR_INVALID_SIZE(ErrorModule::Kernel, ErrCodes::InvalidSize); |
| 62 | constexpr ResultCode ERR_ALREADY_REGISTERED(ErrorModule::Kernel, ErrCodes::AlreadyRegistered); | ||
| 61 | constexpr ResultCode ERR_INVALID_STATE(ErrorModule::Kernel, ErrCodes::InvalidState); | 63 | constexpr ResultCode ERR_INVALID_STATE(ErrorModule::Kernel, ErrCodes::InvalidState); |
| 62 | constexpr ResultCode ERR_INVALID_THREAD_PRIORITY(ErrorModule::Kernel, | 64 | constexpr ResultCode ERR_INVALID_THREAD_PRIORITY(ErrorModule::Kernel, |
| 63 | ErrCodes::InvalidThreadPriority); | 65 | ErrCodes::InvalidThreadPriority); |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index b76280456..1cdaa740a 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -415,8 +415,36 @@ static ResultCode SetThreadActivity(Handle handle, u32 unknown) { | |||
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | /// Gets the thread context | 417 | /// Gets the thread context |
| 418 | static ResultCode GetThreadContext(Handle handle, VAddr addr) { | 418 | static ResultCode GetThreadContext(VAddr thread_context, Handle handle) { |
| 419 | LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, addr=0x{:X}", handle, addr); | 419 | LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle); |
| 420 | |||
| 421 | auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 422 | const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(handle); | ||
| 423 | if (!thread) { | ||
| 424 | return ERR_INVALID_HANDLE; | ||
| 425 | } | ||
| 426 | |||
| 427 | const auto current_process = Core::CurrentProcess(); | ||
| 428 | if (thread->owner_process != current_process) { | ||
| 429 | return ERR_INVALID_HANDLE; | ||
| 430 | } | ||
| 431 | |||
| 432 | if (thread == GetCurrentThread()) { | ||
| 433 | return ERR_ALREADY_REGISTERED; | ||
| 434 | } | ||
| 435 | |||
| 436 | Core::ARM_Interface::ThreadContext ctx = thread->context; | ||
| 437 | // Mask away mode bits, interrupt bits, IL bit, and other reserved bits. | ||
| 438 | ctx.pstate &= 0xFF0FFE20; | ||
| 439 | |||
| 440 | // If 64-bit, we can just write the context registers directly and we're good. | ||
| 441 | // However, if 32-bit, we have to ensure some registers are zeroed out. | ||
| 442 | if (!current_process->Is64BitProcess()) { | ||
| 443 | std::fill(ctx.cpu_registers.begin() + 15, ctx.cpu_registers.end(), 0); | ||
| 444 | std::fill(ctx.vector_registers.begin() + 16, ctx.vector_registers.end(), u128{}); | ||
| 445 | } | ||
| 446 | |||
| 447 | Memory::WriteBlock(thread_context, &ctx, sizeof(ctx)); | ||
| 420 | return RESULT_SUCCESS; | 448 | return RESULT_SUCCESS; |
| 421 | } | 449 | } |
| 422 | 450 | ||
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index fea9ba5ea..22712e64f 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h | |||
| @@ -64,6 +64,11 @@ void SvcWrap() { | |||
| 64 | FuncReturn(func(Param(0), (s32)Param(1)).raw); | 64 | FuncReturn(func(Param(0), (s32)Param(1)).raw); |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | template <ResultCode func(u64, u32)> | ||
| 68 | void SvcWrap() { | ||
| 69 | FuncReturn(func(Param(0), static_cast<u32>(Param(1))).raw); | ||
| 70 | } | ||
| 71 | |||
| 67 | template <ResultCode func(u64*, u64)> | 72 | template <ResultCode func(u64*, u64)> |
| 68 | void SvcWrap() { | 73 | void SvcWrap() { |
| 69 | u64 param_1 = 0; | 74 | u64 param_1 = 0; |