aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/service
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service')
-rw-r--r--src/core/hle/service/am_sys.cpp2
-rw-r--r--src/core/hle/service/apt/apt.cpp92
-rw-r--r--src/core/hle/service/apt/apt.h49
-rw-r--r--src/core/hle/service/apt/apt_a.cpp6
-rw-r--r--src/core/hle/service/apt/apt_s.cpp3
-rw-r--r--src/core/hle/service/apt/apt_u.cpp1
-rw-r--r--src/core/hle/service/cfg/cfg.cpp18
-rw-r--r--src/core/hle/service/cfg/cfg.h4
-rw-r--r--src/core/hle/service/cfg/cfg_u.cpp2
-rw-r--r--src/core/hle/service/dsp_dsp.cpp61
-rw-r--r--src/core/hle/service/err_f.cpp2
-rw-r--r--src/core/hle/service/fs/archive.cpp11
-rw-r--r--src/core/hle/service/fs/archive.h16
-rw-r--r--src/core/hle/service/fs/fs_user.cpp85
-rw-r--r--src/core/hle/service/gsp_gpu.cpp44
-rw-r--r--src/core/hle/service/hid/hid.cpp36
-rw-r--r--src/core/hle/service/hid/hid.h6
-rw-r--r--src/core/hle/service/ir/ir.cpp52
-rw-r--r--src/core/hle/service/ir/ir.h30
-rw-r--r--src/core/hle/service/ir/ir_rst.cpp24
-rw-r--r--src/core/hle/service/ir/ir_rst.h (renamed from src/core/hle/service/ir_rst.h)13
-rw-r--r--src/core/hle/service/ir/ir_u.cpp (renamed from src/core/hle/service/ir_u.cpp)17
-rw-r--r--src/core/hle/service/ir/ir_u.h22
-rw-r--r--src/core/hle/service/ir/ir_user.cpp34
-rw-r--r--src/core/hle/service/ir/ir_user.h22
-rw-r--r--src/core/hle/service/ir_rst.cpp27
-rw-r--r--src/core/hle/service/ldr_ro.cpp2
-rw-r--r--src/core/hle/service/nim_u.cpp48
-rw-r--r--src/core/hle/service/nim_u.h (renamed from src/core/hle/service/ir_u.h)8
-rw-r--r--src/core/hle/service/ns_s.cpp2
-rw-r--r--src/core/hle/service/nwm_uds.cpp113
-rw-r--r--src/core/hle/service/nwm_uds.h2
-rw-r--r--src/core/hle/service/ptm/ptm.cpp64
-rw-r--r--src/core/hle/service/ptm/ptm.h46
-rw-r--r--src/core/hle/service/ptm/ptm_play.cpp8
-rw-r--r--src/core/hle/service/ptm/ptm_sysm.cpp75
-rw-r--r--src/core/hle/service/ptm/ptm_u.cpp64
-rw-r--r--src/core/hle/service/service.cpp70
-rw-r--r--src/core/hle/service/service.h57
-rw-r--r--src/core/hle/service/soc_u.cpp1
-rw-r--r--src/core/hle/service/srv.cpp2
-rw-r--r--src/core/hle/service/y2r_u.cpp4
42 files changed, 883 insertions, 362 deletions
diff --git a/src/core/hle/service/am_sys.cpp b/src/core/hle/service/am_sys.cpp
index b244190a2..f9e3fe4b7 100644
--- a/src/core/hle/service/am_sys.cpp
+++ b/src/core/hle/service/am_sys.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/logging/log.h"
+
#include "core/hle/hle.h"
#include "core/hle/service/am_sys.h"
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 5971f860b..09d463dd5 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -2,7 +2,9 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/common_paths.h"
#include "common/file_util.h"
+#include "common/logging/log.h"
#include "core/hle/service/service.h"
#include "core/hle/service/apt/apt.h"
@@ -32,23 +34,31 @@ static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
static Kernel::SharedPtr<Kernel::Mutex> lock;
static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event
-static Kernel::SharedPtr<Kernel::Event> pause_event = 0; ///< APT pause event
+static Kernel::SharedPtr<Kernel::Event> start_event; ///< APT start event
+
static std::vector<u8> shared_font;
+static u32 cpu_percent; ///< CPU time available to the running application
+
void Initialize(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 app_id = cmd_buff[1];
+ u32 flags = cmd_buff[2];
+ cmd_buff[2] = 0x04000000; // According to 3dbrew, this value should be 0x04000000
cmd_buff[3] = Kernel::g_handle_table.Create(notification_event).MoveFrom();
- cmd_buff[4] = Kernel::g_handle_table.Create(pause_event).MoveFrom();
+ cmd_buff[4] = Kernel::g_handle_table.Create(start_event).MoveFrom();
- // TODO(bunnei): Check if these events are cleared/signaled every time Initialize is called.
+ // TODO(bunnei): Check if these events are cleared every time Initialize is called.
notification_event->Clear();
- pause_event->Signal(); // Fire start event
+ start_event->Clear();
ASSERT_MSG((nullptr != lock), "Cannot initialize without lock");
lock->Release();
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+ LOG_TRACE(Service_APT, "called app_id=0x%08X, flags=0x%08X", app_id, flags);
}
void GetSharedFont(Service::Interface* self) {
@@ -74,7 +84,7 @@ void NotifyToWait(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
u32 app_id = cmd_buff[1];
// TODO(Subv): Verify this, it seems to get SWKBD and Home Menu further.
- pause_event->Signal();
+ start_event->Signal();
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
LOG_WARNING(Service_APT, "(STUBBED) app_id=%u", app_id);
@@ -190,7 +200,38 @@ void CancelParameter(Service::Interface* self) {
cmd_buff[2] = 1; // Set to Success
LOG_WARNING(Service_APT, "(STUBBED) called flag1=0x%08X, unk=0x%08X, flag2=0x%08X, app_id=0x%08X",
- flag1, unk, flag2, app_id);
+ flag1, unk, flag2, app_id);
+}
+
+void PrepareToStartApplication(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 title_info1 = cmd_buff[1];
+ u32 title_info2 = cmd_buff[2];
+ u32 title_info3 = cmd_buff[3];
+ u32 title_info4 = cmd_buff[4];
+ u32 flags = cmd_buff[5];
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+ LOG_WARNING(Service_APT, "(STUBBED) called title_info1=0x%08X, title_info2=0x%08X, title_info3=0x%08X,"
+ "title_info4=0x%08X, flags=0x%08X", title_info1, title_info2, title_info3, title_info4, flags);
+}
+
+void StartApplication(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 buffer1_size = cmd_buff[1];
+ u32 buffer2_size = cmd_buff[2];
+ u32 flag = cmd_buff[3];
+ u32 size1 = cmd_buff[4];
+ u32 buffer1_ptr = cmd_buff[5];
+ u32 size2 = cmd_buff[6];
+ u32 buffer2_ptr = cmd_buff[7];
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+ LOG_WARNING(Service_APT, "(STUBBED) called buffer1_size=0x%08X, buffer2_size=0x%08X, flag=0x%08X,"
+ "size1=0x%08X, buffer1_ptr=0x%08X, size2=0x%08X, buffer2_ptr=0x%08X",
+ buffer1_size, buffer2_size, flag, size1, buffer1_ptr, size2, buffer2_ptr);
}
void AppletUtility(Service::Interface* self) {
@@ -205,15 +246,15 @@ void AppletUtility(Service::Interface* self) {
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
- LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X, buffer1_size=0x%08x, buffer2_size=0x%08x, "
- "buffer1_addr=0x%08x, buffer2_addr=0x%08x", unk, buffer1_size, buffer2_size,
+ LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X, buffer1_size=0x%08X, buffer2_size=0x%08X, "
+ "buffer1_addr=0x%08X, buffer2_addr=0x%08X", unk, buffer1_size, buffer2_size,
buffer1_addr, buffer2_addr);
}
void SetAppCpuTimeLimit(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
- u32 value = cmd_buff[1];
- u32 percent = cmd_buff[2];
+ u32 value = cmd_buff[1];
+ cpu_percent = cmd_buff[2];
if (value != 1) {
LOG_ERROR(Service_APT, "This value should be one, but is actually %u!", value);
@@ -221,27 +262,26 @@ void SetAppCpuTimeLimit(Service::Interface* self) {
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
- LOG_WARNING(Service_APT, "(STUBBED) called percent=0x%08X, value=0x%08x", percent, value);
+ LOG_WARNING(Service_APT, "(STUBBED) called cpu_percent=%u, value=%u", cpu_percent, value);
}
void GetAppCpuTimeLimit(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
u32 value = cmd_buff[1];
+ ASSERT(cpu_percent != 0);
+
if (value != 1) {
LOG_ERROR(Service_APT, "This value should be one, but is actually %u!", value);
}
- // TODO(purpasmart96): This is incorrect, I'm pretty sure the percentage should
- // be set by the application.
-
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
- cmd_buff[2] = 0x80; // Set to 80%
+ cmd_buff[2] = cpu_percent;
- LOG_WARNING(Service_APT, "(STUBBED) called value=0x%08x", value);
+ LOG_WARNING(Service_APT, "(STUBBED) called value=%u", value);
}
-void APTInit() {
+void Init() {
AddService(new APT_A_Interface);
AddService(new APT_S_Interface);
AddService(new APT_U_Interface);
@@ -264,21 +304,29 @@ void APTInit() {
file.ReadBytes(shared_font.data(), (size_t)file.GetSize());
// Create shared font memory object
- shared_font_mem = Kernel::SharedMemory::Create("APT_U:shared_font_mem");
+ using Kernel::MemoryPermission;
+ shared_font_mem = Kernel::SharedMemory::Create(3 * 1024 * 1024, // 3MB
+ MemoryPermission::ReadWrite, MemoryPermission::Read, "APT_U:shared_font_mem");
} else {
LOG_WARNING(Service_APT, "Unable to load shared font: %s", filepath.c_str());
shared_font_mem = nullptr;
}
lock = Kernel::Mutex::Create(false, "APT_U:Lock");
-
+
+ cpu_percent = 0;
+
// TODO(bunnei): Check if these are created in Initialize or on APT process startup.
notification_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Notification");
- pause_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Pause");
+ start_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Start");
}
-void APTShutdown() {
-
+void Shutdown() {
+ shared_font.clear();
+ shared_font_mem = nullptr;
+ lock = nullptr;
+ notification_event = nullptr;
+ start_event = nullptr;
}
} // namespace APT
diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h
index a39adbff9..e7fa39325 100644
--- a/src/core/hle/service/apt/apt.h
+++ b/src/core/hle/service/apt/apt.h
@@ -13,10 +13,13 @@ namespace APT {
/// Signals used by APT functions
enum class SignalType : u32 {
- None = 0x0,
- AppJustStarted = 0x1,
- ReturningToApp = 0xB,
- ExitingApp = 0xC,
+ None = 0x0,
+ AppJustStarted = 0x1,
+ LibAppJustStarted = 0x2,
+ LibAppFinished = 0x3,
+ LibAppClosed = 0xA,
+ ReturningToApp = 0xB,
+ ExitingApp = 0xC,
};
/// App Id's used by APT functions
@@ -179,6 +182,40 @@ void GlanceParameter(Service::Interface* self);
void CancelParameter(Service::Interface* self);
/**
+ * APT::PrepareToStartApplication service function. When the input title-info programID is zero,
+ * NS will load the actual program ID via AMNet:GetTitleIDList. After doing some checks with the
+ * programID, NS will then set a NS state flag to value 1, then set the programID for AppID
+ * 0x300(application) to the input program ID(or the one from GetTitleIDList). A media-type field
+ * in the NS state is also set to the input media-type value
+ * (other state fields are set at this point as well). With 8.0.0-18, NS will set an u8 NS state
+ * field to value 1 when input flags bit8 is set
+ * Inputs:
+ * 1-4 : 0x10-byte title-info struct
+ * 4 : Flags
+ * Outputs:
+ * 0 : Return header
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+void PrepareToStartApplication(Service::Interface* self);
+
+/**
+ * APT::StartApplication service function. Buf0 is copied to NS FIRMparams+0x0, then Buf1 is copied
+ * to the NS FIRMparams+0x480. Then the application is launched.
+ * Inputs:
+ * 1 : Buffer 0 size, max size is 0x300
+ * 2 : Buffer 1 size, max size is 0x20 (this can be zero)
+ * 3 : u8 flag
+ * 4 : (Size0<<14) | 2
+ * 5 : Buffer 0 pointer
+ * 6 : (Size1<<14) | 0x802
+ * 7 : Buffer 1 pointer
+ * Outputs:
+ * 0 : Return Header
+ * 1 : Result of function, 0 on success, otherwise error code
+*/
+void StartApplication(Service::Interface* self);
+
+/**
* APT::AppletUtility service function
* Inputs:
* 1 : Unknown, but clearly used for something
@@ -213,10 +250,10 @@ void SetAppCpuTimeLimit(Service::Interface* self);
void GetAppCpuTimeLimit(Service::Interface* self);
/// Initialize the APT service
-void APTInit();
+void Init();
/// Shutdown the APT service
-void APTShutdown();
+void Shutdown();
} // namespace APT
} // namespace Service
diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp
index dbe5c1d87..864934245 100644
--- a/src/core/hle/service/apt/apt_a.cpp
+++ b/src/core/hle/service/apt/apt_a.cpp
@@ -12,16 +12,16 @@ namespace APT {
const Interface::FunctionInfo FunctionTable[] = {
{0x00010040, GetLockHandle, "GetLockHandle?"},
{0x00020080, Initialize, "Initialize?"},
- {0x00030040, nullptr, "Enable?"},
+ {0x00030040, Enable, "Enable?"},
{0x00040040, nullptr, "Finalize?"},
{0x00050040, nullptr, "GetAppletManInfo?"},
{0x00060040, nullptr, "GetAppletInfo?"},
{0x000D0080, ReceiveParameter, "ReceiveParameter?"},
{0x000E0080, GlanceParameter, "GlanceParameter?"},
{0x003B0040, nullptr, "CancelLibraryApplet?"},
- {0x00430040, nullptr, "NotifyToWait?"},
+ {0x00430040, NotifyToWait, "NotifyToWait?"},
{0x00440000, GetSharedFont, "GetSharedFont?"},
- {0x004B00C2, nullptr, "AppletUtility?"},
+ {0x004B00C2, AppletUtility, "AppletUtility?"},
{0x00550040, nullptr, "WriteInputToNsState?"},
};
diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp
index 3fd348651..396d1f04a 100644
--- a/src/core/hle/service/apt/apt_s.cpp
+++ b/src/core/hle/service/apt/apt_s.cpp
@@ -3,9 +3,6 @@
// Refer to the license.txt file included.
-#include "common/common.h"
-#include "common/file_util.h"
-
#include "core/hle/hle.h"
#include "core/hle/service/apt/apt.h"
#include "core/hle/service/apt/apt_s.h"
diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp
index 5ab23801e..d006b5930 100644
--- a/src/core/hle/service/apt/apt_u.cpp
+++ b/src/core/hle/service/apt/apt_u.cpp
@@ -3,7 +3,6 @@
// Refer to the license.txt file included.
-#include "common/common.h"
#include "common/file_util.h"
#include "core/hle/service/apt/apt.h"
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp
index 6adadb224..2d26c9330 100644
--- a/src/core/hle/service/cfg/cfg.cpp
+++ b/src/core/hle/service/cfg/cfg.cpp
@@ -4,12 +4,16 @@
#include <algorithm>
-#include "core/hle/service/fs/archive.h"
-#include "core/hle/service/service.h"
+#include "common/logging/log.h"
+#include "common/string_util.h"
+
+#include "core/file_sys/file_backend.h"
#include "core/hle/service/cfg/cfg.h"
#include "core/hle/service/cfg/cfg_i.h"
#include "core/hle/service/cfg/cfg_s.h"
#include "core/hle/service/cfg/cfg_u.h"
+#include "core/hle/service/fs/archive.h"
+#include "core/hle/service/service.h"
namespace Service {
namespace CFG {
@@ -53,12 +57,12 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output) {
});
if (itr == std::end(config->block_entries)) {
- LOG_ERROR(Service_CFG, "Config block %u with flags %u was not found", block_id, flag);
+ LOG_ERROR(Service_CFG, "Config block 0x%X with flags %u and size %u was not found", block_id, flag, size);
return ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent);
}
if (itr->size != size) {
- LOG_ERROR(Service_CFG, "Invalid size %u for config block %u with flags %u", size, block_id, flag);
+ LOG_ERROR(Service_CFG, "Invalid size %u for config block 0x%X with flags %u", size, block_id, flag);
return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent);
}
@@ -170,7 +174,7 @@ ResultCode FormatConfig() {
return RESULT_SUCCESS;
}
-void CFGInit() {
+void Init() {
AddService(new CFG_I_Interface);
AddService(new CFG_S_Interface);
AddService(new CFG_U_Interface);
@@ -207,6 +211,7 @@ void CFGInit() {
// Initialize the Username block
// TODO(Subv): Initialize this directly in the variable when MSVC supports char16_t string literals
+ memset(&CONSOLE_USERNAME_BLOCK, 0, sizeof(CONSOLE_USERNAME_BLOCK));
CONSOLE_USERNAME_BLOCK.ng_word = 0;
CONSOLE_USERNAME_BLOCK.zero = 0;
@@ -218,8 +223,7 @@ void CFGInit() {
FormatConfig();
}
-void CFGShutdown() {
-
+void Shutdown() {
}
} // namespace CFG
diff --git a/src/core/hle/service/cfg/cfg.h b/src/core/hle/service/cfg/cfg.h
index e818d7bdc..3488c40d0 100644
--- a/src/core/hle/service/cfg/cfg.h
+++ b/src/core/hle/service/cfg/cfg.h
@@ -135,10 +135,10 @@ ResultCode UpdateConfigNANDSavegame();
ResultCode FormatConfig();
/// Initialize the config service
-void CFGInit();
+void Init();
/// Shutdown the config service
-void CFGShutdown();
+void Shutdown();
} // namespace CFG
} // namespace Service
diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp
index c8c1c5b17..221de9918 100644
--- a/src/core/hle/service/cfg/cfg_u.cpp
+++ b/src/core/hle/service/cfg/cfg_u.cpp
@@ -3,7 +3,9 @@
// Refer to the license.txt file included.
#include "common/file_util.h"
+#include "common/logging/log.h"
#include "common/string_util.h"
+
#include "core/settings.h"
#include "core/file_sys/archive_systemsavedata.h"
#include "core/hle/hle.h"
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp
index 0b3603ce1..fafb43a2f 100644
--- a/src/core/hle/service/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp_dsp.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/logging/log.h"
+
#include "core/hle/hle.h"
#include "core/hle/kernel/event.h"
#include "core/hle/service/dsp_dsp.h"
@@ -11,7 +13,7 @@
namespace DSP_DSP {
-static u32 read_pipe_count = 0;
+static u32 read_pipe_count;
static Kernel::SharedPtr<Kernel::Event> semaphore_event;
static Kernel::SharedPtr<Kernel::Event> interrupt_event;
@@ -40,9 +42,9 @@ static void ConvertProcessAddressFromDspDram(Service::Interface* self) {
u32 addr = cmd_buff[1];
cmd_buff[1] = 0; // No error
- cmd_buff[2] = (addr << 1) + (Memory::DSP_MEMORY_VADDR + 0x40000);
+ cmd_buff[2] = (addr << 1) + (Memory::DSP_RAM_VADDR + 0x40000);
- LOG_WARNING(Service_DSP, "(STUBBED) called with address %u", addr);
+ LOG_WARNING(Service_DSP, "(STUBBED) called with address 0x%08X", addr);
}
/**
@@ -60,12 +62,19 @@ static void ConvertProcessAddressFromDspDram(Service::Interface* self) {
static void LoadComponent(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 size = cmd_buff[1];
+ u32 unk1 = cmd_buff[2];
+ u32 unk2 = cmd_buff[3];
+ u32 new_size = cmd_buff[4];
+ u32 buffer = cmd_buff[5];
+
cmd_buff[1] = 0; // No error
cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware
// TODO(bunnei): Implement real DSP firmware loading
- LOG_WARNING(Service_DSP, "(STUBBED) called");
+ LOG_WARNING(Service_DSP, "(STUBBED) called size=0x%X, unk1=0x%08X, unk2=0x%08X, new_size=0x%X, buffer=0x%08X",
+ size, unk1, unk2, new_size, buffer);
}
/**
@@ -84,6 +93,33 @@ static void GetSemaphoreEventHandle(Service::Interface* self) {
}
/**
+ * DSP_DSP::FlushDataCache service function
+ *
+ * This Function is a no-op, We aren't emulating the CPU cache any time soon.
+ *
+ * Inputs:
+ * 1 : Address
+ * 2 : Size
+ * 3 : Value 0, some descriptor for the KProcess Handle
+ * 4 : KProcess handle
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+static void FlushDataCache(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 address = cmd_buff[1];
+ u32 size = cmd_buff[2];
+ u32 process = cmd_buff[4];
+
+ // TODO(purpasmart96): Verify return header on HW
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+ LOG_DEBUG(Service_DSP, "(STUBBED) called address=0x%08X, size=0x%X, process=0x%08X",
+ address, size, process);
+}
+
+/**
* DSP_DSP::RegisterInterruptEvents service function
* Inputs:
* 1 : Parameter 0 (purpose unknown)
@@ -95,6 +131,10 @@ static void GetSemaphoreEventHandle(Service::Interface* self) {
static void RegisterInterruptEvents(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 param0 = cmd_buff[1];
+ u32 param1 = cmd_buff[2];
+ u32 event_handle = cmd_buff[4];
+
auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]);
if (evt != nullptr) {
interrupt_event = evt;
@@ -106,7 +146,7 @@ static void RegisterInterruptEvents(Service::Interface* self) {
cmd_buff[1] = -1;
}
- LOG_WARNING(Service_DSP, "(STUBBED) called");
+ LOG_WARNING(Service_DSP, "(STUBBED) called param0=%u, param1=%u, event_handle=0x%08X", param0, param1, event_handle);
}
/**
@@ -147,7 +187,7 @@ static void WriteProcessPipe(Service::Interface* self) {
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
- LOG_WARNING(Service_DSP, "(STUBBED) called number=%u, size=0x%08X, new_size=0x%08X, buffer=0x%08X",
+ LOG_WARNING(Service_DSP, "(STUBBED) called number=%u, size=0x%X, new_size=0x%X, buffer=0x%08X",
number, size, new_size, buffer);
}
@@ -165,6 +205,8 @@ static void WriteProcessPipe(Service::Interface* self) {
static void ReadPipeIfPossible(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 unk1 = cmd_buff[1];
+ u32 unk2 = cmd_buff[2];
u32 size = cmd_buff[3] & 0xFFFF;// Lower 16 bits are size
VAddr addr = cmd_buff[0x41];
@@ -190,7 +232,8 @@ static void ReadPipeIfPossible(Service::Interface* self) {
cmd_buff[1] = 0; // No error
cmd_buff[2] = (read_pipe_count - initial_size) * sizeof(u16);
- LOG_WARNING(Service_DSP, "(STUBBED) called size=0x%08X, buffer=0x%08X", size, addr);
+ LOG_WARNING(Service_DSP, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, size=0x%X, buffer=0x%08X",
+ unk1, unk2, size, addr);
}
/**
@@ -225,7 +268,7 @@ static void GetHeadphoneStatus(Service::Interface* self) {
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
cmd_buff[2] = 0; // Not using headphones?
- LOG_WARNING(Service_DSP, "(STUBBED) called");
+ LOG_DEBUG(Service_DSP, "(STUBBED) called");
}
const Interface::FunctionInfo FunctionTable[] = {
@@ -242,7 +285,7 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x001000C0, ReadPipeIfPossible, "ReadPipeIfPossible"},
{0x001100C2, LoadComponent, "LoadComponent"},
{0x00120000, nullptr, "UnloadComponent"},
- {0x00130082, nullptr, "FlushDataCache"},
+ {0x00130082, FlushDataCache, "FlushDataCache"},
{0x00140082, nullptr, "InvalidateDCache"},
{0x00150082, RegisterInterruptEvents, "RegisterInterruptEvents"},
{0x00160000, GetSemaphoreEventHandle, "GetSemaphoreEventHandle"},
diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp
index 58c5acd1e..e8c06c1cf 100644
--- a/src/core/hle/service/err_f.cpp
+++ b/src/core/hle/service/err_f.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/logging/log.h"
+
#include "core/hle/hle.h"
#include "core/hle/service/err_f.h"
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index b0fd834c7..6d4a9c7c9 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -9,6 +9,7 @@
#include "common/common_types.h"
#include "common/file_util.h"
+#include "common/logging/log.h"
#include "common/make_unique.h"
#include "common/math_util.h"
@@ -78,6 +79,11 @@ enum class DirectoryCommand : u32 {
Close = 0x08020000,
};
+File::File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path & path)
+ : path(path), priority(0), backend(std::move(backend)) {}
+
+File::~File() {}
+
ResultVal<bool> File::SyncRequest() {
u32* cmd_buff = Kernel::GetCommandBuffer();
FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]);
@@ -172,6 +178,11 @@ ResultVal<bool> File::SyncRequest() {
return MakeResult<bool>(false);
}
+Directory::Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path & path)
+ : path(path), backend(std::move(backend)) {}
+
+Directory::~Directory() {}
+
ResultVal<bool> Directory::SyncRequest() {
u32* cmd_buff = Kernel::GetCommandBuffer();
DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]);
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h
index b00f0fd60..faab0cb79 100644
--- a/src/core/hle/service/fs/archive.h
+++ b/src/core/hle/service/fs/archive.h
@@ -45,31 +45,27 @@ typedef u64 ArchiveHandle;
class File : public Kernel::Session {
public:
- File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path)
- : path(path), priority(0), backend(std::move(backend)) {
- }
+ File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path);
+ ~File();
std::string GetName() const override { return "Path: " + path.DebugStr(); }
+ ResultVal<bool> SyncRequest() override;
FileSys::Path path; ///< Path of the file
u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means
std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface
-
- ResultVal<bool> SyncRequest() override;
};
class Directory : public Kernel::Session {
public:
- Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path)
- : path(path), backend(std::move(backend)) {
- }
+ Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path);
+ ~Directory();
std::string GetName() const override { return "Directory: " + path.DebugStr(); }
+ ResultVal<bool> SyncRequest() override;
FileSys::Path path; ///< Path of the directory
std::unique_ptr<FileSys::DirectoryBackend> backend; ///< File backend interface
-
- ResultVal<bool> SyncRequest() override;
};
/**
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp
index d8d1d5547..0d2a426b0 100644
--- a/src/core/hle/service/fs/fs_user.cpp
+++ b/src/core/hle/service/fs/fs_user.cpp
@@ -2,10 +2,13 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include "common/common.h"
+#include "common/assert.h"
+#include "common/common_types.h"
#include "common/file_util.h"
+#include "common/logging/log.h"
#include "common/scope_exit.h"
#include "common/string_util.h"
+
#include "core/hle/result.h"
#include "core/hle/service/fs/archive.h"
#include "core/hle/service/fs/fs_user.h"
@@ -20,6 +23,8 @@ using Kernel::Session;
namespace Service {
namespace FS {
+static u32 priority = -1; ///< For SetPriority and GetPriority service functions
+
static ArchiveHandle MakeArchiveHandle(u32 low_word, u32 high_word) {
return (u64)low_word | ((u64)high_word << 32);
}
@@ -215,7 +220,7 @@ static void DeleteDirectory(Service::Interface* self) {
LOG_DEBUG(Service_FS, "type=%d size=%d data=%s",
dirname_type, dirname_size, dir_path.DebugStr().c_str());
-
+
cmd_buff[1] = DeleteDirectoryFromArchive(archive_handle, dir_path).raw;
}
@@ -424,7 +429,7 @@ static void IsSdmcWriteable(Service::Interface* self) {
cmd_buff[1] = RESULT_SUCCESS.raw;
// If the SD isn't enabled, it can't be writeable...else, stubbed true
cmd_buff[2] = Settings::values.use_virtual_sd ? 1 : 0;
-
+
LOG_DEBUG(Service_FS, " (STUBBED)");
}
@@ -511,7 +516,7 @@ static void CreateExtSaveData(Service::Interface* self) {
MediaType media_type = static_cast<MediaType>(cmd_buff[1] & 0xFF);
u32 save_low = cmd_buff[2];
u32 save_high = cmd_buff[3];
-
+
LOG_WARNING(Service_FS, "(STUBBED) savedata_high=%08X savedata_low=%08X cmd_buff[3]=%08X "
"cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X "
"cmd_buff[9]=%08X cmd_buff[10]=%08X cmd_buff[11]=%08X", save_high, save_low,
@@ -573,7 +578,7 @@ static void DeleteSystemSaveData(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
u32 savedata_high = cmd_buff[1];
u32 savedata_low = cmd_buff[2];
-
+
cmd_buff[1] = DeleteSystemSaveData(savedata_high, savedata_low).raw;
}
@@ -601,12 +606,72 @@ static void CreateSystemSaveData(Service::Interface* self) {
LOG_WARNING(Service_FS, "(STUBBED) savedata_high=%08X savedata_low=%08X cmd_buff[3]=%08X "
"cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X "
- "cmd_buff[9]=%08X", savedata_high, savedata_low, cmd_buff[3], cmd_buff[4], cmd_buff[5],
+ "cmd_buff[9]=%08X", savedata_high, savedata_low, cmd_buff[3], cmd_buff[4], cmd_buff[5],
cmd_buff[6], cmd_buff[7], cmd_buff[8], cmd_buff[9]);
cmd_buff[1] = CreateSystemSaveData(savedata_high, savedata_low).raw;
}
+/**
+ * FS_User::InitializeWithSdkVersion service function.
+ * Inputs:
+ * 0 : 0x08610042
+ * 1 : Unknown
+ * 2 : Unknown
+ * 3 : Unknown
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+static void InitializeWithSdkVersion(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 unk1 = cmd_buff[1];
+ u32 unk2 = cmd_buff[2];
+ u32 unk3 = cmd_buff[3];
+
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(Service_FS, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, unk3=0x%08X",
+ unk1, unk2, unk3);
+}
+
+/**
+ * FS_User::SetPriority service function.
+ * Inputs:
+ * 0 : 0x08620040
+ * 1 : priority
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+static void SetPriority(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ priority = cmd_buff[1];
+
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_DEBUG(Service_FS, "called priority=0x%08X", priority);
+}
+
+/**
+ * FS_User::GetPriority service function.
+ * Inputs:
+ * 0 : 0x08630000
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : priority
+ */
+static void GetPriority(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ ASSERT(priority != -1);
+
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = priority;
+
+ LOG_DEBUG(Service_FS, "called priority=0x%08X", priority);
+}
+
const Interface::FunctionInfo FunctionTable[] = {
{0x000100C6, nullptr, "Dummy1"},
{0x040100C4, nullptr, "Control"},
@@ -695,15 +760,17 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x08560240, CreateSystemSaveData, "CreateSystemSaveData"},
{0x08570080, DeleteSystemSaveData, "DeleteSystemSaveData"},
{0x08580000, nullptr, "GetMovableSedHashedKeyYRandomData"},
- {0x08610042, nullptr, "InitializeWithSdkVersion"},
- {0x08620040, nullptr, "SetPriority"},
- {0x08630000, nullptr, "GetPriority"},
+ {0x08610042, InitializeWithSdkVersion, "InitializeWithSdkVersion"},
+ {0x08620040, SetPriority, "SetPriority"},
+ {0x08630000, GetPriority, "GetPriority"},
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// Interface class
Interface::Interface() {
+
+ priority = -1;
Register(FunctionTable);
}
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index cff585698..c11c5faba 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -5,6 +5,7 @@
#include "common/bit_field.h"
#include "core/mem_map.h"
+#include "core/memory.h"
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/result.h"
@@ -30,13 +31,12 @@ namespace GSP_GPU {
Kernel::SharedPtr<Kernel::Event> g_interrupt_event;
/// GSP shared memoryings
Kernel::SharedPtr<Kernel::SharedMemory> g_shared_memory;
-/// Thread index into interrupt relay queue, 1 is arbitrary
-u32 g_thread_id = 1;
+/// Thread index into interrupt relay queue
+u32 g_thread_id = 0;
/// Gets a pointer to a thread command buffer in GSP shared memory
static inline u8* GetCommandBuffer(u32 thread_id) {
- ResultVal<u8*> ptr = g_shared_memory->GetPointer(0x800 + (thread_id * sizeof(CommandBuffer)));
- return ptr.ValueOr(nullptr);
+ return g_shared_memory->GetPointer(0x800 + (thread_id * sizeof(CommandBuffer)));
}
static inline FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index) {
@@ -44,14 +44,14 @@ static inline FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_in
// For each thread there are two FrameBufferUpdate fields
u32 offset = 0x200 + (2 * thread_id + screen_index) * sizeof(FrameBufferUpdate);
- ResultVal<u8*> ptr = g_shared_memory->GetPointer(offset);
- return reinterpret_cast<FrameBufferUpdate*>(ptr.ValueOr(nullptr));
+ u8* ptr = g_shared_memory->GetPointer(offset);
+ return reinterpret_cast<FrameBufferUpdate*>(ptr);
}
/// Gets a pointer to the interrupt relay queue for a given thread index
static inline InterruptRelayQueue* GetInterruptRelayQueue(u32 thread_id) {
- ResultVal<u8*> ptr = g_shared_memory->GetPointer(sizeof(InterruptRelayQueue) * thread_id);
- return reinterpret_cast<InterruptRelayQueue*>(ptr.ValueOr(nullptr));
+ u8* ptr = g_shared_memory->GetPointer(sizeof(InterruptRelayQueue) * thread_id);
+ return reinterpret_cast<InterruptRelayQueue*>(ptr);
}
/**
@@ -204,16 +204,18 @@ static void ReadHWRegs(Service::Interface* self) {
static void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) {
u32 base_address = 0x400000;
+ PAddr phys_address_left = Memory::VirtualToPhysicalAddress(info.address_left);
+ PAddr phys_address_right = Memory::VirtualToPhysicalAddress(info.address_right);
if (info.active_fb == 0) {
WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left1)), 4,
- &info.address_left);
+ &phys_address_left);
WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right1)), 4,
- &info.address_right);
+ &phys_address_right);
} else {
WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left2)), 4,
- &info.address_left);
+ &phys_address_left);
WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right2)), 4,
- &info.address_right);
+ &phys_address_right);
}
WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].stride)), 4,
&info.stride);
@@ -265,6 +267,9 @@ static void FlushDataCache(Service::Interface* self) {
// TODO(purpasmart96): Verify return header on HW
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+ LOG_DEBUG(Service_GSP, "(STUBBED) called address=0x%08X, size=0x%08X, process=0x%08X",
+ address, size, process);
}
/**
@@ -273,7 +278,7 @@ static void FlushDataCache(Service::Interface* self) {
* 1 : "Flags" field, purpose is unknown
* 3 : Handle to GSP synchronization event
* Outputs:
- * 0 : Result of function, 0 on success, otherwise error code
+ * 1 : Result of function, 0x2A07 on success, otherwise error code
* 2 : Thread index into GSP command buffer
* 4 : Handle to GSP shared memory
*/
@@ -283,11 +288,12 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) {
g_interrupt_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[3]);
ASSERT_MSG((g_interrupt_event != nullptr), "handle is not valid!");
- g_shared_memory = Kernel::SharedMemory::Create("GSPSharedMem");
Handle shmem_handle = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom();
- cmd_buff[1] = 0x2A07; // Value verified by 3dmoo team, purpose unknown, but needed for GSP init
+ // This specific code is required for a successful initialization, rather than 0
+ cmd_buff[1] = ResultCode((ErrorDescription)519, ErrorModule::GX,
+ ErrorSummary::Success, ErrorLevel::Success).raw;
cmd_buff[2] = g_thread_id++; // Thread ID
cmd_buff[4] = shmem_handle; // GSP shared memory
@@ -522,8 +528,12 @@ Interface::Interface() {
Register(FunctionTable);
g_interrupt_event = 0;
- g_shared_memory = 0;
- g_thread_id = 1;
+
+ using Kernel::MemoryPermission;
+ g_shared_memory = Kernel::SharedMemory::Create(0x1000, MemoryPermission::ReadWrite,
+ MemoryPermission::ReadWrite, "GSPSharedMem");
+
+ g_thread_id = 0;
}
} // namespace
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 138603d9b..9695f7e56 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/logging/log.h"
+
#include "core/hle/service/service.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/hid/hid_spvr.h"
@@ -20,17 +22,17 @@ namespace HID {
static const int MAX_CIRCLEPAD_POS = 0x9C; ///< Max value for a circle pad position
// Handle to shared memory region designated to HID_User service
-static Kernel::SharedPtr<Kernel::SharedMemory> shared_mem = nullptr;
+static Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
// Event handles
-static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_1 = nullptr;
-static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_2 = nullptr;
-static Kernel::SharedPtr<Kernel::Event> event_accelerometer = nullptr;
-static Kernel::SharedPtr<Kernel::Event> event_gyroscope = nullptr;
-static Kernel::SharedPtr<Kernel::Event> event_debug_pad = nullptr;
+static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_1;
+static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_2;
+static Kernel::SharedPtr<Kernel::Event> event_accelerometer;
+static Kernel::SharedPtr<Kernel::Event> event_gyroscope;
+static Kernel::SharedPtr<Kernel::Event> event_debug_pad;
-static u32 next_pad_index = 0;
-static u32 next_touch_index = 0;
+static u32 next_pad_index;
+static u32 next_touch_index;
// TODO(peachum):
// Add a method for setting analog input from joystick device for the circle Pad.
@@ -45,8 +47,8 @@ static u32 next_touch_index = 0;
// * Set PadData.current_state.circle_left = 1 if current PadEntry.circle_pad_x <= -41
// * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_y <= -41
-void HIDUpdate() {
- SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer().ValueOr(nullptr));
+void Update() {
+ SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer());
const PadState state = VideoCore::g_emu_window->GetPadState();
if (mem == nullptr) {
@@ -155,13 +157,15 @@ void GetSoundVolume(Service::Interface* self) {
LOG_WARNING(Service_HID, "(STUBBED) called");
}
-void HIDInit() {
+void Init() {
using namespace Kernel;
AddService(new HID_U_Interface);
AddService(new HID_SPVR_Interface);
- shared_mem = SharedMemory::Create("HID:SharedMem");
+ using Kernel::MemoryPermission;
+ shared_mem = SharedMemory::Create(0x1000, MemoryPermission::ReadWrite,
+ MemoryPermission::Read, "HID:SharedMem");
next_pad_index = 0;
next_touch_index = 0;
@@ -174,7 +178,13 @@ void HIDInit() {
event_debug_pad = Event::Create(RESETTYPE_ONESHOT, "HID:EventDebugPad");
}
-void HIDShutdown() {
+void Shutdown() {
+ shared_mem = nullptr;
+ event_pad_or_touch_1 = nullptr;
+ event_pad_or_touch_2 = nullptr;
+ event_accelerometer = nullptr;
+ event_gyroscope = nullptr;
+ event_debug_pad = nullptr;
}
} // namespace HID
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 97462c7f8..897bd6764 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -200,13 +200,13 @@ void EnableGyroscopeLow(Interface* self);
void GetSoundVolume(Interface* self);
/// Checks for user input updates
-void HIDUpdate();
+void Update();
/// Initialize HID service
-void HIDInit();
+void Init();
/// Shutdown HID service
-void HIDShutdown();
+void Shutdown();
}
}
diff --git a/src/core/hle/service/ir/ir.cpp b/src/core/hle/service/ir/ir.cpp
new file mode 100644
index 000000000..adfbb258d
--- /dev/null
+++ b/src/core/hle/service/ir/ir.cpp
@@ -0,0 +1,52 @@
+// Copyright 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/service.h"
+#include "core/hle/service/ir/ir.h"
+#include "core/hle/service/ir/ir_rst.h"
+#include "core/hle/service/ir/ir_u.h"
+#include "core/hle/service/ir/ir_user.h"
+
+#include "core/hle/hle.h"
+#include "core/hle/kernel/event.h"
+#include "core/hle/kernel/shared_memory.h"
+
+namespace Service {
+namespace IR {
+
+static Kernel::SharedPtr<Kernel::Event> handle_event;
+static Kernel::SharedPtr<Kernel::SharedMemory> shared_memory;
+
+void GetHandles(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0x4000000;
+ cmd_buff[3] = Kernel::g_handle_table.Create(Service::IR::shared_memory).MoveFrom();
+ cmd_buff[4] = Kernel::g_handle_table.Create(Service::IR::handle_event).MoveFrom();
+}
+
+void Init() {
+ using namespace Kernel;
+
+ AddService(new IR_RST_Interface);
+ AddService(new IR_U_Interface);
+ AddService(new IR_User_Interface);
+
+ using Kernel::MemoryPermission;
+ shared_memory = SharedMemory::Create(0x1000, Kernel::MemoryPermission::ReadWrite,
+ Kernel::MemoryPermission::ReadWrite, "IR:SharedMemory");
+
+ // Create event handle(s)
+ handle_event = Event::Create(RESETTYPE_ONESHOT, "IR:HandleEvent");
+}
+
+void Shutdown() {
+ shared_memory = nullptr;
+ handle_event = nullptr;
+}
+
+} // namespace IR
+
+} // namespace Service
diff --git a/src/core/hle/service/ir/ir.h b/src/core/hle/service/ir/ir.h
new file mode 100644
index 000000000..c16d963e7
--- /dev/null
+++ b/src/core/hle/service/ir/ir.h
@@ -0,0 +1,30 @@
+// Copyright 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/service/service.h"
+
+namespace Service {
+namespace IR {
+
+/**
+ * IR::GetHandles service function
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : Translate header, used by the ARM11-kernel
+ * 3 : Shared memory handle
+ * 4 : Event handle
+ */
+void GetHandles(Interface* self);
+
+/// Initialize IR service
+void Init();
+
+/// Shutdown IR service
+void Shutdown();
+
+} // namespace IR
+} // namespace Service
diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp
new file mode 100644
index 000000000..96ae63420
--- /dev/null
+++ b/src/core/hle/service/ir/ir_rst.cpp
@@ -0,0 +1,24 @@
+// Copyright 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/hle.h"
+#include "core/hle/service/ir/ir.h"
+#include "core/hle/service/ir/ir_rst.h"
+
+namespace Service {
+namespace IR {
+
+const Interface::FunctionInfo FunctionTable[] = {
+ {0x00010000, GetHandles, "GetHandles"},
+ {0x00020080, nullptr, "Initialize"},
+ {0x00030000, nullptr, "Shutdown"},
+ {0x00090000, nullptr, "WriteToTwoFields"},
+};
+
+IR_RST_Interface::IR_RST_Interface() {
+ Register(FunctionTable);
+}
+
+} // namespace IR
+} // namespace Service
diff --git a/src/core/hle/service/ir_rst.h b/src/core/hle/service/ir/ir_rst.h
index deef701c5..a492e15c9 100644
--- a/src/core/hle/service/ir_rst.h
+++ b/src/core/hle/service/ir/ir_rst.h
@@ -6,18 +6,17 @@
#include "core/hle/service/service.h"
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Namespace IR_RST
+namespace Service {
+namespace IR {
-namespace IR_RST {
-
-class Interface : public Service::Interface {
+class IR_RST_Interface : public Service::Interface {
public:
- Interface();
+ IR_RST_Interface();
std::string GetPortName() const override {
return "ir:rst";
}
};
-} // namespace
+} // namespace IR
+} // namespace Service
diff --git a/src/core/hle/service/ir_u.cpp b/src/core/hle/service/ir/ir_u.cpp
index 608ed3c06..1b1e3078b 100644
--- a/src/core/hle/service/ir_u.cpp
+++ b/src/core/hle/service/ir/ir_u.cpp
@@ -3,12 +3,11 @@
// Refer to the license.txt file included.
#include "core/hle/hle.h"
-#include "core/hle/service/ir_u.h"
+#include "core/hle/service/ir/ir.h"
+#include "core/hle/service/ir/ir_u.h"
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Namespace IR_U
-
-namespace IR_U {
+namespace Service {
+namespace IR {
const Interface::FunctionInfo FunctionTable[] = {
{0x00010000, nullptr, "Initialize"},
@@ -31,11 +30,9 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x00120040, nullptr, "SetSleepModeState"},
};
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Interface class
-
-Interface::Interface() {
+IR_U_Interface::IR_U_Interface() {
Register(FunctionTable);
}
-} // namespace
+} // namespace IR
+} // namespace Service
diff --git a/src/core/hle/service/ir/ir_u.h b/src/core/hle/service/ir/ir_u.h
new file mode 100644
index 000000000..056d2ce1a
--- /dev/null
+++ b/src/core/hle/service/ir/ir_u.h
@@ -0,0 +1,22 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service {
+namespace IR {
+
+class IR_U_Interface : public Service::Interface {
+public:
+ IR_U_Interface();
+
+ std::string GetPortName() const override {
+ return "ir:u";
+ }
+};
+
+} // namespace IR
+} // namespace Service
diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp
new file mode 100644
index 000000000..8e3ff140f
--- /dev/null
+++ b/src/core/hle/service/ir/ir_user.cpp
@@ -0,0 +1,34 @@
+// Copyright 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/hle.h"
+#include "core/hle/service/ir/ir.h"
+#include "core/hle/service/ir/ir_user.h"
+
+namespace Service {
+namespace IR {
+
+const Interface::FunctionInfo FunctionTable[] = {
+ {0x00010182, nullptr, "InitializeIrNop"},
+ {0x00020000, nullptr, "FinalizeIrNop"},
+ {0x00030000, nullptr, "ClearReceiveBuffer"},
+ {0x00040000, nullptr, "ClearSendBuffer"},
+ {0x00060040, nullptr, "RequireConnection"},
+ {0x00090000, nullptr, "Disconnect"},
+ {0x000A0000, nullptr, "GetReceiveEvent"},
+ {0x000B0000, nullptr, "GetSendEvent"},
+ {0x000C0000, nullptr, "GetConnectionStatusEvent"},
+ {0x000D0042, nullptr, "SendIrNop"},
+ {0x000E0042, nullptr, "SendIrNopLarge"},
+ {0x00180182, nullptr, "InitializeIrNopShared"},
+ {0x00190040, nullptr, "ReleaseReceivedData"},
+ {0x001A0040, nullptr, "SetOwnMachineId"},
+};
+
+IR_User_Interface::IR_User_Interface() {
+ Register(FunctionTable);
+}
+
+} // namespace IR
+} // namespace Service
diff --git a/src/core/hle/service/ir/ir_user.h b/src/core/hle/service/ir/ir_user.h
new file mode 100644
index 000000000..71c932ffa
--- /dev/null
+++ b/src/core/hle/service/ir/ir_user.h
@@ -0,0 +1,22 @@
+// Copyright 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service {
+namespace IR {
+
+class IR_User_Interface : public Service::Interface {
+public:
+ IR_User_Interface();
+
+ std::string GetPortName() const override {
+ return "ir:USER";
+ }
+};
+
+} // namespace IR
+} // namespace Service
diff --git a/src/core/hle/service/ir_rst.cpp b/src/core/hle/service/ir_rst.cpp
deleted file mode 100644
index 4c26c2f03..000000000
--- a/src/core/hle/service/ir_rst.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "core/hle/hle.h"
-#include "core/hle/service/ir_rst.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Namespace IR_RST
-
-namespace IR_RST {
-
-const Interface::FunctionInfo FunctionTable[] = {
- {0x00010000, nullptr, "GetHandles"},
- {0x00020080, nullptr, "Initialize"},
- {0x00030000, nullptr, "Shutdown"},
- {0x00090000, nullptr, "WriteToTwoFields"},
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Interface class
-
-Interface::Interface() {
- Register(FunctionTable);
-}
-
-} // namespace
diff --git a/src/core/hle/service/ldr_ro.cpp b/src/core/hle/service/ldr_ro.cpp
index c0c4a2344..155b97f69 100644
--- a/src/core/hle/service/ldr_ro.cpp
+++ b/src/core/hle/service/ldr_ro.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/logging/log.h"
+
#include "core/hle/hle.h"
#include "core/hle/service/ldr_ro.h"
diff --git a/src/core/hle/service/nim_u.cpp b/src/core/hle/service/nim_u.cpp
new file mode 100644
index 000000000..5f13bd98e
--- /dev/null
+++ b/src/core/hle/service/nim_u.cpp
@@ -0,0 +1,48 @@
+// Copyright 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/logging/log.h"
+
+#include "core/hle/hle.h"
+#include "core/hle/service/nim_u.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace NIM_U
+
+namespace NIM_U {
+
+/**
+ * NIM_U::CheckSysUpdateAvailable service function
+ * Inputs:
+ * 1 : None
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : flag, 0 = no system update available, 1 = system update available.
+ */
+static void CheckSysUpdateAvailable(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // No update available
+
+ LOG_WARNING(Service_NWM, "(STUBBED) called");
+}
+
+const Interface::FunctionInfo FunctionTable[] = {
+ {0x00010000, nullptr, "StartSysUpdate"},
+ {0x00020000, nullptr, "GetUpdateDownloadProgress"},
+ {0x00040000, nullptr, "FinishTitlesInstall"},
+ {0x00050000, nullptr, "CheckForSysUpdateEvent"},
+ {0x00090000, CheckSysUpdateAvailable, "CheckSysUpdateAvailable"},
+ {0x000A0000, nullptr, "GetState"},
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
+
+Interface::Interface() {
+ Register(FunctionTable);
+}
+
+} // namespace
diff --git a/src/core/hle/service/ir_u.h b/src/core/hle/service/nim_u.h
index ec47a1524..57a1f6acf 100644
--- a/src/core/hle/service/ir_u.h
+++ b/src/core/hle/service/nim_u.h
@@ -1,4 +1,4 @@
-// Copyright 2014 Citra Emulator Project
+// Copyright 2015 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@@ -7,16 +7,16 @@
#include "core/hle/service/service.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
-// Namespace IR_U
+// Namespace NIM_U
-namespace IR_U {
+namespace NIM_U {
class Interface : public Service::Interface {
public:
Interface();
std::string GetPortName() const override {
- return "ir:u";
+ return "nim:u";
}
};
diff --git a/src/core/hle/service/ns_s.cpp b/src/core/hle/service/ns_s.cpp
index 5cf3e2039..6b3ef6ece 100644
--- a/src/core/hle/service/ns_s.cpp
+++ b/src/core/hle/service/ns_s.cpp
@@ -3,8 +3,6 @@
// Refer to the license.txt file included.
-#include "common/common.h"
-
#include "core/hle/hle.h"
#include "core/hle/service/ns_s.h"
diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp
index 88be6c8d9..25b01860e 100644
--- a/src/core/hle/service/nwm_uds.cpp
+++ b/src/core/hle/service/nwm_uds.cpp
@@ -2,7 +2,10 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/logging/log.h"
+
#include "core/hle/hle.h"
+#include "core/hle/kernel/event.h"
#include "core/hle/service/nwm_uds.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -10,21 +13,115 @@
namespace NWM_UDS {
+static Kernel::SharedPtr<Kernel::Event> handle_event;
+
+/**
+ * NWM_UDS::Shutdown service function
+ * Inputs:
+ * 1 : None
+ * Outputs:
+ * 0 : Return header
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+static void Shutdown(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ // TODO(purpasmart): Verify return header on HW
+
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(Service_NWM, "(STUBBED) called");
+}
+
+/**
+ * NWM_UDS::RecvBeaconBroadcastData service function
+ * Inputs:
+ * 1 : Output buffer max size
+ * 2 : Unknown
+ * 3 : Unknown
+ * 4 : MAC address?
+ * 6-14 : Unknown, usually zero / uninitialized?
+ * 15 : WLan Comm ID
+ * 16 : This is the ID also located at offset 0xE in the CTR-generation structure.
+ * 17 : Value 0
+ * 18 : Input handle
+ * 19 : (Size<<4) | 12
+ * 20 : Output buffer ptr
+ * Outputs:
+ * 0 : Return header
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+static void RecvBeaconBroadcastData(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 out_buffer_size = cmd_buff[1];
+ u32 unk1 = cmd_buff[2];
+ u32 unk2 = cmd_buff[3];
+ u32 mac_address = cmd_buff[4];
+
+ u32 unk3 = cmd_buff[6];
+
+ u32 wlan_comm_id = cmd_buff[15];
+ u32 ctr_gen_id = cmd_buff[16];
+ u32 value = cmd_buff[17];
+ u32 input_handle = cmd_buff[18];
+ u32 new_buffer_size = cmd_buff[19];
+ u32 out_buffer_ptr = cmd_buff[20];
+
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(Service_NWM, "(STUBBED) called out_buffer_size=0x%08X, unk1=0x%08X, unk2=0x%08X,"
+ "mac_address=0x%08X, unk3=0x%08X, wlan_comm_id=0x%08X, ctr_gen_id=0x%08X,"
+ "value=%u, input_handle=0x%08X, new_buffer_size=0x%08X, out_buffer_ptr=0x%08X",
+ out_buffer_size, unk1, unk2, mac_address, unk3, wlan_comm_id, ctr_gen_id, value,
+ input_handle, new_buffer_size, out_buffer_ptr);
+}
+
+/**
+ * NWM_UDS::Initialize service function
+ * Inputs:
+ * 1 : Unknown
+ * 2-11 : Input Structure
+ * 12 : Unknown u16
+ * 13 : Value 0
+ * 14 : Handle
+ * Outputs:
+ * 0 : Return header
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : Value 0
+ * 3 : Output handle
+ */
+static void Initialize(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 unk1 = cmd_buff[1];
+ u32 unk2 = cmd_buff[12];
+ u32 value = cmd_buff[13];
+ u32 handle = cmd_buff[14];
+
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0;
+ cmd_buff[3] = Kernel::g_handle_table.Create(handle_event).MoveFrom(); //TODO(purpasmart): Verify if this is a event handle
+
+ LOG_WARNING(Service_NWM, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, value=%u, handle=0x%08X",
+ unk1, unk2, value, handle);
+}
+
const Interface::FunctionInfo FunctionTable[] = {
- {0x00030000, nullptr, "Shutdown"},
- {0x000F0404, nullptr, "RecvBeaconBroadcastData"},
- {0x00100042, nullptr, "SetBeaconAdditionalData"},
- {0x001400C0, nullptr, "RecvBroadcastDataFrame"},
- {0x001B0302, nullptr, "Initialize"},
- {0x001D0044, nullptr, "BeginHostingNetwork"},
- {0x001E0084, nullptr, "ConnectToNetwork"},
- {0x001F0006, nullptr, "DecryptBeaconData"},
+ {0x00030000, Shutdown, "Shutdown"},
+ {0x000F0404, RecvBeaconBroadcastData, "RecvBeaconBroadcastData"},
+ {0x00100042, nullptr, "SetBeaconAdditionalData"},
+ {0x001400C0, nullptr, "RecvBroadcastDataFrame"},
+ {0x001B0302, Initialize, "Initialize"},
+ {0x001D0044, nullptr, "BeginHostingNetwork"},
+ {0x001E0084, nullptr, "ConnectToNetwork"},
+ {0x001F0006, nullptr, "DecryptBeaconData"},
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// Interface class
Interface::Interface() {
+ handle_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "NWM_UDS::handle_event");
+
Register(FunctionTable);
}
diff --git a/src/core/hle/service/nwm_uds.h b/src/core/hle/service/nwm_uds.h
index 9043f5aa7..82abdff28 100644
--- a/src/core/hle/service/nwm_uds.h
+++ b/src/core/hle/service/nwm_uds.h
@@ -18,7 +18,7 @@ public:
Interface();
std::string GetPortName() const override {
- return "nwm:UDS";
+ return "nwm::UDS";
}
};
diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp
index 56c918d4f..2c7d49c9f 100644
--- a/src/core/hle/service/ptm/ptm.cpp
+++ b/src/core/hle/service/ptm/ptm.cpp
@@ -2,12 +2,15 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include "core/hle/service/service.h"
+#include "common/logging/log.h"
+
+#include "core/file_sys/file_backend.h"
#include "core/hle/service/fs/archive.h"
#include "core/hle/service/ptm/ptm.h"
#include "core/hle/service/ptm/ptm_play.h"
#include "core/hle/service/ptm/ptm_sysm.h"
#include "core/hle/service/ptm/ptm_u.h"
+#include "core/hle/service/service.h"
namespace Service {
namespace PTM {
@@ -18,31 +21,70 @@ static const GameCoin default_game_coin = { 0x4F00, 42, 0, 0, 0, 2014, 12, 29 };
/// Id of the SharedExtData archive used by the PTM process
static const std::vector<u8> ptm_shared_extdata_id = {0, 0, 0, 0, 0x0B, 0, 0, 0xF0, 0, 0, 0, 0};
-static bool shell_open = true;
+static bool shell_open;
-static bool battery_is_charging = true;
+static bool battery_is_charging;
+
+void GetAdapterState(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
-u32 GetAdapterState() {
// TODO(purpasmart96): This function is only a stub,
// it returns a valid result without implementing full functionality.
- return battery_is_charging ? 1 : 0;
+
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = battery_is_charging ? 1 : 0;
+
+ LOG_WARNING(Service_PTM, "(STUBBED) called");
}
-u32 GetShellState() {
- return shell_open ? 1 : 0;
+void GetShellState(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = shell_open ? 1 : 0;
+}
+
+void GetBatteryLevel(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ // TODO(purpasmart96): This function is only a stub,
+ // it returns a valid result without implementing full functionality.
+
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = static_cast<u32>(ChargeLevels::CompletelyFull); // Set to a completely full battery
+
+ LOG_WARNING(Service_PTM, "(STUBBED) called");
}
-ChargeLevels GetBatteryLevel() {
+void GetBatteryChargeState(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
// TODO(purpasmart96): This function is only a stub,
// it returns a valid result without implementing full functionality.
- return ChargeLevels::CompletelyFull; // Set to a completely full battery
+
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = battery_is_charging ? 1 : 0;
+
+ LOG_WARNING(Service_PTM, "(STUBBED) called");
}
-void PTMInit() {
+void IsLegacyPowerOff(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0;
+
+ LOG_WARNING(Service_PTM, "(STUBBED) called");
+}
+
+void Init() {
AddService(new PTM_Play_Interface);
AddService(new PTM_Sysm_Interface);
AddService(new PTM_U_Interface);
+ shell_open = true;
+ battery_is_charging = true;
+
// Open the SharedExtSaveData archive 0xF000000B and create the gamecoin.dat file if it doesn't exist
FileSys::Path archive_path(ptm_shared_extdata_id);
auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
@@ -68,7 +110,7 @@ void PTMInit() {
}
}
-void PTMShutdown() {
+void Shutdown() {
}
diff --git a/src/core/hle/service/ptm/ptm.h b/src/core/hle/service/ptm/ptm.h
index f697aae4d..493e6a11f 100644
--- a/src/core/hle/service/ptm/ptm.h
+++ b/src/core/hle/service/ptm/ptm.h
@@ -5,6 +5,7 @@
#pragma once
#include <array>
+#include "core/hle/service/service.h"
#include "core/hle/result.h"
namespace Service {
@@ -35,31 +36,54 @@ struct GameCoin {
};
/**
- * Returns whether the battery is charging or not.
* It is unknown if GetAdapterState is the same as GetBatteryChargeState,
* it is likely to just be a duplicate function of GetBatteryChargeState
* that controls another part of the HW.
- * @returns 1 if the battery is charging, and 0 otherwise.
+ * PTM::GetAdapterState service function
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : Output of function, 0 = not charging, 1 = charging.
*/
-u32 GetAdapterState();
+void GetAdapterState(Interface* self);
/**
- * Returns whether the 3DS's physical shell casing is open or closed
- * @returns 1 if the shell is open, and 0 if otherwise
+ * PTM::GetShellState service function.
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : Whether the 3DS's physical shell casing is open (1) or closed (0)
*/
-u32 GetShellState();
+void GetShellState(Interface* self);
/**
- * Get the current battery's charge level.
- * @returns The battery's charge level.
+ * PTM::GetBatteryLevel service function
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : Battery level, 5 = completely full battery, 4 = mostly full battery,
+ * 3 = half full battery, 2 = low battery, 1 = critical battery.
*/
-ChargeLevels GetBatteryLevel();
+void GetBatteryLevel(Interface* self);
+
+/**
+ * PTM::GetBatteryChargeState service function
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : Output of function, 0 = not charging, 1 = charging.
+ */
+void GetBatteryChargeState(Interface* self);
+
+/**
+ * PTM::IsLegacyPowerOff service function
+ * Outputs:
+ * 1: Result code, 0 on success, otherwise error code
+ * 2: Whether the system is going through a power off
+ */
+void IsLegacyPowerOff(Interface* self);
/// Initialize the PTM service
-void PTMInit();
+void Init();
/// Shutdown the PTM service
-void PTMShutdown();
+void Shutdown();
} // namespace PTM
} // namespace Service
diff --git a/src/core/hle/service/ptm/ptm_play.cpp b/src/core/hle/service/ptm/ptm_play.cpp
index 8e8ae8558..48e68a3d8 100644
--- a/src/core/hle/service/ptm/ptm_play.cpp
+++ b/src/core/hle/service/ptm/ptm_play.cpp
@@ -9,10 +9,10 @@ namespace Service {
namespace PTM {
const Interface::FunctionInfo FunctionTable[] = {
- { 0x08070082, nullptr, "GetPlayHistory" },
- { 0x08080000, nullptr, "GetPlayHistoryStart" },
- { 0x08090000, nullptr, "GetPlayHistoryLength" },
- { 0x080B0080, nullptr, "CalcPlayHistoryStart" },
+ {0x08070082, nullptr, "GetPlayHistory"},
+ {0x08080000, nullptr, "GetPlayHistoryStart"},
+ {0x08090000, nullptr, "GetPlayHistoryLength"},
+ {0x080B0080, nullptr, "CalcPlayHistoryStart"},
};
PTM_Play_Interface::PTM_Play_Interface() {
diff --git a/src/core/hle/service/ptm/ptm_sysm.cpp b/src/core/hle/service/ptm/ptm_sysm.cpp
index 2d841f69c..655658f3b 100644
--- a/src/core/hle/service/ptm/ptm_sysm.cpp
+++ b/src/core/hle/service/ptm/ptm_sysm.cpp
@@ -2,57 +2,44 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include "common/make_unique.h"
-#include "core/file_sys/archive_extsavedata.h"
#include "core/hle/hle.h"
+#include "core/hle/service/ptm/ptm.h"
#include "core/hle/service/ptm/ptm_sysm.h"
namespace Service {
namespace PTM {
-/**
- * Returns whether the system is powering off (?)
- * Outputs:
- * 1: Result code, 0 on success, otherwise error code
- * 2: Whether the system is going through a power off
- */
-void IsLegacyPowerOff(Service::Interface* self) {
- u32* cmd_buff = Kernel::GetCommandBuffer();
- cmd_buff[1] = RESULT_SUCCESS.raw;
- cmd_buff[2] = 0;
-}
-
const Interface::FunctionInfo FunctionTable[] = {
- {0x040100C0, nullptr, "SetRtcAlarmEx"},
- {0x04020042, nullptr, "ReplySleepQuery"},
- {0x04030042, nullptr, "NotifySleepPreparationComplete"},
- {0x04040102, nullptr, "SetWakeupTrigger"},
- {0x04050000, nullptr, "GetAwakeReason"},
- {0x04060000, nullptr, "RequestSleep"},
- {0x040700C0, nullptr, "ShutdownAsync"},
- {0x04080000, nullptr, "Awake"},
- {0x04090080, nullptr, "RebootAsync"},
- {0x040A0000, nullptr, "CheckNew3DS"},
- {0x08010640, nullptr, "SetInfoLEDPattern"},
- {0x08020040, nullptr, "SetInfoLEDPatternHeader"},
- {0x08030000, nullptr, "GetInfoLEDStatus"},
- {0x08040040, nullptr, "SetBatteryEmptyLEDPattern"},
- {0x08050000, nullptr, "ClearStepHistory"},
- {0x080600C2, nullptr, "SetStepHistory"},
- {0x08070082, nullptr, "GetPlayHistory"},
- {0x08080000, nullptr, "GetPlayHistoryStart"},
- {0x08090000, nullptr, "GetPlayHistoryLength"},
- {0x080A0000, nullptr, "ClearPlayHistory"},
- {0x080B0080, nullptr, "CalcPlayHistoryStart"},
- {0x080C0080, nullptr, "SetUserTime"},
- {0x080D0000, nullptr, "InvalidateSystemTime"},
- {0x080E0140, nullptr, "NotifyPlayEvent"},
- {0x080F0000, IsLegacyPowerOff, "IsLegacyPowerOff"},
- {0x08100000, nullptr, "ClearLegacyPowerOff"},
- {0x08110000, nullptr, "GetShellStatus"},
- {0x08120000, nullptr, "IsShutdownByBatteryEmpty"},
- {0x08130000, nullptr, "FormatSavedata"},
- {0x08140000, nullptr, "GetLegacyJumpProhibitedFlag"}
+ {0x040100C0, nullptr, "SetRtcAlarmEx"},
+ {0x04020042, nullptr, "ReplySleepQuery"},
+ {0x04030042, nullptr, "NotifySleepPreparationComplete"},
+ {0x04040102, nullptr, "SetWakeupTrigger"},
+ {0x04050000, nullptr, "GetAwakeReason"},
+ {0x04060000, nullptr, "RequestSleep"},
+ {0x040700C0, nullptr, "ShutdownAsync"},
+ {0x04080000, nullptr, "Awake"},
+ {0x04090080, nullptr, "RebootAsync"},
+ {0x040A0000, nullptr, "CheckNew3DS"},
+ {0x08010640, nullptr, "SetInfoLEDPattern"},
+ {0x08020040, nullptr, "SetInfoLEDPatternHeader"},
+ {0x08030000, nullptr, "GetInfoLEDStatus"},
+ {0x08040040, nullptr, "SetBatteryEmptyLEDPattern"},
+ {0x08050000, nullptr, "ClearStepHistory"},
+ {0x080600C2, nullptr, "SetStepHistory"},
+ {0x08070082, nullptr, "GetPlayHistory"},
+ {0x08080000, nullptr, "GetPlayHistoryStart"},
+ {0x08090000, nullptr, "GetPlayHistoryLength"},
+ {0x080A0000, nullptr, "ClearPlayHistory"},
+ {0x080B0080, nullptr, "CalcPlayHistoryStart"},
+ {0x080C0080, nullptr, "SetUserTime"},
+ {0x080D0000, nullptr, "InvalidateSystemTime"},
+ {0x080E0140, nullptr, "NotifyPlayEvent"},
+ {0x080F0000, IsLegacyPowerOff, "IsLegacyPowerOff"},
+ {0x08100000, nullptr, "ClearLegacyPowerOff"},
+ {0x08110000, nullptr, "GetShellStatus"},
+ {0x08120000, nullptr, "IsShutdownByBatteryEmpty"},
+ {0x08130000, nullptr, "FormatSavedata"},
+ {0x08140000, nullptr, "GetLegacyJumpProhibitedFlag"}
};
PTM_Sysm_Interface::PTM_Sysm_Interface() {
diff --git a/src/core/hle/service/ptm/ptm_u.cpp b/src/core/hle/service/ptm/ptm_u.cpp
index 0af7c8bf6..3f5e9c7c1 100644
--- a/src/core/hle/service/ptm/ptm_u.cpp
+++ b/src/core/hle/service/ptm/ptm_u.cpp
@@ -2,7 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include "common/make_unique.h"
+#include "common/logging/log.h"
#include "core/hle/hle.h"
#include "core/hle/service/ptm/ptm.h"
@@ -11,68 +11,6 @@
namespace Service {
namespace PTM {
-/**
- * PTM_U::GetAdapterState service function
- * Outputs:
- * 1 : Result of function, 0 on success, otherwise error code
- * 2 : Output of function, 0 = not charging, 1 = charging.
- */
-static void GetAdapterState(Service::Interface* self) {
- u32* cmd_buff = Kernel::GetCommandBuffer();
-
- cmd_buff[1] = RESULT_SUCCESS.raw;
- cmd_buff[2] = GetAdapterState();
-
- LOG_WARNING(Service_PTM, "(STUBBED) called");
-}
-
-/*
- * PTM_User::GetShellState service function.
- * Outputs:
- * 1 : Result of function, 0 on success, otherwise error code
- * 2 : Whether the 3DS's physical shell casing is open (1) or closed (0)
- */
-static void GetShellState(Service::Interface* self) {
- u32* cmd_buff = Kernel::GetCommandBuffer();
-
- cmd_buff[1] = RESULT_SUCCESS.raw;
- cmd_buff[2] = GetShellState();
-}
-
-/**
- * PTM_U::GetBatteryLevel service function
- * Outputs:
- * 1 : Result of function, 0 on success, otherwise error code
- * 2 : Battery level, 5 = completely full battery, 4 = mostly full battery,
- * 3 = half full battery, 2 = low battery, 1 = critical battery.
- */
-static void GetBatteryLevel(Service::Interface* self) {
- u32* cmd_buff = Kernel::GetCommandBuffer();
-
- cmd_buff[1] = RESULT_SUCCESS.raw;
- cmd_buff[2] = static_cast<u32>(GetBatteryLevel());
-
- LOG_WARNING(Service_PTM, "(STUBBED) called");
-}
-
-/**
- * PTM_U::GetBatteryChargeState service function
- * Outputs:
- * 1 : Result of function, 0 on success, otherwise error code
- * 2 : Output of function, 0 = not charging, 1 = charging.
- */
-static void GetBatteryChargeState(Service::Interface* self) {
- u32* cmd_buff = Kernel::GetCommandBuffer();
-
- // TODO(purpasmart96): This function is only a stub,
- // it returns a valid result without implementing full functionality.
-
- cmd_buff[1] = RESULT_SUCCESS.raw;
- cmd_buff[2] = GetAdapterState();
-
- LOG_WARNING(Service_PTM, "(STUBBED) called");
-}
-
const Interface::FunctionInfo FunctionTable[] = {
{0x00010002, nullptr, "RegisterAlarmClient"},
{0x00020080, nullptr, "SetRtcAlarm"},
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 91f13cd7e..64185c62e 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -2,7 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include "common/common.h"
+#include "common/logging/log.h"
#include "common/string_util.h"
#include "core/hle/service/service.h"
@@ -24,14 +24,13 @@
#include "core/hle/service/gsp_gpu.h"
#include "core/hle/service/gsp_lcd.h"
#include "core/hle/service/http_c.h"
-#include "core/hle/service/ir_rst.h"
-#include "core/hle/service/ir_u.h"
#include "core/hle/service/ldr_ro.h"
#include "core/hle/service/mic_u.h"
#include "core/hle/service/ndm_u.h"
#include "core/hle/service/news_s.h"
#include "core/hle/service/news_u.h"
#include "core/hle/service/nim_aoc.h"
+#include "core/hle/service/nim_u.h"
#include "core/hle/service/ns_s.h"
#include "core/hle/service/nwm_uds.h"
#include "core/hle/service/pm_app.h"
@@ -44,6 +43,7 @@
#include "core/hle/service/fs/archive.h"
#include "core/hle/service/cfg/cfg.h"
#include "core/hle/service/hid/hid.h"
+#include "core/hle/service/ir/ir.h"
#include "core/hle/service/ptm/ptm.h"
namespace Service {
@@ -51,6 +51,49 @@ namespace Service {
std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_ports;
std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services;
+/**
+ * Creates a function string for logging, complete with the name (or header code, depending
+ * on what's passed in) the port name, and all the cmd_buff arguments.
+ */
+static std::string MakeFunctionString(const char* name, const char* port_name, const u32* cmd_buff) {
+ // Number of params == bits 0-5 + bits 6-11
+ int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F);
+
+ std::string function_string = Common::StringFromFormat("function '%s': port=%s", name, port_name);
+ for (int i = 1; i <= num_params; ++i) {
+ function_string += Common::StringFromFormat(", cmd_buff[%i]=%u", i, cmd_buff[i]);
+ }
+ return function_string;
+}
+
+ResultVal<bool> Interface::SyncRequest() {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ auto itr = m_functions.find(cmd_buff[0]);
+
+ if (itr == m_functions.end() || itr->second.func == nullptr) {
+ std::string function_name = (itr == m_functions.end()) ? Common::StringFromFormat("0x%08X", cmd_buff[0]) : itr->second.name;
+ LOG_ERROR(Service, "unknown / unimplemented %s", MakeFunctionString(function_name.c_str(), GetPortName().c_str(), cmd_buff).c_str());
+
+ // TODO(bunnei): Hack - ignore error
+ cmd_buff[1] = 0;
+ return MakeResult<bool>(false);
+ } else {
+ LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str());
+ }
+
+ itr->second.func(this);
+
+ return MakeResult<bool>(false); // TODO: Implement return from actual function
+}
+
+void Interface::Register(const FunctionInfo* functions, size_t n) {
+ m_functions.reserve(n);
+ for (size_t i = 0; i < n; ++i) {
+ // Usually this array is sorted by id already, so hint to instead at the end
+ m_functions.emplace_hint(m_functions.cend(), functions[i].id, functions[i]);
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////
// Module interface
@@ -68,10 +111,11 @@ void Init() {
AddNamedPort(new ERR_F::Interface);
Service::FS::ArchiveInit();
- Service::CFG::CFGInit();
- Service::APT::APTInit();
- Service::PTM::PTMInit();
- Service::HID::HIDInit();
+ Service::CFG::Init();
+ Service::APT::Init();
+ Service::PTM::Init();
+ Service::HID::Init();
+ Service::IR::Init();
AddService(new AC_U::Interface);
AddService(new ACT_U::Interface);
@@ -90,14 +134,13 @@ void Init() {
AddService(new GSP_GPU::Interface);
AddService(new GSP_LCD::Interface);
AddService(new HTTP_C::Interface);
- AddService(new IR_RST::Interface);
- AddService(new IR_U::Interface);
AddService(new LDR_RO::Interface);
AddService(new MIC_U::Interface);
AddService(new NDM_U::Interface);
AddService(new NEWS_S::Interface);
AddService(new NEWS_U::Interface);
AddService(new NIM_AOC::Interface);
+ AddService(new NIM_U::Interface);
AddService(new NS_S::Interface);
AddService(new NWM_UDS::Interface);
AddService(new PM_APP::Interface);
@@ -110,10 +153,11 @@ void Init() {
/// Shutdown ServiceManager
void Shutdown() {
- Service::HID::HIDShutdown();
- Service::PTM::PTMShutdown();
- Service::APT::APTShutdown();
- Service::CFG::CFGShutdown();
+ Service::IR::Shutdown();
+ Service::HID::Shutdown();
+ Service::PTM::Shutdown();
+ Service::APT::Shutdown();
+ Service::CFG::Shutdown();
Service::FS::ArchiveShutdown();
g_srv_services.clear();
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index bfe16ebad..77bfb9ff1 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -4,20 +4,15 @@
#pragma once
-#include <algorithm>
#include <string>
#include <unordered_map>
-#include <vector>
#include <boost/container/flat_map.hpp>
-#include "common/common.h"
-#include "common/string_util.h"
-#include "core/mem_map.h"
+#include "common/common_types.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/session.h"
-#include "core/hle/svc.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// Namespace Service
@@ -26,31 +21,11 @@ namespace Service {
static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 characters)
-class Manager;
-
/// Interface to a CTROS service
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;
-
- /**
- * Creates a function string for logging, complete with the name (or header code, depending
- * on what's passed in) the port name, and all the cmd_buff arguments.
- */
- std::string MakeFunctionString(const char* name, const char* port_name, const u32* cmd_buff) {
- // Number of params == bits 0-5 + bits 6-11
- int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F);
-
- std::string function_string = Common::StringFromFormat("function '%s': port=%s", name, port_name);
- for (int i = 1; i <= num_params; ++i) {
- function_string += Common::StringFromFormat(", cmd_buff[%i]=%u", i, cmd_buff[i]);
- }
- return function_string;
- }
-
public:
std::string GetName() const override { return GetPortName(); }
@@ -70,25 +45,7 @@ public:
return "[UNKNOWN SERVICE PORT]";
}
- ResultVal<bool> SyncRequest() override {
- u32* cmd_buff = Kernel::GetCommandBuffer();
- auto itr = m_functions.find(cmd_buff[0]);
-
- if (itr == m_functions.end() || itr->second.func == nullptr) {
- std::string function_name = (itr == m_functions.end()) ? Common::StringFromFormat("0x%08X", cmd_buff[0]) : itr->second.name;
- LOG_ERROR(Service, "unknown / unimplemented %s", MakeFunctionString(function_name.c_str(), GetPortName().c_str(), cmd_buff).c_str());
-
- // TODO(bunnei): Hack - ignore error
- cmd_buff[1] = 0;
- return MakeResult<bool>(false);
- } else {
- LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str());
- }
-
- itr->second.func(this);
-
- return MakeResult<bool>(false); // TODO: Implement return from actual function
- }
+ ResultVal<bool> SyncRequest() override;
protected:
@@ -96,14 +53,12 @@ protected:
* Registers the functions in the service
*/
template <size_t N>
- void Register(const FunctionInfo (&functions)[N]) {
- m_functions.reserve(N);
- for (auto& fn : functions) {
- // Usually this array is sorted by id already, so hint to instead at the end
- m_functions.emplace_hint(m_functions.cend(), fn.id, fn);
- }
+ inline void Register(const FunctionInfo (&functions)[N]) {
+ Register(functions, N);
}
+ void Register(const FunctionInfo* functions, size_t n);
+
private:
boost::container::flat_map<u32, FunctionInfo> m_functions;
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index 231ead185..39b8d65fd 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/logging/log.h"
#include "common/platform.h"
#if EMU_PLATFORM == PLATFORM_WINDOWS
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp
index cc59a03ce..6c49fa6cf 100644
--- a/src/core/hle/service/srv.cpp
+++ b/src/core/hle/service/srv.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/logging/log.h"
+
#include "core/hle/hle.h"
#include "core/hle/service/srv.h"
#include "core/hle/kernel/event.h"
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp
index 6607965e1..085192a07 100644
--- a/src/core/hle/service/y2r_u.cpp
+++ b/src/core/hle/service/y2r_u.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/logging/log.h"
+
#include "core/hle/hle.h"
#include "core/hle/kernel/event.h"
#include "core/hle/service/y2r_u.h"
@@ -11,7 +13,7 @@
namespace Y2R_U {
-static Kernel::SharedPtr<Kernel::Event> completion_event = 0;
+static Kernel::SharedPtr<Kernel::Event> completion_event;
/**
* Y2R_U::IsBusyConversion service function