diff mbox series

[2/3] efi/cper, cxl: Decode CXL Component Events DRAM Event Record

Message ID 20231012230301.58500-3-Smita.KoralahalliChannabasappa@amd.com
State New
Headers show
Series efi/cper, cxl: Decode CXL Component Events CPER | expand

Commit Message

Smita Koralahalli Oct. 12, 2023, 11:03 p.m. UTC
Add support for decoding CXL Component Events DRAM Event Record
as defined in CXL rev 3.0 section 8.2.9.2.1.2.

Signed-off-by: Smita Koralahalli <Smita.KoralahalliChannabasappa@amd.com>
---
 drivers/firmware/efi/cper.c     |  8 ++++
 drivers/firmware/efi/cper_cxl.c | 79 +++++++++++++++++++++++++++++++++
 drivers/firmware/efi/cper_cxl.h | 28 ++++++++++++
 3 files changed, 115 insertions(+)
diff mbox series

Patch

diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index b911b1f574db..1d182487fa13 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -615,6 +615,14 @@  cper_estatus_print_section(const char *pfx, struct acpi_hest_generic_data *gdata
 			cper_print_gen_media(newpfx, gmer);
 		else
 			goto err_section_too_small;
+	} else if (guid_equal(sec_type, &CPER_SEC_CXL_DRAM)) {
+		struct cper_sec_comp_event *dram = acpi_hest_get_payload(gdata);
+
+		printk("%ssection_type: CXL DRAM Event\n", newpfx);
+		if (gdata->error_data_length >= sizeof(*dram))
+			cper_print_dram(newpfx, dram);
+		else
+			goto err_section_too_small;
 	} else {
 		const void *err = acpi_hest_get_payload(gdata);
 
diff --git a/drivers/firmware/efi/cper_cxl.c b/drivers/firmware/efi/cper_cxl.c
index 8f7b88cc574b..3fba360b7dc6 100644
--- a/drivers/firmware/efi/cper_cxl.c
+++ b/drivers/firmware/efi/cper_cxl.c
@@ -30,6 +30,15 @@ 
 #define GMER_VALID_DEVICE			BIT_ULL(2)
 #define GMER_VALID_COMP_ID			BIT_ULL(3)
 
+#define DRAM_VALID_CHANNEL			BIT_ULL(0)
+#define DRAM_VALID_RANK				BIT_ULL(1)
+#define DRAM_VALID_NIBBLE_MASK			BIT_ULL(2)
+#define DRAM_VALID_BANK_GROUP			BIT_ULL(3)
+#define DRAM_VALID_BANK				BIT_ULL(4)
+#define DRAM_VALID_ROW				BIT_ULL(5)
+#define DRAM_VALID_COLUMN			BIT_ULL(6)
+#define DRAM_VALID_CORRECTION_MASK		BIT_ULL(7)
+
 /* CXL RAS Capability Structure, CXL v3.0 sec 8.2.4.16 */
 struct cxl_ras_capability_regs {
 	u32 uncor_status;
@@ -103,6 +112,13 @@  static const char * const transaction_type_strs[] = {
 	"internal media management",
 };
 
+static const char * const dram_mem_type_strs[] = {
+	"media ECC error",
+	"scrub media ECC error",
+	"invalid address",
+	"data path error",
+};
+
 void cper_print_prot_err(const char *pfx, const struct cper_sec_prot_err *prot_err)
 {
 	if (prot_err->valid_bits & PROT_ERR_VALID_AGENT_TYPE)
@@ -330,3 +346,66 @@  void cper_print_gen_media(const char *pfx, const struct cper_sec_comp_event *eve
 			       sizeof(gmer->comp_id), 0);
 	}
 }
+
+void cper_print_dram(const char *pfx, const struct cper_sec_comp_event *event)
+{
+	struct cper_sec_dram *dram;
+
+	cper_print_comp_event(pfx, event);
+
+	if (!(event->valid_bits & COMP_EVENT_VALID_EVENT_LOG))
+		return;
+
+	dram = (struct cper_sec_dram *)(event + 1);
+
+	cper_print_event_record(pfx, &dram->record);
+
+	pr_info("%s device physical address: 0x%016llx\n", pfx, dram->dpa);
+	pr_info("%s memory event descriptor: 0x%02x\n", pfx, dram->descriptor);
+	cper_print_bits(pfx, dram->descriptor, mem_evt_descriptor_strs,
+			ARRAY_SIZE(mem_evt_descriptor_strs));
+
+	pr_info("%s memory event type: %d, %s\n", pfx, dram->type,
+		dram->type < ARRAY_SIZE(dram_mem_type_strs)
+		? dram_mem_type_strs[dram->type] : "unknown");
+
+	pr_info("%s transaction type: %d, %s\n", pfx, dram->transaction_type,
+		dram->transaction_type < ARRAY_SIZE(transaction_type_strs)
+		? transaction_type_strs[dram->transaction_type] : "unknown");
+
+	if (dram->validity_flags & DRAM_VALID_CHANNEL)
+		pr_info("%s channel: 0x%02x\n", pfx, dram->channel);
+
+	if (dram->validity_flags & DRAM_VALID_RANK)
+		pr_info("%s rank: 0x%02x\n", pfx, dram->rank);
+
+	if (dram->validity_flags & DRAM_VALID_NIBBLE_MASK) {
+		const __u8 *nibble;
+
+		nibble = dram->nibble_mask;
+		pr_info("%s nibble mask: %02x%02x%02x\n", pfx, nibble[2],
+			nibble[1], nibble[0]);
+	}
+
+	if (dram->validity_flags & DRAM_VALID_BANK_GROUP)
+		pr_info("%s bank group: 0x%02x\n", pfx, dram->bank_group);
+
+	if (dram->validity_flags & DRAM_VALID_BANK)
+		pr_info("%s bank: 0x%02x\n", pfx, dram->bank);
+
+	if (dram->validity_flags & DRAM_VALID_ROW) {
+		const __u8 *row;
+
+		row = dram->row;
+		pr_info("%s row: %02x%02x%02x\n", pfx, row[2], row[1], row[0]);
+	}
+
+	if (dram->validity_flags & DRAM_VALID_COLUMN)
+		pr_info("%s column: 0x%04x\n", pfx, dram->column);
+
+	if (dram->validity_flags & DRAM_VALID_CORRECTION_MASK) {
+		pr_info("%s correction mask :\n", pfx);
+		print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4,
+			       dram->cor_mask, sizeof(dram->cor_mask), 0);
+	}
+}
diff --git a/drivers/firmware/efi/cper_cxl.h b/drivers/firmware/efi/cper_cxl.h
index 94528db208de..967847b571cb 100644
--- a/drivers/firmware/efi/cper_cxl.h
+++ b/drivers/firmware/efi/cper_cxl.h
@@ -20,6 +20,11 @@ 
 	GUID_INIT(0xFBCD0A77, 0xC260, 0x417F, 0x85, 0xA9, 0x08, 0x8B,	\
 		  0x16, 0x21, 0xEB, 0xA6)
 
