summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2014-12-14 03:30:11 -0200
committerGravatar Yuri Kunde Schlesner2014-12-15 18:26:17 -0200
commite321decf98a6b0041e4d6b30ca79f24308bbb82c (patch)
tree5d458d4768cd95942154f1b2c9298fac04882700 /src/core/hle/kernel
parentMerge pull request #276 from lioncash/decrappify (diff)
downloadyuzu-e321decf98a6b0041e4d6b30ca79f24308bbb82c.tar.gz
yuzu-e321decf98a6b0041e4d6b30ca79f24308bbb82c.tar.xz
yuzu-e321decf98a6b0041e4d6b30ca79f24308bbb82c.zip
Remove SyncRequest from K::Object and create a new K::Session type
This is a first step at fixing the conceptual insanity that is our handling of service and IPC calls. For now, interfaces still directly derived from Session because we don't have the infrastructure to do it properly. (That is, Processes and scheduling them.)
Diffstat (limited to 'src/core/hle/kernel')
-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
3 files changed, 75 insertions, 38 deletions
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}