diff options
| author | 2018-06-21 00:49:43 -0600 | |
|---|---|---|
| committer | 2018-06-21 00:49:43 -0600 | |
| commit | 7e191dccc184ae85ce5ade2bca913ab331002481 (patch) | |
| tree | 184b0444e9d0cd3bfaea3ebf8c2742802753f58b /src/core/hle/kernel/svc.cpp | |
| parent | Merge pull request #576 from Subv/warnings1 (diff) | |
| download | yuzu-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/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 53 |
1 files changed, 50 insertions, 3 deletions
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 |
| 584 | static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr, | 585 | static 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) | ||
| 694 | static 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) | ||
| 717 | static 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 |
| 693 | static u64 GetSystemTick() { | 740 | static 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"}, |