Rewrote mm:u to follow switchbrew.org documentation and update them

Credit: Antique - [Sudachi Dev] (https://sudachi.emuplace.app/)
This commit is contained in:
JPikachu 2025-03-25 20:56:47 +00:00 committed by Briar
parent ada5dcf01a
commit 6abd4d2f2b

View file

@ -7,7 +7,42 @@
#include "core/hle/service/server_manager.h" #include "core/hle/service/server_manager.h"
#include "core/hle/service/sm/sm.h" #include "core/hle/service/sm/sm.h"
#include <vector>
namespace Service::MM { 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> { class MM_U final : public ServiceFramework<MM_U> {
public: public:
@ -30,26 +65,53 @@ public:
private: private:
void InitializeOld(HLERequestContext& ctx) { 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}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
} }
void FinalizeOld(HLERequestContext& ctx) { 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}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
} }
void SetAndWaitOld(HLERequestContext& ctx) { void SetAndWaitOld(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; LOG_DEBUG(Service_MM, "(STUBBED) called");
min = rp.Pop<u32>();
max = rp.Pop<u32>(); IPC::RequestParser rp{ctx};
LOG_DEBUG(Service_MM, "(STUBBED) called, min=0x{:X}, max=0x{:X}", min, max); 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;
}
}
current = min;
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
} }
@ -57,35 +119,72 @@ private:
void GetOld(HLERequestContext& ctx) { void GetOld(HLERequestContext& ctx) {
LOG_DEBUG(Service_MM, "(STUBBED) called"); 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}; IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
rb.Push(current); rb.Push<u32>(0);
} }
void Initialize(HLERequestContext& ctx) { 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}; IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
rb.Push<u32>(id); // Any non zero value rb.Push(request_id - 1);
} }
void Finalize(HLERequestContext& ctx) { 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}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
} }
void SetAndWait(HLERequestContext& ctx) { void SetAndWait(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; LOG_DEBUG(Service_MM, "(STUBBED) called");
u32 input_id = rp.Pop<u32>();
min = rp.Pop<u32>(); IPC::RequestParser rp{ctx};
max = rp.Pop<u32>(); const auto id = rp.Pop<u32>();
LOG_DEBUG(Service_MM, "(STUBBED) called, input_id=0x{:X}, min=0x{:X}, max=0x{:X}", input_id, const auto min = rp.Pop<u32>();
min, max); const auto max = rp.Pop<s32>();
for (auto& session : sessions) {
if (session.request_id == id) {
session.SetAndWait(min, max);
break;
}
}
current = min;
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
} }
@ -93,15 +192,25 @@ private:
void Get(HLERequestContext& ctx) { void Get(HLERequestContext& ctx) {
LOG_DEBUG(Service_MM, "(STUBBED) called"); 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}; IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
rb.Push(current); rb.Push(session.min);
return;
}
} }
u32 min{0}; IPC::ResponseBuilder rb{ctx, 3};
u32 max{0}; rb.Push(ResultSuccess);
u32 current{0}; rb.Push<u32>(0);
u32 id{1}; }
std::vector<Session> sessions;
u32 request_id{1};
}; };
void LoopProcess(Core::System& system) { void LoopProcess(Core::System& system) {