summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Zach Hilman2019-06-29 17:18:07 -0400
committerGravatar Zach Hilman2019-09-22 12:34:55 -0400
commitef9a7fa1f5e593bf6cd49aab2ee371b7ca84512e (patch)
tree86afb16448acf822ab4a1e2fe0c71c7a6866e41d
parentcore: Add LM::Manager to system (diff)
downloadyuzu-ef9a7fa1f5e593bf6cd49aab2ee371b7ca84512e.tar.gz
yuzu-ef9a7fa1f5e593bf6cd49aab2ee371b7ca84512e.tar.xz
yuzu-ef9a7fa1f5e593bf6cd49aab2ee371b7ca84512e.zip
lm: Implement manager class to output to reporter
-rw-r--r--src/core/hle/service/lm/manager.cpp129
-rw-r--r--src/core/hle/service/lm/manager.h104
2 files changed, 233 insertions, 0 deletions
diff --git a/src/core/hle/service/lm/manager.cpp b/src/core/hle/service/lm/manager.cpp
new file mode 100644
index 000000000..fd8edaf46
--- /dev/null
+++ b/src/core/hle/service/lm/manager.cpp
@@ -0,0 +1,129 @@
1// Copyright 2019 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/assert.h"
6#include "common/logging/log.h"
7#include "common/string_util.h"
8#include "core/hle/service/lm/manager.h"
9#include "core/reporter.h"
10
11namespace Service::LM {
12
13std::ostream& operator<<(std::ostream& os, DestinationFlag dest) {
14 std::vector<std::string> array;
15 const auto check_single_flag = [dest, &array](DestinationFlag check, std::string name) {
16 if ((static_cast<u32>(check) & static_cast<u32>(dest)) > 0) {
17 array.emplace_back(std::move(name));
18 }
19 };
20
21 check_single_flag(DestinationFlag::Default, "Default");
22 check_single_flag(DestinationFlag::UART, "UART");
23 check_single_flag(DestinationFlag::UARTSleeping, "UART (Sleeping)");
24
25 os << "[";
26 for (const auto& entry : array) {
27 os << entry << ", ";
28 }
29 return os << "]";
30}
31
32std::ostream& operator<<(std::ostream& os, MessageHeader::Severity severity) {
33 switch (severity) {
34 case MessageHeader::Severity::Trace:
35 return os << "Trace";
36 case MessageHeader::Severity::Info:
37 return os << "Info";
38 case MessageHeader::Severity::Warning:
39 return os << "Warning";
40 case MessageHeader::Severity::Error:
41 return os << "Error";
42 case MessageHeader::Severity::Critical:
43 return os << "Critical";
44 default:
45 return os << fmt::format("{:08X}", static_cast<u32>(severity));
46 }
47}
48
49std::ostream& operator<<(std::ostream& os, Field field) {
50 switch (field) {
51 case Field::Skip:
52 return os << "Skip";
53 case Field::Message:
54 return os << "Message";
55 case Field::Line:
56 return os << "Line";
57 case Field::Filename:
58 return os << "Filename";
59 case Field::Function:
60 return os << "Function";
61 case Field::Module:
62 return os << "Module";
63 case Field::Thread:
64 return os << "Thread";
65 default:
66 return os << fmt::format("{:08X}", static_cast<u32>(field));
67 }
68}
69
70std::string FormatField(Field type, const std::vector<u8>& data) {
71 switch (type) {
72 case Field::Skip:
73 return "";
74 case Field::Line:
75 if (data.size() >= sizeof(u32)) {
76 u32 line;
77 std::memcpy(&line, data.data(), sizeof(u32));
78 return fmt::format("{:08X}", line);
79 }
80 return "[ERROR DECODING LINE NUMBER]";
81 case Field::Message:
82 case Field::Filename:
83 case Field::Function:
84 case Field::Module:
85 case Field::Thread:
86 return Common::StringFromFixedZeroTerminatedBuffer(
87 reinterpret_cast<const char*>(data.data()), data.size());
88 default:
89 UNIMPLEMENTED();
90 }
91}
92
93Manager::Manager(Core::Reporter& reporter) : reporter(reporter) {}
94
95Manager::~Manager() = default;
96
97void Manager::SetEnabled(bool enabled) {
98 this->enabled = enabled;
99}
100
101void Manager::SetDestination(DestinationFlag destination) {
102 this->destination = destination;
103}
104
105void Manager::Log(LogMessage message) {
106 if (message.header.IsHeadLog()) {
107 InitializeLog();
108 }
109
110 current_log.emplace_back(std::move(message));
111
112 if (current_log.back().header.IsTailLog()) {
113 FinalizeLog();
114 }
115}
116
117void Manager::InitializeLog() {
118 current_log.clear();
119
120 LOG_INFO(Service_LM, "Initialized new log session!");
121}
122
123void Manager::FinalizeLog() {
124 reporter.SaveLogReport(static_cast<u32>(destination), std::move(current_log));
125
126 LOG_INFO(Service_LM, "Finalized current log session!");
127}
128
129} // namespace Service::LM
diff --git a/src/core/hle/service/lm/manager.h b/src/core/hle/service/lm/manager.h
new file mode 100644
index 000000000..af0a27257
--- /dev/null
+++ b/src/core/hle/service/lm/manager.h
@@ -0,0 +1,104 @@
1// Copyright 2019 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <map>
8#include <ostream>
9#include <vector>
10#include "common/bit_field.h"
11#include "common/common_types.h"
12#include "common/swap.h"
13
14namespace Core {
15class Reporter;
16}
17
18namespace Service::LM {
19
20enum class DestinationFlag : u32 {
21 Default = 1,
22 UART = 2,
23 UARTSleeping = 4,
24
25 All = 0xFFFF,
26};
27
28struct MessageHeader {
29 enum Flags : u32_le {
30 IsHead = 1,
31 IsTail = 2,
32 };
33 enum Severity : u32_le {
34 Trace,
35 Info,
36 Warning,
37 Error,
38 Critical,
39 };
40
41 u64_le pid;
42 u64_le thread_context;
43 union {
44 BitField<0, 16, Flags> flags;
45 BitField<16, 8, Severity> severity;
46 BitField<24, 8, u32> verbosity;
47 };
48 u32_le payload_size;
49
50 bool IsHeadLog() const {
51 return flags & IsHead;
52 }
53 bool IsTailLog() const {
54 return flags & IsTail;
55 }
56};
57static_assert(sizeof(MessageHeader) == 0x18, "MessageHeader is incorrect size");
58
59enum class Field : u8 {
60 Skip = 1,
61 Message = 2,
62 Line = 3,
63 Filename = 4,
64 Function = 5,
65 Module = 6,
66 Thread = 7,
67};
68
69std::ostream& operator<<(std::ostream& os, DestinationFlag dest);
70std::ostream& operator<<(std::ostream& os, MessageHeader::Severity severity);
71std::ostream& operator<<(std::ostream& os, Field field);
72
73using FieldMap = std::map<Field, std::vector<u8>>;
74
75struct LogMessage {
76 MessageHeader header;
77 FieldMap fields;
78};
79
80std::string FormatField(Field type, const std::vector<u8>& data);
81
82class Manager {
83public:
84 Manager(Core::Reporter& reporter);
85 ~Manager();
86
87 void SetEnabled(bool enabled);
88 void SetDestination(DestinationFlag destination);
89
90 void Log(LogMessage message);
91
92private:
93 void InitializeLog();
94 void FinalizeLog();
95
96 bool enabled = true;
97 DestinationFlag destination = DestinationFlag::All;
98
99 std::vector<LogMessage> current_log;
100
101 Core::Reporter& reporter;
102};
103
104} // namespace Service::LM