summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar Michael Scire2018-06-21 00:49:43 -0600
committerGravatar Michael Scire2018-06-21 00:49:43 -0600
commit7e191dccc184ae85ce5ade2bca913ab331002481 (patch)
tree184b0444e9d0cd3bfaea3ebf8c2742802753f58b /src/core/hle/kernel
parentMerge pull request #576 from Subv/warnings1 (diff)
downloadyuzu-7e191dccc184ae85ce5ade2bca913ab331002481.tar.gz
yuzu-7e191dccc184ae85ce5ade2bca913ab331002481.tar.xz
yuzu-7e191dccc184ae85ce5ade2bca913ab331002481.zip
Kernel/Arbiters: Add stubs for 4.x SignalToAddress/WaitForAddres SVCs.
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp46
-rw-r--r--src/core/hle/kernel/address_arbiter.h32
-rw-r--r--src/core/hle/kernel/errors.h10
-rw-r--r--src/core/hle/kernel/mutex.cpp4
-rw-r--r--src/core/hle/kernel/svc.cpp53
-rw-r--r--src/core/hle/kernel/svc_wrap.h10
-rw-r--r--src/core/hle/kernel/thread.h1
7 files changed, 147 insertions, 9 deletions
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
new file mode 100644
index 000000000..cfd2c1590
--- /dev/null
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -0,0 +1,46 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/assert.h"
6#include "common/common_funcs.h"
7#include "common/common_types.h"
8#include "core/hle/kernel/kernel.h"
9#include "core/hle/kernel/process.h"
10#include "core/hle/kernel/thread.h"
11#include "core/memory.h"
12
13namespace Kernel {
14 namespace AddressArbiter {
15
16 // Signals an address being waited on.
17 ResultCode SignalToAddress(VAddr address, s32 value, s32 num_to_wake) {
18 // TODO
19 return RESULT_SUCCESS;
20 }
21
22 // Signals an address being waited on and increments its value if equal to the value argument.
23 ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake) {
24 // TODO
25 return RESULT_SUCCESS;
26 }
27
28 // Signals an address being waited on and modifies its value based on waiting thread count if equal to the value argument.
29 ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake) {
30 // TODO
31 return RESULT_SUCCESS;
32 }
33
34 // Waits on an address if the value passed is less than the argument value, optionally decrementing.
35 ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, bool should_decrement) {
36 // TODO
37 return RESULT_SUCCESS;
38 }
39
40 // Waits on an address if the value passed is equal to the argument value.
41 ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) {
42 // TODO
43 return RESULT_SUCCESS;
44 }
45 } // namespace AddressArbiter
46} // namespace Kernel \ No newline at end of file
diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h
new file mode 100644
index 000000000..3eba103dd
--- /dev/null
+++ b/src/core/hle/kernel/address_arbiter.h
@@ -0,0 +1,32 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/result.h"
8
9namespace Kernel {
10
11 namespace AddressArbiter {
12 enum class ArbitrationType {
13 WaitIfLessThan = 0,
14 DecrementAndWaitIfLessThan = 1,
15 WaitIfEqual = 2,
16 };
17
18 enum class SignalType {
19 Signal = 0,
20 IncrementAndSignalIfEqual = 1,
21 ModifyByWaitingCountAndSignalIfEqual = 2,
22 };
23
24 ResultCode SignalToAddress(VAddr address, s32 value, s32 num_to_wake);
25 ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake);
26 ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake);
27
28 ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, bool should_decrement);
29 ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout);
30 } // namespace AddressArbiter
31
32} // namespace Kernel \ No newline at end of file
diff --git a/src/core/hle/kernel/errors.h b/src/core/hle/kernel/errors.h
index e1b5430bf..7ac960042 100644
--- a/src/core/hle/kernel/errors.h
+++ b/src/core/hle/kernel/errors.h
@@ -20,13 +20,15 @@ enum {
20 MaxConnectionsReached = 52, 20 MaxConnectionsReached = 52,
21 21
22 // Confirmed Switch OS error codes 22 // Confirmed Switch OS error codes
23 MisalignedAddress = 102, 23 InvalidAddress = 102,
24 InvalidMemoryState = 106,
24 InvalidProcessorId = 113, 25 InvalidProcessorId = 113,
25 InvalidHandle = 114, 26 InvalidHandle = 114,
26 InvalidCombination = 116, 27 InvalidCombination = 116,
27 Timeout = 117, 28 Timeout = 117,
28 SynchronizationCanceled = 118, 29 SynchronizationCanceled = 118,
29 TooLarge = 119, 30 TooLarge = 119,
31 InvalidEnumValue = 120,
30}; 32};
31} 33}
32 34
@@ -39,13 +41,13 @@ constexpr ResultCode ERR_SESSION_CLOSED_BY_REMOTE(-1);
39constexpr ResultCode ERR_PORT_NAME_TOO_LONG(-1); 41constexpr ResultCode ERR_PORT_NAME_TOO_LONG(-1);
40constexpr ResultCode ERR_WRONG_PERMISSION(-1); 42constexpr ResultCode ERR_WRONG_PERMISSION(-1);
41constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(-1); 43constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(-1);
42constexpr ResultCode ERR_INVALID_ENUM_VALUE(-1); 44constexpr ResultCode ERR_INVALID_ENUM_VALUE(ErrorModule::Kernel, ErrCodes::InvalidEnumValue);
43constexpr ResultCode ERR_INVALID_ENUM_VALUE_FND(-1); 45constexpr ResultCode ERR_INVALID_ENUM_VALUE_FND(-1);
44constexpr ResultCode ERR_INVALID_COMBINATION(-1); 46constexpr ResultCode ERR_INVALID_COMBINATION(-1);
45constexpr ResultCode ERR_INVALID_COMBINATION_KERNEL(-1); 47constexpr ResultCode ERR_INVALID_COMBINATION_KERNEL(-1);
46constexpr ResultCode ERR_OUT_OF_MEMORY(-1); 48constexpr ResultCode ERR_OUT_OF_MEMORY(-1);
47constexpr ResultCode ERR_INVALID_ADDRESS(-1); 49constexpr ResultCode ERR_INVALID_ADDRESS(ErrorModule::Kernel, ErrCodes::InvalidAddress);
48constexpr ResultCode ERR_INVALID_ADDRESS_STATE(-1); 50constexpr ResultCode ERR_INVALID_ADDRESS_STATE(ErrorModule::Kernel, ErrCodes::InvalidMemoryState);
49constexpr ResultCode ERR_INVALID_HANDLE(ErrorModule::Kernel, ErrCodes::InvalidHandle); 51constexpr ResultCode ERR_INVALID_HANDLE(ErrorModule::Kernel, ErrCodes::InvalidHandle);
50constexpr ResultCode ERR_INVALID_POINTER(-1); 52constexpr ResultCode ERR_INVALID_POINTER(-1);
51constexpr ResultCode ERR_INVALID_OBJECT_ADDR(-1); 53constexpr ResultCode ERR_INVALID_OBJECT_ADDR(-1);
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index bc144f3de..65560226d 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -59,7 +59,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
59 Handle requesting_thread_handle) { 59 Handle requesting_thread_handle) {
60 // The mutex address must be 4-byte aligned 60 // The mutex address must be 4-byte aligned
61 if ((address % sizeof(u32)) != 0) { 61 if ((address % sizeof(u32)) != 0) {
62 return ResultCode(ErrorModule::Kernel, ErrCodes::MisalignedAddress); 62 return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidAddress);
63 } 63 }
64 64
65 SharedPtr<Thread> holding_thread = g_handle_table.Get<Thread>(holding_thread_handle); 65 SharedPtr<Thread> holding_thread = g_handle_table.Get<Thread>(holding_thread_handle);
@@ -97,7 +97,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
97ResultCode Mutex::Release(VAddr address) { 97ResultCode Mutex::Release(VAddr address) {
98 // The mutex address must be 4-byte aligned 98 // The mutex address must be 4-byte aligned
99 if ((address % sizeof(u32)) != 0) { 99 if ((address % sizeof(u32)) != 0) {
100 return ResultCode(ErrorModule::Kernel, ErrCodes::MisalignedAddress); 100 return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidAddress);
101 } 101 }
102 102
103 auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(GetCurrentThread(), address); 103 auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(GetCurrentThread(), address);
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 69ba7b777..4b4831c08 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -11,6 +11,7 @@
11#include "common/string_util.h" 11#include "common/string_util.h"
12#include "core/core.h" 12#include "core/core.h"
13#include "core/core_timing.h" 13#include "core/core_timing.h"
14#include "core/hle/kernel/address_arbiter.h"
14#include "core/hle/kernel/client_port.h" 15#include "core/hle/kernel/client_port.h"
15#include "core/hle/kernel/client_session.h" 16#include "core/hle/kernel/client_session.h"
16#include "core/hle/kernel/event.h" 17#include "core/hle/kernel/event.h"
@@ -580,7 +581,7 @@ static void SleepThread(s64 nanoseconds) {
580 Core::System::GetInstance().PrepareReschedule(); 581 Core::System::GetInstance().PrepareReschedule();
581} 582}
582 583
583/// Signal process wide key atomic 584/// Wait process wide key atomic
584static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr, 585static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr,
585 Handle thread_handle, s64 nano_seconds) { 586 Handle thread_handle, s64 nano_seconds) {
586 NGLOG_TRACE( 587 NGLOG_TRACE(
@@ -689,6 +690,52 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
689 return RESULT_SUCCESS; 690 return RESULT_SUCCESS;
690} 691}
691 692
693// Wait for an address (via Address Arbiter)
694static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout) {
695 // If the passed address is a kernel virtual address, return invalid memory state.
696 if ((address + 0x8000000000LL) < 0x7FFFE00000LL) {
697 return ERR_INVALID_ADDRESS_STATE;
698 }
699 // If the address is not properly aligned to 4 bytes, return invalid address.
700 if (address % sizeof(u32) != 0) {
701 return ERR_INVALID_ADDRESS;
702 }
703
704 switch ((AddressArbiter::ArbitrationType)type) {
705 case AddressArbiter::ArbitrationType::WaitIfLessThan:
706 return AddressArbiter::WaitForAddressIfLessThan(address, value, timeout, false);
707 case AddressArbiter::ArbitrationType::DecrementAndWaitIfLessThan:
708 return AddressArbiter::WaitForAddressIfLessThan(address, value, timeout, true);
709 case AddressArbiter::ArbitrationType::WaitIfEqual:
710 return AddressArbiter::WaitForAddressIfEqual(address, value, timeout);
711 default:
712 return ERR_INVALID_ENUM_VALUE;
713 }
714}
715
716// Signals to an address (via Address Arbiter)
717static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to_wake) {
718 // If the passed address is a kernel virtual address, return invalid memory state.
719 if ((address + 0x8000000000LL) < 0x7FFFE00000LL) {
720 return ERR_INVALID_ADDRESS_STATE;
721 }
722 // If the address is not properly aligned to 4 bytes, return invalid address.
723 if (address % sizeof(u32) != 0) {
724 return ERR_INVALID_ADDRESS;
725 }
726
727 switch ((AddressArbiter::SignalType)type) {
728 case AddressArbiter::SignalType::Signal:
729 return AddressArbiter::SignalToAddress(address, value, num_to_wake);
730 case AddressArbiter::SignalType::IncrementAndSignalIfEqual:
731 return AddressArbiter::IncrementAndSignalToAddressIfEqual(address, value, num_to_wake);
732 case AddressArbiter::SignalType::ModifyByWaitingCountAndSignalIfEqual:
733 return AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(address, value, num_to_wake);
734 default:
735 return ERR_INVALID_ENUM_VALUE;
736 }
737}
738
692/// This returns the total CPU ticks elapsed since the CPU was powered-on 739/// This returns the total CPU ticks elapsed since the CPU was powered-on
693static u64 GetSystemTick() { 740static u64 GetSystemTick() {
694 const u64 result{CoreTiming::GetTicks()}; 741 const u64 result{CoreTiming::GetTicks()};
@@ -861,8 +908,8 @@ static const FunctionDef SVC_Table[] = {
861 {0x31, nullptr, "GetResourceLimitCurrentValue"}, 908 {0x31, nullptr, "GetResourceLimitCurrentValue"},
862 {0x32, SvcWrap<SetThreadActivity>, "SetThreadActivity"}, 909 {0x32, SvcWrap<SetThreadActivity>, "SetThreadActivity"},
863 {0x33, SvcWrap<GetThreadContext>, "GetThreadContext"}, 910 {0x33, SvcWrap<GetThreadContext>, "GetThreadContext"},
864 {0x34, nullptr, "WaitForAddress"}, 911 {0x34, SvcWrap<WaitForAddress>, "WaitForAddress"},
865 {0x35, nullptr, "SignalToAddress"}, 912 {0x35, SvcWrap<SignalToAddress>, "SignalToAddress"},
866 {0x36, nullptr, "Unknown"}, 913 {0x36, nullptr, "Unknown"},
867 {0x37, nullptr, "Unknown"}, 914 {0x37, nullptr, "Unknown"},
868 {0x38, nullptr, "Unknown"}, 915 {0x38, nullptr, "Unknown"},
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
index 40aa88cc1..efae4fdfe 100644
--- a/src/core/hle/kernel/svc_wrap.h
+++ b/src/core/hle/kernel/svc_wrap.h
@@ -179,6 +179,16 @@ void SvcWrap() {
179 FuncReturn(retval); 179 FuncReturn(retval);
180} 180}
181 181
182template <ResultCode func(u64, u32, s32, s64)>
183void SvcWrap() {
184 FuncReturn(func(PARAM(0), (u32)(PARAM(1) & 0xFFFFFFFF), (s32)(PARAM(2) & 0xFFFFFFFF), (s64)PARAM(3)).raw);
185}
186
187template <ResultCode func(u64, u32, s32, s32)>
188void SvcWrap() {
189 FuncReturn(func(PARAM(0), (u32)(PARAM(1) & 0xFFFFFFFF), (s32)(PARAM(2) & 0xFFFFFFFF), (s32)(PARAM(3) & 0xFFFFFFFF)).raw);
190}
191
182//////////////////////////////////////////////////////////////////////////////////////////////////// 192////////////////////////////////////////////////////////////////////////////////////////////////////
183// Function wrappers that return type u32 193// Function wrappers that return type u32
184 194
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 1d2da6d50..023c9dbe9 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -45,6 +45,7 @@ enum ThreadStatus {
45 THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false 45 THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false
46 THREADSTATUS_WAIT_SYNCH_ALL, ///< Waiting due to WaitSynchronizationN with wait_all = true 46 THREADSTATUS_WAIT_SYNCH_ALL, ///< Waiting due to WaitSynchronizationN with wait_all = true
47 THREADSTATUS_WAIT_MUTEX, ///< Waiting due to an ArbitrateLock/WaitProcessWideKey svc 47 THREADSTATUS_WAIT_MUTEX, ///< Waiting due to an ArbitrateLock/WaitProcessWideKey svc
48 THREADSTATUS_WAIT_ARB, ///< Waiting due to a SignalToAddress/WaitForAddress svc
48 THREADSTATUS_DORMANT, ///< Created but not yet made ready 49 THREADSTATUS_DORMANT, ///< Created but not yet made ready
49 THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated 50 THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated
50}; 51};