-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
efi/cper, cxl: Decode CXL Protocol Error Section
Add support for decoding CXL Protocol Error Section as defined in UEFI 2.10 Section N.2.13. Do the section decoding in a new cper_cxl.c file. This new file will be used in the future for more CXL CPERs decode support. Add this to the existing UEFI_CPER config. Signed-off-by: Smita Koralahalli <Smita.KoralahalliChannabasappa@amd.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
- Loading branch information
Smita Koralahalli
authored and
Ard Biesheuvel
committed
Nov 18, 2022
1 parent
d981a88
commit abdbf1a
Showing
4 changed files
with
228 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* UEFI Common Platform Error Record (CPER) support for CXL Section. | ||
* | ||
* Copyright (C) 2022 Advanced Micro Devices, Inc. | ||
* | ||
* Author: Smita Koralahalli <Smita.KoralahalliChannabasappa@amd.com> | ||
*/ | ||
|
||
#include <linux/cper.h> | ||
#include "cper_cxl.h" | ||
|
||
#define PROT_ERR_VALID_AGENT_TYPE BIT_ULL(0) | ||
#define PROT_ERR_VALID_AGENT_ADDRESS BIT_ULL(1) | ||
#define PROT_ERR_VALID_DEVICE_ID BIT_ULL(2) | ||
#define PROT_ERR_VALID_SERIAL_NUMBER BIT_ULL(3) | ||
#define PROT_ERR_VALID_CAPABILITY BIT_ULL(4) | ||
#define PROT_ERR_VALID_DVSEC BIT_ULL(5) | ||
|
||
static const char * const prot_err_agent_type_strs[] = { | ||
"Restricted CXL Device", | ||
"Restricted CXL Host Downstream Port", | ||
"CXL Device", | ||
"CXL Logical Device", | ||
"CXL Fabric Manager managed Logical Device", | ||
"CXL Root Port", | ||
"CXL Downstream Switch Port", | ||
"CXL Upstream Switch Port", | ||
}; | ||
|
||
/* | ||
* The layout of the enumeration and the values matches CXL Agent Type | ||
* field in the UEFI 2.10 Section N.2.13, | ||
*/ | ||
enum { | ||
RCD, /* Restricted CXL Device */ | ||
RCH_DP, /* Restricted CXL Host Downstream Port */ | ||
DEVICE, /* CXL Device */ | ||
LD, /* CXL Logical Device */ | ||
FMLD, /* CXL Fabric Manager managed Logical Device */ | ||
RP, /* CXL Root Port */ | ||
DSP, /* CXL Downstream Switch Port */ | ||
USP, /* CXL Upstream Switch Port */ | ||
}; | ||
|
||
void cper_print_prot_err(const char *pfx, const struct cper_sec_prot_err *prot_err) | ||
{ | ||
if (prot_err->valid_bits & PROT_ERR_VALID_AGENT_TYPE) | ||
pr_info("%s agent_type: %d, %s\n", pfx, prot_err->agent_type, | ||
prot_err->agent_type < ARRAY_SIZE(prot_err_agent_type_strs) | ||
? prot_err_agent_type_strs[prot_err->agent_type] | ||
: "unknown"); | ||
|
||
if (prot_err->valid_bits & PROT_ERR_VALID_AGENT_ADDRESS) { | ||
switch (prot_err->agent_type) { | ||
/* | ||
* According to UEFI 2.10 Section N.2.13, the term CXL Device | ||
* is used to refer to Restricted CXL Device, CXL Device, CXL | ||
* Logical Device or a CXL Fabric Manager Managed Logical | ||
* Device. | ||
*/ | ||
case RCD: | ||
case DEVICE: | ||
case LD: | ||
case FMLD: | ||
case RP: | ||
case DSP: | ||
case USP: | ||
pr_info("%s agent_address: %04x:%02x:%02x.%x\n", | ||
pfx, prot_err->agent_addr.segment, | ||
prot_err->agent_addr.bus, | ||
prot_err->agent_addr.device, | ||
prot_err->agent_addr.function); | ||
break; | ||
case RCH_DP: | ||
pr_info("%s rcrb_base_address: 0x%016llx\n", pfx, | ||
prot_err->agent_addr.rcrb_base_addr); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
if (prot_err->valid_bits & PROT_ERR_VALID_DEVICE_ID) { | ||
const __u8 *class_code; | ||
|
||
switch (prot_err->agent_type) { | ||
case RCD: | ||
case DEVICE: | ||
case LD: | ||
case FMLD: | ||
case RP: | ||
case DSP: | ||
case USP: | ||
pr_info("%s slot: %d\n", pfx, | ||
prot_err->device_id.slot >> CPER_PCIE_SLOT_SHIFT); | ||
pr_info("%s vendor_id: 0x%04x, device_id: 0x%04x\n", | ||
pfx, prot_err->device_id.vendor_id, | ||
prot_err->device_id.device_id); | ||
pr_info("%s sub_vendor_id: 0x%04x, sub_device_id: 0x%04x\n", | ||
pfx, prot_err->device_id.subsystem_vendor_id, | ||
prot_err->device_id.subsystem_id); | ||
class_code = prot_err->device_id.class_code; | ||
pr_info("%s class_code: %02x%02x\n", pfx, | ||
class_code[1], class_code[0]); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
if (prot_err->valid_bits & PROT_ERR_VALID_SERIAL_NUMBER) { | ||
switch (prot_err->agent_type) { | ||
case RCD: | ||
case DEVICE: | ||
case LD: | ||
case FMLD: | ||
pr_info("%s lower_dw: 0x%08x, upper_dw: 0x%08x\n", pfx, | ||
prot_err->dev_serial_num.lower_dw, | ||
prot_err->dev_serial_num.upper_dw); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
if (prot_err->valid_bits & PROT_ERR_VALID_CAPABILITY) { | ||
switch (prot_err->agent_type) { | ||
case RCD: | ||
case DEVICE: | ||
case LD: | ||
case FMLD: | ||
case RP: | ||
case DSP: | ||
case USP: | ||
print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4, | ||
prot_err->capability, | ||
sizeof(prot_err->capability), 0); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
if (prot_err->valid_bits & PROT_ERR_VALID_DVSEC) { | ||
pr_info("%s DVSEC length: 0x%04x\n", pfx, prot_err->dvsec_len); | ||
|
||
pr_info("%s CXL DVSEC:\n", pfx); | ||
print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4, (prot_err + 1), | ||
prot_err->dvsec_len, 0); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-only */ | ||
/* | ||
* UEFI Common Platform Error Record (CPER) support for CXL Section. | ||
* | ||
* Copyright (C) 2022 Advanced Micro Devices, Inc. | ||
* | ||
* Author: Smita Koralahalli <Smita.KoralahalliChannabasappa@amd.com> | ||
*/ | ||
|
||
#ifndef LINUX_CPER_CXL_H | ||
#define LINUX_CPER_CXL_H | ||
|
||
/* CXL Protocol Error Section */ | ||
#define CPER_SEC_CXL_PROT_ERR \ | ||
GUID_INIT(0x80B9EFB4, 0x52B5, 0x4DE3, 0xA7, 0x77, 0x68, 0x78, \ | ||
0x4B, 0x77, 0x10, 0x48) | ||
|
||
#pragma pack(1) | ||
|
||
/* Compute Express Link Protocol Error Section, UEFI v2.10 sec N.2.13 */ | ||
struct cper_sec_prot_err { | ||
u64 valid_bits; | ||
u8 agent_type; | ||
u8 reserved[7]; | ||
|
||
/* | ||
* Except for RCH Downstream Port, all the remaining CXL Agent | ||
* types are uniquely identified by the PCIe compatible SBDF number. | ||
*/ | ||
union { | ||
u64 rcrb_base_addr; | ||
struct { | ||
u8 function; | ||
u8 device; | ||
u8 bus; | ||
u16 segment; | ||
u8 reserved_1[3]; | ||
}; | ||
} agent_addr; | ||
|
||
struct { | ||
u16 vendor_id; | ||
u16 device_id; | ||
u16 subsystem_vendor_id; | ||
u16 subsystem_id; | ||
u8 class_code[2]; | ||
u16 slot; | ||
u8 reserved_1[4]; | ||
} device_id; | ||
|
||
struct { | ||
u32 lower_dw; | ||
u32 upper_dw; | ||
} dev_serial_num; | ||
|
||
u8 capability[60]; | ||
u16 dvsec_len; | ||
u16 err_len; | ||
u8 reserved_2[4]; | ||
}; | ||
|
||
#pragma pack() | ||
|
||
void cper_print_prot_err(const char *pfx, const struct cper_sec_prot_err *prot_err); | ||
|
||
#endif //__CPER_CXL_ |