Index: sys/arm64/arm64/trap.c =================================================================== --- sys/arm64/arm64/trap.c +++ sys/arm64/arm64/trap.c @@ -617,15 +617,39 @@ void do_serror(struct trapframe *frame) { + const char *err_str = "Unhandled System Error"; uint64_t esr, far; far = READ_SPECIALREG(far_el1); esr = frame->tf_esr; - print_registers(frame); - printf(" far: %16lx\n", far); - printf(" esr: %.8lx\n", esr); - panic("Unhandled System Error"); + if (ESR_ELx_EXCEPTION(esr) == EXCP_SERROR && + (esr & ISS_DATA_DFSC_MASK) == ISS_SERROR_DFSC_ASI) { + switch(ISS_SERROR_AET(esr)) { + case ISS_SERROR_AET_CE: /* Corrected error */ + case ISS_SERROR_AET_UEO: /* Restartable error */ + err_str = NULL; + break; + + /* + * These errors are uncorrected and unrestartable. Without + * support to correct them the best we can do is to panic + * the kernel. + */ + case ISS_SERROR_AET_UC: + case ISS_SERROR_AET_UEU: + case ISS_SERROR_AET_UER: + err_str = "Uncorrected RAS System Error"; + break; + } + } + + if (err_str != NULL) { + print_registers(frame); + printf(" far: %16lx\n", far); + printf(" esr: %.8lx\n", esr); + panic("%s", err_str); + } } void Index: sys/arm64/include/armreg.h =================================================================== --- sys/arm64/include/armreg.h +++ sys/arm64/include/armreg.h @@ -213,6 +213,17 @@ #define ISS_DATA_DFSC_ECC_L3 (0x1f << 0) #define ISS_DATA_DFSC_ALIGN (0x21 << 0) #define ISS_DATA_DFSC_TLB_CONFLICT (0x30 << 0) + +#define ISS_SERROR_AET_SHIFT 10 +#define ISS_SERROR_AET_MASK (0x7 << ISS_SERROR_AET_SHIFT) +#define ISS_SERROR_AET(esr) ((esr) & ISS_SERROR_AET_MASK) +#define ISS_SERROR_AET_UC (0x0 << ISS_SERROR_AET_SHIFT) +#define ISS_SERROR_AET_UEU (0x1 << ISS_SERROR_AET_SHIFT) +#define ISS_SERROR_AET_UEO (0x2 << ISS_SERROR_AET_SHIFT) +#define ISS_SERROR_AET_UER (0x3 << ISS_SERROR_AET_SHIFT) +#define ISS_SERROR_AET_CE (0x6 << ISS_SERROR_AET_SHIFT) +#define ISS_SERROR_DFSC_ASI (0x81 << 0) /* Asynchronous SError interrupt */ + #define ESR_ELx_IL (0x01 << 25) #define ESR_ELx_EC_SHIFT 26 #define ESR_ELx_EC_MASK (0x3f << 26)