File Index
Files and directories
Sign in
FILE

cper_cxl.c

File preview with syntax highlighting.

linux-6.19.14/drivers/firmware/efi/cper_cxl.c C
  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 <cxl/event.h>
 12
 13static const char * const prot_err_agent_type_strs[] = {
 14	"Restricted CXL Device",
 15	"Restricted CXL Host Downstream Port",
 16	"CXL Device",
 17	"CXL Logical Device",
 18	"CXL Fabric Manager managed Logical Device",
 19	"CXL Root Port",
 20	"CXL Downstream Switch Port",
 21	"CXL Upstream Switch Port",
 22};
 23
 24void cxl_cper_print_prot_err(const char *pfx,
 25			     const struct cxl_cper_sec_prot_err *prot_err)
 26{
 27	if (prot_err->valid_bits & PROT_ERR_VALID_AGENT_TYPE)
 28		pr_info("%s agent_type: %d, %s\n", pfx, prot_err->agent_type,
 29			prot_err->agent_type < ARRAY_SIZE(prot_err_agent_type_strs)
 30			? prot_err_agent_type_strs[prot_err->agent_type]
 31			: "unknown");
 32
 33	if (prot_err->valid_bits & PROT_ERR_VALID_AGENT_ADDRESS) {
 34		switch (prot_err->agent_type) {
 35		/*
 36		 * According to UEFI 2.10 Section N.2.13, the term CXL Device
 37		 * is used to refer to Restricted CXL Device, CXL Device, CXL
 38		 * Logical Device or a CXL Fabric Manager Managed Logical
 39		 * Device.
 40		 */
 41		case RCD:
 42		case DEVICE:
 43		case LD:
 44		case FMLD:
 45		case RP:
 46		case DSP:
 47		case USP:
 48			pr_info("%s agent_address: %04x:%02x:%02x.%x\n",
 49				pfx, prot_err->agent_addr.segment,
 50				prot_err->agent_addr.bus,
 51				prot_err->agent_addr.device,
 52				prot_err->agent_addr.function);
 53			break;
 54		case RCH_DP:
 55			pr_info("%s rcrb_base_address: 0x%016llx\n", pfx,
 56				prot_err->agent_addr.rcrb_base_addr);
 57			break;
 58		default:
 59			break;
 60		}
 61	}
 62
 63	if (prot_err->valid_bits & PROT_ERR_VALID_DEVICE_ID) {
 64		const __u8 *class_code;
 65
 66		switch (prot_err->agent_type) {
 67		case RCD:
 68		case DEVICE:
 69		case LD:
 70		case FMLD:
 71		case RP:
 72		case DSP:
 73		case USP:
 74			pr_info("%s slot: %d\n", pfx,
 75				prot_err->device_id.slot >> CPER_PCIE_SLOT_SHIFT);
 76			pr_info("%s vendor_id: 0x%04x, device_id: 0x%04x\n",
 77				pfx, prot_err->device_id.vendor_id,
 78				prot_err->device_id.device_id);
 79			pr_info("%s sub_vendor_id: 0x%04x, sub_device_id: 0x%04x\n",
 80				pfx, prot_err->device_id.subsystem_vendor_id,
 81				prot_err->device_id.subsystem_id);
 82			class_code = prot_err->device_id.class_code;
 83			pr_info("%s class_code: %02x%02x\n", pfx,
 84				class_code[1], class_code[0]);
 85			break;
 86		default:
 87			break;
 88		}
 89	}
 90
 91	if (prot_err->valid_bits & PROT_ERR_VALID_SERIAL_NUMBER) {
 92		switch (prot_err->agent_type) {
 93		case RCD:
 94		case DEVICE:
 95		case LD:
 96		case FMLD:
 97			pr_info("%s lower_dw: 0x%08x, upper_dw: 0x%08x\n", pfx,
 98				prot_err->dev_serial_num.lower_dw,
 99				prot_err->dev_serial_num.upper_dw);
100			break;
101		default:
102			break;
103		}
104	}
105
106	if (prot_err->valid_bits & PROT_ERR_VALID_CAPABILITY) {
107		switch (prot_err->agent_type) {
108		case RCD:
109		case DEVICE:
110		case LD:
111		case FMLD:
112		case RP:
113		case DSP:
114		case USP:
115			print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4,
116				       prot_err->capability,
117				       sizeof(prot_err->capability), 0);
118			break;
119		default:
120			break;
121		}
122	}
123
124	if (prot_err->valid_bits & PROT_ERR_VALID_DVSEC) {
125		pr_info("%s DVSEC length: 0x%04x\n", pfx, prot_err->dvsec_len);
126
127		pr_info("%s CXL DVSEC:\n", pfx);
128		print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4, (prot_err + 1),
129			       prot_err->dvsec_len, 0);
130	}
131
132	if (prot_err->valid_bits & PROT_ERR_VALID_ERROR_LOG) {
133		size_t size = sizeof(*prot_err) + prot_err->dvsec_len;
134		struct cxl_ras_capability_regs *cxl_ras;
135
136		pr_info("%s Error log length: 0x%04x\n", pfx, prot_err->err_len);
137
138		pr_info("%s CXL Error Log:\n", pfx);
139		cxl_ras = (struct cxl_ras_capability_regs *)((long)prot_err + size);
140		pr_info("%s cxl_ras_uncor_status: 0x%08x", pfx,
141			cxl_ras->uncor_status);
142		pr_info("%s cxl_ras_uncor_mask: 0x%08x\n", pfx,
143			cxl_ras->uncor_mask);
144		pr_info("%s cxl_ras_uncor_severity: 0x%08x\n", pfx,
145			cxl_ras->uncor_severity);
146		pr_info("%s cxl_ras_cor_status: 0x%08x", pfx,
147			cxl_ras->cor_status);
148		pr_info("%s cxl_ras_cor_mask: 0x%08x\n", pfx,
149			cxl_ras->cor_mask);
150		pr_info("%s cap_control: 0x%08x\n", pfx,
151			cxl_ras->cap_control);
152		pr_info("%s Header Log Registers:\n", pfx);
153		print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4, cxl_ras->header_log,
154			       sizeof(cxl_ras->header_log), 0);
155	}
156}
~/ Read-only file preview.