[SWDEV-522623] Add afid functionality to API and CLI (#330)

Change-Id: I015bde926491d54e09da8f39b05650515711e09f

[SWDEV-522623] Add afid functionality to API and CLI


Change-Id: I015bde926491d54e09da8f39b05650515711e09f

Signed-off-by: Oosman Saeed <oossaeed@amd.com>
Co-authored-by: Oosman Saeed <oossaeed@amd.com>
Этот коммит содержится в:
Saeed, OosmanиOosman Saeed authored and GitHub committed 2025-05-16 10:49:56 +08:00
1 родитель d4f057f95f
Коммит 1bb1f8acc2
21 file changed
+2228 -209

No files matched your search

+285
Просмотреть файл
@@ -0,0 +1,285 @@
/**
* @file aca_decode.c
* @brief Implementation of ACA error decoding functions
*
* This file contains functions for decoding and analyzing ACA error information from
* raw register data. It provides functionality to determine error severity, bank
* information, and specific error types based on hardware-specific error codes.
*/
#include "aca_decode.h"
#include "aca_tables.h"
#include "error_map.h"
#include <string.h>
/**
* @brief Gets the bank name based on hardware ID and ACA type
* @param[in] decoder Pointer to the ACA decoder structure
* @param[out] bank_name Pointer to a string containing the bank name
* @return 0 on success, -1 on failure
*/
static int
aca_decoder_get_bank(const aca_decoder_t *decoder, const char **bank_name)
{
if (!decoder || !bank_name)
{
return -1;
}
const aca_ipid_fields_t *ipid = &decoder->ipid;
return find_bank_name(ipid->hardware_id, ipid->aca_type, bank_name);
}
/**
* @brief Determines the error severity based on status fields
* @param[in] status Pointer to the ACA status fields structure
* @return String indicating error severity: "Fatal", "Uncorrected, Non-fatal", "Corrected", or "UNKNOWN"
*/
static const char *get_error_severity(const aca_status_fields_t *status)
{
if (status->poison)
return "Uncorrected, Non-fatal";
if (status->pcc)
return "Fatal";
if (!status->pcc && status->uc && status->tcc)
return "Fatal";
if (!status->pcc && status->uc && !status->tcc)
return "Uncorrected, Non-fatal";
if (!status->pcc && !status->uc && !status->tcc && status->deferred)
return "Uncorrected, Non-fatal";
if (!status->pcc && !status->uc && !status->tcc && !status->deferred)
return "Corrected";
return "UNKNOWN";
}
/**
* @brief Determines the error category based on bank and error type
* @param[in] bank Pointer to the bank name
* @param[in] error_type Pointer to the error type
* @return String indicating error category: "HBM Errors", "Off-Package Link Errors", or "Device Internal Errors"
*/
static const char *get_error_category(const char *bank, const char *error_type)
{
if (!bank || !error_type)
{
return "UNKNOWN";
}
if (strcmp(bank, "umc") == 0)
{
if (strcmp(error_type, "On-die ECC") == 0 ||
strcmp(error_type, "WriteDataPoisonErr") == 0 ||
strcmp(error_type, "AddressCommandParityErr") == 0 ||
strcmp(error_type, "WriteDataCrcErr") == 0 ||
strcmp(error_type, "EcsErr") == 0 ||
strcmp(error_type, "RdCrcErr") == 0 ||
strcmp(error_type, "End-to-end CRC") == 0)
{
return "HBM Errors";
}
}
else if (strcmp(bank, "pcs_xgmi") == 0 ||
strcmp(bank, "kpx_serdes") == 0 ||
strcmp(bank, "kpx_wafl") == 0 ||
(strcmp(bank, "psp") == 0 && strcmp(error_type, "WAFL") == 0))
{
return "Off-Package Link Errors";
}
return "Device Internal Errors";
}
/**
* @brief Determines the service error type from error attributes
* @param[in] error_category Pointer to the error category string
* @param[in] error_bank Pointer to the error bank string
* @param[in] error_type Pointer to the error type string
* @param[in] error_severity Pointer to the error severity string
* @param[out] service_error_type Pointer to store the resulting service error type string
* @return 0 on success, non-zero on failure
*/
static int get_service_error_type(const char *error_category, const char *error_bank, const char *error_type,
const char *error_severity, const char **service_error_type)
{
if (!error_category || !error_type || !error_severity || !service_error_type ||
strcmp(error_category, "UNKNOWN") == 0 ||
strcmp(error_type, "UNKNOWN") == 0 ||
strcmp(error_severity, "UNKNOWN") == 0)
{
return -1;
}
if (strcmp(error_type, "Bad Page Retirement Threshold") == 0)
{
*service_error_type = "Bad Page Retirement Threshold";
return 0;
}
if (strcmp(error_type, "RdCrcErr") == 0)
{
*service_error_type = "End-to-end CRC";
return 0;
}
if ((strcmp(error_category, "HBM Errors") == 0) && (strcmp(error_severity, "Corrected") == 0))
{
*service_error_type = "All";
return 0;
}
if ((strcmp(error_category, "HBM Errors") == 0) && (strcmp(error_severity, "Fatal") == 0) &&
(strcmp(error_type, "On-die ECC") != 0) && (strcmp(error_type, "End-to-end CRC") != 0))
{
*service_error_type = "All Others";
return 0;
}
if (strcmp(error_category, "Device Internal Errors") == 0)
{
if ((strcmp(error_severity, "Uncorrected, Non-fatal") == 0 ||
strcmp(error_severity, "Corrected") == 0 ||
strcmp(error_severity, "Fatal") == 0) &&
strcmp(error_type, "Hardware Assertion (HWA)") != 0 &&
strcmp(error_type, "Watchdog Timeout (WDT)") != 0)
{
*service_error_type = "All Others";
return 0;
}
}
if (strcmp(error_category, "Off-Package Link Errors") == 0)
{
if (strcmp(error_bank, "pcs_xgmi") == 0)
{
*service_error_type = "XGMI";
return 0;
}
if (strcmp(error_bank, "kpx_wafl") == 0)
{
*service_error_type = "WAFL";
return 0;
}
}
return -1;
}
/**
* @brief Extracts error information from the decoder and populates the info structure
* @param[in] decoder Pointer to the ACA decoder structure
* @param[out] info Pointer to the error info structure to be populated
*/
static void aca_decoder_get_error_info(const aca_decoder_t *decoder, aca_error_info_t *info)
{
const char *bank;
const char *error_type;
int result;
result = aca_decoder_get_bank(decoder, &bank);
if (result < 0)
{
bank = "UNKNOWN";
}
info->bank_ref = bank;
// 0b1000 indicate error threshold has been exceeded, and is always fatal
if (decoder->flags & 0x8)
{
info->severity_ref = "Fatal";
}
else
{
info->severity_ref = get_error_severity(&decoder->status);
}
if (decoder->status.error_code_ext >= 0x3A && decoder->status.error_code_ext <= 0x3E)
{
uint32_t instance_id = decoder->ipid.instance_id_lo;
uint32_t error_info = decoder->synd.error_information & 0xFF;
if ((instance_id == 0x36430400 || instance_id == 0x38430400 ||
instance_id == 0x36430401 || instance_id == 0x38430401) &&
find_error_in_table(xcd_error_table, NUM_XCD_ERRORS, error_info, &error_type) == 0)
{
info->error_type_ref = error_type;
}
else if ((instance_id == 0x3B30400 || instance_id == 0x3B30401) &&
find_error_in_table(aid_error_table, NUM_AID_ERRORS, error_info, &error_type) == 0)
{
info->error_type_ref = error_type;
}
else
{
info->error_type_ref = "UNKNOWN";
}
}
// 0b1000 indicate error threshold has been exceeded
else if (decoder->flags & 0x8)
{
info->error_type_ref = "Bad Page Retirement Threshold";
}
else
{
if (find_error_type_by_bank(bank, decoder->status.error_code_ext, &error_type) == 0)
{
info->error_type_ref = error_type;
}
else
{
info->error_type_ref = "UNKNOWN";
}
}
// 0b1000 indicate error threshold has been exceeded, and is always a HBM error
if (decoder->flags & 0x8)
{
info->category_ref = "HBM Errors";
}
else
{
info->category_ref = get_error_category(bank, info->error_type_ref);
}
const char *service_error;
if (get_service_error_type(info->category_ref, info->bank_ref, info->error_type_ref, info->severity_ref, &service_error) != 0)
{
service_error = info->error_type_ref;
}
info->afid = get_error_id(info->category_ref, service_error, info->severity_ref);
}
/**
* @brief Initializes an ACA decoder structure with raw register values
* @param[out] decoder Pointer to the decoder structure to initialize
* @param[in] hw_revision Hardware hw_revision number
* @param[in] flags Decoder flags
* @param[in] status_reg Raw status register value
* @param[in] ipid_reg Raw IPID register value
* @param[in] synd_reg Raw syndrome register value
*/
static void aca_decoder_init(aca_decoder_t *decoder, uint16_t hw_revision, uint32_t flags,
uint64_t status_reg, uint64_t ipid_reg, uint64_t synd_reg)
{
memset(decoder, 0, sizeof(aca_decoder_t));
decoder->hw_revision = hw_revision;
decoder->flags = flags;
decoder->aca_status = status_reg;
decoder->aca_ipid = ipid_reg;
decoder->aca_synd = synd_reg;
aca_status_init(&decoder->status, status_reg);
aca_ipid_init(&decoder->ipid, ipid_reg);
aca_synd_init(&decoder->synd, synd_reg);
}
aca_error_info_t aca_decode(const aca_raw_data_t *raw_data)
{
aca_decoder_t decoder = {0};
aca_error_info_t info = {0};
aca_decoder_init(&decoder,
raw_data->hw_revision,
raw_data->flags,
raw_data->aca_status,
raw_data->aca_ipid,
raw_data->aca_synd);
aca_decoder_get_error_info(&decoder, &info);
return info;
}
+76
Просмотреть файл
@@ -0,0 +1,76 @@
/**
* @file aca_fields.c
* @brief Implementation of ACA register field handling
*
* This file contains functions for initializing and reading various ACA register fields
* including status, IPID, and syndrome registers. Each function
* extracts specific bit fields from raw register values and populates corresponding
* field structures.
*/
#include "aca_fields.h"
/**
* @brief Extracts a bit field from a value
* @param[in] value The source value to extract bits from
* @param[in] start Starting bit position
* @param[in] count Number of bits to extract
* @param[in] type The type to cast the extracted bits to
* @return The extracted bits as a value of the specified type
*/
#define EXTRACT_BITS(value, start, count, type) ((type)(((value) >> (start)) & ((1ULL << (count)) - 1)))
uint64_t aca_fields_read(const aca_fields_t *fields)
{
return fields->raw_value;
}
void aca_status_init(aca_status_fields_t *fields, uint64_t status_reg)
{
fields->base.raw_value = status_reg;
fields->error_code = EXTRACT_BITS(status_reg, 0, 16, uint16_t);
fields->error_code_ext = EXTRACT_BITS(status_reg, 16, 6, uint8_t);
fields->reserv22 = EXTRACT_BITS(status_reg, 22, 2, uint8_t);
fields->addr_lsb = EXTRACT_BITS(status_reg, 24, 6, uint8_t);
fields->reserv30 = EXTRACT_BITS(status_reg, 30, 2, uint8_t);
fields->err_core_id = EXTRACT_BITS(status_reg, 32, 6, uint8_t);
fields->reserv38 = EXTRACT_BITS(status_reg, 38, 2, uint8_t);
fields->scrub = EXTRACT_BITS(status_reg, 40, 1, uint8_t);
fields->reserv41 = EXTRACT_BITS(status_reg, 41, 2, uint8_t);
fields->poison = EXTRACT_BITS(status_reg, 43, 1, uint8_t);
fields->deferred = EXTRACT_BITS(status_reg, 44, 1, uint8_t);
fields->uecc = EXTRACT_BITS(status_reg, 45, 1, uint8_t);
fields->cecc = EXTRACT_BITS(status_reg, 46, 1, uint8_t);
fields->reserv47 = EXTRACT_BITS(status_reg, 47, 5, uint8_t);
fields->synd_v = EXTRACT_BITS(status_reg, 53, 1, uint8_t);
fields->reserv54 = EXTRACT_BITS(status_reg, 54, 1, uint8_t);
fields->tcc = EXTRACT_BITS(status_reg, 55, 1, uint8_t);
fields->err_core_id_val = EXTRACT_BITS(status_reg, 56, 1, uint8_t);
fields->pcc = EXTRACT_BITS(status_reg, 57, 1, uint8_t);
fields->addr_v = EXTRACT_BITS(status_reg, 58, 1, uint8_t);
fields->misc_v = EXTRACT_BITS(status_reg, 59, 1, uint8_t);
fields->en = EXTRACT_BITS(status_reg, 60, 1, uint8_t);
fields->uc = EXTRACT_BITS(status_reg, 61, 1, uint8_t);
fields->overflow = EXTRACT_BITS(status_reg, 62, 1, uint8_t);
fields->val = EXTRACT_BITS(status_reg, 63, 1, uint8_t);
}
void aca_ipid_init(aca_ipid_fields_t *fields, uint64_t ipid_reg)
{
fields->base.raw_value = ipid_reg;
fields->instance_id_lo = EXTRACT_BITS(ipid_reg, 0, 32, uint32_t);
fields->hardware_id = EXTRACT_BITS(ipid_reg, 32, 12, uint16_t);
fields->instance_id_hi = EXTRACT_BITS(ipid_reg, 44, 4, uint8_t);
fields->aca_type = EXTRACT_BITS(ipid_reg, 48, 16, uint16_t);
}
void aca_synd_init(aca_synd_fields_t *fields, uint64_t synd_reg)
{
fields->base.raw_value = synd_reg;
fields->error_information = EXTRACT_BITS(synd_reg, 0, 18, uint32_t);
fields->length = EXTRACT_BITS(synd_reg, 18, 6, uint8_t);
fields->error_priority = EXTRACT_BITS(synd_reg, 24, 3, uint8_t);
fields->reserved27 = EXTRACT_BITS(synd_reg, 27, 5, uint8_t);
fields->syndrome = EXTRACT_BITS(synd_reg, 32, 7, uint16_t);
fields->reserved39 = EXTRACT_BITS(synd_reg, 39, 25, uint32_t);
}
+368
Просмотреть файл
@@ -0,0 +1,368 @@
/**
* @file aca_tables.c
* @brief ACA Decode Tables Implementation
*
* This file contains lookup tables and helper functions for mapping ACA error codes
* to human-readable strings. It includes:
* - Bank mapping table for hardware IDs and ACA types
* - Error type mapping table for bank-specific error codes
* - GFX error mapping tables for XCD and AID errors
* - Lookup functions to find bank names and error types
*/
#include "aca_tables.h"
#include <stdint.h>
#include <stddef.h>
#include <string.h>
/**
* @brief Mapping table for hardware IDs and ACA types to bank names
*/
const aca_bank_entry_t bank_table[] = {
{0x2E, 0x02, "cs"},
{0x2E, 0x01, "pie"},
{0x96, 0x00, "umc"},
{0xFF, 0x01, "psp"},
{0x01, 0x01, "smu"},
{0x18, 0x00, "nbio"},
{0x46, 0x01, "pcie"},
{0x05, 0x00, "pb"},
{0x259, 0x00, "kpx_serdes"},
{0x2E, 0x04, "mall"},
{0x267, 0x00, "kpx_wafl"},
{0x50, 0x00, "pcs_xgmi"},
{0x6C, 0x00, "nbif"},
{0x80, 0x00, "shub"},
{0x170, 0x00, "usr_dp"},
{0x180, 0x00, "usr_cp"}};
/**
* @brief Mapping table for bank-specific error codes to error types
*/
const aca_error_type_t error_table[] = {
{"cs", 0x0, "FTI_ILL_REQ"},
{"cs", 0x1, "FTI_ADDR_VIOL"},
{"cs", 0x2, "FTI_SEC_VIOL"},
{"cs", 0x3, "FTI_ILL_RSP"},
{"cs", 0x4, "FTI_RSP_NO_MTCH"},
{"cs", 0x5, "FTI_PAR_ERR"},
{"cs", 0x6, "SDP_PAR_ERR"},
{"cs", 0x7, "ATM_PAR_ERR"},
{"cs", 0x8, "SDP_RSP_NO_MTCH"},
{"cs", 0x9, "SPF_PRT_ERR"},
{"cs", 0xa, "SPF_ECC_ERR"},
{"cs", 0xb, "SDP_UNEXP_RETRY"},
{"cs", 0xc, "CNTR_OVFL"},
{"cs", 0xd, "CNTR_UNFL"},
{"cs", 0xe, "FTI_ND_ILL_REQ"},
{"cs", 0xf, "FTI_ND_ADDR_VIOL"},
{"cs", 0x10, "FTI_ND_SEC_VIOL"},
{"cs", 0x11, "Hardware Assertion (HWA)"},
{"cs", 0x12, "ST_PRT_ERR"},
{"cs", 0x13, "ST_ECC_ERR"},
{"cs", 0x14, "ST_TXN_ERR"},
{"pie", 0x0, "Hardware Assertion (HWA)"},
{"pie", 0x1, "CSW"},
{"pie", 0x2, "GMI"},
{"pie", 0x3, "FTI_DAT_STAT"},
{"pie", 0x4, "DEF"},
{"pie", 0x5, "Watchdog Timeout (WDT)"},
{"pie", 0x6, "CNLI"},
{"pie", 0x7, "RSLVFCI"},
{"umc", 0x0, "On-die ECC"},
{"umc", 0x1, "WriteDataPoisonErr"},
{"umc", 0x2, "SdpParityErr"},
{"umc", 0x4, "AddressCommandParityErr"},
{"umc", 0x5, "WriteDataCrcErr"},
{"umc", 0x6, "SramEccErr"},
{"umc", 0x9, "EcsErr"},
{"umc", 0xa, "ThrttlErr"},
{"umc", 0xb, "RdCrcErr"},
{"umc", 0xd, "MpFwErr"},
{"umc", 0xe, "MpParErr"},
{"umc", 0xf, "End-to-end CRC"},
{"psp", 0x0, "Mp0HighSramError"},
{"psp", 0x1, "Mp0LowSramError"},
{"psp", 0x2, "Mp0IDataBank0Error"},
{"psp", 0x3, "Mp0IDataBank1Error"},
{"psp", 0x4, "Mp0ITagRam0Error"},
{"psp", 0x5, "Mp0ITagRam1Error"},
{"psp", 0x6, "Mp0DDataBank0Error"},
{"psp", 0x7, "Mp0DDataBank1Error"},
{"psp", 0x8, "Mp0DDataBank2Error"},
{"psp", 0x9, "Mp0DDataBank3Error"},
{"psp", 0xa, "Mp0DTagBank0Error"},
{"psp", 0xb, "Mp0DTagBank1Error"},
{"psp", 0xc, "Mp0DTagBank2Error"},
{"psp", 0xd, "Mp0DTagBank3Error"},
{"psp", 0xe, "Mp0DDirtyRamError"},
{"psp", 0xf, "Mp0TlbBank0Error"},
{"psp", 0x10, "Mp0TlbBank1Error"},
{"psp", 0x11, "Mp0SHubIfRdBufError"},
{"psp", 0x12, "PhyRamEccError"},
{"psp", 0x3a, "PoisonDataConsumption"},
{"psp", 0x3b, "SRAM_EDC"},
{"psp", 0x3c, "SMN_Parity"},
{"psp", 0x3d, "SMN_Timeout"},
{"psp", 0x3f, "WAFL"},
{"smu", 0x0, "Mp5HighSramError"},
{"smu", 0x1, "Mp5LowSramError"},
{"smu", 0x2, "Mp5DCacheAError"},
{"smu", 0x3, "Mp5DCacheBError"},
{"smu", 0x4, "Mp5DTagAError"},
{"smu", 0x5, "Mp5DTagBError"},
{"smu", 0x6, "Mp5ICacheAError"},
{"smu", 0x7, "Mp5ICacheBError"},
{"smu", 0x8, "Mp5ITagAError"},
{"smu", 0x9, "Mp5ITagBError"},
{"smu", 0xb, "PhyRamEccError"},
{"smu", 0x3a, "GFX_IP_Correctable_Error"},
{"smu", 0x3b, "GFX_IP_Fatal_Error"},
{"smu", 0x3d, "Reserved"},
{"smu", 0x3e, "GFX_IP_Poison_Error"},
{"nbio", 0x0, "EccParityError"},
{"nbio", 0x1, "PCIE_Sideband"},
{"nbio", 0x2, "Ext_ErrEvent"},
{"nbio", 0x3, "Egress_Poison"},
{"nbio", 0x4, "IOHC_Internal_Poison"},
{"nbio", 0x5, "Int_ErrEvent"},
{"pcie", 0x0, "SDP_PARITY_ERR_LOG"},
{"pb", 0x0, "EccError"},
{"kpx_serdes", 0x0, "RAMECC"},
{"kpx_serdes", 0x1, "ARCIns"},
{"kpx_serdes", 0x2, "ARCData"},
{"kpx_serdes", 0x3, "APB"},
{"mall", 0x0, "CNTR_OVFL"},
{"mall", 0x1, "CNTR_UNFL"},
{"mall", 0x2, "CSDP_PAR_ERR"},
{"mall", 0x3, "USDP_PAR_ERR"},
{"mall", 0x4, "CACHE_TAG0_ERR"},
{"mall", 0x5, "CACHE_TAG1_ERR"},
{"mall", 0x6, "CACHE_DAT_ERR"},
{"kpx_wafl", 0x0, "RAMECC"},
{"kpx_wafl", 0x1, "ARCIns"},
{"kpx_wafl", 0x2, "ARCData"},
{"kpx_wafl", 0x3, "APB"},
{"pcs_xgmi", 0x0, "DataLossErr"},
{"pcs_xgmi", 0x1, "TrainingErr"},
{"pcs_xgmi", 0x2, "FlowCtrlAckErr"},
{"pcs_xgmi", 0x3, "RxFifoUnderflowErr"},
{"pcs_xgmi", 0x4, "RxFifoOverflowErr"},
{"pcs_xgmi", 0x5, "CRCErr"},
{"pcs_xgmi", 0x6, "BERExceededErr"},
{"pcs_xgmi", 0x7, "TxMetaDataErr_TxVcidDataErr"},
{"pcs_xgmi", 0x8, "ReplayBufParityErr"},
{"pcs_xgmi", 0x9, "DataParityErr"},
{"pcs_xgmi", 0xa, "ReplayFifoOverflowErr"},
{"pcs_xgmi", 0xb, "ReplaFifoUnderflowErr"},
{"pcs_xgmi", 0xc, "ElasticFifoOverflowErr"},
{"pcs_xgmi", 0xd, "DeskewErr"},
{"pcs_xgmi", 0xe, "FlowCtrlCRCErr"},
{"pcs_xgmi", 0xf, "DataStartupLimitErr"},
{"pcs_xgmi", 0x10, "FCInitTimeoutErr"},
{"pcs_xgmi", 0x11, "RecoveryTimeoutErr"},
{"pcs_xgmi", 0x12, "ReadySerialTimeoutErr"},
{"pcs_xgmi", 0x13, "ReadySerialAttemptErr"},
{"pcs_xgmi", 0x14, "RecoveryAttemptErr"},
{"pcs_xgmi", 0x15, "RecoveryRelockAttemptErr"},
{"pcs_xgmi", 0x16, "ReplayAttemptErr"},
{"pcs_xgmi", 0x17, "SyncHdrErr"},
{"pcs_xgmi", 0x18, "TxReplayTimeoutErr"},
{"pcs_xgmi", 0x19, "RxReplayTimeoutErr"},
{"pcs_xgmi", 0x1a, "LinkSubTxTimeoutErr"},
{"pcs_xgmi", 0x1b, "LinkSubRxTimeoutErr"},
{"pcs_xgmi", 0x1c, "RxCMDPktErr"},
{"nbif", 0x0, "TIMEOUT_ERR"},
{"nbif", 0x1, "SRAM_ECC_ERR"},
{"nbif", 0x2, "NTB_ERR_EVENT"},
{"nbif", 0x3, "SDP_PARITY_ERR"},
{"shub", 0x0, "TIMEOUT_ERR"},
{"shub", 0x1, "SRAM_ECC_ERR"},
{"shub", 0x2, "NTB_ERR_EVENT"},
{"shub", 0x3, "SDP_PARITY_ERR"},
{"usr_dp", 0x0, "MstCMDErr"},
{"usr_dp", 0x1, "MstRxFIFOErr"},
{"usr_dp", 0x2, "MstDeskewErr"},
{"usr_dp", 0x3, "MstDetectTimeoutErr"},
{"usr_dp", 0x4, "MstFlowControlErr"},
{"usr_dp", 0x5, "MstDataValidFifoErr"},
{"usr_dp", 0x6, "macLinkStateErr"},
{"usr_dp", 0x7, "DeskewErr"},
{"usr_dp", 0x8, "InitTimeoutErr"},
{"usr_dp", 0x9, "InitAttemptErr"},
{"usr_dp", 0xa, "RecoveryTimeoutErr"},
{"usr_dp", 0xb, "RecoveryAttemptErr"},
{"usr_dp", 0xc, "EyeTrainingTimeoutErr"},
{"usr_dp", 0xd, "DataStartupLimitErr"},
{"usr_dp", 0xe, "LS0ExitErr"},
{"usr_dp", 0xf, "PLLpowerStateUpdateTimeoutErr"},
{"usr_dp", 0x10, "RxFifoErr"},
{"usr_dp", 0x11, "LcuErr"},
{"usr_dp", 0x12, "convCECCErr"},
{"usr_dp", 0x13, "convUECCErr"},
{"usr_dp", 0x15, "rxDataLossErr"},
{"usr_dp", 0x16, "ReplayCECCErr"},
{"usr_dp", 0x17, "ReplayUECCErr"},
{"usr_dp", 0x18, "CRCErr"},
{"usr_dp", 0x19, "BERExceededErr"},
{"usr_dp", 0x1a, "FCInitTimeoutErr"},
{"usr_dp", 0x1b, "FCInitAttemptErr"},
{"usr_dp", 0x1c, "ReplayTimoutErr"},
{"usr_dp", 0x1d, "ReplayAttemptErr"},
{"usr_dp", 0x1e, "ReplayUnderflowErr"},
{"usr_dp", 0x1f, "ReplayOverflowErr"},
{"usr_cp", 0x0, "PacketTypeErr"},
{"usr_cp", 0x1, "RxFifoErr"},
{"usr_cp", 0x2, "DeskewErr"},
{"usr_cp", 0x3, "RxDetectTimeoutErr"},
{"usr_cp", 0x4, "DataParityErr"},
{"usr_cp", 0x5, "DataLossErr"},
{"usr_cp", 0x6, "LcuErr"},
{"usr_cp", 0x7, "HB1HandshakeTimeoutErr"},
{"usr_cp", 0x8, "HB2HandshakeTimeoutErr"},
{"usr_cp", 0x9, "ClkSleepRspTimeoutErr"},
{"usr_cp", 0xa, "ClkWakeRspTimeoutErr"},
{"usr_cp", 0xb, "resetAttackErr"},
{"usr_cp", 0xc, "remoteLinkFatalErr"},
};
/**
* @brief Error GFX mapping table for XCD errors
*/
const aca_error_entry_t xcd_error_table[] = {
{0x0, "GfxGcError"},
{0x1, "GfxGcError"},
{0x2, "GfxGcError"},
{0x3, "GfxGcError"},
{0x4, "GfxGcError"},
{0x5, "GfxGcError"},
{0x6, "GfxGcError"},
{0x7, "GfxGcError"},
{0x8, "GfxGcError"},
{0x9, "GfxGcError"},
{0xa, "GfxGcError"},
{0xb, "GfxGcError"},
{0xc, "GfxGcError"},
{0xd, "GfxGcError"},
{0xe, "GfxGcError"},
{0xf, "GfxGcError"},
{0x10, "GfxGcError"},
{0x28, "Reserved"},
{0x2a, "Reserved"}};
/**
* @brief Error GFX mapping table for AID errors
*/
const aca_error_entry_t aid_error_table[] = {
{0x0, "GfxGcError"},
{0x1, "GfxGcError"},
{0x2, "GfxGcError"},
{0x3, "GfxGcError"},
{0x4, "GfxGcError"},
{0x5, "GfxMmhubError"},
{0x6, "GfxMmhubError"},
{0x7, "GfxMmhubError"},
{0x8, "GfxMmhubError"},
{0x9, "GfxMmhubError"},
{0xa, "GfxMmhubError"},
{0xb, "GfxMmhubError"},
{0xc, "GfxMmhubError"},
{0xd, "GfxGcError"},
{0xe, "GfxVcnError"},
{0xf, "GfxVcnError"},
{0x10, "GfxVcnError"},
{0x11, "GfxVcnError"},
{0x12, "GfxVcnError"},
{0x13, "GfxVcnError"},
{0x14, "GfxVcnError"},
{0x15, "GfxVcnError"},
{0x16, "GfxVcnError"},
{0x17, "GfxVcnError"},
{0x18, "GfxVcnError"},
{0x19, "GfxVcnError"},
{0x1a, "GfxVcnError"},
{0x1b, "GfxVcnError"},
{0x1c, "GfxVcnError"},
{0x1d, "GfxVcnError"},
{0x1e, "GfxVcnError"},
{0x1f, "GfxVcnError"},
{0x20, "GfxVcnError"},
{0x21, "GfxSdmaError"},
{0x22, "GfxSdmaError"},
{0x23, "GfxSdmaError"},
{0x24, "GfxSdmaError"},
{0x25, "GfxHdpError"},
{0x26, "GfxAthubError"},
{0x27, "GfxGcError"},
{0x28, "Reserved"},
{0x29, "Reserved"},
{0x2a, "Reserved"},
{0x2b, "Reserved"}};
const size_t NUM_BANKS = sizeof(bank_table) / sizeof(bank_table[0]);
const size_t NUM_ERRORS = sizeof(error_table) / sizeof(error_table[0]);
const size_t NUM_XCD_ERRORS = sizeof(xcd_error_table) / sizeof(xcd_error_table[0]);
const size_t NUM_AID_ERRORS = sizeof(aid_error_table) / sizeof(aid_error_table[0]);
int find_bank_name(uint16_t hw_id, uint16_t aca_type, const char **bank_name)
{
if (!bank_name)
{
return -1;
}
for (size_t i = 0; i < NUM_BANKS; i++)
{
if (bank_table[i].hw_id == hw_id &&
bank_table[i].aca_type == aca_type)
{
*bank_name = bank_table[i].name;
return 0;
}
}
*bank_name = "UNKNOWN";
return 1;
}
int find_error_type_by_bank(const char *bank, uint32_t error_code, const char **error_type)
{
if (!bank || !error_type)
{
return -1;
}
for (size_t i = 0; i < NUM_ERRORS; i++)
{
if (error_code == error_table[i].error_code &&
strcmp(bank, error_table[i].bank) == 0)
{
*error_type = error_table[i].type;
return 0;
}
}
*error_type = "UNKNOWN";
return 1;
}
int find_error_in_table(const aca_error_entry_t *table, size_t table_size,
uint32_t error_code, const char **error_type)
{
if (!table || !error_type)
{
return -1;
}
for (size_t i = 0; i < table_size; i++)
{
if (table[i].error_code == error_code)
{
*error_type = table[i].type;
return 0;
}
}
*error_type = "UNKNOWN";
return 1;
}
+59
Просмотреть файл
@@ -0,0 +1,59 @@
#include "error_map.h"
#include <string.h>
static const error_map_entry_t error_map[] = {
{1, "Boot-Time Errors", "FW Load", "CPER", "Fail-to-init"},
{2, "Boot-Time Errors", "HBM BIST Test", "CPER", "Fail-to-init"},
{3, "Boot-Time Errors", "HBM Memory Test", "CPER", "Fail-to-init"},
{4, "Boot-Time Errors", "HBM Training", "CPER", "Fail-to-init"},
{5, "Boot-Time Errors", "Unhandled", "CPER", "Fail-to-init"},
{6, "Boot-Time Errors", "Unknown", "CPER", "Fail-to-init"},
{7, "Boot-Time Errors", "USR CP Link Training", "CPER", "Fail-to-init"},
{8, "Boot-Time Errors", "USR DP Link Training", "CPER", "Fail-to-init"},
{9, "Boot-Time Errors", "WAFL Link Training", "CPER", "Fail-to-init"},
{10, "Boot-Time Errors", "XGMI Link Training", "CPER", "Fail-to-init"},
{11, "Boot-Time Errors", "Boot Controller Data Abort", "CPER", "Fail-to-init"},
{12, "Boot-Time Errors", "Boot Controller Generic", "CPER ", "Fail-to-init"},
{13, "Off-Package Link Errors", "PCIe AER", "CPER", "Corrected"},
{14, "Off-Package Link Errors", "PCIe AER", "CPER", "Fatal"},
{15, "Off-Package Link Errors", "WAFL", "CPER", "Corrected"},
{16, "Off-Package Link Errors", "WAFL", "CPER", "Fatal"},
{17, "Off-Package Link Errors", "XGMI", "CPER", "Corrected"},
{18, "Off-Package Link Errors", "XGMI", "CPER", "Fatal"},
{19, "HBM Errors", "Bad Page Retirement Threshold", "CPER", "Fatal"},
{20, "HBM Errors", "On-die ECC", "CPER", "Fatal"},
{21, "HBM Errors", "End-to-end CRC", "CPER", "Fatal"},
{22, "HBM Errors", "On-die ECC", "CPER", "Uncorrected, Non-fatal"},
{23, "HBM Errors", "End-to-end CRC", "CPER", "Uncorrected, Non-fatal"},
{24, "HBM Errors", "All", "CPER", "Corrected"},
{25, "HBM Errors", "All Others", "CPER", "Fatal"},
{26, "Device Internal Errors", "Hardware Assertion (HWA)", "CPER", "Fatal"},
{27, "Device Internal Errors", "Watchdog Timeout (WDT)", "CPER", "Fatal"},
{28, "Device Internal Errors", "All Others", "CPER", "Uncorrected, Non-fatal"},
{29, "Device Internal Errors", "All Others", "CPER", "Corrected"},
{30, "Device Internal Errors", "All Others", "CPER", "Fatal"}};
static const size_t NUM_ERROR_ENTRIES = sizeof(error_map) / sizeof(error_map[0]);
int get_error_id(const char *error_category, const char *error_type, const char *error_severity)
{
if (!error_category || !error_type || !error_severity ||
strcmp(error_category, "UNKNOWN") == 0 ||
strcmp(error_type, "UNKNOWN") == 0 ||
strcmp(error_severity, "UNKNOWN") == 0)
{
return -1;
}
for (size_t i = 0; i < NUM_ERROR_ENTRIES; i++)
{
if (strcmp(error_map[i].error_category, error_category) == 0 &&
strcmp(error_map[i].error_type, error_type) == 0 &&
strcmp(error_map[i].error_severity, error_severity) == 0)
{
return (int)error_map[i].id;
}
}
return -1;
}