190 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*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 Type45 * 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 Device70 * is used to refer to Restricted CXL Device, CXL Device, CXL71 * Logical Device or a CXL Fabric Manager Managed Logical72 * 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}190