summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/common_funcs.h2
-rw-r--r--src/common/logging/backend.cpp1
-rw-r--r--src/common/logging/log.h1
-rw-r--r--src/core/hle/service/err_f.cpp165
4 files changed, 166 insertions, 3 deletions
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h
index 4bbcc3571..28ccebc15 100644
--- a/src/common/common_funcs.h
+++ b/src/common/common_funcs.h
@@ -14,8 +14,6 @@
14#define SLEEP(x) usleep(x*1000) 14#define SLEEP(x) usleep(x*1000)
15#endif 15#endif
16 16
17template <bool> struct CompileTimeAssert;
18template<> struct CompileTimeAssert<true> {};
19 17
20#define b2(x) ( (x) | ( (x) >> 1) ) 18#define b2(x) ( (x) | ( (x) >> 1) )
21#define b4(x) ( b2(x) | ( b2(x) >> 2) ) 19#define b4(x) ( b2(x) | ( b2(x) >> 2) )
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 8fee20a83..7c1010b22 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -33,6 +33,7 @@ static std::shared_ptr<Logger> global_logger;
33 CLS(Service) \ 33 CLS(Service) \
34 SUB(Service, SRV) \ 34 SUB(Service, SRV) \
35 SUB(Service, FS) \ 35 SUB(Service, FS) \
36 SUB(Service, ERR) \
36 SUB(Service, APT) \ 37 SUB(Service, APT) \
37 SUB(Service, GSP) \ 38 SUB(Service, GSP) \
38 SUB(Service, AC) \ 39 SUB(Service, AC) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index 6c5ca3968..7b67b3c07 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -53,6 +53,7 @@ enum class Class : ClassType {
53 /// should have its own subclass. 53 /// should have its own subclass.
54 Service_SRV, ///< The SRV (Service Directory) implementation 54 Service_SRV, ///< The SRV (Service Directory) implementation
55 Service_FS, ///< The FS (Filesystem) service implementation 55 Service_FS, ///< The FS (Filesystem) service implementation
56 Service_ERR, ///< The ERR (Error) port implementation
56 Service_APT, ///< The APT (Applets) service 57 Service_APT, ///< The APT (Applets) service
57 Service_GSP, ///< The GSP (GPU control) service 58 Service_GSP, ///< The GSP (GPU control) service
58 Service_AC, ///< The AC (WiFi status) service 59 Service_AC, ///< The AC (WiFi status) service
diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp
index 8d765acb5..58c5acd1e 100644
--- a/src/core/hle/service/err_f.cpp
+++ b/src/core/hle/service/err_f.cpp
@@ -10,8 +10,171 @@
10 10
11namespace ERR_F { 11namespace ERR_F {
12 12
13enum {
14 ErrSpecifier0 = 0,
15 ErrSpecifier1 = 1,
16 ErrSpecifier3 = 3,
17 ErrSpecifier4 = 4,
18};
19
20// This is used instead of ResultCode from result.h
21// because we can't have non-trivial data members in unions.
22union RSL {
23 u32 raw;
24
25 BitField<0, 10, u32> description;
26 BitField<10, 8, u32> module;
27 BitField<21, 6, u32> summary;
28 BitField<27, 5, u32> level;
29};
30
31union ErrInfo {
32 u8 specifier;
33
34 struct {
35 u8 specifier; // 0x0
36 u8 rev_high; // 0x1
37 u16 rev_low; // 0x2
38 RSL result_code; // 0x4
39 u32 address; // 0x8
40 INSERT_PADDING_BYTES(4); // 0xC
41 u32 pid_low; // 0x10
42 u32 pid_high; // 0x14
43 u32 aid_low; // 0x18
44 u32 aid_high; // 0x1C
45 } errtype1;
46
47 struct {
48 u8 specifier; // 0x0
49 u8 rev_high; // 0x1
50 u16 rev_low; // 0x2
51 INSERT_PADDING_BYTES(0xC); // 0x4
52 u32 pid_low; // 0x10
53 u32 pid_high; // 0x14
54 u32 aid_low; // 0x18
55 u32 aid_high; // 0x1C
56 u8 error_type; // 0x20
57 INSERT_PADDING_BYTES(3); // 0x21
58 u32 fault_status_reg; // 0x24
59 u32 fault_addr; // 0x28
60 u32 fpexc; // 0x2C
61 u32 finst; // 0x30
62 u32 finst2; // 0x34
63 INSERT_PADDING_BYTES(0x34); // 0x38
64 u32 sp; // 0x6C
65 u32 pc; // 0x70
66 u32 lr; // 0x74
67 u32 cpsr; // 0x78
68 } errtype3;
69
70 struct {
71 u8 specifier; // 0x0
72 u8 rev_high; // 0x1
73 u16 rev_low; // 0x2
74 RSL result_code; // 0x4
75 INSERT_PADDING_BYTES(8); // 0x8
76 u32 pid_low; // 0x10
77 u32 pid_high; // 0x14
78 u32 aid_low; // 0x18
79 u32 aid_high; // 0x1C
80 char debug_string1[0x2E]; // 0x20
81 char debug_string2[0x2E]; // 0x4E
82 } errtype4;
83};
84
85enum {
86 PrefetchAbort = 0,
87 DataAbort = 1,
88 UndefInstr = 2,
89 VectorFP = 3
90};
91
92static std::string GetErrInfo3Type(u8 type_code) {
93 switch (type_code) {
94 case PrefetchAbort: return "Prefetch Abort";
95 case DataAbort: return "Data Abort";
96 case UndefInstr: return "Undefined Instruction";
97 case VectorFP: return "Vector Floating Point";
98 default: return "unknown";
99 }
100}
101
102static void ThrowFatalError(Service::Interface* self) {
103 u32* cmd_buff = Kernel::GetCommandBuffer();
104
105 LOG_CRITICAL(Service_ERR, "Fatal error!");
106 const ErrInfo* errinfo = reinterpret_cast<ErrInfo*>(&cmd_buff[1]);
107
108 switch (errinfo->specifier) {
109 case ErrSpecifier0:
110 case ErrSpecifier1:
111 {
112 const auto& errtype = errinfo->errtype1;
113 LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high);
114 LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16));
115 LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high);
116 LOG_CRITICAL(Service_ERR, "ADR: 0x%08X", errtype.address);
117
118 LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw);
119 LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value());
120 LOG_CRITICAL(Service_ERR, " Summary: %u", errtype.result_code.summary.Value());
121 LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value());
122 LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value());
123 break;
124 }
125
126 case ErrSpecifier3:
127 {
128 const auto& errtype = errinfo->errtype3;
129 LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high);
130 LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16));
131 LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high);
132 LOG_CRITICAL(Service_ERR, "TYPE: %s", GetErrInfo3Type(errtype.error_type).c_str());
133
134 LOG_CRITICAL(Service_ERR, "PC: 0x%08X", errtype.pc);
135 LOG_CRITICAL(Service_ERR, "LR: 0x%08X", errtype.lr);
136 LOG_CRITICAL(Service_ERR, "SP: 0x%08X", errtype.sp);
137 LOG_CRITICAL(Service_ERR, "CPSR: 0x%08X", errtype.cpsr);
138
139 switch (errtype.error_type) {
140 case PrefetchAbort:
141 case DataAbort:
142 LOG_CRITICAL(Service_ERR, "Fault Address: 0x%08X", errtype.fault_addr);
143 LOG_CRITICAL(Service_ERR, "Fault Status Register: 0x%08X", errtype.fault_status_reg);
144 break;
145 case VectorFP:
146 LOG_CRITICAL(Service_ERR, "FPEXC: 0x%08X", errtype.fpexc);
147 LOG_CRITICAL(Service_ERR, "FINST: 0x%08X", errtype.finst);
148 LOG_CRITICAL(Service_ERR, "FINST2: 0x%08X", errtype.finst2);
149 break;
150 }
151 break;
152 }
153
154 case ErrSpecifier4:
155 {
156 const auto& errtype = errinfo->errtype4;
157 LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high);
158 LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16));
159 LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high);
160
161 LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw);
162 LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value());
163 LOG_CRITICAL(Service_ERR, " Summary: %u", errtype.result_code.summary.Value());
164 LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value());
165 LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value());
166
167 LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string1);
168 LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string2);
169 break;
170 }
171 }
172
173 cmd_buff[1] = 0; // No error
174}
175
13const Interface::FunctionInfo FunctionTable[] = { 176const Interface::FunctionInfo FunctionTable[] = {
14 {0x00010800, nullptr, "ThrowFatalError"} 177 {0x00010800, ThrowFatalError, "ThrowFatalError"}
15}; 178};
16 179
17//////////////////////////////////////////////////////////////////////////////////////////////////// 180////////////////////////////////////////////////////////////////////////////////////////////////////