Added information reporting from ThrowFatalError
This was RE'd from the errdisp applet.
This commit is contained in:
		
							parent
							
								
									ec8f2210e3
								
							
						
					
					
						commit
						0420a4d1de
					
				@ -14,8 +14,6 @@
 | 
			
		||||
#define SLEEP(x) usleep(x*1000)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template <bool> struct CompileTimeAssert;
 | 
			
		||||
template<> struct CompileTimeAssert<true> {};
 | 
			
		||||
 | 
			
		||||
#define b2(x)   (   (x) | (   (x) >> 1) )
 | 
			
		||||
#define b4(x)   ( b2(x) | ( b2(x) >> 2) )
 | 
			
		||||
 | 
			
		||||
@ -33,6 +33,7 @@ static std::shared_ptr<Logger> global_logger;
 | 
			
		||||
        CLS(Service) \
 | 
			
		||||
        SUB(Service, SRV) \
 | 
			
		||||
        SUB(Service, FS) \
 | 
			
		||||
        SUB(Service, ERR) \
 | 
			
		||||
        SUB(Service, APT) \
 | 
			
		||||
        SUB(Service, GSP) \
 | 
			
		||||
        SUB(Service, AC) \
 | 
			
		||||
 | 
			
		||||
@ -53,6 +53,7 @@ enum class Class : ClassType {
 | 
			
		||||
                                ///  should have its own subclass.
 | 
			
		||||
    Service_SRV,                ///< The SRV (Service Directory) implementation
 | 
			
		||||
    Service_FS,                 ///< The FS (Filesystem) service implementation
 | 
			
		||||
    Service_ERR,                ///< The ERR (Error) port implementation
 | 
			
		||||
    Service_APT,                ///< The APT (Applets) service
 | 
			
		||||
    Service_GSP,                ///< The GSP (GPU control) service
 | 
			
		||||
    Service_AC,                 ///< The AC (WiFi status) service
 | 
			
		||||
 | 
			
		||||
@ -10,8 +10,171 @@
 | 
			
		||||
 | 
			
		||||
namespace ERR_F {
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    ErrSpecifier0 = 0,
 | 
			
		||||
    ErrSpecifier1 = 1,
 | 
			
		||||
    ErrSpecifier3 = 3,
 | 
			
		||||
    ErrSpecifier4 = 4,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// This is used instead of ResultCode from result.h
 | 
			
		||||
// because we can't have non-trivial data members in unions.
 | 
			
		||||
union RSL {
 | 
			
		||||
    u32 raw;
 | 
			
		||||
 | 
			
		||||
    BitField<0, 10, u32> description;
 | 
			
		||||
    BitField<10, 8, u32> module;
 | 
			
		||||
    BitField<21, 6, u32> summary;
 | 
			
		||||
    BitField<27, 5, u32> level;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
union ErrInfo {
 | 
			
		||||
    u8 specifier;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        u8 specifier;                // 0x0
 | 
			
		||||
        u8 rev_high;                 // 0x1
 | 
			
		||||
        u16 rev_low;                 // 0x2
 | 
			
		||||
        RSL result_code;             // 0x4
 | 
			
		||||
        u32 address;                 // 0x8
 | 
			
		||||
        INSERT_PADDING_BYTES(4);     // 0xC
 | 
			
		||||
        u32 pid_low;                 // 0x10
 | 
			
		||||
        u32 pid_high;                // 0x14
 | 
			
		||||
        u32 aid_low;                 // 0x18
 | 
			
		||||
        u32 aid_high;                // 0x1C
 | 
			
		||||
    } errtype1;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        u8 specifier;                // 0x0
 | 
			
		||||
        u8 rev_high;                 // 0x1
 | 
			
		||||
        u16 rev_low;                 // 0x2
 | 
			
		||||
        INSERT_PADDING_BYTES(0xC);   // 0x4
 | 
			
		||||
        u32 pid_low;                 // 0x10
 | 
			
		||||
        u32 pid_high;                // 0x14
 | 
			
		||||
        u32 aid_low;                 // 0x18
 | 
			
		||||
        u32 aid_high;                // 0x1C
 | 
			
		||||
        u8 error_type;               // 0x20
 | 
			
		||||
        INSERT_PADDING_BYTES(3);     // 0x21
 | 
			
		||||
        u32 fault_status_reg;        // 0x24
 | 
			
		||||
        u32 fault_addr;              // 0x28
 | 
			
		||||
        u32 fpexc;                   // 0x2C
 | 
			
		||||
        u32 finst;                   // 0x30
 | 
			
		||||
        u32 finst2;                  // 0x34
 | 
			
		||||
        INSERT_PADDING_BYTES(0x34);  // 0x38
 | 
			
		||||
        u32 sp;                      // 0x6C
 | 
			
		||||
        u32 pc;                      // 0x70
 | 
			
		||||
        u32 lr;                      // 0x74
 | 
			
		||||
        u32 cpsr;                    // 0x78
 | 
			
		||||
    } errtype3;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        u8 specifier;                // 0x0
 | 
			
		||||
        u8 rev_high;                 // 0x1
 | 
			
		||||
        u16 rev_low;                 // 0x2
 | 
			
		||||
        RSL result_code;             // 0x4
 | 
			
		||||
        INSERT_PADDING_BYTES(8);     // 0x8
 | 
			
		||||
        u32 pid_low;                 // 0x10
 | 
			
		||||
        u32 pid_high;                // 0x14
 | 
			
		||||
        u32 aid_low;                 // 0x18
 | 
			
		||||
        u32 aid_high;                // 0x1C
 | 
			
		||||
        char debug_string1[0x2E];    // 0x20
 | 
			
		||||
        char debug_string2[0x2E];    // 0x4E
 | 
			
		||||
    } errtype4;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PrefetchAbort = 0,
 | 
			
		||||
    DataAbort     = 1,
 | 
			
		||||
    UndefInstr    = 2,
 | 
			
		||||
    VectorFP      = 3
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static std::string GetErrInfo3Type(u8 type_code) {
 | 
			
		||||
    switch (type_code) {
 | 
			
		||||
    case PrefetchAbort: return "Prefetch Abort";
 | 
			
		||||
    case DataAbort:     return "Data Abort";
 | 
			
		||||
    case UndefInstr:    return "Undefined Instruction";
 | 
			
		||||
    case VectorFP:      return "Vector Floating Point";
 | 
			
		||||
    default: return "unknown";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ThrowFatalError(Service::Interface* self) {
 | 
			
		||||
    u32* cmd_buff = Kernel::GetCommandBuffer();
 | 
			
		||||
 | 
			
		||||
    LOG_CRITICAL(Service_ERR, "Fatal error!");
 | 
			
		||||
    const ErrInfo* errinfo = reinterpret_cast<ErrInfo*>(&cmd_buff[1]);
 | 
			
		||||
 | 
			
		||||
    switch (errinfo->specifier) {
 | 
			
		||||
    case ErrSpecifier0:
 | 
			
		||||
    case ErrSpecifier1:
 | 
			
		||||
    {
 | 
			
		||||
        const auto& errtype = errinfo->errtype1;
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high);
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16));
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high);
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "ADR: 0x%08X", errtype.address);
 | 
			
		||||
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw);
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "  Level: %u",   errtype.result_code.level.Value());
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "  Summary: %u", errtype.result_code.summary.Value());
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "  Module: %u",  errtype.result_code.module.Value());
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "  Desc: %u",    errtype.result_code.description.Value());
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case ErrSpecifier3:
 | 
			
		||||
    {
 | 
			
		||||
        const auto& errtype = errinfo->errtype3;
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high);
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16));
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high);
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "TYPE: %s", GetErrInfo3Type(errtype.error_type).c_str());
 | 
			
		||||
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "PC: 0x%08X", errtype.pc);
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "LR: 0x%08X", errtype.lr);
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "SP: 0x%08X", errtype.sp);
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "CPSR: 0x%08X", errtype.cpsr);
 | 
			
		||||
 | 
			
		||||
        switch (errtype.error_type) {
 | 
			
		||||
        case PrefetchAbort:
 | 
			
		||||
        case DataAbort:
 | 
			
		||||
            LOG_CRITICAL(Service_ERR, "Fault Address: 0x%08X", errtype.fault_addr);
 | 
			
		||||
            LOG_CRITICAL(Service_ERR, "Fault Status Register: 0x%08X", errtype.fault_status_reg);
 | 
			
		||||
            break;
 | 
			
		||||
        case VectorFP:
 | 
			
		||||
            LOG_CRITICAL(Service_ERR, "FPEXC: 0x%08X", errtype.fpexc);
 | 
			
		||||
            LOG_CRITICAL(Service_ERR, "FINST: 0x%08X", errtype.finst);
 | 
			
		||||
            LOG_CRITICAL(Service_ERR, "FINST2: 0x%08X", errtype.finst2);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case ErrSpecifier4:
 | 
			
		||||
    {
 | 
			
		||||
        const auto& errtype = errinfo->errtype4;
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high);
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16));
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high);
 | 
			
		||||
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw);
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "  Level: %u",   errtype.result_code.level.Value());
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "  Summary: %u", errtype.result_code.summary.Value());
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "  Module: %u",  errtype.result_code.module.Value());
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "  Desc: %u",    errtype.result_code.description.Value());
 | 
			
		||||
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string1);
 | 
			
		||||
        LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string2);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmd_buff[1] = 0; // No error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Interface::FunctionInfo FunctionTable[] = {
 | 
			
		||||
    {0x00010800, nullptr,               "ThrowFatalError"}
 | 
			
		||||
    {0x00010800, ThrowFatalError,           "ThrowFatalError"}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user