aarch64: error: Beautify error printing

Make the printing of errors a bit more descriptive and print the FAR_ELn
register only when strictly required.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
This commit is contained in:
Carlo Caione 2020-11-09 16:00:37 +01:00 committed by Anas Nashif
commit a054e424e4
2 changed files with 103 additions and 82 deletions

View file

@ -17,118 +17,132 @@
LOG_MODULE_DECLARE(os); LOG_MODULE_DECLARE(os);
static void print_EC_cause(uint64_t esr) static void dump_esr(uint64_t esr, bool *dump_far)
{ {
uint32_t EC = (uint32_t)esr >> 26; const char *err;
switch (EC) { switch (ESR_EC(esr)) {
case 0b000000: case 0b000000: /* 0x00 */
LOG_ERR("Unknown reason"); err = "Unknown reason";
break; break;
case 0b000001: case 0b000001: /* 0x01 */
LOG_ERR("Trapped WFI or WFE instruction execution"); err = "Trapped WFI or WFE instruction execution";
break; break;
case 0b000011: case 0b000011: /* 0x03 */
LOG_ERR("Trapped MCR or MRC access with (coproc==0b1111) that " err = "Trapped MCR or MRC access with (coproc==0b1111) that "
"is not reported using EC 0b000000"); "is not reported using EC 0b000000";
break; break;
case 0b000100: case 0b000100: /* 0x04 */
LOG_ERR("Trapped MCRR or MRRC access with (coproc==0b1111) " err = "Trapped MCRR or MRRC access with (coproc==0b1111) "
"that is not reported using EC 0b000000"); "that is not reported using EC 0b000000";
break; break;
case 0b000101: case 0b000101: /* 0x05 */
LOG_ERR("Trapped MCR or MRC access with (coproc==0b1110)"); err = "Trapped MCR or MRC access with (coproc==0b1110)";
break; break;
case 0b000110: case 0b000110: /* 0x06 */
LOG_ERR("Trapped LDC or STC access"); err = "Trapped LDC or STC access";
break; break;
case 0b000111: case 0b000111: /* 0x07 */
LOG_ERR("Trapped access to SVE, Advanced SIMD, or " err = "Trapped access to SVE, Advanced SIMD, or "
"floating-point functionality"); "floating-point functionality";
break; break;
case 0b001100: case 0b001100: /* 0x0c */
LOG_ERR("Trapped MRRC access with (coproc==0b1110)"); err = "Trapped MRRC access with (coproc==0b1110)";
break; break;
case 0b001101: case 0b001101: /* 0x0d */
LOG_ERR("Branch Target Exception"); err = "Branch Target Exception";
break; break;
case 0b001110: case 0b001110: /* 0x0e */
LOG_ERR("Illegal Execution state"); err = "Illegal Execution state";
break; break;
case 0b010001: case 0b010001: /* 0x11 */
LOG_ERR("SVC instruction execution in AArch32 state"); err = "SVC instruction execution in AArch32 state";
break; break;
case 0b011000: case 0b011000: /* 0x18 */
LOG_ERR("Trapped MSR, MRS or System instruction execution in " err = "Trapped MSR, MRS or System instruction execution in "
"AArch64 state, that is not reported using EC " "AArch64 state, that is not reported using EC "
"0b000000, 0b000001 or 0b000111"); "0b000000, 0b000001 or 0b000111";
break; break;
case 0b011001: case 0b011001: /* 0x19 */
LOG_ERR("Trapped access to SVE functionality"); err = "Trapped access to SVE functionality";
break; break;
case 0b100000: case 0b100000: /* 0x20 */
LOG_ERR("Instruction Abort from a lower Exception level, that " *dump_far = true;
"might be using AArch32 or AArch64"); err = "Instruction Abort from a lower Exception level, that "
"might be using AArch32 or AArch64";
break; break;
case 0b100001: case 0b100001: /* 0x21 */
LOG_ERR("Instruction Abort taken without a change in Exception " *dump_far = true;
"level."); err = "Instruction Abort taken without a change in Exception "
"level.";
break; break;
case 0b100010: case 0b100010: /* 0x22 */
LOG_ERR("PC alignment fault exception."); *dump_far = true;
err = "PC alignment fault exception.";
break; break;
case 0b100100: case 0b100100: /* 0x24 */
LOG_ERR("Data Abort from a lower Exception level, that might " *dump_far = true;
"be using AArch32 or AArch64"); err = "Data Abort from a lower Exception level, that might "
"be using AArch32 or AArch64";
break; break;
case 0b100101: case 0b100101: /* 0x25 */
LOG_ERR("Data Abort taken without a change in Exception level"); *dump_far = true;
err = "Data Abort taken without a change in Exception level";
break; break;
case 0b100110: case 0b100110: /* 0x26 */
LOG_ERR("SP alignment fault exception"); err = "SP alignment fault exception";
break; break;
case 0b101000: case 0b101000: /* 0x28 */
LOG_ERR("Trapped floating-point exception taken from AArch32 " err = "Trapped floating-point exception taken from AArch32 "
"state"); "state";
break; break;
case 0b101100: case 0b101100: /* 0x2c */
LOG_ERR("Trapped floating-point exception taken from AArch64 " err = "Trapped floating-point exception taken from AArch64 "
"state."); "state.";
break; break;
case 0b101111: case 0b101111: /* 0x2f */
LOG_ERR("SError interrupt"); err = "SError interrupt";
break; break;
case 0b110000: case 0b110000: /* 0x30 */
LOG_ERR("Breakpoint exception from a lower Exception level, " err = "Breakpoint exception from a lower Exception level, "
"that might be using AArch32 or AArch64"); "that might be using AArch32 or AArch64";
break; break;
case 0b110001: case 0b110001: /* 0x31 */
LOG_ERR("Breakpoint exception taken without a change in " err = "Breakpoint exception taken without a change in "
"Exception level"); "Exception level";
break; break;
case 0b110010: case 0b110010: /* 0x32 */
LOG_ERR("Software Step exception from a lower Exception level, " err = "Software Step exception from a lower Exception level, "
"that might be using AArch32 or AArch64"); "that might be using AArch32 or AArch64";
break; break;
case 0b110011: case 0b110011: /* 0x33 */
LOG_ERR("Software Step exception taken without a change in " err = "Software Step exception taken without a change in "
"Exception level"); "Exception level";
break; break;
case 0b110100: case 0b110100: /* 0x34 */
LOG_ERR("Watchpoint exception from a lower Exception level, " *dump_far = true;
"that might be using AArch32 or AArch64"); err = "Watchpoint exception from a lower Exception level, "
"that might be using AArch32 or AArch64";
break; break;
case 0b110101: case 0b110101: /* 0x35 */
LOG_ERR("Watchpoint exception taken without a change in " *dump_far = true;
"Exception level."); err = "Watchpoint exception taken without a change in "
"Exception level.";
break; break;
case 0b111000: case 0b111000: /* 0x38 */
LOG_ERR("BKPT instruction execution in AArch32 state"); err = "BKPT instruction execution in AArch32 state";
break; break;
case 0b111100: case 0b111100: /* 0x3c */
LOG_ERR("BRK instruction execution in AArch64 state."); err = "BRK instruction execution in AArch64 state.";
break; break;
default:
err = "Unknown";
} }
LOG_ERR("ESR_ELn: 0x%016llx", esr);
LOG_ERR(" EC: 0x%llx (%s)", ESR_EC(esr), err);
LOG_ERR(" IL: 0x%llx", ESR_IL(esr));
LOG_ERR(" ISS: 0x%llx", ESR_ISS(esr));
} }
static void esf_dump(const z_arch_esf_t *esf) static void esf_dump(const z_arch_esf_t *esf)
@ -179,11 +193,14 @@ void z_arm64_fatal_error(unsigned int reason, const z_arch_esf_t *esf)
} }
if (GET_EL(el) != MODE_EL0) { if (GET_EL(el) != MODE_EL0) {
LOG_ERR("ESR_ELn: 0x%016llx", esr); bool dump_far = false;
LOG_ERR("FAR_ELn: 0x%016llx", far);
LOG_ERR("ELR_ELn: 0x%016llx", elr); LOG_ERR("ELR_ELn: 0x%016llx", elr);
print_EC_cause(esr); dump_esr(esr, &dump_far);
if (dump_far)
LOG_ERR("FAR_ELn: 0x%016llx", far);
} }
} }

View file

@ -160,6 +160,10 @@
#define GET_EL(_mode) (((_mode) >> MODE_EL_SHIFT) & MODE_EL_MASK) #define GET_EL(_mode) (((_mode) >> MODE_EL_SHIFT) & MODE_EL_MASK)
#define ESR_EC(esr) (((esr) >> 26) & BIT_MASK(6))
#define ESR_IL(esr) (((esr) >> 25) & BIT_MASK(1))
#define ESR_ISS(esr) ((esr) & BIT_MASK(25))
/* mpidr */ /* mpidr */
#define MPIDR_AFFLVL_MASK 0xff #define MPIDR_AFFLVL_MASK 0xff