From: Xiang Liu <[email protected]>

Introduce new fields for BOOT CPER encoding, only important fields are
introduced here due to the cache size limit.

Signed-off-by: Xiang Liu <[email protected]>
Reviewed-by: Hawking Zhang <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/ras/core/log_ring.c |  8 +++-
 drivers/gpu/drm/amd/ras/core/log_ring.h | 11 ++++++
 drivers/gpu/drm/amd/ras/core/ras_cper.c | 51 +++++++++++++++++++++++++
 drivers/gpu/drm/amd/ras/core/ras_cper.h | 10 ++++-
 4 files changed, 76 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/ras/core/log_ring.c 
b/drivers/gpu/drm/amd/ras/core/log_ring.c
index 175c8b3571447..73f075b0f1fdd 100644
--- a/drivers/gpu/drm/amd/ras/core/log_ring.c
+++ b/drivers/gpu/drm/amd/ras/core/log_ring.c
@@ -251,8 +251,12 @@ void ras_log_ring_add_log_event(struct ras_core_context 
*ras_core,
                batch_tag ? batch_tag->timestamp : 
ras_core_get_utc_second_timestamp(ras_core);
        log->event = event;
 
-       if (data)
-               memcpy(&log->aca_reg, data, sizeof(log->aca_reg));
+       if (data) {
+               if (event == RAS_LOG_EVENT_BOOT)
+                       memcpy(&log->boot_err_ctx, data, 
sizeof(log->boot_err_ctx));
+               else
+                       memcpy(&log->aca_reg, data, sizeof(log->aca_reg));
+       }
 
        if (event == RAS_LOG_EVENT_RMA) {
                memcpy(&log->aca_reg, ras_rma_aca_reg, sizeof(log->aca_reg));
diff --git a/drivers/gpu/drm/amd/ras/core/log_ring.h 
b/drivers/gpu/drm/amd/ras/core/log_ring.h
index 13973add0e5cb..428ad48d08fee 100644
--- a/drivers/gpu/drm/amd/ras/core/log_ring.h
+++ b/drivers/gpu/drm/amd/ras/core/log_ring.h
@@ -24,6 +24,7 @@
 #ifndef __LOG_RING_H__
 #define __LOG_RING_H__
 #include "aca.h"
+#include "ras_cper.h"
 
 #define MAX_RECORD_PER_BATCH 32
 
@@ -38,6 +39,7 @@ enum ras_log_event {
        RAS_LOG_EVENT_POISON_CONSUMPTION,
        RAS_LOG_EVENT_RMA,
        RAS_LOG_EVENT_MCE,
+       RAS_LOG_EVENT_BOOT,
        RAS_LOG_EVENT_COUNT_MAX,
 };
 
@@ -45,12 +47,21 @@ struct ras_aca_reg {
        uint64_t regs[ACA_REG_MAX_COUNT];
 };
 
+struct ras_boot_err_ctx {
+       u8 section_type[16];
+       u32 error_severity;
+       u16 reg_ctx_type;
+       u16 reg_arr_size;
+       u64 regs[CPER_OAM_MAX_COUNT];
+};
+
 struct ras_log_info {
        uint64_t seqno;
        uint64_t timestamp;
        enum ras_log_event event;
        union {
                struct ras_aca_reg aca_reg;
+               struct ras_boot_err_ctx boot_err_ctx;
        };
 };
 
diff --git a/drivers/gpu/drm/amd/ras/core/ras_cper.c 
b/drivers/gpu/drm/amd/ras/core/ras_cper.c
index fb37c7cc29142..6d7c1cf6a8f4e 100644
--- a/drivers/gpu/drm/amd/ras/core/ras_cper.c
+++ b/drivers/gpu/drm/amd/ras/core/ras_cper.c
@@ -174,6 +174,19 @@ static int fill_section_runtime(struct ras_core_context 
*ras_core,
        return 0;
 }
 
+static int fill_section_boot(struct ras_core_context *ras_core, struct 
cper_section_boot *boot,
+                            struct ras_log_info *log)
+{
+       struct ras_boot_err_ctx *ctx = &log->boot_err_ctx;
+       struct crashdump_boot *data = &boot->data;
+
+       data->reg_ctx_type = ctx->reg_ctx_type;
+       data->reg_arr_size = ctx->reg_arr_size;
+       memcpy(data->msg, ctx->regs, min(boot->data.reg_arr_size, 
sizeof(data->msg)));
+
+       return 0;
+}
+
 static int cper_generate_runtime_record(struct ras_core_context *ras_core,
        struct cper_section_hdr *hdr, struct ras_log_info *trace_arr, uint32_t 
arr_num,
                enum ras_cper_severity sev)
@@ -225,6 +238,41 @@ static int cper_generate_fatal_record(struct 
ras_core_context *ras_core,
        return 0;
 }
 
+static int cper_generate_boot_record(struct ras_core_context *ras_core, u8 
*buffer,
+                                    struct ras_log_info *trace_arr, u32 
arr_num)
+{
+       struct ras_cper_boot_record *record;
+       int i;
+
+       record = kzalloc(sizeof(*record), GFP_KERNEL);
+       if (!record)
+               return -ENOMEM;
+
+       for (i = 0; i < arr_num; i++) {
+               u32 severity = trace_arr[i].boot_err_ctx.error_severity;
+               struct ras_cper_guid section_type;
+
+               memcpy(&section_type, &trace_arr[i].boot_err_ctx.section_type,
+                      min(sizeof(section_type), 
sizeof(trace_arr[i].boot_err_ctx.section_type)));
+
+               fill_section_hdr(ras_core, &record->hdr, RAS_CPER_TYPE_BOOT, 
severity,
+                                &trace_arr[i]);
+               record->hdr.record_length = RAS_HDR_LEN + RAS_SEC_DESC_LEN + 
RAS_BOOT_SEC_LEN;
+               record->hdr.sec_cnt = 1;
+
+               fill_section_descriptor(ras_core, &record->descriptor, 
severity, section_type,
+                                       offsetof(struct ras_cper_boot_record, 
boot),
+                                       sizeof(struct ras_cper_boot_record));
+
+               fill_section_boot(ras_core, &record->boot, &trace_arr[i]);
+
+               memcpy(buffer + (i * record->hdr.record_length), record, 
record->hdr.record_length);
+       }
+
+       kfree(record);
+       return 0;
+}
+
 static int cper_get_record_size(enum ras_cper_type type, uint16_t 
section_count)
 {
        int size = 0;
@@ -331,6 +379,9 @@ int ras_cper_generate_cper(struct ras_core_context 
*ras_core,
        case RAS_LOG_EVENT_UE:
                cper_generate_fatal_record(ras_core, buffer + saved_size, 
trace_list, count);
                break;
+       case RAS_LOG_EVENT_BOOT:
+               cper_generate_boot_record(ras_core, buffer + saved_size, 
trace_list, count);
+               break;
        default:
                RAS_DEV_WARN(ras_core->dev, "Unprocessed trace event: %d\n", 
trace_list[0].event);
                break;
diff --git a/drivers/gpu/drm/amd/ras/core/ras_cper.h 
b/drivers/gpu/drm/amd/ras/core/ras_cper.h
index 8bfbeb7d78e01..037e8072eb2bc 100644
--- a/drivers/gpu/drm/amd/ras/core/ras_cper.h
+++ b/drivers/gpu/drm/amd/ras/core/ras_cper.h
@@ -30,11 +30,11 @@ struct ras_cper_guid {
 };
 
 #define CPER_GUID__INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7)               
        \
-       ((struct ras_cper_guid)                                                 
        \
+       (struct ras_cper_guid)                                                  
        \
        {{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 
0xff, \
                (b) & 0xff, ((b) >> 8) & 0xff,                                  
\
                (c) & 0xff, ((c) >> 8) & 0xff,                                  
\
-               (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }})
+               (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}
 
 #define CPER_HDR__REV_1          (0x100)
 #define CPER_SEC__MINOR_REV_1    (0x01)
@@ -278,6 +278,12 @@ struct ras_cper_fatal_record {
        struct cper_section_desc descriptor;
        struct cper_section_fatal fatal;
 };
+
+struct ras_cper_boot_record {
+       struct cper_section_hdr hdr;
+       struct cper_section_desc descriptor;
+       struct cper_section_boot boot;
+};
 #pragma pack(pop)
 
 #define RAS_HDR_LEN                            (sizeof(struct 
cper_section_hdr))
-- 
2.55.0

Reply via email to