summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/service/ac_u.cpp26
-rw-r--r--src/core/hle/service/gsp_gpu.cpp40
-rw-r--r--src/core/hle/service/ndm/ndm.cpp197
-rw-r--r--src/core/hle/service/ndm/ndm.h216
-rw-r--r--src/core/hle/service/ndm/ndm_u.cpp34
-rw-r--r--src/core/hle/svc.cpp4
6 files changed, 487 insertions, 30 deletions
diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp
index d67325506..5241dd3e7 100644
--- a/src/core/hle/service/ac_u.cpp
+++ b/src/core/hle/service/ac_u.cpp
@@ -3,6 +3,8 @@
// Refer to the license.txt file included.
#include "common/logging/log.h"
+
+#include "core/hle/kernel/event.h"
#include "core/hle/service/ac_u.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -11,6 +13,28 @@
namespace AC_U {
/**
+ * AC_U::CloseAsync service function
+ * Inputs:
+ * 1 : Always 0x20
+ * 3 : Always 0
+ * 4 : Event handle, should be signaled when AC connection is closed
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+static void CloseAsync(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]);
+
+ if (evt) {
+ evt->name = "AC_U:close_event";
+ evt->Signal();
+ }
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+ LOG_WARNING(Service_AC, "(STUBBED) called");
+}
+/**
* AC_U::GetWifiStatus service function
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
@@ -47,7 +71,7 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x00010000, nullptr, "CreateDefaultConfig"},
{0x00040006, nullptr, "ConnectAsync"},
{0x00050002, nullptr, "GetConnectResult"},
- {0x00080004, nullptr, "CloseAsync"},
+ {0x00080004, CloseAsync, "CloseAsync"},
{0x00090002, nullptr, "GetCloseResult"},
{0x000A0000, nullptr, "GetLastErrorCode"},
{0x000D0000, GetWifiStatus, "GetWifiStatus"},
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index 233592d7f..b4c146e08 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -43,6 +43,8 @@ Kernel::SharedPtr<Kernel::SharedMemory> g_shared_memory;
/// Thread index into interrupt relay queue
u32 g_thread_id = 0;
+static bool gpu_right_acquired = false;
+
/// Gets a pointer to a thread command buffer in GSP shared memory
static inline u8* GetCommandBuffer(u32 thread_id) {
return g_shared_memory->GetPointer(0x800 + (thread_id * sizeof(CommandBuffer)));
@@ -370,6 +372,9 @@ static void UnregisterInterruptRelayQueue(Service::Interface* self) {
* @todo This probably does not belong in the GSP module, instead move to video_core
*/
void SignalInterrupt(InterruptId interrupt_id) {
+ if (!gpu_right_acquired) {
+ return;
+ }
if (nullptr == g_interrupt_event) {
LOG_WARNING(Service_GSP, "cannot synchronize until GSP event has been created!");
return;
@@ -624,6 +629,35 @@ static void ImportDisplayCaptureInfo(Service::Interface* self) {
LOG_WARNING(Service_GSP, "called");
}
+/**
+ * GSP_GPU::AcquireRight service function
+ * Outputs:
+ * 1: Result code
+ */
+static void AcquireRight(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ gpu_right_acquired = true;
+
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(Service_GSP, "called");
+}
+
+/**
+ * GSP_GPU::ReleaseRight service function
+ * Outputs:
+ * 1: Result code
+ */
+static void ReleaseRight(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ gpu_right_acquired = false;
+
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(Service_GSP, "called");
+}
const Interface::FunctionInfo FunctionTable[] = {
{0x00010082, WriteHWRegs, "WriteHWRegs"},
@@ -647,8 +681,8 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x00130042, RegisterInterruptRelayQueue, "RegisterInterruptRelayQueue"},
{0x00140000, UnregisterInterruptRelayQueue, "UnregisterInterruptRelayQueue"},
{0x00150002, nullptr, "TryAcquireRight"},
- {0x00160042, nullptr, "AcquireRight"},
- {0x00170000, nullptr, "ReleaseRight"},
+ {0x00160042, AcquireRight, "AcquireRight"},
+ {0x00170000, ReleaseRight, "ReleaseRight"},
{0x00180000, ImportDisplayCaptureInfo, "ImportDisplayCaptureInfo"},
{0x00190000, nullptr, "SaveVramSysArea"},
{0x001A0000, nullptr, "RestoreVramSysArea"},
@@ -669,11 +703,13 @@ Interface::Interface() {
g_shared_memory = nullptr;
g_thread_id = 0;
+ gpu_right_acquired = false;
}
Interface::~Interface() {
g_interrupt_event = nullptr;
g_shared_memory = nullptr;
+ gpu_right_acquired = false;
}
} // namespace
diff --git a/src/core/hle/service/ndm/ndm.cpp b/src/core/hle/service/ndm/ndm.cpp
index 47076a7b8..bc9c3413d 100644
--- a/src/core/hle/service/ndm/ndm.cpp
+++ b/src/core/hle/service/ndm/ndm.cpp
@@ -11,28 +11,217 @@
namespace Service {
namespace NDM {
-void SuspendDaemons(Service::Interface* self) {
+enum : u32 {
+ DEFAULT_RETRY_INTERVAL = 10,
+ DEFAULT_SCAN_INTERVAL = 30
+};
+
+static DaemonMask daemon_bit_mask = DaemonMask::Default;
+static DaemonMask default_daemon_bit_mask = DaemonMask::Default;
+static std::array<DaemonStatus, 4> daemon_status = { DaemonStatus::Idle, DaemonStatus::Idle, DaemonStatus::Idle, DaemonStatus::Idle };
+static ExclusiveState exclusive_state = ExclusiveState::None;
+static u32 scan_interval = DEFAULT_SCAN_INTERVAL;
+static u32 retry_interval = DEFAULT_RETRY_INTERVAL;
+static bool daemon_lock_enabled = false;
+
+void EnterExclusiveState(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ exclusive_state = static_cast<ExclusiveState>(cmd_buff[1]);
+
+ cmd_buff[0] = IPC::MakeHeader(0x1, 1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_NDM, "(STUBBED) exclusive_state=0x%08X ", exclusive_state);
+}
+
+void LeaveExclusiveState(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ exclusive_state = ExclusiveState::None;
+
+ cmd_buff[0] = IPC::MakeHeader(0x2, 1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_NDM, "(STUBBED) exclusive_state=0x%08X ", exclusive_state);
+}
+
+void QueryExclusiveMode(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
- LOG_WARNING(Service_NDM, "(STUBBED) bit_mask=0x%08X ", cmd_buff[1]);
+ cmd_buff[0] = IPC::MakeHeader(0x3, 2, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ cmd_buff[2] = static_cast<u32>(exclusive_state);
+ LOG_WARNING(Service_NDM, "(STUBBED) exclusive_state=0x%08X ", exclusive_state);
+}
+
+void LockState(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ daemon_lock_enabled = true;
+
+ cmd_buff[0] = IPC::MakeHeader(0x4, 1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_NDM, "(STUBBED) daemon_lock_enabled=0x%08X ", daemon_lock_enabled);
+}
+
+void UnlockState(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ daemon_lock_enabled = false;
+ cmd_buff[0] = IPC::MakeHeader(0x5, 1, 0);
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_NDM, "(STUBBED) daemon_lock_enabled=0x%08X ", daemon_lock_enabled);
+}
+
+void SuspendDaemons(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 bit_mask = cmd_buff[1] & 0xF;
+ daemon_bit_mask = static_cast<DaemonMask>(static_cast<u32>(default_daemon_bit_mask) & ~bit_mask);
+ for (size_t index = 0; index < daemon_status.size(); ++index) {
+ if (bit_mask & (1 << index)) {
+ daemon_status[index] = DaemonStatus::Suspended;
+ }
+ }
+
+ cmd_buff[0] = IPC::MakeHeader(0x6, 1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_NDM, "(STUBBED) daemon_bit_mask=0x%08X ", daemon_bit_mask);
}
void ResumeDaemons(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 bit_mask = cmd_buff[1] & 0xF;
+ daemon_bit_mask = static_cast<DaemonMask>(static_cast<u32>(daemon_bit_mask) | bit_mask);
+ for (size_t index = 0; index < daemon_status.size(); ++index) {
+ if (bit_mask & (1 << index)) {
+ daemon_status[index] = DaemonStatus::Idle;
+ }
+ }
+
+ cmd_buff[0] = IPC::MakeHeader(0x7, 1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_NDM, "(STUBBED) daemon_bit_mask=0x%08X ", daemon_bit_mask);
+}
+
+void SuspendScheduler(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[0] = IPC::MakeHeader(0x8, 1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_NDM, "(STUBBED) called");
+}
+
+void ResumeScheduler(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[0] = IPC::MakeHeader(0x9, 1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_NDM, "(STUBBED) called");
+}
+
+void QueryStatus(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 daemon = cmd_buff[1] & 0xF;
- LOG_WARNING(Service_NDM, "(STUBBED) bit_mask=0x%08X ", cmd_buff[1]);
+ cmd_buff[0] = IPC::MakeHeader(0xD, 2, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ cmd_buff[2] = static_cast<u32>(daemon_status.at(daemon));
+ LOG_WARNING(Service_NDM, "(STUBBED) daemon=0x%08X, daemon_status=0x%08X", daemon, cmd_buff[2]);
+}
+
+void GetDaemonDisableCount(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 daemon = cmd_buff[1] & 0xF;
+
+ cmd_buff[0] = IPC::MakeHeader(0xE, 3, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ cmd_buff[2] = 0;
+ cmd_buff[3] = 0;
+ LOG_WARNING(Service_NDM, "(STUBBED) daemon=0x%08X", daemon);
+}
+
+void GetSchedulerDisableCount(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[0] = IPC::MakeHeader(0xF, 3, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ cmd_buff[2] = 0;
+ cmd_buff[3] = 0;
+ LOG_WARNING(Service_NDM, "(STUBBED) called");
+}
+
+void SetScanInterval(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ scan_interval = cmd_buff[1];
+ cmd_buff[0] = IPC::MakeHeader(0x10, 1, 0);
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_NDM, "(STUBBED) scan_interval=0x%08X ", scan_interval);
+}
+
+void GetScanInterval(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[0] = IPC::MakeHeader(0x11, 2, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ cmd_buff[2] = scan_interval;
+ LOG_WARNING(Service_NDM, "(STUBBED) scan_interval=0x%08X ", scan_interval);
+}
+
+void SetRetryInterval(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ retry_interval = cmd_buff[1];
+
+ cmd_buff[0] = IPC::MakeHeader(0x12, 1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_NDM, "(STUBBED) retry_interval=0x%08X ", retry_interval);
+}
+
+void GetRetryInterval(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[0] = IPC::MakeHeader(0x13, 2, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ cmd_buff[2] = retry_interval;
+ LOG_WARNING(Service_NDM, "(STUBBED) retry_interval=0x%08X ", retry_interval);
}
void OverrideDefaultDaemons(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 bit_mask = cmd_buff[1] & 0xF;
+ default_daemon_bit_mask = static_cast<DaemonMask>(bit_mask);
+ daemon_bit_mask = default_daemon_bit_mask;
+ for (size_t index = 0; index < daemon_status.size(); ++index) {
+ if (bit_mask & (1 << index)) {
+ daemon_status[index] = DaemonStatus::Idle;
+ }
+ }
- LOG_WARNING(Service_NDM, "(STUBBED) bit_mask=0x%08X ", cmd_buff[1]);
+ cmd_buff[0] = IPC::MakeHeader(0x14, 1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_NDM, "(STUBBED) default_daemon_bit_mask=0x%08X ", default_daemon_bit_mask);
+}
+
+void ResetDefaultDaemons(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ default_daemon_bit_mask = DaemonMask::Default;
+
+ cmd_buff[0] = IPC::MakeHeader(0x15, 1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_NDM, "(STUBBED) default_daemon_bit_mask=0x%08X ", default_daemon_bit_mask);
+}
+
+void GetDefaultDaemons(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[0] = IPC::MakeHeader(0x16, 2, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ cmd_buff[2] = static_cast<u32>(default_daemon_bit_mask);
+ LOG_WARNING(Service_NDM, "(STUBBED) default_daemon_bit_mask=0x%08X ", default_daemon_bit_mask);
+}
+
+void ClearHalfAwakeMacFilter(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ cmd_buff[0] = IPC::MakeHeader(0x17, 1, 0);
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_NDM, "(STUBBED) called");
}
void Init() {
diff --git a/src/core/hle/service/ndm/ndm.h b/src/core/hle/service/ndm/ndm.h
index 734730f8c..5c2b968dc 100644
--- a/src/core/hle/service/ndm/ndm.h
+++ b/src/core/hle/service/ndm/ndm.h
@@ -12,10 +12,91 @@ class Interface;
namespace NDM {
+enum class Daemon : u32 {
+ Cec = 0,
+ Boss = 1,
+ Nim = 2,
+ Friend = 3
+};
+
+enum class DaemonMask : u32 {
+ None = 0,
+ Cec = (1 << static_cast<u32>(Daemon::Cec)),
+ Boss = (1 << static_cast<u32>(Daemon::Boss)),
+ Nim = (1 << static_cast<u32>(Daemon::Nim)),
+ Friend = (1 << static_cast<u32>(Daemon::Friend)),
+ Default = Cec | Friend,
+ All = Cec | Boss | Nim | Friend
+};
+
+enum class DaemonStatus : u32 {
+ Busy = 0,
+ Idle = 1,
+ Suspending = 2,
+ Suspended = 3
+};
+
+enum class ExclusiveState : u32 {
+ None = 0,
+ Infrastructure = 1,
+ LocalCommunications = 2,
+ Streetpass = 3,
+ StreetpassData = 4,
+};
+
+/**
+ * NDM::EnterExclusiveState service function
+ * Inputs:
+ * 0 : Header code [0x00010042]
+ * 1 : Exclusive State
+ * 2 : 0x20
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ */
+void EnterExclusiveState(Service::Interface* self);
+
+/**
+ * NDM::LeaveExclusiveState service function
+ * Inputs:
+ * 0 : Header code [0x00020002]
+ * 1 : 0x20
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ */
+void LeaveExclusiveState(Service::Interface* self);
+
+/**
+ * NDM::QueryExclusiveMode service function
+ * Inputs:
+ * 0 : Header code [0x00030000]
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ * 2 : Current Exclusive State
+ */
+void QueryExclusiveMode(Service::Interface* self);
+
+/**
+ * NDM::LockState service function
+ * Inputs:
+ * 0 : Header code [0x00040002]
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ */
+void LockState(Service::Interface* self);
+
+/**
+ * NDM::UnlockState service function
+ * Inputs:
+ * 0 : Header code [0x00050002]
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ */
+void UnlockState(Service::Interface* self);
+
/**
- * SuspendDaemons
+ * NDM::SuspendDaemons service function
* Inputs:
- * 0 : Command header (0x00020082)
+ * 0 : Header code [0x00060040]
* 1 : Daemon bit mask
* Outputs:
* 1 : Result, 0 on success, otherwise error code
@@ -23,9 +104,9 @@ namespace NDM {
void SuspendDaemons(Service::Interface* self);
/**
- * ResumeDaemons
+ * NDM::ResumeDaemons service function
* Inputs:
- * 0 : Command header (0x00020082)
+ * 0 : Header code [0x00070040]
* 1 : Daemon bit mask
* Outputs:
* 1 : Result, 0 on success, otherwise error code
@@ -33,15 +114,138 @@ void SuspendDaemons(Service::Interface* self);
void ResumeDaemons(Service::Interface* self);
/**
- * OverrideDefaultDaemons
+ * NDM::SuspendScheduler service function
* Inputs:
- * 0 : Command header (0x00020082)
+ * 0 : Header code [0x00080040]
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ */
+void SuspendScheduler(Service::Interface* self);
+
+/**
+ * NDM::ResumeScheduler service function
+ * Inputs:
+ * 0 : Header code [0x00090000]
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ */
+void ResumeScheduler(Service::Interface* self);
+
+/**
+ * NDM::QueryStatus service function
+ * Inputs:
+ * 0 : Header code [0x000D0040]
+ * 1 : Daemon
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ * 2 : Daemon status
+ */
+void QueryStatus(Service::Interface* self);
+
+/**
+ * NDM::GetDaemonDisableCount service function
+ * Inputs:
+ * 0 : Header code [0x000E0040]
+ * 1 : Daemon
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ * 2 : Current process disable count
+ * 3 : Total disable count
+ */
+void GetDaemonDisableCount(Service::Interface* self);
+
+/**
+ * NDM::GetSchedulerDisableCount service function
+ * Inputs:
+ * 0 : Header code [0x000F0000]
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ * 2 : Current process disable count
+ * 3 : Total disable count
+ */
+void GetSchedulerDisableCount(Service::Interface* self);
+
+/**
+ * NDM::SetScanInterval service function
+ * Inputs:
+ * 0 : Header code [0x00100040]
+ * 1 : Interval (default = 30)
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ */
+void SetScanInterval(Service::Interface* self);
+
+/**
+ * NDM::GetScanInterval service function
+ * Inputs:
+ * 0 : Header code [0x00110000]
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ * 2 : Interval (default = 30)
+ */
+void GetScanInterval(Service::Interface* self);
+
+/**
+ * NDM::SetRetryInterval service function
+ * Inputs:
+ * 0 : Header code [0x00120040]
+ * 1 : Interval (default = 10)
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ */
+void SetRetryInterval(Service::Interface* self);
+
+/**
+ * NDM::GetRetryInterval service function
+ * Inputs:
+ * 0 : Header code [0x00130000]
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ * 2 : Interval (default = 10)
+ */
+void GetRetryInterval(Service::Interface* self);
+
+
+/**
+ * NDM::OverrideDefaultDaemons service function
+ * Inputs:
+ * 0 : Header code [0x00140040]
* 1 : Daemon bit mask
* Outputs:
* 1 : Result, 0 on success, otherwise error code
*/
void OverrideDefaultDaemons(Service::Interface* self);
+/**
+ * NDM::ResetDefaultDaemons service function
+ * Inputs:
+ * 0 : Header code [0x00150000]
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ */
+void ResetDefaultDaemons(Service::Interface* self);
+
+/**
+ * NDM::GetDefaultDaemons service function
+ * Inputs:
+ * 0 : Header code [0x00160000]
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ * 2 : Daemon bit mask
+ * Note:
+ * Gets the current default daemon bit mask. The default value is (DAEMONMASK_CEC | DAEMONMASK_FRIENDS)
+ */
+void GetDefaultDaemons(Service::Interface* self);
+
+/**
+ * NDM::ClearHalfAwakeMacFilter service function
+ * Inputs:
+ * 0 : Header code [0x00170000]
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ */
+void ClearHalfAwakeMacFilter(Service::Interface* self);
+
/// Initialize NDM service
void Init();
diff --git a/src/core/hle/service/ndm/ndm_u.cpp b/src/core/hle/service/ndm/ndm_u.cpp
index bf95cc7aa..3ff0744ee 100644
--- a/src/core/hle/service/ndm/ndm_u.cpp
+++ b/src/core/hle/service/ndm/ndm_u.cpp
@@ -9,29 +9,29 @@ namespace Service {
namespace NDM {
const Interface::FunctionInfo FunctionTable[] = {
- {0x00010042, nullptr, "EnterExclusiveState"},
- {0x00020002, nullptr, "LeaveExclusiveState"},
- {0x00030000, nullptr, "QueryExclusiveMode"},
- {0x00040002, nullptr, "LockState"},
- {0x00050002, nullptr, "UnlockState"},
+ {0x00010042, EnterExclusiveState, "EnterExclusiveState"},
+ {0x00020002, LeaveExclusiveState, "LeaveExclusiveState"},
+ {0x00030000, QueryExclusiveMode, "QueryExclusiveMode"},
+ {0x00040002, LockState, "LockState"},
+ {0x00050002, UnlockState, "UnlockState"},
{0x00060040, SuspendDaemons, "SuspendDaemons"},
{0x00070040, ResumeDaemons, "ResumeDaemons"},
- {0x00080040, nullptr, "DisableWifiUsage"},
- {0x00090000, nullptr, "EnableWifiUsage"},
+ {0x00080040, SuspendScheduler, "SuspendScheduler"},
+ {0x00090000, ResumeScheduler, "ResumeScheduler"},
{0x000A0000, nullptr, "GetCurrentState"},
{0x000B0000, nullptr, "GetTargetState"},
{0x000C0000, nullptr, "<Stubbed>"},
- {0x000D0040, nullptr, "QueryStatus"},
- {0x000E0040, nullptr, "GetDaemonDisableCount"},
- {0x000F0000, nullptr, "GetSchedulerDisableCount"},
- {0x00100040, nullptr, "SetScanInterval"},
- {0x00110000, nullptr, "GetScanInterval"},
- {0x00120040, nullptr, "SetRetryInterval"},
- {0x00130000, nullptr, "GetRetryInterval"},
+ {0x000D0040, QueryStatus, "QueryStatus"},
+ {0x000E0040, GetDaemonDisableCount, "GetDaemonDisableCount"},
+ {0x000F0000, GetSchedulerDisableCount,"GetSchedulerDisableCount"},
+ {0x00100040, SetScanInterval, "SetScanInterval"},
+ {0x00110000, GetScanInterval, "GetScanInterval"},
+ {0x00120040, SetRetryInterval, "SetRetryInterval"},
+ {0x00130000, GetRetryInterval, "GetRetryInterval"},
{0x00140040, OverrideDefaultDaemons, "OverrideDefaultDaemons"},
- {0x00150000, nullptr, "ResetDefaultDaemons"},
- {0x00160000, nullptr, "GetDefaultDaemons"},
- {0x00170000, nullptr, "ClearHalfAwakeMacFilter"},
+ {0x00150000, ResetDefaultDaemons, "ResetDefaultDaemons"},
+ {0x00160000, GetDefaultDaemons, "GetDefaultDaemons"},
+ {0x00170000, ClearHalfAwakeMacFilter, "ClearHalfAwakeMacFilter"},
};
NDM_U_Interface::NDM_U_Interface() {
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index a9a1a3244..fb2aecbf2 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -859,6 +859,10 @@ static ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type) {
// TODO(yuriks): Type 0 returns a slightly higher number than type 2, but I'm not sure
// what's the difference between them.
*out = process->heap_used + process->linear_heap_used + process->misc_memory_used;
+ if(*out % Memory::PAGE_SIZE != 0) {
+ LOG_ERROR(Kernel_SVC, "called, memory size not page-aligned");
+ return ERR_MISALIGNED_SIZE;
+ }
break;
case 1:
case 3: