diff options
| author | 2019-11-28 11:43:17 -0500 | |
|---|---|---|
| committer | 2019-11-28 11:43:17 -0500 | |
| commit | e3ee017e91ef4d713f1af8cb60c5157e40d43f18 (patch) | |
| tree | e0a5b47cac1d548599b8ceba7f71b40746fe6b48 /src/core/hle/kernel | |
| parent | Merge pull request #3171 from lioncash/internal-link (diff) | |
| parent | core/memory; Migrate over SetCurrentPageTable() to the Memory class (diff) | |
| download | yuzu-e3ee017e91ef4d713f1af8cb60c5157e40d43f18.tar.gz yuzu-e3ee017e91ef4d713f1af8cb60c5157e40d43f18.tar.xz yuzu-e3ee017e91ef4d713f1af8cb60c5157e40d43f18.zip | |
Merge pull request #3169 from lioncash/memory
core/memory: Deglobalize memory management code
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/address_arbiter.cpp | 34 | ||||
| -rw-r--r-- | src/core/hle/kernel/client_session.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/client_session.h | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 21 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 18 | ||||
| -rw-r--r-- | src/core/hle/kernel/mutex.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/server_session.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/server_session.h | 9 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 51 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/vm_manager.cpp | 13 |
11 files changed, 105 insertions, 67 deletions
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 4859954cb..98d07fa5b 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp | |||
| @@ -67,23 +67,27 @@ ResultCode AddressArbiter::SignalToAddressOnly(VAddr address, s32 num_to_wake) { | |||
| 67 | 67 | ||
| 68 | ResultCode AddressArbiter::IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, | 68 | ResultCode AddressArbiter::IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, |
| 69 | s32 num_to_wake) { | 69 | s32 num_to_wake) { |
| 70 | auto& memory = system.Memory(); | ||
| 71 | |||
| 70 | // Ensure that we can write to the address. | 72 | // Ensure that we can write to the address. |
| 71 | if (!Memory::IsValidVirtualAddress(address)) { | 73 | if (!memory.IsValidVirtualAddress(address)) { |
| 72 | return ERR_INVALID_ADDRESS_STATE; | 74 | return ERR_INVALID_ADDRESS_STATE; |
| 73 | } | 75 | } |
| 74 | 76 | ||
| 75 | if (static_cast<s32>(Memory::Read32(address)) != value) { | 77 | if (static_cast<s32>(memory.Read32(address)) != value) { |
| 76 | return ERR_INVALID_STATE; | 78 | return ERR_INVALID_STATE; |
| 77 | } | 79 | } |
| 78 | 80 | ||
| 79 | Memory::Write32(address, static_cast<u32>(value + 1)); | 81 | memory.Write32(address, static_cast<u32>(value + 1)); |
| 80 | return SignalToAddressOnly(address, num_to_wake); | 82 | return SignalToAddressOnly(address, num_to_wake); |
| 81 | } | 83 | } |
| 82 | 84 | ||
| 83 | ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, | 85 | ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, |
| 84 | s32 num_to_wake) { | 86 | s32 num_to_wake) { |
| 87 | auto& memory = system.Memory(); | ||
| 88 | |||
| 85 | // Ensure that we can write to the address. | 89 | // Ensure that we can write to the address. |
| 86 | if (!Memory::IsValidVirtualAddress(address)) { | 90 | if (!memory.IsValidVirtualAddress(address)) { |
| 87 | return ERR_INVALID_ADDRESS_STATE; | 91 | return ERR_INVALID_ADDRESS_STATE; |
| 88 | } | 92 | } |
| 89 | 93 | ||
| @@ -109,11 +113,11 @@ ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr a | |||
| 109 | } | 113 | } |
| 110 | } | 114 | } |
| 111 | 115 | ||
| 112 | if (static_cast<s32>(Memory::Read32(address)) != value) { | 116 | if (static_cast<s32>(memory.Read32(address)) != value) { |
| 113 | return ERR_INVALID_STATE; | 117 | return ERR_INVALID_STATE; |
| 114 | } | 118 | } |
| 115 | 119 | ||
| 116 | Memory::Write32(address, static_cast<u32>(updated_value)); | 120 | memory.Write32(address, static_cast<u32>(updated_value)); |
| 117 | WakeThreads(waiting_threads, num_to_wake); | 121 | WakeThreads(waiting_threads, num_to_wake); |
| 118 | return RESULT_SUCCESS; | 122 | return RESULT_SUCCESS; |
| 119 | } | 123 | } |
| @@ -134,18 +138,20 @@ ResultCode AddressArbiter::WaitForAddress(VAddr address, ArbitrationType type, s | |||
| 134 | 138 | ||
| 135 | ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, | 139 | ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, |
| 136 | bool should_decrement) { | 140 | bool should_decrement) { |
| 141 | auto& memory = system.Memory(); | ||
| 142 | |||
| 137 | // Ensure that we can read the address. | 143 | // Ensure that we can read the address. |
| 138 | if (!Memory::IsValidVirtualAddress(address)) { | 144 | if (!memory.IsValidVirtualAddress(address)) { |
| 139 | return ERR_INVALID_ADDRESS_STATE; | 145 | return ERR_INVALID_ADDRESS_STATE; |
| 140 | } | 146 | } |
| 141 | 147 | ||
| 142 | const s32 cur_value = static_cast<s32>(Memory::Read32(address)); | 148 | const s32 cur_value = static_cast<s32>(memory.Read32(address)); |
| 143 | if (cur_value >= value) { | 149 | if (cur_value >= value) { |
| 144 | return ERR_INVALID_STATE; | 150 | return ERR_INVALID_STATE; |
| 145 | } | 151 | } |
| 146 | 152 | ||
| 147 | if (should_decrement) { | 153 | if (should_decrement) { |
| 148 | Memory::Write32(address, static_cast<u32>(cur_value - 1)); | 154 | memory.Write32(address, static_cast<u32>(cur_value - 1)); |
| 149 | } | 155 | } |
| 150 | 156 | ||
| 151 | // Short-circuit without rescheduling, if timeout is zero. | 157 | // Short-circuit without rescheduling, if timeout is zero. |
| @@ -157,15 +163,19 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6 | |||
| 157 | } | 163 | } |
| 158 | 164 | ||
| 159 | ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) { | 165 | ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) { |
| 166 | auto& memory = system.Memory(); | ||
| 167 | |||
| 160 | // Ensure that we can read the address. | 168 | // Ensure that we can read the address. |
| 161 | if (!Memory::IsValidVirtualAddress(address)) { | 169 | if (!memory.IsValidVirtualAddress(address)) { |
| 162 | return ERR_INVALID_ADDRESS_STATE; | 170 | return ERR_INVALID_ADDRESS_STATE; |
| 163 | } | 171 | } |
| 172 | |||
| 164 | // Only wait for the address if equal. | 173 | // Only wait for the address if equal. |
| 165 | if (static_cast<s32>(Memory::Read32(address)) != value) { | 174 | if (static_cast<s32>(memory.Read32(address)) != value) { |
| 166 | return ERR_INVALID_STATE; | 175 | return ERR_INVALID_STATE; |
| 167 | } | 176 | } |
| 168 | // Short-circuit without rescheduling, if timeout is zero. | 177 | |
| 178 | // Short-circuit without rescheduling if timeout is zero. | ||
| 169 | if (timeout == 0) { | 179 | if (timeout == 0) { |
| 170 | return RESULT_TIMEOUT; | 180 | return RESULT_TIMEOUT; |
| 171 | } | 181 | } |
diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp index 5995a6556..9849dbe91 100644 --- a/src/core/hle/kernel/client_session.cpp +++ b/src/core/hle/kernel/client_session.cpp | |||
| @@ -21,10 +21,10 @@ ClientSession::~ClientSession() { | |||
| 21 | } | 21 | } |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | ResultCode ClientSession::SendSyncRequest(Thread* thread) { | 24 | ResultCode ClientSession::SendSyncRequest(Thread* thread, Memory::Memory& memory) { |
| 25 | // Signal the server session that new data is available | 25 | // Signal the server session that new data is available |
| 26 | if (auto server = parent->server.lock()) { | 26 | if (auto server = parent->server.lock()) { |
| 27 | return server->HandleSyncRequest(SharedFrom(thread)); | 27 | return server->HandleSyncRequest(SharedFrom(thread), memory); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | return ERR_SESSION_CLOSED_BY_REMOTE; | 30 | return ERR_SESSION_CLOSED_BY_REMOTE; |
diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h index 5ae41db29..484dd7bc9 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/client_session.h | |||
| @@ -10,6 +10,10 @@ | |||
| 10 | 10 | ||
| 11 | union ResultCode; | 11 | union ResultCode; |
| 12 | 12 | ||
| 13 | namespace Memory { | ||
| 14 | class Memory; | ||
| 15 | } | ||
| 16 | |||
| 13 | namespace Kernel { | 17 | namespace Kernel { |
| 14 | 18 | ||
| 15 | class KernelCore; | 19 | class KernelCore; |
| @@ -37,7 +41,7 @@ public: | |||
| 37 | return HANDLE_TYPE; | 41 | return HANDLE_TYPE; |
| 38 | } | 42 | } |
| 39 | 43 | ||
| 40 | ResultCode SendSyncRequest(Thread* thread); | 44 | ResultCode SendSyncRequest(Thread* thread, Memory::Memory& memory); |
| 41 | 45 | ||
| 42 | private: | 46 | private: |
| 43 | /// The parent session, which links to the server endpoint. | 47 | /// The parent session, which links to the server endpoint. |
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index be24cef06..8b01567a8 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -214,10 +214,11 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const HandleTabl | |||
| 214 | ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) { | 214 | ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) { |
| 215 | auto& owner_process = *thread.GetOwnerProcess(); | 215 | auto& owner_process = *thread.GetOwnerProcess(); |
| 216 | auto& handle_table = owner_process.GetHandleTable(); | 216 | auto& handle_table = owner_process.GetHandleTable(); |
| 217 | auto& memory = Core::System::GetInstance().Memory(); | ||
| 217 | 218 | ||
| 218 | std::array<u32, IPC::COMMAND_BUFFER_LENGTH> dst_cmdbuf; | 219 | std::array<u32, IPC::COMMAND_BUFFER_LENGTH> dst_cmdbuf; |
| 219 | Memory::ReadBlock(owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(), | 220 | memory.ReadBlock(owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(), |
| 220 | dst_cmdbuf.size() * sizeof(u32)); | 221 | dst_cmdbuf.size() * sizeof(u32)); |
| 221 | 222 | ||
| 222 | // The header was already built in the internal command buffer. Attempt to parse it to verify | 223 | // The header was already built in the internal command buffer. Attempt to parse it to verify |
| 223 | // the integrity and then copy it over to the target command buffer. | 224 | // the integrity and then copy it over to the target command buffer. |
| @@ -273,8 +274,8 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) { | |||
| 273 | } | 274 | } |
| 274 | 275 | ||
| 275 | // Copy the translated command buffer back into the thread's command buffer area. | 276 | // Copy the translated command buffer back into the thread's command buffer area. |
| 276 | Memory::WriteBlock(owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(), | 277 | memory.WriteBlock(owner_process, thread.GetTLSAddress(), dst_cmdbuf.data(), |
| 277 | dst_cmdbuf.size() * sizeof(u32)); | 278 | dst_cmdbuf.size() * sizeof(u32)); |
| 278 | 279 | ||
| 279 | return RESULT_SUCCESS; | 280 | return RESULT_SUCCESS; |
| 280 | } | 281 | } |
| @@ -282,15 +283,14 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) { | |||
| 282 | std::vector<u8> HLERequestContext::ReadBuffer(int buffer_index) const { | 283 | std::vector<u8> HLERequestContext::ReadBuffer(int buffer_index) const { |
| 283 | std::vector<u8> buffer; | 284 | std::vector<u8> buffer; |
| 284 | const bool is_buffer_a{BufferDescriptorA().size() && BufferDescriptorA()[buffer_index].Size()}; | 285 | const bool is_buffer_a{BufferDescriptorA().size() && BufferDescriptorA()[buffer_index].Size()}; |
| 286 | auto& memory = Core::System::GetInstance().Memory(); | ||
| 285 | 287 | ||
| 286 | if (is_buffer_a) { | 288 | if (is_buffer_a) { |
| 287 | buffer.resize(BufferDescriptorA()[buffer_index].Size()); | 289 | buffer.resize(BufferDescriptorA()[buffer_index].Size()); |
| 288 | Memory::ReadBlock(BufferDescriptorA()[buffer_index].Address(), buffer.data(), | 290 | memory.ReadBlock(BufferDescriptorA()[buffer_index].Address(), buffer.data(), buffer.size()); |
| 289 | buffer.size()); | ||
| 290 | } else { | 291 | } else { |
| 291 | buffer.resize(BufferDescriptorX()[buffer_index].Size()); | 292 | buffer.resize(BufferDescriptorX()[buffer_index].Size()); |
| 292 | Memory::ReadBlock(BufferDescriptorX()[buffer_index].Address(), buffer.data(), | 293 | memory.ReadBlock(BufferDescriptorX()[buffer_index].Address(), buffer.data(), buffer.size()); |
| 293 | buffer.size()); | ||
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | return buffer; | 296 | return buffer; |
| @@ -311,10 +311,11 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size, | |||
| 311 | size = buffer_size; // TODO(bunnei): This needs to be HW tested | 311 | size = buffer_size; // TODO(bunnei): This needs to be HW tested |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | auto& memory = Core::System::GetInstance().Memory(); | ||
| 314 | if (is_buffer_b) { | 315 | if (is_buffer_b) { |
| 315 | Memory::WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size); | 316 | memory.WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size); |
| 316 | } else { | 317 | } else { |
| 317 | Memory::WriteBlock(BufferDescriptorC()[buffer_index].Address(), buffer, size); | 318 | memory.WriteBlock(BufferDescriptorC()[buffer_index].Address(), buffer, size); |
| 318 | } | 319 | } |
| 319 | 320 | ||
| 320 | return size; | 321 | return size; |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index a9851113a..1c90546a4 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -154,6 +154,16 @@ struct KernelCore::Impl { | |||
| 154 | system.CoreTiming().ScheduleEvent(time_interval, preemption_event); | 154 | system.CoreTiming().ScheduleEvent(time_interval, preemption_event); |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | void MakeCurrentProcess(Process* process) { | ||
| 158 | current_process = process; | ||
| 159 | |||
| 160 | if (process == nullptr) { | ||
| 161 | return; | ||
| 162 | } | ||
| 163 | |||
| 164 | system.Memory().SetCurrentPageTable(*process); | ||
| 165 | } | ||
| 166 | |||
| 157 | std::atomic<u32> next_object_id{0}; | 167 | std::atomic<u32> next_object_id{0}; |
| 158 | std::atomic<u64> next_kernel_process_id{Process::InitialKIPIDMin}; | 168 | std::atomic<u64> next_kernel_process_id{Process::InitialKIPIDMin}; |
| 159 | std::atomic<u64> next_user_process_id{Process::ProcessIDMin}; | 169 | std::atomic<u64> next_user_process_id{Process::ProcessIDMin}; |
| @@ -208,13 +218,7 @@ void KernelCore::AppendNewProcess(std::shared_ptr<Process> process) { | |||
| 208 | } | 218 | } |
| 209 | 219 | ||
| 210 | void KernelCore::MakeCurrentProcess(Process* process) { | 220 | void KernelCore::MakeCurrentProcess(Process* process) { |
| 211 | impl->current_process = process; | 221 | impl->MakeCurrentProcess(process); |
| 212 | |||
| 213 | if (process == nullptr) { | ||
| 214 | return; | ||
| 215 | } | ||
| 216 | |||
| 217 | Memory::SetCurrentPageTable(*process); | ||
| 218 | } | 222 | } |
| 219 | 223 | ||
| 220 | Process* KernelCore::CurrentProcess() { | 224 | Process* KernelCore::CurrentProcess() { |
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 8493d0f78..061e9bcb0 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp | |||
| @@ -79,7 +79,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, | |||
| 79 | // thread. | 79 | // thread. |
| 80 | ASSERT(requesting_thread == current_thread); | 80 | ASSERT(requesting_thread == current_thread); |
| 81 | 81 | ||
| 82 | const u32 addr_value = Memory::Read32(address); | 82 | const u32 addr_value = system.Memory().Read32(address); |
| 83 | 83 | ||
| 84 | // If the mutex isn't being held, just return success. | 84 | // If the mutex isn't being held, just return success. |
| 85 | if (addr_value != (holding_thread_handle | Mutex::MutexHasWaitersFlag)) { | 85 | if (addr_value != (holding_thread_handle | Mutex::MutexHasWaitersFlag)) { |
| @@ -117,7 +117,7 @@ ResultCode Mutex::Release(VAddr address) { | |||
| 117 | 117 | ||
| 118 | // There are no more threads waiting for the mutex, release it completely. | 118 | // There are no more threads waiting for the mutex, release it completely. |
| 119 | if (thread == nullptr) { | 119 | if (thread == nullptr) { |
| 120 | Memory::Write32(address, 0); | 120 | system.Memory().Write32(address, 0); |
| 121 | return RESULT_SUCCESS; | 121 | return RESULT_SUCCESS; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| @@ -132,7 +132,7 @@ ResultCode Mutex::Release(VAddr address) { | |||
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | // Grant the mutex to the next waiting thread and resume it. | 134 | // Grant the mutex to the next waiting thread and resume it. |
| 135 | Memory::Write32(address, mutex_value); | 135 | system.Memory().Write32(address, mutex_value); |
| 136 | 136 | ||
| 137 | ASSERT(thread->GetStatus() == ThreadStatus::WaitMutex); | 137 | ASSERT(thread->GetStatus() == ThreadStatus::WaitMutex); |
| 138 | thread->ResumeFromWait(); | 138 | thread->ResumeFromWait(); |
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index c7db21eb2..1198c7a97 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include "core/hle/kernel/server_session.h" | 19 | #include "core/hle/kernel/server_session.h" |
| 20 | #include "core/hle/kernel/session.h" | 20 | #include "core/hle/kernel/session.h" |
| 21 | #include "core/hle/kernel/thread.h" | 21 | #include "core/hle/kernel/thread.h" |
| 22 | #include "core/memory.h" | ||
| 22 | 23 | ||
| 23 | namespace Kernel { | 24 | namespace Kernel { |
| 24 | 25 | ||
| @@ -127,12 +128,13 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con | |||
| 127 | return RESULT_SUCCESS; | 128 | return RESULT_SUCCESS; |
| 128 | } | 129 | } |
| 129 | 130 | ||
| 130 | ResultCode ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread) { | 131 | ResultCode ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread, |
| 132 | Memory::Memory& memory) { | ||
| 131 | // The ServerSession received a sync request, this means that there's new data available | 133 | // The ServerSession received a sync request, this means that there's new data available |
| 132 | // from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or | 134 | // from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or |
| 133 | // similar. | 135 | // similar. |
| 134 | Kernel::HLERequestContext context(SharedFrom(this), thread); | 136 | Kernel::HLERequestContext context(SharedFrom(this), thread); |
| 135 | u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress()); | 137 | u32* cmd_buf = (u32*)memory.GetPointer(thread->GetTLSAddress()); |
| 136 | context.PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); | 138 | context.PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); |
| 137 | 139 | ||
| 138 | ResultCode result = RESULT_SUCCESS; | 140 | ResultCode result = RESULT_SUCCESS; |
diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 8a65647b6..641709a45 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h | |||
| @@ -13,6 +13,10 @@ | |||
| 13 | #include "core/hle/kernel/wait_object.h" | 13 | #include "core/hle/kernel/wait_object.h" |
| 14 | #include "core/hle/result.h" | 14 | #include "core/hle/result.h" |
| 15 | 15 | ||
| 16 | namespace Memory { | ||
| 17 | class Memory; | ||
| 18 | } | ||
| 19 | |||
| 16 | namespace Kernel { | 20 | namespace Kernel { |
| 17 | 21 | ||
| 18 | class ClientPort; | 22 | class ClientPort; |
| @@ -85,10 +89,13 @@ public: | |||
| 85 | 89 | ||
| 86 | /** | 90 | /** |
| 87 | * Handle a sync request from the emulated application. | 91 | * Handle a sync request from the emulated application. |
| 92 | * | ||
| 88 | * @param thread Thread that initiated the request. | 93 | * @param thread Thread that initiated the request. |
| 94 | * @param memory Memory context to handle the sync request under. | ||
| 95 | * | ||
| 89 | * @returns ResultCode from the operation. | 96 | * @returns ResultCode from the operation. |
| 90 | */ | 97 | */ |
| 91 | ResultCode HandleSyncRequest(std::shared_ptr<Thread> thread); | 98 | ResultCode HandleSyncRequest(std::shared_ptr<Thread> thread, Memory::Memory& memory); |
| 92 | 99 | ||
| 93 | bool ShouldWait(const Thread* thread) const override; | 100 | bool ShouldWait(const Thread* thread) const override; |
| 94 | 101 | ||
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 9928b3a26..db3ae3eb8 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -332,7 +332,9 @@ static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_ad | |||
| 332 | /// Connect to an OS service given the port name, returns the handle to the port to out | 332 | /// Connect to an OS service given the port name, returns the handle to the port to out |
| 333 | static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, | 333 | static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, |
| 334 | VAddr port_name_address) { | 334 | VAddr port_name_address) { |
| 335 | if (!Memory::IsValidVirtualAddress(port_name_address)) { | 335 | auto& memory = system.Memory(); |
| 336 | |||
| 337 | if (!memory.IsValidVirtualAddress(port_name_address)) { | ||
| 336 | LOG_ERROR(Kernel_SVC, | 338 | LOG_ERROR(Kernel_SVC, |
| 337 | "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}", | 339 | "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}", |
| 338 | port_name_address); | 340 | port_name_address); |
| @@ -341,7 +343,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, | |||
| 341 | 343 | ||
| 342 | static constexpr std::size_t PortNameMaxLength = 11; | 344 | static constexpr std::size_t PortNameMaxLength = 11; |
| 343 | // Read 1 char beyond the max allowed port name to detect names that are too long. | 345 | // Read 1 char beyond the max allowed port name to detect names that are too long. |
| 344 | std::string port_name = Memory::ReadCString(port_name_address, PortNameMaxLength + 1); | 346 | const std::string port_name = memory.ReadCString(port_name_address, PortNameMaxLength + 1); |
| 345 | if (port_name.size() > PortNameMaxLength) { | 347 | if (port_name.size() > PortNameMaxLength) { |
| 346 | LOG_ERROR(Kernel_SVC, "Port name is too long, expected {} but got {}", PortNameMaxLength, | 348 | LOG_ERROR(Kernel_SVC, "Port name is too long, expected {} but got {}", PortNameMaxLength, |
| 347 | port_name.size()); | 349 | port_name.size()); |
| @@ -383,7 +385,7 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | |||
| 383 | 385 | ||
| 384 | // TODO(Subv): svcSendSyncRequest should put the caller thread to sleep while the server | 386 | // TODO(Subv): svcSendSyncRequest should put the caller thread to sleep while the server |
| 385 | // responds and cause a reschedule. | 387 | // responds and cause a reschedule. |
| 386 | return session->SendSyncRequest(system.CurrentScheduler().GetCurrentThread()); | 388 | return session->SendSyncRequest(system.CurrentScheduler().GetCurrentThread(), system.Memory()); |
| 387 | } | 389 | } |
| 388 | 390 | ||
| 389 | /// Get the ID for the specified thread. | 391 | /// Get the ID for the specified thread. |
| @@ -452,7 +454,8 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr | |||
| 452 | LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", | 454 | LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", |
| 453 | handles_address, handle_count, nano_seconds); | 455 | handles_address, handle_count, nano_seconds); |
| 454 | 456 | ||
| 455 | if (!Memory::IsValidVirtualAddress(handles_address)) { | 457 | auto& memory = system.Memory(); |
| 458 | if (!memory.IsValidVirtualAddress(handles_address)) { | ||
| 456 | LOG_ERROR(Kernel_SVC, | 459 | LOG_ERROR(Kernel_SVC, |
| 457 | "Handle address is not a valid virtual address, handle_address=0x{:016X}", | 460 | "Handle address is not a valid virtual address, handle_address=0x{:016X}", |
| 458 | handles_address); | 461 | handles_address); |
| @@ -474,7 +477,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr | |||
| 474 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 477 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 475 | 478 | ||
| 476 | for (u64 i = 0; i < handle_count; ++i) { | 479 | for (u64 i = 0; i < handle_count; ++i) { |
| 477 | const Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); | 480 | const Handle handle = memory.Read32(handles_address + i * sizeof(Handle)); |
| 478 | const auto object = handle_table.Get<WaitObject>(handle); | 481 | const auto object = handle_table.Get<WaitObject>(handle); |
| 479 | 482 | ||
| 480 | if (object == nullptr) { | 483 | if (object == nullptr) { |
| @@ -616,13 +619,15 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { | |||
| 616 | return; | 619 | return; |
| 617 | } | 620 | } |
| 618 | 621 | ||
| 622 | auto& memory = system.Memory(); | ||
| 623 | |||
| 619 | // This typically is an error code so we're going to assume this is the case | 624 | // This typically is an error code so we're going to assume this is the case |
| 620 | if (sz == sizeof(u32)) { | 625 | if (sz == sizeof(u32)) { |
| 621 | LOG_CRITICAL(Debug_Emulated, "debug_buffer_err_code={:X}", Memory::Read32(addr)); | 626 | LOG_CRITICAL(Debug_Emulated, "debug_buffer_err_code={:X}", memory.Read32(addr)); |
| 622 | } else { | 627 | } else { |
| 623 | // We don't know what's in here so we'll hexdump it | 628 | // We don't know what's in here so we'll hexdump it |
| 624 | debug_buffer.resize(sz); | 629 | debug_buffer.resize(sz); |
| 625 | Memory::ReadBlock(addr, debug_buffer.data(), sz); | 630 | memory.ReadBlock(addr, debug_buffer.data(), sz); |
| 626 | std::string hexdump; | 631 | std::string hexdump; |
| 627 | for (std::size_t i = 0; i < debug_buffer.size(); i++) { | 632 | for (std::size_t i = 0; i < debug_buffer.size(); i++) { |
| 628 | hexdump += fmt::format("{:02X} ", debug_buffer[i]); | 633 | hexdump += fmt::format("{:02X} ", debug_buffer[i]); |
| @@ -712,7 +717,7 @@ static void OutputDebugString([[maybe_unused]] Core::System& system, VAddr addre | |||
| 712 | } | 717 | } |
| 713 | 718 | ||
| 714 | std::string str(len, '\0'); | 719 | std::string str(len, '\0'); |
| 715 | Memory::ReadBlock(address, str.data(), str.size()); | 720 | system.Memory().ReadBlock(address, str.data(), str.size()); |
| 716 | LOG_DEBUG(Debug_Emulated, "{}", str); | 721 | LOG_DEBUG(Debug_Emulated, "{}", str); |
| 717 | } | 722 | } |
| 718 | 723 | ||
| @@ -1115,7 +1120,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, H | |||
| 1115 | std::fill(ctx.vector_registers.begin() + 16, ctx.vector_registers.end(), u128{}); | 1120 | std::fill(ctx.vector_registers.begin() + 16, ctx.vector_registers.end(), u128{}); |
| 1116 | } | 1121 | } |
| 1117 | 1122 | ||
| 1118 | Memory::WriteBlock(thread_context, &ctx, sizeof(ctx)); | 1123 | system.Memory().WriteBlock(thread_context, &ctx, sizeof(ctx)); |
| 1119 | return RESULT_SUCCESS; | 1124 | return RESULT_SUCCESS; |
| 1120 | } | 1125 | } |
| 1121 | 1126 | ||
| @@ -1275,20 +1280,21 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add | |||
| 1275 | return ERR_INVALID_HANDLE; | 1280 | return ERR_INVALID_HANDLE; |
| 1276 | } | 1281 | } |
| 1277 | 1282 | ||
| 1283 | auto& memory = system.Memory(); | ||
| 1278 | const auto& vm_manager = process->VMManager(); | 1284 | const auto& vm_manager = process->VMManager(); |
| 1279 | const MemoryInfo memory_info = vm_manager.QueryMemory(address); | 1285 | const MemoryInfo memory_info = vm_manager.QueryMemory(address); |
| 1280 | 1286 | ||
| 1281 | Memory::Write64(memory_info_address, memory_info.base_address); | 1287 | memory.Write64(memory_info_address, memory_info.base_address); |
| 1282 | Memory::Write64(memory_info_address + 8, memory_info.size); | 1288 | memory.Write64(memory_info_address + 8, memory_info.size); |
| 1283 | Memory::Write32(memory_info_address + 16, memory_info.state); | 1289 | memory.Write32(memory_info_address + 16, memory_info.state); |
| 1284 | Memory::Write32(memory_info_address + 20, memory_info.attributes); | 1290 | memory.Write32(memory_info_address + 20, memory_info.attributes); |
| 1285 | Memory::Write32(memory_info_address + 24, memory_info.permission); | 1291 | memory.Write32(memory_info_address + 24, memory_info.permission); |
| 1286 | Memory::Write32(memory_info_address + 32, memory_info.ipc_ref_count); | 1292 | memory.Write32(memory_info_address + 32, memory_info.ipc_ref_count); |
| 1287 | Memory::Write32(memory_info_address + 28, memory_info.device_ref_count); | 1293 | memory.Write32(memory_info_address + 28, memory_info.device_ref_count); |
| 1288 | Memory::Write32(memory_info_address + 36, 0); | 1294 | memory.Write32(memory_info_address + 36, 0); |
| 1289 | 1295 | ||
| 1290 | // Page info appears to be currently unused by the kernel and is always set to zero. | 1296 | // Page info appears to be currently unused by the kernel and is always set to zero. |
| 1291 | Memory::Write32(page_info_address, 0); | 1297 | memory.Write32(page_info_address, 0); |
| 1292 | 1298 | ||
| 1293 | return RESULT_SUCCESS; | 1299 | return RESULT_SUCCESS; |
| 1294 | } | 1300 | } |
| @@ -1672,6 +1678,7 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var | |||
| 1672 | 1678 | ||
| 1673 | const std::size_t current_core = system.CurrentCoreIndex(); | 1679 | const std::size_t current_core = system.CurrentCoreIndex(); |
| 1674 | auto& monitor = system.Monitor(); | 1680 | auto& monitor = system.Monitor(); |
| 1681 | auto& memory = system.Memory(); | ||
| 1675 | 1682 | ||
| 1676 | // Atomically read the value of the mutex. | 1683 | // Atomically read the value of the mutex. |
| 1677 | u32 mutex_val = 0; | 1684 | u32 mutex_val = 0; |
| @@ -1681,7 +1688,7 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var | |||
| 1681 | monitor.SetExclusive(current_core, mutex_address); | 1688 | monitor.SetExclusive(current_core, mutex_address); |
| 1682 | 1689 | ||
| 1683 | // If the mutex is not yet acquired, acquire it. | 1690 | // If the mutex is not yet acquired, acquire it. |
| 1684 | mutex_val = Memory::Read32(mutex_address); | 1691 | mutex_val = memory.Read32(mutex_address); |
| 1685 | 1692 | ||
| 1686 | if (mutex_val != 0) { | 1693 | if (mutex_val != 0) { |
| 1687 | update_val = mutex_val | Mutex::MutexHasWaitersFlag; | 1694 | update_val = mutex_val | Mutex::MutexHasWaitersFlag; |
| @@ -2284,12 +2291,13 @@ static ResultCode GetProcessList(Core::System& system, u32* out_num_processes, | |||
| 2284 | return ERR_INVALID_ADDRESS_STATE; | 2291 | return ERR_INVALID_ADDRESS_STATE; |
| 2285 | } | 2292 | } |
| 2286 | 2293 | ||
| 2294 | auto& memory = system.Memory(); | ||
| 2287 | const auto& process_list = kernel.GetProcessList(); | 2295 | const auto& process_list = kernel.GetProcessList(); |
| 2288 | const auto num_processes = process_list.size(); | 2296 | const auto num_processes = process_list.size(); |
| 2289 | const auto copy_amount = std::min(std::size_t{out_process_ids_size}, num_processes); | 2297 | const auto copy_amount = std::min(std::size_t{out_process_ids_size}, num_processes); |
| 2290 | 2298 | ||
| 2291 | for (std::size_t i = 0; i < copy_amount; ++i) { | 2299 | for (std::size_t i = 0; i < copy_amount; ++i) { |
| 2292 | Memory::Write64(out_process_ids, process_list[i]->GetProcessID()); | 2300 | memory.Write64(out_process_ids, process_list[i]->GetProcessID()); |
| 2293 | out_process_ids += sizeof(u64); | 2301 | out_process_ids += sizeof(u64); |
| 2294 | } | 2302 | } |
| 2295 | 2303 | ||
| @@ -2323,13 +2331,14 @@ static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAdd | |||
| 2323 | return ERR_INVALID_ADDRESS_STATE; | 2331 | return ERR_INVALID_ADDRESS_STATE; |
| 2324 | } | 2332 | } |
| 2325 | 2333 | ||
| 2334 | auto& memory = system.Memory(); | ||
| 2326 | const auto& thread_list = current_process->GetThreadList(); | 2335 | const auto& thread_list = current_process->GetThreadList(); |
| 2327 | const auto num_threads = thread_list.size(); | 2336 | const auto num_threads = thread_list.size(); |
| 2328 | const auto copy_amount = std::min(std::size_t{out_thread_ids_size}, num_threads); | 2337 | const auto copy_amount = std::min(std::size_t{out_thread_ids_size}, num_threads); |
| 2329 | 2338 | ||
| 2330 | auto list_iter = thread_list.cbegin(); | 2339 | auto list_iter = thread_list.cbegin(); |
| 2331 | for (std::size_t i = 0; i < copy_amount; ++i, ++list_iter) { | 2340 | for (std::size_t i = 0; i < copy_amount; ++i, ++list_iter) { |
| 2332 | Memory::Write64(out_thread_ids, (*list_iter)->GetThreadID()); | 2341 | memory.Write64(out_thread_ids, (*list_iter)->GetThreadID()); |
| 2333 | out_thread_ids += sizeof(u64); | 2342 | out_thread_ids += sizeof(u64); |
| 2334 | } | 2343 | } |
| 2335 | 2344 | ||
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 735019d96..e84e5ce0d 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -162,13 +162,13 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(KernelCore& kernel, std::strin | |||
| 162 | return ERR_INVALID_PROCESSOR_ID; | 162 | return ERR_INVALID_PROCESSOR_ID; |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | if (!Memory::IsValidVirtualAddress(owner_process, entry_point)) { | 165 | auto& system = Core::System::GetInstance(); |
| 166 | if (!system.Memory().IsValidVirtualAddress(owner_process, entry_point)) { | ||
| 166 | LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point); | 167 | LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point); |
| 167 | // TODO (bunnei): Find the correct error code to use here | 168 | // TODO (bunnei): Find the correct error code to use here |
| 168 | return RESULT_UNKNOWN; | 169 | return RESULT_UNKNOWN; |
| 169 | } | 170 | } |
| 170 | 171 | ||
| 171 | auto& system = Core::System::GetInstance(); | ||
| 172 | std::shared_ptr<Thread> thread = std::make_shared<Thread>(kernel); | 172 | std::shared_ptr<Thread> thread = std::make_shared<Thread>(kernel); |
| 173 | 173 | ||
| 174 | thread->thread_id = kernel.CreateNewThreadID(); | 174 | thread->thread_id = kernel.CreateNewThreadID(); |
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index e6eee09d7..a9a20ef76 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | #include "core/hle/kernel/resource_limit.h" | 16 | #include "core/hle/kernel/resource_limit.h" |
| 17 | #include "core/hle/kernel/vm_manager.h" | 17 | #include "core/hle/kernel/vm_manager.h" |
| 18 | #include "core/memory.h" | 18 | #include "core/memory.h" |
| 19 | #include "core/memory_setup.h" | ||
| 20 | 19 | ||
| 21 | namespace Kernel { | 20 | namespace Kernel { |
| 22 | namespace { | 21 | namespace { |
| @@ -786,19 +785,21 @@ void VMManager::MergeAdjacentVMA(VirtualMemoryArea& left, const VirtualMemoryAre | |||
| 786 | } | 785 | } |
| 787 | 786 | ||
| 788 | void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) { | 787 | void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) { |
| 788 | auto& memory = system.Memory(); | ||
| 789 | |||
| 789 | switch (vma.type) { | 790 | switch (vma.type) { |
| 790 | case VMAType::Free: | 791 | case VMAType::Free: |
| 791 | Memory::UnmapRegion(page_table, vma.base, vma.size); | 792 | memory.UnmapRegion(page_table, vma.base, vma.size); |
| 792 | break; | 793 | break; |
| 793 | case VMAType::AllocatedMemoryBlock: | 794 | case VMAType::AllocatedMemoryBlock: |
| 794 | Memory::MapMemoryRegion(page_table, vma.base, vma.size, | 795 | memory.MapMemoryRegion(page_table, vma.base, vma.size, |
| 795 | vma.backing_block->data() + vma.offset); | 796 | vma.backing_block->data() + vma.offset); |
| 796 | break; | 797 | break; |
| 797 | case VMAType::BackingMemory: | 798 | case VMAType::BackingMemory: |
| 798 | Memory::MapMemoryRegion(page_table, vma.base, vma.size, vma.backing_memory); | 799 | memory.MapMemoryRegion(page_table, vma.base, vma.size, vma.backing_memory); |
| 799 | break; | 800 | break; |
| 800 | case VMAType::MMIO: | 801 | case VMAType::MMIO: |
| 801 | Memory::MapIoRegion(page_table, vma.base, vma.size, vma.mmio_handler); | 802 | memory.MapIoRegion(page_table, vma.base, vma.size, vma.mmio_handler); |
| 802 | break; | 803 | break; |
| 803 | } | 804 | } |
| 804 | } | 805 | } |