xref: /linux/drivers/firmware/efi/cper_cxl.c (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
1abdbf1a2SSmita Koralahalli // SPDX-License-Identifier: GPL-2.0-only
2abdbf1a2SSmita Koralahalli /*
3abdbf1a2SSmita Koralahalli  * UEFI Common Platform Error Record (CPER) support for CXL Section.
4abdbf1a2SSmita Koralahalli  *
5abdbf1a2SSmita Koralahalli  * Copyright (C) 2022 Advanced Micro Devices, Inc.
6abdbf1a2SSmita Koralahalli  *
7abdbf1a2SSmita Koralahalli  * Author: Smita Koralahalli <Smita.KoralahalliChannabasappa@amd.com>
8abdbf1a2SSmita Koralahalli  */
9abdbf1a2SSmita Koralahalli 
10abdbf1a2SSmita Koralahalli #include <linux/cper.h>
11abdbf1a2SSmita Koralahalli #include "cper_cxl.h"
12abdbf1a2SSmita Koralahalli 
13abdbf1a2SSmita Koralahalli #define PROT_ERR_VALID_AGENT_TYPE		BIT_ULL(0)
14abdbf1a2SSmita Koralahalli #define PROT_ERR_VALID_AGENT_ADDRESS		BIT_ULL(1)
15abdbf1a2SSmita Koralahalli #define PROT_ERR_VALID_DEVICE_ID		BIT_ULL(2)
16abdbf1a2SSmita Koralahalli #define PROT_ERR_VALID_SERIAL_NUMBER		BIT_ULL(3)
17abdbf1a2SSmita Koralahalli #define PROT_ERR_VALID_CAPABILITY		BIT_ULL(4)
18abdbf1a2SSmita Koralahalli #define PROT_ERR_VALID_DVSEC			BIT_ULL(5)
192fb6999dSSmita Koralahalli #define PROT_ERR_VALID_ERROR_LOG		BIT_ULL(6)
20abdbf1a2SSmita Koralahalli 
21*b0048092SDan Williams /* CXL RAS Capability Structure, CXL v3.0 sec 8.2.4.16 */
22*b0048092SDan Williams struct cxl_ras_capability_regs {
23*b0048092SDan Williams 	u32 uncor_status;
24*b0048092SDan Williams 	u32 uncor_mask;
25*b0048092SDan Williams 	u32 uncor_severity;
26*b0048092SDan Williams 	u32 cor_status;
27*b0048092SDan Williams 	u32 cor_mask;
28*b0048092SDan Williams 	u32 cap_control;
29*b0048092SDan Williams 	u32 header_log[16];
30*b0048092SDan Williams };
31*b0048092SDan Williams 
32abdbf1a2SSmita Koralahalli static const char * const prot_err_agent_type_strs[] = {
33abdbf1a2SSmita Koralahalli 	"Restricted CXL Device",
34abdbf1a2SSmita Koralahalli 	"Restricted CXL Host Downstream Port",
35abdbf1a2SSmita Koralahalli 	"CXL Device",
36abdbf1a2SSmita Koralahalli 	"CXL Logical Device",
37abdbf1a2SSmita Koralahalli 	"CXL Fabric Manager managed Logical Device",
38abdbf1a2SSmita Koralahalli 	"CXL Root Port",
39abdbf1a2SSmita Koralahalli 	"CXL Downstream Switch Port",
40abdbf1a2SSmita Koralahalli 	"CXL Upstream Switch Port",
41abdbf1a2SSmita Koralahalli };
42abdbf1a2SSmita Koralahalli 
43abdbf1a2SSmita Koralahalli /*
44abdbf1a2SSmita Koralahalli  * The layout of the enumeration and the values matches CXL Agent Type
45abdbf1a2SSmita Koralahalli  * field in the UEFI 2.10 Section N.2.13,
46abdbf1a2SSmita Koralahalli  */
47abdbf1a2SSmita Koralahalli enum {
48abdbf1a2SSmita Koralahalli 	RCD,	/* Restricted CXL Device */
49abdbf1a2SSmita Koralahalli 	RCH_DP,	/* Restricted CXL Host Downstream Port */
50abdbf1a2SSmita Koralahalli 	DEVICE,	/* CXL Device */
51abdbf1a2SSmita Koralahalli 	LD,	/* CXL Logical Device */
52abdbf1a2SSmita Koralahalli 	FMLD,	/* CXL Fabric Manager managed Logical Device */
53abdbf1a2SSmita Koralahalli 	RP,	/* CXL Root Port */
54abdbf1a2SSmita Koralahalli 	DSP,	/* CXL Downstream Switch Port */
55abdbf1a2SSmita Koralahalli 	USP,	/* CXL Upstream Switch Port */
56abdbf1a2SSmita Koralahalli };
57abdbf1a2SSmita Koralahalli 
cper_print_prot_err(const char * pfx,const struct cper_sec_prot_err * prot_err)58abdbf1a2SSmita Koralahalli void cper_print_prot_err(const char *pfx, const struct cper_sec_prot_err *prot_err)
59abdbf1a2SSmita Koralahalli {
60abdbf1a2SSmita Koralahalli 	if (prot_err->valid_bits & PROT_ERR_VALID_AGENT_TYPE)
61abdbf1a2SSmita Koralahalli 		pr_info("%s agent_type: %d, %s\n", pfx, prot_err->agent_type,
62abdbf1a2SSmita Koralahalli 			prot_err->agent_type < ARRAY_SIZE(prot_err_agent_type_strs)
63abdbf1a2SSmita Koralahalli 			? prot_err_agent_type_strs[prot_err->agent_type]
64abdbf1a2SSmita Koralahalli 			: "unknown");
65abdbf1a2SSmita Koralahalli 
66abdbf1a2SSmita Koralahalli 	if (prot_err->valid_bits & PROT_ERR_VALID_AGENT_ADDRESS) {
67abdbf1a2SSmita Koralahalli 		switch (prot_err->agent_type) {
68abdbf1a2SSmita Koralahalli 		/*
69abdbf1a2SSmita Koralahalli 		 * According to UEFI 2.10 Section N.2.13, the term CXL Device
70abdbf1a2SSmita Koralahalli 		 * is used to refer to Restricted CXL Device, CXL Device, CXL
71abdbf1a2SSmita Koralahalli 		 * Logical Device or a CXL Fabric Manager Managed Logical
72abdbf1a2SSmita Koralahalli 		 * Device.
73abdbf1a2SSmita Koralahalli 		 */
74abdbf1a2SSmita Koralahalli 		case RCD:
75abdbf1a2SSmita Koralahalli 		case DEVICE:
76abdbf1a2SSmita Koralahalli 		case LD:
77abdbf1a2SSmita Koralahalli 		case FMLD:
78abdbf1a2SSmita Koralahalli 		case RP:
79abdbf1a2SSmita Koralahalli 		case DSP:
80abdbf1a2SSmita Koralahalli 		case USP:
81abdbf1a2SSmita Koralahalli 			pr_info("%s agent_address: %04x:%02x:%02x.%x\n",
82abdbf1a2SSmita Koralahalli 				pfx, prot_err->agent_addr.segment,
83abdbf1a2SSmita Koralahalli 				prot_err->agent_addr.bus,
84abdbf1a2SSmita Koralahalli 				prot_err->agent_addr.device,
85abdbf1a2SSmita Koralahalli 				prot_err->agent_addr.function);
86abdbf1a2SSmita Koralahalli 			break;
87abdbf1a2SSmita Koralahalli 		case RCH_DP:
88abdbf1a2SSmita Koralahalli 			pr_info("%s rcrb_base_address: 0x%016llx\n", pfx,
89abdbf1a2SSmita Koralahalli 				prot_err->agent_addr.rcrb_base_addr);
90abdbf1a2SSmita Koralahalli 			break;
91abdbf1a2SSmita Koralahalli 		default:
92abdbf1a2SSmita Koralahalli 			break;
93abdbf1a2SSmita Koralahalli 		}
94abdbf1a2SSmita Koralahalli 	}
95abdbf1a2SSmita Koralahalli 
96abdbf1a2SSmita Koralahalli 	if (prot_err->valid_bits & PROT_ERR_VALID_DEVICE_ID) {
97abdbf1a2SSmita Koralahalli 		const __u8 *class_code;
98abdbf1a2SSmita Koralahalli 
99abdbf1a2SSmita Koralahalli 		switch (prot_err->agent_type) {
100abdbf1a2SSmita Koralahalli 		case RCD:
101abdbf1a2SSmita Koralahalli 		case DEVICE:
102abdbf1a2SSmita Koralahalli 		case LD:
103abdbf1a2SSmita Koralahalli 		case FMLD:
104abdbf1a2SSmita Koralahalli 		case RP:
105abdbf1a2SSmita Koralahalli 		case DSP:
106abdbf1a2SSmita Koralahalli 		case USP:
107abdbf1a2SSmita Koralahalli 			pr_info("%s slot: %d\n", pfx,
108abdbf1a2SSmita Koralahalli 				prot_err->device_id.slot >> CPER_PCIE_SLOT_SHIFT);
109abdbf1a2SSmita Koralahalli 			pr_info("%s vendor_id: 0x%04x, device_id: 0x%04x\n",
110abdbf1a2SSmita Koralahalli 				pfx, prot_err->device_id.vendor_id,
111abdbf1a2SSmita Koralahalli 				prot_err->device_id.device_id);
112abdbf1a2SSmita Koralahalli 			pr_info("%s sub_vendor_id: 0x%04x, sub_device_id: 0x%04x\n",
113abdbf1a2SSmita Koralahalli 				pfx, prot_err->device_id.subsystem_vendor_id,
114abdbf1a2SSmita Koralahalli 				prot_err->device_id.subsystem_id);
115abdbf1a2SSmita Koralahalli 			class_code = prot_err->device_id.class_code;
116abdbf1a2SSmita Koralahalli 			pr_info("%s class_code: %02x%02x\n", pfx,
117abdbf1a2SSmita Koralahalli 				class_code[1], class_code[0]);
118abdbf1a2SSmita Koralahalli 			break;
119abdbf1a2SSmita Koralahalli 		default:
120abdbf1a2SSmita Koralahalli 			break;
121abdbf1a2SSmita Koralahalli 		}
122abdbf1a2SSmita Koralahalli 	}
123abdbf1a2SSmita Koralahalli 
124abdbf1a2SSmita Koralahalli 	if (prot_err->valid_bits & PROT_ERR_VALID_SERIAL_NUMBER) {
125abdbf1a2SSmita Koralahalli 		switch (prot_err->agent_type) {
126abdbf1a2SSmita Koralahalli 		case RCD:
127abdbf1a2SSmita Koralahalli 		case DEVICE:
128abdbf1a2SSmita Koralahalli 		case LD:
129abdbf1a2SSmita Koralahalli 		case FMLD:
130abdbf1a2SSmita Koralahalli 			pr_info("%s lower_dw: 0x%08x, upper_dw: 0x%08x\n", pfx,
131abdbf1a2SSmita Koralahalli 				prot_err->dev_serial_num.lower_dw,
132abdbf1a2SSmita Koralahalli 				prot_err->dev_serial_num.upper_dw);
133abdbf1a2SSmita Koralahalli 			break;
134abdbf1a2SSmita Koralahalli 		default:
135abdbf1a2SSmita Koralahalli 			break;
136abdbf1a2SSmita Koralahalli 		}
137abdbf1a2SSmita Koralahalli 	}
138abdbf1a2SSmita Koralahalli 
139abdbf1a2SSmita Koralahalli 	if (prot_err->valid_bits & PROT_ERR_VALID_CAPABILITY) {
140abdbf1a2SSmita Koralahalli 		switch (prot_err->agent_type) {
141abdbf1a2SSmita Koralahalli 		case RCD:
142abdbf1a2SSmita Koralahalli 		case DEVICE:
143abdbf1a2SSmita Koralahalli 		case LD:
144abdbf1a2SSmita Koralahalli 		case FMLD:
145abdbf1a2SSmita Koralahalli 		case RP:
146abdbf1a2SSmita Koralahalli 		case DSP:
147abdbf1a2SSmita Koralahalli 		case USP:
148abdbf1a2SSmita Koralahalli 			print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4,
149abdbf1a2SSmita Koralahalli 				       prot_err->capability,
150abdbf1a2SSmita Koralahalli 				       sizeof(prot_err->capability), 0);
151abdbf1a2SSmita Koralahalli 			break;
152abdbf1a2SSmita Koralahalli 		default:
153abdbf1a2SSmita Koralahalli 			break;
154abdbf1a2SSmita Koralahalli 		}
155abdbf1a2SSmita Koralahalli 	}
156abdbf1a2SSmita Koralahalli 
157abdbf1a2SSmita Koralahalli 	if (prot_err->valid_bits & PROT_ERR_VALID_DVSEC) {
158abdbf1a2SSmita Koralahalli 		pr_info("%s DVSEC length: 0x%04x\n", pfx, prot_err->dvsec_len);
159abdbf1a2SSmita Koralahalli 
160abdbf1a2SSmita Koralahalli 		pr_info("%s CXL DVSEC:\n", pfx);
161abdbf1a2SSmita Koralahalli 		print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4, (prot_err + 1),
162abdbf1a2SSmita Koralahalli 			       prot_err->dvsec_len, 0);
163abdbf1a2SSmita Koralahalli 	}
1642fb6999dSSmita Koralahalli 
1652fb6999dSSmita Koralahalli 	if (prot_err->valid_bits & PROT_ERR_VALID_ERROR_LOG) {
1662fb6999dSSmita Koralahalli 		size_t size = sizeof(*prot_err) + prot_err->dvsec_len;
1672fb6999dSSmita Koralahalli 		struct cxl_ras_capability_regs *cxl_ras;
1682fb6999dSSmita Koralahalli 
1692fb6999dSSmita Koralahalli 		pr_info("%s Error log length: 0x%04x\n", pfx, prot_err->err_len);
1702fb6999dSSmita Koralahalli 
1712fb6999dSSmita Koralahalli 		pr_info("%s CXL Error Log:\n", pfx);
1722fb6999dSSmita Koralahalli 		cxl_ras = (struct cxl_ras_capability_regs *)((long)prot_err + size);
1732fb6999dSSmita Koralahalli 		pr_info("%s cxl_ras_uncor_status: 0x%08x", pfx,
1742fb6999dSSmita Koralahalli 			cxl_ras->uncor_status);
1752fb6999dSSmita Koralahalli 		pr_info("%s cxl_ras_uncor_mask: 0x%08x\n", pfx,
1762fb6999dSSmita Koralahalli 			cxl_ras->uncor_mask);
1772fb6999dSSmita Koralahalli 		pr_info("%s cxl_ras_uncor_severity: 0x%08x\n", pfx,
1782fb6999dSSmita Koralahalli 			cxl_ras->uncor_severity);
1792fb6999dSSmita Koralahalli 		pr_info("%s cxl_ras_cor_status: 0x%08x", pfx,
1802fb6999dSSmita Koralahalli 			cxl_ras->cor_status);
1812fb6999dSSmita Koralahalli 		pr_info("%s cxl_ras_cor_mask: 0x%08x\n", pfx,
1822fb6999dSSmita Koralahalli 			cxl_ras->cor_mask);
1832fb6999dSSmita Koralahalli 		pr_info("%s cap_control: 0x%08x\n", pfx,
1842fb6999dSSmita Koralahalli 			cxl_ras->cap_control);
1852fb6999dSSmita Koralahalli 		pr_info("%s Header Log Registers:\n", pfx);
1862fb6999dSSmita Koralahalli 		print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4, cxl_ras->header_log,
1872fb6999dSSmita Koralahalli 			       sizeof(cxl_ras->header_log), 0);
1882fb6999dSSmita Koralahalli 	}
189abdbf1a2SSmita Koralahalli }
190