summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/arm/interpreter/armemu.cpp24
-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
16 files changed, 141 insertions, 116 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index dcbe12a89..5306d957c 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -112,6 +112,7 @@ set(HEADERS
hle/kernel/kernel.h
hle/kernel/mutex.h
hle/kernel/semaphore.h
+ hle/kernel/session.h
hle/kernel/shared_memory.h
hle/kernel/thread.h
hle/service/ac_u.h
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index ec40881f8..33ebc7986 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -6101,18 +6101,18 @@ L_stm_s_takeabort:
return 1;
}
- case 0x6c:
- if ((instr & 0xf03f0) == 0xf0070) { //uxtb16
- u8 src1 = BITS(0, 3);
- u8 tar = BITS(12, 15);
- u32 base = state->Reg[src1];
- u32 shamt = BITS(9,10)* 8;
- u32 in = ((base << (32 - shamt)) | (base >> shamt));
- state->Reg[tar] = in & 0x00FF00FF;
- return 1;
- } else
- printf ("Unhandled v6 insn: uxtab16\n");
- break;
+ case 0x6c:
+ if ((instr & 0xf03f0) == 0xf0070) { //uxtb16
+ u8 rm_idx = BITS(0, 3);
+ u8 rd_idx = BITS(12, 15);
+ u32 rm_val = state->Reg[rm_idx];
+ u32 rotation = BITS(10, 11) * 8;
+ u32 in = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
+ state->Reg[rd_idx] = in & 0x00FF00FF;
+ return 1;
+ } else
+ printf ("Unhandled v6 insn: uxtab16\n");
+ break;
case 0x6e: {
ARMword Rm;
int ror = -1;
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 @@
// Licensed under GPLv2
// Refer to the license.txt file included.
+#include <map>
+
#include "common/common_types.h"
#include "common/file_util.h"
#include "common/math_util.h"
@@ -10,8 +12,8 @@
#include "core/file_sys/archive_sdmc.h"
#include "core/file_sys/directory.h"
#include "core/hle/kernel/archive.h"
+#include "core/hle/kernel/session.h"
#include "core/hle/result.h"
-#include "core/hle/service/service.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// Kernel namespace
@@ -41,19 +43,15 @@ enum class DirectoryCommand : u32 {
Close = 0x08020000,
};
-class Archive : public Object {
+class Archive : public Kernel::Session {
public:
- std::string GetTypeName() const override { return "Archive"; }
- std::string GetName() const override { return name; }
-
- static Kernel::HandleType GetStaticHandleType() { return HandleType::Archive; }
- Kernel::HandleType GetHandleType() const override { return HandleType::Archive; }
+ std::string GetName() const override { return "Archive: " + name; }
std::string name; ///< Name of archive (optional)
FileSys::Archive* backend; ///< Archive backend interface
ResultVal<bool> SyncRequest() override {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]);
switch (cmd) {
@@ -102,7 +100,8 @@ public:
default:
{
LOG_ERROR(Service_FS, "Unknown command=0x%08X", cmd);
- return UnimplementedFunction(ErrorModule::FS);
+ cmd_buff[0] = UnimplementedFunction(ErrorModule::FS).raw;
+ return MakeResult<bool>(false);
}
}
cmd_buff[1] = 0; // No error
@@ -110,19 +109,15 @@ public:
}
};
-class File : public Object {
+class File : public Kernel::Session {
public:
- std::string GetTypeName() const override { return "File"; }
- std::string GetName() const override { return path.DebugStr(); }
-
- static Kernel::HandleType GetStaticHandleType() { return HandleType::File; }
- Kernel::HandleType GetHandleType() const override { return HandleType::File; }
+ std::string GetName() const override { return "Path: " + path.DebugStr(); }
FileSys::Path path; ///< Path of the file
std::unique_ptr<FileSys::File> backend; ///< File backend interface
ResultVal<bool> SyncRequest() override {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]);
switch (cmd) {
@@ -188,19 +183,15 @@ public:
}
};
-class Directory : public Object {
+class Directory : public Kernel::Session {
public:
- std::string GetTypeName() const override { return "Directory"; }
- std::string GetName() const override { return path.DebugStr(); }
-
- static Kernel::HandleType GetStaticHandleType() { return HandleType::Directory; }
- Kernel::HandleType GetHandleType() const override { return HandleType::Directory; }
+ std::string GetName() const override { return "Directory: " + path.DebugStr(); }
FileSys::Path path; ///< Path of the directory
std::unique_ptr<FileSys::Directory> backend; ///< File backend interface
ResultVal<bool> SyncRequest() override {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]);
switch (cmd) {
@@ -230,7 +221,7 @@ public:
LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd);
ResultCode error = UnimplementedFunction(ErrorModule::FS);
cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that.
- return error;
+ return MakeResult<bool>(false);
}
cmd_buff[1] = 0; // No error
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 {
enum class HandleType : u32 {
Unknown = 0,
Port = 1,
- Service = 2,
+ Session = 2,
Event = 3,
Mutex = 4,
SharedMemory = 5,
@@ -30,10 +30,7 @@ enum class HandleType : u32 {
Thread = 7,
Process = 8,
AddressArbiter = 9,
- File = 10,
- Semaphore = 11,
- Archive = 12,
- Directory = 13,
+ Semaphore = 10,
};
enum {
@@ -53,15 +50,6 @@ public:
virtual Kernel::HandleType GetHandleType() const = 0;
/**
- * Synchronize kernel object.
- * @return True if the current thread should wait as a result of the sync
- */
- virtual ResultVal<bool> SyncRequest() {
- LOG_ERROR(Kernel, "(UNIMPLEMENTED)");
- return UnimplementedFunction(ErrorModule::Kernel);
- }
-
- /**
* Wait for kernel object to synchronize.
* @return True if the current thread should wait as a result of the wait
*/
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 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/kernel/kernel.h"
+
+namespace Kernel {
+
+static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header
+
+/**
+ * Returns a pointer to the command buffer in kernel memory
+ * @param offset Optional offset into command buffer
+ * @return Pointer to command buffer
+ */
+inline static u32* GetCommandBuffer(const int offset=0) {
+ return (u32*)Memory::GetPointer(Memory::KERNEL_MEMORY_VADDR + kCommandHeaderOffset + offset);
+}
+
+/**
+ * Kernel object representing the client endpoint of an IPC session. Sessions are the basic CTR-OS
+ * primitive for communication between different processes, and are used to implement service calls
+ * to the various system services.
+ *
+ * To make a service call, the client must write the command header and parameters to the buffer
+ * located at offset 0x80 of the TLS (Thread-Local Storage) area, then execute a SendSyncRequest
+ * SVC call with its Session handle. The kernel will read the command header, using it to marshall
+ * the parameters to the process at the server endpoint of the session. After the server replies to
+ * the request, the response is marshalled back to the caller's TLS buffer and control is
+ * transferred back to it.
+ *
+ * In Citra, only the client endpoint is currently implemented and only HLE calls, where the IPC
+ * request is answered by C++ code in the emulator, are supported. When SendSyncRequest is called
+ * with the session handle, this class's SyncRequest method is called, which should read the TLS
+ * buffer and emulate the call accordingly. Since the code can directly read the emulated memory,
+ * no parameter marshalling is done.
+ *
+ * In the long term, this should be turned into the full-fledged IPC mechanism implemented by
+ * CTR-OS so that IPC calls can be optionally handled by the real implementations of processes, as
+ * opposed to HLE simulations.
+ */
+class Session : public Object {
+public:
+ std::string GetTypeName() const override { return "Session"; }
+
+ static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Session; }
+ Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Session; }
+
+ /**
+ * Handles a synchronous call to this session using HLE emulation. Emulated <-> emulated calls
+ * aren't supported yet.
+ */
+ virtual ResultVal<bool> SyncRequest() = 0;
+};
+
+}
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 {
* 2 : Output connection type, 0 = none, 1 = Old3DS Internet, 2 = New3DS Internet.
*/
void GetWifiStatus(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO(purpasmart96): This function is only a stub,
// 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 {
};
void Initialize(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
cmd_buff[3] = Kernel::CreateEvent(RESETTYPE_ONESHOT, "APT_U:Menu"); // APT menu event handle
cmd_buff[4] = Kernel::CreateEvent(RESETTYPE_ONESHOT, "APT_U:Pause"); // APT pause event handle
@@ -57,7 +57,7 @@ void Initialize(Service::Interface* self) {
}
void GetLockHandle(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field
if (0 == lock_handle) {
@@ -78,14 +78,14 @@ void GetLockHandle(Service::Interface* self) {
}
void Enable(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
u32 unk = cmd_buff[1]; // TODO(bunnei): What is this field used for?
cmd_buff[1] = 0; // No error
LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk);
}
void InquireNotification(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
u32 app_id = cmd_buff[2];
cmd_buff[1] = 0; // No error
cmd_buff[2] = static_cast<u32>(SignalType::None); // Signal type
@@ -112,7 +112,7 @@ void InquireNotification(Service::Interface* self) {
* 8 : Output parameter buffer ptr
*/
void ReceiveParameter(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
u32 app_id = cmd_buff[1];
u32 buffer_size = cmd_buff[2];
cmd_buff[1] = 0; // No error
@@ -143,7 +143,7 @@ void ReceiveParameter(Service::Interface* self) {
* 8 : Output parameter buffer ptr
*/
void GlanceParameter(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
u32 app_id = cmd_buff[1];
u32 buffer_size = cmd_buff[2];
@@ -170,7 +170,7 @@ void GlanceParameter(Service::Interface* self) {
* 1 : Result of function, 0 on success, otherwise error code
*/
void AppletUtility(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
// These are from 3dbrew - I'm not really sure what they're used for.
u32 unk = cmd_buff[1];
@@ -196,7 +196,7 @@ void AppletUtility(Service::Interface* self) {
void GetSharedFont(Service::Interface* self) {
LOG_TRACE(Kernel_SVC, "called");
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
if (!shared_font.empty()) {
// 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 = {
* 2 : Country's 2-char string
*/
static void GetCountryCodeString(Service::Interface* self) {
- u32* cmd_buffer = Service::GetCommandBuffer();
+ u32* cmd_buffer = Kernel::GetCommandBuffer();
u32 country_code_id = cmd_buffer[1];
if (country_code_id >= country_codes.size() || 0 == country_codes[country_code_id]) {
@@ -74,7 +74,7 @@ static void GetCountryCodeString(Service::Interface* self) {
* 2 : Country Code ID
*/
static void GetCountryCodeID(Service::Interface* self) {
- u32* cmd_buffer = Service::GetCommandBuffer();
+ u32* cmd_buffer = Kernel::GetCommandBuffer();
u16 country_code = cmd_buffer[1];
u16 country_code_id = 0;
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;
* 2 : (inaddr << 1) + 0x1FF40000 (where 0x1FF00000 is the DSP RAM address)
*/
void ConvertProcessAddressFromDspDram(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
u32 addr = cmd_buff[1];
@@ -48,7 +48,7 @@ void ConvertProcessAddressFromDspDram(Service::Interface* self) {
* 2 : Component loaded, 0 on not loaded, 1 on loaded
*/
void LoadComponent(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
cmd_buff[1] = 0; // No error
cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware
@@ -65,7 +65,7 @@ void LoadComponent(Service::Interface* self) {
* 3 : Semaphore event handle
*/
void GetSemaphoreEventHandle(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
cmd_buff[1] = 0; // No error
cmd_buff[3] = semaphore_event; // Event handle
@@ -83,7 +83,7 @@ void GetSemaphoreEventHandle(Service::Interface* self) {
* 1 : Result of function, 0 on success, otherwise error code
*/
void RegisterInterruptEvents(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
interrupt_event = static_cast<Handle>(cmd_buff[4]);
@@ -100,7 +100,7 @@ void RegisterInterruptEvents(Service::Interface* self) {
* 1 : Result of function, 0 on success, otherwise error code
*/
void WriteReg0x10(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
Kernel::SignalEvent(interrupt_event);
@@ -121,7 +121,7 @@ void WriteReg0x10(Service::Interface* self) {
* 2 : Number of bytes read from pipe
*/
void ReadPipeIfPossible(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
u32 size = cmd_buff[3] & 0xFFFF;// Lower 16 bits are size
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 @@
namespace FS_User {
static void Initialize(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO(Link Mauve): check the behavior when cmd_buff[1] isn't 32, as per
// http://3dbrew.org/wiki/FS:Initialize#Request
@@ -43,7 +43,7 @@ static void Initialize(Service::Interface* self) {
* 3 : File handle
*/
static void OpenFile(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to
// 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
@@ -86,7 +86,7 @@ static void OpenFile(Service::Interface* self) {
* 3 : File handle
*/
static void OpenFileDirectly(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
auto archive_id = static_cast<FileSys::Archive::IdCode>(cmd_buff[2]);
auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[3]);
@@ -141,7 +141,7 @@ static void OpenFileDirectly(Service::Interface* self) {
* 1 : Result of function, 0 on success, otherwise error code
*/
void DeleteFile(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to
// 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
@@ -175,7 +175,7 @@ void DeleteFile(Service::Interface* self) {
* 1 : Result of function, 0 on success, otherwise error code
*/
void RenameFile(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO(Link Mauve): cmd_buff[2] and cmd_buff[6], aka archive handle lower word, aren't used according to
// 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
@@ -210,7 +210,7 @@ void RenameFile(Service::Interface* self) {
* 1 : Result of function, 0 on success, otherwise error code
*/
void DeleteDirectory(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to
// 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
@@ -239,7 +239,7 @@ void DeleteDirectory(Service::Interface* self) {
* 1 : Result of function, 0 on success, otherwise error code
*/
static void CreateDirectory(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO: cmd_buff[2], aka archive handle lower word, isn't used according to
// 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
@@ -272,7 +272,7 @@ static void CreateDirectory(Service::Interface* self) {
* 1 : Result of function, 0 on success, otherwise error code
*/
void RenameDirectory(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO(Link Mauve): cmd_buff[2] and cmd_buff[6], aka archive handle lower word, aren't used according to
// 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
@@ -296,7 +296,7 @@ void RenameDirectory(Service::Interface* self) {
}
static void OpenDirectory(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to
// 3dmoo's or ctrulib's implementations. Triple check if it's really the case.
@@ -332,7 +332,7 @@ static void OpenDirectory(Service::Interface* self) {
* 3 : Archive handle upper word (same as file handle)
*/
static void OpenArchive(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
auto archive_id = static_cast<FileSys::Archive::IdCode>(cmd_buff[1]);
auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[2]);
@@ -365,7 +365,7 @@ static void OpenArchive(Service::Interface* self) {
* 2 : Whether the Sdmc could be detected
*/
static void IsSdmcDetected(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
cmd_buff[1] = 0;
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) {
/// Write a GSP GPU hardware register
static void WriteHWRegs(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
u32 reg_addr = cmd_buff[1];
u32 size = cmd_buff[2];
@@ -83,7 +83,7 @@ static void WriteHWRegs(Service::Interface* self) {
/// Read a GSP GPU hardware register
static void ReadHWRegs(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
u32 reg_addr = cmd_buff[1];
u32 size = cmd_buff[2];
@@ -136,7 +136,7 @@ static void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) {
* 1: Result code
*/
static void SetBufferSwap(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
u32 screen_id = cmd_buff[1];
FrameBufferInfo* fb_info = (FrameBufferInfo*)&cmd_buff[2];
SetBufferSwap(screen_id, *fb_info);
@@ -155,7 +155,7 @@ static void SetBufferSwap(Service::Interface* self) {
* 4 : Handle to GSP shared memory
*/
static void RegisterInterruptRelayQueue(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
u32 flags = cmd_buff[1];
g_interrupt_event = cmd_buff[3];
g_shared_memory = Kernel::CreateSharedMemory("GSPSharedMem");
@@ -323,7 +323,7 @@ static void TriggerCmdReqQueue(Service::Interface* self) {
}
}
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
cmd_buff[1] = 0; // No error
}
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() {
* 8 : Event signaled by HID_User
*/
static void GetIPCHandles(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
cmd_buff[1] = 0; // No error
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;
* 2 : Output of function, 0 = not charging, 1 = charging.
*/
static void GetAdapterState(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO(purpasmart96): This function is only a stub,
// it returns a valid result without implementing full functionality.
@@ -52,7 +52,7 @@ static void GetAdapterState(Service::Interface* self) {
* 2 : Whether the 3DS's physical shell casing is open (1) or closed (0)
*/
static void GetShellState(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
cmd_buff[1] = 0;
cmd_buff[2] = shell_open ? 1 : 0;
@@ -68,7 +68,7 @@ static void GetShellState(Service::Interface* self) {
* 3 = half full battery, 2 = low battery, 1 = critical battery.
*/
static void GetBatteryLevel(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO(purpasmart96): This function is only a stub,
// it returns a valid result without implementing full functionality.
@@ -86,7 +86,7 @@ static void GetBatteryLevel(Service::Interface* self) {
* 2 : Output of function, 0 = not charging, 1 = charging.
*/
static void GetBatteryChargeState(Service::Interface* self) {
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO(purpasmart96): This function is only a stub,
// 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 @@
#include "core/mem_map.h"
#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/session.h"
#include "core/hle/svc.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -21,30 +22,19 @@
namespace Service {
-static const int kMaxPortSize = 0x08; ///< Maximum size of a port name (8 characters)
-static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header
-
-/**
- * Returns a pointer to the command buffer in kernel memory
- * @param offset Optional offset into command buffer
- * @return Pointer to command buffer
- */
-inline static u32* GetCommandBuffer(const int offset=0) {
- return (u32*)Memory::GetPointer(Memory::KERNEL_MEMORY_VADDR + kCommandHeaderOffset + offset);
-}
+static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 characters)
class Manager;
/// Interface to a CTROS service
-class Interface : public Kernel::Object {
+class Interface : public Kernel::Session {
+ // TODO(yuriks): An "Interface" being a Kernel::Object is mostly non-sense. Interface should be
+ // just something that encapsulates a session and acts as a helper to implement service
+ // processes.
+
friend class Manager;
public:
-
std::string GetName() const override { return GetPortName(); }
- std::string GetTypeName() const override { return GetPortName(); }
-
- static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Service; }
- Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Service; }
typedef void (*Function)(Interface*);
@@ -77,7 +67,7 @@ public:
}
ResultVal<bool> SyncRequest() override {
- u32* cmd_buff = GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
auto itr = m_functions.find(cmd_buff[0]);
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;
static void Initialize(Service::Interface* self) {
LOG_DEBUG(Service_SRV, "called");
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
cmd_buff[1] = 0; // No error
}
@@ -24,7 +24,7 @@ static void Initialize(Service::Interface* self) {
static void GetProcSemaphore(Service::Interface* self) {
LOG_TRACE(Service_SRV, "called");
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO(bunnei): Change to a semaphore once these have been implemented
g_event_handle = Kernel::CreateEvent(RESETTYPE_ONESHOT, "SRV:Event");
@@ -36,7 +36,7 @@ static void GetProcSemaphore(Service::Interface* self) {
static void GetServiceHandle(Service::Interface* self) {
ResultCode res = RESULT_SUCCESS;
- u32* cmd_buff = Service::GetCommandBuffer();
+ u32* cmd_buff = Kernel::GetCommandBuffer();
std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize);
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) {
/// Synchronize to an OS service
static Result SendSyncRequest(Handle handle) {
- // TODO(yuriks): ObjectPool::Get tries to check the Object type, which fails since this is a generic base Object,
- // so we are forced to use GetFast and manually verify the handle.
- if (!Kernel::g_object_pool.IsValid(handle)) {
+ Kernel::Session* session = Kernel::g_object_pool.Get<Kernel::Session>(handle);
+ if (session == nullptr) {
return InvalidHandle(ErrorModule::Kernel).raw;
}
- Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handle);
- _assert_msg_(KERNEL, (object != nullptr), "called, but kernel object is nullptr!");
- LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s)", handle, object->GetTypeName().c_str());
+ LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s)", handle, session->GetName().c_str());
- ResultVal<bool> wait = object->SyncRequest();
+ ResultVal<bool> wait = session->SyncRequest();
if (wait.Succeeded() && *wait) {
Kernel::WaitCurrentThread(WAITTYPE_SYNCH); // TODO(bunnei): Is this correct?
}