+/* CXL DRAM Section */
+#define CPER_SEC_CXL_DRAM						\
+	GUID_INIT(0x601DCBB3, 0x9C06, 0x4EAB, 0xB8, 0xAF, 0x4E, 0x9B,	\
+		  0xFB, 0x5C, 0x96, 0x24)
+
 #pragma pack(1)
 
 /* Compute Express Link Protocol Error Section, UEFI v2.10 sec N.2.13 */
@@ -120,9 +125,32 @@  struct cper_sec_gen_media {
 	u8 reserved[46];
 };
 
+/*
+ * CXL DRAM Event Record
+ * CXL rev 3.0 sec 8.2.9.2.1.2; Table 8-44
+ */
+struct cper_sec_dram {
+	struct common_event_record record;
+	u64 dpa;
+	u8 descriptor;
+	u8 type;
+	u8 transaction_type;
+	u16 validity_flags;
+	u8 channel;
+	u8 rank;
+	u8 nibble_mask[3];
+	u8 bank_group;
+	u8 bank;
+	u8 row[3];
+	u16 column;
+	u8 cor_mask[32];
+	u8 reserved[23];
+};
+
 #pragma pack()
 
 void cper_print_prot_err(const char *pfx, const struct cper_sec_prot_err *prot_err);
 void cper_print_gen_media(const char *pfx, const struct cper_sec_comp_event *event);
+void cper_print_dram(const char *pfx, const struct cper_sec_comp_event *event);
 
 #endif //__CPER_CXL_