summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar JamePeng2016-10-02 16:04:50 +0800
committerGravatar JamePeng2016-10-06 21:03:12 +0800
commit691f069743bd0cf06cb070ee14c8e4ef51977550 (patch)
treedbae4310088f9365fcee7b2bb851851d664d85fd /src
parentMerge pull request #1652 from wwylele/kernal-tool (diff)
downloadyuzu-691f069743bd0cf06cb070ee14c8e4ef51977550.tar.gz
yuzu-691f069743bd0cf06cb070ee14c8e4ef51977550.tar.xz
yuzu-691f069743bd0cf06cb070ee14c8e4ef51977550.zip
Rework the code of err:f service
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/err_f.cpp316
1 files changed, 198 insertions, 118 deletions
diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp
index 3ca4f98de..9905757c7 100644
--- a/src/core/hle/service/err_f.cpp
+++ b/src/core/hle/service/err_f.cpp
@@ -2,9 +2,15 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <array>
6#include <chrono>
7#include <iomanip>
8#include <sstream>
9
5#include "common/bit_field.h" 10#include "common/bit_field.h"
6#include "common/common_types.h" 11#include "common/common_types.h"
7#include "common/logging/log.h" 12#include "common/logging/log.h"
13#include "core/hle/result.h"
8#include "core/hle/service/err_f.h" 14#include "core/hle/service/err_f.h"
9 15
10//////////////////////////////////////////////////////////////////////////////////////////////////// 16////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -12,12 +18,45 @@
12 18
13namespace ERR_F { 19namespace ERR_F {
14 20
15enum { 21enum class FatalErrType : u32 {
16 ErrSpecifier0 = 0, 22 Generic = 0,
17 ErrSpecifier1 = 1, 23 Corrupted = 1,
18 ErrSpecifier3 = 3, 24 CardRemoved = 2,
19 ErrSpecifier4 = 4, 25 Exception = 3,
26 ResultFailure = 4,
27 Logged = 5,
28};
29
30enum class ExceptionType : u32 {
31 PrefetchAbort = 0,
32 DataAbort = 1,
33 Undefined = 2,
34 VectorFP = 3,
35};
36
37struct ExceptionInfo {
38 u8 exception_type;
39 INSERT_PADDING_BYTES(3);
40 u32 sr;
41 u32 ar;
42 u32 fpexc;
43 u32 fpinst;
44 u32 fpinst2;
45};
46static_assert(sizeof(ExceptionInfo) == 0x18, "ExceptionInfo struct has incorrect size");
47
48struct ExceptionContext final {
49 std::array<u32, 16> arm_regs;
50 u32 cpsr;
20}; 51};
52static_assert(sizeof(ExceptionContext) == 0x44, "ExceptionContext struct has incorrect size");
53
54struct ExceptionData {
55 ExceptionInfo exception_info;
56 ExceptionContext exception_context;
57 INSERT_PADDING_WORDS(1);
58};
59static_assert(sizeof(ExceptionData) == 0x60, "ExceptionData struct has incorrect size");
21 60
22// This is used instead of ResultCode from result.h 61// This is used instead of ResultCode from result.h
23// because we can't have non-trivial data members in unions. 62// because we can't have non-trivial data members in unions.
@@ -30,150 +69,191 @@ union RSL {
30 BitField<27, 5, u32> level; 69 BitField<27, 5, u32> level;
31}; 70};
32 71
33union ErrInfo { 72struct ErrInfo {
34 u8 specifier; 73 struct ErrInfoCommon {
35 74 u8 specifier; // 0x0
36 struct { 75 u8 rev_high; // 0x1
37 u8 specifier; // 0x0 76 u16 rev_low; // 0x2
38 u8 rev_high; // 0x1 77 RSL result_code; // 0x4
39 u16 rev_low; // 0x2 78 u32 pc_address; // 0x8
40 RSL result_code; // 0x4 79 u32 pid; // 0xC
41 u32 address; // 0x8 80 u32 title_id_low; // 0x10
42 INSERT_PADDING_BYTES(4); // 0xC 81 u32 title_id_high; // 0x14
43 u32 pid_low; // 0x10 82 u32 app_title_id_low; // 0x18
44 u32 pid_high; // 0x14 83 u32 app_title_id_high; // 0x1C
45 u32 aid_low; // 0x18 84 } errinfo_common;
46 u32 aid_high; // 0x1C 85 static_assert(sizeof(ErrInfoCommon) == 0x20, "ErrInfoCommon struct has incorrect size");
47 } errtype1; 86
48 87 union {
49 struct { 88 struct {
50 u8 specifier; // 0x0 89 char data[0x60]; // 0x20
51 u8 rev_high; // 0x1 90 } generic;
52 u16 rev_low; // 0x2 91
53 INSERT_PADDING_BYTES(0xC); // 0x4 92 struct {
54 u32 pid_low; // 0x10 93 ExceptionData exception_data; // 0x20
55 u32 pid_high; // 0x14 94 } exception;
56 u32 aid_low; // 0x18 95
57 u32 aid_high; // 0x1C 96 struct {
58 u8 error_type; // 0x20 97 char message[0x60]; // 0x20
59 INSERT_PADDING_BYTES(3); // 0x21 98 } result_failure;
60 u32 fault_status_reg; // 0x24 99 };
61 u32 fault_addr; // 0x28
62 u32 fpexc; // 0x2C
63 u32 finst; // 0x30
64 u32 finst2; // 0x34
65 INSERT_PADDING_BYTES(0x34); // 0x38
66 u32 sp; // 0x6C
67 u32 pc; // 0x70
68 u32 lr; // 0x74
69 u32 cpsr; // 0x78
70 } errtype3;
71
72 struct {
73 u8 specifier; // 0x0
74 u8 rev_high; // 0x1
75 u16 rev_low; // 0x2
76 RSL result_code; // 0x4
77 INSERT_PADDING_BYTES(8); // 0x8
78 u32 pid_low; // 0x10
79 u32 pid_high; // 0x14
80 u32 aid_low; // 0x18
81 u32 aid_high; // 0x1C
82 char debug_string1[0x2E]; // 0x20
83 char debug_string2[0x2E]; // 0x4E
84 } errtype4;
85}; 100};
86 101
87enum { PrefetchAbort = 0, DataAbort = 1, UndefInstr = 2, VectorFP = 3 }; 102static std::string GetErrType(u8 type_code) {
103 switch (static_cast<FatalErrType>(type_code)) {
104 case FatalErrType::Generic:
105 return "Generic";
106 case FatalErrType::Corrupted:
107 return "Corrupted";
108 case FatalErrType::CardRemoved:
109 return "CardRemoved";
110 case FatalErrType::Exception:
111 return "Exception";
112 case FatalErrType::ResultFailure:
113 return "ResultFailure";
114 case FatalErrType::Logged:
115 return "Logged";
116 default:
117 return "Unknown Error Type";
118 }
119}
88 120
89static std::string GetErrInfo3Type(u8 type_code) { 121static std::string GetExceptionType(u8 type_code) {
90 switch (type_code) { 122 switch (static_cast<ExceptionType>(type_code)) {
91 case PrefetchAbort: 123 case ExceptionType::PrefetchAbort:
92 return "Prefetch Abort"; 124 return "Prefetch Abort";
93 case DataAbort: 125 case ExceptionType::DataAbort:
94 return "Data Abort"; 126 return "Data Abort";
95 case UndefInstr: 127 case ExceptionType::Undefined:
96 return "Undefined Instruction"; 128 return "Undefined Exception";
97 case VectorFP: 129 case ExceptionType::VectorFP:
98 return "Vector Floating Point"; 130 return "Vector Floating Point Exception";
99 default: 131 default:
100 return "unknown"; 132 return "Unknown Exception Type";
101 } 133 }
102} 134}
103 135
136static std::string GetCurrentSystemTime() {
137 auto now = std::chrono::system_clock::now();
138 auto time = std::chrono::system_clock::to_time_t(now);
139
140 std::stringstream time_stream;
141 time_stream << std::put_time(std::localtime(&time), "%Y/%m/%d %H:%M:%S");
142 return time_stream.str();
143}
144
145static void LogGenericInfo(const ErrInfo::ErrInfoCommon& errinfo_common) {
146 LOG_CRITICAL(Service_ERR, "PID: 0x%08X", errinfo_common.pid);
147 LOG_CRITICAL(Service_ERR, "REV: 0x%08X_0x%08X", errinfo_common.rev_high,
148 errinfo_common.rev_low);
149 LOG_CRITICAL(Service_ERR, "TID: 0x%08X_0x%08X", errinfo_common.title_id_high,
150 errinfo_common.title_id_low);
151 LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errinfo_common.app_title_id_high,
152 errinfo_common.app_title_id_low);
153 LOG_CRITICAL(Service_ERR, "ADR: 0x%08X", errinfo_common.pc_address);
154
155 LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errinfo_common.result_code.raw);
156 LOG_CRITICAL(Service_ERR, " Level: %u", errinfo_common.result_code.level.Value());
157 LOG_CRITICAL(Service_ERR, " Summary: %u", errinfo_common.result_code.summary.Value());
158 LOG_CRITICAL(Service_ERR, " Module: %u", errinfo_common.result_code.module.Value());
159 LOG_CRITICAL(Service_ERR, " Desc: %u", errinfo_common.result_code.description.Value());
160}
161
162/* ThrowFatalError function
163 * Inputs:
164 * 0 : Header code [0x00010800]
165 * 1-32 : FatalErrInfo
166 * Outputs:
167 * 0 : Header code
168 * 1 : Result code
169 */
104static void ThrowFatalError(Service::Interface* self) { 170static void ThrowFatalError(Service::Interface* self) {
105 u32* cmd_buff = Kernel::GetCommandBuffer(); 171 u32* cmd_buff = Kernel::GetCommandBuffer();
106 172
107 LOG_CRITICAL(Service_ERR, "Fatal error!"); 173 LOG_CRITICAL(Service_ERR, "Fatal error");
108 const ErrInfo* errinfo = reinterpret_cast<ErrInfo*>(&cmd_buff[1]); 174 const ErrInfo* errinfo = reinterpret_cast<ErrInfo*>(&cmd_buff[1]);
175 LOG_CRITICAL(Service_ERR, "Fatal error type: %s",
176 GetErrType(errinfo->errinfo_common.specifier).c_str());
109 177
110 switch (errinfo->specifier) { 178 // Generic Info
111 case ErrSpecifier0: 179 LogGenericInfo(errinfo->errinfo_common);
112 case ErrSpecifier1: { 180
113 const auto& errtype = errinfo->errtype1; 181 switch (static_cast<FatalErrType>(errinfo->errinfo_common.specifier)) {
114 LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high); 182 case FatalErrType::Generic:
115 LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16)); 183 case FatalErrType::Corrupted:
116 LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high); 184 case FatalErrType::CardRemoved:
117 LOG_CRITICAL(Service_ERR, "ADR: 0x%08X", errtype.address); 185 case FatalErrType::Logged: {
118 186 LOG_CRITICAL(Service_ERR, "Datetime: %s", GetCurrentSystemTime().c_str());
119 LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw);
120 LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value());
121 LOG_CRITICAL(Service_ERR, " Summary: %u", errtype.result_code.summary.Value());
122 LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value());
123 LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value());
124 break; 187 break;
125 } 188 }
189 case FatalErrType::Exception: {
190 const auto& errtype = errinfo->exception;
191
192 // Register Info
193 LOG_CRITICAL(Service_ERR, "ARM Registers:");
194 for (u32 index = 0; index < errtype.exception_data.exception_context.arm_regs.size();
195 ++index) {
196 if (index < 13) {
197 LOG_DEBUG(Service_ERR, "r%u=0x%08X", index,
198 errtype.exception_data.exception_context.arm_regs.at(index));
199 } else if (index == 13) {
200 LOG_CRITICAL(Service_ERR, "SP=0x%08X",
201 errtype.exception_data.exception_context.arm_regs.at(index));
202 } else if (index == 14) {
203 LOG_CRITICAL(Service_ERR, "LR=0x%08X",
204 errtype.exception_data.exception_context.arm_regs.at(index));
205 } else if (index == 15) {
206 LOG_CRITICAL(Service_ERR, "PC=0x%08X",
207 errtype.exception_data.exception_context.arm_regs.at(index));
208 }
209 }
210 LOG_CRITICAL(Service_ERR, "CPSR=0x%08X", errtype.exception_data.exception_context.cpsr);
126 211
127 case ErrSpecifier3: { 212 // Exception Info
128 const auto& errtype = errinfo->errtype3; 213 LOG_CRITICAL(
129 LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high); 214 Service_ERR, "EXCEPTION TYPE: %s",
130 LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16)); 215 GetExceptionType(errtype.exception_data.exception_info.exception_type).c_str());
131 LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high); 216 switch (static_cast<ExceptionType>(errtype.exception_data.exception_info.exception_type)) {
132 LOG_CRITICAL(Service_ERR, "TYPE: %s", GetErrInfo3Type(errtype.error_type).c_str()); 217 case ExceptionType::PrefetchAbort:
133 218 LOG_CRITICAL(Service_ERR, "IFSR: 0x%08X", errtype.exception_data.exception_info.sr);
134 LOG_CRITICAL(Service_ERR, "PC: 0x%08X", errtype.pc); 219 LOG_CRITICAL(Service_ERR, "r15: 0x%08X", errtype.exception_data.exception_info.ar);
135 LOG_CRITICAL(Service_ERR, "LR: 0x%08X", errtype.lr); 220 case ExceptionType::DataAbort:
136 LOG_CRITICAL(Service_ERR, "SP: 0x%08X", errtype.sp); 221 LOG_CRITICAL(Service_ERR, "DFSR: 0x%08X", errtype.exception_data.exception_info.sr);
137 LOG_CRITICAL(Service_ERR, "CPSR: 0x%08X", errtype.cpsr); 222 LOG_CRITICAL(Service_ERR, "DFAR: 0x%08X", errtype.exception_data.exception_info.ar);
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; 223 break;
145 case VectorFP: 224 case ExceptionType::VectorFP:
146 LOG_CRITICAL(Service_ERR, "FPEXC: 0x%08X", errtype.fpexc); 225 LOG_CRITICAL(Service_ERR, "FPEXC: 0x%08X",
147 LOG_CRITICAL(Service_ERR, "FINST: 0x%08X", errtype.finst); 226 errtype.exception_data.exception_info.fpinst);
148 LOG_CRITICAL(Service_ERR, "FINST2: 0x%08X", errtype.finst2); 227 LOG_CRITICAL(Service_ERR, "FINST: 0x%08X",
228 errtype.exception_data.exception_info.fpinst);
229 LOG_CRITICAL(Service_ERR, "FINST2: 0x%08X",
230 errtype.exception_data.exception_info.fpinst2);
149 break; 231 break;
150 } 232 }
233 LOG_CRITICAL(Service_ERR, "Datetime: %s", GetCurrentSystemTime().c_str());
151 break; 234 break;
152 } 235 }
153 236
154 case ErrSpecifier4: { 237 case FatalErrType::ResultFailure: {
155 const auto& errtype = errinfo->errtype4; 238 const auto& errtype = errinfo->result_failure;
156 LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high);
157 LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16));
158 LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high);
159 239
160 LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw); 240 // Failure Message
161 LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value()); 241 LOG_CRITICAL(Service_ERR, "Failure Message: %s", errtype.message);
162 LOG_CRITICAL(Service_ERR, " Summary: %u", errtype.result_code.summary.Value()); 242 LOG_CRITICAL(Service_ERR, "Datetime: %s", GetCurrentSystemTime().c_str());
163 LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value());
164 LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value());
165
166 LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string1);
167 LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string2);
168 break; 243 break;
169 } 244 }
170 }
171 245
172 cmd_buff[1] = 0; // No error 246 } // switch FatalErrType
247
248 cmd_buff[0] = IPC::MakeHeader(0x1, 1, 0);
249 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
173} 250}
174 251
175const Interface::FunctionInfo FunctionTable[] = { 252const Interface::FunctionInfo FunctionTable[] = {
253 // clang-format off
176 {0x00010800, ThrowFatalError, "ThrowFatalError"}, 254 {0x00010800, ThrowFatalError, "ThrowFatalError"},
255 {0x00020042, nullptr, "SetUserString"},
256 // clang-format on
177}; 257};
178 258
179//////////////////////////////////////////////////////////////////////////////////////////////////// 259////////////////////////////////////////////////////////////////////////////////////////////////////