[PATCH 006/109] drm/amd/ras: Introduce BOOT CPER encoding function

Alex Deucher <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.