summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2019-04-11 21:50:05 -0400
committerGravatar GitHub2019-04-11 21:50:05 -0400
commit83a2fb3c3a1d75be6e4e01bdeeb1cc23293561ad (patch)
tree2c5bac8e30d7dd7e6b660d3c4050f8838ef1d744 /src/core/hle/kernel/svc.cpp
parentMerge pull request #2388 from lioncash/constexpr (diff)
parentkernel/svc: Deglobalize the supervisor call handlers (diff)
downloadyuzu-83a2fb3c3a1d75be6e4e01bdeeb1cc23293561ad.tar.gz
yuzu-83a2fb3c3a1d75be6e4e01bdeeb1cc23293561ad.tar.xz
yuzu-83a2fb3c3a1d75be6e4e01bdeeb1cc23293561ad.zip
Merge pull request #2360 from lioncash/svc-global
kernel/svc: Deglobalize the supervisor call handlers
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp337
1 files changed, 175 insertions, 162 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 2fd07ab34..e5d4d6b55 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -131,16 +131,15 @@ enum class ResourceLimitValueType {
131 LimitValue, 131 LimitValue,
132}; 132};
133 133
134ResultVal<s64> RetrieveResourceLimitValue(Handle resource_limit, u32 resource_type, 134ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit,
135 ResourceLimitValueType value_type) { 135 u32 resource_type, ResourceLimitValueType value_type) {
136 const auto type = static_cast<ResourceType>(resource_type); 136 const auto type = static_cast<ResourceType>(resource_type);
137 if (!IsValidResourceType(type)) { 137 if (!IsValidResourceType(type)) {
138 LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); 138 LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type);
139 return ERR_INVALID_ENUM_VALUE; 139 return ERR_INVALID_ENUM_VALUE;
140 } 140 }
141 141
142 const auto& kernel = Core::System::GetInstance().Kernel(); 142 const auto* const current_process = system.Kernel().CurrentProcess();
143 const auto* const current_process = kernel.CurrentProcess();
144 ASSERT(current_process != nullptr); 143 ASSERT(current_process != nullptr);
145 144
146 const auto resource_limit_object = 145 const auto resource_limit_object =
@@ -160,7 +159,7 @@ ResultVal<s64> RetrieveResourceLimitValue(Handle resource_limit, u32 resource_ty
160} // Anonymous namespace 159} // Anonymous namespace
161 160
162/// Set the process heap to a given Size. It can both extend and shrink the heap. 161/// Set the process heap to a given Size. It can both extend and shrink the heap.
163static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { 162static ResultCode SetHeapSize(Core::System& system, VAddr* heap_addr, u64 heap_size) {
164 LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size); 163 LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size);
165 164
166 // Size must be a multiple of 0x200000 (2MB) and be equal to or less than 8GB. 165 // Size must be a multiple of 0x200000 (2MB) and be equal to or less than 8GB.
@@ -175,7 +174,7 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
175 return ERR_INVALID_SIZE; 174 return ERR_INVALID_SIZE;
176 } 175 }
177 176
178 auto& vm_manager = Core::System::GetInstance().Kernel().CurrentProcess()->VMManager(); 177 auto& vm_manager = system.Kernel().CurrentProcess()->VMManager();
179 const auto alloc_result = vm_manager.SetHeapSize(heap_size); 178 const auto alloc_result = vm_manager.SetHeapSize(heap_size);
180 if (alloc_result.Failed()) { 179 if (alloc_result.Failed()) {
181 return alloc_result.Code(); 180 return alloc_result.Code();
@@ -185,7 +184,7 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
185 return RESULT_SUCCESS; 184 return RESULT_SUCCESS;
186} 185}
187 186
188static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) { 187static ResultCode SetMemoryPermission(Core::System& system, VAddr addr, u64 size, u32 prot) {
189 LOG_TRACE(Kernel_SVC, "called, addr=0x{:X}, size=0x{:X}, prot=0x{:X}", addr, size, prot); 188 LOG_TRACE(Kernel_SVC, "called, addr=0x{:X}, size=0x{:X}, prot=0x{:X}", addr, size, prot);
190 189
191 if (!Common::Is4KBAligned(addr)) { 190 if (!Common::Is4KBAligned(addr)) {
@@ -217,7 +216,7 @@ static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) {
217 return ERR_INVALID_MEMORY_PERMISSIONS; 216 return ERR_INVALID_MEMORY_PERMISSIONS;
218 } 217 }
219 218
220 auto* const current_process = Core::CurrentProcess(); 219 auto* const current_process = system.Kernel().CurrentProcess();
221 auto& vm_manager = current_process->VMManager(); 220 auto& vm_manager = current_process->VMManager();
222 221
223 if (!vm_manager.IsWithinAddressSpace(addr, size)) { 222 if (!vm_manager.IsWithinAddressSpace(addr, size)) {
@@ -242,7 +241,8 @@ static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) {
242 return vm_manager.ReprotectRange(addr, size, converted_permissions); 241 return vm_manager.ReprotectRange(addr, size, converted_permissions);
243} 242}
244 243
245static ResultCode SetMemoryAttribute(VAddr address, u64 size, u32 mask, u32 attribute) { 244static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask,
245 u32 attribute) {
246 LOG_DEBUG(Kernel_SVC, 246 LOG_DEBUG(Kernel_SVC,
247 "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address, 247 "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address,
248 size, mask, attribute); 248 size, mask, attribute);
@@ -280,7 +280,7 @@ static ResultCode SetMemoryAttribute(VAddr address, u64 size, u32 mask, u32 attr
280 return ERR_INVALID_COMBINATION; 280 return ERR_INVALID_COMBINATION;
281 } 281 }
282 282
283 auto& vm_manager = Core::CurrentProcess()->VMManager(); 283 auto& vm_manager = system.Kernel().CurrentProcess()->VMManager();
284 if (!vm_manager.IsWithinAddressSpace(address, size)) { 284 if (!vm_manager.IsWithinAddressSpace(address, size)) {
285 LOG_ERROR(Kernel_SVC, 285 LOG_ERROR(Kernel_SVC,
286 "Given address (0x{:016X}) is outside the bounds of the address space.", address); 286 "Given address (0x{:016X}) is outside the bounds of the address space.", address);
@@ -291,11 +291,11 @@ static ResultCode SetMemoryAttribute(VAddr address, u64 size, u32 mask, u32 attr
291} 291}
292 292
293/// Maps a memory range into a different range. 293/// Maps a memory range into a different range.
294static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { 294static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
295 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, 295 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
296 src_addr, size); 296 src_addr, size);
297 297
298 auto& vm_manager = Core::CurrentProcess()->VMManager(); 298 auto& vm_manager = system.Kernel().CurrentProcess()->VMManager();
299 const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size); 299 const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size);
300 300
301 if (result.IsError()) { 301 if (result.IsError()) {
@@ -306,11 +306,11 @@ static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
306} 306}
307 307
308/// Unmaps a region that was previously mapped with svcMapMemory 308/// Unmaps a region that was previously mapped with svcMapMemory
309static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { 309static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
310 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, 310 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
311 src_addr, size); 311 src_addr, size);
312 312
313 auto& vm_manager = Core::CurrentProcess()->VMManager(); 313 auto& vm_manager = system.Kernel().CurrentProcess()->VMManager();
314 const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size); 314 const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size);
315 315
316 if (result.IsError()) { 316 if (result.IsError()) {
@@ -321,7 +321,8 @@ static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
321} 321}
322 322
323/// Connect to an OS service given the port name, returns the handle to the port to out 323/// Connect to an OS service given the port name, returns the handle to the port to out
324static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address) { 324static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,
325 VAddr port_name_address) {
325 if (!Memory::IsValidVirtualAddress(port_name_address)) { 326 if (!Memory::IsValidVirtualAddress(port_name_address)) {
326 LOG_ERROR(Kernel_SVC, 327 LOG_ERROR(Kernel_SVC,
327 "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}", 328 "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}",
@@ -340,8 +341,8 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address
340 341
341 LOG_TRACE(Kernel_SVC, "called port_name={}", port_name); 342 LOG_TRACE(Kernel_SVC, "called port_name={}", port_name);
342 343
343 auto& kernel = Core::System::GetInstance().Kernel(); 344 auto& kernel = system.Kernel();
344 auto it = kernel.FindNamedPort(port_name); 345 const auto it = kernel.FindNamedPort(port_name);
345 if (!kernel.IsValidNamedPort(it)) { 346 if (!kernel.IsValidNamedPort(it)) {
346 LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: {}", port_name); 347 LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: {}", port_name);
347 return ERR_NOT_FOUND; 348 return ERR_NOT_FOUND;
@@ -353,14 +354,14 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address
353 CASCADE_RESULT(client_session, client_port->Connect()); 354 CASCADE_RESULT(client_session, client_port->Connect());
354 355
355 // Return the client session 356 // Return the client session
356 auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 357 auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
357 CASCADE_RESULT(*out_handle, handle_table.Create(client_session)); 358 CASCADE_RESULT(*out_handle, handle_table.Create(client_session));
358 return RESULT_SUCCESS; 359 return RESULT_SUCCESS;
359} 360}
360 361
361/// Makes a blocking IPC call to an OS service. 362/// Makes a blocking IPC call to an OS service.
362static ResultCode SendSyncRequest(Handle handle) { 363static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
363 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 364 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
364 SharedPtr<ClientSession> session = handle_table.Get<ClientSession>(handle); 365 SharedPtr<ClientSession> session = handle_table.Get<ClientSession>(handle);
365 if (!session) { 366 if (!session) {
366 LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle); 367 LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle);
@@ -369,18 +370,18 @@ static ResultCode SendSyncRequest(Handle handle) {
369 370
370 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); 371 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
371 372
372 Core::System::GetInstance().PrepareReschedule(); 373 system.PrepareReschedule();
373 374
374 // TODO(Subv): svcSendSyncRequest should put the caller thread to sleep while the server 375 // TODO(Subv): svcSendSyncRequest should put the caller thread to sleep while the server
375 // responds and cause a reschedule. 376 // responds and cause a reschedule.
376 return session->SendSyncRequest(GetCurrentThread()); 377 return session->SendSyncRequest(system.CurrentScheduler().GetCurrentThread());
377} 378}
378 379
379/// Get the ID for the specified thread. 380/// Get the ID for the specified thread.
380static ResultCode GetThreadId(u64* thread_id, Handle thread_handle) { 381static ResultCode GetThreadId(Core::System& system, u64* thread_id, Handle thread_handle) {
381 LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); 382 LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
382 383
383 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 384 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
384 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); 385 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
385 if (!thread) { 386 if (!thread) {
386 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", thread_handle); 387 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", thread_handle);
@@ -392,10 +393,10 @@ static ResultCode GetThreadId(u64* thread_id, Handle thread_handle) {
392} 393}
393 394
394/// Gets the ID of the specified process or a specified thread's owning process. 395/// Gets the ID of the specified process or a specified thread's owning process.
395static ResultCode GetProcessId(u64* process_id, Handle handle) { 396static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle handle) {
396 LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle); 397 LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle);
397 398
398 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 399 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
399 const SharedPtr<Process> process = handle_table.Get<Process>(handle); 400 const SharedPtr<Process> process = handle_table.Get<Process>(handle);
400 if (process) { 401 if (process) {
401 *process_id = process->GetProcessID(); 402 *process_id = process->GetProcessID();
@@ -437,8 +438,8 @@ static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thr
437}; 438};
438 439
439/// Wait for the given handles to synchronize, timeout after the specified nanoseconds 440/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
440static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 handle_count, 441static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr handles_address,
441 s64 nano_seconds) { 442 u64 handle_count, s64 nano_seconds) {
442 LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", 443 LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}",
443 handles_address, handle_count, nano_seconds); 444 handles_address, handle_count, nano_seconds);
444 445
@@ -457,11 +458,11 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64
457 return ERR_OUT_OF_RANGE; 458 return ERR_OUT_OF_RANGE;
458 } 459 }
459 460
460 auto* const thread = GetCurrentThread(); 461 auto* const thread = system.CurrentScheduler().GetCurrentThread();
461 462
462 using ObjectPtr = Thread::ThreadWaitObjects::value_type; 463 using ObjectPtr = Thread::ThreadWaitObjects::value_type;
463 Thread::ThreadWaitObjects objects(handle_count); 464 Thread::ThreadWaitObjects objects(handle_count);
464 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 465 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
465 466
466 for (u64 i = 0; i < handle_count; ++i) { 467 for (u64 i = 0; i < handle_count; ++i) {
467 const Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); 468 const Handle handle = Memory::Read32(handles_address + i * sizeof(Handle));
@@ -507,16 +508,16 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64
507 thread->WakeAfterDelay(nano_seconds); 508 thread->WakeAfterDelay(nano_seconds);
508 thread->SetWakeupCallback(DefaultThreadWakeupCallback); 509 thread->SetWakeupCallback(DefaultThreadWakeupCallback);
509 510
510 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); 511 system.CpuCore(thread->GetProcessorID()).PrepareReschedule();
511 512
512 return RESULT_TIMEOUT; 513 return RESULT_TIMEOUT;
513} 514}
514 515
515/// Resumes a thread waiting on WaitSynchronization 516/// Resumes a thread waiting on WaitSynchronization
516static ResultCode CancelSynchronization(Handle thread_handle) { 517static ResultCode CancelSynchronization(Core::System& system, Handle thread_handle) {
517 LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle); 518 LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle);
518 519
519 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 520 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
520 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); 521 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
521 if (!thread) { 522 if (!thread) {
522 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", 523 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
@@ -531,8 +532,8 @@ static ResultCode CancelSynchronization(Handle thread_handle) {
531} 532}
532 533
533/// Attempts to locks a mutex, creating it if it does not already exist 534/// Attempts to locks a mutex, creating it if it does not already exist
534static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr, 535static ResultCode ArbitrateLock(Core::System& system, Handle holding_thread_handle,
535 Handle requesting_thread_handle) { 536 VAddr mutex_addr, Handle requesting_thread_handle) {
536 LOG_TRACE(Kernel_SVC, 537 LOG_TRACE(Kernel_SVC,
537 "called holding_thread_handle=0x{:08X}, mutex_addr=0x{:X}, " 538 "called holding_thread_handle=0x{:08X}, mutex_addr=0x{:X}, "
538 "requesting_current_thread_handle=0x{:08X}", 539 "requesting_current_thread_handle=0x{:08X}",
@@ -549,13 +550,13 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr,
549 return ERR_INVALID_ADDRESS; 550 return ERR_INVALID_ADDRESS;
550 } 551 }
551 552
552 auto* const current_process = Core::System::GetInstance().Kernel().CurrentProcess(); 553 auto* const current_process = system.Kernel().CurrentProcess();
553 return current_process->GetMutex().TryAcquire(mutex_addr, holding_thread_handle, 554 return current_process->GetMutex().TryAcquire(mutex_addr, holding_thread_handle,
554 requesting_thread_handle); 555 requesting_thread_handle);
555} 556}
556 557
557/// Unlock a mutex 558/// Unlock a mutex
558static ResultCode ArbitrateUnlock(VAddr mutex_addr) { 559static ResultCode ArbitrateUnlock(Core::System& system, VAddr mutex_addr) {
559 LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr); 560 LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr);
560 561
561 if (Memory::IsKernelVirtualAddress(mutex_addr)) { 562 if (Memory::IsKernelVirtualAddress(mutex_addr)) {
@@ -569,7 +570,7 @@ static ResultCode ArbitrateUnlock(VAddr mutex_addr) {
569 return ERR_INVALID_ADDRESS; 570 return ERR_INVALID_ADDRESS;
570 } 571 }
571 572
572 auto* const current_process = Core::System::GetInstance().Kernel().CurrentProcess(); 573 auto* const current_process = system.Kernel().CurrentProcess();
573 return current_process->GetMutex().Release(mutex_addr); 574 return current_process->GetMutex().Release(mutex_addr);
574} 575}
575 576
@@ -592,7 +593,7 @@ struct BreakReason {
592}; 593};
593 594
594/// Break program execution 595/// Break program execution
595static void Break(u32 reason, u64 info1, u64 info2) { 596static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {
596 BreakReason break_reason{reason}; 597 BreakReason break_reason{reason};
597 bool has_dumped_buffer{}; 598 bool has_dumped_buffer{};
598 599
@@ -670,22 +671,24 @@ static void Break(u32 reason, u64 info1, u64 info2) {
670 Debug_Emulated, 671 Debug_Emulated,
671 "Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}", 672 "Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}",
672 reason, info1, info2); 673 reason, info1, info2);
674
673 handle_debug_buffer(info1, info2); 675 handle_debug_buffer(info1, info2);
674 Core::System::GetInstance() 676
675 .ArmInterface(static_cast<std::size_t>(GetCurrentThread()->GetProcessorID())) 677 auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
676 .LogBacktrace(); 678 const auto thread_processor_id = current_thread->GetProcessorID();
679 system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace();
677 ASSERT(false); 680 ASSERT(false);
678 681
679 Core::CurrentProcess()->PrepareForTermination(); 682 system.Kernel().CurrentProcess()->PrepareForTermination();
680 683
681 // Kill the current thread 684 // Kill the current thread
682 GetCurrentThread()->Stop(); 685 current_thread->Stop();
683 Core::System::GetInstance().PrepareReschedule(); 686 system.PrepareReschedule();
684 } 687 }
685} 688}
686 689
687/// Used to output a message on a debug hardware unit - does nothing on a retail unit 690/// Used to output a message on a debug hardware unit - does nothing on a retail unit
688static void OutputDebugString(VAddr address, u64 len) { 691static void OutputDebugString([[maybe_unused]] Core::System& system, VAddr address, u64 len) {
689 if (len == 0) { 692 if (len == 0) {
690 return; 693 return;
691 } 694 }
@@ -696,7 +699,8 @@ static void OutputDebugString(VAddr address, u64 len) {
696} 699}
697 700
698/// Gets system/memory information for the current process 701/// Gets system/memory information for the current process
699static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) { 702static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 handle,
703 u64 info_sub_id) {
700 LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, 704 LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id,
701 info_sub_id, handle); 705 info_sub_id, handle);
702 706
@@ -754,7 +758,8 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
754 return ERR_INVALID_ENUM_VALUE; 758 return ERR_INVALID_ENUM_VALUE;
755 } 759 }
756 760
757 const auto& current_process_handle_table = Core::CurrentProcess()->GetHandleTable(); 761 const auto& current_process_handle_table =
762 system.Kernel().CurrentProcess()->GetHandleTable();
758 const auto process = current_process_handle_table.Get<Process>(static_cast<Handle>(handle)); 763 const auto process = current_process_handle_table.Get<Process>(static_cast<Handle>(handle));
759 if (!process) { 764 if (!process) {
760 return ERR_INVALID_HANDLE; 765 return ERR_INVALID_HANDLE;
@@ -844,7 +849,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
844 return ERR_INVALID_COMBINATION; 849 return ERR_INVALID_COMBINATION;
845 } 850 }
846 851
847 Process* const current_process = Core::CurrentProcess(); 852 Process* const current_process = system.Kernel().CurrentProcess();
848 HandleTable& handle_table = current_process->GetHandleTable(); 853 HandleTable& handle_table = current_process->GetHandleTable();
849 const auto resource_limit = current_process->GetResourceLimit(); 854 const auto resource_limit = current_process->GetResourceLimit();
850 if (!resource_limit) { 855 if (!resource_limit) {
@@ -875,7 +880,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
875 return ERR_INVALID_COMBINATION; 880 return ERR_INVALID_COMBINATION;
876 } 881 }
877 882
878 *result = Core::CurrentProcess()->GetRandomEntropy(info_sub_id); 883 *result = system.Kernel().CurrentProcess()->GetRandomEntropy(info_sub_id);
879 return RESULT_SUCCESS; 884 return RESULT_SUCCESS;
880 885
881 case GetInfoType::PrivilegedProcessId: 886 case GetInfoType::PrivilegedProcessId:
@@ -892,15 +897,14 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
892 return ERR_INVALID_COMBINATION; 897 return ERR_INVALID_COMBINATION;
893 } 898 }
894 899
895 const auto thread = 900 const auto thread = system.Kernel().CurrentProcess()->GetHandleTable().Get<Thread>(
896 Core::CurrentProcess()->GetHandleTable().Get<Thread>(static_cast<Handle>(handle)); 901 static_cast<Handle>(handle));
897 if (!thread) { 902 if (!thread) {
898 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", 903 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}",
899 static_cast<Handle>(handle)); 904 static_cast<Handle>(handle));
900 return ERR_INVALID_HANDLE; 905 return ERR_INVALID_HANDLE;
901 } 906 }
902 907
903 const auto& system = Core::System::GetInstance();
904 const auto& core_timing = system.CoreTiming(); 908 const auto& core_timing = system.CoreTiming();
905 const auto& scheduler = system.CurrentScheduler(); 909 const auto& scheduler = system.CurrentScheduler();
906 const auto* const current_thread = scheduler.GetCurrentThread(); 910 const auto* const current_thread = scheduler.GetCurrentThread();
@@ -927,13 +931,13 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
927} 931}
928 932
929/// Sets the thread activity 933/// Sets the thread activity
930static ResultCode SetThreadActivity(Handle handle, u32 activity) { 934static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 activity) {
931 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", handle, activity); 935 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", handle, activity);
932 if (activity > static_cast<u32>(ThreadActivity::Paused)) { 936 if (activity > static_cast<u32>(ThreadActivity::Paused)) {
933 return ERR_INVALID_ENUM_VALUE; 937 return ERR_INVALID_ENUM_VALUE;
934 } 938 }
935 939
936 const auto* current_process = Core::CurrentProcess(); 940 const auto* current_process = system.Kernel().CurrentProcess();
937 const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); 941 const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
938 if (!thread) { 942 if (!thread) {
939 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle); 943 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
@@ -950,7 +954,7 @@ static ResultCode SetThreadActivity(Handle handle, u32 activity) {
950 return ERR_INVALID_HANDLE; 954 return ERR_INVALID_HANDLE;
951 } 955 }
952 956
953 if (thread == GetCurrentThread()) { 957 if (thread == system.CurrentScheduler().GetCurrentThread()) {
954 LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); 958 LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
955 return ERR_BUSY; 959 return ERR_BUSY;
956 } 960 }
@@ -960,10 +964,10 @@ static ResultCode SetThreadActivity(Handle handle, u32 activity) {
960} 964}
961 965
962/// Gets the thread context 966/// Gets the thread context
963static ResultCode GetThreadContext(VAddr thread_context, Handle handle) { 967static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, Handle handle) {
964 LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle); 968 LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle);
965 969
966 const auto* current_process = Core::CurrentProcess(); 970 const auto* current_process = system.Kernel().CurrentProcess();
967 const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); 971 const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
968 if (!thread) { 972 if (!thread) {
969 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle); 973 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
@@ -980,7 +984,7 @@ static ResultCode GetThreadContext(VAddr thread_context, Handle handle) {
980 return ERR_INVALID_HANDLE; 984 return ERR_INVALID_HANDLE;
981 } 985 }
982 986
983 if (thread == GetCurrentThread()) { 987 if (thread == system.CurrentScheduler().GetCurrentThread()) {
984 LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); 988 LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
985 return ERR_BUSY; 989 return ERR_BUSY;
986 } 990 }
@@ -1001,10 +1005,10 @@ static ResultCode GetThreadContext(VAddr thread_context, Handle handle) {
1001} 1005}
1002 1006
1003/// Gets the priority for the specified thread 1007/// Gets the priority for the specified thread
1004static ResultCode GetThreadPriority(u32* priority, Handle handle) { 1008static ResultCode GetThreadPriority(Core::System& system, u32* priority, Handle handle) {
1005 LOG_TRACE(Kernel_SVC, "called"); 1009 LOG_TRACE(Kernel_SVC, "called");
1006 1010
1007 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1011 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1008 const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle); 1012 const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle);
1009 if (!thread) { 1013 if (!thread) {
1010 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle); 1014 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
@@ -1016,7 +1020,7 @@ static ResultCode GetThreadPriority(u32* priority, Handle handle) {
1016} 1020}
1017 1021
1018/// Sets the priority for the specified thread 1022/// Sets the priority for the specified thread
1019static ResultCode SetThreadPriority(Handle handle, u32 priority) { 1023static ResultCode SetThreadPriority(Core::System& system, Handle handle, u32 priority) {
1020 LOG_TRACE(Kernel_SVC, "called"); 1024 LOG_TRACE(Kernel_SVC, "called");
1021 1025
1022 if (priority > THREADPRIO_LOWEST) { 1026 if (priority > THREADPRIO_LOWEST) {
@@ -1027,7 +1031,7 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
1027 return ERR_INVALID_THREAD_PRIORITY; 1031 return ERR_INVALID_THREAD_PRIORITY;
1028 } 1032 }
1029 1033
1030 const auto* const current_process = Core::CurrentProcess(); 1034 const auto* const current_process = system.Kernel().CurrentProcess();
1031 1035
1032 SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); 1036 SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
1033 if (!thread) { 1037 if (!thread) {
@@ -1037,18 +1041,18 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
1037 1041
1038 thread->SetPriority(priority); 1042 thread->SetPriority(priority);
1039 1043
1040 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); 1044 system.CpuCore(thread->GetProcessorID()).PrepareReschedule();
1041 return RESULT_SUCCESS; 1045 return RESULT_SUCCESS;
1042} 1046}
1043 1047
1044/// Get which CPU core is executing the current thread 1048/// Get which CPU core is executing the current thread
1045static u32 GetCurrentProcessorNumber() { 1049static u32 GetCurrentProcessorNumber(Core::System& system) {
1046 LOG_TRACE(Kernel_SVC, "called"); 1050 LOG_TRACE(Kernel_SVC, "called");
1047 return GetCurrentThread()->GetProcessorID(); 1051 return system.CurrentScheduler().GetCurrentThread()->GetProcessorID();
1048} 1052}
1049 1053
1050static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size, 1054static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_handle, VAddr addr,
1051 u32 permissions) { 1055 u64 size, u32 permissions) {
1052 LOG_TRACE(Kernel_SVC, 1056 LOG_TRACE(Kernel_SVC,
1053 "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", 1057 "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
1054 shared_memory_handle, addr, size, permissions); 1058 shared_memory_handle, addr, size, permissions);
@@ -1082,7 +1086,7 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
1082 return ERR_INVALID_MEMORY_PERMISSIONS; 1086 return ERR_INVALID_MEMORY_PERMISSIONS;
1083 } 1087 }
1084 1088
1085 auto* const current_process = Core::CurrentProcess(); 1089 auto* const current_process = system.Kernel().CurrentProcess();
1086 auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle); 1090 auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle);
1087 if (!shared_memory) { 1091 if (!shared_memory) {
1088 LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}", 1092 LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}",
@@ -1100,7 +1104,8 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
1100 return shared_memory->Map(*current_process, addr, permissions_type, MemoryPermission::DontCare); 1104 return shared_memory->Map(*current_process, addr, permissions_type, MemoryPermission::DontCare);
1101} 1105}
1102 1106
1103static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) { 1107static ResultCode UnmapSharedMemory(Core::System& system, Handle shared_memory_handle, VAddr addr,
1108 u64 size) {
1104 LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}", 1109 LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}",
1105 shared_memory_handle, addr, size); 1110 shared_memory_handle, addr, size);
1106 1111
@@ -1125,7 +1130,7 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64
1125 return ERR_INVALID_ADDRESS_STATE; 1130 return ERR_INVALID_ADDRESS_STATE;
1126 } 1131 }
1127 1132
1128 auto* const current_process = Core::CurrentProcess(); 1133 auto* const current_process = system.Kernel().CurrentProcess();
1129 auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle); 1134 auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle);
1130 if (!shared_memory) { 1135 if (!shared_memory) {
1131 LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}", 1136 LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}",
@@ -1143,10 +1148,11 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64
1143 return shared_memory->Unmap(*current_process, addr, size); 1148 return shared_memory->Unmap(*current_process, addr, size);
1144} 1149}
1145 1150
1146static ResultCode QueryProcessMemory(VAddr memory_info_address, VAddr page_info_address, 1151static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address,
1147 Handle process_handle, VAddr address) { 1152 VAddr page_info_address, Handle process_handle,
1153 VAddr address) {
1148 LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); 1154 LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address);
1149 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1155 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1150 SharedPtr<Process> process = handle_table.Get<Process>(process_handle); 1156 SharedPtr<Process> process = handle_table.Get<Process>(process_handle);
1151 if (!process) { 1157 if (!process) {
1152 LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", 1158 LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
@@ -1172,20 +1178,20 @@ static ResultCode QueryProcessMemory(VAddr memory_info_address, VAddr page_info_
1172 return RESULT_SUCCESS; 1178 return RESULT_SUCCESS;
1173} 1179}
1174 1180
1175static ResultCode QueryMemory(VAddr memory_info_address, VAddr page_info_address, 1181static ResultCode QueryMemory(Core::System& system, VAddr memory_info_address,
1176 VAddr query_address) { 1182 VAddr page_info_address, VAddr query_address) {
1177 LOG_TRACE(Kernel_SVC, 1183 LOG_TRACE(Kernel_SVC,
1178 "called, memory_info_address=0x{:016X}, page_info_address=0x{:016X}, " 1184 "called, memory_info_address=0x{:016X}, page_info_address=0x{:016X}, "
1179 "query_address=0x{:016X}", 1185 "query_address=0x{:016X}",
1180 memory_info_address, page_info_address, query_address); 1186 memory_info_address, page_info_address, query_address);
1181 1187
1182 return QueryProcessMemory(memory_info_address, page_info_address, CurrentProcess, 1188 return QueryProcessMemory(system, memory_info_address, page_info_address, CurrentProcess,
1183 query_address); 1189 query_address);
1184} 1190}
1185 1191
1186/// Exits the current process 1192/// Exits the current process
1187static void ExitProcess() { 1193static void ExitProcess(Core::System& system) {
1188 auto* current_process = Core::CurrentProcess(); 1194 auto* current_process = system.Kernel().CurrentProcess();
1189 1195
1190 LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID()); 1196 LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID());
1191 ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running, 1197 ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running,
@@ -1194,20 +1200,20 @@ static void ExitProcess() {
1194 current_process->PrepareForTermination(); 1200 current_process->PrepareForTermination();
1195 1201
1196 // Kill the current thread 1202 // Kill the current thread
1197 GetCurrentThread()->Stop(); 1203 system.CurrentScheduler().GetCurrentThread()->Stop();
1198 1204
1199 Core::System::GetInstance().PrepareReschedule(); 1205 system.PrepareReschedule();
1200} 1206}
1201 1207
1202/// Creates a new thread 1208/// Creates a new thread
1203static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, 1209static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg,
1204 u32 priority, s32 processor_id) { 1210 VAddr stack_top, u32 priority, s32 processor_id) {
1205 LOG_TRACE(Kernel_SVC, 1211 LOG_TRACE(Kernel_SVC,
1206 "called entrypoint=0x{:08X}, arg=0x{:08X}, stacktop=0x{:08X}, " 1212 "called entrypoint=0x{:08X}, arg=0x{:08X}, stacktop=0x{:08X}, "
1207 "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}", 1213 "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}",
1208 entry_point, arg, stack_top, priority, processor_id, *out_handle); 1214 entry_point, arg, stack_top, priority, processor_id, *out_handle);
1209 1215
1210 auto* const current_process = Core::CurrentProcess(); 1216 auto* const current_process = system.Kernel().CurrentProcess();
1211 1217
1212 if (processor_id == THREADPROCESSORID_IDEAL) { 1218 if (processor_id == THREADPROCESSORID_IDEAL) {
1213 // Set the target CPU to the one specified by the process. 1219 // Set the target CPU to the one specified by the process.
@@ -1239,7 +1245,7 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
1239 } 1245 }
1240 1246
1241 const std::string name = fmt::format("thread-{:X}", entry_point); 1247 const std::string name = fmt::format("thread-{:X}", entry_point);
1242 auto& kernel = Core::System::GetInstance().Kernel(); 1248 auto& kernel = system.Kernel();
1243 CASCADE_RESULT(SharedPtr<Thread> thread, 1249 CASCADE_RESULT(SharedPtr<Thread> thread,
1244 Thread::Create(kernel, name, entry_point, priority, arg, processor_id, stack_top, 1250 Thread::Create(kernel, name, entry_point, priority, arg, processor_id, stack_top,
1245 *current_process)); 1251 *current_process));
@@ -1253,16 +1259,16 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
1253 thread->SetGuestHandle(*new_guest_handle); 1259 thread->SetGuestHandle(*new_guest_handle);
1254 *out_handle = *new_guest_handle; 1260 *out_handle = *new_guest_handle;
1255 1261
1256 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); 1262 system.CpuCore(thread->GetProcessorID()).PrepareReschedule();
1257 1263
1258 return RESULT_SUCCESS; 1264 return RESULT_SUCCESS;
1259} 1265}
1260 1266
1261/// Starts the thread for the provided handle 1267/// Starts the thread for the provided handle
1262static ResultCode StartThread(Handle thread_handle) { 1268static ResultCode StartThread(Core::System& system, Handle thread_handle) {
1263 LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); 1269 LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
1264 1270
1265 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1271 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1266 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); 1272 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
1267 if (!thread) { 1273 if (!thread) {
1268 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", 1274 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
@@ -1275,16 +1281,14 @@ static ResultCode StartThread(Handle thread_handle) {
1275 thread->ResumeFromWait(); 1281 thread->ResumeFromWait();
1276 1282
1277 if (thread->GetStatus() == ThreadStatus::Ready) { 1283 if (thread->GetStatus() == ThreadStatus::Ready) {
1278 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); 1284 system.CpuCore(thread->GetProcessorID()).PrepareReschedule();
1279 } 1285 }
1280 1286
1281 return RESULT_SUCCESS; 1287 return RESULT_SUCCESS;
1282} 1288}
1283 1289
1284/// Called when a thread exits 1290/// Called when a thread exits
1285static void ExitThread() { 1291static void ExitThread(Core::System& system) {
1286 auto& system = Core::System::GetInstance();
1287
1288 LOG_TRACE(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); 1292 LOG_TRACE(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC());
1289 1293
1290 auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); 1294 auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
@@ -1294,7 +1298,7 @@ static void ExitThread() {
1294} 1298}
1295 1299
1296/// Sleep the current thread 1300/// Sleep the current thread
1297static void SleepThread(s64 nanoseconds) { 1301static void SleepThread(Core::System& system, s64 nanoseconds) {
1298 LOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds); 1302 LOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds);
1299 1303
1300 enum class SleepType : s64 { 1304 enum class SleepType : s64 {
@@ -1303,7 +1307,6 @@ static void SleepThread(s64 nanoseconds) {
1303 YieldAndWaitForLoadBalancing = -2, 1307 YieldAndWaitForLoadBalancing = -2,
1304 }; 1308 };
1305 1309
1306 auto& system = Core::System::GetInstance();
1307 auto& scheduler = system.CurrentScheduler(); 1310 auto& scheduler = system.CurrentScheduler();
1308 auto* const current_thread = scheduler.GetCurrentThread(); 1311 auto* const current_thread = scheduler.GetCurrentThread();
1309 1312
@@ -1332,8 +1335,9 @@ static void SleepThread(s64 nanoseconds) {
1332} 1335}
1333 1336
1334/// Wait process wide key atomic 1337/// Wait process wide key atomic
1335static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr, 1338static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_addr,
1336 Handle thread_handle, s64 nano_seconds) { 1339 VAddr condition_variable_addr, Handle thread_handle,
1340 s64 nano_seconds) {
1337 LOG_TRACE( 1341 LOG_TRACE(
1338 Kernel_SVC, 1342 Kernel_SVC,
1339 "called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle=0x{:08X}, timeout={}", 1343 "called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle=0x{:08X}, timeout={}",
@@ -1353,7 +1357,7 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
1353 return ERR_INVALID_ADDRESS; 1357 return ERR_INVALID_ADDRESS;
1354 } 1358 }
1355 1359
1356 auto* const current_process = Core::System::GetInstance().Kernel().CurrentProcess(); 1360 auto* const current_process = system.Kernel().CurrentProcess();
1357 const auto& handle_table = current_process->GetHandleTable(); 1361 const auto& handle_table = current_process->GetHandleTable();
1358 SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); 1362 SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
1359 ASSERT(thread); 1363 ASSERT(thread);
@@ -1363,7 +1367,7 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
1363 return release_result; 1367 return release_result;
1364 } 1368 }
1365 1369
1366 SharedPtr<Thread> current_thread = GetCurrentThread(); 1370 SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
1367 current_thread->SetCondVarWaitAddress(condition_variable_addr); 1371 current_thread->SetCondVarWaitAddress(condition_variable_addr);
1368 current_thread->SetMutexWaitAddress(mutex_addr); 1372 current_thread->SetMutexWaitAddress(mutex_addr);
1369 current_thread->SetWaitHandle(thread_handle); 1373 current_thread->SetWaitHandle(thread_handle);
@@ -1374,19 +1378,20 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
1374 1378
1375 // Note: Deliberately don't attempt to inherit the lock owner's priority. 1379 // Note: Deliberately don't attempt to inherit the lock owner's priority.
1376 1380
1377 Core::System::GetInstance().CpuCore(current_thread->GetProcessorID()).PrepareReschedule(); 1381 system.CpuCore(current_thread->GetProcessorID()).PrepareReschedule();
1378 return RESULT_SUCCESS; 1382 return RESULT_SUCCESS;
1379} 1383}
1380 1384
1381/// Signal process wide key 1385/// Signal process wide key
1382static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target) { 1386static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_variable_addr,
1387 s32 target) {
1383 LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}", 1388 LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}",
1384 condition_variable_addr, target); 1389 condition_variable_addr, target);
1385 1390
1386 const auto RetrieveWaitingThreads = [](std::size_t core_index, 1391 const auto RetrieveWaitingThreads = [&system](std::size_t core_index,
1387 std::vector<SharedPtr<Thread>>& waiting_threads, 1392 std::vector<SharedPtr<Thread>>& waiting_threads,
1388 VAddr condvar_addr) { 1393 VAddr condvar_addr) {
1389 const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); 1394 const auto& scheduler = system.Scheduler(core_index);
1390 const auto& thread_list = scheduler.GetThreadList(); 1395 const auto& thread_list = scheduler.GetThreadList();
1391 1396
1392 for (const auto& thread : thread_list) { 1397 for (const auto& thread : thread_list) {
@@ -1425,9 +1430,8 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
1425 // liberate Cond Var Thread. 1430 // liberate Cond Var Thread.
1426 thread->SetCondVarWaitAddress(0); 1431 thread->SetCondVarWaitAddress(0);
1427 1432
1428 std::size_t current_core = Core::System::GetInstance().CurrentCoreIndex(); 1433 const std::size_t current_core = system.CurrentCoreIndex();
1429 1434 auto& monitor = system.Monitor();
1430 auto& monitor = Core::System::GetInstance().Monitor();
1431 1435
1432 // Atomically read the value of the mutex. 1436 // Atomically read the value of the mutex.
1433 u32 mutex_val = 0; 1437 u32 mutex_val = 0;
@@ -1456,7 +1460,7 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
1456 thread->SetLockOwner(nullptr); 1460 thread->SetLockOwner(nullptr);
1457 thread->SetMutexWaitAddress(0); 1461 thread->SetMutexWaitAddress(0);
1458 thread->SetWaitHandle(0); 1462 thread->SetWaitHandle(0);
1459 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); 1463 system.CpuCore(thread->GetProcessorID()).PrepareReschedule();
1460 } else { 1464 } else {
1461 // Atomically signal that the mutex now has a waiting thread. 1465 // Atomically signal that the mutex now has a waiting thread.
1462 do { 1466 do {
@@ -1472,7 +1476,7 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
1472 1476
1473 // The mutex is already owned by some other thread, make this thread wait on it. 1477 // The mutex is already owned by some other thread, make this thread wait on it.
1474 const Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask); 1478 const Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask);
1475 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1479 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1476 auto owner = handle_table.Get<Thread>(owner_handle); 1480 auto owner = handle_table.Get<Thread>(owner_handle);
1477 ASSERT(owner); 1481 ASSERT(owner);
1478 ASSERT(thread->GetStatus() == ThreadStatus::WaitCondVar); 1482 ASSERT(thread->GetStatus() == ThreadStatus::WaitCondVar);
@@ -1487,14 +1491,17 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
1487} 1491}
1488 1492
1489// Wait for an address (via Address Arbiter) 1493// Wait for an address (via Address Arbiter)
1490static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout) { 1494static ResultCode WaitForAddress(Core::System& system, VAddr address, u32 type, s32 value,
1495 s64 timeout) {
1491 LOG_WARNING(Kernel_SVC, "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, timeout={}", 1496 LOG_WARNING(Kernel_SVC, "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, timeout={}",
1492 address, type, value, timeout); 1497 address, type, value, timeout);
1498
1493 // If the passed address is a kernel virtual address, return invalid memory state. 1499 // If the passed address is a kernel virtual address, return invalid memory state.
1494 if (Memory::IsKernelVirtualAddress(address)) { 1500 if (Memory::IsKernelVirtualAddress(address)) {
1495 LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address, address={:016X}", address); 1501 LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address, address={:016X}", address);
1496 return ERR_INVALID_ADDRESS_STATE; 1502 return ERR_INVALID_ADDRESS_STATE;
1497 } 1503 }
1504
1498 // If the address is not properly aligned to 4 bytes, return invalid address. 1505 // If the address is not properly aligned to 4 bytes, return invalid address.
1499 if (!Common::IsWordAligned(address)) { 1506 if (!Common::IsWordAligned(address)) {
1500 LOG_ERROR(Kernel_SVC, "Address is not word aligned, address={:016X}", address); 1507 LOG_ERROR(Kernel_SVC, "Address is not word aligned, address={:016X}", address);
@@ -1502,20 +1509,22 @@ static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout
1502 } 1509 }
1503 1510
1504 const auto arbitration_type = static_cast<AddressArbiter::ArbitrationType>(type); 1511 const auto arbitration_type = static_cast<AddressArbiter::ArbitrationType>(type);
1505 auto& address_arbiter = 1512 auto& address_arbiter = system.Kernel().CurrentProcess()->GetAddressArbiter();
1506 Core::System::GetInstance().Kernel().CurrentProcess()->GetAddressArbiter();
1507 return address_arbiter.WaitForAddress(address, arbitration_type, value, timeout); 1513 return address_arbiter.WaitForAddress(address, arbitration_type, value, timeout);
1508} 1514}
1509 1515
1510// Signals to an address (via Address Arbiter) 1516// Signals to an address (via Address Arbiter)
1511static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to_wake) { 1517static ResultCode SignalToAddress(Core::System& system, VAddr address, u32 type, s32 value,
1518 s32 num_to_wake) {
1512 LOG_WARNING(Kernel_SVC, "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, num_to_wake=0x{:X}", 1519 LOG_WARNING(Kernel_SVC, "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, num_to_wake=0x{:X}",
1513 address, type, value, num_to_wake); 1520 address, type, value, num_to_wake);
1521
1514 // If the passed address is a kernel virtual address, return invalid memory state. 1522 // If the passed address is a kernel virtual address, return invalid memory state.
1515 if (Memory::IsKernelVirtualAddress(address)) { 1523 if (Memory::IsKernelVirtualAddress(address)) {
1516 LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address, address={:016X}", address); 1524 LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address, address={:016X}", address);
1517 return ERR_INVALID_ADDRESS_STATE; 1525 return ERR_INVALID_ADDRESS_STATE;
1518 } 1526 }
1527
1519 // If the address is not properly aligned to 4 bytes, return invalid address. 1528 // If the address is not properly aligned to 4 bytes, return invalid address.
1520 if (!Common::IsWordAligned(address)) { 1529 if (!Common::IsWordAligned(address)) {
1521 LOG_ERROR(Kernel_SVC, "Address is not word aligned, address={:016X}", address); 1530 LOG_ERROR(Kernel_SVC, "Address is not word aligned, address={:016X}", address);
@@ -1523,16 +1532,15 @@ static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to
1523 } 1532 }
1524 1533
1525 const auto signal_type = static_cast<AddressArbiter::SignalType>(type); 1534 const auto signal_type = static_cast<AddressArbiter::SignalType>(type);
1526 auto& address_arbiter = 1535 auto& address_arbiter = system.Kernel().CurrentProcess()->GetAddressArbiter();
1527 Core::System::GetInstance().Kernel().CurrentProcess()->GetAddressArbiter();
1528 return address_arbiter.SignalToAddress(address, signal_type, value, num_to_wake); 1536 return address_arbiter.SignalToAddress(address, signal_type, value, num_to_wake);
1529} 1537}
1530 1538
1531/// This returns the total CPU ticks elapsed since the CPU was powered-on 1539/// This returns the total CPU ticks elapsed since the CPU was powered-on
1532static u64 GetSystemTick() { 1540static u64 GetSystemTick(Core::System& system) {
1533 LOG_TRACE(Kernel_SVC, "called"); 1541 LOG_TRACE(Kernel_SVC, "called");
1534 1542
1535 auto& core_timing = Core::System::GetInstance().CoreTiming(); 1543 auto& core_timing = system.CoreTiming();
1536 const u64 result{core_timing.GetTicks()}; 1544 const u64 result{core_timing.GetTicks()};
1537 1545
1538 // Advance time to defeat dumb games that busy-wait for the frame to end. 1546 // Advance time to defeat dumb games that busy-wait for the frame to end.
@@ -1542,18 +1550,18 @@ static u64 GetSystemTick() {
1542} 1550}
1543 1551
1544/// Close a handle 1552/// Close a handle
1545static ResultCode CloseHandle(Handle handle) { 1553static ResultCode CloseHandle(Core::System& system, Handle handle) {
1546 LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); 1554 LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle);
1547 1555
1548 auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1556 auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1549 return handle_table.Close(handle); 1557 return handle_table.Close(handle);
1550} 1558}
1551 1559
1552/// Clears the signaled state of an event or process. 1560/// Clears the signaled state of an event or process.
1553static ResultCode ResetSignal(Handle handle) { 1561static ResultCode ResetSignal(Core::System& system, Handle handle) {
1554 LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); 1562 LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle);
1555 1563
1556 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1564 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1557 1565
1558 auto event = handle_table.Get<ReadableEvent>(handle); 1566 auto event = handle_table.Get<ReadableEvent>(handle);
1559 if (event) { 1567 if (event) {
@@ -1570,7 +1578,8 @@ static ResultCode ResetSignal(Handle handle) {
1570} 1578}
1571 1579
1572/// Creates a TransferMemory object 1580/// Creates a TransferMemory object
1573static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32 permissions) { 1581static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAddr addr, u64 size,
1582 u32 permissions) {
1574 LOG_DEBUG(Kernel_SVC, "called addr=0x{:X}, size=0x{:X}, perms=0x{:08X}", addr, size, 1583 LOG_DEBUG(Kernel_SVC, "called addr=0x{:X}, size=0x{:X}, perms=0x{:08X}", addr, size,
1575 permissions); 1584 permissions);
1576 1585
@@ -1598,7 +1607,7 @@ static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32
1598 return ERR_INVALID_MEMORY_PERMISSIONS; 1607 return ERR_INVALID_MEMORY_PERMISSIONS;
1599 } 1608 }
1600 1609
1601 auto& kernel = Core::System::GetInstance().Kernel(); 1610 auto& kernel = system.Kernel();
1602 auto transfer_mem_handle = TransferMemory::Create(kernel, addr, size, perms); 1611 auto transfer_mem_handle = TransferMemory::Create(kernel, addr, size, perms);
1603 1612
1604 auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); 1613 auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
@@ -1611,7 +1620,8 @@ static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32
1611 return RESULT_SUCCESS; 1620 return RESULT_SUCCESS;
1612} 1621}
1613 1622
1614static ResultCode MapTransferMemory(Handle handle, VAddr address, u64 size, u32 permission_raw) { 1623static ResultCode MapTransferMemory(Core::System& system, Handle handle, VAddr address, u64 size,
1624 u32 permission_raw) {
1615 LOG_DEBUG(Kernel_SVC, 1625 LOG_DEBUG(Kernel_SVC,
1616 "called. handle=0x{:08X}, address=0x{:016X}, size=0x{:016X}, permissions=0x{:08X}", 1626 "called. handle=0x{:08X}, address=0x{:016X}, size=0x{:016X}, permissions=0x{:08X}",
1617 handle, address, size, permission_raw); 1627 handle, address, size, permission_raw);
@@ -1645,7 +1655,7 @@ static ResultCode MapTransferMemory(Handle handle, VAddr address, u64 size, u32
1645 return ERR_INVALID_STATE; 1655 return ERR_INVALID_STATE;
1646 } 1656 }
1647 1657
1648 const auto& kernel = Core::System::GetInstance().Kernel(); 1658 const auto& kernel = system.Kernel();
1649 const auto* const current_process = kernel.CurrentProcess(); 1659 const auto* const current_process = kernel.CurrentProcess();
1650 const auto& handle_table = current_process->GetHandleTable(); 1660 const auto& handle_table = current_process->GetHandleTable();
1651 1661
@@ -1667,7 +1677,8 @@ static ResultCode MapTransferMemory(Handle handle, VAddr address, u64 size, u32
1667 return transfer_memory->MapMemory(address, size, permissions); 1677 return transfer_memory->MapMemory(address, size, permissions);
1668} 1678}
1669 1679
1670static ResultCode UnmapTransferMemory(Handle handle, VAddr address, u64 size) { 1680static ResultCode UnmapTransferMemory(Core::System& system, Handle handle, VAddr address,
1681 u64 size) {
1671 LOG_DEBUG(Kernel_SVC, "called. handle=0x{:08X}, address=0x{:016X}, size=0x{:016X}", handle, 1682 LOG_DEBUG(Kernel_SVC, "called. handle=0x{:08X}, address=0x{:016X}, size=0x{:016X}", handle,
1672 address, size); 1683 address, size);
1673 1684
@@ -1692,7 +1703,7 @@ static ResultCode UnmapTransferMemory(Handle handle, VAddr address, u64 size) {
1692 return ERR_INVALID_ADDRESS_STATE; 1703 return ERR_INVALID_ADDRESS_STATE;
1693 } 1704 }
1694 1705
1695 const auto& kernel = Core::System::GetInstance().Kernel(); 1706 const auto& kernel = system.Kernel();
1696 const auto* const current_process = kernel.CurrentProcess(); 1707 const auto* const current_process = kernel.CurrentProcess();
1697 const auto& handle_table = current_process->GetHandleTable(); 1708 const auto& handle_table = current_process->GetHandleTable();
1698 1709
@@ -1714,10 +1725,11 @@ static ResultCode UnmapTransferMemory(Handle handle, VAddr address, u64 size) {
1714 return transfer_memory->UnmapMemory(address, size); 1725 return transfer_memory->UnmapMemory(address, size);
1715} 1726}
1716 1727
1717static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) { 1728static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, u32* core,
1729 u64* mask) {
1718 LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); 1730 LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle);
1719 1731
1720 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1732 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1721 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); 1733 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
1722 if (!thread) { 1734 if (!thread) {
1723 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", 1735 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
@@ -1731,11 +1743,12 @@ static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask)
1731 return RESULT_SUCCESS; 1743 return RESULT_SUCCESS;
1732} 1744}
1733 1745
1734static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { 1746static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, u32 core,
1747 u64 mask) {
1735 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:016X}, core=0x{:X}", thread_handle, 1748 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:016X}, core=0x{:X}", thread_handle,
1736 mask, core); 1749 mask, core);
1737 1750
1738 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1751 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1739 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); 1752 const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
1740 if (!thread) { 1753 if (!thread) {
1741 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", 1754 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
@@ -1780,8 +1793,8 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
1780 return RESULT_SUCCESS; 1793 return RESULT_SUCCESS;
1781} 1794}
1782 1795
1783static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permissions, 1796static ResultCode CreateSharedMemory(Core::System& system, Handle* handle, u64 size,
1784 u32 remote_permissions) { 1797 u32 local_permissions, u32 remote_permissions) {
1785 LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size, 1798 LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size,
1786 local_permissions, remote_permissions); 1799 local_permissions, remote_permissions);
1787 if (size == 0) { 1800 if (size == 0) {
@@ -1817,7 +1830,7 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss
1817 return ERR_INVALID_MEMORY_PERMISSIONS; 1830 return ERR_INVALID_MEMORY_PERMISSIONS;
1818 } 1831 }
1819 1832
1820 auto& kernel = Core::System::GetInstance().Kernel(); 1833 auto& kernel = system.Kernel();
1821 auto process = kernel.CurrentProcess(); 1834 auto process = kernel.CurrentProcess();
1822 auto& handle_table = process->GetHandleTable(); 1835 auto& handle_table = process->GetHandleTable();
1823 auto shared_mem_handle = SharedMemory::Create(kernel, process, size, local_perms, remote_perms); 1836 auto shared_mem_handle = SharedMemory::Create(kernel, process, size, local_perms, remote_perms);
@@ -1826,10 +1839,10 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss
1826 return RESULT_SUCCESS; 1839 return RESULT_SUCCESS;
1827} 1840}
1828 1841
1829static ResultCode CreateEvent(Handle* write_handle, Handle* read_handle) { 1842static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle* read_handle) {
1830 LOG_DEBUG(Kernel_SVC, "called"); 1843 LOG_DEBUG(Kernel_SVC, "called");
1831 1844
1832 auto& kernel = Core::System::GetInstance().Kernel(); 1845 auto& kernel = system.Kernel();
1833 const auto [readable_event, writable_event] = 1846 const auto [readable_event, writable_event] =
1834 WritableEvent::CreateEventPair(kernel, ResetType::Sticky, "CreateEvent"); 1847 WritableEvent::CreateEventPair(kernel, ResetType::Sticky, "CreateEvent");
1835 1848
@@ -1854,10 +1867,10 @@ static ResultCode CreateEvent(Handle* write_handle, Handle* read_handle) {
1854 return RESULT_SUCCESS; 1867 return RESULT_SUCCESS;
1855} 1868}
1856 1869
1857static ResultCode ClearEvent(Handle handle) { 1870static ResultCode ClearEvent(Core::System& system, Handle handle) {
1858 LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); 1871 LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle);
1859 1872
1860 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1873 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1861 1874
1862 auto writable_event = handle_table.Get<WritableEvent>(handle); 1875 auto writable_event = handle_table.Get<WritableEvent>(handle);
1863 if (writable_event) { 1876 if (writable_event) {
@@ -1875,10 +1888,10 @@ static ResultCode ClearEvent(Handle handle) {
1875 return ERR_INVALID_HANDLE; 1888 return ERR_INVALID_HANDLE;
1876} 1889}
1877 1890
1878static ResultCode SignalEvent(Handle handle) { 1891static ResultCode SignalEvent(Core::System& system, Handle handle) {
1879 LOG_DEBUG(Kernel_SVC, "called. Handle=0x{:08X}", handle); 1892 LOG_DEBUG(Kernel_SVC, "called. Handle=0x{:08X}", handle);
1880 1893
1881 HandleTable& handle_table = Core::CurrentProcess()->GetHandleTable(); 1894 HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1882 auto writable_event = handle_table.Get<WritableEvent>(handle); 1895 auto writable_event = handle_table.Get<WritableEvent>(handle);
1883 1896
1884 if (!writable_event) { 1897 if (!writable_event) {
@@ -1890,7 +1903,7 @@ static ResultCode SignalEvent(Handle handle) {
1890 return RESULT_SUCCESS; 1903 return RESULT_SUCCESS;
1891} 1904}
1892 1905
1893static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) { 1906static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) {
1894 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type); 1907 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type);
1895 1908
1896 // This function currently only allows retrieving a process' status. 1909 // This function currently only allows retrieving a process' status.
@@ -1898,7 +1911,7 @@ static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) {
1898 Status, 1911 Status,
1899 }; 1912 };
1900 1913
1901 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1914 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1902 const auto process = handle_table.Get<Process>(process_handle); 1915 const auto process = handle_table.Get<Process>(process_handle);
1903 if (!process) { 1916 if (!process) {
1904 LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", 1917 LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
@@ -1916,10 +1929,10 @@ static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) {
1916 return RESULT_SUCCESS; 1929 return RESULT_SUCCESS;
1917} 1930}
1918 1931
1919static ResultCode CreateResourceLimit(Handle* out_handle) { 1932static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) {
1920 LOG_DEBUG(Kernel_SVC, "called"); 1933 LOG_DEBUG(Kernel_SVC, "called");
1921 1934
1922 auto& kernel = Core::System::GetInstance().Kernel(); 1935 auto& kernel = system.Kernel();
1923 auto resource_limit = ResourceLimit::Create(kernel); 1936 auto resource_limit = ResourceLimit::Create(kernel);
1924 1937
1925 auto* const current_process = kernel.CurrentProcess(); 1938 auto* const current_process = kernel.CurrentProcess();
@@ -1934,11 +1947,11 @@ static ResultCode CreateResourceLimit(Handle* out_handle) {
1934 return RESULT_SUCCESS; 1947 return RESULT_SUCCESS;
1935} 1948}
1936 1949
1937static ResultCode GetResourceLimitLimitValue(u64* out_value, Handle resource_limit, 1950static ResultCode GetResourceLimitLimitValue(Core::System& system, u64* out_value,
1938 u32 resource_type) { 1951 Handle resource_limit, u32 resource_type) {
1939 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type); 1952 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type);
1940 1953
1941 const auto limit_value = RetrieveResourceLimitValue(resource_limit, resource_type, 1954 const auto limit_value = RetrieveResourceLimitValue(system, resource_limit, resource_type,
1942 ResourceLimitValueType::LimitValue); 1955 ResourceLimitValueType::LimitValue);
1943 if (limit_value.Failed()) { 1956 if (limit_value.Failed()) {
1944 return limit_value.Code(); 1957 return limit_value.Code();
@@ -1948,11 +1961,11 @@ static ResultCode GetResourceLimitLimitValue(u64* out_value, Handle resource_lim
1948 return RESULT_SUCCESS; 1961 return RESULT_SUCCESS;
1949} 1962}
1950 1963
1951static ResultCode GetResourceLimitCurrentValue(u64* out_value, Handle resource_limit, 1964static ResultCode GetResourceLimitCurrentValue(Core::System& system, u64* out_value,
1952 u32 resource_type) { 1965 Handle resource_limit, u32 resource_type) {
1953 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type); 1966 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type);
1954 1967
1955 const auto current_value = RetrieveResourceLimitValue(resource_limit, resource_type, 1968 const auto current_value = RetrieveResourceLimitValue(system, resource_limit, resource_type,
1956 ResourceLimitValueType::CurrentValue); 1969 ResourceLimitValueType::CurrentValue);
1957 if (current_value.Failed()) { 1970 if (current_value.Failed()) {
1958 return current_value.Code(); 1971 return current_value.Code();
@@ -1962,7 +1975,8 @@ static ResultCode GetResourceLimitCurrentValue(u64* out_value, Handle resource_l
1962 return RESULT_SUCCESS; 1975 return RESULT_SUCCESS;
1963} 1976}
1964 1977
1965static ResultCode SetResourceLimitLimitValue(Handle resource_limit, u32 resource_type, u64 value) { 1978static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resource_limit,
1979 u32 resource_type, u64 value) {
1966 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit, 1980 LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit,
1967 resource_type, value); 1981 resource_type, value);
1968 1982
@@ -1972,8 +1986,7 @@ static ResultCode SetResourceLimitLimitValue(Handle resource_limit, u32 resource
1972 return ERR_INVALID_ENUM_VALUE; 1986 return ERR_INVALID_ENUM_VALUE;
1973 } 1987 }
1974 1988
1975 auto& kernel = Core::System::GetInstance().Kernel(); 1989 auto* const current_process = system.Kernel().CurrentProcess();
1976 auto* const current_process = kernel.CurrentProcess();
1977 ASSERT(current_process != nullptr); 1990 ASSERT(current_process != nullptr);
1978 1991
1979 auto resource_limit_object = 1992 auto resource_limit_object =
@@ -1997,8 +2010,8 @@ static ResultCode SetResourceLimitLimitValue(Handle resource_limit, u32 resource
1997 return RESULT_SUCCESS; 2010 return RESULT_SUCCESS;
1998} 2011}
1999 2012
2000static ResultCode GetProcessList(u32* out_num_processes, VAddr out_process_ids, 2013static ResultCode GetProcessList(Core::System& system, u32* out_num_processes,
2001 u32 out_process_ids_size) { 2014 VAddr out_process_ids, u32 out_process_ids_size) {
2002 LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}", 2015 LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}",
2003 out_process_ids, out_process_ids_size); 2016 out_process_ids, out_process_ids_size);
2004 2017
@@ -2010,7 +2023,7 @@ static ResultCode GetProcessList(u32* out_num_processes, VAddr out_process_ids,
2010 return ERR_OUT_OF_RANGE; 2023 return ERR_OUT_OF_RANGE;
2011 } 2024 }
2012 2025
2013 const auto& kernel = Core::System::GetInstance().Kernel(); 2026 const auto& kernel = system.Kernel();
2014 const auto& vm_manager = kernel.CurrentProcess()->VMManager(); 2027 const auto& vm_manager = kernel.CurrentProcess()->VMManager();
2015 const auto total_copy_size = out_process_ids_size * sizeof(u64); 2028 const auto total_copy_size = out_process_ids_size * sizeof(u64);
2016 2029
@@ -2034,8 +2047,8 @@ static ResultCode GetProcessList(u32* out_num_processes, VAddr out_process_ids,
2034 return RESULT_SUCCESS; 2047 return RESULT_SUCCESS;
2035} 2048}
2036 2049
2037ResultCode GetThreadList(u32* out_num_threads, VAddr out_thread_ids, u32 out_thread_ids_size, 2050ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_thread_ids,
2038 Handle debug_handle) { 2051 u32 out_thread_ids_size, Handle debug_handle) {
2039 // TODO: Handle this case when debug events are supported. 2052 // TODO: Handle this case when debug events are supported.
2040 UNIMPLEMENTED_IF(debug_handle != InvalidHandle); 2053 UNIMPLEMENTED_IF(debug_handle != InvalidHandle);
2041 2054
@@ -2049,7 +2062,7 @@ ResultCode GetThreadList(u32* out_num_threads, VAddr out_thread_ids, u32 out_thr
2049 return ERR_OUT_OF_RANGE; 2062 return ERR_OUT_OF_RANGE;
2050 } 2063 }
2051 2064
2052 const auto* const current_process = Core::System::GetInstance().Kernel().CurrentProcess(); 2065 const auto* const current_process = system.Kernel().CurrentProcess();
2053 const auto& vm_manager = current_process->VMManager(); 2066 const auto& vm_manager = current_process->VMManager();
2054 const auto total_copy_size = out_thread_ids_size * sizeof(u64); 2067 const auto total_copy_size = out_thread_ids_size * sizeof(u64);
2055 2068
@@ -2076,7 +2089,7 @@ ResultCode GetThreadList(u32* out_num_threads, VAddr out_thread_ids, u32 out_thr
2076 2089
2077namespace { 2090namespace {
2078struct FunctionDef { 2091struct FunctionDef {
2079 using Func = void(); 2092 using Func = void(Core::System&);
2080 2093
2081 u32 id; 2094 u32 id;
2082 Func* func; 2095 Func* func;
@@ -2225,7 +2238,7 @@ static const FunctionDef* GetSVCInfo(u32 func_num) {
2225 2238
2226MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70)); 2239MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
2227 2240
2228void CallSVC(u32 immediate) { 2241void CallSVC(Core::System& system, u32 immediate) {
2229 MICROPROFILE_SCOPE(Kernel_SVC); 2242 MICROPROFILE_SCOPE(Kernel_SVC);
2230 2243
2231 // Lock the global kernel mutex when we enter the kernel HLE. 2244 // Lock the global kernel mutex when we enter the kernel HLE.
@@ -2234,7 +2247,7 @@ void CallSVC(u32 immediate) {
2234 const FunctionDef* info = GetSVCInfo(immediate); 2247 const FunctionDef* info = GetSVCInfo(immediate);
2235 if (info) { 2248 if (info) {
2236 if (info->func) { 2249 if (info->func) {
2237 info->func(); 2250 info->func(system);
2238 } else { 2251 } else {
2239 LOG_CRITICAL(Kernel_SVC, "Unimplemented SVC function {}(..)", info->name); 2252 LOG_CRITICAL(Kernel_SVC, "Unimplemented SVC function {}(..)", info->name);
2240 } 2253 }