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.  | 
