summaryrefslogtreecommitdiff
path: root/src/core/hle/svc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/svc.cpp')
-rw-r--r--src/core/hle/svc.cpp43
1 files changed, 39 insertions, 4 deletions
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index cba94eac3..1ba61d807 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -9,6 +9,8 @@
9#include "core/hle/kernel/client_port.h" 9#include "core/hle/kernel/client_port.h"
10#include "core/hle/kernel/client_session.h" 10#include "core/hle/kernel/client_session.h"
11#include "core/hle/kernel/handle_table.h" 11#include "core/hle/kernel/handle_table.h"
12#include "core/hle/kernel/mutex.h"
13#include "core/hle/kernel/object_address_table.h"
12#include "core/hle/kernel/process.h" 14#include "core/hle/kernel/process.h"
13#include "core/hle/kernel/resource_limit.h" 15#include "core/hle/kernel/resource_limit.h"
14#include "core/hle/kernel/sync_object.h" 16#include "core/hle/kernel/sync_object.h"
@@ -45,7 +47,7 @@ static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
45/// Unmaps a region that was previously mapped with svcMapMemory 47/// Unmaps a region that was previously mapped with svcMapMemory
46static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { 48static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
47 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr, 49 LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr,
48 src_addr, size); 50 src_addr, size);
49 return Kernel::g_current_process->UnmapMemory(dst_addr, src_addr, size); 51 return Kernel::g_current_process->UnmapMemory(dst_addr, src_addr, size);
50} 52}
51 53
@@ -99,7 +101,8 @@ static ResultCode SendSyncRequest(Kernel::Handle handle) {
99static ResultCode GetThreadId(u32* thread_id, Kernel::Handle thread_handle) { 101static ResultCode GetThreadId(u32* thread_id, Kernel::Handle thread_handle) {
100 LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle); 102 LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle);
101 103
102 const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(thread_handle); 104 const SharedPtr<Kernel::Thread> thread =
105 Kernel::g_handle_table.Get<Kernel::Thread>(thread_handle);
103 if (!thread) { 106 if (!thread) {
104 return ERR_INVALID_HANDLE; 107 return ERR_INVALID_HANDLE;
105 } 108 }
@@ -177,7 +180,7 @@ static void Break(u64 unk_0, u64 unk_1, u64 unk_2) {
177} 180}
178 181
179/// Used to output a message on a debug hardware unit - does nothing on a retail unit 182/// Used to output a message on a debug hardware unit - does nothing on a retail unit
180static void OutputDebugString(VAddr address, int len) { 183static void OutputDebugString(VAddr address, s32 len) {
181 std::vector<char> string(len); 184 std::vector<char> string(len);
182 Memory::ReadBlock(address, string.data(), len); 185 Memory::ReadBlock(address, string.data(), len);
183 LOG_DEBUG(Debug_Emulated, "%.*s", len, string.data()); 186 LOG_DEBUG(Debug_Emulated, "%.*s", len, string.data());
@@ -272,6 +275,38 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAdd
272 return QueryProcessMemory(memory_info, page_info, Kernel::CurrentProcess, addr); 275 return QueryProcessMemory(memory_info, page_info, Kernel::CurrentProcess, addr);
273} 276}
274 277
278/// Exits the current process
279static void ExitProcess() {
280 LOG_INFO(Kernel_SVC, "Process %u exiting", Kernel::g_current_process->process_id);
281
282 ASSERT_MSG(Kernel::g_current_process->status == Kernel::ProcessStatus::Running,
283 "Process has already exited");
284
285 Kernel::g_current_process->status = Kernel::ProcessStatus::Exited;
286
287 // Stop all the process threads that are currently waiting for objects.
288 auto& thread_list = Kernel::GetThreadList();
289 for (auto& thread : thread_list) {
290 if (thread->owner_process != Kernel::g_current_process)
291 continue;
292
293 if (thread == Kernel::GetCurrentThread())
294 continue;
295
296 // TODO(Subv): When are the other running/ready threads terminated?
297 ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY ||
298 thread->status == THREADSTATUS_WAIT_SYNCH_ALL,
299 "Exiting processes with non-waiting threads is currently unimplemented");
300
301 thread->Stop();
302 }
303
304 // Kill the current thread
305 Kernel::GetCurrentThread()->Stop();
306
307 Core::System::GetInstance().PrepareReschedule();
308}
309
275/// Creates a new thread 310/// Creates a new thread
276static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, 311static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top,
277 u32 priority, s32 processor_id) { 312 u32 priority, s32 processor_id) {
@@ -400,7 +435,7 @@ static const FunctionDef SVC_Table[] = {
400 {0x04, HLE::Wrap<MapMemory>, "svcMapMemory"}, 435 {0x04, HLE::Wrap<MapMemory>, "svcMapMemory"},
401 {0x05, HLE::Wrap<UnmapMemory>, "svcUnmapMemory"}, 436 {0x05, HLE::Wrap<UnmapMemory>, "svcUnmapMemory"},
402 {0x06, HLE::Wrap<QueryMemory>, "svcQueryMemory"}, 437 {0x06, HLE::Wrap<QueryMemory>, "svcQueryMemory"},
403 {0x07, nullptr, "svcExitProcess"}, 438 {0x07, HLE::Wrap<ExitProcess>, "svcExitProcess"},
404 {0x08, HLE::Wrap<CreateThread>, "svcCreateThread"}, 439 {0x08, HLE::Wrap<CreateThread>, "svcCreateThread"},
405 {0x09, HLE::Wrap<StartThread>, "svcStartThread"}, 440 {0x09, HLE::Wrap<StartThread>, "svcStartThread"},
406 {0x0A, HLE::Wrap<ExitThread>, "svcExitThread"}, 441 {0x0A, HLE::Wrap<ExitThread>, "svcExitThread"},