PCIe CPER Section Enhancement
This commit improves PCIe error reporting capabilities by:
- Adding support for PCIe capability version detection and parsing
- Expanding Advanced Error Reporting information extraction
The changes include:
- New capability_registers structure to decode PCIe capability registers
- Updated PCIe JSON Schema to match
- Support for PCIe 2.0+ extended registers when detected
- Improved error source identification and root error status reporting
- Fix typo for Advanced Error Reporting capabilit[i]es_control
- Updated generate/gen-section-pcie.c and pcie.json example
In the future we could:
- Implement TLP header log parsing with detailed descriptions
- Add support for Flit mode in PCIe 2.0+ devices
Tested:
- test/cper-tests passes
- cper-convert to-json|to-cper on pcie.cper|json in example path
- Tested "cper-convert to-json-section" using an extracted OS GHES PCIE
CPER from error injection and compare against expected values
Note, schema validation is intentionally less restrictive than it could
be for pcie advanced error reporting as it evolves.
Change-Id: Ifebb9d97d28a3a487a0aab53bf9e757afeedd64a
Signed-off-by: Erwin Tsaur <etsaur@nvidia.com>
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/cper-utils.c b/cper-utils.c
index f6adbdb..01c1f7e 100644
--- a/cper-utils.c
+++ b/cper-utils.c
@@ -491,3 +491,47 @@
json_object_new_string_len(platform_string,
sizeof(platform_string) - 1));
}
+
+void add_int(json_object *register_ir, const char *field_name, int value)
+{
+ json_object_object_add(register_ir, field_name,
+ json_object_new_uint64(value));
+}
+
+void add_bool(json_object *register_ir, const char *field_name, UINT64 value)
+{
+ json_object_object_add(register_ir, field_name,
+ json_object_new_boolean(value));
+}
+
+void add_bool_enum(json_object *register_ir, const char *field_name,
+ const char *value_dict[2], UINT64 value_int)
+{
+ const char *value = value_dict[0];
+ if (value_int > 0) {
+ value = value_dict[1];
+ }
+ json_object_object_add(register_ir, field_name,
+ json_object_new_string(value));
+}
+
+void add_dict(json_object *register_ir, const char *field_name, UINT64 value,
+ const char *dict[], size_t dict_size)
+{
+ json_object *field_ir = json_object_new_object();
+ json_object_object_add(register_ir, field_name, field_ir);
+ json_object_object_add(field_ir, "raw", json_object_new_uint64(value));
+
+ if (dict != NULL) {
+ if (value < dict_size) {
+ const char *name = dict[value];
+ if (name != NULL) {
+ const char *value_name = name;
+
+ json_object_object_add(
+ field_ir, "value",
+ json_object_new_string(value_name));
+ }
+ }
+ }
+}
diff --git a/examples/pcie.cperhex b/examples/pcie.cperhex
index 921660c..9920993 100644
--- a/examples/pcie.cperhex
+++ b/examples/pcie.cperhex
@@ -1,14 +1,14 @@
-435045520000ffffffff0100000000000300000098010000130021002604
-125500000000000000000000000000000000000000000000000000000000
+435045520000ffffffff0100010000000300000098010000300016000401
+171700000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
-0000000000009a7f435b0000000004000000000000000000000000000000
-0000000000000000c8000000d00000009cbf0300e300000054e995d9c1bb
-0f43ad91b44dcb3c6f356668938aa36c6e3f2b9dcf0ef92fd4d802000000
-48493c4348686e353b6f5c2d6c276d000000000055000000000000000700
-0000000000007b8fe1540000000000000000000000000000000000000000
-6d4e4f1ea0401a1b0000000070b1cda60f4f37180daa93a6ed6e715623dd
-d9902c28aecc68c8e737c3569b330868da17b7112fc4bbc26aa830dbff54
-b8d8e4e40093b0695b97a01f000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000
\ No newline at end of file
+000000000000e0e8bf1f0000000004000000000000000000000000000000
+0000000000000000c8000000d00000002baa0300a200000054e995d9c1bb
+0f43ad91b44dcb3c6f3549fd824ea90870d4b28a2954489a0abc01000000
+0f2b6a773f7842374c65740d0c4a6f502e245b00d5000000000000000500
+0000245000007cc254f800000000765a2e63339fc99a66320db73158a300
+255d051758e95ed4abb2cdc69bb454110e827441213ddc8770e93ea141e1
+fc673e017e97eadc6b968f385c2aecb03bfb32af3c54ec18db5c021afe43
+fbfaaa3afb29d1e6053c7c9475d8be6189f95cbba8990f95b1ebf1b305ef
+f700e9a13ae5ca0bcbd0484764bd1f231ea81c7b64c514735ac55e4b7963
+3b706424119e09dcaad4acf21b10af3b33cde3504847155cbb6f2219ba9b
+7df50be11a1c7f23f829f8a41b13b5ca4ee8
diff --git a/examples/pcie.json b/examples/pcie.json
index 4318600..bf0ca94 100644
--- a/examples/pcie.json
+++ b/examples/pcie.json
@@ -11,7 +11,7 @@
},
"persistenceInfo": 0,
"platformID": "00000000-0000-0000-0000-000000000000",
- "recordID": 1531150234,
+ "recordID": 532670688,
"recordLength": 408,
"revision": {
"major": 0,
@@ -19,10 +19,10 @@
},
"sectionCount": 1,
"severity": {
- "code": 0,
- "name": "Recoverable"
+ "code": 1,
+ "name": "Fatal"
},
- "timestamp": "5512-04-26T21:00:13+00:00",
+ "timestamp": "1717-01-04T16:00:30+00:00",
"timestampIsPrecise": false
},
"sectionDescriptors": [
@@ -32,16 +32,15 @@
"errorThresholdExceeded": false,
"latentError": true,
"overflow": true,
- "primary": true,
- "propagated": true,
+ "primary": false,
+ "propagated": false,
"reset": false,
"resourceNotAccessible": false
},
- "fruID": "8a936866-6ca3-3f6e-2b9d-cf0ef92fd4d8",
- "fruText": "HI<CHhn5;o\\-l'm",
+ "fruID": "4e82fd49-08a9-d470-b28a-2954489a0abc",
"revision": {
- "major": 191,
- "minor": 156
+ "major": 170,
+ "minor": 43
},
"sectionLength": 208,
"sectionOffset": 200,
@@ -50,25 +49,319 @@
"type": "PCIe"
},
"severity": {
- "code": 2,
- "name": "Corrected"
+ "code": 1,
+ "name": "Fatal"
}
}
],
"sections": [
{
"Pcie": {
+ "aerInfo": {
+ "advanced_error_capabilities_and_control": {
+ "first_error_pointer": 10,
+ "header_log_size": 24,
+ "logged_tlp_size": 25
+ },
+ "capability_header": {
+ "capability_id": 55413,
+ "capability_version": 14,
+ "next_capability_offset": 1563
+ },
+ "correctable_error_mask": {
+ "advisory_non_fatal_error_mask": 1,
+ "bad_dllp_mask": 1,
+ "bad_tlp_mask": 1,
+ "corrected_internal_error_mask": 0,
+ "header_log_overflow_mask": 1,
+ "receiver_error_mask": 1,
+ "replay_num_rollover_mask": 1,
+ "replay_timer_timeout_mask": 0
+ },
+ "correctable_error_status": {
+ "advisory_non_fatal_error_status": true,
+ "bad_dllp_status": false,
+ "bad_tlp_status": false,
+ "corrected_internal_error_status": true,
+ "header_log_overflow_status": true,
+ "receiver_error_status": true,
+ "replay_num_rollover_status": true,
+ "replay_timer_timeout_status": false
+ },
+ "data": "ddi+YYn5XLuomQ+VsevxswXv9wDpoTrlygvL0EhHZL0fIx6oHHtkxRRzWsVeS3ljO3BkJBGeCdyq1KzyGxCvOzPN41BIRxVcu28iGbqbffUL4RocfyP4KfikGxO1yk7o",
+ "error_source_id": {
+ "err_cor_source_identification": 40465,
+ "err_fatal_nonfatal_source_identification": 56329
+ },
+ "root_error_command": {},
+ "root_error_status": {
+ "advanced_error_interrupt_message_number": 18,
+ "err_cor_subclass": 0
+ },
+ "uncorrectable_error_mask": {
+ "acs_violation_mask": 0,
+ "atomicop_egress_blocked_mask": 1,
+ "completer_abort_mask": 1,
+ "completion_timeout_mask": 0,
+ "data_link_protocol_error_mask": 0,
+ "dmwr_request_egress_blocked_mask": 0,
+ "ecrc_error_mask": 1,
+ "flow_control_protocol_error_mask": 0,
+ "ide_check_failed_mask": 1,
+ "malformed_tlp_mask": 1,
+ "mc_blocked_tlp_mask": 0,
+ "misrouted_ide_tlp_mask": 0,
+ "pcrc_check_failed_mask": 0,
+ "poisoned_tlp_egress_blocked_mask": 1,
+ "poisoned_tlp_received_mask": 1,
+ "receiver_overflow_mask": 1,
+ "surprise_down_error_mask": 1,
+ "tlp_prefix_blocked_error_mask": 0,
+ "tlp_translation_egress_blocked_mask": 1,
+ "uncorrectable_internal_error_mask": 0,
+ "unexpected_completion_mask": 1,
+ "unsupported_request_error_mask": 0
+ },
+ "uncorrectable_error_severity": {
+ "acs_violation_severity": "Fatal",
+ "atomicop_egress_blocked_severity": "Fatal",
+ "completer_abort_severity": "Fatal",
+ "completion_timeout_severity": "Fatal",
+ "data_link_protocol_error_severity": "Fatal",
+ "dmwr_request_egress_blocked_severity": "NonFatal",
+ "ecrc_error_severity": "NonFatal",
+ "flow_control_protocol_error_severity": "Fatal",
+ "ide_check_failed_severity": "Fatal",
+ "malformed_tlp_severity": "NonFatal",
+ "mc_blocked_tlp_severity": "Fatal",
+ "misrouted_ide_tlp_severity": "Fatal",
+ "pcrc_check_failed_severity": "NonFatal",
+ "poisoned_tlp_egress_blocked_severity": "NonFatal",
+ "poisoned_tlp_received_severity": "NonFatal",
+ "receiver_overflow_severity": "NonFatal",
+ "surprise_down_error_severity": "Fatal",
+ "tlp_prefix_blocked_error_severity": "Fatal",
+ "tlp_translation_egress_blocked_severity": "Fatal",
+ "uncorrectable_internal_error_severity": "Fatal",
+ "unexpected_completion_severity": "Fatal",
+ "unsupported_request_error_severity": "Fatal"
+ },
+ "uncorrectable_error_status": {
+ "acs_violation_status": false,
+ "atomicop_egress_blocked_status": true,
+ "completer_abort_status": true,
+ "completion_timeout_status": true,
+ "data_link_protocol_error_status": false,
+ "dmwr_request_egress_blocked_status": true,
+ "ecrc_error_status": true,
+ "flow_control_protocol_error_status": true,
+ "ide_check_failed_status": true,
+ "malformed_tlp_status": true,
+ "mc_blocked_tlp_status": false,
+ "misrouted_ide_tlp_status": true,
+ "pcrc_check_failed_status": false,
+ "poisoned_tlp_egress_blocked_status": false,
+ "poisoned_tlp_received": true,
+ "receiver_overflow_status": false,
+ "surprise_down_error_status": false,
+ "tlp_prefix_blocked_error_status": true,
+ "tlp_translation_egress_blocked_status": true,
+ "uncorrectable_internal_error_status": true,
+ "unexpected_completion_status": false,
+ "unsupported_request_error_status": true
+ }
+ },
"capabilityStructure": {
- "data": "cLHNpg9PNxgNqpOm7W5xViPd2ZAsKK7MaMjnN8NWmzMIaNoXtxEvxLvCaqgw2/9UuNjk5ACTsGlbl6Af"
+ "data": "m7RUEQ6CdEEhPdyHcOk+oUHh/Gc+AX6X6txrlo84XCrssDv7Mq88VOwY21wCGv5D+/qqOvsp0eYFPHyU",
+ "device_capabilities": {
+ "captured_slot_power_limit_scale": 0,
+ "captured_slot_power_limit_value": 93,
+ "endpoint_l0s_acceptable_latency": {
+ "raw": 0
+ },
+ "endpoint_l1_acceptable_latency": {
+ "raw": 1
+ },
+ "err_cor_subclass_capable": false,
+ "extended_tag_field_supported": "NotSupported",
+ "function_level_reset_capability_supported": "NotSupported",
+ "max_payload_size_supported": 6,
+ "mixed_mps_supported": "NotSupported",
+ "phantom_functions_supported": "Supported",
+ "role_based_error_reporting": true,
+ "rx_mps_fixed": 0,
+ "tee_io_supported": "Supported"
+ },
+ "device_capabilities2": {
+ "_128_bit_cas_completer_supported": "Supported",
+ "_32_bit_atomicop_completer_supported": "NotSupported",
+ "_64_bit_atomicop_completer_supported": "Supported",
+ "ari_forwarding_supported": "Supported",
+ "atomic_op_routing_supported": "NotSupported",
+ "completion_timeout_disable_supported": "Supported",
+ "completion_timeout_ranges_supported": 2,
+ "dmwr_lengths_supported": 2,
+ "emergency_power_reduction_supported": "NotSupported",
+ "ltr_mechanism_supported": "Supported",
+ "max_end_end_tlp_prefixes": {
+ "raw": 0
+ },
+ "no_ro_enabled_pr_pr_passing": "Passing",
+ "obff_supported": "Supported",
+ "tph_completer_supported": "Supported"
+ },
+ "device_control": {
+ "aux_power_pm_enable": "Enabled",
+ "correctable_error_reporting_enable": "Enabled",
+ "enable_no_snoop": 1,
+ "extended_tag_field_enable": "Enabled",
+ "fatal_error_reporting_enable": "Disabled",
+ "function_level_reset": false,
+ "max_payload_size": 1,
+ "max_read_request_size": 3,
+ "non_fatal_error_reporting_enable": "Disabled",
+ "phantom_functions_enable": "Disabled",
+ "relaxed_ordering_enable": "Disabled",
+ "unsupported_request_reporting_enabled": "Disabled"
+ },
+ "device_control2": {
+ "10_bit_tag_requester_enable": true,
+ "ari_forwarding_enable": true,
+ "atomicop_egress_blocking": true,
+ "atomicop_requester_enable": true,
+ "completion_timeout_value": 12,
+ "emergency_power_reduction_request": true,
+ "ido_completion_enable": false,
+ "ido_request_enable": false,
+ "ltr_mechanism_enable": false,
+ "obff_enable": 0
+ },
+ "device_status": {
+ "aux_power_detected": true,
+ "correctable_error_detected": false,
+ "emergency_power_reduction": 3,
+ "fatal_error_detected": true,
+ "non_fatal_error_detected": false,
+ "transactions_pending": false,
+ "unsupported_request_detected": true
+ },
+ "device_status2": {},
+ "link_capabilities": {
+ "aspm_optionality_compliance": false,
+ "aspm_support": 2,
+ "clock_power_management": true,
+ "data_link_layer_link_active_reporting_capable": true,
+ "l0s_exit_latency": 6,
+ "l1_exit_latency": 5,
+ "link_bandwidth_notification_capability": true,
+ "max_link_speed": 0,
+ "maximum_link_width": 23,
+ "port_number": 161,
+ "surprise_down_error_reporting_capable": true
+ },
+ "link_capabilities2": {
+ "crosslink_supported": "NotSupported",
+ "drs_supported": "NotSupported",
+ "lower_skp_os_generation_supported": 125,
+ "lower_skp_os_reception_supported": 42,
+ "retimer_presence_detect_supported": "Supported",
+ "supported_link_speeds": 26,
+ "two_retimers_presence_detect_supported": "NotSupported"
+ },
+ "link_control": {
+ "aspm_control": 1,
+ "extended_synch": 0,
+ "flit_mode_disable": 1,
+ "link_disable": 0,
+ "ptm_prop_delay_adaptation_interpretation": false,
+ "retrain_link": 0,
+ "sris_clocking": 0
+ },
+ "link_control2": {
+ "compliance_preset_de_emphasis": 2,
+ "compliance_sos": true,
+ "enter_compliance": "Supported",
+ "enter_modified_compliance": false,
+ "hardware_autonomous_speed_disable": {
+ "raw": 1
+ },
+ "selectable_de_emphasis": true,
+ "target_link_speed": {
+ "raw": 11
+ },
+ "transmit_margin": 3
+ },
+ "link_status": {
+ "current_link_speed": 12,
+ "link_training": 0,
+ "negotiated_link_width": 63
+ },
+ "link_status2": {
+ "crosslink_resolution": 2,
+ "current_de_emphasis_level": 1,
+ "downstream_component_presence": 6,
+ "drs_message_received": true,
+ "equalization_8gts_complete": false,
+ "equalization_8gts_phase1_successful": false,
+ "equalization_8gts_phase2_successful": false,
+ "equalization_8gts_phase3_successful": true,
+ "flit_mode_status": 1,
+ "link_equalization_request_8gts": false,
+ "retimer_presence_detected": true,
+ "two_retimers_presence_detected": true
+ },
+ "pcie_capabilities": {
+ "capability_version": 4,
+ "device_port_type": {
+ "raw": 5,
+ "value": "PCIE_PCI_BRIDGE"
+ },
+ "flit_mode_supported": "NotSupported",
+ "interrupt_message_number": 8,
+ "slot_implemented": true
+ },
+ "pcie_capability_header": {
+ "capability_id": {
+ "raw": 155
+ },
+ "next_capability_pointer": 180
+ },
+ "root_capabilities": {},
+ "root_control": {},
+ "root_status": {
+ "pme_pending": 1,
+ "pme_requester_id": 45292,
+ "pme_status": 1
+ },
+ "slot_capabilities": {
+ "physical_slot_number": 4847,
+ "slot_power_limit_scale": 0,
+ "slot_power_limit_value": {
+ "raw": 2
+ }
+ },
+ "slot_capabilities2": {},
+ "slot_control": {
+ "attention_indicator_control": 3,
+ "power_indicator_control": 0,
+ "rsvdp": 1
+ },
+ "slot_control2": {},
+ "slot_status": {
+ "command_completed": 0,
+ "mrl_sensor_changed": 0,
+ "mrl_sensor_state": 1
+ },
+ "slot_status2": {}
},
"commandStatus": {
- "commandRegister": 36731,
- "statusRegister": 21729
+ "commandRegister": 49788,
+ "statusRegister": 63572
},
- "deviceSerialNumber": 1952944444865990253,
+ "deviceSerialNumber": 15302925148404145445,
"portType": {
- "name": "PCI Express to PCI/PCI-X Bridge",
- "value": 7
+ "name": "Upstream Switch Port",
+ "value": 5
}
}
}
diff --git a/generator/sections/gen-section-pcie.c b/generator/sections/gen-section-pcie.c
index 2111d28..063ab9b 100644
--- a/generator/sections/gen-section-pcie.c
+++ b/generator/sections/gen-section-pcie.c
@@ -26,7 +26,15 @@
if (validBitsType == ALL_VALID) {
*validation = 0xFF;
} else if (validBitsType == SOME_VALID) {
- *validation = 0x55;
+ /*
+ * Valid Sections
+ * 0b00000001 : Port Type
+ * 0b00000100 : Command Status Valid
+ * 0b00010000 : Device Serial Number Valid
+ * 0b01000000 : Capability Structure Valid
+ * 0b10000000 : AER Info Valid
+ */
+ *validation = 0xD5;
}
UINT32 *version = (UINT32 *)(bytes + 12);
*version &= 0xFFFF; //Version bytes 2-3
diff --git a/include/libcper/cper-utils.h b/include/libcper/cper-utils.h
index 0231f34..992c725 100644
--- a/include/libcper/cper-utils.h
+++ b/include/libcper/cper-utils.h
@@ -67,6 +67,16 @@
void add_guid(json_object *ir, const char *field_name, EFI_GUID *guid);
+void add_int(json_object *register_ir, const char *field_name, int value);
+
+void add_bool(json_object *register_ir, const char *field_name, UINT64 value);
+
+void add_bool_enum(json_object *register_ir, const char *field_name,
+ const char *value_dict[2], UINT64 value);
+
+void add_dict(json_object *register_ir, const char *field_name, UINT64 value,
+ const char *dict[], size_t dict_size);
+
//The available severity types for CPER.
extern const char *CPER_SEVERITY_TYPES[4];
diff --git a/include/libcper/sections/cper-section-pcie.h b/include/libcper/sections/cper-section-pcie.h
index 93206b7..4466168 100644
--- a/include/libcper/sections/cper-section-pcie.h
+++ b/include/libcper/sections/cper-section-pcie.h
@@ -33,6 +33,767 @@
json_object *cper_section_pcie_to_ir(const UINT8 *section, UINT32 size);
void ir_section_pcie_to_cper(json_object *section, FILE *out);
+/*
+ * This file is designed as a standard c header file and as a script friendly
+ * source fo the PCIe PCIe Capability and Advanced Error Registers structures.
+ * The template of each register is:
+ *
+ *
+ * * <Name of Capabaility Structure>
+ * * CAPABILITY_ID = <id of capability structure>
+ * * <Register Name>
+ * * Offset: <offset of the register in the capability structure>
+ * struct {
+ * <register width> <field name> : <field width>;
+ * <register width> <field name> : <field width>;
+ * <register width> <field name> : <field width>;
+ * }
+ */
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * PCI Express Capability Structure Header
+ * Offset: 0x0
+ */
+typedef struct {
+ UINT16 capability_id : 8; // bits [7:0] - Capability ID (should be 0x10)
+ UINT16 next_capability_pointer : 8; // bits [7:0] - Next capability pointer
+} __attribute__((packed)) pcie_capability_header_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * PCI Express Capabilities Register
+ * Offset: 0x2
+ */
+typedef struct {
+ UINT16 capability_version : 4; // bits [3:0]
+ UINT16 device_port_type : 4; // bits [7:4]
+ UINT16 slot_implemented : 1; // bit [8]
+ UINT16 interrupt_message_number : 5; // bits [13:9]
+ UINT16 undefined : 1; // bit [14]
+ UINT16 flit_mode_supported : 1; // bit [15]
+} __attribute__((packed)) pcie_capabilities_t;
+
+static const char *device_port_type_dict[] = {
+ "PCIE", // 0x0
+ "PCI", // 0x1
+ "ROOT_PORT", // 0x4
+ "UPSTREAM", // 0x5
+ "DOWNSTREAM", // 0x6
+ "PCIE_PCI_BRIDGE", // 0x7
+ "PCI_PCIE_BRIDGE", // 0x8
+ "RCiEP", // 0x9
+ "RCEC", // 0xa
+};
+
+static const size_t device_port_type_dict_size =
+ sizeof(device_port_type_dict) / sizeof(device_port_type_dict[0]);
+
+/*
+ * Begin Of PCIe Capability Registers
+ */
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Device Capabilities Register
+ * Offset: 0x4
+ */
+typedef struct {
+ UINT32 max_payload_size_supported : 3; // bits [2:0]
+ UINT32 phantom_functions_supported : 2; // bits [4:3]
+ UINT32 extended_tag_field_supported : 1; // bit [5]
+ UINT32 endpoint_l0s_acceptable_latency : 3; // bits [8:6]
+ UINT32 endpoint_l1_acceptable_latency : 3; // bits [11:9]
+ UINT32 undefined : 3; // bits [14:12]
+ UINT32 role_based_error_reporting : 1; // bit [15]
+ UINT32 err_cor_subclass_capable : 1; // bit [16]
+ UINT32 rx_mps_fixed : 1; // bits [17]
+ UINT32 captured_slot_power_limit_value : 8; // bits [25:18]
+ UINT32 captured_slot_power_limit_scale : 2; // bits [27:26]
+ UINT32 function_level_reset_capability : 1; // bit [28]
+ UINT32 mixed_mps_supported : 1; // bit [29]
+ UINT32 tee_io_supported : 1; // bit [30]
+ UINT32 rsvdp : 1; // bit [31]
+} __attribute__((packed)) device_capabilities_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Device Control Register
+ * Offset: 0x8
+ */
+typedef struct {
+ UINT16 correctable_error_reporting_enable : 1; // bit [0]
+ UINT16 non_fatal_error_reporting_enable : 1; // bit [1]
+ UINT16 fatal_error_reporting_enable : 1; // bit [2]
+ UINT16 unsupported_request_reporting_enable : 1; // bit [3]
+ UINT16 enable_relaxed_ordering : 1; // bit [4]
+ UINT16 max_payload_size : 3; // bits [7:5]
+ UINT16 extended_tag_field_enable : 1; // bit [8]
+ UINT16 phantom_functions_enable : 1; // bit [9]
+ UINT16 aux_power_pm_enable : 1; // bit [10]
+ UINT16 enable_no_snoop : 1; // bit [11]
+ UINT16 max_read_request_size : 3; // bits [14:12]
+ UINT16 function_level_reset : 1; // bit [15]
+} __attribute__((packed)) device_control_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Device Status Register
+ * Offset: 0xA
+ */
+typedef struct {
+ UINT16 correctable_error_detected : 1; // bit [0]
+ UINT16 non_fatal_error_detected : 1; // bit [1]
+ UINT16 fatal_error_detected : 1; // bit [2]
+ UINT16 unsupported_request_detected : 1; // bit [3]
+ UINT16 aux_power_detected : 1; // bit [4]
+ UINT16 transactions_pending : 1; // bit [5]
+ UINT16 emergency_power_reduction : 2; // bits [7:6] (PCIe 4.0+)
+ UINT16 rsvdz : 8; // bits [15:8]
+} __attribute__((packed)) device_status_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Link Capabilities Register
+ * Offset: 0xC
+ */
+typedef struct {
+ UINT32 max_link_speed : 4; // bits [3:0]
+ UINT32 maximum_link_width : 6; // bits [9:4]
+ UINT32 aspm_support : 2; // bits [11:10]
+ UINT32 l0s_exit_latency : 3; // bits [14:12]
+ UINT32 l1_exit_latency : 3; // bits [17:15]
+ UINT32 clock_power_management : 1; // bit [18]
+ UINT32 surprise_down_error_reporting_capable : 1; // bit [19]
+ UINT32 data_link_layer_link_active_reporting_capable : 1; // bit [20]
+ UINT32 link_bandwidth_notification_capability : 1; // bit [21]
+ UINT32 aspm_optionality_compliance : 1; // bit [22]
+ UINT32 rsvdp : 1; // bit [23]
+ UINT32 port_number : 8; // bits [31:24]
+} __attribute__((packed)) link_capabilities_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Link Control Register
+ * Offset: 0x10
+ */
+typedef struct {
+ UINT16 aspm_control : 2; // bits [1:0]
+ // ptm_propagation_delay_adaptation_interpretation_bit
+ UINT16 ptm_prop_delay_adaptation_interpretation : 1; // bit [2]
+ UINT16 read_completion_boundary : 1; // bit [3]
+ UINT16 link_disable : 1; // bit [4]
+ UINT16 retrain_link : 1; // bit [5]
+ UINT16 common_clock_configuration : 1; // bit [6]
+ UINT16 extended_synch : 1; // bit [7]
+ UINT16 enable_clock_power_management : 1; // bit [8]
+ UINT16 hardware_autonomous_width_disable : 1; // bit [9]
+ UINT16 link_bandwidth_management_interrupt_enable : 1; // bit [10]
+ UINT16 link_autonomous_bandwidth_interrupt_enable : 1; // bit [11]
+ UINT16 sris_clocking : 1; // bit [12]
+ UINT16 flit_mode_disable : 1; // bit [13]
+ UINT16 drs_signaling_control : 1; // bits [15:14]
+} __attribute__((packed)) link_control_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Link Status Register
+ * Offset: 0x12
+ */
+typedef struct {
+ UINT16 current_link_speed : 4; // bits [3:0]
+ UINT16 negotiated_link_width : 6; // bits [9:4]
+ UINT16 undefined : 1; // bit [10]
+ UINT16 link_training : 1; // bit [11]
+ UINT16 slot_clock_configuration : 1; // bit [12]
+ UINT16 data_link_layer_link_active : 1; // bit [13]
+ UINT16 link_bandwidth_management_status : 1; // bit [14]
+ UINT16 link_autonomous_bandwidth_status : 1; // bit [15]
+} __attribute__((packed)) link_status_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Slot Capabilities Register
+ * Offset: 0x14
+ */
+typedef struct {
+ UINT32 attention_button_present : 1; // bit [0]
+ UINT32 power_controller_present : 1; // bit [1]
+ UINT32 mrl_sensor_present : 1; // bit [2]
+ UINT32 attention_indicator_present : 1; // bit [3]
+ UINT32 power_indicator_present : 1; // bit [4]
+ UINT32 hot_plug_surprise : 1; // bit [5]
+ UINT32 hot_plug_capable : 1; // bit [6]
+ UINT32 slot_power_limit_value : 8; // bits [14:7]
+ UINT32 slot_power_limit_scale : 2; // bits [16:15]
+ UINT32 electromechanical_interlock_present : 1; // bit [17]
+ UINT32 no_command_completed_support : 1; // bit [18]
+ UINT32 physical_slot_number : 13; // bits [31:19]
+} __attribute__((packed)) slot_capabilities_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Slot Control Register
+ * Offset: 0x18
+ */
+typedef struct {
+ UINT16 attention_button_pressed_enable : 1; // bit [0]
+ UINT16 power_fault_detected_enable : 1; // bit [1]
+ UINT16 mrl_sensor_changed_enable : 1; // bit [2]
+ UINT16 presence_detect_changed_enable : 1; // bit [3]
+ UINT16 command_completed_interrupt_enable : 1; // bit [4]
+ UINT16 hot_plug_interrupt_enable : 1; // bit [5]
+ UINT16 attention_indicator_control : 2; // bits [7:6]
+ UINT16 power_indicator_control : 2; // bits [9:8]
+ UINT16 power_controller_control : 1; // bit [10]
+ UINT16 electromechanical_interlock_control : 1; // bit [11]
+ UINT16 data_link_layer_state_changed_enable : 1; // bit [12]
+ UINT16 auto_slot_power_limit_disable : 1; // bit [13]
+ UINT16 in_band_pd_disable : 1; // bit [14]
+ UINT16 rsvdp : 1; // bit [15]
+} __attribute__((packed)) slot_control_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Slot Status Register
+ * Offset: 0x1A
+ */
+typedef struct {
+ UINT16 attention_button_pressed : 1; // bit [0]
+ UINT16 power_fault_detected : 1; // bit [1]
+ UINT16 mrl_sensor_changed : 1; // bit [2]
+ UINT16 presence_detect_changed : 1; // bit [3]
+ UINT16 command_completed : 1; // bit [4]
+ UINT16 mrl_sensor_state : 1; // bit [5]
+ UINT16 presence_detect_state : 1; // bit [6]
+ UINT16 electromechanical_interlock_status : 1; // bit [7]
+ UINT16 data_link_layer_state_changed : 1; // bit [8]
+ UINT16 rsvdz : 7; // bits [15:9]
+} __attribute__((packed)) slot_status_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Root Control Register
+ * Offset: 0x1C
+ */
+typedef struct {
+ UINT16 system_error_on_correctable_error_enable : 1; // bit [0]
+ UINT16 system_error_on_non_fatal_error_enable : 1; // bit [1]
+ UINT16 system_error_on_fatal_error_enable : 1; // bit [2]
+ UINT16 pme_interrupt_enable : 1; // bit [3]
+ UINT16 configuration_rrs_software_visibility_enable : 1; // bit [4]
+ UINT16 no_nfm_subtree_below_this_root_port : 1; // bit [5]
+ UINT16 rsvdp : 10; // bits [15:6]
+} __attribute__((packed)) root_control_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Root Capabilities Register
+ * Offset: 0x1E
+ */
+typedef struct {
+ UINT16 configuraton_rrs_software_visibility : 1; // bit [0]
+ UINT16 rsvdp : 15; // bits [15:1]
+} __attribute__((packed)) root_capabilities_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Root Status Register
+ * Offset: 0x20
+ */
+typedef struct {
+ UINT32 pme_requester_id : 16; // bits [15:0]
+ UINT32 pme_status : 1; // bit [16]
+ UINT32 pme_pending : 1; // bit [17]
+ UINT32 rsvdp : 14; // bits [31:18]
+} __attribute__((packed)) root_status_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Device Capabilities 2 Register
+ * Offset: 0x24
+ */
+typedef struct {
+ UINT32 completion_timeout_ranges_supported : 4; // bits [3:0]
+ UINT32 completion_timeout_disable_supported : 1; // bit [4]
+ UINT32 ari_forwarding_supported : 1; // bit [5]
+ UINT32 atomic_op_routing_supported : 1; // bit [6]
+ UINT32 _32_bit_atomicop_completer_supported : 1; // bit [7]
+ UINT32 _64_bit_atomicop_completer_supported : 1; // bit [8]
+ UINT32 _128_bit_cas_completer_supported : 1; // bit [9]
+ UINT32 no_ro_enabled_pr_pr_passing : 1; // bit [10]
+ UINT32 ltr_mechanism_supported : 1; // bit [11]
+ UINT32 tph_completer_supported : 2; // bits [13:12]
+ UINT32 undefined : 2; // bit [15:14]
+ UINT32 _10_bit_tag_completer_supported : 1; // bit [16]
+ UINT32 _10_bit_tag_requester_supported : 1; // bit [17]
+ UINT32 obff_supported : 2; // bits [19:18]
+ UINT32 extended_fmt_field_supported : 1; // bit [20]
+ UINT32 end_end_tlp_prefix_supported : 1; // bit [21]
+ UINT32 max_end_end_tlp_prefixes : 2; // bits [23:22]
+ UINT32 emergency_power_reduction_supported : 2; // bits [25:24]
+ // emergency_power_reduction_initialization_required
+ UINT32 emergency_power_reduction_init_required : 1; // bit [26]
+ UINT32 rsvdp : 1; // bit [27]
+ UINT32 dmwr_completer_supported : 1; // bit [28]
+ UINT32 dmwr_lengths_supported : 2; // bits [30:29]
+ UINT32 frs_supported : 1; // bit [31]
+} __attribute__((packed)) device_capabilities2_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Device Control 2 Register
+ * Offset: 0x28
+ */
+typedef struct {
+ UINT16 completion_timeout_value : 4; // bits [3:0]
+ UINT16 completion_timeout_disable : 1; // bit [4]
+ UINT16 ari_forwarding_enable : 1; // bit [5]
+ UINT16 atomicop_requester_enable : 1; // bit [6]
+ UINT16 atomicop_egress_blocking : 1; // bit [7]
+ UINT16 ido_request_enable : 1; // bit [8]
+ UINT16 ido_completion_enable : 1; // bit [9]
+ UINT16 ltr_mechanism_enable : 1; // bit [10]
+ UINT16 emergency_power_reduction_request : 1; // bit [11]
+ UINT16 _10_bit_tag_requester_enable : 1; // bit [12]
+ UINT16 obff_enable : 2; // bits [14:13]
+ UINT16 end_end_tlp_prefix_blocking : 1; // bit [15]
+} __attribute__((packed)) device_control2_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Device Status 2 Register
+ * Offset: 0x2A
+ */
+typedef struct {
+ UINT16 rsvdz : 16; // bits [15:0]
+} __attribute__((packed)) device_status2_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Link Capabilities 2 Register
+ * Offset: 0x2C
+ */
+typedef struct {
+ UINT32 rsvdp : 1; // bit [0]
+ union {
+ struct {
+ UINT32 l_2_5g_supported : 1;
+ UINT32 l_5g_supported : 1;
+ UINT32 l_8g_supported : 1;
+ UINT32 l_16g_supported : 1;
+ UINT32 l_32g_supported : 1;
+ UINT32 reserved1 : 1;
+ UINT32 reserved2 : 1;
+ } __attribute__((packed)) supported_link_speeds;
+ UINT32 supported_link_speeds_register : 7; // bits [7:1]
+ };
+
+ UINT32 crosslink_supported : 1; // bit [8]
+ UINT32 lower_skp_os_generation_supported : 7; // bit [15:9]
+ UINT32 lower_skp_os_reception_supported : 7; // bit [22:16]
+ UINT32 retimer_presence_detect_supported : 1; // bit [23]
+ UINT32 two_retimers_presence_detect_supported : 1; // bit [24]
+ UINT32 reserved : 6; // bits [30:25]
+ UINT32 drs_supported : 1; // bit [31]
+} __attribute__((packed)) link_capabilities2_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Link Control 2 Register
+ * Offset: 0x30
+ */
+typedef struct {
+ UINT16 target_link_speed : 4; // bits [3:0]
+ UINT16 enter_compliance : 1; // bit [4]
+ UINT16 hardware_autonomous_speed_disable : 1; // bit [5]
+ UINT16 selectable_de_emphasis : 1; // bit [6]
+ UINT16 transmit_margin : 3; // bits [9:7]
+ UINT16 enter_modified_compliance : 1; // bit [10]
+ UINT16 compliance_sos : 1; // bit [11]
+ UINT16 compliance_preset_de_emphasis : 4; // bits [15:12]
+} __attribute__((packed)) link_control2_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Link Status 2 Register
+ * Offset: 0x32
+ */
+typedef struct {
+ UINT16 current_de_emphasis_level : 1; // bit [0]
+ UINT16 equalization_8gts_complete : 1; // bit [1]
+ UINT16 equalization_8gts_phase1_successful : 1; // bit [2]
+ UINT16 equalization_8gts_phase2_successful : 1; // bit [3]
+ UINT16 equalization_8gts_phase3_successful : 1; // bit [4]
+ UINT16 link_equalization_request_8gts : 1; // bit [5]
+ UINT16 retimer_presence_detected : 1; // bit [6]
+ UINT16 two_retimers_presence_detected : 1; // bit [7]
+ UINT16 crosslink_resolution : 2; // bits [9:8]
+ UINT16 flit_mode_status : 1; // bit [10]
+ UINT16 rsvdz : 1; // bit [11]
+ UINT16 downstream_component_presence : 3; // bits [14:12]
+ UINT16 drs_message_received : 1; // bit [15]
+} __attribute__((packed)) link_status2_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Slot Capabilities 2 Register
+ * Offset: 0x34
+ */
+typedef struct {
+ UINT32 rsvdp : 32; // bits [31:0]
+} __attribute__((packed)) slot_capabilities2_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Slot Control 2 Register
+ * Offset: 0x38
+ */
+typedef struct {
+ UINT16 rsvdp : 16; // bits [15:0]
+} __attribute__((packed)) slot_control2_t;
+
+/*
+ * PCI Express Capability Structure
+ * CAPABILITY_ID = 0x10
+ * Slot Status 2 Register
+ * Offset: 0x3A
+ */
+typedef struct {
+ UINT16 rsvdp : 16; // bits [15:0]
+} __attribute__((packed)) slot_status2_t;
+
+/*
+ * End Of PCIe Capability Registers
+ */
+
+/*
+ * Begin Of AER Registers
+ */
+
+/*
+ * PCI Express Advanced Error Reporting Capability Structure
+ * CAPABILITY_ID = 0x01
+ * AER Capability Header
+ * Offset: 0x0
+ */
+typedef struct {
+ UINT16 capability_id : 16; // bits [15:0]
+ UINT16 capability_version : 4; // bits [19:16]
+ UINT16 next_capability_offset : 12; // bits [31:20]
+} __attribute__((packed)) capability_header_t;
+
+/*
+ * PCI Express Advanced Error Reporting Capability Structure
+ * CAPABILITY_ID = 0x01
+ * Uncorrectable Error Status Register
+ * Offset: 0x4
+ */
+typedef struct {
+ UINT32 undefined : 1; // bits [0]
+ UINT32 rsvdz1 : 3; // bits [3:1]
+ UINT32 data_link_protocol_error_status : 1; // bit [4]
+ UINT32 surprise_down_error_status : 1; // bit [5]
+ UINT32 rsvdz2 : 6; // bits [11:6]
+ UINT32 poisoned_tlp_received : 1; // bit [12]
+ UINT32 flow_control_protocol_error_status : 1; // bit [13]
+ UINT32 completion_timeout_status : 1; // bit [14]
+ UINT32 completer_abort_status : 1; // bit [15]
+ UINT32 unexpected_completion_status : 1; // bit [16]
+ UINT32 receiver_overflow_status : 1; // bit [17]
+ UINT32 malformed_tlp_status : 1; // bit [18]
+ UINT32 ecrc_error_status : 1; // bit [19]
+ UINT32 unsupported_request_error_status : 1; // bit [20]
+ UINT32 acs_violation_status : 1; // bit [21]
+ UINT32 uncorrectable_internal_error_status : 1; // bit [22]
+ UINT32 mc_blocked_tlp_status : 1; // bit [23]
+ UINT32 atomicop_egress_blocked_status : 1; // bit [24]
+ UINT32 tlp_prefix_blocked_error_status : 1; // bit [25]
+ UINT32 poisoned_tlp_egress_blocked_status : 1; // bit [26]
+ UINT32 dmwr_request_egress_blocked_status : 1; // bit [27]
+ UINT32 ide_check_failed_status : 1; // bit [28]
+ UINT32 misrouted_ide_tlp_status : 1; // bit [29]
+ UINT32 pcrc_check_failed_status : 1; // bit [30]
+ UINT32 tlp_translation_egress_blocked_status : 1; // bit [31]
+} __attribute__((packed)) uncorrectable_error_status_t;
+
+/*
+ * PCI Express Advanced Error Reporting Capability Structure
+ * CAPABILITY_ID = 0x01
+ * Uncorrectable Error Mask Register
+ * Offset: 0x8
+ */
+typedef struct {
+ UINT32 undefined : 1; // bits [0]
+ UINT32 rsvdz1 : 3; // bits [3:1]
+ UINT32 data_link_protocol_error_mask : 1; // bit [4]
+ UINT32 surprise_down_error_mask : 1; // bit [5]
+ UINT32 rsvdz2 : 6; // bits [11:6]
+ UINT32 poisoned_tlp_received_mask : 1; // bit [12]
+ UINT32 flow_control_protocol_error_mask : 1; // bit [13]
+ UINT32 completion_timeout_mask : 1; // bit [14]
+ UINT32 completer_abort_mask : 1; // bit [15]
+ UINT32 unexpected_completion_mask : 1; // bit [16]
+ UINT32 receiver_overflow_mask : 1; // bit [17]
+ UINT32 malformed_tlp_mask : 1; // bit [18]
+ UINT32 ecrc_error_mask : 1; // bit [19]
+ UINT32 unsupported_request_error_mask : 1; // bit [20]
+ UINT32 acs_violation_mask : 1; // bit [21]
+ UINT32 uncorrectable_internal_error_mask : 1; // bit [22]
+ UINT32 mc_blocked_tlp_mask : 1; // bit [23]
+ UINT32 atomicop_egress_blocked_mask : 1; // bit [24]
+ UINT32 tlp_prefix_blocked_error_mask : 1; // bit [25]
+ UINT32 poisoned_tlp_egress_blocked_mask : 1; // bit [26]
+ UINT32 dmwr_request_egress_blocked_mask : 1; // bit [27]
+ UINT32 ide_check_failed_mask : 1; // bit [28]
+ UINT32 misrouted_ide_tlp_mask : 1; // bit [29]
+ UINT32 pcrc_check_failed_mask : 1; // bit [30]
+ UINT32 tlp_translation_egress_blocked_mask : 1; // bit [31]
+} __attribute__((packed)) uncorrectable_error_mask_t;
+
+static const char *severity_dict[] = {
+ "NonFatal", // 0x0
+ "Fatal", // 0x1
+};
+
+static const size_t severity_dict_size =
+ sizeof(severity_dict) / sizeof(severity_dict[0]);
+
+static const char *supported_dict[] = {
+ "NotSupported", // 0x0
+ "Supported", // 0x1
+};
+
+static const size_t supported_dict_size =
+ sizeof(severity_dict) / sizeof(severity_dict[0]);
+
+static const char *enabled_dict[] = {
+ "Disabled", // 0x0
+ "Enabled", // 0x1
+};
+
+static const size_t enabled_dict_size =
+ sizeof(enabled_dict) / sizeof(enabled_dict[0]);
+
+static const char *passing_dict[] = {
+ "Failed", // 0x0
+ "Passing", // 0x1
+};
+
+static const size_t passing_dict_size =
+ sizeof(passing_dict) / sizeof(passing_dict[0]);
+
+/*
+ * PCI Express Advanced Error Reporting Capability Structure
+ * CAPABILITY_ID = 0x01
+ * Uncorrectable Error Severity Register
+ * Offset: 0xC
+ */
+typedef struct {
+ UINT32 undefined : 1; // bits [0]
+ UINT32 rsvdz1 : 3; // bits [3:1]
+ UINT32 data_link_protocol_error_severity : 1; // bit [4]
+ UINT32 surprise_down_error_severity : 1; // bit [5]
+ UINT32 rsvdz2 : 6; // bits [11:6]
+ UINT32 poisoned_tlp_received_severity : 1; // bit [12]
+ UINT32 flow_control_protocol_error_severity : 1; // bit [13]
+ UINT32 completion_timeout_severity : 1; // bit [14]
+ UINT32 completer_abort_severity : 1; // bit [15]
+ UINT32 unexpected_completion_severity : 1; // bit [16]
+ UINT32 receiver_overflow_severity : 1; // bit [17]
+ UINT32 malformed_tlp_severity : 1; // bit [18]
+ UINT32 ecrc_error_severity : 1; // bit [19]
+ UINT32 unsupported_request_error_severity : 1; // bit [20]
+ UINT32 acs_violation_severity : 1; // bit [21]
+ UINT32 uncorrectable_internal_error_severity : 1; // bit [22]
+ UINT32 mc_blocked_tlp_severity : 1; // bit [23]
+ UINT32 atomicop_egress_blocked_severity : 1; // bit [24]
+ UINT32 tlp_prefix_blocked_error_severity : 1; // bit [25]
+ UINT32 poisoned_tlp_egress_blocked_severity : 1; // bit [26]
+ UINT32 dmwr_request_egress_blocked_severity : 1; // bit [27]
+ UINT32 ide_check_failed_severity : 1; // bit [28]
+ UINT32 misrouted_ide_tlp_severity : 1; // bit [29]
+ UINT32 pcrc_check_failed_severity : 1; // bit [30]
+ UINT32 tlp_translation_egress_blocked_severity : 1; // bit [31]
+} __attribute__((packed)) uncorrectable_error_severity_t;
+
+/*
+ * PCI Express Advanced Error Reporting Capability Structure
+ * CAPABILITY_ID = 0x01
+ * Correctable Error Status Register
+ * Offset: 0x10
+ */
+typedef struct {
+ UINT32 receiver_error_status : 1; // bit [0]
+ UINT32 rsvdz1 : 5; // bits [5:1]
+ UINT32 bad_tlp_status : 1; // bit [6]
+ UINT32 bad_dllp_status : 1; // bit [7]
+ UINT32 replay_num_rollover_status : 1; // bit [8]
+ UINT32 rsvdz2 : 3; // bits [11:9]
+ UINT32 replay_timer_timeout_status : 1; // bit [12]
+ UINT32 advisory_non_fatal_error_status : 1; // bit [13]
+ UINT32 corrected_internal_error_status : 1; // bit [14]
+ UINT32 header_log_overflow_status : 1; // bit [15]
+ UINT32 rsvdz3 : 16; // bits [31:16]
+} __attribute__((packed)) correctable_error_status_t;
+
+/*
+ * PCI Express Advanced Error Reporting Capability Structure
+ * CAPABILITY_ID = 0x01
+ * Correctable Error Mask Register
+ * Offset: 0x14
+ */
+typedef struct {
+ UINT32 receiver_error_mask : 1; // bit [0]
+ UINT32 rsvdz1 : 5; // bits [5:1]
+ UINT32 bad_tlp_mask : 1; // bit [6]
+ UINT32 bad_dllp_mask : 1; // bit [7]
+ UINT32 replay_num_rollover_mask : 1; // bit [8]
+ UINT32 rsvdz2 : 3; // bits [11:9]
+ UINT32 replay_timer_timeout_mask : 1; // bit [12]
+ UINT32 advisory_non_fatal_error_mask : 1; // bit [13]
+ UINT32 corrected_internal_error_mask : 1; // bit [14]
+ UINT32 header_log_overflow_mask : 1; // bit [15]
+ UINT32 rsvdz3 : 16; // bits [31:16]
+} __attribute__((packed)) correctable_error_mask_t;
+
+/*
+ * PCI Express Advanced Error Reporting Capability Structure
+ * CAPABILITY_ID = 0x01
+ * Advanced Error Capabilities and Control Register
+ * Offset: 0x18
+ */
+typedef struct {
+ UINT32 first_error_pointer : 5; // bits [4:0]
+ UINT32 ecrc_generation_capable : 1; // bit [5]
+ UINT32 ecrc_generation_enable : 1; // bit [6]
+ UINT32 ecrc_check_capable : 1; // bit [7]
+ UINT32 ecrc_check_enable : 1; // bit [8]
+ UINT32 multiple_header_recording_capable : 1; // bit [9]
+ UINT32 multiple_header_recording_enable : 1; // bit [10]
+ UINT32 tlp_prefix_log_present : 1; // bit [11]
+ UINT32 completion_timeout_prefix_header_log_capable : 1; // bit [12]
+ UINT32 header_log_size : 5; // bits [17:13]
+ UINT32 logged_tlp_was_flit_mode : 1; // bit [18]
+ UINT32 logged_tlp_size : 5; // bits [23:19]
+ UINT32 rsvdp : 8; // bits [31:24]
+} __attribute__((packed)) advanced_error_capabilities_and_control_t;
+
+/*
+ * PCI Express Advanced Error Reporting Capability Structure
+ * CAPABILITY_ID = 0x01
+ * Root Error Command Register
+ * Offset: 0x2C
+ */
+typedef struct {
+ UINT32 correctable_error_reporting_enable : 1; // bit [0]
+ UINT32 non_fatal_error_reporting_enable : 1; // bit [1]
+ UINT32 fatal_error_reporting_enable : 1; // bit [2]
+ UINT32 rsvdp : 29; // bits [31:3]
+} __attribute__((packed)) root_error_command_t;
+
+/*
+ * PCI Express Advanced Error Reporting Capability Structure
+ * CAPABILITY_ID = 0x01
+ * Root Error Status Register
+ * Offset: 0x30
+ */
+typedef struct {
+ UINT32 err_cor_received : 1; // bit [0]
+ UINT32 multiple_err_cor_received : 1; // bit [1]
+ UINT32 err_fatal_nonfatal_received : 1; // bit [2]
+ UINT32 multiple_err_fatal_nonfatal_received : 1; // bit [3]
+ UINT32 first_uncorrectable_fatal : 1; // bit [4]
+ UINT32 non_fatal_error_messages_received : 1; // bit [5]
+ UINT32 fatal_error_messages_received : 1; // bit [6]
+ UINT32 err_cor_subclass : 2; // bit [8:7]
+ UINT32 rsvdz : 16; // bit [9:26]
+ UINT32 advanced_error_interrupt_message_number : 5; // bits [31:27]
+} __attribute__((packed)) root_error_status_t;
+
+/*
+ * PCI Express Advanced Error Reporting Capability Structure
+ * CAPABILITY_ID = 0x01
+ * Error Source Identification Register
+ * Offset: 0x34
+ */
+typedef struct {
+ UINT32 err_cor_source_identification : 16; // bits [15:0]
+ UINT32 err_fatal_nonfatal_source_identification : 16; // bits [31:16]
+} __attribute__((packed)) error_source_id_t;
+
+typedef struct {
+ pcie_capability_header_t pcie_capability_header;
+ pcie_capabilities_t pcie_capabilities;
+ device_capabilities_t device_capabilities;
+ device_control_t device_control;
+ device_status_t device_status;
+ link_capabilities_t link_capabilities;
+ link_control_t link_control;
+ link_status_t link_status;
+ slot_capabilities_t slot_capabilities;
+ slot_control_t slot_control;
+ slot_status_t slot_status;
+ root_control_t root_control;
+ root_capabilities_t root_capabilities;
+ root_status_t root_status;
+ // "2" postfixed only valid when pcie_capabilities_fields.cap_version >= 2
+ device_capabilities2_t device_capabilities2;
+ device_control2_t device_control2;
+ device_status2_t device_status2;
+ link_capabilities2_t link_capabilities2;
+ link_control2_t link_control2;
+ link_status2_t link_status2;
+ slot_capabilities2_t slot_capabilities2;
+ slot_control2_t slot_control2;
+ slot_status2_t slot_status2;
+} __attribute__((packed)) capability_registers;
+
+typedef struct {
+ capability_header_t capability_header;
+ uncorrectable_error_status_t uncorrectable_error_status;
+ uncorrectable_error_mask_t uncorrectable_error_mask;
+ uncorrectable_error_severity_t uncorrectable_error_severity;
+ correctable_error_status_t correctable_error_status;
+ correctable_error_mask_t correctable_error_mask;
+ advanced_error_capabilities_and_control_t
+ advanced_error_capabilities_and_control;
+ UINT32 tlp_header[4];
+ root_error_command_t root_error_command;
+ root_error_status_t root_error_status;
+ error_source_id_t error_source_id;
+ union {
+ struct { // Non-flit mode TLP prefix logs
+ UINT32 log[4];
+ } non_flit_logs;
+ struct { // Flit mode TLP header logs
+ UINT32 header[10];
+ } flit_tlp_header_logs;
+ } tlp_pfrefix;
+} __attribute__((packed)) aer_info_registers;
+
#ifdef __cplusplus
}
#endif
diff --git a/sections/cper-section-pcie.c b/sections/cper-section-pcie.c
index ee8a1d9..508b05f 100644
--- a/sections/cper-section-pcie.c
+++ b/sections/cper-section-pcie.c
@@ -13,16 +13,8 @@
#include <libcper/sections/cper-section-pcie.h>
#include <libcper/log.h>
-struct aer_info_registers {
- UINT32 pcie_capability_header;
- UINT32 uncorrectable_error_status;
- UINT32 uncorrectable_error_mask;
- UINT32 uncorrectable_error_severity;
- UINT32 correctable_error_status;
- UINT32 correctable_error_mask;
- UINT32 aer_capabilites_control;
- UINT32 tlp_header_log[4];
-};
+json_object *pcie_capability_to_ir(EFI_PCIE_ERROR_DATA *pcie_error);
+json_object *pcie_aer_to_ir(EFI_PCIE_ERROR_DATA *pcie_error);
//Converts a single PCIe CPER section into JSON IR.
json_object *cper_section_pcie_to_ir(const UINT8 *section, UINT32 size)
@@ -142,113 +134,1081 @@
//Capability structure.
//The PCIe capability structure provided here could either be PCIe 1.1 Capability Structure
- //(36-byte, padded to 60 bytes) or PCIe 2.0 Capability Structure (60-byte). There does not seem
- //to be a way to differentiate these, so this is left as a b64 dump.
- int32_t encoded_len = 0;
- char *encoded = NULL;
+ //(36-byte, padded to 60 bytes) or PCIe 2.0 Capability Structure (60-byte).
+ //Check the PCIe Capabilities Registers (offset 0x2) to determine the capability version.
if (isvalid_prop_to_ir(&ui64Type, 6)) {
- char *encoded =
- base64_encode((UINT8 *)pcie_error->Capability.PcieCap,
- 60, &encoded_len);
- if (encoded == NULL) {
- cper_print_log(
- "Failed to allocate encode output buffer. \n");
- } else {
- json_object *capability = json_object_new_object();
- json_object_object_add(capability, "data",
- json_object_new_string_len(
- encoded, encoded_len));
- free(encoded);
-
- json_object_object_add(
- section_ir, "capabilityStructure", capability);
- }
+ json_object_object_add(section_ir, "capabilityStructure",
+ pcie_capability_to_ir(pcie_error));
}
//AER information.
- encoded_len = 0;
- encoded = NULL;
if (isvalid_prop_to_ir(&ui64Type, 7)) {
- json_object *aer_capability_ir = json_object_new_object();
-
- encoded = base64_encode((UINT8 *)pcie_error->AerInfo.PcieAer,
- 96, &encoded_len);
- if (encoded == NULL) {
- cper_print_log(
- "Failed to allocate encode output buffer. \n");
- } else {
- json_object_object_add(aer_capability_ir, "data",
- json_object_new_string_len(
- encoded, encoded_len));
- free(encoded);
- }
-
- struct aer_info_registers *aer_decode;
- aer_decode = (struct aer_info_registers *)&pcie_error->AerInfo
- .PcieAer;
- json_object_object_add(
- aer_capability_ir, "capability_header",
- json_object_new_uint64(
- aer_decode->pcie_capability_header));
- json_object_object_add(
- aer_capability_ir, "uncorrectable_error_status",
- json_object_new_uint64(
- aer_decode->uncorrectable_error_status));
-
- snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN,
- "0x%08" PRIX32,
- aer_decode->uncorrectable_error_status);
- json_object_object_add(aer_capability_ir,
- "uncorrectable_error_status_hex",
- json_object_new_string(hexstring_buf));
-
- json_object_object_add(
- aer_capability_ir, "uncorrectable_error_mask",
- json_object_new_uint64(
- aer_decode->uncorrectable_error_mask));
- json_object_object_add(
- aer_capability_ir, "uncorrectable_error_severity",
- json_object_new_uint64(
- aer_decode->uncorrectable_error_severity));
- json_object_object_add(
- aer_capability_ir, "correctable_error_status",
- json_object_new_uint64(
- aer_decode->correctable_error_status));
-
- int len = snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN,
- "0x%08" PRIX32,
- aer_decode->correctable_error_status);
- json_object_object_add(
- aer_capability_ir, "correctable_error_status_hex",
- json_object_new_string_len(hexstring_buf, len));
-
- json_object_object_add(
- aer_capability_ir, "correctable_error_mask",
- json_object_new_uint64(
- aer_decode->correctable_error_mask));
- json_object_object_add(
- aer_capability_ir, "capabilites_control",
- json_object_new_uint64(
- aer_decode->aer_capabilites_control));
- json_object_object_add(
- aer_capability_ir, "tlp_header_0",
- json_object_new_uint64(aer_decode->tlp_header_log[0]));
- json_object_object_add(
- aer_capability_ir, "tlp_header_1",
- json_object_new_uint64(aer_decode->tlp_header_log[1]));
- json_object_object_add(
- aer_capability_ir, "tlp_header_2",
- json_object_new_uint64(aer_decode->tlp_header_log[2]));
- json_object_object_add(
- aer_capability_ir, "tlp_header_3",
- json_object_new_uint64(aer_decode->tlp_header_log[3]));
json_object_object_add(section_ir, "aerInfo",
- aer_capability_ir);
+ pcie_aer_to_ir(pcie_error));
}
return section_ir;
}
+//Converts PCIe Capability Structure section into JSON IR.
+json_object *pcie_capability_to_ir(EFI_PCIE_ERROR_DATA *pcie_error)
+{
+ int32_t encoded_len = 0;
+ char *encoded = NULL;
+ json_object *pcie_capability_ir = json_object_new_object();
+
+ encoded = base64_encode((UINT8 *)pcie_error->Capability.PcieCap, 60,
+ &encoded_len);
+ if (encoded == NULL) {
+ printf("Failed to allocate encode output buffer. \n");
+ } else {
+ json_object_object_add(pcie_capability_ir, "data",
+ json_object_new_string_len(encoded,
+ encoded_len));
+ free(encoded);
+ }
+
+ json_object *fields_ir;
+ capability_registers *cap_decode;
+ cap_decode = (capability_registers *)&pcie_error->Capability.PcieCap;
+
+ /*
+ * PCI Express Capability Structure Header
+ * Offset: 0x0
+ */
+ fields_ir = json_object_new_object();
+ pcie_capability_header_t *pcie_cap_header =
+ &cap_decode->pcie_capability_header;
+ add_dict(fields_ir, "capability_id", pcie_cap_header->capability_id,
+ NULL, 0);
+ add_int(fields_ir, "next_capability_pointer",
+ pcie_cap_header->next_capability_pointer);
+ json_object_object_add(pcie_capability_ir, "pcie_capability_header",
+ fields_ir);
+
+ /*
+ * PCI Express Capabilities Register
+ * Offset: 0x2
+ */
+ fields_ir = json_object_new_object();
+ pcie_capabilities_t *pcie_cap = &cap_decode->pcie_capabilities;
+ add_int(fields_ir, "capability_version", pcie_cap->capability_version);
+ add_dict(fields_ir, "device_port_type", pcie_cap->device_port_type,
+ device_port_type_dict, device_port_type_dict_size);
+ add_bool(fields_ir, "slot_implemented", pcie_cap->slot_implemented);
+ add_int(fields_ir, "interrupt_message_number",
+ pcie_cap->interrupt_message_number);
+ //add_int(fields_ir, "undefined", pcie_cap->undefined);
+ add_bool_enum(fields_ir, "flit_mode_supported", supported_dict,
+ pcie_cap->flit_mode_supported);
+ json_object_object_add(pcie_capability_ir, "pcie_capabilities",
+ fields_ir);
+
+ /*
+ * Device Capabilities Register
+ * Offset: 0x4
+ */
+ fields_ir = json_object_new_object();
+ add_int(fields_ir, "max_payload_size_supported",
+ cap_decode->device_capabilities.max_payload_size_supported);
+ add_bool_enum(
+ fields_ir, "phantom_functions_supported", supported_dict,
+ cap_decode->device_capabilities.phantom_functions_supported);
+ add_bool_enum(
+ fields_ir, "extended_tag_field_supported", supported_dict,
+ cap_decode->device_capabilities.extended_tag_field_supported);
+ add_dict(
+ fields_ir, "endpoint_l0s_acceptable_latency",
+ cap_decode->device_capabilities.endpoint_l0s_acceptable_latency,
+ NULL, 0);
+ add_dict(fields_ir, "endpoint_l1_acceptable_latency",
+ cap_decode->device_capabilities.endpoint_l1_acceptable_latency,
+ NULL, 0);
+ //add_int(fields_ir, "undefined",
+ // cap_decode->device_capabilities.undefined);
+ add_bool(fields_ir, "role_based_error_reporting",
+ cap_decode->device_capabilities.role_based_error_reporting);
+ add_bool(fields_ir, "err_cor_subclass_capable",
+ cap_decode->device_capabilities.err_cor_subclass_capable);
+ add_int(fields_ir, "rx_mps_fixed",
+ cap_decode->device_capabilities.rx_mps_fixed);
+ add_int(fields_ir, "captured_slot_power_limit_value",
+ cap_decode->device_capabilities.captured_slot_power_limit_value);
+ add_int(fields_ir, "captured_slot_power_limit_scale",
+ cap_decode->device_capabilities.captured_slot_power_limit_scale);
+ add_bool_enum(
+ fields_ir, "function_level_reset_capability_supported",
+ supported_dict,
+ cap_decode->device_capabilities.function_level_reset_capability);
+ add_bool_enum(fields_ir, "mixed_mps_supported", supported_dict,
+ cap_decode->device_capabilities.mixed_mps_supported);
+ add_bool_enum(fields_ir, "tee_io_supported", supported_dict,
+ cap_decode->device_capabilities.tee_io_supported);
+ //add_int(fields_ir, "rsvdp", cap_decode->device_capabilities.rsvdp);
+ json_object_object_add(pcie_capability_ir, "device_capabilities",
+ fields_ir);
+
+ /*
+ * Device Control Register
+ * Offset: 0x8
+ */
+ fields_ir = json_object_new_object();
+ add_bool_enum(
+ fields_ir, "correctable_error_reporting_enable", enabled_dict,
+ cap_decode->device_control.correctable_error_reporting_enable);
+ add_bool_enum(
+ fields_ir, "non_fatal_error_reporting_enable", enabled_dict,
+ cap_decode->device_control.non_fatal_error_reporting_enable);
+ add_bool_enum(fields_ir, "fatal_error_reporting_enable", enabled_dict,
+ cap_decode->device_control.fatal_error_reporting_enable);
+ add_bool_enum(
+ fields_ir, "unsupported_request_reporting_enabled",
+ enabled_dict,
+ cap_decode->device_control.unsupported_request_reporting_enable);
+ add_bool_enum(fields_ir, "relaxed_ordering_enable", enabled_dict,
+ cap_decode->device_control.enable_relaxed_ordering);
+ add_int(fields_ir, "max_payload_size",
+ cap_decode->device_control.max_payload_size);
+ add_bool_enum(fields_ir, "extended_tag_field_enable", enabled_dict,
+ cap_decode->device_control.extended_tag_field_enable);
+ add_bool_enum(fields_ir, "phantom_functions_enable", enabled_dict,
+ cap_decode->device_control.phantom_functions_enable);
+ add_bool_enum(fields_ir, "aux_power_pm_enable", enabled_dict,
+ cap_decode->device_control.aux_power_pm_enable);
+ add_int(fields_ir, "enable_no_snoop",
+ cap_decode->device_control.enable_no_snoop);
+ add_int(fields_ir, "max_read_request_size",
+ cap_decode->device_control.max_read_request_size);
+ add_bool(fields_ir, "function_level_reset",
+ cap_decode->device_control.function_level_reset);
+ json_object_object_add(pcie_capability_ir, "device_control", fields_ir);
+
+ /*
+ * Device Status Register
+ * Offset: 0xA
+ */
+ fields_ir = json_object_new_object();
+ add_bool(fields_ir, "correctable_error_detected",
+ cap_decode->device_status.correctable_error_detected);
+ add_bool(fields_ir, "non_fatal_error_detected",
+ cap_decode->device_status.non_fatal_error_detected);
+ add_bool(fields_ir, "fatal_error_detected",
+ cap_decode->device_status.fatal_error_detected);
+ add_bool(fields_ir, "unsupported_request_detected",
+ cap_decode->device_status.unsupported_request_detected);
+ add_bool(fields_ir, "aux_power_detected",
+ cap_decode->device_status.aux_power_detected);
+ add_bool(fields_ir, "transactions_pending",
+ cap_decode->device_status.transactions_pending);
+ add_int(fields_ir, "emergency_power_reduction",
+ cap_decode->device_status.emergency_power_reduction);
+ //add_int(fields_ir, "rsvdz", cap_decode->device_status.rsvdz);
+ json_object_object_add(pcie_capability_ir, "device_status", fields_ir);
+
+ /*
+ * Link Capabilities Register
+ * Offset: 0xC
+ */
+ fields_ir = json_object_new_object();
+ add_int(fields_ir, "max_link_speed",
+ cap_decode->link_capabilities.max_link_speed);
+ add_int(fields_ir, "maximum_link_width",
+ cap_decode->link_capabilities.maximum_link_width);
+ add_int(fields_ir, "aspm_support",
+ cap_decode->link_capabilities.aspm_support);
+ add_int(fields_ir, "l0s_exit_latency",
+ cap_decode->link_capabilities.l0s_exit_latency);
+ add_int(fields_ir, "l1_exit_latency",
+ cap_decode->link_capabilities.l1_exit_latency);
+ add_bool(fields_ir, "clock_power_management",
+ cap_decode->link_capabilities.clock_power_management);
+ add_bool(fields_ir, "surprise_down_error_reporting_capable",
+ cap_decode->link_capabilities
+ .surprise_down_error_reporting_capable);
+ add_bool(fields_ir, "data_link_layer_link_active_reporting_capable",
+ cap_decode->link_capabilities
+ .data_link_layer_link_active_reporting_capable);
+ add_bool(fields_ir, "link_bandwidth_notification_capability",
+ cap_decode->link_capabilities
+ .link_bandwidth_notification_capability);
+ add_bool(fields_ir, "aspm_optionality_compliance",
+ cap_decode->link_capabilities.aspm_optionality_compliance);
+ //add_int(fields_ir, "rsvdp", cap_decode->link_capabilities.rsvdp);
+ add_int(fields_ir, "port_number",
+ cap_decode->link_capabilities.port_number);
+ json_object_object_add(pcie_capability_ir, "link_capabilities",
+ fields_ir);
+
+ /*
+ * Link Control Register
+ * Offset: 0x10
+ */
+ fields_ir = json_object_new_object();
+ add_int(fields_ir, "aspm_control",
+ cap_decode->link_control.aspm_control);
+ add_bool(fields_ir, "ptm_prop_delay_adaptation_interpretation",
+ cap_decode->link_control
+ .ptm_prop_delay_adaptation_interpretation);
+ //add_bool(fields_ir, "read_completion_boundary",
+ // cap_decode->link_control.read_completion_boundary);
+ add_int(fields_ir, "link_disable",
+ cap_decode->link_control.link_disable);
+ add_int(fields_ir, "retrain_link",
+ cap_decode->link_control.retrain_link);
+ //add_bool(fields_ir, "common_clock_configuration",
+ // cap_decode->link_control.common_clock_configuration);
+ add_int(fields_ir, "extended_synch",
+ cap_decode->link_control.extended_synch);
+ //add_bool(fields_ir, "enable_clock_power_management",
+ // cap_decode->link_control.enable_clock_power_management);
+ //add_bool(fields_ir, "hardware_autonomous_width_disable",
+ // cap_decode->link_control.hardware_autonomous_width_disable);
+ //add_bool(fields_ir, "link_bandwidth_management_interrupt_enable",
+ // cap_decode->link_control
+ // .link_bandwidth_management_interrupt_enable);
+ //add_bool(fields_ir, "link_autonomous_bandwidth_interrupt_enable",
+ // cap_decode->link_control
+ // .link_autonomous_bandwidth_interrupt_enable);
+ add_int(fields_ir, "sris_clocking",
+ cap_decode->link_control.sris_clocking);
+ add_int(fields_ir, "flit_mode_disable",
+ cap_decode->link_control.flit_mode_disable);
+ //add_bool(fields_ir, "drs_signaling_control",
+ // cap_decode->link_control.drs_signaling_control);
+ json_object_object_add(pcie_capability_ir, "link_control", fields_ir);
+
+ /*
+ * Link Status Register
+ * Offset: 0x12
+ */
+ fields_ir = json_object_new_object();
+ add_int(fields_ir, "current_link_speed",
+ cap_decode->link_status.current_link_speed);
+ add_int(fields_ir, "negotiated_link_width",
+ cap_decode->link_status.negotiated_link_width);
+ //add_int(fields_ir, "undefined", cap_decode->link_status.undefined);
+ add_int(fields_ir, "link_training",
+ cap_decode->link_status.link_training);
+ //add_bool(fields_ir, "slot_clock_configuration",
+ // cap_decode->link_status.slot_clock_configuration);
+ //add_bool(fields_ir, "data_link_layer_link_active",
+ // cap_decode->link_status.data_link_layer_link_active);
+ //add_bool(fields_ir, "link_bandwidth_management_status",
+ // cap_decode->link_status.link_bandwidth_management_status);
+ //add_bool(fields_ir, "link_autonomous_bandwidth_status",
+ // cap_decode->link_status.link_autonomous_bandwidth_status);
+ json_object_object_add(pcie_capability_ir, "link_status", fields_ir);
+
+ /*
+ * Slot Capabilities Register
+ * Offset: 0x14
+ */
+ fields_ir = json_object_new_object();
+ //add_bool(fields_ir, "attention_button_present",
+ // cap_decode->slot_capabilities.attention_button_present);
+ //add_bool(fields_ir, "power_controller_present",
+ // cap_decode->slot_capabilities.power_controller_present);
+ //add_bool(fields_ir, "mrl_sensor_present",
+ // cap_decode->slot_capabilities.mrl_sensor_present);
+ //add_bool(fields_ir, "attention_indicator_present",
+ // cap_decode->slot_capabilities.attention_indicator_present);
+ //add_bool(fields_ir, "power_indicator_present",
+ // cap_decode->slot_capabilities.power_indicator_present);
+ //add_bool(fields_ir, "hot_plug_surprise",
+ // cap_decode->slot_capabilities.hot_plug_surprise);
+ //add_bool(fields_ir, "hot_plug_capable",
+ // cap_decode->slot_capabilities.hot_plug_capable);
+ add_dict(fields_ir, "slot_power_limit_value",
+ cap_decode->slot_capabilities.slot_power_limit_value, NULL, 0);
+ add_int(fields_ir, "slot_power_limit_scale",
+ cap_decode->slot_capabilities.slot_power_limit_scale);
+ //add_bool(fields_ir, "electromechanical_interlock_present",
+ // cap_decode->slot_capabilities
+ // .electromechanical_interlock_present);
+ //add_bool(fields_ir, "no_command_completed_support",
+ // cap_decode->slot_capabilities.no_command_completed_support);
+ add_int(fields_ir, "physical_slot_number",
+ cap_decode->slot_capabilities.physical_slot_number);
+ json_object_object_add(pcie_capability_ir, "slot_capabilities",
+ fields_ir);
+
+ /*
+ * Slot Control Register
+ * Offset: 0x18
+ */
+ fields_ir = json_object_new_object();
+ //add_bool(fields_ir, "attention_button_pressed_enable",
+ // cap_decode->slot_control.attention_button_pressed_enable);
+ //add_bool(fields_ir, "power_fault_detected_enable",
+ // cap_decode->slot_control.power_fault_detected_enable);
+ //add_bool(fields_ir, "mrl_sensor_changed_enable",
+ // cap_decode->slot_control.mrl_sensor_changed_enable);
+ //add_bool(fields_ir, "presence_detect_changed_enable",
+ // cap_decode->slot_control.presence_detect_changed_enable);
+ //add_bool(fields_ir, "command_completed_interrupt_enable",
+ // cap_decode->slot_control.command_completed_interrupt_enable);
+ //add_bool(fields_ir, "hot_plug_interrupt_enable",
+ // cap_decode->slot_control.hot_plug_interrupt_enable);
+ add_int(fields_ir, "attention_indicator_control",
+ cap_decode->slot_control.attention_indicator_control);
+ add_int(fields_ir, "power_indicator_control",
+ cap_decode->slot_control.power_indicator_control);
+ //add_bool(fields_ir, "power_controller_control",
+ // cap_decode->slot_control.power_controller_control);
+ //add_bool(fields_ir, "electromechanical_interlock_control",
+ // cap_decode->slot_control.electromechanical_interlock_control);
+ //add_bool(fields_ir, "data_link_layer_state_changed_enable",
+ // cap_decode->slot_control.data_link_layer_state_changed_enable);
+ //add_bool(fields_ir, "auto_slot_power_limit_disable",
+ // cap_decode->slot_control.auto_slot_power_limit_disable);
+ //add_bool(fields_ir, "in_band_pd_disable",
+ // cap_decode->slot_control.in_band_pd_disable);
+ add_int(fields_ir, "rsvdp", cap_decode->slot_control.rsvdp);
+ json_object_object_add(pcie_capability_ir, "slot_control", fields_ir);
+
+ /*
+ * Slot Status Register
+ * Offset: 0x1A
+ */
+ fields_ir = json_object_new_object();
+ //add_bool(fields_ir, "attention_button_pressed",
+ // cap_decode->slot_status.attention_button_pressed);
+ //add_bool(fields_ir, "power_fault_detected",
+ // cap_decode->slot_status.power_fault_detected);
+ add_int(fields_ir, "mrl_sensor_changed",
+ cap_decode->slot_status.mrl_sensor_changed);
+ //add_bool(fields_ir, "presence_detect_changed",
+ // cap_decode->slot_status.presence_detect_changed);
+ add_int(fields_ir, "command_completed",
+ cap_decode->slot_status.command_completed);
+ add_int(fields_ir, "mrl_sensor_state",
+ cap_decode->slot_status.mrl_sensor_state);
+ //add_bool(fields_ir, "presence_detect_state",
+ // cap_decode->slot_status.presence_detect_state);
+ //add_bool(fields_ir, "electromechanical_interlock_status",
+ // cap_decode->slot_status.electromechanical_interlock_status);
+ //add_bool(fields_ir, "data_link_layer_state_changed",
+ // cap_decode->slot_status.data_link_layer_state_changed);
+ //add_int(fields_ir, "rsvdz", cap_decode->slot_status.rsvdz);
+ json_object_object_add(pcie_capability_ir, "slot_status", fields_ir);
+
+ /*
+ * Root Control Register
+ * Offset: 0x1C
+ */
+ fields_ir = json_object_new_object();
+ //add_bool(fields_ir, "system_error_on_correctable_error_enable",
+ // cap_decode->root_control
+ // .system_error_on_correctable_error_enable);
+ //add_bool(
+ // fields_ir, "system_error_on_non_fatal_error_enable",
+ // cap_decode->root_control.system_error_on_non_fatal_error_enable);
+ //add_bool(fields_ir, "system_error_on_fatal_error_enable",
+ // cap_decode->root_control.system_error_on_fatal_error_enable);
+ //add_bool(fields_ir, "pme_interrupt_enable",
+ // cap_decode->root_control.pme_interrupt_enable);
+ //add_bool(fields_ir, "configuration_rrs_software_visibility_enable",
+ // cap_decode->root_control
+ // .configuration_rrs_software_visibility_enable);
+ //add_bool(fields_ir, "no_nfm_subtree_below_this_root_port",
+ // cap_decode->root_control.no_nfm_subtree_below_this_root_port);
+ //add_int(fields_ir, "rsvdp", cap_decode->root_control.rsvdp);
+ json_object_object_add(pcie_capability_ir, "root_control", fields_ir);
+
+ /*
+ * Root Capabilities Register
+ * Offset: 0x1E
+ */
+ fields_ir = json_object_new_object();
+ //add_bool(fields_ir, "configuraton_rrs_software_visibility",
+ // cap_decode->root_capabilities
+ // .configuraton_rrs_software_visibility);
+ //add_int(fields_ir, "rsvdp", cap_decode->root_capabilities.rsvdp);
+ json_object_object_add(pcie_capability_ir, "root_capabilities",
+ fields_ir);
+
+ /*
+ * Root Status Register
+ * Offset: 0x20
+ */
+ fields_ir = json_object_new_object();
+ add_int(fields_ir, "pme_requester_id",
+ cap_decode->root_status.pme_requester_id);
+ add_int(fields_ir, "pme_status", cap_decode->root_status.pme_status);
+ add_int(fields_ir, "pme_pending", cap_decode->root_status.pme_pending);
+ //add_int(fields_ir, "rsvdp", cap_decode->root_status.rsvdp);
+ json_object_object_add(pcie_capability_ir, "root_status", fields_ir);
+
+ if (cap_decode->pcie_capabilities.capability_version < 2) {
+ return pcie_capability_ir;
+ }
+
+ /*
+ * Device Capabilities 2 Register
+ * Offset: 0x24
+ */
+ fields_ir = json_object_new_object();
+ add_int(fields_ir, "completion_timeout_ranges_supported",
+ cap_decode->device_capabilities2
+ .completion_timeout_ranges_supported);
+ add_bool_enum(fields_ir, "completion_timeout_disable_supported",
+ supported_dict,
+ cap_decode->device_capabilities2
+ .completion_timeout_disable_supported);
+ add_bool_enum(
+ fields_ir, "ari_forwarding_supported", supported_dict,
+ cap_decode->device_capabilities2.ari_forwarding_supported);
+ add_bool_enum(
+ fields_ir, "atomic_op_routing_supported", supported_dict,
+ cap_decode->device_capabilities2.atomic_op_routing_supported);
+ add_bool_enum(fields_ir, "_32_bit_atomicop_completer_supported",
+ supported_dict,
+ cap_decode->device_capabilities2
+ ._32_bit_atomicop_completer_supported);
+ add_bool_enum(fields_ir, "_64_bit_atomicop_completer_supported",
+ supported_dict,
+ cap_decode->device_capabilities2
+ ._64_bit_atomicop_completer_supported);
+ add_bool_enum(fields_ir, "_128_bit_cas_completer_supported",
+ supported_dict,
+ cap_decode->device_capabilities2
+ ._128_bit_cas_completer_supported);
+ add_bool_enum(
+ fields_ir, "no_ro_enabled_pr_pr_passing", passing_dict,
+ cap_decode->device_capabilities2.no_ro_enabled_pr_pr_passing);
+ add_bool_enum(fields_ir, "ltr_mechanism_supported", supported_dict,
+ cap_decode->device_capabilities2.ltr_mechanism_supported);
+ add_bool_enum(fields_ir, "tph_completer_supported", supported_dict,
+ cap_decode->device_capabilities2.tph_completer_supported);
+ //add_int(fields_ir, "undefined",
+ // cap_decode->device_capabilities2.undefined);
+ //add_bool(fields_ir, "_10_bit_tag_completer_supported",
+ // cap_decode->device_capabilities2
+ // ._10_bit_tag_completer_supported);
+ //add_bool(fields_ir, "_10_bit_tag_requester_supported",
+ // cap_decode->device_capabilities2
+ // ._10_bit_tag_requester_supported);
+ add_bool_enum(fields_ir, "obff_supported", supported_dict,
+ cap_decode->device_capabilities2.obff_supported);
+ //add_bool(fields_ir, "extended_fmt_field_supported",
+ // cap_decode->device_capabilities2.extended_fmt_field_supported);
+ //add_bool(fields_ir, "end_end_tlp_prefix_supported",
+ // cap_decode->device_capabilities2.end_end_tlp_prefix_supported);
+ add_dict(fields_ir, "max_end_end_tlp_prefixes",
+ cap_decode->device_capabilities2.max_end_end_tlp_prefixes,
+ NULL, 0);
+ add_bool_enum(fields_ir, "emergency_power_reduction_supported",
+ supported_dict,
+ cap_decode->device_capabilities2
+ .emergency_power_reduction_supported);
+ //add_bool(fields_ir, "emergency_power_reduction_init_required",
+ // cap_decode->device_capabilities2
+ // .emergency_power_reduction_init_required);
+ //add_int(fields_ir, "rsvdp", cap_decode->device_capabilities2.rsvdp);
+ //add_bool(fields_ir, "dmwr_completer_supported",
+ // cap_decode->device_capabilities2.dmwr_completer_supported);
+ add_int(fields_ir, "dmwr_lengths_supported",
+ cap_decode->device_capabilities2.dmwr_lengths_supported);
+ //add_bool(fields_ir, "frs_supported",
+ // cap_decode->device_capabilities2.frs_supported);
+ json_object_object_add(pcie_capability_ir, "device_capabilities2",
+ fields_ir);
+
+ /*
+ * Device Control 2 Register
+ * Offset: 0x28
+ */
+ fields_ir = json_object_new_object();
+ add_int(fields_ir, "completion_timeout_value",
+ cap_decode->device_control2.completion_timeout_value);
+ //add_bool(fields_ir, "completion_timeout_disable",
+ // cap_decode->device_control2.completion_timeout_disable);
+ add_bool(fields_ir, "ari_forwarding_enable",
+ cap_decode->device_control2.ari_forwarding_enable);
+ add_bool(fields_ir, "atomicop_requester_enable",
+ cap_decode->device_control2.atomicop_requester_enable);
+ add_bool(fields_ir, "atomicop_egress_blocking",
+ cap_decode->device_control2.atomicop_egress_blocking);
+ add_bool(fields_ir, "ido_request_enable",
+ cap_decode->device_control2.ido_request_enable);
+ add_bool(fields_ir, "ido_completion_enable",
+ cap_decode->device_control2.ido_completion_enable);
+ add_bool(fields_ir, "ltr_mechanism_enable",
+ cap_decode->device_control2.ltr_mechanism_enable);
+ add_bool(fields_ir, "emergency_power_reduction_request",
+ cap_decode->device_control2.emergency_power_reduction_request);
+ add_bool(fields_ir, "10_bit_tag_requester_enable",
+ cap_decode->device_control2._10_bit_tag_requester_enable);
+ add_int(fields_ir, "obff_enable",
+ cap_decode->device_control2.obff_enable);
+ //add_bool(fields_ir, "end_end_tlp_prefix_blocking",
+ // cap_decode->device_control2.end_end_tlp_prefix_blocking);
+ json_object_object_add(pcie_capability_ir, "device_control2",
+ fields_ir);
+
+ /*
+ * Device Status 2 Register
+ * Offset: 0x2A
+ */
+ fields_ir = json_object_new_object();
+ //add_int(fields_ir, "rsvdz", cap_decode->device_status2.rsvdz);
+ json_object_object_add(pcie_capability_ir, "device_status2", fields_ir);
+
+ /*
+ * Link Capabilities 2 Register
+ * Offset: 0x2C
+ */
+ fields_ir = json_object_new_object();
+ //add_int(fields_ir, "rsvdp", cap_decode->link_capabilities2.rsvdp);
+ add_int(fields_ir, "supported_link_speeds",
+ cap_decode->link_capabilities2.supported_link_speeds_register);
+ add_bool_enum(fields_ir, "crosslink_supported", supported_dict,
+ cap_decode->link_capabilities2.crosslink_supported);
+ add_int(fields_ir, "lower_skp_os_generation_supported",
+ cap_decode->link_capabilities2
+ .lower_skp_os_generation_supported);
+ add_int(fields_ir, "lower_skp_os_reception_supported",
+ cap_decode->link_capabilities2.lower_skp_os_reception_supported);
+ add_bool_enum(fields_ir, "retimer_presence_detect_supported",
+ supported_dict,
+ cap_decode->link_capabilities2
+ .retimer_presence_detect_supported);
+ add_bool_enum(fields_ir, "two_retimers_presence_detect_supported",
+ supported_dict,
+ cap_decode->link_capabilities2
+ .two_retimers_presence_detect_supported);
+ //add_int(fields_ir, "reserved", cap_decode->link_capabilities2.reserved);
+ add_bool_enum(fields_ir, "drs_supported", supported_dict,
+ cap_decode->link_capabilities2.drs_supported);
+ json_object_object_add(pcie_capability_ir, "link_capabilities2",
+ fields_ir);
+
+ /*
+ * Link Control 2 Register
+ * Offset: 0x30
+ */
+ fields_ir = json_object_new_object();
+ add_dict(fields_ir, "target_link_speed",
+ cap_decode->link_control2.target_link_speed, NULL, 0);
+ add_bool_enum(fields_ir, "enter_compliance", supported_dict,
+ cap_decode->link_control2.enter_compliance);
+ add_dict(fields_ir, "hardware_autonomous_speed_disable",
+ cap_decode->link_control2.hardware_autonomous_speed_disable,
+ NULL, 0);
+ add_bool(fields_ir, "selectable_de_emphasis",
+ cap_decode->link_control2.selectable_de_emphasis);
+ add_int(fields_ir, "transmit_margin",
+ cap_decode->link_control2.transmit_margin);
+ add_bool(fields_ir, "enter_modified_compliance",
+ cap_decode->link_control2.enter_modified_compliance);
+ add_bool(fields_ir, "compliance_sos",
+ cap_decode->link_control2.compliance_sos);
+ add_int(fields_ir, "compliance_preset_de_emphasis",
+ cap_decode->link_control2.compliance_preset_de_emphasis);
+ json_object_object_add(pcie_capability_ir, "link_control2", fields_ir);
+
+ /*
+ * Link Status 2 Register
+ * Offset: 0x32
+ */
+ fields_ir = json_object_new_object();
+ add_int(fields_ir, "current_de_emphasis_level",
+ cap_decode->link_status2.current_de_emphasis_level);
+ add_bool(fields_ir, "equalization_8gts_complete",
+ cap_decode->link_status2.equalization_8gts_complete);
+ add_bool(fields_ir, "equalization_8gts_phase1_successful",
+ cap_decode->link_status2.equalization_8gts_phase1_successful);
+ add_bool(fields_ir, "equalization_8gts_phase2_successful",
+ cap_decode->link_status2.equalization_8gts_phase2_successful);
+ add_bool(fields_ir, "equalization_8gts_phase3_successful",
+ cap_decode->link_status2.equalization_8gts_phase3_successful);
+ add_bool(fields_ir, "link_equalization_request_8gts",
+ cap_decode->link_status2.link_equalization_request_8gts);
+ add_bool(fields_ir, "retimer_presence_detected",
+ cap_decode->link_status2.retimer_presence_detected);
+ add_bool(fields_ir, "two_retimers_presence_detected",
+ cap_decode->link_status2.two_retimers_presence_detected);
+ add_int(fields_ir, "crosslink_resolution",
+ cap_decode->link_status2.crosslink_resolution);
+ add_int(fields_ir, "flit_mode_status",
+ cap_decode->link_status2.flit_mode_status);
+ //add_int(fields_ir, "rsvdz", cap_decode->link_status2.rsvdz);
+ add_int(fields_ir, "downstream_component_presence",
+ cap_decode->link_status2.downstream_component_presence);
+ add_bool(fields_ir, "drs_message_received",
+ cap_decode->link_status2.drs_message_received);
+ json_object_object_add(pcie_capability_ir, "link_status2", fields_ir);
+
+ /*
+ * Slot Capabilities 2 Register
+ * Offset: 0x34
+ */
+ fields_ir = json_object_new_object();
+ //add_int(fields_ir, "rsvdp", cap_decode->slot_capabilities2.rsvdp);
+ json_object_object_add(pcie_capability_ir, "slot_capabilities2",
+ fields_ir);
+
+ /*
+ * Slot Control 2 Register
+ * Offset: 0x38
+ */
+ fields_ir = json_object_new_object();
+ //add_int(fields_ir, "rsvdp", cap_decode->slot_control2.rsvdp);
+ json_object_object_add(pcie_capability_ir, "slot_control2", fields_ir);
+
+ /*
+ * Slot Status 2 Register
+ * Offset: 0x3A
+ */
+ fields_ir = json_object_new_object();
+ //add_int(fields_ir, "rsvdp", cap_decode->slot_status2.rsvdp);
+ json_object_object_add(pcie_capability_ir, "slot_status2", fields_ir);
+
+ return pcie_capability_ir;
+}
+
+//Converts PCIe Capability Structure section into JSON IR.
+json_object *pcie_aer_to_ir(EFI_PCIE_ERROR_DATA *pcie_error)
+{
+ int32_t encoded_len = 0;
+ char *encoded = NULL;
+ json_object *aer_capability_ir = json_object_new_object();
+
+ encoded = base64_encode((UINT8 *)pcie_error->AerInfo.PcieAer, 96,
+ &encoded_len);
+ if (encoded == NULL) {
+ printf("Failed to allocate encode output buffer. \n");
+ } else {
+ json_object_object_add(aer_capability_ir, "data",
+ json_object_new_string_len(encoded,
+ encoded_len));
+ free(encoded);
+ }
+
+ json_object *fields_ir;
+
+ aer_info_registers *aer_decode;
+ aer_decode = (aer_info_registers *)&pcie_error->AerInfo.PcieAer;
+
+ /*
+ * AER Capability Header
+ * Offset: 0x0
+ */
+ fields_ir = json_object_new_object();
+ add_int(fields_ir, "capability_id",
+ aer_decode->capability_header.capability_id);
+ add_int(fields_ir, "capability_version",
+ aer_decode->capability_header.capability_version);
+ add_int(fields_ir, "next_capability_offset",
+ aer_decode->capability_header.next_capability_offset);
+ json_object_object_add(aer_capability_ir, "capability_header",
+ fields_ir);
+
+ /*
+ * Uncorrectable Error Status Register
+ * Offset: 0x4
+ */
+ fields_ir = json_object_new_object();
+ //add_bool(fields_ir, "undefined",
+ // aer_decode->uncorrectable_error_status.undefined);
+ //add_int(fields_ir, "rsvdz1",
+ // aer_decode->uncorrectable_error_status.rsvdz1);
+ add_bool(fields_ir, "data_link_protocol_error_status",
+ aer_decode->uncorrectable_error_status
+ .data_link_protocol_error_status);
+ add_bool(fields_ir, "surprise_down_error_status",
+ aer_decode->uncorrectable_error_status
+ .surprise_down_error_status);
+ //add_int(fields_ir, "rsvdz2",
+ // aer_decode->uncorrectable_error_status.rsvdz2);
+ add_bool(fields_ir, "poisoned_tlp_received",
+ aer_decode->uncorrectable_error_status.poisoned_tlp_received);
+ add_bool(fields_ir, "flow_control_protocol_error_status",
+ aer_decode->uncorrectable_error_status
+ .flow_control_protocol_error_status);
+ add_bool(fields_ir, "completion_timeout_status",
+ aer_decode->uncorrectable_error_status
+ .completion_timeout_status);
+ add_bool(fields_ir, "completer_abort_status",
+ aer_decode->uncorrectable_error_status.completer_abort_status);
+ add_bool(fields_ir, "unexpected_completion_status",
+ aer_decode->uncorrectable_error_status
+ .unexpected_completion_status);
+ add_bool(
+ fields_ir, "receiver_overflow_status",
+ aer_decode->uncorrectable_error_status.receiver_overflow_status);
+ add_bool(fields_ir, "malformed_tlp_status",
+ aer_decode->uncorrectable_error_status.malformed_tlp_status);
+ add_bool(fields_ir, "ecrc_error_status",
+ aer_decode->uncorrectable_error_status.ecrc_error_status);
+ add_bool(fields_ir, "unsupported_request_error_status",
+ aer_decode->uncorrectable_error_status
+ .unsupported_request_error_status);
+ add_bool(fields_ir, "acs_violation_status",
+ aer_decode->uncorrectable_error_status.acs_violation_status);
+ add_bool(fields_ir, "uncorrectable_internal_error_status",
+ aer_decode->uncorrectable_error_status
+ .uncorrectable_internal_error_status);
+ add_bool(fields_ir, "mc_blocked_tlp_status",
+ aer_decode->uncorrectable_error_status.mc_blocked_tlp_status);
+ add_bool(fields_ir, "atomicop_egress_blocked_status",
+ aer_decode->uncorrectable_error_status
+ .atomicop_egress_blocked_status);
+ add_bool(fields_ir, "tlp_prefix_blocked_error_status",
+ aer_decode->uncorrectable_error_status
+ .tlp_prefix_blocked_error_status);
+ add_bool(fields_ir, "poisoned_tlp_egress_blocked_status",
+ aer_decode->uncorrectable_error_status
+ .poisoned_tlp_egress_blocked_status);
+ add_bool(fields_ir, "dmwr_request_egress_blocked_status",
+ aer_decode->uncorrectable_error_status
+ .dmwr_request_egress_blocked_status);
+ add_bool(
+ fields_ir, "ide_check_failed_status",
+ aer_decode->uncorrectable_error_status.ide_check_failed_status);
+ add_bool(
+ fields_ir, "misrouted_ide_tlp_status",
+ aer_decode->uncorrectable_error_status.misrouted_ide_tlp_status);
+ add_bool(
+ fields_ir, "pcrc_check_failed_status",
+ aer_decode->uncorrectable_error_status.pcrc_check_failed_status);
+ add_bool(fields_ir, "tlp_translation_egress_blocked_status",
+ aer_decode->uncorrectable_error_status
+ .tlp_translation_egress_blocked_status);
+ json_object_object_add(aer_capability_ir, "uncorrectable_error_status",
+ fields_ir);
+
+ /*
+ * Uncorrectable Error Mask Register
+ * Offset: 0x8
+ */
+ fields_ir = json_object_new_object();
+ //add_bool(fields_ir, "undefined",
+ // aer_decode->uncorrectable_error_mask.undefined);
+ //add_int(fields_ir, "rsvdz1",
+ // aer_decode->uncorrectable_error_mask.rsvdz1);
+ add_int(fields_ir, "data_link_protocol_error_mask",
+ aer_decode->uncorrectable_error_mask
+ .data_link_protocol_error_mask);
+ add_int(fields_ir, "surprise_down_error_mask",
+ aer_decode->uncorrectable_error_mask.surprise_down_error_mask);
+ //add_int(fields_ir, "rsvdz2",
+ // aer_decode->uncorrectable_error_mask.rsvdz2);
+ add_int(fields_ir, "poisoned_tlp_received_mask",
+ aer_decode->uncorrectable_error_mask.poisoned_tlp_received_mask);
+ add_int(fields_ir, "flow_control_protocol_error_mask",
+ aer_decode->uncorrectable_error_mask
+ .flow_control_protocol_error_mask);
+ add_int(fields_ir, "completion_timeout_mask",
+ aer_decode->uncorrectable_error_mask.completion_timeout_mask);
+ add_int(fields_ir, "completer_abort_mask",
+ aer_decode->uncorrectable_error_mask.completer_abort_mask);
+ add_int(fields_ir, "unexpected_completion_mask",
+ aer_decode->uncorrectable_error_mask.unexpected_completion_mask);
+ add_int(fields_ir, "receiver_overflow_mask",
+ aer_decode->uncorrectable_error_mask.receiver_overflow_mask);
+ add_int(fields_ir, "malformed_tlp_mask",
+ aer_decode->uncorrectable_error_mask.malformed_tlp_mask);
+ add_int(fields_ir, "ecrc_error_mask",
+ aer_decode->uncorrectable_error_mask.ecrc_error_mask);
+ add_int(fields_ir, "unsupported_request_error_mask",
+ aer_decode->uncorrectable_error_mask
+ .unsupported_request_error_mask);
+ add_int(fields_ir, "acs_violation_mask",
+ aer_decode->uncorrectable_error_mask.acs_violation_mask);
+ add_int(fields_ir, "uncorrectable_internal_error_mask",
+ aer_decode->uncorrectable_error_mask
+ .uncorrectable_internal_error_mask);
+ add_int(fields_ir, "mc_blocked_tlp_mask",
+ aer_decode->uncorrectable_error_mask.mc_blocked_tlp_mask);
+ add_int(fields_ir, "atomicop_egress_blocked_mask",
+ aer_decode->uncorrectable_error_mask
+ .atomicop_egress_blocked_mask);
+ add_int(fields_ir, "tlp_prefix_blocked_error_mask",
+ aer_decode->uncorrectable_error_mask
+ .tlp_prefix_blocked_error_mask);
+ add_int(fields_ir, "poisoned_tlp_egress_blocked_mask",
+ aer_decode->uncorrectable_error_mask
+ .poisoned_tlp_egress_blocked_mask);
+ add_int(fields_ir, "dmwr_request_egress_blocked_mask",
+ aer_decode->uncorrectable_error_mask
+ .dmwr_request_egress_blocked_mask);
+ add_int(fields_ir, "ide_check_failed_mask",
+ aer_decode->uncorrectable_error_mask.ide_check_failed_mask);
+ add_int(fields_ir, "misrouted_ide_tlp_mask",
+ aer_decode->uncorrectable_error_mask.misrouted_ide_tlp_mask);
+ add_int(fields_ir, "pcrc_check_failed_mask",
+ aer_decode->uncorrectable_error_mask.pcrc_check_failed_mask);
+ add_int(fields_ir, "tlp_translation_egress_blocked_mask",
+ aer_decode->uncorrectable_error_mask
+ .tlp_translation_egress_blocked_mask);
+ json_object_object_add(aer_capability_ir, "uncorrectable_error_mask",
+ fields_ir);
+
+ /*
+ * Uncorrectable Error Severity Register
+ * Offset: 0xC
+ */
+ fields_ir = json_object_new_object();
+ //add_bool(fields_ir, "undefined",
+ // aer_decode->uncorrectable_error_severity.undefined);
+ //add_int(fields_ir, "rsvdz1",
+ // aer_decode->uncorrectable_error_severity.rsvdz1);
+ add_bool_enum(fields_ir, "data_link_protocol_error_severity",
+ severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .data_link_protocol_error_severity);
+ add_bool_enum(fields_ir, "surprise_down_error_severity", severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .surprise_down_error_severity);
+ //add_int(fields_ir, "rsvdz2",
+ // aer_decode->uncorrectable_error_severity.rsvdz2);
+ add_bool_enum(fields_ir, "poisoned_tlp_received_severity",
+ severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .poisoned_tlp_received_severity);
+ add_bool_enum(fields_ir, "flow_control_protocol_error_severity",
+ severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .flow_control_protocol_error_severity);
+ add_bool_enum(fields_ir, "completion_timeout_severity", severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .completion_timeout_severity);
+ add_bool_enum(fields_ir, "completer_abort_severity", severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .completer_abort_severity);
+ add_bool_enum(fields_ir, "unexpected_completion_severity",
+ severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .unexpected_completion_severity);
+ add_bool_enum(fields_ir, "receiver_overflow_severity", severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .receiver_overflow_severity);
+ add_bool_enum(
+ fields_ir, "malformed_tlp_severity", severity_dict,
+ aer_decode->uncorrectable_error_severity.malformed_tlp_severity);
+ add_bool_enum(
+ fields_ir, "ecrc_error_severity", severity_dict,
+ aer_decode->uncorrectable_error_severity.ecrc_error_severity);
+ add_bool_enum(fields_ir, "unsupported_request_error_severity",
+ severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .unsupported_request_error_severity);
+ add_bool_enum(
+ fields_ir, "acs_violation_severity", severity_dict,
+ aer_decode->uncorrectable_error_severity.acs_violation_severity);
+ add_bool_enum(fields_ir, "uncorrectable_internal_error_severity",
+ severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .uncorrectable_internal_error_severity);
+ add_bool_enum(fields_ir, "mc_blocked_tlp_severity", severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .mc_blocked_tlp_severity);
+ add_bool_enum(fields_ir, "atomicop_egress_blocked_severity",
+ severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .atomicop_egress_blocked_severity);
+ add_bool_enum(fields_ir, "tlp_prefix_blocked_error_severity",
+ severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .tlp_prefix_blocked_error_severity);
+ add_bool_enum(fields_ir, "poisoned_tlp_egress_blocked_severity",
+ severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .poisoned_tlp_egress_blocked_severity);
+ add_bool_enum(fields_ir, "dmwr_request_egress_blocked_severity",
+ severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .dmwr_request_egress_blocked_severity);
+ add_bool_enum(fields_ir, "ide_check_failed_severity", severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .ide_check_failed_severity);
+ add_bool_enum(fields_ir, "misrouted_ide_tlp_severity", severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .misrouted_ide_tlp_severity);
+ add_bool_enum(fields_ir, "pcrc_check_failed_severity", severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .pcrc_check_failed_severity);
+ add_bool_enum(fields_ir, "tlp_translation_egress_blocked_severity",
+ severity_dict,
+ aer_decode->uncorrectable_error_severity
+ .tlp_translation_egress_blocked_severity);
+ json_object_object_add(aer_capability_ir,
+ "uncorrectable_error_severity", fields_ir);
+
+ /*
+ * Correctable Error Status Register
+ * Offset: 0x10
+ */
+ fields_ir = json_object_new_object();
+ add_bool(fields_ir, "receiver_error_status",
+ aer_decode->correctable_error_status.receiver_error_status);
+ //add_int(fields_ir, "rsvdz1",
+ // aer_decode->correctable_error_status.rsvdz1);
+ add_bool(fields_ir, "bad_tlp_status",
+ aer_decode->correctable_error_status.bad_tlp_status);
+ add_bool(fields_ir, "bad_dllp_status",
+ aer_decode->correctable_error_status.bad_dllp_status);
+ add_bool(
+ fields_ir, "replay_num_rollover_status",
+ aer_decode->correctable_error_status.replay_num_rollover_status);
+ //add_int(fields_ir, "rsvdz2",
+ // aer_decode->correctable_error_status.rsvdz2);
+ add_bool(fields_ir, "replay_timer_timeout_status",
+ aer_decode->correctable_error_status
+ .replay_timer_timeout_status);
+ add_bool(fields_ir, "advisory_non_fatal_error_status",
+ aer_decode->correctable_error_status
+ .advisory_non_fatal_error_status);
+ add_bool(fields_ir, "corrected_internal_error_status",
+ aer_decode->correctable_error_status
+ .corrected_internal_error_status);
+ add_bool(
+ fields_ir, "header_log_overflow_status",
+ aer_decode->correctable_error_status.header_log_overflow_status);
+ //add_int(fields_ir, "rsvdz3",
+ // aer_decode->correctable_error_status.rsvdz3);
+ json_object_object_add(aer_capability_ir, "correctable_error_status",
+ fields_ir);
+
+ /*
+ * Correctable Error Mask Register
+ * Offset: 0x14
+ */
+ fields_ir = json_object_new_object();
+ add_int(fields_ir, "receiver_error_mask",
+ aer_decode->correctable_error_mask.receiver_error_mask);
+ //add_int(fields_ir, "rsvdz1", aer_decode->correctable_error_mask.rsvdz1);
+ add_int(fields_ir, "bad_tlp_mask",
+ aer_decode->correctable_error_mask.bad_tlp_mask);
+ add_int(fields_ir, "bad_dllp_mask",
+ aer_decode->correctable_error_mask.bad_dllp_mask);
+ add_int(fields_ir, "replay_num_rollover_mask",
+ aer_decode->correctable_error_mask.replay_num_rollover_mask);
+ //add_int(fields_ir, "rsvdz2", aer_decode->correctable_error_mask.rsvdz2);
+ add_int(fields_ir, "replay_timer_timeout_mask",
+ aer_decode->correctable_error_mask.replay_timer_timeout_mask);
+ add_int(fields_ir, "advisory_non_fatal_error_mask",
+ aer_decode->correctable_error_mask
+ .advisory_non_fatal_error_mask);
+ add_int(fields_ir, "corrected_internal_error_mask",
+ aer_decode->correctable_error_mask
+ .corrected_internal_error_mask);
+ add_int(fields_ir, "header_log_overflow_mask",
+ aer_decode->correctable_error_mask.header_log_overflow_mask);
+ //add_int(fields_ir, "rsvdz3", aer_decode->correctable_error_mask.rsvdz3);
+ json_object_object_add(aer_capability_ir, "correctable_error_mask",
+ fields_ir);
+
+ /*
+ * Advanced Error Capabilities and Control Register
+ * Offset: 0x18
+ */
+ fields_ir = json_object_new_object();
+ add_int(fields_ir, "first_error_pointer",
+ aer_decode->advanced_error_capabilities_and_control
+ .first_error_pointer);
+ //add_bool(fields_ir, "ecrc_generation_capable",
+ // aer_decode->advanced_error_capabilities_and_control
+ // .ecrc_generation_capable);
+ //add_bool(fields_ir, "ecrc_generation_enable",
+ // aer_decode->advanced_error_capabilities_and_control
+ // .ecrc_generation_enable);
+ //add_bool(fields_ir, "ecrc_check_capable",
+ // aer_decode->advanced_error_capabilities_and_control
+ // .ecrc_check_capable);
+ //add_bool(fields_ir, "ecrc_check_enable",
+ // aer_decode->advanced_error_capabilities_and_control
+ // .ecrc_check_enable);
+ //add_bool(fields_ir, "multiple_header_recording_capable",
+ // aer_decode->advanced_error_capabilities_and_control
+ // .multiple_header_recording_capable);
+ //add_bool(fields_ir, "multiple_header_recording_enable",
+ // aer_decode->advanced_error_capabilities_and_control
+ // .multiple_header_recording_enable);
+ //add_bool(fields_ir, "tlp_prefix_log_present",
+ // aer_decode->advanced_error_capabilities_and_control
+ // .tlp_prefix_log_present);
+ //add_bool(fields_ir, "completion_timeout_prefix_header_log_capable",
+ // aer_decode->advanced_error_capabilities_and_control
+ // .completion_timeout_prefix_header_log_capable);
+ add_int(fields_ir, "header_log_size",
+ aer_decode->advanced_error_capabilities_and_control
+ .header_log_size);
+ //add_bool(fields_ir, "logged_tlp_was_flit_mode",
+ // aer_decode->advanced_error_capabilities_and_control
+ // .logged_tlp_was_flit_mode);
+ add_int(fields_ir, "logged_tlp_size",
+ aer_decode->advanced_error_capabilities_and_control
+ .logged_tlp_size);
+ //add_int(fields_ir, "rsvdp",
+ // aer_decode->advanced_error_capabilities_and_control.rsvdp);
+ json_object_object_add(aer_capability_ir,
+ "advanced_error_capabilities_and_control",
+ fields_ir);
+
+ /*
+ * Root Error Command Register
+ * Offset: 0x2C
+ */
+ fields_ir = json_object_new_object();
+ //add_bool(fields_ir, "correctable_error_reporting_enable",
+ // aer_decode->root_error_command
+ // .correctable_error_reporting_enable);
+ //add_bool(
+ // fields_ir, "non_fatal_error_reporting_enable",
+ // aer_decode->root_error_command.non_fatal_error_reporting_enable);
+ //add_bool(fields_ir, "fatal_error_reporting_enable",
+ // aer_decode->root_error_command.fatal_error_reporting_enable);
+ //add_int(fields_ir, "rsvdp", aer_decode->root_error_command.rsvdp);
+ json_object_object_add(aer_capability_ir, "root_error_command",
+ fields_ir);
+
+ /*
+ * Root Error Status Register
+ * Offset: 0x30
+ */
+ fields_ir = json_object_new_object();
+ //add_bool(fields_ir, "err_cor_received",
+ // aer_decode->root_error_status.err_cor_received);
+ //add_bool(fields_ir, "multiple_err_cor_received",
+ // aer_decode->root_error_status.multiple_err_cor_received);
+ //add_bool(fields_ir, "err_fatal_nonfatal_received",
+ // aer_decode->root_error_status.err_fatal_nonfatal_received);
+ //add_bool(fields_ir, "multiple_err_fatal_nonfatal_received",
+ // aer_decode->root_error_status
+ // .multiple_err_fatal_nonfatal_received);
+ //add_bool(fields_ir, "first_uncorrectable_fatal",
+ // aer_decode->root_error_status.first_uncorrectable_fatal);
+ //add_bool(
+ // fields_ir, "non_fatal_error_messages_received",
+ // aer_decode->root_error_status.non_fatal_error_messages_received);
+ //add_bool(fields_ir, "fatal_error_messages_received",
+ // aer_decode->root_error_status.fatal_error_messages_received);
+ add_int(fields_ir, "err_cor_subclass",
+ aer_decode->root_error_status.err_cor_subclass);
+ //add_int(fields_ir, "rsvdz", aer_decode->root_error_status.rsvdz);
+ add_int(fields_ir, "advanced_error_interrupt_message_number",
+ aer_decode->root_error_status
+ .advanced_error_interrupt_message_number);
+ json_object_object_add(aer_capability_ir, "root_error_status",
+ fields_ir);
+
+ /*
+ * Error Source Identification Register
+ * Offset: 0x34
+ */
+ fields_ir = json_object_new_object();
+ add_int(fields_ir, "err_cor_source_identification",
+ aer_decode->error_source_id.err_cor_source_identification);
+ add_int(fields_ir, "err_fatal_nonfatal_source_identification",
+ aer_decode->error_source_id
+ .err_fatal_nonfatal_source_identification);
+ json_object_object_add(aer_capability_ir, "error_source_id", fields_ir);
+
+ return aer_capability_ir;
+}
+
//Converts a single CPER-JSON PCIe section into CPER binary, outputting to the given stream.
void ir_section_pcie_to_cper(json_object *section, FILE *out)
{
@@ -261,7 +1221,7 @@
//Version.
if (json_object_object_get_ex(section, "version", &obj)) {
- json_object *version = obj;
+ const json_object *version = obj;
UINT32 minor = int_to_bcd(json_object_get_int(
json_object_object_get(version, "minor")));
UINT32 major = int_to_bcd(json_object_get_int(
@@ -272,7 +1232,7 @@
//Command/status registers.
if (json_object_object_get_ex(section, "commandStatus", &obj)) {
- json_object *command_status = obj;
+ const json_object *command_status = obj;
UINT32 command = (UINT16)json_object_get_uint64(
json_object_object_get(command_status,
"commandRegister"));
@@ -285,7 +1245,7 @@
//Device ID.
if (json_object_object_get_ex(section, "deviceID", &obj)) {
- json_object *device_id = obj;
+ const json_object *device_id = obj;
UINT64 class_id = json_object_get_uint64(
json_object_object_get(device_id, "classCode"));
section_cper->DevBridge.VendorId =
@@ -319,7 +1279,7 @@
//Bridge/control status.
if (json_object_object_get_ex(section, "bridgeControlStatus", &obj)) {
- json_object *bridge_control = obj;
+ const json_object *bridge_control = obj;
UINT32 bridge_status = (UINT16)json_object_get_uint64(
json_object_object_get(bridge_control,
"secondaryStatusRegister"));
@@ -336,13 +1296,12 @@
UINT8 *decoded = NULL;
json_object *encoded = NULL;
if (json_object_object_get_ex(section, "capabilityStructure", &obj)) {
- json_object *capability = obj;
- json_object *encoded =
- json_object_object_get(capability, "data");
+ const json_object *capability = obj;
+ encoded = json_object_object_get(capability, "data");
- UINT8 *decoded = base64_decode(
- json_object_get_string(encoded),
- json_object_get_string_len(encoded), &decoded_len);
+ decoded = base64_decode(json_object_get_string(encoded),
+ json_object_get_string_len(encoded),
+ &decoded_len);
if (decoded == NULL) {
cper_print_log(
"Failed to allocate decode output buffer. \n");
@@ -358,7 +1317,7 @@
encoded = NULL;
//AER capability structure.
if (json_object_object_get_ex(section, "aerInfo", &obj)) {
- json_object *aer_info = obj;
+ const json_object *aer_info = obj;
encoded = json_object_object_get(aer_info, "data");
decoded_len = 0;
diff --git a/specification/json/sections/cper-pcie-aerInfo.json b/specification/json/sections/cper-pcie-aerInfo.json
new file mode 100644
index 0000000..957e6a9
--- /dev/null
+++ b/specification/json/sections/cper-pcie-aerInfo.json
@@ -0,0 +1,153 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "title": "PCIe Capability Structure",
+ "type": "object",
+ "description": "PCIe Advanced Error Reporting Extended Capability Structure",
+ "additionalProperties": false,
+ "required": [
+ "data",
+ "capability_header",
+ "uncorrectable_error_status",
+ "uncorrectable_error_mask",
+ "uncorrectable_error_severity",
+ "correctable_error_status",
+ "correctable_error_mask",
+ "advanced_error_capabilities_and_control",
+ "root_error_command",
+ "root_error_status",
+ "error_source_id"
+ ],
+ "properties": {
+ "data": {
+ "type": "string"
+ },
+ "capability_header": {
+ "type": "object",
+ "description": "AER Capability Header (Offset: 0x0)",
+ "required": [
+ "capability_id",
+ "capability_version",
+ "next_capability_offset"
+ ],
+ "properties": {
+ "capability_id": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 65535
+ },
+ "capability_version": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 15
+ },
+ "next_capability_offset": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 4095
+ }
+ }
+ },
+ "uncorrectable_error_status": {
+ "type": "object",
+ "description": "Uncorrectable Error Status Register (Offset: 0x4)",
+ "required": [],
+ "properties": {}
+ },
+ "uncorrectable_error_mask": {
+ "type": "object",
+ "description": "Uncorrectable Error Mask Register (Offset: 0x8)",
+ "required": [],
+ "properties": {}
+ },
+ "uncorrectable_error_severity": {
+ "type": "object",
+ "description": "Uncorrectable Error Severity Register (Offset: 0xC)",
+ "required": [],
+ "properties": {}
+ },
+ "correctable_error_status": {
+ "type": "object",
+ "description": "Correctable Error Status Register (Offset: 0x10)",
+ "required": [],
+ "properties": {}
+ },
+ "correctable_error_mask": {
+ "type": "object",
+ "description": "Correctable Error Mask Register (Offset: 0x14)",
+ "required": [],
+ "properties": {}
+ },
+ "advanced_error_capabilities_and_control": {
+ "type": "object",
+ "description": "Advanced Error Capabilities and Control Register (Offset: 0x18)",
+ "required": [
+ "first_error_pointer",
+ "header_log_size",
+ "logged_tlp_size"
+ ],
+ "properties": {
+ "first_error_pointer": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 31
+ },
+ "header_log_size": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 31
+ },
+ "logged_tlp_size": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 31
+ }
+ }
+ },
+ "root_error_command": {
+ "type": "object",
+ "description": "Root Error Command Register (Offset: 0x2C)",
+ "required": [],
+ "properties": {}
+ },
+ "root_error_status": {
+ "type": "object",
+ "description": "Root Error Status Register (Offset: 0x30)",
+ "required": [
+ "err_cor_subclass",
+ "advanced_error_interrupt_message_number"
+ ],
+ "properties": {
+ "err_cor_subclass": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 3
+ },
+ "advanced_error_interrupt_message_number": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 31
+ }
+ }
+ },
+ "error_source_id": {
+ "type": "object",
+ "description": "Error Source Identification Register (Offset: 0x34)",
+ "required": [
+ "err_cor_source_identification",
+ "err_fatal_nonfatal_source_identification"
+ ],
+ "properties": {
+ "err_cor_source_identification": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 65535
+ },
+ "err_fatal_nonfatal_source_identification": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 65535
+ }
+ }
+ }
+ }
+}
diff --git a/specification/json/sections/cper-pcie-capabilityStructure.json b/specification/json/sections/cper-pcie-capabilityStructure.json
new file mode 100644
index 0000000..a8a1c3c
--- /dev/null
+++ b/specification/json/sections/cper-pcie-capabilityStructure.json
@@ -0,0 +1,651 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "title": "PCIe Capability Structure",
+ "type": "object",
+ "description": "PCIe 1.0 or PCIe 2.0 Capability structure",
+ "additionalProperties": false,
+ "required": [
+ "data",
+ "pcie_capability_header",
+ "pcie_capabilities",
+ "device_capabilities",
+ "device_control",
+ "device_status",
+ "link_capabilities",
+ "link_control",
+ "link_status",
+ "slot_capabilities",
+ "slot_control",
+ "slot_status",
+ "root_control",
+ "root_capabilities",
+ "root_status"
+ ],
+ "properties": {
+ "data": {
+ "type": "string"
+ },
+ "pcie_capability_header": {
+ "type": "object",
+ "description": "The templat of each register is: ()",
+ "required": ["capability_id", "next_capability_pointer"],
+ "properties": {
+ "capability_id": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 255
+ }
+ }
+ },
+ "next_capability_pointer": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 255
+ }
+ }
+ }
+ }
+ },
+ "pcie_capabilities": {
+ "type": "object",
+ "description": "PCI Express Capabilities Register (Offset: 0x2)",
+ "required": [
+ "capability_version",
+ "device_port_type",
+ "interrupt_message_number"
+ ],
+ "properties": {
+ "capability_version": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 15
+ }
+ }
+ },
+ "device_port_type": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 15
+ }
+ }
+ },
+ "interrupt_message_number": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 31
+ }
+ }
+ }
+ }
+ },
+ "device_capabilities": {
+ "type": "object",
+ "description": "/* (PCI Express Capability Structure)",
+ "required": [
+ "max_payload_size_supported",
+ "phantom_functions_supported",
+ "endpoint_l0s_acceptable_latency",
+ "endpoint_l1_acceptable_latency",
+ "captured_slot_power_limit_value",
+ "captured_slot_power_limit_scale"
+ ],
+ "properties": {
+ "max_payload_size_supported": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 7
+ },
+ "phantom_functions_supported": {
+ "type": "boolean"
+ },
+ "endpoint_l0s_acceptable_latency": {
+ "type": "object",
+ "required": ["raw"],
+ "properties": {
+ "raw": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 3
+ }
+ }
+ },
+ "endpoint_l1_acceptable_latency": {
+ "type": "object",
+ "required": ["raw"],
+ "properties": {
+ "raw": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 3
+ }
+ }
+ },
+ "captured_slot_power_limit_value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 255
+ },
+ "captured_slot_power_limit_scale": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 3
+ }
+ }
+ },
+ "device_control": {
+ "type": "object",
+ "description": "Device Control Register (Offset: 0x8)",
+ "required": ["max_payload_size", "max_read_request_size"],
+ "properties": {
+ "max_payload_size": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 7
+ },
+ "max_read_request_size": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 7
+ }
+ }
+ },
+ "device_status": {
+ "type": "object",
+ "description": "Device Status Register (Offset: 0xA)",
+ "required": ["emergency_power_reduction"],
+ "properties": {
+ "emergency_power_reduction": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 3
+ }
+ }
+ }
+ }
+ },
+ "link_capabilities": {
+ "type": "object",
+ "description": "Link Capabilities Register (Offset: 0xC)",
+ "required": [
+ "max_link_speed",
+ "maximum_link_width",
+ "aspm_support",
+ "l0s_exit_latency",
+ "l1_exit_latency",
+ "port_number"
+ ],
+ "properties": {
+ "max_link_speed": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 15
+ }
+ }
+ },
+ "maximum_link_width": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 63
+ }
+ }
+ },
+ "aspm_support": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 3
+ }
+ }
+ },
+ "l0s_exit_latency": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 7
+ }
+ }
+ },
+ "l1_exit_latency": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 7
+ }
+ }
+ },
+ "port_number": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 255
+ }
+ }
+ }
+ }
+ },
+ "link_control": {
+ "type": "object",
+ "description": "Link Control Register (Offset: 0x10)",
+ "required": ["aspm_control"],
+ "properties": {
+ "aspm_control": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 3
+ }
+ }
+ }
+ }
+ },
+ "link_status": {
+ "type": "object",
+ "description": "Link Status Register (Offset: 0x12)",
+ "required": ["current_link_speed", "negotiated_link_width"],
+ "properties": {
+ "current_link_speed": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 15
+ }
+ }
+ },
+ "negotiated_link_width": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 63
+ }
+ }
+ }
+ }
+ },
+ "slot_capabilities": {
+ "type": "object",
+ "description": "Slot Capabilities Register (Offset: 0x14)",
+ "required": [
+ "slot_power_limit_value",
+ "slot_power_limit_scale",
+ "physical_slot_number"
+ ],
+ "properties": {
+ "slot_power_limit_value": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 255
+ }
+ }
+ },
+ "slot_power_limit_scale": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 3
+ }
+ }
+ },
+ "physical_slot_number": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 8191
+ }
+ }
+ }
+ }
+ },
+ "slot_control": {
+ "type": "object",
+ "description": "Slot Control Register (Offset: 0x18)",
+ "required": [
+ "attention_indicator_control",
+ "power_indicator_control"
+ ],
+ "properties": {
+ "attention_indicator_control": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 3
+ }
+ }
+ },
+ "power_indicator_control": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 3
+ }
+ }
+ }
+ }
+ },
+ "slot_status": {
+ "type": "object",
+ "description": "Slot Status Register (Offset: 0x1A)",
+ "required": [],
+ "properties": {}
+ },
+ "root_control": {
+ "type": "object",
+ "description": "Root Control Register (Offset: 0x1C)",
+ "required": [],
+ "properties": {}
+ },
+ "root_capabilities": {
+ "type": "object",
+ "description": "Root Capabilities Register (Offset: 0x1E)",
+ "required": [],
+ "properties": {}
+ },
+ "root_status": {
+ "type": "object",
+ "description": "Root Status Register (Offset: 0x20)",
+ "required": ["pme_requester_id"],
+ "properties": {
+ "pme_requester_id": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 65535
+ }
+ }
+ }
+ }
+ },
+ "device_capabilities2": {
+ "type": "object",
+ "description": "Device Capabilities 2 Register (Offset: 0x24)",
+ "required": [
+ "completion_timeout_ranges_supported",
+ "tph_completer_supported",
+ "obff_supported",
+ "max_end_end_tlp_prefixes",
+ "emergency_power_reduction_supported",
+ "dmwr_lengths_supported"
+ ],
+ "properties": {
+ "completion_timeout_ranges_supported": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 15
+ },
+ "tph_completer_supported": {
+ "type": "boolean"
+ },
+ "obff_supported": {
+ "type": "boolean"
+ },
+ "max_end_end_tlp_prefixes": {
+ "properties": {
+ "raw": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 3
+ }
+ }
+ },
+ "emergency_power_reduction_supported": {
+ "type": "boolean"
+ },
+ "dmwr_lengths_supported": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 3
+ }
+ }
+ },
+ "device_control2": {
+ "type": "object",
+ "description": "Device Control 2 Register (Offset: 0x28)",
+ "required": ["completion_timeout_value", "obff_enable"],
+ "properties": {
+ "completion_timeout_value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 15
+ },
+ "obff_enable": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 3
+ }
+ }
+ }
+ }
+ },
+ "device_status2": {
+ "type": "object",
+ "description": "Device Status 2 Register (Offset: 0x2A)",
+ "required": [],
+ "properties": {}
+ },
+ "link_capabilities2": {
+ "type": "object",
+ "description": "Link Capabilities 2 Register (Offset: 0x2C)",
+ "required": [
+ "supported_link_speeds",
+ "lower_skp_os_generation_supported",
+ "lower_skp_os_reception_supported",
+ "reserved"
+ ],
+ "properties": {
+ "supported_link_speeds": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 127
+ }
+ }
+ },
+ "lower_skp_os_generation_supported": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 127
+ }
+ }
+ },
+ "lower_skp_os_reception_supported": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 127
+ }
+ }
+ },
+ "reserved": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 63
+ }
+ }
+ }
+ }
+ },
+ "link_control2": {
+ "type": "object",
+ "description": "Link Control 2 Register (Offset: 0x30)",
+ "required": [
+ "target_link_speed",
+ "transmit_margin",
+ "compliance_preset_de_emphasis"
+ ],
+ "properties": {
+ "target_link_speed": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 15
+ }
+ }
+ },
+ "transmit_margin": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 7
+ }
+ }
+ },
+ "compliance_preset_de_emphasis": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 15
+ }
+ }
+ }
+ }
+ },
+ "link_status2": {
+ "type": "object",
+ "description": "Link Status 2 Register (Offset: 0x32)",
+ "required": [
+ "crosslink_resolution",
+ "downstream_component_presence"
+ ],
+ "properties": {
+ "crosslink_resolution": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 3
+ }
+ }
+ },
+ "downstream_component_presence": {
+ "type": "object",
+ "required": ["value"],
+ "properties": {
+ "value": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 7
+ }
+ }
+ }
+ }
+ },
+ "slot_capabilities2": {
+ "type": "object",
+ "description": "Slot Capabilities 2 Register (Offset: 0x34)",
+ "required": [],
+ "properties": {}
+ },
+ "slot_control2": {
+ "type": "object",
+ "description": "Slot Control 2 Register (Offset: 0x38)",
+ "required": [],
+ "properties": {}
+ },
+ "slot_status2": {
+ "type": "object",
+ "description": "Slot Status 2 Register (Offset: 0x3A)",
+ "required": [],
+ "properties": {}
+ }
+ }
+}
diff --git a/specification/json/sections/cper-pcie.json b/specification/json/sections/cper-pcie.json
index 2f2b23c..d6e6811 100644
--- a/specification/json/sections/cper-pcie.json
+++ b/specification/json/sections/cper-pcie.json
@@ -108,64 +108,11 @@
},
"capabilityStructure": {
"type": "object",
- "additionalProperties": false,
- "description": "This feild reports either the PCIe 2.0 Capability structure",
- "required": ["data"],
- "properties": {
- "data": {
- "type": "string"
- }
- }
+ "description": "PCIe Capabilities structure"
},
"aerInfo": {
"type": "object",
- "additionalProperties": false,
- "description": "PCIe Advanced Error Reporting Extended Capability Structure.",
- "required": ["data"],
- "properties": {
- "data": {
- "type": "string"
- },
- "capability_header": {
- "type": "integer"
- },
- "uncorrectable_error_status": {
- "type": "integer"
- },
- "uncorrectable_error_status_hex": {
- "type": "string"
- },
- "uncorrectable_error_mask": {
- "type": "integer"
- },
- "uncorrectable_error_severity": {
- "type": "integer"
- },
- "correctable_error_status": {
- "type": "integer"
- },
- "correctable_error_status_hex": {
- "type": "string"
- },
- "correctable_error_mask": {
- "type": "integer"
- },
- "capabilites_control": {
- "type": "integer"
- },
- "tlp_header_0": {
- "type": "integer"
- },
- "tlp_header_1": {
- "type": "integer"
- },
- "tlp_header_2": {
- "type": "integer"
- },
- "tlp_header_3": {
- "type": "integer"
- }
- }
+ "description": "PCIe Advanced Error Reporting Information"
}
}
}
diff --git a/tests/ir-tests.cpp b/tests/ir-tests.cpp
index d255353..a43aced 100644
--- a/tests/ir-tests.cpp
+++ b/tests/ir-tests.cpp
@@ -488,7 +488,7 @@
}
//Entrypoint for the testing program.
-int main()
+int main(int argc, char **argv)
{
if (GEN_EXAMPLES) {
cper_create_examples("arm");
@@ -508,6 +508,6 @@
cper_create_examples("nvidia");
cper_create_examples("unknown");
}
- testing::InitGoogleTest();
+ testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/tests/meson.build b/tests/meson.build
index f65dc41..ca21b42 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -1,6 +1,6 @@
cmake = import('cmake')
-gtest = dependency('gtest', main: true, disabler: true, required: false)
+gtest = dependency('gtest', disabler: true, required: false)
gmock = dependency('gmock', disabler: true, required: false)
if not gtest.found() or not gmock.found()
gtest_proj = import('cmake').subproject('googletest', required: false)
diff --git a/tests/test-utils.cpp b/tests/test-utils.cpp
index ca885fc..11d8a02 100644
--- a/tests/test-utils.cpp
+++ b/tests/test-utils.cpp
@@ -30,6 +30,13 @@
"timedOut", "level", "operation", "preciseIP",
"restartableIP", "overflow", "uncorrected",
"transactionType" } },
+ // Several PCIe properties are dependent on the device capability
+ // version and whether the device is running in Flit-Mode.
+ // All of these properties are optional.
+ { "./sections/cper-pcie.json",
+ { "device_capabilities2", "device_status2", "device_control2",
+ "link_capabilities2", "link_status2", "link_control2",
+ "slot_capabilities2", "slot_status2", "slot_control2" } },
};
nlohmann::json loadJson(const char *filePath)