diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/init/init_slab_setup.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_client_session.cpp | 15 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_linked_list.h | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_page_buffer.h | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_server_session.cpp | 143 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_server_session.h | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_session_request.cpp | 61 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_session_request.h | 307 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_shared_memory_info.h | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread_local_page.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/slab_helpers.h | 2 |
13 files changed, 489 insertions, 62 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e7fe675cb..055bea641 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -243,6 +243,8 @@ add_library(core STATIC | |||
| 243 | hle/kernel/k_server_session.h | 243 | hle/kernel/k_server_session.h |
| 244 | hle/kernel/k_session.cpp | 244 | hle/kernel/k_session.cpp |
| 245 | hle/kernel/k_session.h | 245 | hle/kernel/k_session.h |
| 246 | hle/kernel/k_session_request.cpp | ||
| 247 | hle/kernel/k_session_request.h | ||
| 246 | hle/kernel/k_shared_memory.cpp | 248 | hle/kernel/k_shared_memory.cpp |
| 247 | hle/kernel/k_shared_memory.h | 249 | hle/kernel/k_shared_memory.h |
| 248 | hle/kernel/k_shared_memory_info.h | 250 | hle/kernel/k_shared_memory_info.h |
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp index c84d36c8c..477e4e407 100644 --- a/src/core/hle/kernel/init/init_slab_setup.cpp +++ b/src/core/hle/kernel/init/init_slab_setup.cpp | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include "core/hle/kernel/k_process.h" | 18 | #include "core/hle/kernel/k_process.h" |
| 19 | #include "core/hle/kernel/k_resource_limit.h" | 19 | #include "core/hle/kernel/k_resource_limit.h" |
| 20 | #include "core/hle/kernel/k_session.h" | 20 | #include "core/hle/kernel/k_session.h" |
| 21 | #include "core/hle/kernel/k_session_request.h" | ||
| 21 | #include "core/hle/kernel/k_shared_memory.h" | 22 | #include "core/hle/kernel/k_shared_memory.h" |
| 22 | #include "core/hle/kernel/k_shared_memory_info.h" | 23 | #include "core/hle/kernel/k_shared_memory_info.h" |
| 23 | #include "core/hle/kernel/k_system_control.h" | 24 | #include "core/hle/kernel/k_system_control.h" |
| @@ -34,6 +35,7 @@ namespace Kernel::Init { | |||
| 34 | HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__) \ | 35 | HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__) \ |
| 35 | HANDLER(KEvent, (SLAB_COUNT(KEvent)), ##__VA_ARGS__) \ | 36 | HANDLER(KEvent, (SLAB_COUNT(KEvent)), ##__VA_ARGS__) \ |
| 36 | HANDLER(KPort, (SLAB_COUNT(KPort)), ##__VA_ARGS__) \ | 37 | HANDLER(KPort, (SLAB_COUNT(KPort)), ##__VA_ARGS__) \ |
| 38 | HANDLER(KSessionRequest, (SLAB_COUNT(KSession) * 2), ##__VA_ARGS__) \ | ||
| 37 | HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__) \ | 39 | HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__) \ |
| 38 | HANDLER(KSharedMemoryInfo, (SLAB_COUNT(KSharedMemory) * 8), ##__VA_ARGS__) \ | 40 | HANDLER(KSharedMemoryInfo, (SLAB_COUNT(KSharedMemory) * 8), ##__VA_ARGS__) \ |
| 39 | HANDLER(KTransferMemory, (SLAB_COUNT(KTransferMemory)), ##__VA_ARGS__) \ | 41 | HANDLER(KTransferMemory, (SLAB_COUNT(KTransferMemory)), ##__VA_ARGS__) \ |
diff --git a/src/core/hle/kernel/k_client_session.cpp b/src/core/hle/kernel/k_client_session.cpp index 8892c5b7c..b4197a8d5 100644 --- a/src/core/hle/kernel/k_client_session.cpp +++ b/src/core/hle/kernel/k_client_session.cpp | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "common/scope_exit.h" | ||
| 4 | #include "core/hle/kernel/hle_ipc.h" | 5 | #include "core/hle/kernel/hle_ipc.h" |
| 5 | #include "core/hle/kernel/k_client_session.h" | 6 | #include "core/hle/kernel/k_client_session.h" |
| 6 | #include "core/hle/kernel/k_server_session.h" | 7 | #include "core/hle/kernel/k_server_session.h" |
| @@ -10,6 +11,8 @@ | |||
| 10 | 11 | ||
| 11 | namespace Kernel { | 12 | namespace Kernel { |
| 12 | 13 | ||
| 14 | static constexpr u32 MessageBufferSize = 0x100; | ||
| 15 | |||
| 13 | KClientSession::KClientSession(KernelCore& kernel_) | 16 | KClientSession::KClientSession(KernelCore& kernel_) |
| 14 | : KAutoObjectWithSlabHeapAndContainer{kernel_} {} | 17 | : KAutoObjectWithSlabHeapAndContainer{kernel_} {} |
| 15 | KClientSession::~KClientSession() = default; | 18 | KClientSession::~KClientSession() = default; |
| @@ -22,8 +25,16 @@ void KClientSession::Destroy() { | |||
| 22 | void KClientSession::OnServerClosed() {} | 25 | void KClientSession::OnServerClosed() {} |
| 23 | 26 | ||
| 24 | Result KClientSession::SendSyncRequest() { | 27 | Result KClientSession::SendSyncRequest() { |
| 25 | // Signal the server session that new data is available | 28 | // Create a session request. |
| 26 | return parent->GetServerSession().OnRequest(); | 29 | KSessionRequest* request = KSessionRequest::Create(kernel); |
| 30 | R_UNLESS(request != nullptr, ResultOutOfResource); | ||
| 31 | SCOPE_EXIT({ request->Close(); }); | ||
| 32 | |||
| 33 | // Initialize the request. | ||
| 34 | request->Initialize(nullptr, GetCurrentThread(kernel).GetTLSAddress(), MessageBufferSize); | ||
| 35 | |||
| 36 | // Send the request. | ||
| 37 | return parent->GetServerSession().OnRequest(request); | ||
| 27 | } | 38 | } |
| 28 | 39 | ||
| 29 | } // namespace Kernel | 40 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_linked_list.h b/src/core/hle/kernel/k_linked_list.h index 78859ced3..29ebd16b7 100644 --- a/src/core/hle/kernel/k_linked_list.h +++ b/src/core/hle/kernel/k_linked_list.h | |||
| @@ -16,6 +16,7 @@ class KLinkedListNode : public boost::intrusive::list_base_hook<>, | |||
| 16 | public KSlabAllocated<KLinkedListNode> { | 16 | public KSlabAllocated<KLinkedListNode> { |
| 17 | 17 | ||
| 18 | public: | 18 | public: |
| 19 | explicit KLinkedListNode(KernelCore&) {} | ||
| 19 | KLinkedListNode() = default; | 20 | KLinkedListNode() = default; |
| 20 | 21 | ||
| 21 | void Initialize(void* it) { | 22 | void Initialize(void* it) { |
diff --git a/src/core/hle/kernel/k_page_buffer.h b/src/core/hle/kernel/k_page_buffer.h index 7e50dc1d1..aef06e213 100644 --- a/src/core/hle/kernel/k_page_buffer.h +++ b/src/core/hle/kernel/k_page_buffer.h | |||
| @@ -13,6 +13,7 @@ namespace Kernel { | |||
| 13 | 13 | ||
| 14 | class KPageBuffer final : public KSlabAllocated<KPageBuffer> { | 14 | class KPageBuffer final : public KSlabAllocated<KPageBuffer> { |
| 15 | public: | 15 | public: |
| 16 | explicit KPageBuffer(KernelCore&) {} | ||
| 16 | KPageBuffer() = default; | 17 | KPageBuffer() = default; |
| 17 | 18 | ||
| 18 | static KPageBuffer* FromPhysicalAddress(Core::System& system, PAddr phys_addr); | 19 | static KPageBuffer* FromPhysicalAddress(Core::System& system, PAddr phys_addr); |
diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index 4252c9adb..685a2a6e6 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp | |||
| @@ -29,8 +29,6 @@ namespace Kernel { | |||
| 29 | 29 | ||
| 30 | using ThreadQueueImplForKServerSessionRequest = KThreadQueue; | 30 | using ThreadQueueImplForKServerSessionRequest = KThreadQueue; |
| 31 | 31 | ||
| 32 | static constexpr u32 MessageBufferSize = 0x100; | ||
| 33 | |||
| 34 | KServerSession::KServerSession(KernelCore& kernel_) | 32 | KServerSession::KServerSession(KernelCore& kernel_) |
| 35 | : KSynchronizationObject{kernel_}, m_lock{kernel_} {} | 33 | : KSynchronizationObject{kernel_}, m_lock{kernel_} {} |
| 36 | 34 | ||
| @@ -73,7 +71,7 @@ bool KServerSession::IsSignaled() const { | |||
| 73 | } | 71 | } |
| 74 | 72 | ||
| 75 | // Otherwise, we're signaled if we have a request and aren't handling one. | 73 | // Otherwise, we're signaled if we have a request and aren't handling one. |
| 76 | return !m_thread_request_list.empty() && m_current_thread_request == nullptr; | 74 | return !m_request_list.empty() && m_current_request == nullptr; |
| 77 | } | 75 | } |
| 78 | 76 | ||
| 79 | void KServerSession::AppendDomainHandler(SessionRequestHandlerPtr handler) { | 77 | void KServerSession::AppendDomainHandler(SessionRequestHandlerPtr handler) { |
| @@ -178,7 +176,7 @@ Result KServerSession::CompleteSyncRequest(HLERequestContext& context) { | |||
| 178 | return result; | 176 | return result; |
| 179 | } | 177 | } |
| 180 | 178 | ||
| 181 | Result KServerSession::OnRequest() { | 179 | Result KServerSession::OnRequest(KSessionRequest* request) { |
| 182 | // Create the wait queue. | 180 | // Create the wait queue. |
| 183 | ThreadQueueImplForKServerSessionRequest wait_queue{kernel}; | 181 | ThreadQueueImplForKServerSessionRequest wait_queue{kernel}; |
| 184 | 182 | ||
| @@ -198,14 +196,13 @@ Result KServerSession::OnRequest() { | |||
| 198 | this->QueueSyncRequest(GetCurrentThreadPointer(kernel), memory); | 196 | this->QueueSyncRequest(GetCurrentThreadPointer(kernel), memory); |
| 199 | } else { | 197 | } else { |
| 200 | // Non-HLE request. | 198 | // Non-HLE request. |
| 201 | auto* thread{GetCurrentThreadPointer(kernel)}; | ||
| 202 | 199 | ||
| 203 | // Get whether we're empty. | 200 | // Get whether we're empty. |
| 204 | const bool was_empty = m_thread_request_list.empty(); | 201 | const bool was_empty = m_request_list.empty(); |
| 205 | 202 | ||
| 206 | // Add the thread to the list. | 203 | // Add the request to the list. |
| 207 | thread->Open(); | 204 | request->Open(); |
| 208 | m_thread_request_list.push_back(thread); | 205 | m_request_list.push_back(*request); |
| 209 | 206 | ||
| 210 | // If we were empty, signal. | 207 | // If we were empty, signal. |
| 211 | if (was_empty) { | 208 | if (was_empty) { |
| @@ -213,6 +210,9 @@ Result KServerSession::OnRequest() { | |||
| 213 | } | 210 | } |
| 214 | } | 211 | } |
| 215 | 212 | ||
| 213 | // If we have a request event, this is asynchronous, and we don't need to wait. | ||
| 214 | R_SUCCEED_IF(request->GetEvent() != nullptr); | ||
| 215 | |||
| 216 | // This is a synchronous request, so we should wait for our request to complete. | 216 | // This is a synchronous request, so we should wait for our request to complete. |
| 217 | GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC); | 217 | GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC); |
| 218 | GetCurrentThread(kernel).BeginWait(&wait_queue); | 218 | GetCurrentThread(kernel).BeginWait(&wait_queue); |
| @@ -223,32 +223,32 @@ Result KServerSession::OnRequest() { | |||
| 223 | 223 | ||
| 224 | Result KServerSession::SendReply() { | 224 | Result KServerSession::SendReply() { |
| 225 | // Lock the session. | 225 | // Lock the session. |
| 226 | KScopedLightLock lk(m_lock); | 226 | KScopedLightLock lk{m_lock}; |
| 227 | 227 | ||
| 228 | // Get the request. | 228 | // Get the request. |
| 229 | KThread* client_thread; | 229 | KSessionRequest* request; |
| 230 | { | 230 | { |
| 231 | KScopedSchedulerLock sl{kernel}; | 231 | KScopedSchedulerLock sl{kernel}; |
| 232 | 232 | ||
| 233 | // Get the current request. | 233 | // Get the current request. |
| 234 | client_thread = m_current_thread_request; | 234 | request = m_current_request; |
| 235 | R_UNLESS(client_thread != nullptr, ResultInvalidState); | 235 | R_UNLESS(request != nullptr, ResultInvalidState); |
| 236 | 236 | ||
| 237 | // Clear the current request, since we're processing it. | 237 | // Clear the current request, since we're processing it. |
| 238 | m_current_thread_request = nullptr; | 238 | m_current_request = nullptr; |
| 239 | if (!m_thread_request_list.empty()) { | 239 | if (!m_request_list.empty()) { |
| 240 | this->NotifyAvailable(); | 240 | this->NotifyAvailable(); |
| 241 | } | 241 | } |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | // Close reference to the request once we're done processing it. | 244 | // Close reference to the request once we're done processing it. |
| 245 | SCOPE_EXIT({ client_thread->Close(); }); | 245 | SCOPE_EXIT({ request->Close(); }); |
| 246 | 246 | ||
| 247 | // Extract relevant information from the request. | 247 | // Extract relevant information from the request. |
| 248 | // const uintptr_t client_message = request->GetAddress(); | 248 | const uintptr_t client_message = request->GetAddress(); |
| 249 | // const size_t client_buffer_size = request->GetSize(); | 249 | const size_t client_buffer_size = request->GetSize(); |
| 250 | // KThread *client_thread = request->GetThread(); | 250 | KThread* client_thread = request->GetThread(); |
| 251 | // KEvent *event = request->GetEvent(); | 251 | KEvent* event = request->GetEvent(); |
| 252 | 252 | ||
| 253 | // Check whether we're closed. | 253 | // Check whether we're closed. |
| 254 | const bool closed = (client_thread == nullptr || parent->IsClientClosed()); | 254 | const bool closed = (client_thread == nullptr || parent->IsClientClosed()); |
| @@ -261,8 +261,8 @@ Result KServerSession::SendReply() { | |||
| 261 | UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess()); | 261 | UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess()); |
| 262 | 262 | ||
| 263 | auto* src_msg_buffer = memory.GetPointer(server_thread->GetTLSAddress()); | 263 | auto* src_msg_buffer = memory.GetPointer(server_thread->GetTLSAddress()); |
| 264 | auto* dst_msg_buffer = memory.GetPointer(client_thread->GetTLSAddress()); | 264 | auto* dst_msg_buffer = memory.GetPointer(client_message); |
| 265 | std::memcpy(dst_msg_buffer, src_msg_buffer, MessageBufferSize); | 265 | std::memcpy(dst_msg_buffer, src_msg_buffer, client_buffer_size); |
| 266 | } else { | 266 | } else { |
| 267 | result = ResultSessionClosed; | 267 | result = ResultSessionClosed; |
| 268 | } | 268 | } |
| @@ -278,11 +278,30 @@ Result KServerSession::SendReply() { | |||
| 278 | 278 | ||
| 279 | // If there's a client thread, update it. | 279 | // If there's a client thread, update it. |
| 280 | if (client_thread != nullptr) { | 280 | if (client_thread != nullptr) { |
| 281 | // End the client thread's wait. | 281 | if (event != nullptr) { |
| 282 | KScopedSchedulerLock sl{kernel}; | 282 | // // Get the client process/page table. |
| 283 | // KProcess *client_process = client_thread->GetOwnerProcess(); | ||
| 284 | // KPageTable *client_page_table = &client_process->PageTable(); | ||
| 285 | |||
| 286 | // // If we need to, reply with an async error. | ||
| 287 | // if (R_FAILED(client_result)) { | ||
| 288 | // ReplyAsyncError(client_process, client_message, client_buffer_size, | ||
| 289 | // client_result); | ||
| 290 | // } | ||
| 291 | |||
| 292 | // // Unlock the client buffer. | ||
| 293 | // // NOTE: Nintendo does not check the result of this. | ||
| 294 | // client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size); | ||
| 295 | |||
| 296 | // Signal the event. | ||
| 297 | event->Signal(); | ||
| 298 | } else { | ||
| 299 | // End the client thread's wait. | ||
| 300 | KScopedSchedulerLock sl{kernel}; | ||
| 283 | 301 | ||
| 284 | if (!client_thread->IsTerminationRequested()) { | 302 | if (!client_thread->IsTerminationRequested()) { |
| 285 | client_thread->EndWait(client_result); | 303 | client_thread->EndWait(client_result); |
| 304 | } | ||
| 286 | } | 305 | } |
| 287 | } | 306 | } |
| 288 | 307 | ||
| @@ -291,10 +310,10 @@ Result KServerSession::SendReply() { | |||
| 291 | 310 | ||
| 292 | Result KServerSession::ReceiveRequest() { | 311 | Result KServerSession::ReceiveRequest() { |
| 293 | // Lock the session. | 312 | // Lock the session. |
| 294 | KScopedLightLock lk(m_lock); | 313 | KScopedLightLock lk{m_lock}; |
| 295 | 314 | ||
| 296 | // Get the request and client thread. | 315 | // Get the request and client thread. |
| 297 | // KSessionRequest *request; | 316 | KSessionRequest* request; |
| 298 | KThread* client_thread; | 317 | KThread* client_thread; |
| 299 | 318 | ||
| 300 | { | 319 | { |
| @@ -304,35 +323,41 @@ Result KServerSession::ReceiveRequest() { | |||
| 304 | R_UNLESS(!parent->IsClientClosed(), ResultSessionClosed); | 323 | R_UNLESS(!parent->IsClientClosed(), ResultSessionClosed); |
| 305 | 324 | ||
| 306 | // Ensure we aren't already servicing a request. | 325 | // Ensure we aren't already servicing a request. |
| 307 | R_UNLESS(m_current_thread_request == nullptr, ResultNotFound); | 326 | R_UNLESS(m_current_request == nullptr, ResultNotFound); |
| 308 | 327 | ||
| 309 | // Ensure we have a request to service. | 328 | // Ensure we have a request to service. |
| 310 | R_UNLESS(!m_thread_request_list.empty(), ResultNotFound); | 329 | R_UNLESS(!m_request_list.empty(), ResultNotFound); |
| 311 | 330 | ||
| 312 | // Pop the first request from the list. | 331 | // Pop the first request from the list. |
| 313 | client_thread = m_thread_request_list.front(); | 332 | request = &m_request_list.front(); |
| 314 | m_thread_request_list.pop_front(); | 333 | m_request_list.pop_front(); |
| 315 | 334 | ||
| 316 | // Get the thread for the request. | 335 | // Get the thread for the request. |
| 336 | client_thread = request->GetThread(); | ||
| 317 | R_UNLESS(client_thread != nullptr, ResultSessionClosed); | 337 | R_UNLESS(client_thread != nullptr, ResultSessionClosed); |
| 318 | 338 | ||
| 319 | // Open the client thread. | 339 | // Open the client thread. |
| 320 | client_thread->Open(); | 340 | client_thread->Open(); |
| 321 | } | 341 | } |
| 322 | 342 | ||
| 323 | // SCOPE_EXIT({ client_thread->Close(); }); | 343 | SCOPE_EXIT({ client_thread->Close(); }); |
| 324 | 344 | ||
| 325 | // Set the request as our current. | 345 | // Set the request as our current. |
| 326 | m_current_thread_request = client_thread; | 346 | m_current_request = request; |
| 347 | |||
| 348 | // Get the client address. | ||
| 349 | uintptr_t client_message = request->GetAddress(); | ||
| 350 | size_t client_buffer_size = request->GetSize(); | ||
| 351 | // bool recv_list_broken = false; | ||
| 327 | 352 | ||
| 328 | // Receive the message. | 353 | // Receive the message. |
| 329 | Core::Memory::Memory& memory{kernel.System().Memory()}; | 354 | Core::Memory::Memory& memory{kernel.System().Memory()}; |
| 330 | KThread* server_thread{GetCurrentThreadPointer(kernel)}; | 355 | KThread* server_thread{GetCurrentThreadPointer(kernel)}; |
| 331 | UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess()); | 356 | UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess()); |
| 332 | 357 | ||
| 333 | auto* src_msg_buffer = memory.GetPointer(client_thread->GetTLSAddress()); | 358 | auto* src_msg_buffer = memory.GetPointer(client_message); |
| 334 | auto* dst_msg_buffer = memory.GetPointer(server_thread->GetTLSAddress()); | 359 | auto* dst_msg_buffer = memory.GetPointer(server_thread->GetTLSAddress()); |
| 335 | std::memcpy(dst_msg_buffer, src_msg_buffer, MessageBufferSize); | 360 | std::memcpy(dst_msg_buffer, src_msg_buffer, client_buffer_size); |
| 336 | 361 | ||
| 337 | // We succeeded. | 362 | // We succeeded. |
| 338 | return ResultSuccess; | 363 | return ResultSuccess; |
| @@ -344,35 +369,34 @@ void KServerSession::CleanupRequests() { | |||
| 344 | // Clean up any pending requests. | 369 | // Clean up any pending requests. |
| 345 | while (true) { | 370 | while (true) { |
| 346 | // Get the next request. | 371 | // Get the next request. |
| 347 | // KSessionRequest *request = nullptr; | 372 | KSessionRequest* request = nullptr; |
| 348 | KThread* client_thread = nullptr; | ||
| 349 | { | 373 | { |
| 350 | KScopedSchedulerLock sl{kernel}; | 374 | KScopedSchedulerLock sl{kernel}; |
| 351 | 375 | ||
| 352 | if (m_current_thread_request) { | 376 | if (m_current_request) { |
| 353 | // Choose the current request if we have one. | 377 | // Choose the current request if we have one. |
| 354 | client_thread = m_current_thread_request; | 378 | request = m_current_request; |
| 355 | m_current_thread_request = nullptr; | 379 | m_current_request = nullptr; |
| 356 | } else if (!m_thread_request_list.empty()) { | 380 | } else if (!m_request_list.empty()) { |
| 357 | // Pop the request from the front of the list. | 381 | // Pop the request from the front of the list. |
| 358 | client_thread = m_thread_request_list.front(); | 382 | request = &m_request_list.front(); |
| 359 | m_thread_request_list.pop_front(); | 383 | m_request_list.pop_front(); |
| 360 | } | 384 | } |
| 361 | } | 385 | } |
| 362 | 386 | ||
| 363 | // If there's no request, we're done. | 387 | // If there's no request, we're done. |
| 364 | if (client_thread == nullptr) { | 388 | if (request == nullptr) { |
| 365 | break; | 389 | break; |
| 366 | } | 390 | } |
| 367 | 391 | ||
| 368 | // Close a reference to the request once it's cleaned up. | 392 | // Close a reference to the request once it's cleaned up. |
| 369 | SCOPE_EXIT({ client_thread->Close(); }); | 393 | SCOPE_EXIT({ request->Close(); }); |
| 370 | 394 | ||
| 371 | // Extract relevant information from the request. | 395 | // Extract relevant information from the request. |
| 372 | // const uintptr_t client_message = request->GetAddress(); | 396 | // const uintptr_t client_message = request->GetAddress(); |
| 373 | // const size_t client_buffer_size = request->GetSize(); | 397 | // const size_t client_buffer_size = request->GetSize(); |
| 374 | // KThread *client_thread = request->GetThread(); | 398 | KThread* client_thread = request->GetThread(); |
| 375 | // KEvent *event = request->GetEvent(); | 399 | KEvent* event = request->GetEvent(); |
| 376 | 400 | ||
| 377 | // KProcess *server_process = request->GetServerProcess(); | 401 | // KProcess *server_process = request->GetServerProcess(); |
| 378 | // KProcess *client_process = (client_thread != nullptr) ? | 402 | // KProcess *client_process = (client_thread != nullptr) ? |
| @@ -385,11 +409,24 @@ void KServerSession::CleanupRequests() { | |||
| 385 | 409 | ||
| 386 | // If there's a client thread, update it. | 410 | // If there's a client thread, update it. |
| 387 | if (client_thread != nullptr) { | 411 | if (client_thread != nullptr) { |
| 388 | // End the client thread's wait. | 412 | if (event != nullptr) { |
| 389 | KScopedSchedulerLock sl{kernel}; | 413 | // // We need to reply async. |
| 390 | 414 | // ReplyAsyncError(client_process, client_message, client_buffer_size, | |
| 391 | if (!client_thread->IsTerminationRequested()) { | 415 | // (R_SUCCEEDED(result) ? ResultSessionClosed : result)); |
| 392 | client_thread->EndWait(ResultSessionClosed); | 416 | |
| 417 | // // Unlock the client buffer. | ||
| 418 | // NOTE: Nintendo does not check the result of this. | ||
| 419 | // client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size); | ||
| 420 | |||
| 421 | // Signal the event. | ||
| 422 | event->Signal(); | ||
| 423 | } else { | ||
| 424 | // End the client thread's wait. | ||
| 425 | KScopedSchedulerLock sl{kernel}; | ||
| 426 | |||
| 427 | if (!client_thread->IsTerminationRequested()) { | ||
| 428 | client_thread->EndWait(ResultSessionClosed); | ||
| 429 | } | ||
| 393 | } | 430 | } |
| 394 | } | 431 | } |
| 395 | } | 432 | } |
diff --git a/src/core/hle/kernel/k_server_session.h b/src/core/hle/kernel/k_server_session.h index 748d52826..c40ff4aaf 100644 --- a/src/core/hle/kernel/k_server_session.h +++ b/src/core/hle/kernel/k_server_session.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | #include "core/hle/kernel/hle_ipc.h" | 13 | #include "core/hle/kernel/hle_ipc.h" |
| 14 | #include "core/hle/kernel/k_light_lock.h" | 14 | #include "core/hle/kernel/k_light_lock.h" |
| 15 | #include "core/hle/kernel/k_session_request.h" | ||
| 15 | #include "core/hle/kernel/k_synchronization_object.h" | 16 | #include "core/hle/kernel/k_synchronization_object.h" |
| 16 | #include "core/hle/result.h" | 17 | #include "core/hle/result.h" |
| 17 | 18 | ||
| @@ -94,7 +95,7 @@ public: | |||
| 94 | } | 95 | } |
| 95 | 96 | ||
| 96 | /// TODO: flesh these out to match the real kernel | 97 | /// TODO: flesh these out to match the real kernel |
| 97 | Result OnRequest(); | 98 | Result OnRequest(KSessionRequest* request); |
| 98 | Result SendReply(); | 99 | Result SendReply(); |
| 99 | Result ReceiveRequest(); | 100 | Result ReceiveRequest(); |
| 100 | 101 | ||
| @@ -122,9 +123,8 @@ private: | |||
| 122 | KSession* parent{}; | 123 | KSession* parent{}; |
| 123 | 124 | ||
| 124 | /// List of threads which are pending a reply. | 125 | /// List of threads which are pending a reply. |
| 125 | /// FIXME: KSessionRequest | 126 | boost::intrusive::list<KSessionRequest> m_request_list; |
| 126 | std::list<KThread*> m_thread_request_list; | 127 | KSessionRequest* m_current_request; |
| 127 | KThread* m_current_thread_request{}; | ||
| 128 | 128 | ||
| 129 | KLightLock m_lock; | 129 | KLightLock m_lock; |
| 130 | }; | 130 | }; |
diff --git a/src/core/hle/kernel/k_session_request.cpp b/src/core/hle/kernel/k_session_request.cpp new file mode 100644 index 000000000..520da6aa7 --- /dev/null +++ b/src/core/hle/kernel/k_session_request.cpp | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "core/hle/kernel/k_page_buffer.h" | ||
| 5 | #include "core/hle/kernel/k_session_request.h" | ||
| 6 | |||
| 7 | namespace Kernel { | ||
| 8 | |||
| 9 | Result KSessionRequest::SessionMappings::PushMap(VAddr client, VAddr server, size_t size, | ||
| 10 | KMemoryState state, size_t index) { | ||
| 11 | // At most 15 buffers of each type (4-bit descriptor counts). | ||
| 12 | ASSERT(index < ((1ul << 4) - 1) * 3); | ||
| 13 | |||
| 14 | // Get the mapping. | ||
| 15 | Mapping* mapping; | ||
| 16 | if (index < NumStaticMappings) { | ||
| 17 | mapping = &m_static_mappings[index]; | ||
| 18 | } else { | ||
| 19 | // Allocate a page for the extra mappings. | ||
| 20 | if (m_mappings == nullptr) { | ||
| 21 | KPageBuffer* page_buffer = KPageBuffer::Allocate(kernel); | ||
| 22 | R_UNLESS(page_buffer != nullptr, ResultOutOfMemory); | ||
| 23 | |||
| 24 | m_mappings = reinterpret_cast<Mapping*>(page_buffer); | ||
| 25 | } | ||
| 26 | |||
| 27 | mapping = &m_mappings[index - NumStaticMappings]; | ||
| 28 | } | ||
| 29 | |||
| 30 | // Set the mapping. | ||
| 31 | mapping->Set(client, server, size, state); | ||
| 32 | |||
| 33 | return ResultSuccess; | ||
| 34 | } | ||
| 35 | |||
| 36 | Result KSessionRequest::SessionMappings::PushSend(VAddr client, VAddr server, size_t size, | ||
| 37 | KMemoryState state) { | ||
| 38 | ASSERT(m_num_recv == 0); | ||
| 39 | ASSERT(m_num_exch == 0); | ||
| 40 | return this->PushMap(client, server, size, state, m_num_send++); | ||
| 41 | } | ||
| 42 | |||
| 43 | Result KSessionRequest::SessionMappings::PushReceive(VAddr client, VAddr server, size_t size, | ||
| 44 | KMemoryState state) { | ||
| 45 | ASSERT(m_num_exch == 0); | ||
| 46 | return this->PushMap(client, server, size, state, m_num_send + m_num_recv++); | ||
| 47 | } | ||
| 48 | |||
| 49 | Result KSessionRequest::SessionMappings::PushExchange(VAddr client, VAddr server, size_t size, | ||
| 50 | KMemoryState state) { | ||
| 51 | return this->PushMap(client, server, size, state, m_num_send + m_num_recv + m_num_exch++); | ||
| 52 | } | ||
| 53 | |||
| 54 | void KSessionRequest::SessionMappings::Finalize() { | ||
| 55 | if (m_mappings) { | ||
| 56 | KPageBuffer::Free(kernel, reinterpret_cast<KPageBuffer*>(m_mappings)); | ||
| 57 | m_mappings = nullptr; | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_session_request.h b/src/core/hle/kernel/k_session_request.h new file mode 100644 index 000000000..fcf521597 --- /dev/null +++ b/src/core/hle/kernel/k_session_request.h | |||
| @@ -0,0 +1,307 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/kernel/k_auto_object.h" | ||
| 7 | #include "core/hle/kernel/k_event.h" | ||
| 8 | #include "core/hle/kernel/k_memory_block.h" | ||
| 9 | #include "core/hle/kernel/k_process.h" | ||
| 10 | #include "core/hle/kernel/k_thread.h" | ||
| 11 | #include "core/hle/kernel/slab_helpers.h" | ||
| 12 | |||
| 13 | namespace Kernel { | ||
| 14 | |||
| 15 | class KSessionRequest final : public KSlabAllocated<KSessionRequest>, | ||
| 16 | public KAutoObject, | ||
| 17 | public boost::intrusive::list_base_hook<> { | ||
| 18 | KERNEL_AUTOOBJECT_TRAITS(KSessionRequest, KAutoObject); | ||
| 19 | |||
| 20 | public: | ||
| 21 | class SessionMappings { | ||
| 22 | private: | ||
| 23 | static constexpr size_t NumStaticMappings = 8; | ||
| 24 | |||
| 25 | class Mapping { | ||
| 26 | public: | ||
| 27 | constexpr void Set(VAddr c, VAddr s, size_t sz, KMemoryState st) { | ||
| 28 | m_client_address = c; | ||
| 29 | m_server_address = s; | ||
| 30 | m_size = sz; | ||
| 31 | m_state = st; | ||
| 32 | } | ||
| 33 | |||
| 34 | constexpr VAddr GetClientAddress() const { | ||
| 35 | return m_client_address; | ||
| 36 | } | ||
| 37 | constexpr VAddr GetServerAddress() const { | ||
| 38 | return m_server_address; | ||
| 39 | } | ||
| 40 | constexpr size_t GetSize() const { | ||
| 41 | return m_size; | ||
| 42 | } | ||
| 43 | constexpr KMemoryState GetMemoryState() const { | ||
| 44 | return m_state; | ||
| 45 | } | ||
| 46 | |||
| 47 | private: | ||
| 48 | VAddr m_client_address; | ||
| 49 | VAddr m_server_address; | ||
| 50 | size_t m_size; | ||
| 51 | KMemoryState m_state; | ||
| 52 | }; | ||
| 53 | |||
| 54 | public: | ||
| 55 | explicit SessionMappings(KernelCore& kernel_) | ||
| 56 | : kernel(kernel_), m_mappings(nullptr), m_num_send(), m_num_recv(), m_num_exch() {} | ||
| 57 | |||
| 58 | void Initialize() {} | ||
| 59 | void Finalize(); | ||
| 60 | |||
| 61 | size_t GetSendCount() const { | ||
| 62 | return m_num_send; | ||
| 63 | } | ||
| 64 | size_t GetReceiveCount() const { | ||
| 65 | return m_num_recv; | ||
| 66 | } | ||
| 67 | size_t GetExchangeCount() const { | ||
| 68 | return m_num_exch; | ||
| 69 | } | ||
| 70 | |||
| 71 | Result PushSend(VAddr client, VAddr server, size_t size, KMemoryState state); | ||
| 72 | Result PushReceive(VAddr client, VAddr server, size_t size, KMemoryState state); | ||
| 73 | Result PushExchange(VAddr client, VAddr server, size_t size, KMemoryState state); | ||
| 74 | |||
| 75 | VAddr GetSendClientAddress(size_t i) const { | ||
| 76 | return GetSendMapping(i).GetClientAddress(); | ||
| 77 | } | ||
| 78 | VAddr GetSendServerAddress(size_t i) const { | ||
| 79 | return GetSendMapping(i).GetServerAddress(); | ||
| 80 | } | ||
| 81 | size_t GetSendSize(size_t i) const { | ||
| 82 | return GetSendMapping(i).GetSize(); | ||
| 83 | } | ||
| 84 | KMemoryState GetSendMemoryState(size_t i) const { | ||
| 85 | return GetSendMapping(i).GetMemoryState(); | ||
| 86 | } | ||
| 87 | |||
| 88 | VAddr GetReceiveClientAddress(size_t i) const { | ||
| 89 | return GetReceiveMapping(i).GetClientAddress(); | ||
| 90 | } | ||
| 91 | VAddr GetReceiveServerAddress(size_t i) const { | ||
| 92 | return GetReceiveMapping(i).GetServerAddress(); | ||
| 93 | } | ||
| 94 | size_t GetReceiveSize(size_t i) const { | ||
| 95 | return GetReceiveMapping(i).GetSize(); | ||
| 96 | } | ||
| 97 | KMemoryState GetReceiveMemoryState(size_t i) const { | ||
| 98 | return GetReceiveMapping(i).GetMemoryState(); | ||
| 99 | } | ||
| 100 | |||
| 101 | VAddr GetExchangeClientAddress(size_t i) const { | ||
| 102 | return GetExchangeMapping(i).GetClientAddress(); | ||
| 103 | } | ||
| 104 | VAddr GetExchangeServerAddress(size_t i) const { | ||
| 105 | return GetExchangeMapping(i).GetServerAddress(); | ||
| 106 | } | ||
| 107 | size_t GetExchangeSize(size_t i) const { | ||
| 108 | return GetExchangeMapping(i).GetSize(); | ||
| 109 | } | ||
| 110 | KMemoryState GetExchangeMemoryState(size_t i) const { | ||
| 111 | return GetExchangeMapping(i).GetMemoryState(); | ||
| 112 | } | ||
| 113 | |||
| 114 | private: | ||
| 115 | Result PushMap(VAddr client, VAddr server, size_t size, KMemoryState state, size_t index); | ||
| 116 | |||
| 117 | const Mapping& GetSendMapping(size_t i) const { | ||
| 118 | ASSERT(i < m_num_send); | ||
| 119 | |||
| 120 | const size_t index = i; | ||
| 121 | if (index < NumStaticMappings) { | ||
| 122 | return m_static_mappings[index]; | ||
| 123 | } else { | ||
| 124 | return m_mappings[index - NumStaticMappings]; | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | const Mapping& GetReceiveMapping(size_t i) const { | ||
| 129 | ASSERT(i < m_num_recv); | ||
| 130 | |||
| 131 | const size_t index = m_num_send + i; | ||
| 132 | if (index < NumStaticMappings) { | ||
| 133 | return m_static_mappings[index]; | ||
| 134 | } else { | ||
| 135 | return m_mappings[index - NumStaticMappings]; | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | const Mapping& GetExchangeMapping(size_t i) const { | ||
| 140 | ASSERT(i < m_num_exch); | ||
| 141 | |||
| 142 | const size_t index = m_num_send + m_num_recv + i; | ||
| 143 | if (index < NumStaticMappings) { | ||
| 144 | return m_static_mappings[index]; | ||
| 145 | } else { | ||
| 146 | return m_mappings[index - NumStaticMappings]; | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | private: | ||
| 151 | KernelCore& kernel; | ||
| 152 | Mapping m_static_mappings[NumStaticMappings]; | ||
| 153 | Mapping* m_mappings; | ||
| 154 | u8 m_num_send; | ||
| 155 | u8 m_num_recv; | ||
| 156 | u8 m_num_exch; | ||
| 157 | }; | ||
| 158 | |||
| 159 | public: | ||
| 160 | explicit KSessionRequest(KernelCore& kernel_) | ||
| 161 | : KAutoObject(kernel_), m_mappings(kernel_), m_thread(nullptr), m_server(nullptr), | ||
| 162 | m_event(nullptr) {} | ||
| 163 | |||
| 164 | static KSessionRequest* Create(KernelCore& kernel) { | ||
| 165 | KSessionRequest* req = KSessionRequest::Allocate(kernel); | ||
| 166 | if (req != nullptr) [[likely]] { | ||
| 167 | KAutoObject::Create(req); | ||
| 168 | } | ||
| 169 | return req; | ||
| 170 | } | ||
| 171 | |||
| 172 | void Destroy() override { | ||
| 173 | this->Finalize(); | ||
| 174 | KSessionRequest::Free(kernel, this); | ||
| 175 | } | ||
| 176 | |||
| 177 | void Initialize(KEvent* event, uintptr_t address, size_t size) { | ||
| 178 | m_mappings.Initialize(); | ||
| 179 | |||
| 180 | m_thread = GetCurrentThreadPointer(kernel); | ||
| 181 | m_event = event; | ||
| 182 | m_address = address; | ||
| 183 | m_size = size; | ||
| 184 | |||
| 185 | m_thread->Open(); | ||
| 186 | if (m_event != nullptr) { | ||
| 187 | m_event->Open(); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | static void PostDestroy(uintptr_t arg) {} | ||
| 192 | |||
| 193 | KThread* GetThread() const { | ||
| 194 | return m_thread; | ||
| 195 | } | ||
| 196 | KEvent* GetEvent() const { | ||
| 197 | return m_event; | ||
| 198 | } | ||
| 199 | uintptr_t GetAddress() const { | ||
| 200 | return m_address; | ||
| 201 | } | ||
| 202 | size_t GetSize() const { | ||
| 203 | return m_size; | ||
| 204 | } | ||
| 205 | KProcess* GetServerProcess() const { | ||
| 206 | return m_server; | ||
| 207 | } | ||
| 208 | |||
| 209 | void SetServerProcess(KProcess* process) { | ||
| 210 | m_server = process; | ||
| 211 | m_server->Open(); | ||
| 212 | } | ||
| 213 | |||
| 214 | void ClearThread() { | ||
| 215 | m_thread = nullptr; | ||
| 216 | } | ||
| 217 | void ClearEvent() { | ||
| 218 | m_event = nullptr; | ||
| 219 | } | ||
| 220 | |||
| 221 | size_t GetSendCount() const { | ||
| 222 | return m_mappings.GetSendCount(); | ||
| 223 | } | ||
| 224 | size_t GetReceiveCount() const { | ||
| 225 | return m_mappings.GetReceiveCount(); | ||
| 226 | } | ||
| 227 | size_t GetExchangeCount() const { | ||
| 228 | return m_mappings.GetExchangeCount(); | ||
| 229 | } | ||
| 230 | |||
| 231 | Result PushSend(VAddr client, VAddr server, size_t size, KMemoryState state) { | ||
| 232 | return m_mappings.PushSend(client, server, size, state); | ||
| 233 | } | ||
| 234 | |||
| 235 | Result PushReceive(VAddr client, VAddr server, size_t size, KMemoryState state) { | ||
| 236 | return m_mappings.PushReceive(client, server, size, state); | ||
| 237 | } | ||
| 238 | |||
| 239 | Result PushExchange(VAddr client, VAddr server, size_t size, KMemoryState state) { | ||
| 240 | return m_mappings.PushExchange(client, server, size, state); | ||
| 241 | } | ||
| 242 | |||
| 243 | VAddr GetSendClientAddress(size_t i) const { | ||
| 244 | return m_mappings.GetSendClientAddress(i); | ||
| 245 | } | ||
| 246 | VAddr GetSendServerAddress(size_t i) const { | ||
| 247 | return m_mappings.GetSendServerAddress(i); | ||
| 248 | } | ||
| 249 | size_t GetSendSize(size_t i) const { | ||
| 250 | return m_mappings.GetSendSize(i); | ||
| 251 | } | ||
| 252 | KMemoryState GetSendMemoryState(size_t i) const { | ||
| 253 | return m_mappings.GetSendMemoryState(i); | ||
| 254 | } | ||
| 255 | |||
| 256 | VAddr GetReceiveClientAddress(size_t i) const { | ||
| 257 | return m_mappings.GetReceiveClientAddress(i); | ||
| 258 | } | ||
| 259 | VAddr GetReceiveServerAddress(size_t i) const { | ||
| 260 | return m_mappings.GetReceiveServerAddress(i); | ||
| 261 | } | ||
| 262 | size_t GetReceiveSize(size_t i) const { | ||
| 263 | return m_mappings.GetReceiveSize(i); | ||
| 264 | } | ||
| 265 | KMemoryState GetReceiveMemoryState(size_t i) const { | ||
| 266 | return m_mappings.GetReceiveMemoryState(i); | ||
| 267 | } | ||
| 268 | |||
| 269 | VAddr GetExchangeClientAddress(size_t i) const { | ||
| 270 | return m_mappings.GetExchangeClientAddress(i); | ||
| 271 | } | ||
| 272 | VAddr GetExchangeServerAddress(size_t i) const { | ||
| 273 | return m_mappings.GetExchangeServerAddress(i); | ||
| 274 | } | ||
| 275 | size_t GetExchangeSize(size_t i) const { | ||
| 276 | return m_mappings.GetExchangeSize(i); | ||
| 277 | } | ||
| 278 | KMemoryState GetExchangeMemoryState(size_t i) const { | ||
| 279 | return m_mappings.GetExchangeMemoryState(i); | ||
| 280 | } | ||
| 281 | |||
| 282 | private: | ||
| 283 | // NOTE: This is public and virtual in Nintendo's kernel. | ||
| 284 | void Finalize() { | ||
| 285 | m_mappings.Finalize(); | ||
| 286 | |||
| 287 | if (m_thread) { | ||
| 288 | m_thread->Close(); | ||
| 289 | } | ||
| 290 | if (m_event) { | ||
| 291 | m_event->Close(); | ||
| 292 | } | ||
| 293 | if (m_server) { | ||
| 294 | m_server->Close(); | ||
| 295 | } | ||
| 296 | } | ||
| 297 | |||
| 298 | private: | ||
| 299 | SessionMappings m_mappings; | ||
| 300 | KThread* m_thread; | ||
| 301 | KProcess* m_server; | ||
| 302 | KEvent* m_event; | ||
| 303 | uintptr_t m_address; | ||
| 304 | size_t m_size; | ||
| 305 | }; | ||
| 306 | |||
| 307 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_shared_memory_info.h b/src/core/hle/kernel/k_shared_memory_info.h index e43db8515..2bb6b6d08 100644 --- a/src/core/hle/kernel/k_shared_memory_info.h +++ b/src/core/hle/kernel/k_shared_memory_info.h | |||
| @@ -15,7 +15,8 @@ class KSharedMemoryInfo final : public KSlabAllocated<KSharedMemoryInfo>, | |||
| 15 | public boost::intrusive::list_base_hook<> { | 15 | public boost::intrusive::list_base_hook<> { |
| 16 | 16 | ||
| 17 | public: | 17 | public: |
| 18 | explicit KSharedMemoryInfo() = default; | 18 | explicit KSharedMemoryInfo(KernelCore&) {} |
| 19 | KSharedMemoryInfo() = default; | ||
| 19 | 20 | ||
| 20 | constexpr void Initialize(KSharedMemory* shmem) { | 21 | constexpr void Initialize(KSharedMemory* shmem) { |
| 21 | shared_memory = shmem; | 22 | shared_memory = shmem; |
diff --git a/src/core/hle/kernel/k_thread_local_page.h b/src/core/hle/kernel/k_thread_local_page.h index 0a7f22680..5d466ace7 100644 --- a/src/core/hle/kernel/k_thread_local_page.h +++ b/src/core/hle/kernel/k_thread_local_page.h | |||
| @@ -26,7 +26,7 @@ public: | |||
| 26 | static_assert(RegionsPerPage > 0); | 26 | static_assert(RegionsPerPage > 0); |
| 27 | 27 | ||
| 28 | public: | 28 | public: |
| 29 | constexpr explicit KThreadLocalPage(VAddr addr = {}) : m_virt_addr(addr) { | 29 | constexpr explicit KThreadLocalPage(KernelCore&, VAddr addr = {}) : m_virt_addr(addr) { |
| 30 | m_is_region_free.fill(true); | 30 | m_is_region_free.fill(true); |
| 31 | } | 31 | } |
| 32 | 32 | ||
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 6eded9539..266be2bc4 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -47,6 +47,7 @@ class KResourceLimit; | |||
| 47 | class KScheduler; | 47 | class KScheduler; |
| 48 | class KServerSession; | 48 | class KServerSession; |
| 49 | class KSession; | 49 | class KSession; |
| 50 | class KSessionRequest; | ||
| 50 | class KSharedMemory; | 51 | class KSharedMemory; |
| 51 | class KSharedMemoryInfo; | 52 | class KSharedMemoryInfo; |
| 52 | class KThread; | 53 | class KThread; |
| @@ -360,6 +361,8 @@ public: | |||
| 360 | return slab_heap_container->page_buffer; | 361 | return slab_heap_container->page_buffer; |
| 361 | } else if constexpr (std::is_same_v<T, KThreadLocalPage>) { | 362 | } else if constexpr (std::is_same_v<T, KThreadLocalPage>) { |
| 362 | return slab_heap_container->thread_local_page; | 363 | return slab_heap_container->thread_local_page; |
| 364 | } else if constexpr (std::is_same_v<T, KSessionRequest>) { | ||
| 365 | return slab_heap_container->session_request; | ||
| 363 | } | 366 | } |
| 364 | } | 367 | } |
| 365 | 368 | ||
| @@ -422,6 +425,7 @@ private: | |||
| 422 | KSlabHeap<KCodeMemory> code_memory; | 425 | KSlabHeap<KCodeMemory> code_memory; |
| 423 | KSlabHeap<KPageBuffer> page_buffer; | 426 | KSlabHeap<KPageBuffer> page_buffer; |
| 424 | KSlabHeap<KThreadLocalPage> thread_local_page; | 427 | KSlabHeap<KThreadLocalPage> thread_local_page; |
| 428 | KSlabHeap<KSessionRequest> session_request; | ||
| 425 | }; | 429 | }; |
| 426 | 430 | ||
| 427 | std::unique_ptr<SlabHeapContainer> slab_heap_container; | 431 | std::unique_ptr<SlabHeapContainer> slab_heap_container; |
diff --git a/src/core/hle/kernel/slab_helpers.h b/src/core/hle/kernel/slab_helpers.h index 299a981a8..06b51e919 100644 --- a/src/core/hle/kernel/slab_helpers.h +++ b/src/core/hle/kernel/slab_helpers.h | |||
| @@ -24,7 +24,7 @@ public: | |||
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | static Derived* Allocate(KernelCore& kernel) { | 26 | static Derived* Allocate(KernelCore& kernel) { |
| 27 | return kernel.SlabHeap<Derived>().Allocate(); | 27 | return kernel.SlabHeap<Derived>().Allocate(kernel); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | static void Free(KernelCore& kernel, Derived* obj) { | 30 | static void Free(KernelCore& kernel, Derived* obj) { |