diff options
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 38 | ||||
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.h | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 34 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 3 |
4 files changed, 68 insertions, 15 deletions
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 45135a07f..5b3feec66 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -287,18 +287,52 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size, | |||
| 287 | BufferDescriptorB().size() > buffer_index && | 287 | BufferDescriptorB().size() > buffer_index && |
| 288 | BufferDescriptorB()[buffer_index].Size() >= size, | 288 | BufferDescriptorB()[buffer_index].Size() >= size, |
| 289 | { return 0; }, "BufferDescriptorB is invalid, index={}, size={}", buffer_index, size); | 289 | { return 0; }, "BufferDescriptorB is invalid, index={}, size={}", buffer_index, size); |
| 290 | memory.WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size); | 290 | WriteBufferB(buffer, size, buffer_index); |
| 291 | } else { | 291 | } else { |
| 292 | ASSERT_OR_EXECUTE_MSG( | 292 | ASSERT_OR_EXECUTE_MSG( |
| 293 | BufferDescriptorC().size() > buffer_index && | 293 | BufferDescriptorC().size() > buffer_index && |
| 294 | BufferDescriptorC()[buffer_index].Size() >= size, | 294 | BufferDescriptorC()[buffer_index].Size() >= size, |
| 295 | { return 0; }, "BufferDescriptorC is invalid, index={}, size={}", buffer_index, size); | 295 | { return 0; }, "BufferDescriptorC is invalid, index={}, size={}", buffer_index, size); |
| 296 | memory.WriteBlock(BufferDescriptorC()[buffer_index].Address(), buffer, size); | 296 | WriteBufferC(buffer, size, buffer_index); |
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | return size; | 299 | return size; |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | std::size_t HLERequestContext::WriteBufferB(const void* buffer, std::size_t size, | ||
| 303 | std::size_t buffer_index) const { | ||
| 304 | if (buffer_index >= BufferDescriptorB().size() || size == 0) { | ||
| 305 | return 0; | ||
| 306 | } | ||
| 307 | |||
| 308 | const auto buffer_size{BufferDescriptorB()[buffer_index].Size()}; | ||
| 309 | if (size > buffer_size) { | ||
| 310 | LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size, | ||
| 311 | buffer_size); | ||
| 312 | size = buffer_size; // TODO(bunnei): This needs to be HW tested | ||
| 313 | } | ||
| 314 | |||
| 315 | memory.WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size); | ||
| 316 | return size; | ||
| 317 | } | ||
| 318 | |||
| 319 | std::size_t HLERequestContext::WriteBufferC(const void* buffer, std::size_t size, | ||
| 320 | std::size_t buffer_index) const { | ||
| 321 | if (buffer_index >= BufferDescriptorC().size() || size == 0) { | ||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | |||
| 325 | const auto buffer_size{BufferDescriptorC()[buffer_index].Size()}; | ||
| 326 | if (size > buffer_size) { | ||
| 327 | LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size, | ||
| 328 | buffer_size); | ||
| 329 | size = buffer_size; // TODO(bunnei): This needs to be HW tested | ||
| 330 | } | ||
| 331 | |||
| 332 | memory.WriteBlock(BufferDescriptorC()[buffer_index].Address(), buffer, size); | ||
| 333 | return size; | ||
| 334 | } | ||
| 335 | |||
| 302 | std::size_t HLERequestContext::GetReadBufferSize(std::size_t buffer_index) const { | 336 | std::size_t HLERequestContext::GetReadBufferSize(std::size_t buffer_index) const { |
| 303 | const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && | 337 | const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && |
| 304 | BufferDescriptorA()[buffer_index].Size()}; | 338 | BufferDescriptorA()[buffer_index].Size()}; |
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index d3abeee85..99265ce90 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h | |||
| @@ -277,6 +277,14 @@ public: | |||
| 277 | std::size_t WriteBuffer(const void* buffer, std::size_t size, | 277 | std::size_t WriteBuffer(const void* buffer, std::size_t size, |
| 278 | std::size_t buffer_index = 0) const; | 278 | std::size_t buffer_index = 0) const; |
| 279 | 279 | ||
| 280 | /// Helper function to write buffer B | ||
| 281 | std::size_t WriteBufferB(const void* buffer, std::size_t size, | ||
| 282 | std::size_t buffer_index = 0) const; | ||
| 283 | |||
| 284 | /// Helper function to write buffer C | ||
| 285 | std::size_t WriteBufferC(const void* buffer, std::size_t size, | ||
| 286 | std::size_t buffer_index = 0) const; | ||
| 287 | |||
| 280 | /* Helper function to write a buffer using the appropriate buffer descriptor | 288 | /* Helper function to write a buffer using the appropriate buffer descriptor |
| 281 | * | 289 | * |
| 282 | * @tparam T an arbitrary container that satisfies the | 290 | * @tparam T an arbitrary container that satisfies the |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 7307cf262..f23c629dc 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -95,19 +95,7 @@ struct KernelCore::Impl { | |||
| 95 | 95 | ||
| 96 | process_list.clear(); | 96 | process_list.clear(); |
| 97 | 97 | ||
| 98 | // Close all open server sessions and ports. | 98 | CloseServices(); |
| 99 | std::unordered_set<KAutoObject*> server_objects_; | ||
| 100 | { | ||
| 101 | std::scoped_lock lk(server_objects_lock); | ||
| 102 | server_objects_ = server_objects; | ||
| 103 | server_objects.clear(); | ||
| 104 | } | ||
| 105 | for (auto* server_object : server_objects_) { | ||
| 106 | server_object->Close(); | ||
| 107 | } | ||
| 108 | |||
| 109 | // Ensures all service threads gracefully shutdown. | ||
| 110 | ClearServiceThreads(); | ||
| 111 | 99 | ||
| 112 | next_object_id = 0; | 100 | next_object_id = 0; |
| 113 | next_kernel_process_id = KProcess::InitialKIPIDMin; | 101 | next_kernel_process_id = KProcess::InitialKIPIDMin; |
| @@ -191,6 +179,22 @@ struct KernelCore::Impl { | |||
| 191 | global_object_list_container.reset(); | 179 | global_object_list_container.reset(); |
| 192 | } | 180 | } |
| 193 | 181 | ||
| 182 | void CloseServices() { | ||
| 183 | // Close all open server sessions and ports. | ||
| 184 | std::unordered_set<KAutoObject*> server_objects_; | ||
| 185 | { | ||
| 186 | std::scoped_lock lk(server_objects_lock); | ||
| 187 | server_objects_ = server_objects; | ||
| 188 | server_objects.clear(); | ||
| 189 | } | ||
| 190 | for (auto* server_object : server_objects_) { | ||
| 191 | server_object->Close(); | ||
| 192 | } | ||
| 193 | |||
| 194 | // Ensures all service threads gracefully shutdown. | ||
| 195 | ClearServiceThreads(); | ||
| 196 | } | ||
| 197 | |||
| 194 | void InitializePhysicalCores() { | 198 | void InitializePhysicalCores() { |
| 195 | exclusive_monitor = | 199 | exclusive_monitor = |
| 196 | Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES); | 200 | Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES); |
| @@ -813,6 +817,10 @@ void KernelCore::Shutdown() { | |||
| 813 | impl->Shutdown(); | 817 | impl->Shutdown(); |
| 814 | } | 818 | } |
| 815 | 819 | ||
| 820 | void KernelCore::CloseServices() { | ||
| 821 | impl->CloseServices(); | ||
| 822 | } | ||
| 823 | |||
| 816 | const KResourceLimit* KernelCore::GetSystemResourceLimit() const { | 824 | const KResourceLimit* KernelCore::GetSystemResourceLimit() const { |
| 817 | return impl->system_resource_limit; | 825 | return impl->system_resource_limit; |
| 818 | } | 826 | } |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index aa0ebaa02..6c7cf6af2 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -109,6 +109,9 @@ public: | |||
| 109 | /// Clears all resources in use by the kernel instance. | 109 | /// Clears all resources in use by the kernel instance. |
| 110 | void Shutdown(); | 110 | void Shutdown(); |
| 111 | 111 | ||
| 112 | /// Close all active services in use by the kernel instance. | ||
| 113 | void CloseServices(); | ||
| 114 | |||
| 112 | /// Retrieves a shared pointer to the system resource limit instance. | 115 | /// Retrieves a shared pointer to the system resource limit instance. |
| 113 | const KResourceLimit* GetSystemResourceLimit() const; | 116 | const KResourceLimit* GetSystemResourceLimit() const; |
| 114 | 117 | ||