summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/hle/kernel/archive.cpp39
-rw-r--r--src/core/hle/kernel/kernel.h16
-rw-r--r--src/core/hle/kernel/session.h58
-rw-r--r--src/core/hle/service/ac_u.cpp2
-rw-r--r--src/core/hle/service/apt_u.cpp16
-rw-r--r--src/core/hle/service/cfg_u.cpp4
-rw-r--r--src/core/hle/service/dsp_dsp.cpp12
-rw-r--r--src/core/hle/service/fs_user.cpp22
-rw-r--r--src/core/hle/service/gsp_gpu.cpp10
-rw-r--r--src/core/hle/service/hid_user.cpp2
-rw-r--r--src/core/hle/service/ptm_u.cpp8
-rw-r--r--src/core/hle/service/service.h26
-rw-r--r--src/core/hle/service/srv.cpp6
-rw-r--r--src/core/hle/svc.cpp11
15 files changed, 129 insertions, 104 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 567d7454e..ab63f54de 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -108,6 +108,7 @@ set(HEADERS
108 hle/kernel/kernel.h 108 hle/kernel/kernel.h
109 hle/kernel/mutex.h 109 hle/kernel/mutex.h
110 hle/kernel/semaphore.h 110 hle/kernel/semaphore.h
111 hle/kernel/session.h
111 hle/kernel/shared_memory.h 112 hle/kernel/shared_memory.h
112 hle/kernel/thread.h 113 hle/kernel/thread.h
113 hle/service/ac_u.h 114 hle/service/ac_u.h
diff --git a/src/core/hle/kernel/archive.cpp b/src/core/hle/kernel/archive.cpp
index ddc09e13b..0e3eb4564 100644
--- a/src/core/hle/kernel/archive.cpp
+++ b/src/core/hle/kernel/archive.cpp
@@ -2,6 +2,8 @@
2// Licensed under GPLv2 2// Licensed under GPLv2
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <map>
6
5#include "common/common_types.h" 7#include "common/common_types.h"
6#include "common/file_util.h" 8#include "common/file_util.h"
7#include "common/math_util.h" 9#include "common/math_util.h"
@@ -10,8 +12,8 @@
10#include "core/file_sys/archive_sdmc.h" 12#include "core/file_sys/archive_sdmc.h"
11#include "core/file_sys/directory.h" 13#include "core/file_sys/directory.h"
12#include "core/hle/kernel/archive.h" 14#include "core/hle/kernel/archive.h"
15#include "core/hle/kernel/session.h"
13#include "core/hle/result.h" 16#include "core/hle/result.h"
14#include "core/hle/service/service.h"
15 17
16//////////////////////////////////////////////////////////////////////////////////////////////////// 18////////////////////////////////////////////////////////////////////////////////////////////////////
17// Kernel namespace 19// Kernel namespace
@@ -41,19 +43,15 @@ enum class DirectoryCommand : u32 {
41 Close = 0x08020000, 43 Close = 0x08020000,
42}; 44};
43 45
44class Archive : public Object { 46class Archive : public Kernel::Session {
45public: 47public:
46 std::string GetTypeName() const override { return "Archive"; } 48 std::string GetName() const override { return "Archive: " + name; }
47 std::string GetName() const override { return name; }
48
49 static Kernel::HandleType GetStaticHandleType() { return HandleType::Archive; }
50 Kernel::HandleType GetHandleType() const override { return HandleType::Archive; }
51 49
52 std::string name; ///< Name of archive (optional) 50 std::string name; ///< Name of archive (optional)
53 FileSys::Archive* backend; ///< Archive backend interface 51 FileSys::Archive* backend; ///< Archive backend interface
54 52
55 ResultVal<bool> SyncRequest() override { 53 ResultVal<bool> SyncRequest() override {
56 u32* cmd_buff = Service::GetCommandBuffer(); 54 u32* cmd_buff = Kernel::GetCommandBuffer();
57 FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]); 55 FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]);
58 56
59 switch (cmd) { 57 switch (cmd) {
@@ -102,7 +100,8 @@ public:
102 default: 100 default:
103 { 101 {
104 LOG_ERROR(Service_FS, "Unknown command=0x%08X", cmd); 102 LOG_ERROR(Service_FS, "Unknown command=0x%08X", cmd);
105 return UnimplementedFunction(ErrorModule::FS); 103 cmd_buff[0] = UnimplementedFunction(ErrorModule::FS).raw;
104 return MakeResult<bool>(false);
106 } 105 }
107 } 106 }
108 cmd_buff[1] = 0; // No error 107 cmd_buff[1] = 0; // No error
@@ -110,19 +109,15 @@ public:
110 } 109 }
111}; 110};
112 111
113class File : public Object { 112class File : public Kernel::Session {
114public: 113public:
115 std::string GetTypeName() const override { return "File"; } 114 std::string GetName() const override { return "Path: " + path.DebugStr(); }
116 std::string GetName() const override { return path.DebugStr(); }
117
118 static Kernel::HandleType GetStaticHandleType() { return HandleType::File; }
119 Kernel::HandleType GetHandleType() const override { return HandleType::File; }
120 115
121 FileSys::Path path; ///< Path of the file 116 FileSys::Path path; ///< Path of the file
122 std::unique_ptr<FileSys::File> backend; ///< File backend interface 117 std::unique_ptr<FileSys::File> backend; ///< File backend interface
123 118
124 ResultVal<bool> SyncRequest() override { 119 ResultVal<bool> SyncRequest() override {
125 u32* cmd_buff = Service::GetCommandBuffer(); 120 u32* cmd_buff = Kernel::GetCommandBuffer();
126 FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]); 121 FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]);
127 switch (cmd) { 122 switch (cmd) {
128 123
@@ -188,19 +183,15 @@ public:
188 } 183 }
189}; 184};
190 185
191class Directory : public Object { 186class Directory : public Kernel::Session {
192public: 187public:
193 std::string GetTypeName() const override { return "Directory"; } 188 std::string GetName() const override { return "Directory: " + path.DebugStr(); }
194 std::string GetName() const override { return path.DebugStr(); }
195
196 static Kernel::HandleType GetStaticHandleType() { return HandleType::Directory; }
197 Kernel::HandleType GetHandleType() const override { return HandleType::Directory; }
198 189
199 FileSys::Path path; ///< Path of the directory 190 FileSys::Path path; ///< Path of the directory
200 std::unique_ptr<FileSys::Directory> backend; ///< File backend interface 191 std::unique_ptr<FileSys::Directory> backend; ///< File backend interface
201 192
202 ResultVal<bool> SyncRequest() override { 193 ResultVal<bool> SyncRequest() override {
203 u32* cmd_buff = Service::GetCommandBuffer(); 194 u32* cmd_buff = Kernel::GetCommandBuffer();
204 DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]); 195 DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]);
205 switch (cmd) { 196 switch (cmd) {
206 197
@@ -230,7 +221,7 @@ public:
230 LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); 221 LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd);
231 ResultCode error = UnimplementedFunction(ErrorModule::FS); 222 ResultCode error = UnimplementedFunction(ErrorModule::FS);
232 cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. 223 cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that.
233 return error; 224 return MakeResult<bool>(false);
234 } 225 }
235 cmd_buff[1] = 0; // No error 226 cmd_buff[1] = 0; // No error
236 return MakeResult<bool>(false); 227 return MakeResult<bool>(false);
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 85e3264b9..7e0f15c84 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -22,7 +22,7 @@ enum KernelHandle {
22enum class HandleType : u32 { 22enum class HandleType : u32 {
23 Unknown = 0, 23 Unknown = 0,
24 Port = 1, 24 Port = 1,
25 Service = 2, 25 Session = 2,
26 Event = 3, 26 Event = 3,
27 Mutex = 4, 27 Mutex = 4,
28 SharedMemory = 5, 28 SharedMemory = 5,
@@ -30,10 +30,7 @@ enum class HandleType : u32 {
30 Thread = 7, 30 Thread = 7,
31 Process = 8, 31 Process = 8,
32 AddressArbiter = 9, 32 AddressArbiter = 9,
33 File = 10, 33 Semaphore = 10,
34 Semaphore = 11,
35 Archive = 12,
36 Directory = 13,
37}; 34};
38 35
39enum { 36enum {
@@ -53,15 +50,6 @@ public:
53 virtual Kernel::HandleType GetHandleType() const = 0; 50 virtual Kernel::HandleType GetHandleType() const = 0;
54 51
55 /** 52 /**
56 * Synchronize kernel object.
57 * @return True if the current thread should wait as a result of the sync
58 */
59 virtual ResultVal<bool> SyncRequest() {
60 LOG_ERROR(Kernel, "(UNIMPLEMENTED)");
61 return UnimplementedFunction(ErrorModule::Kernel);
62 }
63
64 /**
65 * Wait for kernel object to synchronize. 53 * Wait for kernel object to synchronize.
66 * @return True if the current thread should wait as a result of the wait 54 * @return True if the current thread should wait as a result of the wait
67 */ 55 */
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h
new file mode 100644
index 000000000..06ae4bc39
--- /dev/null
+++ b/src/core/hle/kernel/session.h
@@ -0,0 +1,58 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2+
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/kernel/kernel.h"
8
9namespace Kernel {
10
11static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header
12
13/**
14 * Returns a pointer to the command buffer in kernel memory
15 * @param offset Optional offset into command buffer
16 * @return Pointer to command buffer
17 */
18inline static u32* GetCommandBuffer(const int offset=0) {
19 return (u32*)Memory::GetPointer(Memory::KERNEL_MEMORY_VADDR + kCommandHeaderOffset + offset);
20}
21
22/**
23 * Kernel object representing the client endpoint of an IPC session. Sessions are the basic CTR-OS
24 * primitive for communication between different processes, and are used to implement service calls
25 * to the various system services.
26 *
27 * To make a service call, the client must write the command header and parameters to the buffer
28 * located at offset 0x80 of the TLS (Thread-Local Storage) area, then execute a SendSyncRequest
29 * SVC call with its Session handle. The kernel will read the command header, using it to marshall
30 * the parameters to the process at the server endpoint of the session. After the server replies to
31 * the request, the response is marshalled back to the caller's TLS buffer and control is
32 * transferred back to it.
33 *
34 * In Citra, only the client endpoint is currently implemented and only HLE calls, where the IPC
35 * request is answered by C++ code in the emulator, are supported. When SendSyncRequest is called
36 * with the session handle, this class's SyncRequest method is called, which should read the TLS
37 * buffer and emulate the call accordingly. Since the code can directly read the emulated memory,
38 * no parameter marshalling is done.
39 *
40 * In the long term, this should be turned into the full-fledged IPC mechanism implemented by
41 * CTR-OS so that IPC calls can be optionally handled by the real implementations of processes, as
42 * opposed to HLE simulations.
43 */
44class Session : public Object {
45public:
46 std::string GetTypeName() const override { return "Session"; }
47
48 static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Session; }
49 Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Session; }
50
51 /**
52 * Handles a synchronous call to this session using HLE emulation. Emulated <-> emulated calls
53 * aren't supported yet.
54 */
55 virtual ResultVal<bool> SyncRequest() = 0;
56};
57
58}
diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp
index 4130feb9d..311682abf 100644
--- a/src/core/hle/service/ac_u.cpp
+++ b/src/core/hle/service/ac_u.cpp
@@ -18,7 +18,7 @@ namespace AC_U {
18 * 2 : Output connection type, 0 = none, 1 = Old3DS Internet, 2 = New3DS Internet. 18 * 2 : Output connection type, 0 = none, 1 = Old3DS Internet, 2 = New3DS Internet.
19 */ 19 */
20void GetWifiStatus(Service::Interface* self) { 20void GetWifiStatus(Service::Interface* self) {
21 u32* cmd_buff = Service::GetCommandBuffer(); 21 u32* cmd_buff = Kernel::GetCommandBuffer();
22 22
23 // TODO(purpasmart96): This function is only a stub, 23 // TODO(purpasmart96): This function is only a stub,
24 // it returns a valid result without implementing full functionality. 24 // it returns a valid result without implementing full functionality.
diff --git a/src/core/hle/service/apt_u.cpp b/src/core/hle/service/apt_u.cpp
index b6d5d101f..ebfba4d8d 100644
--- a/src/core/hle/service/apt_u.cpp
+++ b/src/core/hle/service/apt_u.cpp
@@ -40,7 +40,7 @@ enum class SignalType : u32 {
40}; 40};
41 41
42void Initialize(Service::Interface* self) { 42void Initialize(Service::Interface* self) {
43 u32* cmd_buff = Service::GetCommandBuffer(); 43 u32* cmd_buff = Kernel::GetCommandBuffer();
44 44
45 cmd_buff[3] = Kernel::CreateEvent(RESETTYPE_ONESHOT, "APT_U:Menu"); // APT menu event handle 45 cmd_buff[3] = Kernel::CreateEvent(RESETTYPE_ONESHOT, "APT_U:Menu"); // APT menu event handle
46 cmd_buff[4] = Kernel::CreateEvent(RESETTYPE_ONESHOT, "APT_U:Pause"); // APT pause event handle 46 cmd_buff[4] = Kernel::CreateEvent(RESETTYPE_ONESHOT, "APT_U:Pause"); // APT pause event handle
@@ -57,7 +57,7 @@ void Initialize(Service::Interface* self) {
57} 57}
58 58
59void GetLockHandle(Service::Interface* self) { 59void GetLockHandle(Service::Interface* self) {
60 u32* cmd_buff = Service::GetCommandBuffer(); 60 u32* cmd_buff = Kernel::GetCommandBuffer();
61 u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field 61 u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field
62 62
63 if (0 == lock_handle) { 63 if (0 == lock_handle) {
@@ -78,14 +78,14 @@ void GetLockHandle(Service::Interface* self) {
78} 78}
79 79
80void Enable(Service::Interface* self) { 80void Enable(Service::Interface* self) {
81 u32* cmd_buff = Service::GetCommandBuffer(); 81 u32* cmd_buff = Kernel::GetCommandBuffer();
82 u32 unk = cmd_buff[1]; // TODO(bunnei): What is this field used for? 82 u32 unk = cmd_buff[1]; // TODO(bunnei): What is this field used for?
83 cmd_buff[1] = 0; // No error 83 cmd_buff[1] = 0; // No error
84 LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk); 84 LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk);
85} 85}
86 86
87void InquireNotification(Service::Interface* self) { 87void InquireNotification(Service::Interface* self) {
88 u32* cmd_buff = Service::GetCommandBuffer(); 88 u32* cmd_buff = Kernel::GetCommandBuffer();
89 u32 app_id = cmd_buff[2]; 89 u32 app_id = cmd_buff[2];
90 cmd_buff[1] = 0; // No error 90 cmd_buff[1] = 0; // No error
91 cmd_buff[2] = static_cast<u32>(SignalType::None); // Signal type 91 cmd_buff[2] = static_cast<u32>(SignalType::None); // Signal type
@@ -112,7 +112,7 @@ void InquireNotification(Service::Interface* self) {
112 * 8 : Output parameter buffer ptr 112 * 8 : Output parameter buffer ptr
113 */ 113 */
114void ReceiveParameter(Service::Interface* self) { 114void ReceiveParameter(Service::Interface* self) {
115 u32* cmd_buff = Service::GetCommandBuffer(); 115 u32* cmd_buff = Kernel::GetCommandBuffer();
116 u32 app_id = cmd_buff[1]; 116 u32 app_id = cmd_buff[1];
117 u32 buffer_size = cmd_buff[2]; 117 u32 buffer_size = cmd_buff[2];
118 cmd_buff[1] = 0; // No error 118 cmd_buff[1] = 0; // No error
@@ -143,7 +143,7 @@ void ReceiveParameter(Service::Interface* self) {
143 * 8 : Output parameter buffer ptr 143 * 8 : Output parameter buffer ptr
144 */ 144 */
145void GlanceParameter(Service::Interface* self) { 145void GlanceParameter(Service::Interface* self) {
146 u32* cmd_buff = Service::GetCommandBuffer(); 146 u32* cmd_buff = Kernel::GetCommandBuffer();
147 u32 app_id = cmd_buff[1]; 147 u32 app_id = cmd_buff[1];
148 u32 buffer_size = cmd_buff[2]; 148 u32 buffer_size = cmd_buff[2];
149 149
@@ -170,7 +170,7 @@ void GlanceParameter(Service::Interface* self) {
170 * 1 : Result of function, 0 on success, otherwise error code 170 * 1 : Result of function, 0 on success, otherwise error code
171 */ 171 */
172void AppletUtility(Service::Interface* self) { 172void AppletUtility(Service::Interface* self) {
173 u32* cmd_buff = Service::GetCommandBuffer(); 173 u32* cmd_buff = Kernel::GetCommandBuffer();
174 174
175 // These are from 3dbrew - I'm not really sure what they're used for. 175 // These are from 3dbrew - I'm not really sure what they're used for.
176 u32 unk = cmd_buff[1]; 176 u32 unk = cmd_buff[1];
@@ -196,7 +196,7 @@ void AppletUtility(Service::Interface* self) {
196void GetSharedFont(Service::Interface* self) { 196void GetSharedFont(Service::Interface* self) {
197 LOG_TRACE(Kernel_SVC, "called"); 197 LOG_TRACE(Kernel_SVC, "called");
198 198
199 u32* cmd_buff = Service::GetCommandBuffer(); 199 u32* cmd_buff = Kernel::GetCommandBuffer();
200 200
201 if (!shared_font.empty()) { 201 if (!shared_font.empty()) {
202 // TODO(bunnei): This function shouldn't copy the shared font every time it's called. 202 // TODO(bunnei): This function shouldn't copy the shared font every time it's called.
diff --git a/src/core/hle/service/cfg_u.cpp b/src/core/hle/service/cfg_u.cpp
index 972cc0534..2e9d7bf21 100644
--- a/src/core/hle/service/cfg_u.cpp
+++ b/src/core/hle/service/cfg_u.cpp
@@ -52,7 +52,7 @@ static const std::array<u16, 187> country_codes = {
52 * 2 : Country's 2-char string 52 * 2 : Country's 2-char string
53 */ 53 */
54static void GetCountryCodeString(Service::Interface* self) { 54static void GetCountryCodeString(Service::Interface* self) {
55 u32* cmd_buffer = Service::GetCommandBuffer(); 55 u32* cmd_buffer = Kernel::GetCommandBuffer();
56 u32 country_code_id = cmd_buffer[1]; 56 u32 country_code_id = cmd_buffer[1];
57 57
58 if (country_code_id >= country_codes.size() || 0 == country_codes[country_code_id]) { 58 if (country_code_id >= country_codes.size() || 0 == country_codes[country_code_id]) {
@@ -74,7 +74,7 @@ static void GetCountryCodeString(Service::Interface* self) {
74 * 2 : Country Code ID 74 * 2 : Country Code ID
75 */ 75 */
76static void GetCountryCodeID(Service::Interface* self) { 76static void GetCountryCodeID(Service::Interface* self) {
77 u32* cmd_buffer = Service::GetCommandBuffer(); 77 u32* cmd_buffer = Kernel::GetCommandBuffer();
78 u16 country_code = cmd_buffer[1]; 78 u16 country_code = cmd_buffer[1];
79 u16 country_code_id = 0; 79 u16 country_code_id = 0;
80 80
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp
index ce1c9938d..bd82063c6 100644
--- a/src/core/hle/service/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp_dsp.cpp
@@ -25,7 +25,7 @@ static Handle interrupt_event;
25 * 2 : (inaddr << 1) + 0x1FF40000 (where 0x1FF00000 is the DSP RAM address) 25 * 2 : (inaddr << 1) + 0x1FF40000 (where 0x1FF00000 is the DSP RAM address)
26 */ 26 */
27void ConvertProcessAddressFromDspDram(Service::Interface* self) { 27void ConvertProcessAddressFromDspDram(Service::Interface* self) {
28 u32* cmd_buff = Service::GetCommandBuffer(); 28 u32* cmd_buff = Kernel::GetCommandBuffer();
29 29
30 u32 addr = cmd_buff[1]; 30 u32 addr = cmd_buff[1];
31 31
@@ -48,7 +48,7 @@ void ConvertProcessAddressFromDspDram(Service::Interface* self) {
48 * 2 : Component loaded, 0 on not loaded, 1 on loaded 48 * 2 : Component loaded, 0 on not loaded, 1 on loaded
49 */ 49 */
50void LoadComponent(Service::Interface* self) { 50void LoadComponent(Service::Interface* self) {
51 u32* cmd_buff = Service::GetCommandBuffer(); 51 u32* cmd_buff = Kernel::GetCommandBuffer();
52 52
53 cmd_buff[1] = 0; // No error 53 cmd_buff[1] = 0; // No error
54 cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware 54 cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware
@@ -65,7 +65,7 @@ void LoadComponent(Service::Interface* self) {
65 * 3 : Semaphore event handle 65 * 3 : Semaphore event handle
66 */ 66 */
67void GetSemaphoreEventHandle(Service::Interface* self) { 67void GetSemaphoreEventHandle(Service::Interface* self) {
68 u32* cmd_buff = Service::GetCommandBuffer(); 68 u32* cmd_buff = Kernel::GetCommandBuffer();
69 69
70 cmd_buff[1] = 0; // No error 70 cmd_buff[1] = 0; // No error
71 cmd_buff[3] = semaphore_event; // Event handle 71 cmd_buff[3] = semaphore_event; // Event handle
@@ -83,7 +83,7 @@ void GetSemaphoreEventHandle(Service::Interface* self) {
83 * 1 : Result of function, 0 on success, otherwise error code 83 * 1 : Result of function, 0 on success, otherwise error code
84 */ 84 */
85void RegisterInterruptEvents(Service::Interface* self) { 85void RegisterInterruptEvents(Service::Interface* self) {
86 u32* cmd_buff = Service::GetCommandBuffer(); 86 u32* cmd_buff = Kernel::GetCommandBuffer();
87 87
88 interrupt_event = static_cast<Handle>(cmd_buff[4]); 88 interrupt_event = static_cast<Handle>(cmd_buff[4]);
89 89
@@ -100,7 +100,7 @@ void RegisterInterruptEvents(Service::Interface* self) {
100 * 1 : Result of function, 0 on success, otherwise error code 100 * 1 : Result of function, 0 on success, otherwise error code
101 */ 101 */
102void WriteReg0x10(Service::Interface* self) { 102void WriteReg0x10(Service::Interface* self) {
103 u32* cmd_buff = Service::GetCommandBuffer(); 103 u32* cmd_buff = Kernel::GetCommandBuffer();
104 104
105 Kernel::SignalEvent(interrupt_event); 105 Kernel::SignalEvent(interrupt_event);
106 106
@@ -121,7 +121,7 @@ void WriteReg0x10(Service::Interface* self) {
121 * 2 : Number of bytes read from pipe 121 * 2 : Number of bytes read from pipe
122 */ 122 */
123void ReadPipeIfPossible(Service::Interface* self) { 123void ReadPipeIfPossible(Service::Interface* self) {
124 u32* cmd_buff = Service::GetCommandBuffer(); 124 u32* cmd_buff = Kernel::GetCommandBuffer();
125 125
126 u32 size = cmd_buff[3] & 0xFFFF;// Lower 16 bits are size 126 u32 size = cmd_buff[3] & 0xFFFF;// Lower 16 bits are size
127 VAddr addr = cmd_buff[0x41]; 127 VAddr addr = cmd_buff[0x41];
diff --git a/src/core/hle/service/fs_user.cpp b/src/core/hle/service/fs_user.cpp
index 9bda4fe8a..672ba2475 100644
--- a/src/core/hle/service/fs_user.cpp
+++ b/src/core/hle/service/fs_user.cpp
@@ -17,7 +17,7 @@
17namespace FS_User { 17namespace FS_User {
18 18
19static void Initialize(Service::Interface* self) { 19static void Initialize(Service::Interface* self) {
20 u32* cmd_buff = Service::GetCommandBuffer(); 20 u32* cmd_buff = Kernel::GetCommandBuffer();
21 21
22 // TODO(Link Mauve): check the behavior when cmd_buff[1] isn't 32, as per 22 // TODO(Link Mauve): check the behavior when cmd_buff[1] isn't 32, as per
23 // http://3dbrew.org/wiki/FS:Initialize#Request 23 // http://3dbrew.org/wiki/FS:Initialize#Request
@@ -43,7 +43,7 @@ static void Initialize(Service::Interface* self) {
43 * 3 : File handle 43 * 3 : File handle
44 */ 44 */
45static void OpenFile(Service::Interface* self) { 45static void OpenFile(Service::Interface* self) {
46 u32* cmd_buff = Service::GetCommandBuffer(); 46 u32* cmd_buff = Kernel::GetCommandBuffer();
47 47
48 // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to 48 // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to
49 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. 49 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
@@ -86,7 +86,7 @@ static void OpenFile(Service::Interface* self) {
86 * 3 : File handle 86 * 3 : File handle
87 */ 87 */
88static void OpenFileDirectly(Service::Interface* self) { 88static void OpenFileDirectly(Service::Interface* self) {
89 u32* cmd_buff = Service::GetCommandBuffer(); 89 u32* cmd_buff = Kernel::GetCommandBuffer();
90 90
91 auto archive_id = static_cast<FileSys::Archive::IdCode>(cmd_buff[2]); 91 auto archive_id = static_cast<FileSys::Archive::IdCode>(cmd_buff[2]);
92 auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[3]); 92 auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[3]);
@@ -141,7 +141,7 @@ static void OpenFileDirectly(Service::Interface* self) {
141 * 1 : Result of function, 0 on success, otherwise error code 141 * 1 : Result of function, 0 on success, otherwise error code
142 */ 142 */
143void DeleteFile(Service::Interface* self) { 143void DeleteFile(Service::Interface* self) {
144 u32* cmd_buff = Service::GetCommandBuffer(); 144 u32* cmd_buff = Kernel::GetCommandBuffer();
145 145
146 // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to 146 // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to
147 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. 147 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
@@ -175,7 +175,7 @@ void DeleteFile(Service::Interface* self) {
175 * 1 : Result of function, 0 on success, otherwise error code 175 * 1 : Result of function, 0 on success, otherwise error code
176 */ 176 */
177void RenameFile(Service::Interface* self) { 177void RenameFile(Service::Interface* self) {
178 u32* cmd_buff = Service::GetCommandBuffer(); 178 u32* cmd_buff = Kernel::GetCommandBuffer();
179 179
180 // TODO(Link Mauve): cmd_buff[2] and cmd_buff[6], aka archive handle lower word, aren't used according to 180 // TODO(Link Mauve): cmd_buff[2] and cmd_buff[6], aka archive handle lower word, aren't used according to
181 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. 181 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
@@ -210,7 +210,7 @@ void RenameFile(Service::Interface* self) {
210 * 1 : Result of function, 0 on success, otherwise error code 210 * 1 : Result of function, 0 on success, otherwise error code
211 */ 211 */
212void DeleteDirectory(Service::Interface* self) { 212void DeleteDirectory(Service::Interface* self) {
213 u32* cmd_buff = Service::GetCommandBuffer(); 213 u32* cmd_buff = Kernel::GetCommandBuffer();
214 214
215 // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to 215 // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to
216 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. 216 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
@@ -239,7 +239,7 @@ void DeleteDirectory(Service::Interface* self) {
239 * 1 : Result of function, 0 on success, otherwise error code 239 * 1 : Result of function, 0 on success, otherwise error code
240 */ 240 */
241static void CreateDirectory(Service::Interface* self) { 241static void CreateDirectory(Service::Interface* self) {
242 u32* cmd_buff = Service::GetCommandBuffer(); 242 u32* cmd_buff = Kernel::GetCommandBuffer();
243 243
244 // TODO: cmd_buff[2], aka archive handle lower word, isn't used according to 244 // TODO: cmd_buff[2], aka archive handle lower word, isn't used according to
245 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. 245 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
@@ -272,7 +272,7 @@ static void CreateDirectory(Service::Interface* self) {
272 * 1 : Result of function, 0 on success, otherwise error code 272 * 1 : Result of function, 0 on success, otherwise error code
273 */ 273 */
274void RenameDirectory(Service::Interface* self) { 274void RenameDirectory(Service::Interface* self) {
275 u32* cmd_buff = Service::GetCommandBuffer(); 275 u32* cmd_buff = Kernel::GetCommandBuffer();
276 276
277 // TODO(Link Mauve): cmd_buff[2] and cmd_buff[6], aka archive handle lower word, aren't used according to 277 // TODO(Link Mauve): cmd_buff[2] and cmd_buff[6], aka archive handle lower word, aren't used according to
278 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. 278 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
@@ -296,7 +296,7 @@ void RenameDirectory(Service::Interface* self) {
296} 296}
297 297
298static void OpenDirectory(Service::Interface* self) { 298static void OpenDirectory(Service::Interface* self) {
299 u32* cmd_buff = Service::GetCommandBuffer(); 299 u32* cmd_buff = Kernel::GetCommandBuffer();
300 300
301 // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to 301 // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to
302 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. 302 // 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
@@ -332,7 +332,7 @@ static void OpenDirectory(Service::Interface* self) {
332 * 3 : Archive handle upper word (same as file handle) 332 * 3 : Archive handle upper word (same as file handle)
333 */ 333 */
334static void OpenArchive(Service::Interface* self) { 334static void OpenArchive(Service::Interface* self) {
335 u32* cmd_buff = Service::GetCommandBuffer(); 335 u32* cmd_buff = Kernel::GetCommandBuffer();
336 336
337 auto archive_id = static_cast<FileSys::Archive::IdCode>(cmd_buff[1]); 337 auto archive_id = static_cast<FileSys::Archive::IdCode>(cmd_buff[1]);
338 auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[2]); 338 auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[2]);
@@ -365,7 +365,7 @@ static void OpenArchive(Service::Interface* self) {
365* 2 : Whether the Sdmc could be detected 365* 2 : Whether the Sdmc could be detected
366*/ 366*/
367static void IsSdmcDetected(Service::Interface* self) { 367static void IsSdmcDetected(Service::Interface* self) {
368 u32* cmd_buff = Service::GetCommandBuffer(); 368 u32* cmd_buff = Kernel::GetCommandBuffer();
369 369
370 cmd_buff[1] = 0; 370 cmd_buff[1] = 0;
371 cmd_buff[2] = Settings::values.use_virtual_sd ? 1 : 0; 371 cmd_buff[2] = Settings::values.use_virtual_sd ? 1 : 0;
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index 223800560..db8027142 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -72,7 +72,7 @@ static void WriteHWRegs(u32 base_address, u32 size_in_bytes, const u32* data) {
72 72
73/// Write a GSP GPU hardware register 73/// Write a GSP GPU hardware register
74static void WriteHWRegs(Service::Interface* self) { 74static void WriteHWRegs(Service::Interface* self) {
75 u32* cmd_buff = Service::GetCommandBuffer(); 75 u32* cmd_buff = Kernel::GetCommandBuffer();
76 u32 reg_addr = cmd_buff[1]; 76 u32 reg_addr = cmd_buff[1];
77 u32 size = cmd_buff[2]; 77 u32 size = cmd_buff[2];
78 78
@@ -83,7 +83,7 @@ static void WriteHWRegs(Service::Interface* self) {
83 83
84/// Read a GSP GPU hardware register 84/// Read a GSP GPU hardware register
85static void ReadHWRegs(Service::Interface* self) { 85static void ReadHWRegs(Service::Interface* self) {
86 u32* cmd_buff = Service::GetCommandBuffer(); 86 u32* cmd_buff = Kernel::GetCommandBuffer();
87 u32 reg_addr = cmd_buff[1]; 87 u32 reg_addr = cmd_buff[1];
88 u32 size = cmd_buff[2]; 88 u32 size = cmd_buff[2];
89 89
@@ -136,7 +136,7 @@ static void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) {
136 * 1: Result code 136 * 1: Result code
137 */ 137 */
138static void SetBufferSwap(Service::Interface* self) { 138static void SetBufferSwap(Service::Interface* self) {
139 u32* cmd_buff = Service::GetCommandBuffer(); 139 u32* cmd_buff = Kernel::GetCommandBuffer();
140 u32 screen_id = cmd_buff[1]; 140 u32 screen_id = cmd_buff[1];
141 FrameBufferInfo* fb_info = (FrameBufferInfo*)&cmd_buff[2]; 141 FrameBufferInfo* fb_info = (FrameBufferInfo*)&cmd_buff[2];
142 SetBufferSwap(screen_id, *fb_info); 142 SetBufferSwap(screen_id, *fb_info);
@@ -155,7 +155,7 @@ static void SetBufferSwap(Service::Interface* self) {
155 * 4 : Handle to GSP shared memory 155 * 4 : Handle to GSP shared memory
156 */ 156 */
157static void RegisterInterruptRelayQueue(Service::Interface* self) { 157static void RegisterInterruptRelayQueue(Service::Interface* self) {
158 u32* cmd_buff = Service::GetCommandBuffer(); 158 u32* cmd_buff = Kernel::GetCommandBuffer();
159 u32 flags = cmd_buff[1]; 159 u32 flags = cmd_buff[1];
160 g_interrupt_event = cmd_buff[3]; 160 g_interrupt_event = cmd_buff[3];
161 g_shared_memory = Kernel::CreateSharedMemory("GSPSharedMem"); 161 g_shared_memory = Kernel::CreateSharedMemory("GSPSharedMem");
@@ -323,7 +323,7 @@ static void TriggerCmdReqQueue(Service::Interface* self) {
323 } 323 }
324 } 324 }
325 325
326 u32* cmd_buff = Service::GetCommandBuffer(); 326 u32* cmd_buff = Kernel::GetCommandBuffer();
327 cmd_buff[1] = 0; // No error 327 cmd_buff[1] = 0; // No error
328} 328}
329 329
diff --git a/src/core/hle/service/hid_user.cpp b/src/core/hle/service/hid_user.cpp
index 5772199d4..eb2d35964 100644
--- a/src/core/hle/service/hid_user.cpp
+++ b/src/core/hle/service/hid_user.cpp
@@ -153,7 +153,7 @@ void PadUpdateComplete() {
153 * 8 : Event signaled by HID_User 153 * 8 : Event signaled by HID_User
154 */ 154 */
155static void GetIPCHandles(Service::Interface* self) { 155static void GetIPCHandles(Service::Interface* self) {
156 u32* cmd_buff = Service::GetCommandBuffer(); 156 u32* cmd_buff = Kernel::GetCommandBuffer();
157 157
158 cmd_buff[1] = 0; // No error 158 cmd_buff[1] = 0; // No error
159 cmd_buff[3] = shared_mem; 159 cmd_buff[3] = shared_mem;
diff --git a/src/core/hle/service/ptm_u.cpp b/src/core/hle/service/ptm_u.cpp
index 559f148dd..b8c0f6da8 100644
--- a/src/core/hle/service/ptm_u.cpp
+++ b/src/core/hle/service/ptm_u.cpp
@@ -34,7 +34,7 @@ static bool battery_is_charging = true;
34 * 2 : Output of function, 0 = not charging, 1 = charging. 34 * 2 : Output of function, 0 = not charging, 1 = charging.
35 */ 35 */
36static void GetAdapterState(Service::Interface* self) { 36static void GetAdapterState(Service::Interface* self) {
37 u32* cmd_buff = Service::GetCommandBuffer(); 37 u32* cmd_buff = Kernel::GetCommandBuffer();
38 38
39 // TODO(purpasmart96): This function is only a stub, 39 // TODO(purpasmart96): This function is only a stub,
40 // it returns a valid result without implementing full functionality. 40 // it returns a valid result without implementing full functionality.
@@ -52,7 +52,7 @@ static void GetAdapterState(Service::Interface* self) {
52 * 2 : Whether the 3DS's physical shell casing is open (1) or closed (0) 52 * 2 : Whether the 3DS's physical shell casing is open (1) or closed (0)
53 */ 53 */
54static void GetShellState(Service::Interface* self) { 54static void GetShellState(Service::Interface* self) {
55 u32* cmd_buff = Service::GetCommandBuffer(); 55 u32* cmd_buff = Kernel::GetCommandBuffer();
56 56
57 cmd_buff[1] = 0; 57 cmd_buff[1] = 0;
58 cmd_buff[2] = shell_open ? 1 : 0; 58 cmd_buff[2] = shell_open ? 1 : 0;
@@ -68,7 +68,7 @@ static void GetShellState(Service::Interface* self) {
68 * 3 = half full battery, 2 = low battery, 1 = critical battery. 68 * 3 = half full battery, 2 = low battery, 1 = critical battery.
69 */ 69 */
70static void GetBatteryLevel(Service::Interface* self) { 70static void GetBatteryLevel(Service::Interface* self) {
71 u32* cmd_buff = Service::GetCommandBuffer(); 71 u32* cmd_buff = Kernel::GetCommandBuffer();
72 72
73 // TODO(purpasmart96): This function is only a stub, 73 // TODO(purpasmart96): This function is only a stub,
74 // it returns a valid result without implementing full functionality. 74 // it returns a valid result without implementing full functionality.
@@ -86,7 +86,7 @@ static void GetBatteryLevel(Service::Interface* self) {
86 * 2 : Output of function, 0 = not charging, 1 = charging. 86 * 2 : Output of function, 0 = not charging, 1 = charging.
87 */ 87 */
88static void GetBatteryChargeState(Service::Interface* self) { 88static void GetBatteryChargeState(Service::Interface* self) {
89 u32* cmd_buff = Service::GetCommandBuffer(); 89 u32* cmd_buff = Kernel::GetCommandBuffer();
90 90
91 // TODO(purpasmart96): This function is only a stub, 91 // TODO(purpasmart96): This function is only a stub,
92 // it returns a valid result without implementing full functionality. 92 // it returns a valid result without implementing full functionality.
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index baae910a1..9cd906150 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -14,6 +14,7 @@
14#include "core/mem_map.h" 14#include "core/mem_map.h"
15 15
16#include "core/hle/kernel/kernel.h" 16#include "core/hle/kernel/kernel.h"
17#include "core/hle/kernel/session.h"
17#include "core/hle/svc.h" 18#include "core/hle/svc.h"
18 19
19//////////////////////////////////////////////////////////////////////////////////////////////////// 20////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -21,30 +22,19 @@
21 22
22namespace Service { 23namespace Service {
23 24
24static const int kMaxPortSize = 0x08; ///< Maximum size of a port name (8 characters) 25static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 characters)
25static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header
26
27/**
28 * Returns a pointer to the command buffer in kernel memory
29 * @param offset Optional offset into command buffer
30 * @return Pointer to command buffer
31 */
32inline static u32* GetCommandBuffer(const int offset=0) {
33 return (u32*)Memory::GetPointer(Memory::KERNEL_MEMORY_VADDR + kCommandHeaderOffset + offset);
34}
35 26
36class Manager; 27class Manager;
37 28
38/// Interface to a CTROS service 29/// Interface to a CTROS service
39class Interface : public Kernel::Object { 30class Interface : public Kernel::Session {
31 // TODO(yuriks): An "Interface" being a Kernel::Object is mostly non-sense. Interface should be
32 // just something that encapsulates a session and acts as a helper to implement service
33 // processes.
34
40 friend class Manager; 35 friend class Manager;
41public: 36public:
42
43 std::string GetName() const override { return GetPortName(); } 37 std::string GetName() const override { return GetPortName(); }
44 std::string GetTypeName() const override { return GetPortName(); }
45
46 static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Service; }
47 Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Service; }
48 38
49 typedef void (*Function)(Interface*); 39 typedef void (*Function)(Interface*);
50 40
@@ -77,7 +67,7 @@ public:
77 } 67 }
78 68
79 ResultVal<bool> SyncRequest() override { 69 ResultVal<bool> SyncRequest() override {
80 u32* cmd_buff = GetCommandBuffer(); 70 u32* cmd_buff = Kernel::GetCommandBuffer();
81 auto itr = m_functions.find(cmd_buff[0]); 71 auto itr = m_functions.find(cmd_buff[0]);
82 72
83 if (itr == m_functions.end() || itr->second.func == nullptr) { 73 if (itr == m_functions.end() || itr->second.func == nullptr) {
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp
index 24a846533..165fd7aac 100644
--- a/src/core/hle/service/srv.cpp
+++ b/src/core/hle/service/srv.cpp
@@ -16,7 +16,7 @@ static Handle g_event_handle = 0;
16static void Initialize(Service::Interface* self) { 16static void Initialize(Service::Interface* self) {
17 LOG_DEBUG(Service_SRV, "called"); 17 LOG_DEBUG(Service_SRV, "called");
18 18
19 u32* cmd_buff = Service::GetCommandBuffer(); 19 u32* cmd_buff = Kernel::GetCommandBuffer();
20 20
21 cmd_buff[1] = 0; // No error 21 cmd_buff[1] = 0; // No error
22} 22}
@@ -24,7 +24,7 @@ static void Initialize(Service::Interface* self) {
24static void GetProcSemaphore(Service::Interface* self) { 24static void GetProcSemaphore(Service::Interface* self) {
25 LOG_TRACE(Service_SRV, "called"); 25 LOG_TRACE(Service_SRV, "called");
26 26
27 u32* cmd_buff = Service::GetCommandBuffer(); 27 u32* cmd_buff = Kernel::GetCommandBuffer();
28 28
29 // TODO(bunnei): Change to a semaphore once these have been implemented 29 // TODO(bunnei): Change to a semaphore once these have been implemented
30 g_event_handle = Kernel::CreateEvent(RESETTYPE_ONESHOT, "SRV:Event"); 30 g_event_handle = Kernel::CreateEvent(RESETTYPE_ONESHOT, "SRV:Event");
@@ -36,7 +36,7 @@ static void GetProcSemaphore(Service::Interface* self) {
36 36
37static void GetServiceHandle(Service::Interface* self) { 37static void GetServiceHandle(Service::Interface* self) {
38 ResultCode res = RESULT_SUCCESS; 38 ResultCode res = RESULT_SUCCESS;
39 u32* cmd_buff = Service::GetCommandBuffer(); 39 u32* cmd_buff = Kernel::GetCommandBuffer();
40 40
41 std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize); 41 std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize);
42 Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); 42 Service::Interface* service = Service::g_manager->FetchFromPortName(port_name);
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index f3595096e..15cc240f4 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -88,17 +88,14 @@ static Result ConnectToPort(Handle* out, const char* port_name) {
88 88
89/// Synchronize to an OS service 89/// Synchronize to an OS service
90static Result SendSyncRequest(Handle handle) { 90static Result SendSyncRequest(Handle handle) {
91 // TODO(yuriks): ObjectPool::Get tries to check the Object type, which fails since this is a generic base Object, 91 Kernel::Session* session = Kernel::g_object_pool.Get<Kernel::Session>(handle);
92 // so we are forced to use GetFast and manually verify the handle. 92 if (session == nullptr) {
93 if (!Kernel::g_object_pool.IsValid(handle)) {
94 return InvalidHandle(ErrorModule::Kernel).raw; 93 return InvalidHandle(ErrorModule::Kernel).raw;
95 } 94 }
96 Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handle);
97 95
98 _assert_msg_(KERNEL, (object != nullptr), "called, but kernel object is nullptr!"); 96 LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s)", handle, session->GetName().c_str());
99 LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s)", handle, object->GetTypeName().c_str());
100 97
101 ResultVal<bool> wait = object->SyncRequest(); 98 ResultVal<bool> wait = session->SyncRequest();
102 if (wait.Succeeded() && *wait) { 99 if (wait.Succeeded() && *wait) {
103 Kernel::WaitCurrentThread(WAITTYPE_SYNCH); // TODO(bunnei): Is this correct? 100 Kernel::WaitCurrentThread(WAITTYPE_SYNCH); // TODO(bunnei): Is this correct?
104 } 101 }