err_f.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "common/logging/log.h"
  5. #include "core/hle/hle.h"
  6. #include "core/hle/service/err_f.h"
  7. ////////////////////////////////////////////////////////////////////////////////////////////////////
  8. // Namespace ERR_F
  9. namespace ERR_F {
  10. enum {
  11. ErrSpecifier0 = 0,
  12. ErrSpecifier1 = 1,
  13. ErrSpecifier3 = 3,
  14. ErrSpecifier4 = 4,
  15. };
  16. // This is used instead of ResultCode from result.h
  17. // because we can't have non-trivial data members in unions.
  18. union RSL {
  19. u32 raw;
  20. BitField<0, 10, u32> description;
  21. BitField<10, 8, u32> module;
  22. BitField<21, 6, u32> summary;
  23. BitField<27, 5, u32> level;
  24. };
  25. union ErrInfo {
  26. u8 specifier;
  27. struct {
  28. u8 specifier; // 0x0
  29. u8 rev_high; // 0x1
  30. u16 rev_low; // 0x2
  31. RSL result_code; // 0x4
  32. u32 address; // 0x8
  33. INSERT_PADDING_BYTES(4); // 0xC
  34. u32 pid_low; // 0x10
  35. u32 pid_high; // 0x14
  36. u32 aid_low; // 0x18
  37. u32 aid_high; // 0x1C
  38. } errtype1;
  39. struct {
  40. u8 specifier; // 0x0
  41. u8 rev_high; // 0x1
  42. u16 rev_low; // 0x2
  43. INSERT_PADDING_BYTES(0xC); // 0x4
  44. u32 pid_low; // 0x10
  45. u32 pid_high; // 0x14
  46. u32 aid_low; // 0x18
  47. u32 aid_high; // 0x1C
  48. u8 error_type; // 0x20
  49. INSERT_PADDING_BYTES(3); // 0x21
  50. u32 fault_status_reg; // 0x24
  51. u32 fault_addr; // 0x28
  52. u32 fpexc; // 0x2C
  53. u32 finst; // 0x30
  54. u32 finst2; // 0x34
  55. INSERT_PADDING_BYTES(0x34); // 0x38
  56. u32 sp; // 0x6C
  57. u32 pc; // 0x70
  58. u32 lr; // 0x74
  59. u32 cpsr; // 0x78
  60. } errtype3;
  61. struct {
  62. u8 specifier; // 0x0
  63. u8 rev_high; // 0x1
  64. u16 rev_low; // 0x2
  65. RSL result_code; // 0x4
  66. INSERT_PADDING_BYTES(8); // 0x8
  67. u32 pid_low; // 0x10
  68. u32 pid_high; // 0x14
  69. u32 aid_low; // 0x18
  70. u32 aid_high; // 0x1C
  71. char debug_string1[0x2E]; // 0x20
  72. char debug_string2[0x2E]; // 0x4E
  73. } errtype4;
  74. };
  75. enum {
  76. PrefetchAbort = 0,
  77. DataAbort = 1,
  78. UndefInstr = 2,
  79. VectorFP = 3
  80. };
  81. static std::string GetErrInfo3Type(u8 type_code) {
  82. switch (type_code) {
  83. case PrefetchAbort: return "Prefetch Abort";
  84. case DataAbort: return "Data Abort";
  85. case UndefInstr: return "Undefined Instruction";
  86. case VectorFP: return "Vector Floating Point";
  87. default: return "unknown";
  88. }
  89. }
  90. static void ThrowFatalError(Service::Interface* self) {
  91. u32* cmd_buff = Kernel::GetCommandBuffer();
  92. LOG_CRITICAL(Service_ERR, "Fatal error!");
  93. const ErrInfo* errinfo = reinterpret_cast<ErrInfo*>(&cmd_buff[1]);
  94. switch (errinfo->specifier) {
  95. case ErrSpecifier0:
  96. case ErrSpecifier1:
  97. {
  98. const auto& errtype = errinfo->errtype1;
  99. LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high);
  100. LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16));
  101. LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high);
  102. LOG_CRITICAL(Service_ERR, "ADR: 0x%08X", errtype.address);
  103. LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw);
  104. LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value());
  105. LOG_CRITICAL(Service_ERR, " Summary: %u", errtype.result_code.summary.Value());
  106. LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value());
  107. LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value());
  108. break;
  109. }
  110. case ErrSpecifier3:
  111. {
  112. const auto& errtype = errinfo->errtype3;
  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, "TYPE: %s", GetErrInfo3Type(errtype.error_type).c_str());
  117. LOG_CRITICAL(Service_ERR, "PC: 0x%08X", errtype.pc);
  118. LOG_CRITICAL(Service_ERR, "LR: 0x%08X", errtype.lr);
  119. LOG_CRITICAL(Service_ERR, "SP: 0x%08X", errtype.sp);
  120. LOG_CRITICAL(Service_ERR, "CPSR: 0x%08X", errtype.cpsr);
  121. switch (errtype.error_type) {
  122. case PrefetchAbort:
  123. case DataAbort:
  124. LOG_CRITICAL(Service_ERR, "Fault Address: 0x%08X", errtype.fault_addr);
  125. LOG_CRITICAL(Service_ERR, "Fault Status Register: 0x%08X", errtype.fault_status_reg);
  126. break;
  127. case VectorFP:
  128. LOG_CRITICAL(Service_ERR, "FPEXC: 0x%08X", errtype.fpexc);
  129. LOG_CRITICAL(Service_ERR, "FINST: 0x%08X", errtype.finst);
  130. LOG_CRITICAL(Service_ERR, "FINST2: 0x%08X", errtype.finst2);
  131. break;
  132. }
  133. break;
  134. }
  135. case ErrSpecifier4:
  136. {
  137. const auto& errtype = errinfo->errtype4;
  138. LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high);
  139. LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16));
  140. LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high);
  141. LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw);
  142. LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value());
  143. LOG_CRITICAL(Service_ERR, " Summary: %u", errtype.result_code.summary.Value());
  144. LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value());
  145. LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value());
  146. LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string1);
  147. LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string2);
  148. break;
  149. }
  150. }
  151. cmd_buff[1] = 0; // No error
  152. }
  153. const Interface::FunctionInfo FunctionTable[] = {
  154. {0x00010800, ThrowFatalError, "ThrowFatalError"}
  155. };
  156. ////////////////////////////////////////////////////////////////////////////////////////////////////
  157. // Interface class
  158. Interface::Interface() {
  159. Register(FunctionTable);
  160. }
  161. } // namespace