summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2015-01-14 10:04:33 -0500
committerGravatar bunnei2015-01-14 10:04:33 -0500
commit394d44cf7480da210f5aeac9c0d86462b0c36d57 (patch)
tree47c2fee9bbf771240c3b2b34505a9710a9b421b8 /src
parentMerge pull request #473 from archshift/pp3ports (diff)
parentAddrArbiter: Implement arbitration types 3 and 4. (diff)
downloadyuzu-394d44cf7480da210f5aeac9c0d86462b0c36d57.tar.gz
yuzu-394d44cf7480da210f5aeac9c0d86462b0c36d57.tar.xz
yuzu-394d44cf7480da210f5aeac9c0d86462b0c36d57.zip
Merge pull request #480 from Subv/arb_2
AddrArbiter: Implement arbitration types 3 and 4.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp21
-rw-r--r--src/core/hle/kernel/address_arbiter.h2
-rw-r--r--src/core/hle/svc.cpp2
3 files changed, 21 insertions, 4 deletions
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 62e3460e1..b7434aaf2 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -29,7 +29,7 @@ public:
29//////////////////////////////////////////////////////////////////////////////////////////////////// 29////////////////////////////////////////////////////////////////////////////////////////////////////
30 30
31/// Arbitrate an address 31/// Arbitrate an address
32ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) { 32ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value, u64 nanoseconds) {
33 Object* object = Kernel::g_handle_table.GetGeneric(handle).get(); 33 Object* object = Kernel::g_handle_table.GetGeneric(handle).get();
34 if (object == nullptr) 34 if (object == nullptr)
35 return InvalidHandle(ErrorModule::Kernel); 35 return InvalidHandle(ErrorModule::Kernel);
@@ -55,7 +55,13 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3
55 HLE::Reschedule(__func__); 55 HLE::Reschedule(__func__);
56 } 56 }
57 break; 57 break;
58 58 case ArbitrationType::WaitIfLessThanWithTimeout:
59 if ((s32)Memory::Read32(address) <= value) {
60 Kernel::WaitCurrentThread(WAITTYPE_ARB, object, address);
61 Kernel::WakeThreadAfterDelay(GetCurrentThread(), nanoseconds);
62 HLE::Reschedule(__func__);
63 }
64 break;
59 case ArbitrationType::DecrementAndWaitIfLessThan: 65 case ArbitrationType::DecrementAndWaitIfLessThan:
60 { 66 {
61 s32 memory_value = Memory::Read32(address) - 1; 67 s32 memory_value = Memory::Read32(address) - 1;
@@ -66,6 +72,17 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3
66 } 72 }
67 break; 73 break;
68 } 74 }
75 case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout:
76 {
77 s32 memory_value = Memory::Read32(address) - 1;
78 Memory::Write32(address, memory_value);
79 if (memory_value <= value) {
80 Kernel::WaitCurrentThread(WAITTYPE_ARB, object, address);
81 Kernel::WakeThreadAfterDelay(GetCurrentThread(), nanoseconds);
82 HLE::Reschedule(__func__);
83 }
84 break;
85 }
69 86
70 default: 87 default:
71 LOG_ERROR(Kernel, "unknown type=%d", type); 88 LOG_ERROR(Kernel, "unknown type=%d", type);
diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h
index 030e7ad7b..3ffd465a2 100644
--- a/src/core/hle/kernel/address_arbiter.h
+++ b/src/core/hle/kernel/address_arbiter.h
@@ -28,7 +28,7 @@ enum class ArbitrationType : u32 {
28}; 28};
29 29
30/// Arbitrate an address 30/// Arbitrate an address
31ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value); 31ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value, u64 nanoseconds);
32 32
33/// Create an address arbiter 33/// Create an address arbiter
34Handle CreateAddressArbiter(const std::string& name = "Unknown"); 34Handle CreateAddressArbiter(const std::string& name = "Unknown");
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 5c6a3be80..a487f757c 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -194,7 +194,7 @@ static Result ArbitrateAddress(Handle arbiter, u32 address, u32 type, u32 value,
194 LOG_TRACE(Kernel_SVC, "called handle=0x%08X, address=0x%08X, type=0x%08X, value=0x%08X", arbiter, 194 LOG_TRACE(Kernel_SVC, "called handle=0x%08X, address=0x%08X, type=0x%08X, value=0x%08X", arbiter,
195 address, type, value); 195 address, type, value);
196 return Kernel::ArbitrateAddress(arbiter, static_cast<Kernel::ArbitrationType>(type), 196 return Kernel::ArbitrateAddress(arbiter, static_cast<Kernel::ArbitrationType>(type),
197 address, value).raw; 197 address, value, nanoseconds).raw;
198} 198}
199 199
200/// Used to output a message on a debug hardware unit - does nothing on a retail unit 200/// Used to output a message on a debug hardware unit - does nothing on a retail unit