[SWDEV-530385] Update aca-decode with parsing fixes (#435)

*Update aca-decode to #4cd539d that fixes some errors in parsing cper files for afid extraction
*Without this fix, we get garbage value for some cper input files relating GFX_poison_cpers

Signed-off-by: Oosman Saeed <oossaeed@amd.com>
This commit is contained in:
Saeed, Oosman
2025-06-04 18:49:05 -05:00
committed by GitHub
orang tua e2692ab533
melakukan 2c3fa591b5
10 mengubah file dengan 399 tambahan dan 18 penghapusan
+1
Melihat File
@@ -308,6 +308,7 @@ class AMDSMIParser(argparse.ArgumentParser):
"""
class _CheckInputFilePath(argparse.Action):
# Checks the values
outputformat=self.helpers.get_output_format()
def __call__(self, parser, args, values, option_string=None):
path = Path(values)
try:
+48
Melihat File
@@ -0,0 +1,48 @@
#ifndef ACA_API_H
#define ACA_API_H
#include <stdint.h>
#include <stddef.h>
/**
* @brief Structure containing decoded error information
*/
typedef struct
{
const char *bank_ref; /**< Reference to bank name string */
const char *error_type_ref; /**< Reference to error type string */
const char *severity_ref; /**< Reference to error severity string */
const char *category_ref; /**< Reference to error category string */
const char *instance_ref; /**< Reference to instance name string */
int oam; /**< OAM value */
int aid; /**< AID value */
int afid; /**< AFID value (AMD Field ID) */
uint64_t raw_status; /**< Raw status register value */
uint64_t raw_addr; /**< Raw address register value */
uint64_t raw_ipid; /**< Raw IPID register value */
uint64_t raw_synd; /**< Raw syndrome register value */
uint8_t scrub; /**< Scrub bit from status */
uint8_t error_code_ext; /**< Extended error code from status */
} aca_error_info_t;
/**
* @brief Decodes the AFID from a register array
* @param[in] register_array Pointer to an array of 64-bit register values
* @param[in] array_len Size of register array in elements
* @param[in] flag Decoder flags
* @param[in] hw_revision Hardware revision number
* @return AFID value or -1 if decoding fails
*/
int decode_afid(const uint64_t *register_array, size_t array_len, uint32_t flag, uint16_t hw_revision);
/**
* @brief Decodes and returns complete error information from a register array
* @param[in] register_array Pointer to an array of 64-bit register values
* @param[in] array_len Size of register array in elements
* @param[in] flag Decoder flags
* @param[in] hw_revision Hardware revision number
* @return Complete error information structure
*/
aca_error_info_t decode_error_info(const uint64_t *register_array, size_t array_len, uint32_t flag, uint16_t hw_revision);
#endif // ACA_API_H
+6 -14
Melihat File
@@ -2,13 +2,15 @@
* @file aca_decode.h
* @brief Internal decoder interface and data structures
*/
#ifndef ACA_DECODE_H
#define ACA_DECODE_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef ACA_DECODE_H
#define ACA_DECODE_H
#include "aca_api.h"
#include "aca_fields.h"
/**
@@ -17,6 +19,7 @@ extern "C" {
typedef struct
{
uint64_t aca_status; /**< Raw status register value */
uint64_t aca_addr; /**< Raw address register value */
uint64_t aca_ipid; /**< Raw IPID register value */
uint64_t aca_synd; /**< Raw syndrome register value */
uint32_t flags; /**< Decoder flags */
@@ -33,24 +36,13 @@ typedef struct
typedef struct
{
uint64_t aca_status; /**< Raw status register value */
uint64_t aca_addr; /**< Raw address register value */
uint64_t aca_ipid; /**< Raw IPID register value */
uint64_t aca_synd; /**< Raw syndrome register value */
uint32_t flags; /**< Flags from descriptor */
uint16_t hw_revision; /**< Hardware hw_revision number */
} aca_raw_data_t;
/**
* @brief Structure containing decoded error information
*/
typedef struct
{
const char *bank_ref; /**< Reference to bank name string */
const char *error_type_ref; /**< Reference to error type string */
const char *severity_ref; /**< Reference to error severity string */
const char *category_ref; /**< Reference to error category string */
int afid; /**< AFID value (AMD Field ID) */
} aca_error_info_t;
/**
* @brief Main decode function that processes raw ACA error data
* @param[in] raw_data Pointer to structure containing raw ACA error data
+17
Melihat File
@@ -79,6 +79,16 @@ typedef struct
uint32_t reserved39;
} aca_synd_fields_t;
/**
* @brief Structure containing decoded ACA address register fields
*/
typedef struct
{
aca_fields_t base;
uint64_t error_addr;
uint64_t reserved;
} aca_addr_fields_t;
/**
* @brief Reads the raw value from an ACA field structure
* @param[in] fields Pointer to the ACA fields structure
@@ -107,4 +117,11 @@ void aca_ipid_init(aca_ipid_fields_t *fields, uint64_t ipid_reg);
*/
void aca_synd_init(aca_synd_fields_t *fields, uint64_t synd_reg);
/**
* @brief Initializes ACA address fields from a raw address register value
* @param[out] fields Pointer to the address fields structure to initialize
* @param[in] addr_reg Raw 64-bit address register value
*/
void aca_addr_init(aca_addr_fields_t *fields, uint64_t addr_reg);
#endif
+36
Melihat File
@@ -40,6 +40,25 @@ typedef struct
const char *type; /**< Error type string */
} aca_error_entry_t;
/**
* @brief Structure mapping instance_id_hi to OAM and AID values
*/
typedef struct
{
uint8_t oam; /**< OAM value */
uint8_t aid; /**< AID value */
} oam_aid_map_t;
/**
* @brief Structure for mapping bank and instance ID LO to instance name
*/
typedef struct
{
const char *bank; /**< Bank name */
uint32_t instance_id_lo; /**< Instance ID Lo (masked with 0xFFFFFFFC) */
const char *name; /**< Instance name */
} aca_instance_entry_t;
// External table declarations
extern const aca_bank_entry_t bank_table[];
extern const aca_error_type_t error_table[];
@@ -81,4 +100,21 @@ int find_error_type_by_bank(const char *bank, uint32_t error_code, const char **
int find_error_in_table(const aca_error_entry_t *table, size_t table_size,
uint32_t error_code, const char **error_type);
/**
* @brief Find OAM and AID values based on instance_id_hi
* @param[in] instance_id_hi Instance ID low value (0x00-0x0F)
* @param[out] oam_aid Pointer to store OAM and AID values
* @return 0 on success, 1 if not found, -1 on parameter error
*/
int find_oam_aid(uint8_t instance_id_hi, oam_aid_map_t *oam_aid);
/**
* @brief Find instance name based on bank and instance ID
* @param[in] bank Bank name string
* @param[in] instance_id_lo Instance ID (will be masked with 0xFFFFFFFC)
* @param[out] instance_name Pointer to store result string
* @return 0 on success, 1 if not found, -1 on parameter error
*/
int find_instance_name(const char *bank, uint32_t instance_id_lo, const char **instance_name);
#endif
+71
Melihat File
@@ -0,0 +1,71 @@
#include "aca_decode.h"
int decode_afid(const uint64_t *register_array, size_t array_len, uint32_t flag, uint16_t hw_revision)
{
if (!register_array)
{
return -1;
}
aca_raw_data_t raw_data;
if (array_len == 4) // 32 bytes
{
raw_data.aca_status = register_array[0];
raw_data.aca_addr = register_array[1];
raw_data.aca_ipid = register_array[2];
raw_data.aca_synd = register_array[3];
}
else if (array_len == 16) // 128 bytes
{
raw_data.aca_status = register_array[1];
raw_data.aca_addr = register_array[2];
raw_data.aca_ipid = register_array[5];
raw_data.aca_synd = register_array[6];
}
else
{
return -1; // Unsupported size
}
raw_data.flags = flag;
raw_data.hw_revision = hw_revision;
aca_error_info_t error_info = aca_decode(&raw_data);
return error_info.afid;
}
aca_error_info_t decode_error_info(const uint64_t *register_array, size_t array_len, uint32_t flag, uint16_t hw_revision)
{
aca_raw_data_t raw_data = {0};
aca_error_info_t error_info = {0};
if (!register_array)
{
return error_info;
} if (array_len == 4) // 32 bytes
{
raw_data.aca_status = register_array[0];
raw_data.aca_addr = register_array[1];
raw_data.aca_ipid = register_array[2];
raw_data.aca_synd = register_array[3];
}
else if (array_len == 16) // 128 bytes
{
raw_data.aca_status = register_array[1];
raw_data.aca_addr = register_array[2];
raw_data.aca_ipid = register_array[5];
raw_data.aca_synd = register_array[6];
}
else
{
return error_info; // Return zero-initialized structure for unsupported size
}
raw_data.flags = flag;
raw_data.hw_revision = hw_revision;
return aca_decode(&raw_data);
}
+34 -1
Melihat File
@@ -167,7 +167,17 @@ static void aca_decoder_get_error_info(const aca_decoder_t *decoder, aca_error_i
{
const char *bank;
const char *error_type;
const char *instance_name;
int result;
info->raw_status = decoder->aca_status;
info->raw_addr = decoder->aca_addr;
info->raw_ipid = decoder->aca_ipid;
info->raw_synd = decoder->aca_synd;
info->scrub = decoder->status.scrub;
info->error_code_ext = decoder->status.error_code_ext;
result = aca_decoder_get_bank(decoder, &bank);
if (result < 0)
@@ -176,6 +186,15 @@ static void aca_decoder_get_error_info(const aca_decoder_t *decoder, aca_error_i
}
info->bank_ref = bank;
if (find_instance_name(bank, decoder->ipid.instance_id_lo, &instance_name) == 0)
{
info->instance_ref = instance_name;
}
else
{
info->instance_ref = "Decode Inapplicable";
}
// 0b1000 indicate error threshold has been exceeded, and is always fatal
if (decoder->flags & 0x8)
{
@@ -186,6 +205,20 @@ static void aca_decoder_get_error_info(const aca_decoder_t *decoder, aca_error_i
info->severity_ref = get_error_severity(&decoder->status);
}
// Decode OAM and AID from instance_id_lo
oam_aid_map_t oam_aid = {0};
uint8_t instance_id_lo = decoder->ipid.instance_id_lo & 0xFF; // Get lower 8 bits
if (find_oam_aid(instance_id_lo, &oam_aid) == 0)
{
info->oam = oam_aid.oam;
info->aid = oam_aid.aid;
}
else
{
info->oam = -1; // Invalid value
info->aid = -1; // Invalid value
}
if (decoder->status.error_code_ext >= 0x3A && decoder->status.error_code_ext <= 0x3E)
{
uint32_t instance_id = decoder->ipid.instance_id_lo;
@@ -239,7 +272,7 @@ static void aca_decoder_get_error_info(const aca_decoder_t *decoder, aca_error_i
{
service_error = info->error_type_ref;
}
info->afid = get_error_id(info->category_ref, service_error, info->severity_ref);
}
+7
Melihat File
@@ -74,3 +74,10 @@ void aca_synd_init(aca_synd_fields_t *fields, uint64_t synd_reg)
fields->syndrome = EXTRACT_BITS(synd_reg, 32, 7, uint16_t);
fields->reserved39 = EXTRACT_BITS(synd_reg, 39, 25, uint32_t);
}
void aca_addr_init(aca_addr_fields_t *fields, uint64_t addr_reg)
{
fields->base.raw_value = addr_reg;
fields->error_addr = EXTRACT_BITS(addr_reg, 0, 56, uint64_t);
fields->reserved = EXTRACT_BITS(addr_reg, 56, 8, uint8_t);
}
+170
Melihat File
@@ -299,10 +299,144 @@ const aca_error_entry_t aid_error_table[] = {
{0x2a, "Reserved"},
{0x2b, "Reserved"}};
/**
* @brief Table mapping instance_id_hi to OAM and AID values
*/
static const oam_aid_map_t oam_aid_table[] = {
{0, 0}, /* 0x00 */
{1, 0}, /* 0x01 */
{2, 0}, /* 0x02 */
{3, 0}, /* 0x03 */
{0, 1}, /* 0x04 */
{1, 1}, /* 0x05 */
{2, 1}, /* 0x06 */
{3, 1}, /* 0x07 */
{0, 2}, /* 0x08 */
{1, 2}, /* 0x09 */
{2, 2}, /* 0x0A */
{3, 2}, /* 0x0B */
{0, 3}, /* 0x0C */
{1, 3}, /* 0x0D */
{2, 3}, /* 0x0E */
{3, 3} /* 0x0F */
};
// Constants are now defined as global variables
/**
* @brief Table mapping bank and instance ID to instance names
*/
static const aca_instance_entry_t instance_table[] = {
{"cs", 0x1F002000, "cmp0"},
{"cs", 0x1F000000, "cs0"},
{"cs", 0x1F000A00, "cs10"},
{"cs", 0x1F000B00, "cs11"},
{"cs", 0x1F000C00, "cs12"},
{"cs", 0x1F000D00, "cs13"},
{"cs", 0x1F000E00, "cs14"},
{"cs", 0x1F000F00, "cs15"},
{"cs", 0x1F001000, "cs16"},
{"cs", 0x1F001100, "cs17"},
{"cs", 0x1F001200, "cs18"},
{"cs", 0x1F001300, "cs19"},
{"cs", 0x1F000100, "cs1"},
{"cs", 0x1F001400, "cs20"},
{"cs", 0x1F001500, "cs21"},
{"cs", 0x1F001600, "cs22"},
{"cs", 0x1F001700, "cs23"},
{"cs", 0x1F001800, "cs24"},
{"cs", 0x1F001900, "cs25"},
{"cs", 0x1F001A00, "cs26"},
{"cs", 0x1F001B00, "cs27"},
{"cs", 0x1F001C00, "cs28"},
{"cs", 0x1F001D00, "cs29"},
{"cs", 0x1F000200, "cs2"},
{"cs", 0x1F001E00, "cs30"},
{"cs", 0x1F001F00, "cs31"},
{"cs", 0x1F000300, "cs3"},
{"cs", 0x1F000400, "cs4"},
{"cs", 0x1F000500, "cs5"},
{"cs", 0x1F000600, "cs6"},
{"cs", 0x1F000700, "cs7"},
{"cs", 0x1F000800, "cs8"},
{"cs", 0x1F000900, "cs9"},
{"mall", 0x1F005900, "mall0"},
{"mall", 0x1F006300, "mall10"},
{"mall", 0x1F006400, "mall11"},
{"mall", 0x1F006500, "mall12"},
{"mall", 0x1F006600, "mall13"},
{"mall", 0x1F006700, "mall14"},
{"mall", 0x1F006800, "mall15"},
{"mall", 0x1F006900, "mall16"},
{"mall", 0x1F006A00, "mall17"},
{"mall", 0x1F006B00, "mall18"},
{"mall", 0x1F006C00, "mall19"},
{"mall", 0x1F005A00, "mall1"},
{"mall", 0x1F006D00, "mall20"},
{"mall", 0x1F006E00, "mall21"},
{"mall", 0x1F006F00, "mall22"},
{"mall", 0x1F007000, "mall23"},
{"mall", 0x1F007100, "mall24"},
{"mall", 0x1F007200, "mall25"},
{"mall", 0x1F007300, "mall26"},
{"mall", 0x1F007400, "mall27"},
{"mall", 0x1F007500, "mall28"},
{"mall", 0x1F007600, "mall29"},
{"mall", 0x1F005B00, "mall2"},
{"mall", 0x1F007700, "mall30"},
{"mall", 0x1F007800, "mall31"},
{"mall", 0x1F005C00, "mall3"},
{"mall", 0x1F005D00, "mall4"},
{"mall", 0x1F005E00, "mall5"},
{"mall", 0x1F005F00, "mall6"},
{"mall", 0x1F006000, "mall7"},
{"mall", 0x1F006100, "mall8"},
{"mall", 0x1F006200, "mall9"},
{"pb", 0x5EA00, "pb"},
{"pb", 0x30082900, "ccd0 pbccd"},
{"pb", 0x32082900, "ccd1 pbccd"},
{"pb", 0x34082900, "ccd2 pbccd"},
{"pb", 0x36082900, "xcd0 pbccd"},
{"pb", 0x38082900, "xcd1 pbccd"},
{"umc", 0x90F00, "ch0 umc0"},
{"umc", 0x290F00, "ch0 umc1"},
{"umc", 0x490F00, "ch0 umc2"},
{"umc", 0x690F00, "ch0 umc3"},
{"umc", 0x91F00, "ch1 umc0"},
{"umc", 0x291F00, "ch1 umc1"},
{"umc", 0x491F00, "ch1 umc2"},
{"umc", 0x691F00, "ch1 umc3"},
{"umc", 0x92F00, "ch2 umc0"},
{"umc", 0x292F00, "ch2 umc1"},
{"umc", 0x492F00, "ch2 umc2"},
{"umc", 0x692F00, "ch2 umc3"},
{"umc", 0x93F00, "ch3 umc0"},
{"umc", 0x293F00, "ch3 umc1"},
{"umc", 0x493F00, "ch3 umc2"},
{"umc", 0x693F00, "ch3 umc3"},
{"umc", 0x190F00, "ch4 umc0"},
{"umc", 0x390F00, "ch4 umc1"},
{"umc", 0x590F00, "ch4 umc2"},
{"umc", 0x790F00, "ch4 umc3"},
{"umc", 0x191F00, "ch5 umc0"},
{"umc", 0x391F00, "ch5 umc1"},
{"umc", 0x591F00, "ch5 umc2"},
{"umc", 0x791F00, "ch5 umc3"},
{"umc", 0x192F00, "ch6 umc0"},
{"umc", 0x392F00, "ch6 umc1"},
{"umc", 0x592F00, "ch6 umc2"},
{"umc", 0x792F00, "ch6 umc3"},
{"umc", 0x193F00, "ch7 umc0"},
{"umc", 0x393F00, "ch7 umc1"},
{"umc", 0x593F00, "ch7 umc2"},
{"umc", 0x793F00, "ch7 umc3"}};
const size_t NUM_OAM_AID_ENTRIES = sizeof(oam_aid_table) / sizeof(oam_aid_table[0]);
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]);
const size_t NUM_INSTANCES = sizeof(instance_table) / sizeof(instance_table[0]);
int find_bank_name(uint16_t hw_id, uint16_t aca_type, const char **bank_name)
{
@@ -366,3 +500,39 @@ int find_error_in_table(const aca_error_entry_t *table, size_t table_size,
*error_type = "UNKNOWN";
return 1;
}
int find_oam_aid(uint8_t instance_id_hi, oam_aid_map_t *oam_aid)
{
if (!oam_aid || instance_id_hi >= NUM_OAM_AID_ENTRIES)
{
return -1;
}
oam_aid->oam = oam_aid_table[instance_id_hi].oam;
oam_aid->aid = oam_aid_table[instance_id_hi].aid;
return 0;
}
int find_instance_name(const char *bank, uint32_t instance_id_lo, const char **instance_name)
{
if (!bank || !instance_name)
{
return -1;
}
// Mask off the lower 2 bits as specified
uint32_t masked_id = instance_id_lo & 0xFFFFFFFC;
for (size_t i = 0; i < NUM_INSTANCES; i++)
{
if (instance_table[i].instance_id_lo == masked_id &&
strcmp(bank, instance_table[i].bank) == 0)
{
*instance_name = instance_table[i].name;
return 0;
}
}
*instance_name = "UNKNOWN";
return 1;
}
+9 -3
Melihat File
@@ -1,6 +1,8 @@
#include "error_map.h"
#include <string.h>
#define AFID_VERSION "0.7"
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"},
@@ -31,7 +33,11 @@ static const error_map_entry_t error_map[] = {
{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"}};
{30, "Device Internal Errors", "All Others", "CPER", "Fatal"},
{31, "CPER Format", "Malformed CPER", "CPER", "ALL"},
{32, "CPER Format", "Incomplete ACA Data", "CPER", "ALL"},
{33, "CPER Format", "Invalid ACA Data", "CPER", "ALL"},
{34, "Unidentified Errors", "Unidentified Error", "CPER", "ALL"}};
static const size_t NUM_ERROR_ENTRIES = sizeof(error_map) / sizeof(error_map[0]);
@@ -42,7 +48,7 @@ int get_error_id(const char *error_category, const char *error_type, const char
strcmp(error_type, "UNKNOWN") == 0 ||
strcmp(error_severity, "UNKNOWN") == 0)
{
return -1;
return 33; // Return ID for "Invalid Error" if any input is "UNKNOWN" or NULL
}
for (size_t i = 0; i < NUM_ERROR_ENTRIES; i++)
@@ -55,5 +61,5 @@ int get_error_id(const char *error_category, const char *error_type, const char
}
}
return -1;
return 34; // Return ID for "Unidentified Errors" if no match found
}