diff options
-rw-r--r-- | src/core/hle/service/lm/lm.cpp | 65 | ||||
-rw-r--r-- | src/core/hle/service/lm/lm.h | 5 |
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. |