2018-01-13 21:22:39 +00:00
|
|
|
// Copyright 2018 yuzu emulator team
|
2017-10-15 02:18:42 +00:00
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
2018-02-13 06:44:53 +00:00
|
|
|
#include <sstream>
|
2017-10-19 01:41:24 +00:00
|
|
|
#include <string>
|
2018-07-26 02:32:42 +00:00
|
|
|
|
2017-10-15 02:18:42 +00:00
|
|
|
#include "common/logging/log.h"
|
2019-06-29 21:17:35 +00:00
|
|
|
#include "common/scope_exit.h"
|
2017-10-15 02:18:42 +00:00
|
|
|
#include "core/hle/ipc_helpers.h"
|
|
|
|
#include "core/hle/service/lm/lm.h"
|
2019-06-29 21:17:35 +00:00
|
|
|
#include "core/hle/service/lm/manager.h"
|
2018-07-26 02:32:42 +00:00
|
|
|
#include "core/hle/service/service.h"
|
|
|
|
#include "core/memory.h"
|
2017-10-15 02:18:42 +00:00
|
|
|
|
2018-04-20 01:41:44 +00:00
|
|
|
namespace Service::LM {
|
2017-10-15 02:18:42 +00:00
|
|
|
|
2018-08-01 21:08:41 +00:00
|
|
|
class ILogger final : public ServiceFramework<ILogger> {
|
2017-10-19 01:41:24 +00:00
|
|
|
public:
|
2019-11-26 19:10:49 +00:00
|
|
|
explicit ILogger(Manager& manager_, Memory::Memory& memory_)
|
|
|
|
: ServiceFramework("ILogger"), manager{manager_}, memory{memory_} {
|
2017-10-19 01:41:24 +00:00
|
|
|
static const FunctionInfo functions[] = {
|
2019-06-29 21:18:33 +00:00
|
|
|
{0, &ILogger::Log, "Log"},
|
|
|
|
{1, &ILogger::SetDestination, "SetDestination"},
|
2017-10-19 01:41:24 +00:00
|
|
|
};
|
|
|
|
RegisterHandlers(functions);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2019-06-29 21:18:33 +00:00
|
|
|
void Log(Kernel::HLERequestContext& ctx) {
|
2018-01-05 05:45:13 +00:00
|
|
|
// This function only succeeds - Get that out of the way
|
2018-01-24 00:52:18 +00:00
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
2018-01-05 05:45:13 +00:00
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
|
|
|
|
|
// Read MessageHeader, despite not doing anything with it right now
|
2017-10-19 01:41:24 +00:00
|
|
|
MessageHeader header{};
|
2018-01-05 05:45:13 +00:00
|
|
|
VAddr addr{ctx.BufferDescriptorX()[0].Address()};
|
|
|
|
const VAddr end_addr{addr + ctx.BufferDescriptorX()[0].size};
|
2019-11-26 21:29:34 +00:00
|
|
|
memory.ReadBlock(addr, &header, sizeof(MessageHeader));
|
2018-01-05 05:45:13 +00:00
|
|
|
addr += sizeof(MessageHeader);
|
2017-10-19 01:41:24 +00:00
|
|
|
|
2019-06-29 21:18:33 +00:00
|
|
|
FieldMap fields;
|
2018-01-05 05:45:13 +00:00
|
|
|
while (addr < end_addr) {
|
2019-11-26 21:29:34 +00:00
|
|
|
const auto field = static_cast<Field>(memory.Read8(addr++));
|
|
|
|
const auto length = memory.Read8(addr++);
|
2018-01-18 05:08:38 +00:00
|
|
|
|
2019-11-26 21:29:34 +00:00
|
|
|
if (static_cast<Field>(memory.Read8(addr)) == Field::Skip) {
|
2018-01-18 05:08:38 +00:00
|
|
|
++addr;
|
|
|
|
}
|
|
|
|
|
2019-06-29 21:18:33 +00:00
|
|
|
SCOPE_EXIT({ addr += length; });
|
2018-01-18 05:08:38 +00:00
|
|
|
|
2019-06-29 21:18:33 +00:00
|
|
|
if (field == Field::Skip) {
|
|
|
|
continue;
|
|
|
|
}
|
2017-10-19 01:41:24 +00:00
|
|
|
|
2019-06-29 21:18:33 +00:00
|
|
|
std::vector<u8> data(length);
|
2019-11-26 21:29:34 +00:00
|
|
|
memory.ReadBlock(addr, data.data(), length);
|
2019-06-29 21:18:33 +00:00
|
|
|
fields.emplace(field, std::move(data));
|
2018-01-05 05:45:13 +00:00
|
|
|
}
|
|
|
|
|
2019-06-29 21:18:33 +00:00
|
|
|
manager.Log({header, std::move(fields)});
|
2017-10-19 01:41:24 +00:00
|
|
|
}
|
2018-02-13 06:44:53 +00:00
|
|
|
|
2018-11-19 23:00:11 +00:00
|
|
|
void SetDestination(Kernel::HLERequestContext& ctx) {
|
2019-06-29 21:18:33 +00:00
|
|
|
IPC::RequestParser rp{ctx};
|
|
|
|
const auto destination = rp.PopEnum<DestinationFlag>();
|
|
|
|
|
|
|
|
LOG_DEBUG(Service_LM, "called, destination={:08X}", static_cast<u32>(destination));
|
|
|
|
|
|
|
|
manager.SetDestination(destination);
|
2018-11-19 23:00:11 +00:00
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2019-06-29 21:18:33 +00:00
|
|
|
Manager& manager;
|
2019-11-26 19:10:49 +00:00
|
|
|
Memory::Memory& memory;
|
2017-10-19 01:41:24 +00:00
|
|
|
};
|
|
|
|
|
2018-07-26 02:32:42 +00:00
|
|
|
class LM final : public ServiceFramework<LM> {
|
|
|
|
public:
|
2019-11-26 19:10:49 +00:00
|
|
|
explicit LM(Manager& manager_, Memory::Memory& memory_)
|
|
|
|
: ServiceFramework{"lm"}, manager{manager_}, memory{memory_} {
|
2019-06-29 21:17:35 +00:00
|
|
|
// clang-format off
|
2018-07-26 02:32:42 +00:00
|
|
|
static const FunctionInfo functions[] = {
|
2019-06-29 21:17:35 +00:00
|
|
|
{0, &LM::OpenLogger, "OpenLogger"},
|
2018-07-26 02:32:42 +00:00
|
|
|
};
|
2019-06-29 21:17:35 +00:00
|
|
|
// clang-format on
|
|
|
|
|
2018-07-26 02:32:42 +00:00
|
|
|
RegisterHandlers(functions);
|
|
|
|
}
|
2017-10-15 02:18:42 +00:00
|
|
|
|
2019-06-29 21:17:35 +00:00
|
|
|
private:
|
2018-07-26 02:32:42 +00:00
|
|
|
void OpenLogger(Kernel::HLERequestContext& ctx) {
|
2018-11-26 06:06:13 +00:00
|
|
|
LOG_DEBUG(Service_LM, "called");
|
|
|
|
|
2018-07-26 02:32:42 +00:00
|
|
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
2019-11-26 19:10:49 +00:00
|
|
|
rb.PushIpcInterface<ILogger>(manager, memory);
|
2018-07-26 02:32:42 +00:00
|
|
|
}
|
2019-06-29 21:17:35 +00:00
|
|
|
|
|
|
|
Manager& manager;
|
2019-11-26 19:10:49 +00:00
|
|
|
Memory::Memory& memory;
|
2018-07-26 02:32:42 +00:00
|
|
|
};
|
|
|
|
|
2019-06-29 21:17:35 +00:00
|
|
|
void InstallInterfaces(Core::System& system) {
|
2019-11-26 19:10:49 +00:00
|
|
|
std::make_shared<LM>(system.GetLogManager(), system.Memory())
|
|
|
|
->InstallAsService(system.ServiceManager());
|
2017-10-15 02:18:42 +00:00
|
|
|
}
|
|
|
|
|
2018-04-20 01:41:44 +00:00
|
|
|
} // namespace Service::LM
|