Module Name:    src
Committed By:   riastradh
Date:           Sun Oct 27 17:27:11 UTC 2024

Modified Files:
        src/sys/dev/acpi: apei.c

Log Message:
apei(4): Print PCIe cap and AER extcap registers in 32-bit chunks.

PR kern/58775: apei(4) spamming console


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/sys/dev/acpi/apei.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/acpi/apei.c
diff -u src/sys/dev/acpi/apei.c:1.7 src/sys/dev/acpi/apei.c:1.8
--- src/sys/dev/acpi/apei.c:1.7	Sun Oct 27 12:59:08 2024
+++ src/sys/dev/acpi/apei.c	Sun Oct 27 17:27:11 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: apei.c,v 1.7 2024/10/27 12:59:08 riastradh Exp $	*/
+/*	$NetBSD: apei.c,v 1.8 2024/10/27 17:27:11 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2024 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: apei.c,v 1.7 2024/10/27 12:59:08 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: apei.c,v 1.8 2024/10/27 17:27:11 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -608,16 +608,27 @@ apei_cper_pcie_error_report(struct apei_
 	}
 	if (PE->ValidationBits & CPER_PCIE_ERROR_VALID_CAPABILITY_STRUCTURE) {
 		uint32_t dcsr, dsr;
-		char hex[2*sizeof(PE->CapabilityStructure) + 1];
+		char hex[9*sizeof(PE->CapabilityStructure)/4];
 		unsigned i;
 
-		for (i = 0; i < sizeof(PE->CapabilityStructure); i++) {
-			snprintf(hex + 2*i, sizeof(hex) - 2*i, "%02hhx",
-			    PE->CapabilityStructure[i]);
+		/*
+		 * Display a hex dump of each 32-bit register in the
+		 * PCIe capability structure.
+		 */
+		__CTASSERT(sizeof(PE->CapabilityStructure) % 4 == 0);
+		for (i = 0; i < sizeof(PE->CapabilityStructure)/4; i++) {
+			snprintf(hex + 9*i, sizeof(hex) - 9*i, "%08"PRIx32" ",
+			    le32dec(&PE->CapabilityStructure[4*i]));
 		}
+		hex[sizeof(hex) - 1] = '\0';
 		device_printf(sc->sc_dev, "%s: CapabilityStructure={%s}\n",
 		    ctx, hex);
 
+		/*
+		 * If the Device Status Register has any bits set,
+		 * highlight it in particular -- these are probably
+		 * error bits.
+		 */
 		dcsr = le32dec(&PE->CapabilityStructure[PCIE_DCSR]);
 		dsr = __SHIFTOUT(dcsr, __BITS(31,16));
 		if (dsr != 0) {
@@ -642,13 +653,20 @@ apei_cper_pcie_error_report(struct apei_
 		uint32_t uc_status, uc_sev;
 		uint32_t cor_status;
 		uint32_t control;
-		char hex[2*sizeof(PE->AERInfo) + 1];
+		char hex[9*sizeof(PE->AERInfo)/4];
 		unsigned i;
 
-		for (i = 0; i < sizeof(PE->AERInfo); i++) {
-			snprintf(hex + 2*i, sizeof(hex) - 2*i, "%02hhx",
-			    PE->AERInfo[i]);
+		/*
+		 * Display a hex dump of each 32-bit register in the
+		 * PCIe Advanced Error Reporting extended capability
+		 * structure.
+		 */
+		__CTASSERT(sizeof(PE->AERInfo) % 4 == 0);
+		for (i = 0; i < sizeof(PE->AERInfo)/4; i++) {
+			snprintf(hex + 9*i, sizeof(hex) - 9*i, "%08"PRIx32" ",
+			    le32dec(&PE->AERInfo[4*i]));
 		}
+		hex[sizeof(hex) - 1] = '\0';
 		device_printf(sc->sc_dev, "%s: AERInfo={%s}\n", ctx, hex);
 
 			/* XXX move me to pcireg.h */
@@ -673,6 +691,18 @@ apei_cper_pcie_error_report(struct apei_
 	"b\032"	"POISONTLP_EGRESS_BLOCKED\0"				      \
 	"\0"
 
+		/*
+		 * If there are any hardware error status bits set,
+		 * highlight them in particular, in three groups:
+		 *
+		 * - uncorrectable fatal (UC_STATUS and UC_SEVERITY)
+		 * - uncorrectable nonfatal (UC_STATUS but not UC_SEVERITY)
+		 * - corrected (COR_STATUS)
+		 *
+		 * And if there are any uncorrectable errors, show
+		 * which one was reported first, according to
+		 * CAP_CONTROL.
+		 */
 		uc_status = le32dec(&PE->AERInfo[PCI_AER_UC_STATUS]);
 		uc_sev = le32dec(&PE->AERInfo[PCI_AER_UC_SEVERITY]);
 		cor_status = le32dec(&PE->AERInfo[PCI_AER_COR_STATUS]);

Reply via email to