summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar Lioncash2018-08-28 12:30:33 -0400
committerGravatar Lioncash2018-08-28 22:31:51 -0400
commit0cbcd6ec9aeeafc298fe2e6e4ac10d68bb7267c5 (patch)
tree2d7bb143d490c3984bff6deda426b818bf27d552 /src/core/hle/kernel/svc.cpp
parentMerge pull request #1193 from lioncash/priv (diff)
downloadyuzu-0cbcd6ec9aeeafc298fe2e6e4ac10d68bb7267c5.tar.gz
yuzu-0cbcd6ec9aeeafc298fe2e6e4ac10d68bb7267c5.tar.xz
yuzu-0cbcd6ec9aeeafc298fe2e6e4ac10d68bb7267c5.zip
kernel: Eliminate kernel global state
As means to pave the way for getting rid of global state within core, This eliminates kernel global state by removing all globals. Instead this introduces a KernelCore class which acts as a kernel instance. This instance lives in the System class, which keeps its lifetime contained to the lifetime of the System class. This also forces the kernel types to actually interact with the main kernel instance itself instead of having transient kernel state placed all over several translation units, keeping everything together. It also has a nice consequence of making dependencies much more explicit. This also makes our initialization a tad bit more correct. Previously we were creating a kernel process before the actual kernel was initialized, which doesn't really make much sense. The KernelCore class itself follows the PImpl idiom, which allows keeping all the implementation details sealed away from everything else, which forces the use of the exposed API and allows us to avoid any unnecessary inclusions within the main kernel header.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp80
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.
95static ResultCode SendSyncRequest(Handle handle) { 96static 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) {
112static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { 114static 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) {
125static ResultCode GetProcessId(u32* process_id, Handle process_handle) { 128static 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
219static ResultCode CancelSynchronization(Handle thread_handle) { 224static 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
354static ResultCode GetThreadPriority(u32* priority, Handle handle) { 362static 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
432static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/, 444static 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
548static ResultCode StartThread(Handle thread_handle) { 563static 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
784static ResultCode CloseHandle(Handle handle) { 802static 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
790static ResultCode ResetSignal(Handle handle) { 810static 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
806static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) { 830static 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
873static ResultCode ClearEvent(Handle handle) { 902static 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();