From: Hunter He Date: Mon, 25 Dec 2023 09:34:56 +0000 (+0800) Subject: rasdaemon: ras-mc-ctl: Add support to display the JaguarMicro vendor errors X-Git-Tag: v0.8.1~49 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=df5dcc7136944fde866ed19eaa67b747ae5c56c0;p=users%2Fmchehab%2Frasdaemon.git rasdaemon: ras-mc-ctl: Add support to display the JaguarMicro vendor errors Add support to display the JaguarMicro Corsica DPU vendor errors event. Signed-off-by: Hunter He Signed-off-by: Mauro Carvalho Chehab --- diff --git a/Makefile.am b/Makefile.am index a94d8fe..9dd42c9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -80,6 +80,9 @@ endif if WITH_YITIAN_NS_DECODE rasdaemon_SOURCES += non-standard-yitian.c endif +if WITH_JAGUAR_NS_DECODE + rasdaemon_SOURCES += non-standard-jaguarmicro.c +endif rasdaemon_LDADD = -lpthread $(SQLITE3_LIBS) $(LIBTRACEEVENT_LIBS) rasdaemon_CFLAGS = $(SQLITE3_CFLAGS) $(LIBTRACEEVENT_CFLAGS) @@ -89,7 +92,8 @@ include_HEADERS = config.h ras-events.h ras-logger.h ras-mc-handler.h \ ras-extlog-handler.h ras-arm-handler.h ras-non-standard-handler.h \ ras-devlink-handler.h ras-diskerror-handler.h rbtree.h ras-page-isolation.h \ non-standard-hisilicon.h non-standard-ampere.h ras-memory-failure-handler.h \ - ras-cxl-handler.h ras-cpu-isolation.h queue.h non-standard-yitian.h + ras-cxl-handler.h ras-cpu-isolation.h queue.h non-standard-yitian.h \ + non-standard-jaguarmicro.h # This rule can't be called with more than one Makefile job (like make -j8) # I can't figure out a way to fix that diff --git a/configure.ac b/configure.ac index f3fbe8c..163fa17 100644 --- a/configure.ac +++ b/configure.ac @@ -177,6 +177,16 @@ AS_IF([test "x$enable_amp_ns_decode" = "xyes" || test "x$enable_all" = "xyes"], AM_CONDITIONAL([WITH_AMP_NS_DECODE], [test x$enable_amp_ns_decode = xyes || test x$enable_all = xyes]) AM_COND_IF([WITH_AMP_NS_DECODE], [USE_AMP_NS_DECODE="yes"], [USE_AMP_NS_DECODE="no"]) +AC_ARG_ENABLE([jaguar_ns_decode], + AS_HELP_STRING([--enable-jaguar-ns-decode], [enable JAGUAR_NS_DECODE events (currently experimental)])) + +AS_IF([test "x$enable_jaguar_ns_decode" = "xyes" || test "x$enable_all" = "xyes"], [ + AC_DEFINE(HAVE_JAGUAR_NS_DECODE,1,"have JaguarMicro UNKNOWN_SEC events decode") + AC_SUBST([WITH_JAGUAR_NS_DECODE]) +]) +AM_CONDITIONAL([WITH_JAGUAR_NS_DECODE], [test x$enable_jaguar_ns_decode = xyes || test x$enable_all = xyes]) +AM_COND_IF([WITH_JAGUAR_NS_DECODE], [USE_JAGUAR_NS_DECODE="yes"], [USE_JAGUAR_NS_DECODE="no"]) + AC_ARG_ENABLE([cpu_fault_isolation], AS_HELP_STRING([--enable-cpu-fault-isolation], [enable cpu online fault isolation])) @@ -240,4 +250,5 @@ compile time options summary AMP RAS errors : $USE_AMP_NS_DECODE CPU fault isolation : $USE_CPU_FAULT_ISOLATION YITIAN RAS errors : $USE_YITIAN_NS_DECODE + JAGUAR RAS errors : $USE_JAGUAR_NS_DECODE EOF diff --git a/non-standard-jaguarmicro.c b/non-standard-jaguarmicro.c new file mode 100644 index 0000000..d909d7a --- /dev/null +++ b/non-standard-jaguarmicro.c @@ -0,0 +1,1109 @@ +/* + * Copyright (c) 2023, JaguarMicro + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include "ras-record.h" +#include "ras-logger.h" +#include "ras-report.h" +#include "ras-non-standard-handler.h" +#include "non-standard-jaguarmicro.h" +#include "ras-mce-handler.h" + +#define JM_BUF_LEN 256 +#define JM_REG_BUF_LEN 2048 +#define JM_SNPRINTF mce_snprintf + +static void record_jm_data(struct ras_ns_ev_decoder *ev_decoder, + enum jm_oem_data_type data_type, + int id, int64_t data, const char *text); + +struct jm_event { + char error_msg[JM_BUF_LEN]; + char reg_msg[JM_REG_BUF_LEN]; +}; + +/*ras_csr_por Payload Type 0*/ +static const char * const disp_payload0_err_reg_name[] = { + "LOCK_CONTROL:", + "LOCK_FUNCTION:", + "CFG_RAM_ID:", + "ERR_FR_LOW32:", + "ERR_FR_HIGH32:", + "ERR_CTLR_LOW32:", + "ECC_STATUS_LOW32:", + "ECC_ADDR_LOW32:", + "ECC_ADDR_HIGH32:", + "ECC_MISC0_LOW32:", + "ECC_MISC0_HIGH32:", + "ECC_MISC1_LOW32:", + "ECC_MISC1_HIGH32:", + "ECC_MISC2_LOW32:", + "ECC_MISC2_HIGH32:", +}; + +/*SMMU IP Payload Type 1*/ +static const char * const disp_payload1_err_reg_name[] = { + "CSR_INT_STATUS:", + "ERR_FR:", + "ERR_CTLR:", + "ERR_STATUS:", + "ERR_GEN:", +}; + +/*HAC SRAM, Payload Type 2 */ +static const char * const disp_payload2_err_reg_name[] = { + "ECC_1BIT_INFO_LOW32:", + "ECC_1BIT_INFO_HIGH32:", + "ECC_2BIT_INFO_LOW32:", + "ECC_2BIT_INFO_HIGH32:", +}; + +/*CMN IP, Payload Type 5 */ +static const char * const disp_payload5_err_reg_name[] = { + "CFGM_MXP_0:", + "CFGM_HNF_0:", + "CFGM_HNI_0:", + "CFGM_SBSX_0:", + "ERR_FR_NS:", + "ERR_CTLRR_NS:", + "ERR_STATUSR_NS:", + "ERR_ADDRR_NS:", + "ERR_MISCR_NS:", + "ERR_FR:", + "ERR_CTLR:", + "ERR_STATUS:", + "ERR_ADDR:", + "ERR_MISC:", +}; + +/*GIC IP, Payload Type 6 */ +static const char * const disp_payload6_err_reg_name[] = { + "RECORD_ID:", + "GICT_ERR_FR:", + "GICT_ERR_CTLR:", + "GICT_ERR_STATUS:", + "GICT_ERR_ADDR:", + "GICT_ERR_MISC0:", + "GICT_ERR_MISC1:", + "GICT_ERRGSR:", +}; + +static const char * const soc_desc[] = { + "Corsica1.0", +}; + +/* JaguarMicro sub system definitions */ +#define JM_SUB_SYS_CSUB 0 +#define JM_SUB_SYS_CMN 1 +#define JM_SUB_SYS_DDRH 2 +#define JM_SUB_SYS_DDRV 3 +#define JM_SUB_SYS_GIC 4 +#define JM_SUB_SYS_IOSUB 5 +#define JM_SUB_SYS_SCP 6 +#define JM_SUB_SYS_MCP 7 +#define JM_SUB_SYS_IMU0 8 +#define JM_SUB_SYS_DPE 9 +#define JM_SUB_SYS_RPE 10 +#define JM_SUB_SYS_PSUB 11 +#define JM_SUB_SYS_HAC 12 +#define JM_SUB_SYS_TCM 13 +#define JM_SUB_SYS_IMU1 14 + +static const char * const subsystem_desc[] = { + "N2", + "CMN", + "DDRH", + "DDRV", + "GIC", + "IOSUB", + "SCP", + "MCP", + "IMU0", + "DPE", + "RPE", + "PSUB", + "HAC", + "TCM", + "IMU1", +}; + +static const char * const cmn_module_desc[] = { + "MXP", + "HNI", + "HNF", + "SBSX", + "CCG", + "HND", +}; + +static const char * const ddr_module_desc[] = { + "DDRCtrl", + "DDRPHY", + "SRAM", +}; + +static const char * const gic_module_desc[] = { + "GICIP", + "GICSRAM", +}; + +/* JaguarMicro IOSUB sub system module definitions */ +#define JM_SUBSYS_IOSUB_MOD_SMMU 0 +#define JM_SUBSYS_IOSUB_MOD_NIC450 1 +#define JM_SUBSYS_IOSUB_MOD_OTHER 2 + +static const char * const iosub_module_desc[] = { + "SMMU", + "NIC450", + "OTHER", +}; + + +static const char * const scp_module_desc[] = { + "SRAM", + "WDT", + "PLL", +}; + +static const char * const mcp_module_desc[] = { + "SRAM", + "WDT", +}; + +static const char * const imu_module_desc[] = { + "SRAM", + "WDT", +}; +/* JaguarMicro DPE sub system module definitions */ +#define JM_SUBSYS_DPE_MOD_EPG 0 +#define JM_SUBSYS_DPE_MOD_PIPE 1 +#define JM_SUBSYS_DPE_MOD_EMEP 2 +#define JM_SUBSYS_DPE_MOD_IMEP 3 +#define JM_SUBSYS_DPE_MOD_EPAE 4 +#define JM_SUBSYS_DPE_MOD_IPAE 5 +#define JM_SUBSYS_DPE_MOD_ETH 6 +#define JM_SUBSYS_DPE_MOD_TPG 7 +#define JM_SUBSYS_DPE_MOD_MIG 8 +#define JM_SUBSYS_DPE_MOD_HIG 9 +#define JM_SUBSYS_DPE_MOD_DPETOP 10 +#define JM_SUBSYS_DPE_MOD_SMMU 11 + +static const char * const dpe_module_desc[] = { + "EPG", + "PIPE", + "EMEP", + "IMEP", + "EPAE", + "IPAE", + "ETH", + "TPG", + "MIG", + "HIG", + "DPETOP", + "SMMU", +}; + +/* JaguarMicro RPE sub system module definitions */ +#define JM_SUBSYS_RPE_MOD_TOP 0 +#define JM_SUBSYS_RPE_MOD_TXP_RXP 1 +#define JM_SUBSYS_RPE_MOD_SMMU 2 + +static const char * const rpe_module_desc[] = { + "TOP", + "TXP_RXP", + "SMMU", +}; + +/* JaguarMicro PSUB sub system module definitions */ +#define JM_SUBSYS_PSUB_MOD_PCIE0 0 +#define JM_SUBSYS_PSUB_MOD_UP_MIX 1 +#define JM_SUBSYS_PSUB_MOD_PCIE1 2 +#define JM_SUBSYS_PSUB_MOD_PTOP 3 +#define JM_SUBSYS_PSUB_MOD_N2IF 4 +#define JM_SUBSYS_PSUB_MOD_VPE0_RAS 5 +#define JM_SUBSYS_PSUB_MOD_VPE1_RAS 6 +#define JM_SUBSYS_PSUB_MOD_X2RC_SMMU 7 +#define JM_SUBSYS_PSUB_MOD_X16RC_SMMU 8 +#define JM_SUBSYS_PSUB_MOD_SDMA_SMMU 9 + +static const char * const psub_module_desc[] = { + "PCIE0", + "UP_MIX", + "PCIE1", + "PTOP", + "N2IF", + "VPE0_RAS", + "VPE1_RAS", + "X2RC_SMMU", + "X16RC_SMMU", + "SDMA_SMMU", +}; + +static const char * const hac_module_desc[] = { + "SRAM", + "SMMU", +}; + +#define JM_SUBSYS_TCM_MOD_SRAM 0 +#define JM_SUBSYS_TCM_MOD_SMMU 1 +#define JM_SUBSYS_TCM_MOD_IP 2 + +static const char * const tcm_module_desc[] = { + "SRAM", + "SMMU", + "IP", +}; + +static const char * const iosub_smmu_sub_desc[] = { + "TBU", + "TCU", +}; + +static const char * const iosub_other_sub_desc[] = { + "RAM", +}; + +static const char * const smmu_sub_desc[] = { + "TCU", + "TBU", +}; + +static const char * const psub_pcie0_sub_desc[] = { + "RAS0", + "RAS1", +}; + +static const char * const csub_dev_desc[] = { + "CORE", +}; + +static const char * const cmn_dev_desc[] = { + "NID", +}; + +static const char * const ddr_dev_desc[] = { + "CHNL", +}; + +static const char * const default_dev_desc[] = { + "DEV", +}; + +static const char *get_jm_soc_desc(uint8_t soc_id) +{ + if (soc_id >= sizeof(soc_desc)/sizeof(char *)) + return "unknown"; + + return soc_desc[soc_id]; +} + +static const char *get_jm_subsystem_desc(uint8_t subsys_id) +{ + if (subsys_id >= sizeof(subsystem_desc)/sizeof(char *)) + return "unknown"; + + return subsystem_desc[subsys_id]; +} + +static const char *get_jm_module_desc(uint8_t subsys_id, uint8_t mod_id) +{ + const char * const*module; + int tbl_size; + + switch (subsys_id) { + case JM_SUB_SYS_CMN: + module = cmn_module_desc; + tbl_size = sizeof(cmn_module_desc)/sizeof(char *); + break; + case JM_SUB_SYS_DDRH: + case JM_SUB_SYS_DDRV: + module = ddr_module_desc; + tbl_size = sizeof(ddr_module_desc)/sizeof(char *); + break; + + case JM_SUB_SYS_GIC: + module = gic_module_desc; + tbl_size = sizeof(gic_module_desc)/sizeof(char *); + break; + case JM_SUB_SYS_IOSUB: + module = iosub_module_desc; + tbl_size = sizeof(iosub_module_desc)/sizeof(char *); + break; + case JM_SUB_SYS_SCP: + module = scp_module_desc; + tbl_size = sizeof(scp_module_desc)/sizeof(char *); + break; + case JM_SUB_SYS_MCP: + module = mcp_module_desc; + tbl_size = sizeof(mcp_module_desc)/sizeof(char *); + break; + case JM_SUB_SYS_IMU0: + case JM_SUB_SYS_IMU1: + module = imu_module_desc; + tbl_size = sizeof(imu_module_desc)/sizeof(char *); + break; + case JM_SUB_SYS_DPE: + module = dpe_module_desc; + tbl_size = sizeof(dpe_module_desc)/sizeof(char *); + break; + case JM_SUB_SYS_RPE: + module = rpe_module_desc; + tbl_size = sizeof(rpe_module_desc)/sizeof(char *); + break; + case JM_SUB_SYS_PSUB: + module = psub_module_desc; + tbl_size = sizeof(psub_module_desc)/sizeof(char *); + break; + case JM_SUB_SYS_HAC: + module = hac_module_desc; + tbl_size = sizeof(hac_module_desc)/sizeof(char *); + break; + case JM_SUB_SYS_TCM: + module = tcm_module_desc; + tbl_size = sizeof(tcm_module_desc)/sizeof(char *); + break; + + default: + module = NULL; + break; + } + + if ((module == NULL) || (mod_id >= tbl_size)) + return "unknown"; + + return module[mod_id]; +} + +static const char *get_jm_submod_desc(uint8_t subsys_id, uint8_t mod_id, uint8_t sub_id) +{ + const char * const*sub_module; + int tbl_size; + + if (subsys_id == JM_SUB_SYS_IOSUB && mod_id == JM_SUBSYS_IOSUB_MOD_SMMU) { + sub_module = iosub_smmu_sub_desc; + tbl_size = sizeof(iosub_smmu_sub_desc)/sizeof(char *); + } else if (subsys_id == JM_SUB_SYS_IOSUB && mod_id == JM_SUBSYS_IOSUB_MOD_OTHER) { + sub_module = iosub_other_sub_desc; + tbl_size = sizeof(iosub_other_sub_desc)/sizeof(char *); + } else if (subsys_id == JM_SUB_SYS_DPE && mod_id == JM_SUBSYS_DPE_MOD_SMMU) { + sub_module = smmu_sub_desc; + tbl_size = sizeof(smmu_sub_desc)/sizeof(char *); + } else if (subsys_id == JM_SUB_SYS_RPE && mod_id == JM_SUBSYS_RPE_MOD_SMMU) { + sub_module = smmu_sub_desc; + tbl_size = sizeof(smmu_sub_desc)/sizeof(char *); + } else if (subsys_id == JM_SUB_SYS_PSUB && mod_id == JM_SUBSYS_PSUB_MOD_PCIE0) { + sub_module = psub_pcie0_sub_desc; + tbl_size = sizeof(psub_pcie0_sub_desc)/sizeof(char *); + } else if (subsys_id == JM_SUB_SYS_PSUB && mod_id == JM_SUBSYS_PSUB_MOD_X2RC_SMMU) { + sub_module = smmu_sub_desc; + tbl_size = sizeof(smmu_sub_desc)/sizeof(char *); + } else if (subsys_id == JM_SUB_SYS_PSUB && mod_id == JM_SUBSYS_PSUB_MOD_X16RC_SMMU) { + sub_module = smmu_sub_desc; + tbl_size = sizeof(smmu_sub_desc)/sizeof(char *); + } else if (subsys_id == JM_SUB_SYS_PSUB && mod_id == JM_SUBSYS_PSUB_MOD_SDMA_SMMU) { + sub_module = smmu_sub_desc; + tbl_size = sizeof(smmu_sub_desc)/sizeof(char *); + } else if (subsys_id == JM_SUB_SYS_TCM && mod_id == JM_SUBSYS_TCM_MOD_SMMU) { + sub_module = smmu_sub_desc; + tbl_size = sizeof(smmu_sub_desc)/sizeof(char *); + } else { + sub_module = NULL; + tbl_size = 0; + } + + if ((sub_module == NULL) || (sub_id >= tbl_size)) + return "unknown"; + + return sub_module[sub_id]; +} + + +static const char *get_jm_dev_desc(uint8_t subsys_id, uint8_t mod_id, uint8_t sub_id) +{ + if (subsys_id == JM_SUB_SYS_CSUB) + return csub_dev_desc[0]; + else if (subsys_id == JM_SUB_SYS_DDRH || subsys_id == JM_SUB_SYS_DDRV) + return ddr_dev_desc[0]; + else if (subsys_id == JM_SUB_SYS_CMN) + return cmn_dev_desc[0]; + else + return default_dev_desc[0]; +} + + +#define JM_ERR_SEVERITY_NFE 0 +#define JM_ERR_SEVERITY_FE 1 +#define JM_ERR_SEVERITY_CE 2 +#define JM_ERR_SEVERITY_NONE 3 + +/* helper functions */ +static inline char *jm_err_severity(uint8_t err_sev) +{ + switch (err_sev) { + case JM_ERR_SEVERITY_NFE: return "recoverable"; + case JM_ERR_SEVERITY_FE: return "fatal"; + case JM_ERR_SEVERITY_CE: return "corrected"; + case JM_ERR_SEVERITY_NONE: return "none"; + default: + break; + } + return "unknown"; +} + +static void decode_jm_common_sec_head(struct ras_ns_ev_decoder *ev_decoder, + const struct jm_common_sec_head *err, + struct jm_event *event) +{ + if (err->val_bits & BIT(JM_COMMON_VALID_SOC_ID)) { + JM_SNPRINTF(event->error_msg, "[ table_version=%hhu decode_version:%hhu", + err->version, PAYLOAD_VERSION); + record_jm_data(ev_decoder, JM_OEM_DATA_TYPE_INT, + JM_PAYLOAD_FIELD_VERSION, + err->version, NULL); + } + + if (err->val_bits & BIT(JM_COMMON_VALID_SOC_ID)) { + JM_SNPRINTF(event->error_msg, " soc=%s", get_jm_soc_desc(err->soc_id)); + record_jm_data(ev_decoder, JM_OEM_DATA_TYPE_INT, + JM_PAYLOAD_FIELD_SOC_ID, + err->soc_id, NULL); + } + + if (err->val_bits & BIT(JM_COMMON_VALID_SUBSYSTEM_ID)) { + JM_SNPRINTF(event->error_msg, " sub system=%s", + get_jm_subsystem_desc(err->subsystem_id)); + record_jm_data(ev_decoder, JM_OEM_DATA_TYPE_TEXT, + JM_PAYLOAD_FIELD_SUB_SYS, + 0, get_jm_subsystem_desc(err->subsystem_id)); + } + + if (err->val_bits & BIT(JM_COMMON_VALID_MODULE_ID)) { + JM_SNPRINTF(event->error_msg, " module=%s", + get_jm_module_desc(err->subsystem_id, err->module_id)); + record_jm_data(ev_decoder, JM_OEM_DATA_TYPE_TEXT, + JM_PAYLOAD_FIELD_MODULE, + 0, get_jm_module_desc(err->subsystem_id, err->module_id)); + record_jm_data(ev_decoder, JM_OEM_DATA_TYPE_INT, + JM_PAYLOAD_FIELD_MODULE_ID, + err->module_id, NULL); + } + + if (err->val_bits & BIT(JM_COMMON_VALID_SUBMODULE_ID)) { + JM_SNPRINTF(event->error_msg, " sub module=%s", + get_jm_submod_desc(err->subsystem_id, err->module_id, err->submodule_id)); + record_jm_data(ev_decoder, JM_OEM_DATA_TYPE_TEXT, + JM_PAYLOAD_FIELD_SUB_MODULE, + 0, + get_jm_submod_desc(err->subsystem_id, err->module_id, err->submodule_id)); + record_jm_data(ev_decoder, JM_OEM_DATA_TYPE_INT, + JM_PAYLOAD_FIELD_MODULE_ID, + err->submodule_id, NULL); + } + + + if (err->val_bits & BIT(JM_COMMON_VALID_DEV_ID)) { + JM_SNPRINTF(event->error_msg, " dev=%s", + get_jm_dev_desc(err->subsystem_id, err->module_id, err->submodule_id)); + record_jm_data(ev_decoder, JM_OEM_DATA_TYPE_TEXT, + JM_PAYLOAD_FIELD_DEV, + 0, get_jm_dev_desc(err->subsystem_id, err->module_id, err->submodule_id)); + record_jm_data(ev_decoder, JM_OEM_DATA_TYPE_INT, + JM_PAYLOAD_FIELD_DEV_ID, + err->dev_id, NULL); + + } + + + if (err->val_bits & BIT(JM_COMMON_VALID_ERR_TYPE)) { + JM_SNPRINTF(event->error_msg, " err_type=%hu", err->err_type); + record_jm_data(ev_decoder, JM_OEM_DATA_TYPE_INT, + JM_PAYLOAD_FIELD_ERR_TYPE, + err->err_type, NULL); + } + + + if (err->val_bits & BIT(JM_COMMON_VALID_ERR_SEVERITY)) { + JM_SNPRINTF(event->error_msg, " err_severity=%s", + jm_err_severity(err->err_severity)); + record_jm_data(ev_decoder, JM_OEM_DATA_TYPE_TEXT, + JM_PAYLOAD_FIELD_ERR_SEVERITY, + 0, jm_err_severity(err->err_severity)); + } + + JM_SNPRINTF(event->error_msg, "]"); +} + +static void decode_jm_common_sec_tail(struct ras_ns_ev_decoder *ev_decoder, + const struct jm_common_sec_tail *err, + struct jm_event *event, uint32_t val_bits) +{ + if (val_bits & BIT(JM_COMMON_VALID_REG_ARRAY_SIZE) && err->reg_array_size > 0) { + int i; + + JM_SNPRINTF(event->reg_msg, "Extended Register Dump:"); + for (i = 0; i < err->reg_array_size; i++) { + JM_SNPRINTF(event->reg_msg, "reg%02d=0x%08x", + i, err->reg_array[i]); + } + } +} + +#ifdef HAVE_SQLITE3 + +/*key pair definition for jaguar micro specific error payload type 0*/ +static const struct db_fields jm_payload0_event_fields[] = { + { .name = "id", .type = "INTEGER PRIMARY KEY" }, + { .name = "timestamp", .type = "TEXT" }, + { .name = "version", .type = "INTEGER" }, + { .name = "soc_id", .type = "INTEGER" }, + { .name = "subsystem", .type = "TEXT" }, + { .name = "module", .type = "TEXT" }, + { .name = "module_id", .type = "INTEGER" }, + { .name = "sub_module", .type = "TEXT" }, + { .name = "submodule_id", .type = "INTEGER" }, + { .name = "dev", .type = "TEXT" }, + { .name = "dev_id", .type = "INTEGER" }, + { .name = "err_type", .type = "INTEGER" }, + { .name = "err_severity", .type = "TEXT" }, + { .name = "regs_dump", .type = "TEXT" }, +}; + +static const struct db_table_descriptor jm_payload0_event_tab = { + .name = "jm_payload0_event", + .fields = jm_payload0_event_fields, + .num_fields = ARRAY_SIZE(jm_payload0_event_fields), +}; + +/*Save data with different type into sqlite3 db*/ +static void record_jm_data(struct ras_ns_ev_decoder *ev_decoder, + enum jm_oem_data_type data_type, int id, + int64_t data, const char *text) +{ + switch (data_type) { + case JM_OEM_DATA_TYPE_INT: + sqlite3_bind_int(ev_decoder->stmt_dec_record, id, data); + break; + case JM_OEM_DATA_TYPE_INT64: + sqlite3_bind_int64(ev_decoder->stmt_dec_record, id, data); + break; + case JM_OEM_DATA_TYPE_TEXT: + sqlite3_bind_text(ev_decoder->stmt_dec_record, id, text, + -1, NULL); + break; + default: + break; + } +} + +static int store_jm_err_data(struct ras_ns_ev_decoder *ev_decoder, + const char *tab_name) +{ + int rc; + + rc = sqlite3_step(ev_decoder->stmt_dec_record); + if (rc != SQLITE_OK && rc != SQLITE_DONE) + log(TERM, LOG_ERR, + "Failed to do step on sqlite. Table = %s error = %d\n", + tab_name, rc); + + rc = sqlite3_reset(ev_decoder->stmt_dec_record); + if (rc != SQLITE_OK && rc != SQLITE_DONE) + log(TERM, LOG_ERR, + "Failed to reset on sqlite. Table = %s error = %d\n", + tab_name, rc); + + rc = sqlite3_clear_bindings(ev_decoder->stmt_dec_record); + if (rc != SQLITE_OK && rc != SQLITE_DONE) + log(TERM, LOG_ERR, + "Failed to clear bindings on sqlite. Table = %s error = %d\n", + tab_name, rc); + + return rc; +} + + +/*save all JaguarMicro Specific Error Payload type 0 to sqlite3 database*/ +static void record_jm_payload_err(struct ras_ns_ev_decoder *ev_decoder, + const char *reg_str) +{ + if (ev_decoder != NULL) { + record_jm_data(ev_decoder, JM_OEM_DATA_TYPE_TEXT, + JM_PAYLOAD_FIELD_REGS_DUMP, 0, reg_str); + store_jm_err_data(ev_decoder, "jm_payload0_event_tab"); + } +} + +#else +static void record_jm_data(struct ras_ns_ev_decoder *ev_decoder, + enum jm_oem_data_type data_type, + int id, int64_t data, const char *text) +{ +} + +static void record_jm_payload_err(struct ras_ns_ev_decoder *ev_decoder, + const char *reg_str) +{ +} + +#endif + + +/*decode JaguarMicro specific error payload type 0, the CPU's data is save*/ +/*to sqlite by ras-arm-handler, others are saved by this function.*/ +static void decode_jm_payload0_err_regs(struct ras_ns_ev_decoder *ev_decoder, + struct trace_seq *s, + const struct jm_payload0_type_sec *err) +{ + int i = 0; + + const struct jm_common_sec_head *common_head = &err->common_head; + const struct jm_common_sec_tail *common_tail = &err->common_tail; + + struct jm_event jmevent; + + memset(&jmevent, 0, sizeof(struct jm_event)); + trace_seq_printf(s, "\nJaguar Micro Common Error Section:\n"); + decode_jm_common_sec_head(ev_decoder, common_head, &jmevent); + trace_seq_printf(s, "%s\n", jmevent.error_msg); + + //display lock_control + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload0_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->lock_control); + + //display lock_function + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload0_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->lock_function); + + //display cfg_ram_id + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload0_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->cfg_ram_id); + + //display err_fr_low32 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload0_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->err_fr_low32); + + //display err_fr_high32 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload0_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->err_fr_high32); + + //display err_ctlr_low32 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload0_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->err_ctlr_low32); + + //display ecc_status_low32 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload0_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->ecc_status_low32); + + //display ecc_addr_low32 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload0_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->ecc_addr_low32); + + //display ecc_addr_high32 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload0_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->ecc_addr_high32); + + //display ecc_misc0_low32 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload0_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->ecc_misc0_low32); + + //display ecc_misc0_high32 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload0_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->ecc_misc0_high32); + + //display ecc_misc1_low32 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload0_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->ecc_misc1_low32); + + //display ecc_misc1_high32 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload0_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->ecc_misc1_high32); + + //display ecc_misc2_Low32 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload0_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->ecc_misc2_Low32); + + //display ecc_misc2_high32 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload0_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x\n", err->ecc_misc2_high32); + + trace_seq_printf(s, "Register Dump:\n"); + decode_jm_common_sec_tail(ev_decoder, common_tail, &jmevent, common_head->val_bits); + + record_jm_payload_err(ev_decoder, jmevent.reg_msg); + + trace_seq_printf(s, "%s\n", jmevent.reg_msg); +} + +/*decode JaguarMicro specific error payload type 1 and save to sqlite db*/ +static void decode_jm_payload1_err_regs(struct ras_ns_ev_decoder *ev_decoder, + struct trace_seq *s, + const struct jm_payload1_type_sec *err) +{ + int i = 0; + + const struct jm_common_sec_head *common_head = &err->common_head; + const struct jm_common_sec_tail *common_tail = &err->common_tail; + + struct jm_event jmevent; + + memset(&jmevent, 0, sizeof(struct jm_event)); + trace_seq_printf(s, "\nJaguarMicro Common Error Section:\n"); + decode_jm_common_sec_head(ev_decoder, common_head, &jmevent); + trace_seq_printf(s, "%s\n", jmevent.error_msg); + + //display smmu csr(Inturrpt status) + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload1_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->smmu_csr); + + //display ERRFR + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload1_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->errfr); + + //display ERRCTLR + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload1_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->errctlr); + + //display ERRSTATUS + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload1_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->errstatus); + + //display ERRGEN + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload1_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x\n", err->errgen); + + + trace_seq_printf(s, "Register Dump:\n"); + decode_jm_common_sec_tail(ev_decoder, common_tail, &jmevent, common_head->val_bits); + + + record_jm_payload_err(ev_decoder, jmevent.reg_msg); + + trace_seq_printf(s, "%s\n", jmevent.reg_msg); +} + +/*decode JaguarMicro specific error payload type 2 and save to sqlite db*/ +static void decode_jm_payload2_err_regs(struct ras_ns_ev_decoder *ev_decoder, + struct trace_seq *s, + const struct jm_payload2_type_sec *err) +{ + int i = 0; + + const struct jm_common_sec_head *common_head = &err->common_head; + const struct jm_common_sec_tail *common_tail = &err->common_tail; + + struct jm_event jmevent; + + memset(&jmevent, 0, sizeof(struct jm_event)); + trace_seq_printf(s, "\nJaguarMicro Common Error Section:\n"); + decode_jm_common_sec_head(ev_decoder, common_head, &jmevent); + trace_seq_printf(s, "%s\n", jmevent.error_msg); + + + //display ecc_1bit_error_interrupt_low + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload2_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->ecc_1bit_int_low); + + //display ecc_1bit_error_interrupt_high + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload2_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->ecc_1bit_int_high); + + //display ecc_2bit_error_interrupt_low + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload2_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x; ", err->ecc_2bit_int_low); + + //display ecc_2bit_error_interrupt_high + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload2_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%x\n", err->ecc_2bit_int_high); + + + trace_seq_printf(s, "Register Dump:\n"); + decode_jm_common_sec_tail(ev_decoder, common_tail, &jmevent, common_head->val_bits); + + record_jm_payload_err(ev_decoder, jmevent.reg_msg); + + trace_seq_printf(s, "%s\n", jmevent.reg_msg); +} + +/*decode JaguarMicro specific error payload type 5 and save to sqlite db*/ +static void decode_jm_payload5_err_regs(struct ras_ns_ev_decoder *ev_decoder, + struct trace_seq *s, + const struct jm_payload5_type_sec *err) +{ + int i = 0; + + const struct jm_common_sec_head *common_head = &err->common_head; + const struct jm_common_sec_tail *common_tail = &err->common_tail; + + struct jm_event jmevent; + + memset(&jmevent, 0, sizeof(struct jm_event)); + trace_seq_printf(s, "\nJaguarMicro Common Error Section:\n"); + decode_jm_common_sec_head(ev_decoder, common_head, &jmevent); + trace_seq_printf(s, "%s\n", jmevent.error_msg); + + //display cfgm_mxp_0 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload5_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->cfgm_mxp_0); + + //display cfgm_hnf_0 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload5_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->cfgm_hnf_0); + + //display cfgm_hni_0 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload5_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->cfgm_hni_0); + + //display cfgm_sbsx_0 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload5_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->cfgm_sbsx_0); + + //display errfr_NS + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload5_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->errfr_NS); + + //display errctlrr_NS + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload5_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->errctlrr_NS); + + //display errstatusr_NS + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload5_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->errstatusr_NS); + + //display erraddrr_NS + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload5_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->erraddrr_NS); + + //display errmiscr_NS + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload5_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->errmiscr_NS); + + //display errfr + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload5_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->errfr); + + //display errctlr + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload5_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->errctlr); + + //display errstatus + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload5_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->errstatus); + + //display erraddr + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload5_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->erraddr); + + //display errmisc + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload5_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx\n", (unsigned long long)err->errmisc); + + trace_seq_printf(s, "Register Dump:\n"); + decode_jm_common_sec_tail(ev_decoder, common_tail, &jmevent, common_head->val_bits); + + record_jm_payload_err(ev_decoder, jmevent.reg_msg); + + trace_seq_printf(s, "%s\n", jmevent.reg_msg); +} + + +/*decode JaguarMicro specific error payload type 6 and save to sqlite db*/ +static void decode_jm_payload6_err_regs(struct ras_ns_ev_decoder *ev_decoder, + struct trace_seq *s, + const struct jm_payload6_type_sec *err) +{ + int i = 0; + + const struct jm_common_sec_head *common_head = &err->common_head; + const struct jm_common_sec_tail *common_tail = &err->common_tail; + + struct jm_event jmevent; + + memset(&jmevent, 0, sizeof(struct jm_event)); + trace_seq_printf(s, "\nJaguarMicro Common Error Section:\n"); + decode_jm_common_sec_head(ev_decoder, common_head, &jmevent); + trace_seq_printf(s, "%s\n", jmevent.error_msg); + //display RECORD_ID + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload6_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->record_id); + + //display GICT_ERR_FR + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload6_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->gict_err_fr); + + //display GICT_ERR_CTLR + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload6_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->gict_err_ctlr); + + //display GICT_ERR_STATUS + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload6_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->gict_err_status); + + //display GICT_ERR_ADDR + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload6_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->gict_err_addr); + + //display GICT_ERR_MISC0 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload6_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->gict_err_misc0); + + //display GICT_ERR_MISC1 + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload6_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx; ", (unsigned long long)err->gict_err_misc1); + + //display GICT_ERRGSR + JM_SNPRINTF(jmevent.reg_msg, " %s", disp_payload6_err_reg_name[i++]); + JM_SNPRINTF(jmevent.reg_msg, " 0x%llx\n", (unsigned long long)err->gict_errgsr); + + trace_seq_printf(s, "Register Dump:\n"); + decode_jm_common_sec_tail(ev_decoder, common_tail, &jmevent, common_head->val_bits); + + record_jm_payload_err(ev_decoder, jmevent.reg_msg); + trace_seq_printf(s, "%s\n", jmevent.reg_msg); +} + +/* error data decoding functions */ +static int decode_jm_oem_type_error(struct ras_events *ras, + struct ras_ns_ev_decoder *ev_decoder, + struct trace_seq *s, + struct ras_non_standard_event *event, + int payload_type) +{ + int id = JM_PAYLOAD_FIELD_TIMESTAMP; + + record_jm_data(ev_decoder, JM_OEM_DATA_TYPE_TEXT, + id, 0, event->timestamp); + + if (payload_type == PAYLOAD_TYPE_0) { + const struct jm_payload0_type_sec *err = + (struct jm_payload0_type_sec *)event->error; + decode_jm_payload0_err_regs(ev_decoder, s, err); + } else if (payload_type == PAYLOAD_TYPE_1) { + const struct jm_payload1_type_sec *err = + (struct jm_payload1_type_sec *)event->error; + decode_jm_payload1_err_regs(ev_decoder, s, err); + } else if (payload_type == PAYLOAD_TYPE_2) { + const struct jm_payload2_type_sec *err = + (struct jm_payload2_type_sec *)event->error; + decode_jm_payload2_err_regs(ev_decoder, s, err); + } else if (payload_type == PAYLOAD_TYPE_5) { + const struct jm_payload5_type_sec *err = + (struct jm_payload5_type_sec *)event->error; + decode_jm_payload5_err_regs(ev_decoder, s, err); + } else if (payload_type == PAYLOAD_TYPE_6) { + const struct jm_payload6_type_sec *err = + (struct jm_payload6_type_sec *)event->error; + decode_jm_payload6_err_regs(ev_decoder, s, err); + } else { + trace_seq_printf(s, "%s : wrong payload type\n", __func__); + log(TERM, LOG_ERR, "%s : wrong payload type\n", __func__); + return -1; + } + return 0; +} + +/* error type0 data decoding functions */ +static int decode_jm_oem_type0_error(struct ras_events *ras, + struct ras_ns_ev_decoder *ev_decoder, + struct trace_seq *s, + struct ras_non_standard_event *event) +{ + return decode_jm_oem_type_error(ras, ev_decoder, s, event, PAYLOAD_TYPE_0); +} + +/* error type1 data decoding functions */ +static int decode_jm_oem_type1_error(struct ras_events *ras, + struct ras_ns_ev_decoder *ev_decoder, + struct trace_seq *s, + struct ras_non_standard_event *event) +{ + return decode_jm_oem_type_error(ras, ev_decoder, s, event, PAYLOAD_TYPE_1); +} +/* error type2 data decoding functions */ +static int decode_jm_oem_type2_error(struct ras_events *ras, + struct ras_ns_ev_decoder *ev_decoder, + struct trace_seq *s, + struct ras_non_standard_event *event) +{ + return decode_jm_oem_type_error(ras, ev_decoder, s, event, PAYLOAD_TYPE_2); +} + +/* error type5 data decoding functions */ +static int decode_jm_oem_type5_error(struct ras_events *ras, + struct ras_ns_ev_decoder *ev_decoder, + struct trace_seq *s, + struct ras_non_standard_event *event) +{ + return decode_jm_oem_type_error(ras, ev_decoder, s, event, PAYLOAD_TYPE_5); +} + +/* error type6 data decoding functions */ +static int decode_jm_oem_type6_error(struct ras_events *ras, + struct ras_ns_ev_decoder *ev_decoder, + struct trace_seq *s, + struct ras_non_standard_event *event) +{ + return decode_jm_oem_type_error(ras, ev_decoder, s, event, PAYLOAD_TYPE_6); +} + +static int add_jm_oem_type0_table(struct ras_events *ras, struct ras_ns_ev_decoder *ev_decoder) +{ +#ifdef HAVE_SQLITE3 + if (ras->record_events && !ev_decoder->stmt_dec_record) { + if (ras_mc_add_vendor_table(ras, &ev_decoder->stmt_dec_record, + &jm_payload0_event_tab) != SQLITE_OK) { + log(TERM, LOG_WARNING, "Failed to create sql jm_payload0_event_tab\n"); + return -1; + } + } +#endif + return 0; +} + + +struct ras_ns_ev_decoder jm_ns_oem_type_decoder[] = { + { + .sec_type = "82d78ba3-fa14-407a-ba0e-f3ba8170013c", + .add_table = add_jm_oem_type0_table, + .decode = decode_jm_oem_type0_error, + }, + { + .sec_type = "f9723053-2558-49b1-b58a-1c1a82492a62", + .add_table = add_jm_oem_type0_table, + .decode = decode_jm_oem_type1_error, + }, + { + .sec_type = "2d31de54-3037-4f24-a283-f69ca1ec0b9a", + .add_table = add_jm_oem_type0_table, + .decode = decode_jm_oem_type2_error, + }, + { + .sec_type = "dac80d69-0a72-4eba-8114-148ee344af06", + .add_table = add_jm_oem_type0_table, + .decode = decode_jm_oem_type5_error, + }, + { + .sec_type = "746f06fe-405e-451f-8d09-02e802ed984a", + .add_table = add_jm_oem_type0_table, + .decode = decode_jm_oem_type6_error, + }, +}; + +static void __attribute__((constructor)) jm_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(jm_ns_oem_type_decoder); i++) + register_ns_ev_decoder(&jm_ns_oem_type_decoder[i]); +} + + diff --git a/non-standard-jaguarmicro.h b/non-standard-jaguarmicro.h new file mode 100644 index 0000000..eb61a25 --- /dev/null +++ b/non-standard-jaguarmicro.h @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2023, JaguarMicro + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + + +#ifndef __NON_STANDARD_JAGUAR_H +#define __NON_STANDARD_JAGUAR_H + +#include "ras-events.h" +#include +#include "ras-mce-handler.h" + +#define PAYLOAD_TYPE_0 0x00 +#define PAYLOAD_TYPE_1 0x01 +#define PAYLOAD_TYPE_2 0x02 +#define PAYLOAD_TYPE_3 0x03 +#define PAYLOAD_TYPE_4 0x04 +#define PAYLOAD_TYPE_5 0x05 +#define PAYLOAD_TYPE_6 0x06 +#define PAYLOAD_TYPE_7 0x07 +#define PAYLOAD_TYPE_8 0x08 +#define PAYLOAD_TYPE_9 0x09 + +#define PAYLOAD_VERSION 0 + +enum { + JM_COMMON_VALID_VERSION = 0, + JM_COMMON_VALID_SOC_ID, + JM_COMMON_VALID_SUBSYSTEM_ID, + JM_COMMON_VALID_MODULE_ID, + JM_COMMON_VALID_SUBMODULE_ID, + JM_COMMON_VALID_DEV_ID, + JM_COMMON_VALID_ERR_TYPE, + JM_COMMON_VALID_ERR_SEVERITY, + JM_COMMON_VALID_REG_ARRAY_SIZE = 11, +}; + +struct jm_common_sec_head { + uint32_t val_bits; + uint8_t version; + uint8_t soc_id; + uint8_t subsystem_id; + uint8_t module_id; + uint8_t submodule_id; + uint8_t dev_id; + uint16_t err_type; + uint8_t err_severity; + uint8_t reserved[3]; +}; + +struct jm_common_sec_tail { + uint32_t reg_array_size; + uint32_t reg_array[]; +}; + +/* ras_csr_por*/ +struct jm_payload0_type_sec { + struct jm_common_sec_head common_head; + + uint32_t lock_control; + uint32_t lock_function; + uint32_t cfg_ram_id; + uint32_t err_fr_low32; + uint32_t err_fr_high32; + uint32_t err_ctlr_low32; + uint32_t ecc_status_low32; + uint32_t ecc_addr_low32; + uint32_t ecc_addr_high32; + uint32_t ecc_misc0_low32; + uint32_t ecc_misc0_high32; + uint32_t ecc_misc1_low32; + uint32_t ecc_misc1_high32; + uint32_t ecc_misc2_Low32; + uint32_t ecc_misc2_high32; + + struct jm_common_sec_tail common_tail; +}; + +/*SMMU IP*/ +struct jm_payload1_type_sec { + struct jm_common_sec_head common_head; + + uint32_t smmu_csr; + uint32_t errfr; + uint32_t errctlr; + uint32_t errstatus; + uint32_t errgen; + + struct jm_common_sec_tail common_tail; +}; + +/*HAC SRAM */ +struct jm_payload2_type_sec { + struct jm_common_sec_head common_head; + + uint32_t ecc_1bit_int_low; + uint32_t ecc_1bit_int_high; + uint32_t ecc_2bit_int_low; + uint32_t ecc_2bit_int_high; + + struct jm_common_sec_tail common_tail; +}; + +/*CMN IP */ +struct jm_payload5_type_sec { + struct jm_common_sec_head common_head; + + uint64_t cfgm_mxp_0; + uint64_t cfgm_hnf_0; + uint64_t cfgm_hni_0; + uint64_t cfgm_sbsx_0; + uint64_t errfr_NS; + uint64_t errctlrr_NS; + uint64_t errstatusr_NS; + uint64_t erraddrr_NS; + uint64_t errmiscr_NS; + uint64_t errfr; + uint64_t errctlr; + uint64_t errstatus; + uint64_t erraddr; + uint64_t errmisc; + + struct jm_common_sec_tail common_tail; +}; + + +/*GIC IP */ +struct jm_payload6_type_sec { + struct jm_common_sec_head common_head; + uint64_t record_id; + uint64_t gict_err_fr; + uint64_t gict_err_ctlr; + uint64_t gict_err_status; + uint64_t gict_err_addr; + uint64_t gict_err_misc0; + uint64_t gict_err_misc1; + uint64_t gict_errgsr; + + struct jm_common_sec_tail common_tail; +}; + +enum jm_oem_data_type { + JM_OEM_DATA_TYPE_INT, + JM_OEM_DATA_TYPE_INT64, + JM_OEM_DATA_TYPE_TEXT, +}; + +enum { + JM_PAYLOAD_FIELD_ID, + JM_PAYLOAD_FIELD_TIMESTAMP, + JM_PAYLOAD_FIELD_VERSION, + JM_PAYLOAD_FIELD_SOC_ID, + JM_PAYLOAD_FIELD_SUB_SYS, + JM_PAYLOAD_FIELD_MODULE, + JM_PAYLOAD_FIELD_MODULE_ID, + JM_PAYLOAD_FIELD_SUB_MODULE, + JM_PAYLOAD_FIELD_SUBMODULE_ID, + JM_PAYLOAD_FIELD_DEV, + JM_PAYLOAD_FIELD_DEV_ID, + JM_PAYLOAD_FIELD_ERR_TYPE, + JM_PAYLOAD_FIELD_ERR_SEVERITY, + JM_PAYLOAD_FIELD_REGS_DUMP, +}; + + +#define JM_SNPRINTF mce_snprintf +#endif diff --git a/util/ras-mc-ctl.in b/util/ras-mc-ctl.in index fb35afe..227a77d 100755 --- a/util/ras-mc-ctl.in +++ b/util/ras-mc-ctl.in @@ -1542,6 +1542,7 @@ sub errors use constant { HISILICON_KUNPENG_9XX => "KunPeng9xx", THEAD_YITIAN_7XX => "YiTian7XX", + JM_CORSICA_DPU1XX => "CorsicaDpu1xx", }; sub vendor_errors_summary @@ -1549,7 +1550,7 @@ sub vendor_errors_summary require DBI; my ($num_args, $platform_id, $found_platform); my ($query, $query_handle, $count, $out); - my ($module_id, $sub_module_id, $err_severity, $err_sev); + my ($module_id, $sub_module_id, $err_severity, $err_sev, $subsystem); my ($address); $num_args = $#ARGV + 1; @@ -1659,7 +1660,29 @@ sub vendor_errors_summary } $query_handle->finish; } - + # JaguarMicro CorsicaDpu1xx errors + if ($platform_id eq JM_CORSICA_DPU1XX) { + $found_platform = 1; + $query = "select err_severity, subsystem, count(*) from jm_payload0_event$conf{opt}{since} group by err_severity, subsystem"; + $query_handle = $dbh->prepare($query); + if ($query_handle) { + $query_handle->execute(); + $query_handle->bind_columns(\($err_severity, $subsystem, $count)); + $out = ""; + $err_sev = ""; + while($query_handle->fetch()) { + if ($err_severity ne $err_sev) { + $out .= "$err_severity errors:\n"; + $err_sev = $err_severity; + } + $out .= "\t$subsystem: $count\n"; + } + if ($out ne "") { + print "JaguarMicro CorsicaDpu1xx OEM type0 error events summary:\n$out\n"; + } + $query_handle->finish; + } + } if ($platform_id && !($found_platform)) { print "Platform ID $platform_id is not valid\n"; } @@ -1670,10 +1693,10 @@ sub vendor_errors_summary sub vendor_errors { require DBI; - my ($num_args, $platform_id, $found_platform, $module, $found_module); + my ($num_args, $platform_id, $found_platform, $module, $found_module, $module_name, $sub_module); my ($query, $query_handle, $id, $timestamp, $out); my ($version, $soc_id, $socket_id, $totem_id, $nimbus_id, $sub_system_id, $core_id, $port_id); - my ($module_id, $sub_module_id, $err_severity, $err_type, $pcie_info, $regs); + my ($module_id, $sub_module_id, $err_severity, $err_type, $pcie_info, $regs, $subsystem, $dev, $dev_id); my ($address, $regs_dump); $num_args = $#ARGV + 1; @@ -1827,6 +1850,40 @@ sub vendor_errors $query_handle->finish; } + # JaguarMicro CorsicaDpu1xx errors + if ($platform_id eq JM_CORSICA_DPU1XX) { + $found_platform = 1; + $query = "select id, timestamp, version, soc_id, subsystem, module, module_id, sub_module, submodule_id, dev, dev_id, err_type, err_severity, regs_dump from jm_payload0_event$conf{opt}{since} order by id, module_id, err_severity"; + $query_handle = $dbh->prepare($query); + if ($query_handle) { + $query_handle->execute(); + $query_handle->bind_columns(\($id, $timestamp, $version, $soc_id, $subsystem, $module_name, $module_id, $sub_module, $sub_module_id, $dev, $dev_id, $err_type, $err_severity, $regs)); + $out = ""; + while($query_handle->fetch()) { + if ($module eq 0 || ($module_id && uc($module) eq uc($module_id))) { + $out .= "$id. $timestamp Error Info: "; + $out .= "version=$version, "; + $out .= "soc_id=$soc_id, " if (defined $soc_id && length $soc_id); + $out .= "subsystem=$subsystem, " if (defined $subsystem && length $subsystem); + $out .= "module=$module_name, " if (defined $module_name && length $module_name); + $out .= "module_id=$module_id, " if (defined $module_id && length $module_id); + $out .= "sub_module=$sub_module, " if (defined $sub_module && length $sub_module); + $out .= "submodule_id=$sub_module_id, " if (defined $sub_module_id && length $sub_module_id); + $out .= "dev=$dev, " if (defined $dev && length $dev); + $out .= "dev_id=$dev_id, " if (defined $dev_id && length $dev_id); + $out .= "err_type=$err_type, " if (defined $err_type && length $err_type); + $out .= "err_severity=$err_severity, " if (defined $err_severity && length $err_severity); + $out .= "Error Registers: $regs " if (defined $regs && length $regs); + $out .= "\n\n"; + $found_module = 1; + } + } + if ($out ne "") { + print "JaguarMicro Corsica DPU1xx OEM type0 error events:\n$out\n"; + } + $query_handle->finish; + } + } if ($platform_id && !($found_platform)) { print "Platform ID $platform_id is not valid\n"; } elsif ($module && !($found_module)) { @@ -1840,6 +1897,7 @@ sub vendor_platforms print "\nSupported platforms for the vendor-specific errors:\n"; print "\tHiSilicon KunPeng9xx, platform-id=\"", HISILICON_KUNPENG_9XX, "\"\n"; print "\tTHead Yitian7xx, platform-id=\"", THEAD_YITIAN_7XX, "\"\n"; + print "\tJaguarMicro CorsicaDpu1xx, platform-id=\"", JM_CORSICA_DPU1XX, "\"\n"; print "\n"; }