diff options
| -rw-r--r-- | src/core/hle/kernel/address_arbiter.cpp | 25 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 8 | ||||
| -rw-r--r-- | src/core/memory.cpp | 4 | ||||
| -rw-r--r-- | src/core/memory.h | 7 |
4 files changed, 27 insertions, 17 deletions
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 972911e42..e9c8369d7 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp | |||
| @@ -17,7 +17,7 @@ namespace Kernel { | |||
| 17 | namespace AddressArbiter { | 17 | namespace AddressArbiter { |
| 18 | 18 | ||
| 19 | // Performs actual address waiting logic. | 19 | // Performs actual address waiting logic. |
| 20 | ResultCode WaitForAddress(VAddr address, s64 timeout) { | 20 | static ResultCode WaitForAddress(VAddr address, s64 timeout) { |
| 21 | SharedPtr<Thread> current_thread = GetCurrentThread(); | 21 | SharedPtr<Thread> current_thread = GetCurrentThread(); |
| 22 | current_thread->arb_wait_address = address; | 22 | current_thread->arb_wait_address = address; |
| 23 | current_thread->status = THREADSTATUS_WAIT_ARB; | 23 | current_thread->status = THREADSTATUS_WAIT_ARB; |
| @@ -26,12 +26,12 @@ ResultCode WaitForAddress(VAddr address, s64 timeout) { | |||
| 26 | current_thread->WakeAfterDelay(timeout); | 26 | current_thread->WakeAfterDelay(timeout); |
| 27 | 27 | ||
| 28 | Core::System::GetInstance().CpuCore(current_thread->processor_id).PrepareReschedule(); | 28 | Core::System::GetInstance().CpuCore(current_thread->processor_id).PrepareReschedule(); |
| 29 | // This should never actually execute. | 29 | return RESULT_TIMEOUT; |
| 30 | return RESULT_SUCCESS; | ||
| 31 | } | 30 | } |
| 32 | 31 | ||
| 33 | // Gets the threads waiting on an address. | 32 | // Gets the threads waiting on an address. |
| 34 | void GetThreadsWaitingOnAddress(std::vector<SharedPtr<Thread>>& waiting_threads, VAddr address) { | 33 | static void GetThreadsWaitingOnAddress(std::vector<SharedPtr<Thread>>& waiting_threads, |
| 34 | VAddr address) { | ||
| 35 | auto RetrieveWaitingThreads = | 35 | auto RetrieveWaitingThreads = |
| 36 | [](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr arb_addr) { | 36 | [](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr arb_addr) { |
| 37 | const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); | 37 | const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); |
| @@ -56,7 +56,7 @@ void GetThreadsWaitingOnAddress(std::vector<SharedPtr<Thread>>& waiting_threads, | |||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | // Wake up num_to_wake (or all) threads in a vector. | 58 | // Wake up num_to_wake (or all) threads in a vector. |
| 59 | void WakeThreads(std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_to_wake) { | 59 | static void WakeThreads(std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_to_wake) { |
| 60 | // Only process up to 'target' threads, unless 'target' is <= 0, in which case process | 60 | // Only process up to 'target' threads, unless 'target' is <= 0, in which case process |
| 61 | // them all. | 61 | // them all. |
| 62 | size_t last = waiting_threads.size(); | 62 | size_t last = waiting_threads.size(); |
| @@ -64,7 +64,6 @@ void WakeThreads(std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_to_wak | |||
| 64 | last = num_to_wake; | 64 | last = num_to_wake; |
| 65 | 65 | ||
| 66 | // Signal the waiting threads. | 66 | // Signal the waiting threads. |
| 67 | // TODO: Rescheduling should not occur while waking threads. How can it be prevented? | ||
| 68 | for (size_t i = 0; i < last; i++) { | 67 | for (size_t i = 0; i < last; i++) { |
| 69 | ASSERT(waiting_threads[i]->status = THREADSTATUS_WAIT_ARB); | 68 | ASSERT(waiting_threads[i]->status = THREADSTATUS_WAIT_ARB); |
| 70 | waiting_threads[i]->SetWaitSynchronizationResult(RESULT_SUCCESS); | 69 | waiting_threads[i]->SetWaitSynchronizationResult(RESULT_SUCCESS); |
| @@ -90,8 +89,8 @@ ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_ | |||
| 90 | return ERR_INVALID_ADDRESS_STATE; | 89 | return ERR_INVALID_ADDRESS_STATE; |
| 91 | } | 90 | } |
| 92 | 91 | ||
| 93 | if ((s32)Memory::Read32(address) == value) { | 92 | if (static_cast<s32>(Memory::Read32(address)) == value) { |
| 94 | Memory::Write32(address, (u32)(value + 1)); | 93 | Memory::Write32(address, static_cast<u32>(value + 1)); |
| 95 | } else { | 94 | } else { |
| 96 | return ERR_INVALID_STATE; | 95 | return ERR_INVALID_STATE; |
| 97 | } | 96 | } |
| @@ -122,8 +121,8 @@ ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 valu | |||
| 122 | updated_value = value; | 121 | updated_value = value; |
| 123 | } | 122 | } |
| 124 | 123 | ||
| 125 | if ((s32)Memory::Read32(address) == value) { | 124 | if (static_cast<s32>(Memory::Read32(address)) == value) { |
| 126 | Memory::Write32(address, (u32)(updated_value)); | 125 | Memory::Write32(address, static_cast<u32>(updated_value)); |
| 127 | } else { | 126 | } else { |
| 128 | return ERR_INVALID_STATE; | 127 | return ERR_INVALID_STATE; |
| 129 | } | 128 | } |
| @@ -139,9 +138,9 @@ ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, bool | |||
| 139 | return ERR_INVALID_ADDRESS_STATE; | 138 | return ERR_INVALID_ADDRESS_STATE; |
| 140 | } | 139 | } |
| 141 | 140 | ||
| 142 | s32 cur_value = (s32)Memory::Read32(address); | 141 | s32 cur_value = static_cast<s32>(Memory::Read32(address)); |
| 143 | if (cur_value < value) { | 142 | if (cur_value < value) { |
| 144 | Memory::Write32(address, (u32)(cur_value - 1)); | 143 | Memory::Write32(address, static_cast<u32>(cur_value - 1)); |
| 145 | } else { | 144 | } else { |
| 146 | return ERR_INVALID_STATE; | 145 | return ERR_INVALID_STATE; |
| 147 | } | 146 | } |
| @@ -160,7 +159,7 @@ ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) { | |||
| 160 | return ERR_INVALID_ADDRESS_STATE; | 159 | return ERR_INVALID_ADDRESS_STATE; |
| 161 | } | 160 | } |
| 162 | // Only wait for the address if equal. | 161 | // Only wait for the address if equal. |
| 163 | if ((s32)Memory::Read32(address) != value) { | 162 | if (static_cast<s32>(Memory::Read32(address)) != value) { |
| 164 | return ERR_INVALID_STATE; | 163 | return ERR_INVALID_STATE; |
| 165 | } | 164 | } |
| 166 | // Short-circuit without rescheduling, if timeout is zero. | 165 | // Short-circuit without rescheduling, if timeout is zero. |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 95ce2205a..1a36e0d02 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -695,7 +695,7 @@ static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout | |||
| 695 | NGLOG_WARNING(Kernel_SVC, "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, timeout={}", | 695 | NGLOG_WARNING(Kernel_SVC, "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, timeout={}", |
| 696 | address, type, value, timeout); | 696 | address, type, value, timeout); |
| 697 | // If the passed address is a kernel virtual address, return invalid memory state. | 697 | // If the passed address is a kernel virtual address, return invalid memory state. |
| 698 | if ((address + 0x8000000000LL) < 0x7FFFE00000LL) { | 698 | if (Memory::IsKernelVirtualAddress(address)) { |
| 699 | return ERR_INVALID_ADDRESS_STATE; | 699 | return ERR_INVALID_ADDRESS_STATE; |
| 700 | } | 700 | } |
| 701 | // If the address is not properly aligned to 4 bytes, return invalid address. | 701 | // If the address is not properly aligned to 4 bytes, return invalid address. |
| @@ -703,7 +703,7 @@ static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout | |||
| 703 | return ERR_INVALID_ADDRESS; | 703 | return ERR_INVALID_ADDRESS; |
| 704 | } | 704 | } |
| 705 | 705 | ||
| 706 | switch ((AddressArbiter::ArbitrationType)type) { | 706 | switch (static_cast<AddressArbiter::ArbitrationType>(type)) { |
| 707 | case AddressArbiter::ArbitrationType::WaitIfLessThan: | 707 | case AddressArbiter::ArbitrationType::WaitIfLessThan: |
| 708 | return AddressArbiter::WaitForAddressIfLessThan(address, value, timeout, false); | 708 | return AddressArbiter::WaitForAddressIfLessThan(address, value, timeout, false); |
| 709 | case AddressArbiter::ArbitrationType::DecrementAndWaitIfLessThan: | 709 | case AddressArbiter::ArbitrationType::DecrementAndWaitIfLessThan: |
| @@ -721,7 +721,7 @@ static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to | |||
| 721 | "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, num_to_wake=0x{:X}", address, | 721 | "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, num_to_wake=0x{:X}", address, |
| 722 | type, value, num_to_wake); | 722 | type, value, num_to_wake); |
| 723 | // If the passed address is a kernel virtual address, return invalid memory state. | 723 | // If the passed address is a kernel virtual address, return invalid memory state. |
| 724 | if ((address + 0x8000000000LL) < 0x7FFFE00000LL) { | 724 | if (Memory::IsKernelVirtualAddress(address)) { |
| 725 | return ERR_INVALID_ADDRESS_STATE; | 725 | return ERR_INVALID_ADDRESS_STATE; |
| 726 | } | 726 | } |
| 727 | // If the address is not properly aligned to 4 bytes, return invalid address. | 727 | // If the address is not properly aligned to 4 bytes, return invalid address. |
| @@ -729,7 +729,7 @@ static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to | |||
| 729 | return ERR_INVALID_ADDRESS; | 729 | return ERR_INVALID_ADDRESS; |
| 730 | } | 730 | } |
| 731 | 731 | ||
| 732 | switch ((AddressArbiter::SignalType)type) { | 732 | switch (static_cast<AddressArbiter::SignalType>(type)) { |
| 733 | case AddressArbiter::SignalType::Signal: | 733 | case AddressArbiter::SignalType::Signal: |
| 734 | return AddressArbiter::SignalToAddress(address, num_to_wake); | 734 | return AddressArbiter::SignalToAddress(address, num_to_wake); |
| 735 | case AddressArbiter::SignalType::IncrementAndSignalIfEqual: | 735 | case AddressArbiter::SignalType::IncrementAndSignalIfEqual: |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 3b81acd63..f070dee7d 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -241,6 +241,10 @@ bool IsValidVirtualAddress(const VAddr vaddr) { | |||
| 241 | return IsValidVirtualAddress(*Core::CurrentProcess(), vaddr); | 241 | return IsValidVirtualAddress(*Core::CurrentProcess(), vaddr); |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | bool IsKernelVirtualAddress(const VAddr vaddr) { | ||
| 245 | return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END; | ||
| 246 | } | ||
| 247 | |||
| 244 | bool IsValidPhysicalAddress(const PAddr paddr) { | 248 | bool IsValidPhysicalAddress(const PAddr paddr) { |
| 245 | return GetPhysicalPointer(paddr) != nullptr; | 249 | return GetPhysicalPointer(paddr) != nullptr; |
| 246 | } | 250 | } |
diff --git a/src/core/memory.h b/src/core/memory.h index 3f56a2c6a..8d5d017a4 100644 --- a/src/core/memory.h +++ b/src/core/memory.h | |||
| @@ -188,6 +188,11 @@ enum : VAddr { | |||
| 188 | MAP_REGION_VADDR = NEW_MAP_REGION_VADDR_END, | 188 | MAP_REGION_VADDR = NEW_MAP_REGION_VADDR_END, |
| 189 | MAP_REGION_SIZE = 0x1000000000, | 189 | MAP_REGION_SIZE = 0x1000000000, |
| 190 | MAP_REGION_VADDR_END = MAP_REGION_VADDR + MAP_REGION_SIZE, | 190 | MAP_REGION_VADDR_END = MAP_REGION_VADDR + MAP_REGION_SIZE, |
| 191 | |||
| 192 | /// Kernel Virtual Address Range | ||
| 193 | KERNEL_REGION_VADDR = 0xFFFFFF8000000000, | ||
| 194 | KERNEL_REGION_SIZE = 0x7FFFE00000, | ||
| 195 | KERNEL_REGION_END = KERNEL_REGION_VADDR + KERNEL_REGION_SIZE, | ||
| 191 | }; | 196 | }; |
| 192 | 197 | ||
| 193 | /// Currently active page table | 198 | /// Currently active page table |
| @@ -197,6 +202,8 @@ PageTable* GetCurrentPageTable(); | |||
| 197 | /// Determines if the given VAddr is valid for the specified process. | 202 | /// Determines if the given VAddr is valid for the specified process. |
| 198 | bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr); | 203 | bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr); |
| 199 | bool IsValidVirtualAddress(const VAddr addr); | 204 | bool IsValidVirtualAddress(const VAddr addr); |
| 205 | /// Determines if the given VAddr is a kernel address | ||
| 206 | bool IsKernelVirtualAddress(const VAddr addr); | ||
| 200 | 207 | ||
| 201 | bool IsValidPhysicalAddress(const PAddr addr); | 208 | bool IsValidPhysicalAddress(const PAddr addr); |
| 202 | 209 | ||