]> www.infradead.org Git - users/mchehab/rasdaemon.git/commitdiff
rasdaemon: ras-mc-ctl: Add support to display the JaguarMicro vendor errors
authorHunter He <hunter.he@jaguarmicro.com>
Mon, 25 Dec 2023 09:34:56 +0000 (17:34 +0800)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Mon, 22 Jan 2024 07:30:36 +0000 (08:30 +0100)
Add support to display the JaguarMicro Corsica DPU vendor errors event.

Signed-off-by: Hunter He <hunter.he@jaguarmicro.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Makefile.am
configure.ac
non-standard-jaguarmicro.c [new file with mode: 0644]
non-standard-jaguarmicro.h [new file with mode: 0644]
util/ras-mc-ctl.in

index a94d8fe93397c5b1382689b75051d9d2147e5e1f..9dd42c9727f55eb74fb92343739b23258224028a 100644 (file)
@@ -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
index f3fbe8c596a82830d8912030ee0cdfac755c4efb..163fa1776e1d17bf996f48d7c54bc3cd8bad4089 100644 (file)
@@ -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 (file)
index 0000000..d909d7a
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#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 (file)
index 0000000..eb61a25
--- /dev/null
@@ -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 <traceevent/event-parse.h>
+#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
index fb35afeaafe5f157f740e3c2997b734332d817d7..227a77d6741a6e220412e08f73293c9bc6927eee 100755 (executable)
@@ -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";
 }