Linux Audio

Check our new training course

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