diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c index 35c37f667781c7071c714aef274e68dbddca026b..5d97c1b909de995da8d9a3a4f3ffc4bff83f6dc7 100644 --- a/drivers/firmware/efi/cper.c +++ b/drivers/firmware/efi/cper.c @@ -141,8 +141,59 @@ static const char * const proc_flag_strs[] = { "corrected", }; +#if IS_ENABLED(CONFIG_X86) +static const char * const zdi_zpi_err_type_strs[] = { + "No Error", + "Training Error Status (PHY)", + "Data Link Protocol Error Status (DLL)", + "Surprise Down Error Status", + "Flow Control Protocol Error Status (TL)", + "Receiver Overflow Status (TL)", + "Receiver Error Status (PHY)", + "Bad TLP Status (DLL)", + "Bad Data Link Layer Packet (DLLP) Status (DLL)", + "REPLAY_NUM Rollover Status (DLL)", + "Replay Timer Timeout Status (DLL)", + "X16 Link Width Unreliable Status", + "ZPI X8 Link Width Unreliable Status", + "ZPI X4 Link Width Unreliable Status", + "ZPI X2 Link Width Unreliable Status", + "ZPI Gen3 Link Speed Unreliable Status", + "ZPI Gen2 Link Speed Unreliable Status", + "ZDI Gen3 Link Speed Unreliable Status", + "ZDI Gen4 Link Speed Unreliable Status", +}; + +const char *cper_zdi_zpi_err_type_str(unsigned int etype) +{ + return etype < ARRAY_SIZE(zdi_zpi_err_type_strs) ? + zdi_zpi_err_type_strs[etype] : "unknown error"; +} +EXPORT_SYMBOL_GPL(cper_zdi_zpi_err_type_str); + +static void cper_print_proc_generic_zdi_zpi(const char *pfx, + const struct cper_sec_proc_generic *zdi_zpi) +{ + u8 etype = zdi_zpi->responder_id; + + if ((zdi_zpi->requestor_id & 0xff) == 7) + pr_info("%s general processor error(zpi error)\n", pfx); + else if ((zdi_zpi->requestor_id & 0xff) == 6) + pr_info("%s general processor error(zdi error)\n", pfx); + else { + pr_info("%s general processor error(unknown error)\n", pfx); + return; + } + pr_info("%s bus number %llx device number %llx function number 0\n", + pfx, ((zdi_zpi->requestor_id)>>8) & 0xff, + zdi_zpi->requestor_id & 0xff); + pr_info("%s apic id %lld error_type: %s\n", pfx, + zdi_zpi->proc_id, cper_zdi_zpi_err_type_str(etype)); +} +#endif + static void cper_print_proc_generic(const char *pfx, - const struct cper_sec_proc_generic *proc) + const struct cper_sec_proc_generic *proc) { if (proc->validation_bits & CPER_PROC_VALID_TYPE) printk("%s""processor_type: %d, %s\n", pfx, proc->proc_type, @@ -184,6 +235,11 @@ static void cper_print_proc_generic(const char *pfx, pfx, proc->responder_id); if (proc->validation_bits & CPER_PROC_VALID_IP) printk("%s""IP: 0x%016llx\n", pfx, proc->ip); +#if IS_ENABLED(CONFIG_X86) + if (boot_cpu_data.x86_vendor == X86_VENDOR_ZHAOXIN || + boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR) + cper_print_proc_generic_zdi_zpi(pfx, proc); +#endif } static const char * const mem_err_type_strs[] = { diff --git a/include/linux/cper.h b/include/linux/cper.h index c1a7dc3251215a5ba0e982568a746ff5b04602d1..5b5e70a25d1c74d4c4661fef8dd432897622ce88 100644 --- a/include/linux/cper.h +++ b/include/linux/cper.h @@ -578,4 +578,7 @@ void cper_estatus_print(const char *pfx, int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus); int cper_estatus_check(const struct acpi_hest_generic_status *estatus); +#if IS_ENABLED(CONFIG_X86) +const char *cper_zdi_zpi_err_type_str(unsigned int etype); +#endif #endif