| 
									
										
										
										
											2014-04-10 19:58:28 -04:00
										 |  |  | // Copyright 2014 Citra Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.  
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-11 18:44:21 -04:00
										 |  |  | #include <map>
 | 
					
						
							| 
									
										
										
										
											2014-05-18 17:52:02 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-17 14:28:36 -04:00
										 |  |  | #include "common/string_util.h"
 | 
					
						
							| 
									
										
										
										
											2014-05-18 17:52:02 -04:00
										 |  |  | #include "common/symbols.h"
 | 
					
						
							| 
									
										
										
										
											2014-04-11 18:44:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 23:05:31 -04:00
										 |  |  | #include "core/mem_map.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-06 23:15:40 -04:00
										 |  |  | #include "core/hle/kernel/address_arbiter.h"
 | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  | #include "core/hle/kernel/event.h"
 | 
					
						
							| 
									
										
										
										
											2014-05-20 22:57:54 -04:00
										 |  |  | #include "core/hle/kernel/mutex.h"
 | 
					
						
							| 
									
										
										
										
											2014-07-05 00:59:58 -04:00
										 |  |  | #include "core/hle/kernel/shared_memory.h"
 | 
					
						
							| 
									
										
										
										
											2014-05-17 13:47:44 -04:00
										 |  |  | #include "core/hle/kernel/thread.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-10 19:58:28 -04:00
										 |  |  | #include "core/hle/function_wrappers.h"
 | 
					
						
							| 
									
										
										
										
											2014-04-12 21:55:36 -04:00
										 |  |  | #include "core/hle/service/service.h"
 | 
					
						
							| 
									
										
										
										
											2014-04-10 19:58:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2014-05-20 18:28:38 -04:00
										 |  |  | // Namespace SVC
 | 
					
						
							| 
									
										
										
										
											2014-04-10 19:58:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-20 18:28:38 -04:00
										 |  |  | namespace SVC { | 
					
						
							| 
									
										
										
										
											2014-04-10 23:26:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-24 23:56:06 -04:00
										 |  |  | enum ControlMemoryOperation { | 
					
						
							|  |  |  |     MEMORY_OPERATION_HEAP       = 0x00000003, | 
					
						
							|  |  |  |     MEMORY_OPERATION_GSP_HEAP   = 0x00010003, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 23:05:31 -04:00
										 |  |  | /// Map application or GSP heap memory
 | 
					
						
							| 
									
										
										
										
											2014-06-06 23:31:29 -04:00
										 |  |  | Result ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissions) { | 
					
						
							| 
									
										
										
										
											2014-05-29 23:26:58 -04:00
										 |  |  |     DEBUG_LOG(SVC,"called operation=0x%08X, addr0=0x%08X, addr1=0x%08X, size=%08X, permissions=0x%08X",  | 
					
						
							| 
									
										
										
										
											2014-05-06 23:34:20 -04:00
										 |  |  |         operation, addr0, addr1, size, permissions); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-17 23:05:31 -04:00
										 |  |  |     switch (operation) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-24 23:56:06 -04:00
										 |  |  |     // Map normal heap memory
 | 
					
						
							|  |  |  |     case MEMORY_OPERATION_HEAP: | 
					
						
							| 
									
										
										
										
											2014-06-01 20:48:29 -04:00
										 |  |  |         *out_addr = Memory::MapBlock_Heap(size, operation, permissions); | 
					
						
							| 
									
										
										
										
											2014-04-24 23:56:06 -04:00
										 |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Map GSP heap memory
 | 
					
						
							|  |  |  |     case MEMORY_OPERATION_GSP_HEAP: | 
					
						
							| 
									
										
										
										
											2014-06-01 20:48:29 -04:00
										 |  |  |         *out_addr = Memory::MapBlock_HeapGSP(size, operation, permissions); | 
					
						
							| 
									
										
										
										
											2014-04-17 23:05:31 -04:00
										 |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Unknown ControlMemory operation
 | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2014-05-29 23:26:58 -04:00
										 |  |  |         ERROR_LOG(SVC, "unknown operation=0x%08X", operation); | 
					
						
							| 
									
										
										
										
											2014-04-17 23:05:31 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-04-24 23:56:06 -04:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// Maps a memory block to specified address
 | 
					
						
							| 
									
										
										
										
											2014-07-05 00:59:58 -04:00
										 |  |  | Result MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 other_permissions) { | 
					
						
							| 
									
										
										
										
											2014-08-07 20:27:11 -04:00
										 |  |  |     DEBUG_LOG(SVC, "called memblock=0x%08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d",  | 
					
						
							| 
									
										
										
										
											2014-07-05 00:59:58 -04:00
										 |  |  |         handle, addr, permissions, other_permissions); | 
					
						
							| 
									
										
										
										
											2014-07-05 10:22:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Kernel::MemoryPermission permissions_type = static_cast<Kernel::MemoryPermission>(permissions); | 
					
						
							|  |  |  |     switch (permissions_type) { | 
					
						
							|  |  |  |     case Kernel::MemoryPermission::Read: | 
					
						
							|  |  |  |     case Kernel::MemoryPermission::Write: | 
					
						
							|  |  |  |     case Kernel::MemoryPermission::ReadWrite: | 
					
						
							|  |  |  |     case Kernel::MemoryPermission::DontCare: | 
					
						
							|  |  |  |         Kernel::MapSharedMemory(handle, addr, permissions_type,  | 
					
						
							|  |  |  |             static_cast<Kernel::MemoryPermission>(other_permissions)); | 
					
						
							| 
									
										
										
										
											2014-04-24 23:56:06 -04:00
										 |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2014-07-05 00:59:58 -04:00
										 |  |  |         ERROR_LOG(OSHLE, "unknown permissions=0x%08X", permissions); | 
					
						
							| 
									
										
										
										
											2014-04-24 23:56:06 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-04-17 23:05:31 -04:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-12 21:55:36 -04:00
										 |  |  | /// Connect to an OS service given the port name, returns the handle to the port to out
 | 
					
						
							| 
									
										
										
										
											2014-06-06 23:31:29 -04:00
										 |  |  | Result ConnectToPort(Handle* out, const char* port_name) { | 
					
						
							| 
									
										
										
										
											2014-04-12 21:55:36 -04:00
										 |  |  |     Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); | 
					
						
							| 
									
										
										
										
											2014-06-01 20:48:29 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-29 23:26:58 -04:00
										 |  |  |     DEBUG_LOG(SVC, "called port_name=%s", port_name); | 
					
						
							| 
									
										
										
										
											2014-06-06 00:35:49 -04:00
										 |  |  |     _assert_msg_(KERNEL, (service != nullptr), "called, but service is not implemented!"); | 
					
						
							| 
									
										
										
										
											2014-06-01 20:48:29 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     *out = service->GetHandle(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-12 21:55:36 -04:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// Synchronize to an OS service
 | 
					
						
							| 
									
										
										
										
											2014-05-18 22:24:26 -04:00
										 |  |  | Result SendSyncRequest(Handle handle) { | 
					
						
							| 
									
										
										
										
											2014-05-26 21:17:10 -04:00
										 |  |  |     Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handle); | 
					
						
							| 
									
										
										
										
											2014-05-26 22:12:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 00:35:49 -04:00
										 |  |  |     _assert_msg_(KERNEL, (object != nullptr), "called, but kernel object is nullptr!"); | 
					
						
							| 
									
										
										
										
											2014-08-17 23:03:22 -04:00
										 |  |  |     DEBUG_LOG(SVC, "called handle=0x%08X(%s)", handle, object->GetTypeName().c_str()); | 
					
						
							| 
									
										
										
										
											2014-05-26 22:12:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 00:44:44 -04:00
										 |  |  |     bool wait = false; | 
					
						
							| 
									
										
										
										
											2014-05-26 22:12:46 -04:00
										 |  |  |     Result res = object->SyncRequest(&wait); | 
					
						
							|  |  |  |     if (wait) { | 
					
						
							|  |  |  |         Kernel::WaitCurrentThread(WAITTYPE_SYNCH); // TODO(bunnei): Is this correct?
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return res; | 
					
						
							| 
									
										
										
										
											2014-04-10 19:58:28 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-16 20:41:33 -04:00
										 |  |  | /// Close a handle
 | 
					
						
							|  |  |  | Result CloseHandle(Handle handle) { | 
					
						
							|  |  |  |     // ImplementMe
 | 
					
						
							| 
									
										
										
										
											2014-05-29 23:26:58 -04:00
										 |  |  |     ERROR_LOG(SVC, "(UNIMPLEMENTED) called handle=0x%08X", handle); | 
					
						
							| 
									
										
										
										
											2014-04-16 20:41:33 -04:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// Wait for a handle to synchronize, timeout after the specified nanoseconds
 | 
					
						
							| 
									
										
										
										
											2014-05-17 23:37:25 -04:00
										 |  |  | Result WaitSynchronization1(Handle handle, s64 nano_seconds) { | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  |     // TODO(bunnei): Do something with nano_seconds, currently ignoring this
 | 
					
						
							|  |  |  |     bool wait = false; | 
					
						
							| 
									
										
										
										
											2014-06-05 22:35:36 -04:00
										 |  |  |     bool wait_infinite = (nano_seconds == -1); // Used to wait until a thread has terminated
 | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handle); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-17 23:03:22 -04:00
										 |  |  |     DEBUG_LOG(SVC, "called handle=0x%08X(%s:%s), nanoseconds=%d", handle, object->GetTypeName().c_str(),  | 
					
						
							|  |  |  |             object->GetName().c_str(), nano_seconds); | 
					
						
							| 
									
										
										
										
											2014-06-05 22:35:36 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 00:35:49 -04:00
										 |  |  |     _assert_msg_(KERNEL, (object != nullptr), "called, but kernel object is nullptr!"); | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Result res = object->WaitSynchronization(&wait); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-05 22:35:36 -04:00
										 |  |  |     // Check for next thread to schedule
 | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  |     if (wait) { | 
					
						
							| 
									
										
										
										
											2014-06-01 21:42:50 -04:00
										 |  |  |         HLE::Reschedule(__func__); | 
					
						
							| 
									
										
										
										
											2014-06-05 22:35:36 -04:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return res; | 
					
						
							| 
									
										
										
										
											2014-05-17 23:37:25 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds
 | 
					
						
							| 
									
										
										
										
											2014-06-06 23:31:29 -04:00
										 |  |  | Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, bool wait_all,  | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  |     s64 nano_seconds) { | 
					
						
							|  |  |  |     // TODO(bunnei): Do something with nano_seconds, currently ignoring this
 | 
					
						
							|  |  |  |     bool unlock_all = true; | 
					
						
							| 
									
										
										
										
											2014-06-05 22:35:36 -04:00
										 |  |  |     bool wait_infinite = (nano_seconds == -1); // Used to wait until a thread has terminated
 | 
					
						
							| 
									
										
										
										
											2014-05-22 19:32:45 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-29 23:26:58 -04:00
										 |  |  |     DEBUG_LOG(SVC, "called handle_count=%d, wait_all=%s, nanoseconds=%d",  | 
					
						
							| 
									
										
										
										
											2014-05-18 17:52:02 -04:00
										 |  |  |         handle_count, (wait_all ? "true" : "false"), nano_seconds); | 
					
						
							| 
									
										
										
										
											2014-05-22 19:32:45 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  |     // Iterate through each handle, synchronize kernel object
 | 
					
						
							| 
									
										
										
										
											2014-06-06 23:31:29 -04:00
										 |  |  |     for (s32 i = 0; i < handle_count; i++) { | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  |         bool wait = false; | 
					
						
							| 
									
										
										
										
											2014-06-06 00:19:40 -04:00
										 |  |  |         Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handles[i]); | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 00:35:49 -04:00
										 |  |  |         _assert_msg_(KERNEL, (object != nullptr), "called handle=0x%08X, but kernel object " | 
					
						
							|  |  |  |             "is nullptr!", handles[i]); | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-17 23:03:22 -04:00
										 |  |  |         DEBUG_LOG(SVC, "\thandle[%d] = 0x%08X(%s:%s)", i, handles[i], object->GetTypeName().c_str(),  | 
					
						
							|  |  |  |             object->GetName().c_str()); | 
					
						
							| 
									
										
										
										
											2014-05-29 20:24:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  |         Result res = object->WaitSynchronization(&wait); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!wait && !wait_all) { | 
					
						
							| 
									
										
										
										
											2014-06-02 17:54:07 -04:00
										 |  |  |             *out = i; | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  |             return 0; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             unlock_all = false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (wait_all && unlock_all) { | 
					
						
							| 
									
										
										
										
											2014-06-02 17:54:07 -04:00
										 |  |  |         *out = handle_count; | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2014-05-18 17:52:02 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-01 21:42:50 -04:00
										 |  |  |     // Check for next thread to schedule
 | 
					
						
							|  |  |  |     HLE::Reschedule(__func__); | 
					
						
							| 
									
										
										
										
											2014-05-27 22:41:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-05 22:35:36 -04:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2014-04-16 20:41:33 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-01 18:50:36 -04:00
										 |  |  | /// Create an address arbiter (to allocate access to shared resources)
 | 
					
						
							| 
									
										
										
										
											2014-07-06 23:15:40 -04:00
										 |  |  | Result CreateAddressArbiter(u32* arbiter) { | 
					
						
							|  |  |  |     DEBUG_LOG(SVC, "called"); | 
					
						
							|  |  |  |     Handle handle = Kernel::CreateAddressArbiter(); | 
					
						
							|  |  |  |     *arbiter = handle; | 
					
						
							| 
									
										
										
										
											2014-05-01 18:50:36 -04:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-29 20:24:51 -04:00
										 |  |  | /// Arbitrate address
 | 
					
						
							| 
									
										
										
										
											2014-07-06 23:15:40 -04:00
										 |  |  | Result ArbitrateAddress(Handle arbiter, u32 address, u32 type, u32 value, s64 nanoseconds) { | 
					
						
							|  |  |  |     return Kernel::ArbitrateAddress(arbiter, static_cast<Kernel::ArbitrationType>(type), address,  | 
					
						
							|  |  |  |         value); | 
					
						
							| 
									
										
										
										
											2014-05-29 20:24:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-01 18:50:36 -04:00
										 |  |  | /// Used to output a message on a debug hardware unit - does nothing on a retail unit
 | 
					
						
							|  |  |  | void OutputDebugString(const char* string) { | 
					
						
							| 
									
										
										
										
											2014-05-29 23:04:18 -04:00
										 |  |  |     OS_LOG(SVC, "%s", string); | 
					
						
							| 
									
										
										
										
											2014-05-06 23:34:20 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// Get resource limit
 | 
					
						
							| 
									
										
										
										
											2014-06-06 23:31:29 -04:00
										 |  |  | Result GetResourceLimit(Handle* resource_limit, Handle process) { | 
					
						
							| 
									
										
										
										
											2014-05-06 23:34:20 -04:00
										 |  |  |     // With regards to proceess values:
 | 
					
						
							|  |  |  |     // 0xFFFF8001 is a handle alias for the current KProcess, and 0xFFFF8000 is a handle alias for 
 | 
					
						
							|  |  |  |     // the current KThread.
 | 
					
						
							| 
									
										
										
										
											2014-06-01 20:48:29 -04:00
										 |  |  |     *resource_limit = 0xDEADBEEF; | 
					
						
							| 
									
										
										
										
											2014-05-29 23:26:58 -04:00
										 |  |  |     ERROR_LOG(SVC, "(UNIMPLEMENTED) called process=0x%08X", process); | 
					
						
							| 
									
										
										
										
											2014-05-06 23:34:20 -04:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// Get resource limit current values
 | 
					
						
							| 
									
										
										
										
											2014-06-06 23:31:29 -04:00
										 |  |  | Result GetResourceLimitCurrentValues(s64* values, Handle resource_limit, void* names,  | 
					
						
							| 
									
										
										
										
											2014-05-29 23:26:58 -04:00
										 |  |  |     s32 name_count) { | 
					
						
							|  |  |  |     ERROR_LOG(SVC, "(UNIMPLEMENTED) called resource_limit=%08X, names=%s, name_count=%d", | 
					
						
							| 
									
										
										
										
											2014-05-06 23:34:20 -04:00
										 |  |  |         resource_limit, names, name_count); | 
					
						
							|  |  |  |     Memory::Write32(Core::g_app_core->GetReg(0), 0); // Normmatt: Set used memory to 0 for now
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2014-05-01 18:50:36 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-20 22:57:54 -04:00
										 |  |  | /// Creates a new thread
 | 
					
						
							| 
									
										
										
										
											2014-05-20 23:36:35 -04:00
										 |  |  | Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top, u32 processor_id) { | 
					
						
							| 
									
										
										
										
											2014-05-17 13:47:44 -04:00
										 |  |  |     std::string name; | 
					
						
							| 
									
										
										
										
											2014-05-15 18:25:56 -04:00
										 |  |  |     if (Symbols::HasSymbol(entry_point)) { | 
					
						
							|  |  |  |         TSymbol symbol = Symbols::GetSymbol(entry_point); | 
					
						
							| 
									
										
										
										
											2014-05-17 13:47:44 -04:00
										 |  |  |         name = symbol.name; | 
					
						
							| 
									
										
										
										
											2014-05-15 18:25:56 -04:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2014-08-17 14:28:36 -04:00
										 |  |  |         name = StringFromFormat("unknown-%08x", entry_point); | 
					
						
							| 
									
										
										
										
											2014-05-13 21:58:26 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-05-17 13:47:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-22 19:32:45 -04:00
										 |  |  |     Handle thread = Kernel::CreateThread(name.c_str(), entry_point, priority, arg, processor_id, | 
					
						
							| 
									
										
										
										
											2014-05-17 13:47:44 -04:00
										 |  |  |         stack_top); | 
					
						
							| 
									
										
										
										
											2014-05-20 23:36:35 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Core::g_app_core->SetReg(1, thread); | 
					
						
							| 
									
										
										
										
											2014-05-21 21:41:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-29 23:26:58 -04:00
										 |  |  |     DEBUG_LOG(SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " | 
					
						
							| 
									
										
										
										
											2014-05-29 20:24:51 -04:00
										 |  |  |         "threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X", entry_point,  | 
					
						
							| 
									
										
										
										
											2014-05-21 21:41:40 -04:00
										 |  |  |         name.c_str(), arg, stack_top, priority, processor_id, thread); | 
					
						
							| 
									
										
										
										
											2014-05-18 17:52:02 -04:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2014-05-13 21:58:26 -04:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-05 22:35:36 -04:00
										 |  |  | /// Called when a thread exits
 | 
					
						
							|  |  |  | u32 ExitThread() { | 
					
						
							|  |  |  |     Handle thread = Kernel::GetCurrentThreadHandle(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     DEBUG_LOG(SVC, "called, pc=0x%08X", Core::g_app_core->GetPC()); // PC = 0x0010545C
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Kernel::StopThread(thread, __func__); | 
					
						
							|  |  |  |     HLE::Reschedule(__func__); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-01 22:12:54 -04:00
										 |  |  | /// Gets the priority for the specified thread
 | 
					
						
							| 
									
										
										
										
											2014-06-06 23:31:29 -04:00
										 |  |  | Result GetThreadPriority(s32* priority, Handle handle) { | 
					
						
							| 
									
										
										
										
											2014-06-01 22:12:54 -04:00
										 |  |  |     *priority = Kernel::GetThreadPriority(handle); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// Sets the priority for the specified thread
 | 
					
						
							|  |  |  | Result SetThreadPriority(Handle handle, s32 priority) { | 
					
						
							|  |  |  |     return Kernel::SetThreadPriority(handle, priority); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-20 22:57:54 -04:00
										 |  |  | /// Create a mutex
 | 
					
						
							| 
									
										
										
										
											2014-06-06 23:31:29 -04:00
										 |  |  | Result CreateMutex(Handle* mutex, u32 initial_locked) { | 
					
						
							| 
									
										
										
										
											2014-06-01 20:48:29 -04:00
										 |  |  |     *mutex = Kernel::CreateMutex((initial_locked != 0)); | 
					
						
							| 
									
										
										
										
											2014-05-29 23:26:58 -04:00
										 |  |  |     DEBUG_LOG(SVC, "called initial_locked=%s : created handle=0x%08X",  | 
					
						
							| 
									
										
										
										
											2014-06-01 20:48:29 -04:00
										 |  |  |         initial_locked ? "true" : "false", *mutex); | 
					
						
							| 
									
										
										
										
											2014-05-13 21:58:26 -04:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-20 22:57:54 -04:00
										 |  |  | /// Release a mutex
 | 
					
						
							| 
									
										
										
										
											2014-05-13 21:58:26 -04:00
										 |  |  | Result ReleaseMutex(Handle handle) { | 
					
						
							| 
									
										
										
										
											2014-05-29 23:26:58 -04:00
										 |  |  |     DEBUG_LOG(SVC, "called handle=0x%08X", handle); | 
					
						
							| 
									
										
										
										
											2014-06-06 00:35:49 -04:00
										 |  |  |     _assert_msg_(KERNEL, (handle != 0), "called, but handle is nullptr!"); | 
					
						
							| 
									
										
										
										
											2014-05-20 23:03:45 -04:00
										 |  |  |     Kernel::ReleaseMutex(handle); | 
					
						
							| 
									
										
										
										
											2014-05-13 21:58:26 -04:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-20 22:57:54 -04:00
										 |  |  | /// Get current thread ID
 | 
					
						
							| 
									
										
										
										
											2014-06-06 23:31:29 -04:00
										 |  |  | Result GetThreadId(u32* thread_id, Handle thread) { | 
					
						
							| 
									
										
										
										
											2014-05-29 23:26:58 -04:00
										 |  |  |     ERROR_LOG(SVC, "(UNIMPLEMENTED) called thread=0x%08X", thread); | 
					
						
							| 
									
										
										
										
											2014-05-15 20:17:30 -04:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-20 22:57:54 -04:00
										 |  |  | /// Query memory
 | 
					
						
							| 
									
										
										
										
											2014-06-06 23:31:29 -04:00
										 |  |  | Result QueryMemory(void* info, void* out, u32 addr) { | 
					
						
							| 
									
										
										
										
											2014-05-29 23:26:58 -04:00
										 |  |  |     ERROR_LOG(SVC, "(UNIMPLEMENTED) called addr=0x%08X", addr); | 
					
						
							| 
									
										
										
										
											2014-05-15 20:17:30 -04:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-20 22:57:54 -04:00
										 |  |  | /// Create an event
 | 
					
						
							| 
									
										
										
										
											2014-06-06 23:31:29 -04:00
										 |  |  | Result CreateEvent(Handle* evt, u32 reset_type) { | 
					
						
							| 
									
										
										
										
											2014-06-01 20:48:29 -04:00
										 |  |  |     *evt = Kernel::CreateEvent((ResetType)reset_type); | 
					
						
							| 
									
										
										
										
											2014-05-29 23:26:58 -04:00
										 |  |  |     DEBUG_LOG(SVC, "called reset_type=0x%08X : created handle=0x%08X",  | 
					
						
							| 
									
										
										
										
											2014-06-01 20:48:29 -04:00
										 |  |  |         reset_type, *evt); | 
					
						
							| 
									
										
										
										
											2014-05-18 17:52:02 -04:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-26 20:55:48 -04:00
										 |  |  | /// Duplicates a kernel handle
 | 
					
						
							| 
									
										
										
										
											2014-06-06 23:31:29 -04:00
										 |  |  | Result DuplicateHandle(Handle* out, Handle handle) { | 
					
						
							| 
									
										
										
										
											2014-06-01 22:33:53 -04:00
										 |  |  |     DEBUG_LOG(SVC, "called handle=0x%08X", handle); | 
					
						
							| 
									
										
										
										
											2014-06-01 22:12:54 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Translate kernel handles -> real handles
 | 
					
						
							|  |  |  |     if (handle == Kernel::CurrentThread) { | 
					
						
							|  |  |  |         handle = Kernel::GetCurrentThreadHandle(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     _assert_msg_(KERNEL, (handle != Kernel::CurrentProcess), | 
					
						
							|  |  |  |         "(UNIMPLEMENTED) process handle duplication!"); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     // TODO(bunnei): FixMe - This is a hack to return the handle that we were asked to duplicate.
 | 
					
						
							|  |  |  |     *out = handle; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-26 20:55:48 -04:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-05 22:35:36 -04:00
										 |  |  | /// Signals an event
 | 
					
						
							|  |  |  | Result SignalEvent(Handle evt) { | 
					
						
							|  |  |  |     Result res = Kernel::SignalEvent(evt); | 
					
						
							|  |  |  |     DEBUG_LOG(SVC, "called event=0x%08X", evt); | 
					
						
							|  |  |  |     return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-29 20:24:51 -04:00
										 |  |  | /// Clears an event
 | 
					
						
							|  |  |  | Result ClearEvent(Handle evt) { | 
					
						
							|  |  |  |     Result res = Kernel::ClearEvent(evt); | 
					
						
							| 
									
										
										
										
											2014-05-29 23:26:58 -04:00
										 |  |  |     DEBUG_LOG(SVC, "called event=0x%08X", evt); | 
					
						
							| 
									
										
										
										
											2014-05-29 20:24:51 -04:00
										 |  |  |     return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-01 10:37:19 -04:00
										 |  |  | /// Sleep the current thread
 | 
					
						
							|  |  |  | void SleepThread(s64 nanoseconds) { | 
					
						
							|  |  |  |     DEBUG_LOG(SVC, "called nanoseconds=%d", nanoseconds); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-14 20:01:02 -04:00
										 |  |  | /// This returns the total CPU ticks elapsed since the CPU was powered-on
 | 
					
						
							|  |  |  | s64 GetSystemTick() { | 
					
						
							|  |  |  |     return (s64)Core::g_app_core->GetTicks(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-20 18:28:38 -04:00
										 |  |  | const HLE::FunctionDef SVC_Table[] = { | 
					
						
							| 
									
										
										
										
											2014-06-09 22:30:39 -04:00
										 |  |  |     {0x00, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x01, HLE::Wrap<ControlMemory>,        "ControlMemory"}, | 
					
						
							|  |  |  |     {0x02, HLE::Wrap<QueryMemory>,          "QueryMemory"}, | 
					
						
							|  |  |  |     {0x03, nullptr,                         "ExitProcess"}, | 
					
						
							|  |  |  |     {0x04, nullptr,                         "GetProcessAffinityMask"}, | 
					
						
							|  |  |  |     {0x05, nullptr,                         "SetProcessAffinityMask"}, | 
					
						
							|  |  |  |     {0x06, nullptr,                         "GetProcessIdealProcessor"}, | 
					
						
							|  |  |  |     {0x07, nullptr,                         "SetProcessIdealProcessor"}, | 
					
						
							|  |  |  |     {0x08, HLE::Wrap<CreateThread>,         "CreateThread"}, | 
					
						
							|  |  |  |     {0x09, HLE::Wrap<ExitThread>,           "ExitThread"}, | 
					
						
							|  |  |  |     {0x0A, HLE::Wrap<SleepThread>,          "SleepThread"}, | 
					
						
							|  |  |  |     {0x0B, HLE::Wrap<GetThreadPriority>,    "GetThreadPriority"}, | 
					
						
							|  |  |  |     {0x0C, HLE::Wrap<SetThreadPriority>,    "SetThreadPriority"}, | 
					
						
							|  |  |  |     {0x0D, nullptr,                         "GetThreadAffinityMask"}, | 
					
						
							|  |  |  |     {0x0E, nullptr,                         "SetThreadAffinityMask"}, | 
					
						
							|  |  |  |     {0x0F, nullptr,                         "GetThreadIdealProcessor"}, | 
					
						
							|  |  |  |     {0x10, nullptr,                         "SetThreadIdealProcessor"}, | 
					
						
							|  |  |  |     {0x11, nullptr,                         "GetCurrentProcessorNumber"}, | 
					
						
							|  |  |  |     {0x12, nullptr,                         "Run"}, | 
					
						
							|  |  |  |     {0x13, HLE::Wrap<CreateMutex>,          "CreateMutex"}, | 
					
						
							|  |  |  |     {0x14, HLE::Wrap<ReleaseMutex>,         "ReleaseMutex"}, | 
					
						
							|  |  |  |     {0x15, nullptr,                         "CreateSemaphore"}, | 
					
						
							|  |  |  |     {0x16, nullptr,                         "ReleaseSemaphore"}, | 
					
						
							|  |  |  |     {0x17, HLE::Wrap<CreateEvent>,          "CreateEvent"}, | 
					
						
							|  |  |  |     {0x18, HLE::Wrap<SignalEvent>,          "SignalEvent"}, | 
					
						
							|  |  |  |     {0x19, HLE::Wrap<ClearEvent>,           "ClearEvent"}, | 
					
						
							|  |  |  |     {0x1A, nullptr,                         "CreateTimer"}, | 
					
						
							|  |  |  |     {0x1B, nullptr,                         "SetTimer"}, | 
					
						
							|  |  |  |     {0x1C, nullptr,                         "CancelTimer"}, | 
					
						
							|  |  |  |     {0x1D, nullptr,                         "ClearTimer"}, | 
					
						
							|  |  |  |     {0x1E, nullptr,                         "CreateMemoryBlock"}, | 
					
						
							|  |  |  |     {0x1F, HLE::Wrap<MapMemoryBlock>,       "MapMemoryBlock"}, | 
					
						
							|  |  |  |     {0x20, nullptr,                         "UnmapMemoryBlock"}, | 
					
						
							|  |  |  |     {0x21, HLE::Wrap<CreateAddressArbiter>, "CreateAddressArbiter"}, | 
					
						
							|  |  |  |     {0x22, HLE::Wrap<ArbitrateAddress>,     "ArbitrateAddress"}, | 
					
						
							|  |  |  |     {0x23, HLE::Wrap<CloseHandle>,          "CloseHandle"}, | 
					
						
							|  |  |  |     {0x24, HLE::Wrap<WaitSynchronization1>, "WaitSynchronization1"}, | 
					
						
							|  |  |  |     {0x25, HLE::Wrap<WaitSynchronizationN>, "WaitSynchronizationN"}, | 
					
						
							|  |  |  |     {0x26, nullptr,                         "SignalAndWait"}, | 
					
						
							|  |  |  |     {0x27, HLE::Wrap<DuplicateHandle>,      "DuplicateHandle"}, | 
					
						
							| 
									
										
										
										
											2014-08-14 20:01:02 -04:00
										 |  |  |     {0x28, HLE::Wrap<GetSystemTick>,        "GetSystemTick"}, | 
					
						
							| 
									
										
										
										
											2014-06-09 22:30:39 -04:00
										 |  |  |     {0x29, nullptr,                         "GetHandleInfo"}, | 
					
						
							|  |  |  |     {0x2A, nullptr,                         "GetSystemInfo"}, | 
					
						
							|  |  |  |     {0x2B, nullptr,                         "GetProcessInfo"}, | 
					
						
							|  |  |  |     {0x2C, nullptr,                         "GetThreadInfo"}, | 
					
						
							|  |  |  |     {0x2D, HLE::Wrap<ConnectToPort>,        "ConnectToPort"}, | 
					
						
							|  |  |  |     {0x2E, nullptr,                         "SendSyncRequest1"}, | 
					
						
							|  |  |  |     {0x2F, nullptr,                         "SendSyncRequest2"}, | 
					
						
							|  |  |  |     {0x30, nullptr,                         "SendSyncRequest3"}, | 
					
						
							|  |  |  |     {0x31, nullptr,                         "SendSyncRequest4"}, | 
					
						
							|  |  |  |     {0x32, HLE::Wrap<SendSyncRequest>,      "SendSyncRequest"}, | 
					
						
							|  |  |  |     {0x33, nullptr,                         "OpenProcess"}, | 
					
						
							|  |  |  |     {0x34, nullptr,                         "OpenThread"}, | 
					
						
							|  |  |  |     {0x35, nullptr,                         "GetProcessId"}, | 
					
						
							|  |  |  |     {0x36, nullptr,                         "GetProcessIdOfThread"}, | 
					
						
							|  |  |  |     {0x37, HLE::Wrap<GetThreadId>,          "GetThreadId"}, | 
					
						
							|  |  |  |     {0x38, HLE::Wrap<GetResourceLimit>,     "GetResourceLimit"}, | 
					
						
							|  |  |  |     {0x39, nullptr,                         "GetResourceLimitLimitValues"}, | 
					
						
							|  |  |  |     {0x3A, HLE::Wrap<GetResourceLimitCurrentValues>, "GetResourceLimitCurrentValues"}, | 
					
						
							|  |  |  |     {0x3B, nullptr,                         "GetThreadContext"}, | 
					
						
							|  |  |  |     {0x3C, nullptr,                         "Break"}, | 
					
						
							|  |  |  |     {0x3D, HLE::Wrap<OutputDebugString>,    "OutputDebugString"}, | 
					
						
							|  |  |  |     {0x3E, nullptr,                         "ControlPerformanceCounter"}, | 
					
						
							|  |  |  |     {0x3F, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x40, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x41, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x42, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x43, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x44, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x45, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x46, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x47, nullptr,                         "CreatePort"}, | 
					
						
							|  |  |  |     {0x48, nullptr,                         "CreateSessionToPort"}, | 
					
						
							|  |  |  |     {0x49, nullptr,                         "CreateSession"}, | 
					
						
							|  |  |  |     {0x4A, nullptr,                         "AcceptSession"}, | 
					
						
							|  |  |  |     {0x4B, nullptr,                         "ReplyAndReceive1"}, | 
					
						
							|  |  |  |     {0x4C, nullptr,                         "ReplyAndReceive2"}, | 
					
						
							|  |  |  |     {0x4D, nullptr,                         "ReplyAndReceive3"}, | 
					
						
							|  |  |  |     {0x4E, nullptr,                         "ReplyAndReceive4"}, | 
					
						
							|  |  |  |     {0x4F, nullptr,                         "ReplyAndReceive"}, | 
					
						
							|  |  |  |     {0x50, nullptr,                         "BindInterrupt"}, | 
					
						
							|  |  |  |     {0x51, nullptr,                         "UnbindInterrupt"}, | 
					
						
							|  |  |  |     {0x52, nullptr,                         "InvalidateProcessDataCache"}, | 
					
						
							|  |  |  |     {0x53, nullptr,                         "StoreProcessDataCache"}, | 
					
						
							|  |  |  |     {0x54, nullptr,                         "FlushProcessDataCache"}, | 
					
						
							|  |  |  |     {0x55, nullptr,                         "StartInterProcessDma"}, | 
					
						
							|  |  |  |     {0x56, nullptr,                         "StopDma"}, | 
					
						
							|  |  |  |     {0x57, nullptr,                         "GetDmaState"}, | 
					
						
							|  |  |  |     {0x58, nullptr,                         "RestartDma"}, | 
					
						
							|  |  |  |     {0x59, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x5A, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x5B, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x5C, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x5D, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x5E, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x5F, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x60, nullptr,                         "DebugActiveProcess"}, | 
					
						
							|  |  |  |     {0x61, nullptr,                         "BreakDebugProcess"}, | 
					
						
							|  |  |  |     {0x62, nullptr,                         "TerminateDebugProcess"}, | 
					
						
							|  |  |  |     {0x63, nullptr,                         "GetProcessDebugEvent"}, | 
					
						
							|  |  |  |     {0x64, nullptr,                         "ContinueDebugEvent"}, | 
					
						
							|  |  |  |     {0x65, nullptr,                         "GetProcessList"}, | 
					
						
							|  |  |  |     {0x66, nullptr,                         "GetThreadList"}, | 
					
						
							|  |  |  |     {0x67, nullptr,                         "GetDebugThreadContext"}, | 
					
						
							|  |  |  |     {0x68, nullptr,                         "SetDebugThreadContext"}, | 
					
						
							|  |  |  |     {0x69, nullptr,                         "QueryDebugProcessMemory"}, | 
					
						
							|  |  |  |     {0x6A, nullptr,                         "ReadProcessMemory"}, | 
					
						
							|  |  |  |     {0x6B, nullptr,                         "WriteProcessMemory"}, | 
					
						
							|  |  |  |     {0x6C, nullptr,                         "SetHardwareBreakPoint"}, | 
					
						
							|  |  |  |     {0x6D, nullptr,                         "GetDebugThreadParam"}, | 
					
						
							|  |  |  |     {0x6E, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x6F, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x70, nullptr,                         "ControlProcessMemory"}, | 
					
						
							|  |  |  |     {0x71, nullptr,                         "MapProcessMemory"}, | 
					
						
							|  |  |  |     {0x72, nullptr,                         "UnmapProcessMemory"}, | 
					
						
							|  |  |  |     {0x73, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x74, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x75, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x76, nullptr,                         "TerminateProcess"}, | 
					
						
							|  |  |  |     {0x77, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x78, nullptr,                         "CreateResourceLimit"}, | 
					
						
							|  |  |  |     {0x79, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x7A, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x7B, nullptr,                         "Unknown"}, | 
					
						
							|  |  |  |     {0x7C, nullptr,                         "KernelSetState"}, | 
					
						
							|  |  |  |     {0x7D, nullptr,                         "QueryProcessMemory"}, | 
					
						
							| 
									
										
										
										
											2014-04-10 19:58:28 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-11 18:44:21 -04:00
										 |  |  | void Register() { | 
					
						
							| 
									
										
										
										
											2014-05-20 18:28:38 -04:00
										 |  |  |     HLE::RegisterModule("SVC_Table", ARRAY_SIZE(SVC_Table), SVC_Table); | 
					
						
							| 
									
										
										
										
											2014-04-10 19:58:28 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-04-11 18:44:21 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | } // namespace
 |