diff options
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 80 |
1 files changed, 55 insertions, 25 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index cb6253398..099d1053f 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -87,13 +87,15 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address | |||
| 87 | CASCADE_RESULT(client_session, client_port->Connect()); | 87 | CASCADE_RESULT(client_session, client_port->Connect()); |
| 88 | 88 | ||
| 89 | // Return the client session | 89 | // Return the client session |
| 90 | CASCADE_RESULT(*out_handle, g_handle_table.Create(client_session)); | 90 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 91 | CASCADE_RESULT(*out_handle, kernel.HandleTable().Create(client_session)); | ||
| 91 | return RESULT_SUCCESS; | 92 | return RESULT_SUCCESS; |
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | /// Makes a blocking IPC call to an OS service. | 95 | /// Makes a blocking IPC call to an OS service. |
| 95 | static ResultCode SendSyncRequest(Handle handle) { | 96 | static ResultCode SendSyncRequest(Handle handle) { |
| 96 | SharedPtr<ClientSession> session = g_handle_table.Get<ClientSession>(handle); | 97 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 98 | SharedPtr<ClientSession> session = kernel.HandleTable().Get<ClientSession>(handle); | ||
| 97 | if (!session) { | 99 | if (!session) { |
| 98 | LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle); | 100 | LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle); |
| 99 | return ERR_INVALID_HANDLE; | 101 | return ERR_INVALID_HANDLE; |
| @@ -112,7 +114,8 @@ static ResultCode SendSyncRequest(Handle handle) { | |||
| 112 | static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { | 114 | static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { |
| 113 | LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); | 115 | LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); |
| 114 | 116 | ||
| 115 | const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); | 117 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 118 | const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle); | ||
| 116 | if (!thread) { | 119 | if (!thread) { |
| 117 | return ERR_INVALID_HANDLE; | 120 | return ERR_INVALID_HANDLE; |
| 118 | } | 121 | } |
| @@ -125,7 +128,8 @@ static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { | |||
| 125 | static ResultCode GetProcessId(u32* process_id, Handle process_handle) { | 128 | static ResultCode GetProcessId(u32* process_id, Handle process_handle) { |
| 126 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle); | 129 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle); |
| 127 | 130 | ||
| 128 | const SharedPtr<Process> process = g_handle_table.Get<Process>(process_handle); | 131 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 132 | const SharedPtr<Process> process = kernel.HandleTable().Get<Process>(process_handle); | ||
| 129 | if (!process) { | 133 | if (!process) { |
| 130 | return ERR_INVALID_HANDLE; | 134 | return ERR_INVALID_HANDLE; |
| 131 | } | 135 | } |
| @@ -168,10 +172,11 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 | |||
| 168 | 172 | ||
| 169 | using ObjectPtr = SharedPtr<WaitObject>; | 173 | using ObjectPtr = SharedPtr<WaitObject>; |
| 170 | std::vector<ObjectPtr> objects(handle_count); | 174 | std::vector<ObjectPtr> objects(handle_count); |
| 175 | auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 171 | 176 | ||
| 172 | for (u64 i = 0; i < handle_count; ++i) { | 177 | for (u64 i = 0; i < handle_count; ++i) { |
| 173 | const Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); | 178 | const Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); |
| 174 | const auto object = g_handle_table.Get<WaitObject>(handle); | 179 | const auto object = kernel.HandleTable().Get<WaitObject>(handle); |
| 175 | 180 | ||
| 176 | if (object == nullptr) { | 181 | if (object == nullptr) { |
| 177 | return ERR_INVALID_HANDLE; | 182 | return ERR_INVALID_HANDLE; |
| @@ -219,7 +224,8 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 | |||
| 219 | static ResultCode CancelSynchronization(Handle thread_handle) { | 224 | static ResultCode CancelSynchronization(Handle thread_handle) { |
| 220 | LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle); | 225 | LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle); |
| 221 | 226 | ||
| 222 | const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); | 227 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 228 | const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle); | ||
| 223 | if (!thread) { | 229 | if (!thread) { |
| 224 | return ERR_INVALID_HANDLE; | 230 | return ERR_INVALID_HANDLE; |
| 225 | } | 231 | } |
| @@ -239,7 +245,9 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr, | |||
| 239 | "requesting_current_thread_handle=0x{:08X}", | 245 | "requesting_current_thread_handle=0x{:08X}", |
| 240 | holding_thread_handle, mutex_addr, requesting_thread_handle); | 246 | holding_thread_handle, mutex_addr, requesting_thread_handle); |
| 241 | 247 | ||
| 242 | return Mutex::TryAcquire(mutex_addr, holding_thread_handle, requesting_thread_handle); | 248 | auto& handle_table = Core::System::GetInstance().Kernel().HandleTable(); |
| 249 | return Mutex::TryAcquire(handle_table, mutex_addr, holding_thread_handle, | ||
| 250 | requesting_thread_handle); | ||
| 243 | } | 251 | } |
| 244 | 252 | ||
| 245 | /// Unlock a mutex | 253 | /// Unlock a mutex |
| @@ -352,7 +360,8 @@ static ResultCode GetThreadContext(Handle handle, VAddr addr) { | |||
| 352 | 360 | ||
| 353 | /// Gets the priority for the specified thread | 361 | /// Gets the priority for the specified thread |
| 354 | static ResultCode GetThreadPriority(u32* priority, Handle handle) { | 362 | static ResultCode GetThreadPriority(u32* priority, Handle handle) { |
| 355 | const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(handle); | 363 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 364 | const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(handle); | ||
| 356 | if (!thread) | 365 | if (!thread) |
| 357 | return ERR_INVALID_HANDLE; | 366 | return ERR_INVALID_HANDLE; |
| 358 | 367 | ||
| @@ -366,7 +375,8 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { | |||
| 366 | return ERR_OUT_OF_RANGE; | 375 | return ERR_OUT_OF_RANGE; |
| 367 | } | 376 | } |
| 368 | 377 | ||
| 369 | SharedPtr<Thread> thread = g_handle_table.Get<Thread>(handle); | 378 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 379 | SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(handle); | ||
| 370 | if (!thread) | 380 | if (!thread) |
| 371 | return ERR_INVALID_HANDLE; | 381 | return ERR_INVALID_HANDLE; |
| 372 | 382 | ||
| @@ -395,7 +405,8 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s | |||
| 395 | "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", | 405 | "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", |
| 396 | shared_memory_handle, addr, size, permissions); | 406 | shared_memory_handle, addr, size, permissions); |
| 397 | 407 | ||
| 398 | SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle); | 408 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 409 | auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle); | ||
| 399 | if (!shared_memory) { | 410 | if (!shared_memory) { |
| 400 | return ERR_INVALID_HANDLE; | 411 | return ERR_INVALID_HANDLE; |
| 401 | } | 412 | } |
| @@ -423,7 +434,8 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 | |||
| 423 | LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}", | 434 | LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}", |
| 424 | shared_memory_handle, addr, size); | 435 | shared_memory_handle, addr, size); |
| 425 | 436 | ||
| 426 | SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle); | 437 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 438 | auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle); | ||
| 427 | 439 | ||
| 428 | return shared_memory->Unmap(Core::CurrentProcess().get(), addr); | 440 | return shared_memory->Unmap(Core::CurrentProcess().get(), addr); |
| 429 | } | 441 | } |
| @@ -431,7 +443,9 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 | |||
| 431 | /// Query process memory | 443 | /// Query process memory |
| 432 | static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/, | 444 | static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/, |
| 433 | Handle process_handle, u64 addr) { | 445 | Handle process_handle, u64 addr) { |
| 434 | SharedPtr<Process> process = g_handle_table.Get<Process>(process_handle); | 446 | |
| 447 | auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 448 | SharedPtr<Process> process = kernel.HandleTable().Get<Process>(process_handle); | ||
| 435 | if (!process) { | 449 | if (!process) { |
| 436 | return ERR_INVALID_HANDLE; | 450 | return ERR_INVALID_HANDLE; |
| 437 | } | 451 | } |
| @@ -528,10 +542,11 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V | |||
| 528 | break; | 542 | break; |
| 529 | } | 543 | } |
| 530 | 544 | ||
| 545 | auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 531 | CASCADE_RESULT(SharedPtr<Thread> thread, | 546 | CASCADE_RESULT(SharedPtr<Thread> thread, |
| 532 | Thread::Create(name, entry_point, priority, arg, processor_id, stack_top, | 547 | Thread::Create(kernel, name, entry_point, priority, arg, processor_id, stack_top, |
| 533 | Core::CurrentProcess())); | 548 | Core::CurrentProcess())); |
| 534 | CASCADE_RESULT(thread->guest_handle, g_handle_table.Create(thread)); | 549 | CASCADE_RESULT(thread->guest_handle, kernel.HandleTable().Create(thread)); |
| 535 | *out_handle = thread->guest_handle; | 550 | *out_handle = thread->guest_handle; |
| 536 | 551 | ||
| 537 | Core::System::GetInstance().CpuCore(thread->processor_id).PrepareReschedule(); | 552 | Core::System::GetInstance().CpuCore(thread->processor_id).PrepareReschedule(); |
| @@ -548,7 +563,8 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V | |||
| 548 | static ResultCode StartThread(Handle thread_handle) { | 563 | static ResultCode StartThread(Handle thread_handle) { |
| 549 | LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); | 564 | LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); |
| 550 | 565 | ||
| 551 | const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); | 566 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 567 | const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle); | ||
| 552 | if (!thread) { | 568 | if (!thread) { |
| 553 | return ERR_INVALID_HANDLE; | 569 | return ERR_INVALID_HANDLE; |
| 554 | } | 570 | } |
| @@ -595,7 +611,8 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var | |||
| 595 | "called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle=0x{:08X}, timeout={}", | 611 | "called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle=0x{:08X}, timeout={}", |
| 596 | mutex_addr, condition_variable_addr, thread_handle, nano_seconds); | 612 | mutex_addr, condition_variable_addr, thread_handle, nano_seconds); |
| 597 | 613 | ||
| 598 | SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); | 614 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 615 | SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle); | ||
| 599 | ASSERT(thread); | 616 | ASSERT(thread); |
| 600 | 617 | ||
| 601 | CASCADE_CODE(Mutex::Release(mutex_addr)); | 618 | CASCADE_CODE(Mutex::Release(mutex_addr)); |
| @@ -704,8 +721,9 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target | |||
| 704 | mutex_val | Mutex::MutexHasWaitersFlag)); | 721 | mutex_val | Mutex::MutexHasWaitersFlag)); |
| 705 | 722 | ||
| 706 | // The mutex is already owned by some other thread, make this thread wait on it. | 723 | // The mutex is already owned by some other thread, make this thread wait on it. |
| 724 | auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 707 | Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask); | 725 | Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask); |
| 708 | auto owner = g_handle_table.Get<Thread>(owner_handle); | 726 | auto owner = kernel.HandleTable().Get<Thread>(owner_handle); |
| 709 | ASSERT(owner); | 727 | ASSERT(owner); |
| 710 | ASSERT(thread->status == ThreadStatus::WaitMutex); | 728 | ASSERT(thread->status == ThreadStatus::WaitMutex); |
| 711 | thread->wakeup_callback = nullptr; | 729 | thread->wakeup_callback = nullptr; |
| @@ -783,14 +801,20 @@ static u64 GetSystemTick() { | |||
| 783 | /// Close a handle | 801 | /// Close a handle |
| 784 | static ResultCode CloseHandle(Handle handle) { | 802 | static ResultCode CloseHandle(Handle handle) { |
| 785 | LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); | 803 | LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); |
| 786 | return g_handle_table.Close(handle); | 804 | |
| 805 | auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 806 | return kernel.HandleTable().Close(handle); | ||
| 787 | } | 807 | } |
| 788 | 808 | ||
| 789 | /// Reset an event | 809 | /// Reset an event |
| 790 | static ResultCode ResetSignal(Handle handle) { | 810 | static ResultCode ResetSignal(Handle handle) { |
| 791 | LOG_WARNING(Kernel_SVC, "(STUBBED) called handle 0x{:08X}", handle); | 811 | LOG_WARNING(Kernel_SVC, "(STUBBED) called handle 0x{:08X}", handle); |
| 792 | auto event = g_handle_table.Get<Event>(handle); | 812 | |
| 813 | auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 814 | auto event = kernel.HandleTable().Get<Event>(handle); | ||
| 815 | |||
| 793 | ASSERT(event != nullptr); | 816 | ASSERT(event != nullptr); |
| 817 | |||
| 794 | event->Clear(); | 818 | event->Clear(); |
| 795 | return RESULT_SUCCESS; | 819 | return RESULT_SUCCESS; |
| 796 | } | 820 | } |
| @@ -806,7 +830,8 @@ static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32 | |||
| 806 | static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) { | 830 | static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) { |
| 807 | LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); | 831 | LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); |
| 808 | 832 | ||
| 809 | const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); | 833 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 834 | const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle); | ||
| 810 | if (!thread) { | 835 | if (!thread) { |
| 811 | return ERR_INVALID_HANDLE; | 836 | return ERR_INVALID_HANDLE; |
| 812 | } | 837 | } |
| @@ -821,7 +846,8 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { | |||
| 821 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:16X}, core=0x{:X}", thread_handle, | 846 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:16X}, core=0x{:X}", thread_handle, |
| 822 | mask, core); | 847 | mask, core); |
| 823 | 848 | ||
| 824 | const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); | 849 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 850 | const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle); | ||
| 825 | if (!thread) { | 851 | if (!thread) { |
| 826 | return ERR_INVALID_HANDLE; | 852 | return ERR_INVALID_HANDLE; |
| 827 | } | 853 | } |
| @@ -861,19 +887,23 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss | |||
| 861 | u32 remote_permissions) { | 887 | u32 remote_permissions) { |
| 862 | LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size, | 888 | LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size, |
| 863 | local_permissions, remote_permissions); | 889 | local_permissions, remote_permissions); |
| 864 | auto sharedMemHandle = | 890 | |
| 865 | SharedMemory::Create(g_handle_table.Get<Process>(KernelHandle::CurrentProcess), size, | 891 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 892 | auto& handle_table = kernel.HandleTable(); | ||
| 893 | auto shared_mem_handle = | ||
| 894 | SharedMemory::Create(kernel, handle_table.Get<Process>(KernelHandle::CurrentProcess), size, | ||
| 866 | static_cast<MemoryPermission>(local_permissions), | 895 | static_cast<MemoryPermission>(local_permissions), |
| 867 | static_cast<MemoryPermission>(remote_permissions)); | 896 | static_cast<MemoryPermission>(remote_permissions)); |
| 868 | 897 | ||
| 869 | CASCADE_RESULT(*handle, g_handle_table.Create(sharedMemHandle)); | 898 | CASCADE_RESULT(*handle, handle_table.Create(shared_mem_handle)); |
| 870 | return RESULT_SUCCESS; | 899 | return RESULT_SUCCESS; |
| 871 | } | 900 | } |
| 872 | 901 | ||
| 873 | static ResultCode ClearEvent(Handle handle) { | 902 | static ResultCode ClearEvent(Handle handle) { |
| 874 | LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); | 903 | LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); |
| 875 | 904 | ||
| 876 | SharedPtr<Event> evt = g_handle_table.Get<Event>(handle); | 905 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 906 | SharedPtr<Event> evt = kernel.HandleTable().Get<Event>(handle); | ||
| 877 | if (evt == nullptr) | 907 | if (evt == nullptr) |
| 878 | return ERR_INVALID_HANDLE; | 908 | return ERR_INVALID_HANDLE; |
| 879 | evt->Clear(); | 909 | evt->Clear(); |