aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJPikachu <JPikachu@EDEN-emu.git>2025-03-25 20:56:47 +0000
committerBriar <205427297+icybriarr@users.noreply.github.com>2025-04-04 03:40:48 +0200
commit6abd4d2f2b7bdd90dfe6e4ad02fd8d8bc7fd3b57 (patch)
treef35702f0886e39c4825e259417b1a8fb9e29ad3c
parentada5dcf01a9cca36c7df8ebf78249b570eb501c9 (diff)
Rewrote mm:u to follow switchbrew.org documentation and update them
Credit: Antique - [Sudachi Dev] (https://sudachi.emuplace.app/)
-rw-r--r--src/core/hle/service/mm/mm_u.cpp161
1 files changed, 135 insertions, 26 deletions
diff --git a/src/core/hle/service/mm/mm_u.cpp b/src/core/hle/service/mm/mm_u.cpp
index 6f43b19684..8fa2341ffb 100644
--- a/src/core/hle/service/mm/mm_u.cpp
+++ b/src/core/hle/service/mm/mm_u.cpp
@@ -7,8 +7,43 @@
#include "core/hle/service/server_manager.h"
#include "core/hle/service/sm/sm.h"
+#include <vector>
+
namespace Service::MM {
-
+enum class Module : u32 {
+ CPU = 0,
+ GPU = 1,
+ EMC = 2,
+ SYS_BUS = 3,
+ M_SELECT = 4,
+ NVDEC = 5,
+ NVENC = 6,
+ NVJPG = 7,
+ TEST = 8
+};
+
+class Session {
+public:
+ Session(Module module_, u32 request_id_, bool is_auto_clear_event_) {
+ this->module = module_;
+ this->request_id = request_id_;
+ this->is_auto_clear_event = is_auto_clear_event_;
+ this->min = 0;
+ this->max = -1;
+ };
+
+public:
+ Module module;
+ u32 request_id, min;
+ s32 max;
+ bool is_auto_clear_event;
+
+ void SetAndWait(u32 min_, s32 max_) {
+ this->min = min_;
+ this->max = max_;
+ }
+};
+
class MM_U final : public ServiceFramework<MM_U> {
public:
explicit MM_U(Core::System& system_) : ServiceFramework{system_, "mm:u"} {
@@ -30,26 +65,53 @@ public:
private:
void InitializeOld(HLERequestContext& ctx) {
- LOG_WARNING(Service_MM, "(STUBBED) called");
-
+ LOG_DEBUG(Service_MM, "(STUBBED) called");
+
+ IPC::RequestParser rp{ctx};
+ const auto module = rp.PopEnum<Module>();
+ rp.Pop<u32>();
+ const auto event_clear_mode = rp.Pop<u32>();
+
+ const bool is_auto_clear_event = event_clear_mode == 1;
+
+ sessions.push_back({module, request_id++, is_auto_clear_event});
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void FinalizeOld(HLERequestContext& ctx) {
- LOG_WARNING(Service_MM, "(STUBBED) called");
+ LOG_DEBUG(Service_MM, "(STUBBED) called");
+
+ IPC::RequestParser rp{ctx};
+ const auto module = rp.PopEnum<Module>();
+
+ for (auto it = sessions.begin(); it != sessions.end(); ++it) {
+ if (it->module == module) {
+ sessions.erase(it);
+ break;
+ }
+ }
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SetAndWaitOld(HLERequestContext& ctx) {
+ LOG_DEBUG(Service_MM, "(STUBBED) called");
+
IPC::RequestParser rp{ctx};
- min = rp.Pop<u32>();
- max = rp.Pop<u32>();
- LOG_DEBUG(Service_MM, "(STUBBED) called, min=0x{:X}, max=0x{:X}", min, max);
-
- current = min;
+ const auto module = rp.PopEnum<Module>();
+ const auto min = rp.Pop<u32>();
+ const auto max = rp.Pop<s32>();
+
+ for (auto& session : sessions) {
+ if (session.module == module) {
+ session.SetAndWait(min, max);
+ break;
+ }
+ }
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
@@ -57,35 +119,72 @@ private:
void GetOld(HLERequestContext& ctx) {
LOG_DEBUG(Service_MM, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ const auto module = rp.PopEnum<Module>();
+
+ for (const auto& session : sessions) {
+ if (session.module == module) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ rb.Push(session.min);
+ return;
+ }
+ }
+
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
- rb.Push(current);
+ rb.Push<u32>(0);
}
void Initialize(HLERequestContext& ctx) {
- LOG_WARNING(Service_MM, "(STUBBED) called");
+ LOG_DEBUG(Service_MM, "(STUBBED) called");
+
+ IPC::RequestParser rp{ctx};
+ const auto module = rp.PopEnum<Module>();
+ rp.Pop<u32>();
+ const auto event_clear_mode = rp.Pop<u32>();
+
+ const bool is_auto_clear_event = event_clear_mode == 1;
+
+ sessions.push_back({module, request_id++, is_auto_clear_event});
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
- rb.Push<u32>(id); // Any non zero value
+ rb.Push(request_id - 1);
}
void Finalize(HLERequestContext& ctx) {
- LOG_WARNING(Service_MM, "(STUBBED) called");
-
+ LOG_DEBUG(Service_MM, "(STUBBED) called");
+
+ IPC::RequestParser rp{ctx};
+ const auto id = rp.Pop<u32>();
+
+ for (auto it = sessions.begin(); it != sessions.end(); ++it) {
+ if (it->request_id == id) {
+ sessions.erase(it);
+ break;
+ }
+ }
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SetAndWait(HLERequestContext& ctx) {
+ LOG_DEBUG(Service_MM, "(STUBBED) called");
+
IPC::RequestParser rp{ctx};
- u32 input_id = rp.Pop<u32>();
- min = rp.Pop<u32>();
- max = rp.Pop<u32>();
- LOG_DEBUG(Service_MM, "(STUBBED) called, input_id=0x{:X}, min=0x{:X}, max=0x{:X}", input_id,
- min, max);
-
- current = min;
+ const auto id = rp.Pop<u32>();
+ const auto min = rp.Pop<u32>();
+ const auto max = rp.Pop<s32>();
+
+ for (auto& session : sessions) {
+ if (session.request_id == id) {
+ session.SetAndWait(min, max);
+ break;
+ }
+ }
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
@@ -93,15 +192,25 @@ private:
void Get(HLERequestContext& ctx) {
LOG_DEBUG(Service_MM, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ const auto id = rp.Pop<u32>();
+
+ for (const auto& session : sessions) {
+ if (session.request_id == id) {
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(session.min);
+ return;
+ }
+ }
+
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
- rb.Push(current);
+ rb.Push<u32>(0);
}
- u32 min{0};
- u32 max{0};
- u32 current{0};
- u32 id{1};
+ std::vector<Session> sessions;
+ u32 request_id{1};
};
void LoopProcess(Core::System& system) {