]> www.infradead.org Git - users/mchehab/rasdaemon.git/commitdiff
rasdaemon:add logging HiSilicon HIP08 H/W errors reported in the OEM format2
authorShiju Jose <shiju.jose@huawei.com>
Mon, 17 Jun 2019 14:28:51 +0000 (15:28 +0100)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Fri, 21 Jun 2019 18:41:01 +0000 (15:41 -0300)
This patch adds logging the HiSilicon HIP08 H/W errors reported
in the non-standard OEM format2.
These errors are from the H/W modules SMMU, HHA, HLLC, PA and DDRC.

Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
non-standard-hisi_hip08.c

index 240e83239c13e9cc633bdaa25495c8f8297539d7..6fe5cbe735eac06e47c911afcfd26b15dd349596 100644 (file)
 #define HISI_OEM_TYPE1_VALID_ERR_MISC_4        BIT(10)
 #define HISI_OEM_TYPE1_VALID_ERR_ADDR  BIT(11)
 
+/* HISI OEM format2 error definitions */
+#define HISI_OEM_MODULE_ID_SMMU        0
+#define HISI_OEM_MODULE_ID_HHA 1
+#define HISI_OEM_MODULE_ID_HLLC        2
+#define HISI_OEM_MODULE_ID_PA  3
+#define HISI_OEM_MODULE_ID_DDRC        4
+
+#define HISI_OEM_TYPE2_VALID_ERR_FR    BIT(6)
+#define HISI_OEM_TYPE2_VALID_ERR_CTRL  BIT(7)
+#define HISI_OEM_TYPE2_VALID_ERR_STATUS        BIT(8)
+#define HISI_OEM_TYPE2_VALID_ERR_ADDR  BIT(9)
+#define HISI_OEM_TYPE2_VALID_ERR_MISC_0        BIT(10)
+#define HISI_OEM_TYPE2_VALID_ERR_MISC_1        BIT(11)
+
 struct hisi_oem_type1_err_sec {
        uint32_t   val_bits;
        uint8_t    version;
@@ -61,6 +75,30 @@ struct hisi_oem_type1_err_sec {
        uint64_t   err_addr;
 };
 
+struct hisi_oem_type2_err_sec {
+       uint32_t   val_bits;
+       uint8_t    version;
+       uint8_t    soc_id;
+       uint8_t    socket_id;
+       uint8_t    nimbus_id;
+       uint8_t    module_id;
+       uint8_t    sub_module_id;
+       uint8_t    err_severity;
+       uint8_t    reserv;
+       uint32_t   err_fr_0;
+       uint32_t   err_fr_1;
+       uint32_t   err_ctrl_0;
+       uint32_t   err_ctrl_1;
+       uint32_t   err_status_0;
+       uint32_t   err_status_1;
+       uint32_t   err_addr_0;
+       uint32_t   err_addr_1;
+       uint32_t   err_misc0_0;
+       uint32_t   err_misc0_1;
+       uint32_t   err_misc1_0;
+       uint32_t   err_misc1_1;
+};
+
 enum hisi_oem_data_type {
        hisi_oem_data_type_int,
        hisi_oem_data_type_int64,
@@ -84,6 +122,29 @@ enum {
        hip08_oem_type1_field_err_addr,
 };
 
+enum {
+       hip08_oem_type2_field_id,
+       hip08_oem_type2_field_version,
+       hip08_oem_type2_field_soc_id,
+       hip08_oem_type2_field_socket_id,
+       hip08_oem_type2_field_nimbus_id,
+       hip08_oem_type2_field_module_id,
+       hip08_oem_type2_field_sub_module_id,
+       hip08_oem_type2_field_err_sev,
+       hip08_oem_type2_field_err_fr_0,
+       hip08_oem_type2_field_err_fr_1,
+       hip08_oem_type2_field_err_ctrl_0,
+       hip08_oem_type2_field_err_ctrl_1,
+       hip08_oem_type2_field_err_status_0,
+       hip08_oem_type2_field_err_status_1,
+       hip08_oem_type2_field_err_addr_0,
+       hip08_oem_type2_field_err_addr_1,
+       hip08_oem_type2_field_err_misc0_0,
+       hip08_oem_type2_field_err_misc0_1,
+       hip08_oem_type2_field_err_misc1_0,
+       hip08_oem_type2_field_err_misc1_1,
+};
+
 /* helper functions */
 static char *err_severity(uint8_t err_sev)
 {
@@ -113,6 +174,62 @@ static char *oem_type1_module_name(uint8_t module_id)
        return "unknown";
 }
 
+static char *oem_type2_module_name(uint8_t module_id)
+{
+       switch (module_id) {
+       case HISI_OEM_MODULE_ID_SMMU: return "SMMU";
+       case HISI_OEM_MODULE_ID_HHA: return "HHA";
+       case HISI_OEM_MODULE_ID_HLLC: return "HLLC";
+       case HISI_OEM_MODULE_ID_PA: return "PA";
+       case HISI_OEM_MODULE_ID_DDRC: return "DDRC";
+       }
+       return "unknown module";
+}
+
+static char *oem_type2_sub_module_id(char *p, uint8_t module_id,
+                                    uint8_t sub_module_id)
+{
+       switch (module_id) {
+       case HISI_OEM_MODULE_ID_SMMU:
+       case HISI_OEM_MODULE_ID_HLLC:
+       case HISI_OEM_MODULE_ID_PA:
+               p += sprintf(p, "%d ", sub_module_id);
+               break;
+
+       case HISI_OEM_MODULE_ID_HHA:
+               if (sub_module_id == 0)
+                       p += sprintf(p, "TA HHA0 ");
+               else if (sub_module_id == 1)
+                       p += sprintf(p, "TA HHA1 ");
+               else if (sub_module_id == 2)
+                       p += sprintf(p, "TB HHA0 ");
+               else if (sub_module_id == 3)
+                       p += sprintf(p, "TB HHA1 ");
+               break;
+
+       case HISI_OEM_MODULE_ID_DDRC:
+               if (sub_module_id == 0)
+                       p += sprintf(p, "TA DDRC0 ");
+               else if (sub_module_id == 1)
+                       p += sprintf(p, "TA DDRC1 ");
+               else if (sub_module_id == 2)
+                       p += sprintf(p, "TA DDRC2 ");
+               else if (sub_module_id == 3)
+                       p += sprintf(p, "TA DDRC3 ");
+               else if (sub_module_id == 4)
+                       p += sprintf(p, "TB DDRC0 ");
+               else if (sub_module_id == 5)
+                       p += sprintf(p, "TB DDRC1 ");
+               else if (sub_module_id == 6)
+                       p += sprintf(p, "TB DDRC2 ");
+               else if (sub_module_id == 7)
+                       p += sprintf(p, "TB DDRC3 ");
+               break;
+       }
+
+       return p;
+}
+
 #ifdef HAVE_SQLITE3
 static const struct db_fields hip08_oem_type1_event_fields[] = {
        { .name = "id",                 .type = "INTEGER PRIMARY KEY" },
@@ -137,6 +254,35 @@ static const struct db_table_descriptor hip08_oem_type1_event_tab = {
        .num_fields = ARRAY_SIZE(hip08_oem_type1_event_fields),
 };
 
+static const struct db_fields hip08_oem_type2_event_fields[] = {
+       { .name = "id",                 .type = "INTEGER PRIMARY KEY" },
+       { .name = "version",            .type = "INTEGER" },
+       { .name = "soc_id",             .type = "INTEGER" },
+       { .name = "socket_id",          .type = "INTEGER" },
+       { .name = "nimbus_id",          .type = "INTEGER" },
+       { .name = "module_id",          .type = "TEXT" },
+       { .name = "sub_module_id",      .type = "INTEGER" },
+       { .name = "err_severity",       .type = "TEXT" },
+       { .name = "err_fr_0",           .type = "INTEGER" },
+       { .name = "err_fr_1",           .type = "INTEGER" },
+       { .name = "err_ctrl_0",         .type = "INTEGER" },
+       { .name = "err_ctrl_1",         .type = "INTEGER" },
+       { .name = "err_status_0",       .type = "INTEGER" },
+       { .name = "err_status_1",       .type = "INTEGER" },
+       { .name = "err_addr_0",         .type = "INTEGER" },
+       { .name = "err_addr_1",         .type = "INTEGER" },
+       { .name = "err_misc0_0",        .type = "INTEGER" },
+       { .name = "err_misc0_1",        .type = "INTEGER" },
+       { .name = "err_misc1_0",        .type = "INTEGER" },
+       { .name = "err_misc1_1",        .type = "INTEGER" },
+};
+
+static const struct db_table_descriptor hip08_oem_type2_event_tab = {
+       .name = "hip08_oem_type2_event",
+       .fields = hip08_oem_type2_event_fields,
+       .num_fields = ARRAY_SIZE(hip08_oem_type2_event_fields),
+};
+
 static void record_vendor_data(struct ras_ns_dec_tab *dec_tab,
                               enum hisi_oem_data_type data_type,
                               int id, int64_t data, const char *text)
@@ -317,11 +463,165 @@ static int decode_hip08_oem_type1_error(struct ras_events *ras,
        return 0;
 }
 
+static int decode_hip08_oem_type2_error(struct ras_events *ras,
+                                       struct ras_ns_dec_tab *dec_tab,
+                                       struct trace_seq *s, const void *error)
+{
+       const struct hisi_oem_type2_err_sec *err = error;
+       char buf[1024];
+       char *p = buf;
+
+       if (err->val_bits == 0) {
+               trace_seq_printf(s, "%s: no valid error information\n",
+                                __func__);
+               return -1;
+       }
+
+#ifdef HAVE_SQLITE3
+       if (!dec_tab->stmt_dec_record) {
+               if (ras_mc_add_vendor_table(ras, &dec_tab->stmt_dec_record,
+                       &hip08_oem_type2_event_tab) != SQLITE_OK) {
+                       trace_seq_printf(s,
+                               "create sql hip08_oem_type2_event_tab fail\n");
+                       return -1;
+               }
+       }
+#endif
+       p += sprintf(p, "[ ");
+       p += sprintf(p, "Table version=%d ", err->version);
+       record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                          hip08_oem_type2_field_version,
+                          err->version, NULL);
+       if (err->val_bits & HISI_OEM_VALID_SOC_ID) {
+               p += sprintf(p, "SOC ID=%d ", err->soc_id);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_soc_id,
+                                  err->soc_id, NULL);
+       }
+
+       if (err->val_bits & HISI_OEM_VALID_SOCKET_ID) {
+               p += sprintf(p, "socket ID=%d ", err->socket_id);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_socket_id,
+                                  err->socket_id, NULL);
+       }
+
+       if (err->val_bits & HISI_OEM_VALID_NIMBUS_ID) {
+               p += sprintf(p, "nimbus ID=%d ", err->nimbus_id);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_nimbus_id,
+                                  err->nimbus_id, NULL);
+       }
+
+       if (err->val_bits & HISI_OEM_VALID_MODULE_ID) {
+               p += sprintf(p, "module=%s ",
+                            oem_type2_module_name(err->module_id));
+               record_vendor_data(dec_tab, hisi_oem_data_type_text,
+                                  hip08_oem_type2_field_module_id,
+                                  0, oem_type2_module_name(err->module_id));
+       }
+
+       if (err->val_bits & HISI_OEM_VALID_SUB_MODULE_ID) {
+               p =  oem_type2_sub_module_id(p, err->module_id,
+                                            err->sub_module_id);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_sub_module_id,
+                                  err->sub_module_id, NULL);
+       }
+
+       if (err->val_bits & HISI_OEM_VALID_ERR_SEVERITY) {
+               p += sprintf(p, "error severity=%s ",
+                            err_severity(err->err_severity));
+               record_vendor_data(dec_tab, hisi_oem_data_type_text,
+                                  hip08_oem_type2_field_err_sev,
+                                  0, err_severity(err->err_severity));
+       }
+
+       p += sprintf(p, "]");
+       trace_seq_printf(s, "\nHISI HIP08: OEM Type-2 Error\n");
+       trace_seq_printf(s, "%s\n", buf);
+
+       trace_seq_printf(s, "Reg Dump:\n");
+       if (err->val_bits & HISI_OEM_TYPE2_VALID_ERR_FR) {
+               trace_seq_printf(s, "ERR_FR_0=0x%x\n", err->err_fr_0);
+               trace_seq_printf(s, "ERR_FR_1=0x%x\n", err->err_fr_1);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_err_fr_0,
+                                  err->err_fr_0, NULL);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_err_fr_1,
+                                  err->err_fr_1, NULL);
+       }
+
+       if (err->val_bits & HISI_OEM_TYPE2_VALID_ERR_CTRL) {
+               trace_seq_printf(s, "ERR_CTRL_0=0x%x\n", err->err_ctrl_0);
+               trace_seq_printf(s, "ERR_CTRL_1=0x%x\n", err->err_ctrl_1);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_err_ctrl_0,
+                                  err->err_ctrl_0, NULL);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_err_ctrl_1,
+                                  err->err_ctrl_1, NULL);
+       }
+
+       if (err->val_bits & HISI_OEM_TYPE2_VALID_ERR_STATUS) {
+               trace_seq_printf(s, "ERR_STATUS_0=0x%x\n", err->err_status_0);
+               trace_seq_printf(s, "ERR_STATUS_1=0x%x\n", err->err_status_1);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_err_status_0,
+                                  err->err_status_0, NULL);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_err_status_1,
+                                  err->err_status_1, NULL);
+       }
+
+       if (err->val_bits & HISI_OEM_TYPE2_VALID_ERR_ADDR) {
+               trace_seq_printf(s, "ERR_ADDR_0=0x%x\n", err->err_addr_0);
+               trace_seq_printf(s, "ERR_ADDR_1=0x%x\n", err->err_addr_1);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_err_addr_0,
+                                  err->err_addr_0, NULL);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_err_addr_1,
+                                  err->err_addr_1, NULL);
+       }
+
+       if (err->val_bits & HISI_OEM_TYPE2_VALID_ERR_MISC_0) {
+               trace_seq_printf(s, "ERR_MISC0_0=0x%x\n", err->err_misc0_0);
+               trace_seq_printf(s, "ERR_MISC0_1=0x%x\n", err->err_misc0_1);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_err_misc0_0,
+                                  err->err_misc0_0, NULL);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_err_misc0_1,
+                                  err->err_misc0_1, NULL);
+       }
+
+       if (err->val_bits & HISI_OEM_TYPE2_VALID_ERR_MISC_1) {
+               trace_seq_printf(s, "ERR_MISC1_0=0x%x\n", err->err_misc1_0);
+               trace_seq_printf(s, "ERR_MISC1_1=0x%x\n", err->err_misc1_1);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_err_misc1_0,
+                                  err->err_misc1_0, NULL);
+               record_vendor_data(dec_tab, hisi_oem_data_type_int,
+                                  hip08_oem_type2_field_err_misc1_1,
+                                  err->err_misc1_1, NULL);
+       }
+
+       step_vendor_data_tab(dec_tab, "hip08_oem_type2_event_tab");
+
+       return 0;
+}
+
 struct ras_ns_dec_tab hip08_ns_oem_tab[] = {
        {
                .sec_type = "1f8161e155d641e6bd107afd1dc5f7c5",
                .decode = decode_hip08_oem_type1_error,
        },
+       {
+               .sec_type = "45534ea6ce2341158535e07ab3aef91d",
+               .decode = decode_hip08_oem_type2_error,
+       },
        { /* sentinel */ }
 };