Просмотр исходного кода

lm: Implement lm::Initialize and Logger::log.

bunnei 8 лет назад
Родитель
Сommit
716e5cf070
2 измененных файлов с 67 добавлено и 3 удалено
  1. 62 3
      src/core/hle/service/lm/lm.cpp
  2. 5 0
      src/core/hle/service/lm/lm.h

+ 62 - 3
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") {

+ 5 - 0
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.