err_f.cpp 6.7 KB

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