summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/service/lm/lm.cpp65
-rw-r--r--src/core/hle/service/lm/lm.h5
2 files changed, 67 insertions, 3 deletions
diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp
index d66ac55ca..72fa6db6b 100644
--- a/src/core/hle/service/lm/lm.cpp
+++ b/src/core/hle/service/lm/lm.cpp
@@ -2,13 +2,61 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <string>
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/client_session.h"
#include "core/hle/service/lm/lm.h"
namespace Service {
namespace LM {
+class Logger final : public ServiceFramework<Logger> {
+public:
+ Logger() : ServiceFramework("Logger") {
+ static const FunctionInfo functions[] = {
+ {0x00000000, &Logger::Log, "Log"},
+ };
+ RegisterHandlers(functions);
+ }
+
+ ~Logger() = default;
+
+private:
+ struct MessageHeader {
+ u64_le pid;
+ u64_le threadContext;
+ union {
+ BitField<0, 16, u32_le> flags;
+ BitField<16, 8, u32_le> severity;
+ BitField<24, 8, u32_le> verbosity;
+ };
+ u32_le payload_size;
+ INSERT_PADDING_WORDS(2);
+ };
+ static_assert(sizeof(MessageHeader) == 0x20, "MessageHeader is incorrect size");
+
+ /**
+ * LM::Initialize service function
+ * Inputs:
+ * 0: 0x00000000
+ * Outputs:
+ * 0: ResultCode
+ */
+ void Log(Kernel::HLERequestContext& ctx) {
+ MessageHeader header{};
+ Memory::ReadBlock(ctx.BufferDescriptorX()[0].Address(), &header, sizeof(MessageHeader));
+
+ std::vector<char> string(header.payload_size);
+ Memory::ReadBlock(ctx.BufferDescriptorX()[0].Address() + sizeof(MessageHeader),
+ string.data(), header.payload_size);
+ LOG_DEBUG(Debug_Emulated, "%.*s", header.payload_size, string.data());
+
+ IPC::RequestBuilder rb{ctx, 1};
+ rb.Push(RESULT_SUCCESS);
+ }
+};
+
void InstallInterfaces(SM::ServiceManager& service_manager) {
std::make_shared<LM>()->InstallAsService(service_manager);
}
@@ -21,9 +69,20 @@ void InstallInterfaces(SM::ServiceManager& service_manager) {
* 0: ResultCode
*/
void LM::Initialize(Kernel::HLERequestContext& ctx) {
- IPC::RequestBuilder rb{ctx, 1};
- rb.Push(RESULT_SUCCESS);
- LOG_WARNING(Service_SM, "(STUBBED) called");
+ auto client_port = std::make_shared<Logger>()->CreatePort();
+ auto session = client_port->Connect();
+ if (session.Succeeded()) {
+ LOG_DEBUG(Service_SM, "called, initialized logger -> session=%u",
+ (*session)->GetObjectId());
+ IPC::RequestBuilder rb{ctx, 1, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushObjects(std::move(session).Unwrap());
+ registered_loggers.emplace_back(std::move(client_port));
+ } else {
+ UNIMPLEMENTED();
+ }
+
+ LOG_INFO(Service_SM, "called");
}
LM::LM() : ServiceFramework("lm") {
diff --git a/src/core/hle/service/lm/lm.h b/src/core/hle/service/lm/lm.h
index c497d82eb..05a92f712 100644
--- a/src/core/hle/service/lm/lm.h
+++ b/src/core/hle/service/lm/lm.h
@@ -4,6 +4,9 @@
#pragma once
+#include <vector>
+#include "core/hle/kernel/client_port.h"
+#include "core/hle/kernel/kernel.h"
#include "core/hle/service/service.h"
namespace Service {
@@ -16,6 +19,8 @@ public:
private:
void Initialize(Kernel::HLERequestContext& ctx);
+
+ std::vector<Kernel::SharedPtr<Kernel::ClientPort>> registered_loggers;
};
/// Registers all LM services with the specified service manager.