Lawrence Tang | 4dbe3d7 | 2022-07-06 13:51:01 +0100 | [diff] [blame] | 1 | /** |
| 2 | * Describes functions for converting PCIe CPER sections from binary and JSON format |
| 3 | * into an intermediate format. |
Ed Tanous | fedd457 | 2024-07-12 13:56:00 -0700 | [diff] [blame] | 4 | * |
Lawrence Tang | 4dbe3d7 | 2022-07-06 13:51:01 +0100 | [diff] [blame] | 5 | * Author: Lawrence.Tang@arm.com |
| 6 | **/ |
| 7 | #include <stdio.h> |
Lawrence Tang | 3b7f45b | 2022-07-14 14:14:30 +0100 | [diff] [blame] | 8 | #include <string.h> |
Lawrence Tang | 5202bbb | 2022-08-12 14:54:36 +0100 | [diff] [blame] | 9 | #include <json.h> |
Thu Nguyen | e42fb48 | 2024-10-15 14:43:11 +0000 | [diff] [blame] | 10 | #include <libcper/base64.h> |
| 11 | #include <libcper/Cper.h> |
| 12 | #include <libcper/cper-utils.h> |
| 13 | #include <libcper/sections/cper-section-pcie.h> |
Ed Tanous | 50b966f | 2025-03-11 09:06:19 -0700 | [diff] [blame] | 14 | #include <libcper/log.h> |
Lawrence Tang | 4dbe3d7 | 2022-07-06 13:51:01 +0100 | [diff] [blame] | 15 | |
Erwin Tsaur | 8870c07 | 2025-02-28 12:57:12 -0800 | [diff] [blame] | 16 | json_object *pcie_capability_to_ir(EFI_PCIE_ERROR_DATA *pcie_error); |
| 17 | json_object *pcie_aer_to_ir(EFI_PCIE_ERROR_DATA *pcie_error); |
Andrew Adriance | 3cebfc2 | 2024-11-20 12:57:04 -0800 | [diff] [blame] | 18 | |
Lawrence Tang | 4dbe3d7 | 2022-07-06 13:51:01 +0100 | [diff] [blame] | 19 | //Converts a single PCIe CPER section into JSON IR. |
Ed Tanous | 12dbd4f | 2025-03-08 19:05:01 -0800 | [diff] [blame] | 20 | json_object *cper_section_pcie_to_ir(const UINT8 *section, UINT32 size) |
Lawrence Tang | 4dbe3d7 | 2022-07-06 13:51:01 +0100 | [diff] [blame] | 21 | { |
Ed Tanous | 12dbd4f | 2025-03-08 19:05:01 -0800 | [diff] [blame] | 22 | if (size < sizeof(EFI_PCIE_ERROR_DATA)) { |
| 23 | return NULL; |
| 24 | } |
| 25 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 26 | EFI_PCIE_ERROR_DATA *pcie_error = (EFI_PCIE_ERROR_DATA *)section; |
| 27 | json_object *section_ir = json_object_new_object(); |
Lawrence Tang | 4dbe3d7 | 2022-07-06 13:51:01 +0100 | [diff] [blame] | 28 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 29 | //Validation bits. |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 30 | ValidationTypes ui64Type = { UINT_64T, |
| 31 | .value.ui64 = pcie_error->ValidFields }; |
Lawrence Tang | 4dbe3d7 | 2022-07-06 13:51:01 +0100 | [diff] [blame] | 32 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 33 | //Port type. |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 34 | if (isvalid_prop_to_ir(&ui64Type, 0)) { |
| 35 | json_object *port_type = integer_to_readable_pair( |
| 36 | pcie_error->PortType, 9, PCIE_ERROR_PORT_TYPES_KEYS, |
| 37 | PCIE_ERROR_PORT_TYPES_VALUES, "Unknown"); |
| 38 | json_object_object_add(section_ir, "portType", port_type); |
| 39 | } |
Lawrence Tang | 4dbe3d7 | 2022-07-06 13:51:01 +0100 | [diff] [blame] | 40 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 41 | //Version, provided each half in BCD. |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 42 | if (isvalid_prop_to_ir(&ui64Type, 1)) { |
| 43 | json_object *version = json_object_new_object(); |
| 44 | json_object_object_add(version, "minor", |
| 45 | json_object_new_int(bcd_to_int( |
| 46 | pcie_error->Version & 0xFF))); |
| 47 | json_object_object_add(version, "major", |
| 48 | json_object_new_int(bcd_to_int( |
| 49 | pcie_error->Version >> 8))); |
| 50 | json_object_object_add(section_ir, "version", version); |
| 51 | } |
Lawrence Tang | 4dbe3d7 | 2022-07-06 13:51:01 +0100 | [diff] [blame] | 52 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 53 | //Command & status. |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 54 | if (isvalid_prop_to_ir(&ui64Type, 2)) { |
| 55 | json_object *command_status = json_object_new_object(); |
| 56 | json_object_object_add( |
| 57 | command_status, "commandRegister", |
| 58 | json_object_new_uint64(pcie_error->CommandStatus & |
| 59 | 0xFFFF)); |
| 60 | json_object_object_add( |
| 61 | command_status, "statusRegister", |
| 62 | json_object_new_uint64(pcie_error->CommandStatus >> |
| 63 | 16)); |
| 64 | json_object_object_add(section_ir, "commandStatus", |
| 65 | command_status); |
| 66 | } |
Lawrence Tang | 4dbe3d7 | 2022-07-06 13:51:01 +0100 | [diff] [blame] | 67 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 68 | //PCIe Device ID. |
Aushim Nagarkatti | cc36701 | 2024-12-05 18:17:27 -0800 | [diff] [blame] | 69 | char hexstring_buf[EFI_UINT64_HEX_STRING_LEN]; |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 70 | if (isvalid_prop_to_ir(&ui64Type, 3)) { |
| 71 | json_object *device_id = json_object_new_object(); |
| 72 | UINT64 class_id = (pcie_error->DevBridge.ClassCode[0] << 16) + |
| 73 | (pcie_error->DevBridge.ClassCode[1] << 8) + |
| 74 | pcie_error->DevBridge.ClassCode[2]; |
| 75 | json_object_object_add( |
| 76 | device_id, "vendorID", |
| 77 | json_object_new_uint64(pcie_error->DevBridge.VendorId)); |
| 78 | json_object_object_add( |
| 79 | device_id, "deviceID", |
| 80 | json_object_new_uint64(pcie_error->DevBridge.DeviceId)); |
Aushim Nagarkatti | cc36701 | 2024-12-05 18:17:27 -0800 | [diff] [blame] | 81 | |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 82 | snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%0X", |
| 83 | pcie_error->DevBridge.DeviceId); |
| 84 | json_object_object_add(device_id, "deviceIDHex", |
| 85 | json_object_new_string(hexstring_buf)); |
| 86 | |
| 87 | json_object_object_add(device_id, "classCode", |
| 88 | json_object_new_uint64(class_id)); |
| 89 | json_object_object_add( |
| 90 | device_id, "functionNumber", |
| 91 | json_object_new_uint64(pcie_error->DevBridge.Function)); |
| 92 | json_object_object_add( |
| 93 | device_id, "deviceNumber", |
| 94 | json_object_new_uint64(pcie_error->DevBridge.Device)); |
| 95 | json_object_object_add( |
| 96 | device_id, "segmentNumber", |
| 97 | json_object_new_uint64(pcie_error->DevBridge.Segment)); |
| 98 | json_object_object_add( |
| 99 | device_id, "primaryOrDeviceBusNumber", |
| 100 | json_object_new_uint64( |
| 101 | pcie_error->DevBridge.PrimaryOrDeviceBus)); |
| 102 | json_object_object_add( |
| 103 | device_id, "secondaryBusNumber", |
| 104 | json_object_new_uint64( |
| 105 | pcie_error->DevBridge.SecondaryBus)); |
| 106 | json_object_object_add( |
| 107 | device_id, "slotNumber", |
| 108 | json_object_new_uint64( |
| 109 | pcie_error->DevBridge.Slot.Number)); |
| 110 | json_object_object_add(section_ir, "deviceID", device_id); |
| 111 | } |
Lawrence Tang | 4dbe3d7 | 2022-07-06 13:51:01 +0100 | [diff] [blame] | 112 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 113 | //Device serial number. |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 114 | if (isvalid_prop_to_ir(&ui64Type, 4)) { |
| 115 | json_object_object_add( |
| 116 | section_ir, "deviceSerialNumber", |
| 117 | json_object_new_uint64(pcie_error->SerialNo)); |
| 118 | } |
Lawrence Tang | 4dbe3d7 | 2022-07-06 13:51:01 +0100 | [diff] [blame] | 119 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 120 | //Bridge control status. |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 121 | if (isvalid_prop_to_ir(&ui64Type, 5)) { |
| 122 | json_object *bridge_control_status = json_object_new_object(); |
| 123 | json_object_object_add( |
| 124 | bridge_control_status, "secondaryStatusRegister", |
| 125 | json_object_new_uint64(pcie_error->BridgeControlStatus & |
| 126 | 0xFFFF)); |
| 127 | json_object_object_add( |
| 128 | bridge_control_status, "controlRegister", |
| 129 | json_object_new_uint64( |
| 130 | pcie_error->BridgeControlStatus >> 16)); |
| 131 | json_object_object_add(section_ir, "bridgeControlStatus", |
| 132 | bridge_control_status); |
| 133 | } |
Lawrence Tang | 4dbe3d7 | 2022-07-06 13:51:01 +0100 | [diff] [blame] | 134 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 135 | //Capability structure. |
| 136 | //The PCIe capability structure provided here could either be PCIe 1.1 Capability Structure |
Erwin Tsaur | 8870c07 | 2025-02-28 12:57:12 -0800 | [diff] [blame] | 137 | //(36-byte, padded to 60 bytes) or PCIe 2.0 Capability Structure (60-byte). |
| 138 | //Check the PCIe Capabilities Registers (offset 0x2) to determine the capability version. |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 139 | if (isvalid_prop_to_ir(&ui64Type, 6)) { |
Erwin Tsaur | 8870c07 | 2025-02-28 12:57:12 -0800 | [diff] [blame] | 140 | json_object_object_add(section_ir, "capabilityStructure", |
| 141 | pcie_capability_to_ir(pcie_error)); |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 142 | } |
Lawrence Tang | 4dbe3d7 | 2022-07-06 13:51:01 +0100 | [diff] [blame] | 143 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 144 | //AER information. |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 145 | if (isvalid_prop_to_ir(&ui64Type, 7)) { |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 146 | json_object_object_add(section_ir, "aerInfo", |
Erwin Tsaur | 8870c07 | 2025-02-28 12:57:12 -0800 | [diff] [blame] | 147 | pcie_aer_to_ir(pcie_error)); |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 148 | } |
Andrew Adriance | 3cebfc2 | 2024-11-20 12:57:04 -0800 | [diff] [blame] | 149 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 150 | return section_ir; |
Lawrence Tang | 3b7f45b | 2022-07-14 14:14:30 +0100 | [diff] [blame] | 151 | } |
| 152 | |
Erwin Tsaur | 8870c07 | 2025-02-28 12:57:12 -0800 | [diff] [blame] | 153 | //Converts PCIe Capability Structure section into JSON IR. |
| 154 | json_object *pcie_capability_to_ir(EFI_PCIE_ERROR_DATA *pcie_error) |
| 155 | { |
| 156 | int32_t encoded_len = 0; |
| 157 | char *encoded = NULL; |
| 158 | json_object *pcie_capability_ir = json_object_new_object(); |
| 159 | |
| 160 | encoded = base64_encode((UINT8 *)pcie_error->Capability.PcieCap, 60, |
| 161 | &encoded_len); |
| 162 | if (encoded == NULL) { |
| 163 | printf("Failed to allocate encode output buffer. \n"); |
| 164 | } else { |
| 165 | json_object_object_add(pcie_capability_ir, "data", |
| 166 | json_object_new_string_len(encoded, |
| 167 | encoded_len)); |
| 168 | free(encoded); |
| 169 | } |
| 170 | |
| 171 | json_object *fields_ir; |
| 172 | capability_registers *cap_decode; |
| 173 | cap_decode = (capability_registers *)&pcie_error->Capability.PcieCap; |
| 174 | |
| 175 | /* |
| 176 | * PCI Express Capability Structure Header |
| 177 | * Offset: 0x0 |
| 178 | */ |
| 179 | fields_ir = json_object_new_object(); |
| 180 | pcie_capability_header_t *pcie_cap_header = |
| 181 | &cap_decode->pcie_capability_header; |
| 182 | add_dict(fields_ir, "capability_id", pcie_cap_header->capability_id, |
| 183 | NULL, 0); |
| 184 | add_int(fields_ir, "next_capability_pointer", |
| 185 | pcie_cap_header->next_capability_pointer); |
| 186 | json_object_object_add(pcie_capability_ir, "pcie_capability_header", |
| 187 | fields_ir); |
| 188 | |
| 189 | /* |
| 190 | * PCI Express Capabilities Register |
| 191 | * Offset: 0x2 |
| 192 | */ |
| 193 | fields_ir = json_object_new_object(); |
| 194 | pcie_capabilities_t *pcie_cap = &cap_decode->pcie_capabilities; |
| 195 | add_int(fields_ir, "capability_version", pcie_cap->capability_version); |
| 196 | add_dict(fields_ir, "device_port_type", pcie_cap->device_port_type, |
| 197 | device_port_type_dict, device_port_type_dict_size); |
| 198 | add_bool(fields_ir, "slot_implemented", pcie_cap->slot_implemented); |
| 199 | add_int(fields_ir, "interrupt_message_number", |
| 200 | pcie_cap->interrupt_message_number); |
| 201 | //add_int(fields_ir, "undefined", pcie_cap->undefined); |
| 202 | add_bool_enum(fields_ir, "flit_mode_supported", supported_dict, |
| 203 | pcie_cap->flit_mode_supported); |
| 204 | json_object_object_add(pcie_capability_ir, "pcie_capabilities", |
| 205 | fields_ir); |
| 206 | |
| 207 | /* |
| 208 | * Device Capabilities Register |
| 209 | * Offset: 0x4 |
| 210 | */ |
| 211 | fields_ir = json_object_new_object(); |
| 212 | add_int(fields_ir, "max_payload_size_supported", |
| 213 | cap_decode->device_capabilities.max_payload_size_supported); |
| 214 | add_bool_enum( |
| 215 | fields_ir, "phantom_functions_supported", supported_dict, |
| 216 | cap_decode->device_capabilities.phantom_functions_supported); |
| 217 | add_bool_enum( |
| 218 | fields_ir, "extended_tag_field_supported", supported_dict, |
| 219 | cap_decode->device_capabilities.extended_tag_field_supported); |
| 220 | add_dict( |
| 221 | fields_ir, "endpoint_l0s_acceptable_latency", |
| 222 | cap_decode->device_capabilities.endpoint_l0s_acceptable_latency, |
| 223 | NULL, 0); |
| 224 | add_dict(fields_ir, "endpoint_l1_acceptable_latency", |
| 225 | cap_decode->device_capabilities.endpoint_l1_acceptable_latency, |
| 226 | NULL, 0); |
| 227 | //add_int(fields_ir, "undefined", |
| 228 | // cap_decode->device_capabilities.undefined); |
| 229 | add_bool(fields_ir, "role_based_error_reporting", |
| 230 | cap_decode->device_capabilities.role_based_error_reporting); |
| 231 | add_bool(fields_ir, "err_cor_subclass_capable", |
| 232 | cap_decode->device_capabilities.err_cor_subclass_capable); |
| 233 | add_int(fields_ir, "rx_mps_fixed", |
| 234 | cap_decode->device_capabilities.rx_mps_fixed); |
| 235 | add_int(fields_ir, "captured_slot_power_limit_value", |
| 236 | cap_decode->device_capabilities.captured_slot_power_limit_value); |
| 237 | add_int(fields_ir, "captured_slot_power_limit_scale", |
| 238 | cap_decode->device_capabilities.captured_slot_power_limit_scale); |
| 239 | add_bool_enum( |
| 240 | fields_ir, "function_level_reset_capability_supported", |
| 241 | supported_dict, |
| 242 | cap_decode->device_capabilities.function_level_reset_capability); |
| 243 | add_bool_enum(fields_ir, "mixed_mps_supported", supported_dict, |
| 244 | cap_decode->device_capabilities.mixed_mps_supported); |
| 245 | add_bool_enum(fields_ir, "tee_io_supported", supported_dict, |
| 246 | cap_decode->device_capabilities.tee_io_supported); |
| 247 | //add_int(fields_ir, "rsvdp", cap_decode->device_capabilities.rsvdp); |
| 248 | json_object_object_add(pcie_capability_ir, "device_capabilities", |
| 249 | fields_ir); |
| 250 | |
| 251 | /* |
| 252 | * Device Control Register |
| 253 | * Offset: 0x8 |
| 254 | */ |
| 255 | fields_ir = json_object_new_object(); |
| 256 | add_bool_enum( |
| 257 | fields_ir, "correctable_error_reporting_enable", enabled_dict, |
| 258 | cap_decode->device_control.correctable_error_reporting_enable); |
| 259 | add_bool_enum( |
| 260 | fields_ir, "non_fatal_error_reporting_enable", enabled_dict, |
| 261 | cap_decode->device_control.non_fatal_error_reporting_enable); |
| 262 | add_bool_enum(fields_ir, "fatal_error_reporting_enable", enabled_dict, |
| 263 | cap_decode->device_control.fatal_error_reporting_enable); |
| 264 | add_bool_enum( |
| 265 | fields_ir, "unsupported_request_reporting_enabled", |
| 266 | enabled_dict, |
| 267 | cap_decode->device_control.unsupported_request_reporting_enable); |
| 268 | add_bool_enum(fields_ir, "relaxed_ordering_enable", enabled_dict, |
| 269 | cap_decode->device_control.enable_relaxed_ordering); |
| 270 | add_int(fields_ir, "max_payload_size", |
| 271 | cap_decode->device_control.max_payload_size); |
| 272 | add_bool_enum(fields_ir, "extended_tag_field_enable", enabled_dict, |
| 273 | cap_decode->device_control.extended_tag_field_enable); |
| 274 | add_bool_enum(fields_ir, "phantom_functions_enable", enabled_dict, |
| 275 | cap_decode->device_control.phantom_functions_enable); |
| 276 | add_bool_enum(fields_ir, "aux_power_pm_enable", enabled_dict, |
| 277 | cap_decode->device_control.aux_power_pm_enable); |
| 278 | add_int(fields_ir, "enable_no_snoop", |
| 279 | cap_decode->device_control.enable_no_snoop); |
| 280 | add_int(fields_ir, "max_read_request_size", |
| 281 | cap_decode->device_control.max_read_request_size); |
| 282 | add_bool(fields_ir, "function_level_reset", |
| 283 | cap_decode->device_control.function_level_reset); |
| 284 | json_object_object_add(pcie_capability_ir, "device_control", fields_ir); |
| 285 | |
| 286 | /* |
| 287 | * Device Status Register |
| 288 | * Offset: 0xA |
| 289 | */ |
| 290 | fields_ir = json_object_new_object(); |
| 291 | add_bool(fields_ir, "correctable_error_detected", |
| 292 | cap_decode->device_status.correctable_error_detected); |
| 293 | add_bool(fields_ir, "non_fatal_error_detected", |
| 294 | cap_decode->device_status.non_fatal_error_detected); |
| 295 | add_bool(fields_ir, "fatal_error_detected", |
| 296 | cap_decode->device_status.fatal_error_detected); |
| 297 | add_bool(fields_ir, "unsupported_request_detected", |
| 298 | cap_decode->device_status.unsupported_request_detected); |
| 299 | add_bool(fields_ir, "aux_power_detected", |
| 300 | cap_decode->device_status.aux_power_detected); |
| 301 | add_bool(fields_ir, "transactions_pending", |
| 302 | cap_decode->device_status.transactions_pending); |
| 303 | add_int(fields_ir, "emergency_power_reduction", |
| 304 | cap_decode->device_status.emergency_power_reduction); |
| 305 | //add_int(fields_ir, "rsvdz", cap_decode->device_status.rsvdz); |
| 306 | json_object_object_add(pcie_capability_ir, "device_status", fields_ir); |
| 307 | |
| 308 | /* |
| 309 | * Link Capabilities Register |
| 310 | * Offset: 0xC |
| 311 | */ |
| 312 | fields_ir = json_object_new_object(); |
| 313 | add_int(fields_ir, "max_link_speed", |
| 314 | cap_decode->link_capabilities.max_link_speed); |
| 315 | add_int(fields_ir, "maximum_link_width", |
| 316 | cap_decode->link_capabilities.maximum_link_width); |
| 317 | add_int(fields_ir, "aspm_support", |
| 318 | cap_decode->link_capabilities.aspm_support); |
| 319 | add_int(fields_ir, "l0s_exit_latency", |
| 320 | cap_decode->link_capabilities.l0s_exit_latency); |
| 321 | add_int(fields_ir, "l1_exit_latency", |
| 322 | cap_decode->link_capabilities.l1_exit_latency); |
| 323 | add_bool(fields_ir, "clock_power_management", |
| 324 | cap_decode->link_capabilities.clock_power_management); |
| 325 | add_bool(fields_ir, "surprise_down_error_reporting_capable", |
| 326 | cap_decode->link_capabilities |
| 327 | .surprise_down_error_reporting_capable); |
| 328 | add_bool(fields_ir, "data_link_layer_link_active_reporting_capable", |
| 329 | cap_decode->link_capabilities |
| 330 | .data_link_layer_link_active_reporting_capable); |
| 331 | add_bool(fields_ir, "link_bandwidth_notification_capability", |
| 332 | cap_decode->link_capabilities |
| 333 | .link_bandwidth_notification_capability); |
| 334 | add_bool(fields_ir, "aspm_optionality_compliance", |
| 335 | cap_decode->link_capabilities.aspm_optionality_compliance); |
| 336 | //add_int(fields_ir, "rsvdp", cap_decode->link_capabilities.rsvdp); |
| 337 | add_int(fields_ir, "port_number", |
| 338 | cap_decode->link_capabilities.port_number); |
| 339 | json_object_object_add(pcie_capability_ir, "link_capabilities", |
| 340 | fields_ir); |
| 341 | |
| 342 | /* |
| 343 | * Link Control Register |
| 344 | * Offset: 0x10 |
| 345 | */ |
| 346 | fields_ir = json_object_new_object(); |
| 347 | add_int(fields_ir, "aspm_control", |
| 348 | cap_decode->link_control.aspm_control); |
| 349 | add_bool(fields_ir, "ptm_prop_delay_adaptation_interpretation", |
| 350 | cap_decode->link_control |
| 351 | .ptm_prop_delay_adaptation_interpretation); |
| 352 | //add_bool(fields_ir, "read_completion_boundary", |
| 353 | // cap_decode->link_control.read_completion_boundary); |
| 354 | add_int(fields_ir, "link_disable", |
| 355 | cap_decode->link_control.link_disable); |
| 356 | add_int(fields_ir, "retrain_link", |
| 357 | cap_decode->link_control.retrain_link); |
| 358 | //add_bool(fields_ir, "common_clock_configuration", |
| 359 | // cap_decode->link_control.common_clock_configuration); |
| 360 | add_int(fields_ir, "extended_synch", |
| 361 | cap_decode->link_control.extended_synch); |
| 362 | //add_bool(fields_ir, "enable_clock_power_management", |
| 363 | // cap_decode->link_control.enable_clock_power_management); |
| 364 | //add_bool(fields_ir, "hardware_autonomous_width_disable", |
| 365 | // cap_decode->link_control.hardware_autonomous_width_disable); |
| 366 | //add_bool(fields_ir, "link_bandwidth_management_interrupt_enable", |
| 367 | // cap_decode->link_control |
| 368 | // .link_bandwidth_management_interrupt_enable); |
| 369 | //add_bool(fields_ir, "link_autonomous_bandwidth_interrupt_enable", |
| 370 | // cap_decode->link_control |
| 371 | // .link_autonomous_bandwidth_interrupt_enable); |
| 372 | add_int(fields_ir, "sris_clocking", |
| 373 | cap_decode->link_control.sris_clocking); |
| 374 | add_int(fields_ir, "flit_mode_disable", |
| 375 | cap_decode->link_control.flit_mode_disable); |
| 376 | //add_bool(fields_ir, "drs_signaling_control", |
| 377 | // cap_decode->link_control.drs_signaling_control); |
| 378 | json_object_object_add(pcie_capability_ir, "link_control", fields_ir); |
| 379 | |
| 380 | /* |
| 381 | * Link Status Register |
| 382 | * Offset: 0x12 |
| 383 | */ |
| 384 | fields_ir = json_object_new_object(); |
| 385 | add_int(fields_ir, "current_link_speed", |
| 386 | cap_decode->link_status.current_link_speed); |
| 387 | add_int(fields_ir, "negotiated_link_width", |
| 388 | cap_decode->link_status.negotiated_link_width); |
| 389 | //add_int(fields_ir, "undefined", cap_decode->link_status.undefined); |
| 390 | add_int(fields_ir, "link_training", |
| 391 | cap_decode->link_status.link_training); |
| 392 | //add_bool(fields_ir, "slot_clock_configuration", |
| 393 | // cap_decode->link_status.slot_clock_configuration); |
| 394 | //add_bool(fields_ir, "data_link_layer_link_active", |
| 395 | // cap_decode->link_status.data_link_layer_link_active); |
| 396 | //add_bool(fields_ir, "link_bandwidth_management_status", |
| 397 | // cap_decode->link_status.link_bandwidth_management_status); |
| 398 | //add_bool(fields_ir, "link_autonomous_bandwidth_status", |
| 399 | // cap_decode->link_status.link_autonomous_bandwidth_status); |
| 400 | json_object_object_add(pcie_capability_ir, "link_status", fields_ir); |
| 401 | |
| 402 | /* |
| 403 | * Slot Capabilities Register |
| 404 | * Offset: 0x14 |
| 405 | */ |
| 406 | fields_ir = json_object_new_object(); |
| 407 | //add_bool(fields_ir, "attention_button_present", |
| 408 | // cap_decode->slot_capabilities.attention_button_present); |
| 409 | //add_bool(fields_ir, "power_controller_present", |
| 410 | // cap_decode->slot_capabilities.power_controller_present); |
| 411 | //add_bool(fields_ir, "mrl_sensor_present", |
| 412 | // cap_decode->slot_capabilities.mrl_sensor_present); |
| 413 | //add_bool(fields_ir, "attention_indicator_present", |
| 414 | // cap_decode->slot_capabilities.attention_indicator_present); |
| 415 | //add_bool(fields_ir, "power_indicator_present", |
| 416 | // cap_decode->slot_capabilities.power_indicator_present); |
| 417 | //add_bool(fields_ir, "hot_plug_surprise", |
| 418 | // cap_decode->slot_capabilities.hot_plug_surprise); |
| 419 | //add_bool(fields_ir, "hot_plug_capable", |
| 420 | // cap_decode->slot_capabilities.hot_plug_capable); |
| 421 | add_dict(fields_ir, "slot_power_limit_value", |
| 422 | cap_decode->slot_capabilities.slot_power_limit_value, NULL, 0); |
| 423 | add_int(fields_ir, "slot_power_limit_scale", |
| 424 | cap_decode->slot_capabilities.slot_power_limit_scale); |
| 425 | //add_bool(fields_ir, "electromechanical_interlock_present", |
| 426 | // cap_decode->slot_capabilities |
| 427 | // .electromechanical_interlock_present); |
| 428 | //add_bool(fields_ir, "no_command_completed_support", |
| 429 | // cap_decode->slot_capabilities.no_command_completed_support); |
| 430 | add_int(fields_ir, "physical_slot_number", |
| 431 | cap_decode->slot_capabilities.physical_slot_number); |
| 432 | json_object_object_add(pcie_capability_ir, "slot_capabilities", |
| 433 | fields_ir); |
| 434 | |
| 435 | /* |
| 436 | * Slot Control Register |
| 437 | * Offset: 0x18 |
| 438 | */ |
| 439 | fields_ir = json_object_new_object(); |
| 440 | //add_bool(fields_ir, "attention_button_pressed_enable", |
| 441 | // cap_decode->slot_control.attention_button_pressed_enable); |
| 442 | //add_bool(fields_ir, "power_fault_detected_enable", |
| 443 | // cap_decode->slot_control.power_fault_detected_enable); |
| 444 | //add_bool(fields_ir, "mrl_sensor_changed_enable", |
| 445 | // cap_decode->slot_control.mrl_sensor_changed_enable); |
| 446 | //add_bool(fields_ir, "presence_detect_changed_enable", |
| 447 | // cap_decode->slot_control.presence_detect_changed_enable); |
| 448 | //add_bool(fields_ir, "command_completed_interrupt_enable", |
| 449 | // cap_decode->slot_control.command_completed_interrupt_enable); |
| 450 | //add_bool(fields_ir, "hot_plug_interrupt_enable", |
| 451 | // cap_decode->slot_control.hot_plug_interrupt_enable); |
| 452 | add_int(fields_ir, "attention_indicator_control", |
| 453 | cap_decode->slot_control.attention_indicator_control); |
| 454 | add_int(fields_ir, "power_indicator_control", |
| 455 | cap_decode->slot_control.power_indicator_control); |
| 456 | //add_bool(fields_ir, "power_controller_control", |
| 457 | // cap_decode->slot_control.power_controller_control); |
| 458 | //add_bool(fields_ir, "electromechanical_interlock_control", |
| 459 | // cap_decode->slot_control.electromechanical_interlock_control); |
| 460 | //add_bool(fields_ir, "data_link_layer_state_changed_enable", |
| 461 | // cap_decode->slot_control.data_link_layer_state_changed_enable); |
| 462 | //add_bool(fields_ir, "auto_slot_power_limit_disable", |
| 463 | // cap_decode->slot_control.auto_slot_power_limit_disable); |
| 464 | //add_bool(fields_ir, "in_band_pd_disable", |
| 465 | // cap_decode->slot_control.in_band_pd_disable); |
| 466 | add_int(fields_ir, "rsvdp", cap_decode->slot_control.rsvdp); |
| 467 | json_object_object_add(pcie_capability_ir, "slot_control", fields_ir); |
| 468 | |
| 469 | /* |
| 470 | * Slot Status Register |
| 471 | * Offset: 0x1A |
| 472 | */ |
| 473 | fields_ir = json_object_new_object(); |
| 474 | //add_bool(fields_ir, "attention_button_pressed", |
| 475 | // cap_decode->slot_status.attention_button_pressed); |
| 476 | //add_bool(fields_ir, "power_fault_detected", |
| 477 | // cap_decode->slot_status.power_fault_detected); |
| 478 | add_int(fields_ir, "mrl_sensor_changed", |
| 479 | cap_decode->slot_status.mrl_sensor_changed); |
| 480 | //add_bool(fields_ir, "presence_detect_changed", |
| 481 | // cap_decode->slot_status.presence_detect_changed); |
| 482 | add_int(fields_ir, "command_completed", |
| 483 | cap_decode->slot_status.command_completed); |
| 484 | add_int(fields_ir, "mrl_sensor_state", |
| 485 | cap_decode->slot_status.mrl_sensor_state); |
| 486 | //add_bool(fields_ir, "presence_detect_state", |
| 487 | // cap_decode->slot_status.presence_detect_state); |
| 488 | //add_bool(fields_ir, "electromechanical_interlock_status", |
| 489 | // cap_decode->slot_status.electromechanical_interlock_status); |
| 490 | //add_bool(fields_ir, "data_link_layer_state_changed", |
| 491 | // cap_decode->slot_status.data_link_layer_state_changed); |
| 492 | //add_int(fields_ir, "rsvdz", cap_decode->slot_status.rsvdz); |
| 493 | json_object_object_add(pcie_capability_ir, "slot_status", fields_ir); |
| 494 | |
| 495 | /* |
| 496 | * Root Control Register |
| 497 | * Offset: 0x1C |
| 498 | */ |
| 499 | fields_ir = json_object_new_object(); |
| 500 | //add_bool(fields_ir, "system_error_on_correctable_error_enable", |
| 501 | // cap_decode->root_control |
| 502 | // .system_error_on_correctable_error_enable); |
| 503 | //add_bool( |
| 504 | // fields_ir, "system_error_on_non_fatal_error_enable", |
| 505 | // cap_decode->root_control.system_error_on_non_fatal_error_enable); |
| 506 | //add_bool(fields_ir, "system_error_on_fatal_error_enable", |
| 507 | // cap_decode->root_control.system_error_on_fatal_error_enable); |
| 508 | //add_bool(fields_ir, "pme_interrupt_enable", |
| 509 | // cap_decode->root_control.pme_interrupt_enable); |
| 510 | //add_bool(fields_ir, "configuration_rrs_software_visibility_enable", |
| 511 | // cap_decode->root_control |
| 512 | // .configuration_rrs_software_visibility_enable); |
| 513 | //add_bool(fields_ir, "no_nfm_subtree_below_this_root_port", |
| 514 | // cap_decode->root_control.no_nfm_subtree_below_this_root_port); |
| 515 | //add_int(fields_ir, "rsvdp", cap_decode->root_control.rsvdp); |
| 516 | json_object_object_add(pcie_capability_ir, "root_control", fields_ir); |
| 517 | |
| 518 | /* |
| 519 | * Root Capabilities Register |
| 520 | * Offset: 0x1E |
| 521 | */ |
| 522 | fields_ir = json_object_new_object(); |
| 523 | //add_bool(fields_ir, "configuraton_rrs_software_visibility", |
| 524 | // cap_decode->root_capabilities |
| 525 | // .configuraton_rrs_software_visibility); |
| 526 | //add_int(fields_ir, "rsvdp", cap_decode->root_capabilities.rsvdp); |
| 527 | json_object_object_add(pcie_capability_ir, "root_capabilities", |
| 528 | fields_ir); |
| 529 | |
| 530 | /* |
| 531 | * Root Status Register |
| 532 | * Offset: 0x20 |
| 533 | */ |
| 534 | fields_ir = json_object_new_object(); |
| 535 | add_int(fields_ir, "pme_requester_id", |
| 536 | cap_decode->root_status.pme_requester_id); |
| 537 | add_int(fields_ir, "pme_status", cap_decode->root_status.pme_status); |
| 538 | add_int(fields_ir, "pme_pending", cap_decode->root_status.pme_pending); |
| 539 | //add_int(fields_ir, "rsvdp", cap_decode->root_status.rsvdp); |
| 540 | json_object_object_add(pcie_capability_ir, "root_status", fields_ir); |
| 541 | |
| 542 | if (cap_decode->pcie_capabilities.capability_version < 2) { |
| 543 | return pcie_capability_ir; |
| 544 | } |
| 545 | |
| 546 | /* |
| 547 | * Device Capabilities 2 Register |
| 548 | * Offset: 0x24 |
| 549 | */ |
| 550 | fields_ir = json_object_new_object(); |
| 551 | add_int(fields_ir, "completion_timeout_ranges_supported", |
| 552 | cap_decode->device_capabilities2 |
| 553 | .completion_timeout_ranges_supported); |
| 554 | add_bool_enum(fields_ir, "completion_timeout_disable_supported", |
| 555 | supported_dict, |
| 556 | cap_decode->device_capabilities2 |
| 557 | .completion_timeout_disable_supported); |
| 558 | add_bool_enum( |
| 559 | fields_ir, "ari_forwarding_supported", supported_dict, |
| 560 | cap_decode->device_capabilities2.ari_forwarding_supported); |
| 561 | add_bool_enum( |
| 562 | fields_ir, "atomic_op_routing_supported", supported_dict, |
| 563 | cap_decode->device_capabilities2.atomic_op_routing_supported); |
| 564 | add_bool_enum(fields_ir, "_32_bit_atomicop_completer_supported", |
| 565 | supported_dict, |
| 566 | cap_decode->device_capabilities2 |
| 567 | ._32_bit_atomicop_completer_supported); |
| 568 | add_bool_enum(fields_ir, "_64_bit_atomicop_completer_supported", |
| 569 | supported_dict, |
| 570 | cap_decode->device_capabilities2 |
| 571 | ._64_bit_atomicop_completer_supported); |
| 572 | add_bool_enum(fields_ir, "_128_bit_cas_completer_supported", |
| 573 | supported_dict, |
| 574 | cap_decode->device_capabilities2 |
| 575 | ._128_bit_cas_completer_supported); |
| 576 | add_bool_enum( |
| 577 | fields_ir, "no_ro_enabled_pr_pr_passing", passing_dict, |
| 578 | cap_decode->device_capabilities2.no_ro_enabled_pr_pr_passing); |
| 579 | add_bool_enum(fields_ir, "ltr_mechanism_supported", supported_dict, |
| 580 | cap_decode->device_capabilities2.ltr_mechanism_supported); |
| 581 | add_bool_enum(fields_ir, "tph_completer_supported", supported_dict, |
| 582 | cap_decode->device_capabilities2.tph_completer_supported); |
| 583 | //add_int(fields_ir, "undefined", |
| 584 | // cap_decode->device_capabilities2.undefined); |
| 585 | //add_bool(fields_ir, "_10_bit_tag_completer_supported", |
| 586 | // cap_decode->device_capabilities2 |
| 587 | // ._10_bit_tag_completer_supported); |
| 588 | //add_bool(fields_ir, "_10_bit_tag_requester_supported", |
| 589 | // cap_decode->device_capabilities2 |
| 590 | // ._10_bit_tag_requester_supported); |
| 591 | add_bool_enum(fields_ir, "obff_supported", supported_dict, |
| 592 | cap_decode->device_capabilities2.obff_supported); |
| 593 | //add_bool(fields_ir, "extended_fmt_field_supported", |
| 594 | // cap_decode->device_capabilities2.extended_fmt_field_supported); |
| 595 | //add_bool(fields_ir, "end_end_tlp_prefix_supported", |
| 596 | // cap_decode->device_capabilities2.end_end_tlp_prefix_supported); |
| 597 | add_dict(fields_ir, "max_end_end_tlp_prefixes", |
| 598 | cap_decode->device_capabilities2.max_end_end_tlp_prefixes, |
| 599 | NULL, 0); |
| 600 | add_bool_enum(fields_ir, "emergency_power_reduction_supported", |
| 601 | supported_dict, |
| 602 | cap_decode->device_capabilities2 |
| 603 | .emergency_power_reduction_supported); |
| 604 | //add_bool(fields_ir, "emergency_power_reduction_init_required", |
| 605 | // cap_decode->device_capabilities2 |
| 606 | // .emergency_power_reduction_init_required); |
| 607 | //add_int(fields_ir, "rsvdp", cap_decode->device_capabilities2.rsvdp); |
| 608 | //add_bool(fields_ir, "dmwr_completer_supported", |
| 609 | // cap_decode->device_capabilities2.dmwr_completer_supported); |
| 610 | add_int(fields_ir, "dmwr_lengths_supported", |
| 611 | cap_decode->device_capabilities2.dmwr_lengths_supported); |
| 612 | //add_bool(fields_ir, "frs_supported", |
| 613 | // cap_decode->device_capabilities2.frs_supported); |
| 614 | json_object_object_add(pcie_capability_ir, "device_capabilities2", |
| 615 | fields_ir); |
| 616 | |
| 617 | /* |
| 618 | * Device Control 2 Register |
| 619 | * Offset: 0x28 |
| 620 | */ |
| 621 | fields_ir = json_object_new_object(); |
| 622 | add_int(fields_ir, "completion_timeout_value", |
| 623 | cap_decode->device_control2.completion_timeout_value); |
| 624 | //add_bool(fields_ir, "completion_timeout_disable", |
| 625 | // cap_decode->device_control2.completion_timeout_disable); |
| 626 | add_bool(fields_ir, "ari_forwarding_enable", |
| 627 | cap_decode->device_control2.ari_forwarding_enable); |
| 628 | add_bool(fields_ir, "atomicop_requester_enable", |
| 629 | cap_decode->device_control2.atomicop_requester_enable); |
| 630 | add_bool(fields_ir, "atomicop_egress_blocking", |
| 631 | cap_decode->device_control2.atomicop_egress_blocking); |
| 632 | add_bool(fields_ir, "ido_request_enable", |
| 633 | cap_decode->device_control2.ido_request_enable); |
| 634 | add_bool(fields_ir, "ido_completion_enable", |
| 635 | cap_decode->device_control2.ido_completion_enable); |
| 636 | add_bool(fields_ir, "ltr_mechanism_enable", |
| 637 | cap_decode->device_control2.ltr_mechanism_enable); |
| 638 | add_bool(fields_ir, "emergency_power_reduction_request", |
| 639 | cap_decode->device_control2.emergency_power_reduction_request); |
| 640 | add_bool(fields_ir, "10_bit_tag_requester_enable", |
| 641 | cap_decode->device_control2._10_bit_tag_requester_enable); |
| 642 | add_int(fields_ir, "obff_enable", |
| 643 | cap_decode->device_control2.obff_enable); |
| 644 | //add_bool(fields_ir, "end_end_tlp_prefix_blocking", |
| 645 | // cap_decode->device_control2.end_end_tlp_prefix_blocking); |
| 646 | json_object_object_add(pcie_capability_ir, "device_control2", |
| 647 | fields_ir); |
| 648 | |
| 649 | /* |
| 650 | * Device Status 2 Register |
| 651 | * Offset: 0x2A |
| 652 | */ |
| 653 | fields_ir = json_object_new_object(); |
| 654 | //add_int(fields_ir, "rsvdz", cap_decode->device_status2.rsvdz); |
| 655 | json_object_object_add(pcie_capability_ir, "device_status2", fields_ir); |
| 656 | |
| 657 | /* |
| 658 | * Link Capabilities 2 Register |
| 659 | * Offset: 0x2C |
| 660 | */ |
| 661 | fields_ir = json_object_new_object(); |
| 662 | //add_int(fields_ir, "rsvdp", cap_decode->link_capabilities2.rsvdp); |
| 663 | add_int(fields_ir, "supported_link_speeds", |
| 664 | cap_decode->link_capabilities2.supported_link_speeds_register); |
| 665 | add_bool_enum(fields_ir, "crosslink_supported", supported_dict, |
| 666 | cap_decode->link_capabilities2.crosslink_supported); |
| 667 | add_int(fields_ir, "lower_skp_os_generation_supported", |
| 668 | cap_decode->link_capabilities2 |
| 669 | .lower_skp_os_generation_supported); |
| 670 | add_int(fields_ir, "lower_skp_os_reception_supported", |
| 671 | cap_decode->link_capabilities2.lower_skp_os_reception_supported); |
| 672 | add_bool_enum(fields_ir, "retimer_presence_detect_supported", |
| 673 | supported_dict, |
| 674 | cap_decode->link_capabilities2 |
| 675 | .retimer_presence_detect_supported); |
| 676 | add_bool_enum(fields_ir, "two_retimers_presence_detect_supported", |
| 677 | supported_dict, |
| 678 | cap_decode->link_capabilities2 |
| 679 | .two_retimers_presence_detect_supported); |
| 680 | //add_int(fields_ir, "reserved", cap_decode->link_capabilities2.reserved); |
| 681 | add_bool_enum(fields_ir, "drs_supported", supported_dict, |
| 682 | cap_decode->link_capabilities2.drs_supported); |
| 683 | json_object_object_add(pcie_capability_ir, "link_capabilities2", |
| 684 | fields_ir); |
| 685 | |
| 686 | /* |
| 687 | * Link Control 2 Register |
| 688 | * Offset: 0x30 |
| 689 | */ |
| 690 | fields_ir = json_object_new_object(); |
| 691 | add_dict(fields_ir, "target_link_speed", |
| 692 | cap_decode->link_control2.target_link_speed, NULL, 0); |
| 693 | add_bool_enum(fields_ir, "enter_compliance", supported_dict, |
| 694 | cap_decode->link_control2.enter_compliance); |
| 695 | add_dict(fields_ir, "hardware_autonomous_speed_disable", |
| 696 | cap_decode->link_control2.hardware_autonomous_speed_disable, |
| 697 | NULL, 0); |
| 698 | add_bool(fields_ir, "selectable_de_emphasis", |
| 699 | cap_decode->link_control2.selectable_de_emphasis); |
| 700 | add_int(fields_ir, "transmit_margin", |
| 701 | cap_decode->link_control2.transmit_margin); |
| 702 | add_bool(fields_ir, "enter_modified_compliance", |
| 703 | cap_decode->link_control2.enter_modified_compliance); |
| 704 | add_bool(fields_ir, "compliance_sos", |
| 705 | cap_decode->link_control2.compliance_sos); |
| 706 | add_int(fields_ir, "compliance_preset_de_emphasis", |
| 707 | cap_decode->link_control2.compliance_preset_de_emphasis); |
| 708 | json_object_object_add(pcie_capability_ir, "link_control2", fields_ir); |
| 709 | |
| 710 | /* |
| 711 | * Link Status 2 Register |
| 712 | * Offset: 0x32 |
| 713 | */ |
| 714 | fields_ir = json_object_new_object(); |
| 715 | add_int(fields_ir, "current_de_emphasis_level", |
| 716 | cap_decode->link_status2.current_de_emphasis_level); |
| 717 | add_bool(fields_ir, "equalization_8gts_complete", |
| 718 | cap_decode->link_status2.equalization_8gts_complete); |
| 719 | add_bool(fields_ir, "equalization_8gts_phase1_successful", |
| 720 | cap_decode->link_status2.equalization_8gts_phase1_successful); |
| 721 | add_bool(fields_ir, "equalization_8gts_phase2_successful", |
| 722 | cap_decode->link_status2.equalization_8gts_phase2_successful); |
| 723 | add_bool(fields_ir, "equalization_8gts_phase3_successful", |
| 724 | cap_decode->link_status2.equalization_8gts_phase3_successful); |
| 725 | add_bool(fields_ir, "link_equalization_request_8gts", |
| 726 | cap_decode->link_status2.link_equalization_request_8gts); |
| 727 | add_bool(fields_ir, "retimer_presence_detected", |
| 728 | cap_decode->link_status2.retimer_presence_detected); |
| 729 | add_bool(fields_ir, "two_retimers_presence_detected", |
| 730 | cap_decode->link_status2.two_retimers_presence_detected); |
| 731 | add_int(fields_ir, "crosslink_resolution", |
| 732 | cap_decode->link_status2.crosslink_resolution); |
| 733 | add_int(fields_ir, "flit_mode_status", |
| 734 | cap_decode->link_status2.flit_mode_status); |
| 735 | //add_int(fields_ir, "rsvdz", cap_decode->link_status2.rsvdz); |
| 736 | add_int(fields_ir, "downstream_component_presence", |
| 737 | cap_decode->link_status2.downstream_component_presence); |
| 738 | add_bool(fields_ir, "drs_message_received", |
| 739 | cap_decode->link_status2.drs_message_received); |
| 740 | json_object_object_add(pcie_capability_ir, "link_status2", fields_ir); |
| 741 | |
| 742 | /* |
| 743 | * Slot Capabilities 2 Register |
| 744 | * Offset: 0x34 |
| 745 | */ |
| 746 | fields_ir = json_object_new_object(); |
| 747 | //add_int(fields_ir, "rsvdp", cap_decode->slot_capabilities2.rsvdp); |
| 748 | json_object_object_add(pcie_capability_ir, "slot_capabilities2", |
| 749 | fields_ir); |
| 750 | |
| 751 | /* |
| 752 | * Slot Control 2 Register |
| 753 | * Offset: 0x38 |
| 754 | */ |
| 755 | fields_ir = json_object_new_object(); |
| 756 | //add_int(fields_ir, "rsvdp", cap_decode->slot_control2.rsvdp); |
| 757 | json_object_object_add(pcie_capability_ir, "slot_control2", fields_ir); |
| 758 | |
| 759 | /* |
| 760 | * Slot Status 2 Register |
| 761 | * Offset: 0x3A |
| 762 | */ |
| 763 | fields_ir = json_object_new_object(); |
| 764 | //add_int(fields_ir, "rsvdp", cap_decode->slot_status2.rsvdp); |
| 765 | json_object_object_add(pcie_capability_ir, "slot_status2", fields_ir); |
| 766 | |
| 767 | return pcie_capability_ir; |
| 768 | } |
| 769 | |
| 770 | //Converts PCIe Capability Structure section into JSON IR. |
| 771 | json_object *pcie_aer_to_ir(EFI_PCIE_ERROR_DATA *pcie_error) |
| 772 | { |
| 773 | int32_t encoded_len = 0; |
| 774 | char *encoded = NULL; |
| 775 | json_object *aer_capability_ir = json_object_new_object(); |
| 776 | |
| 777 | encoded = base64_encode((UINT8 *)pcie_error->AerInfo.PcieAer, 96, |
| 778 | &encoded_len); |
| 779 | if (encoded == NULL) { |
| 780 | printf("Failed to allocate encode output buffer. \n"); |
| 781 | } else { |
| 782 | json_object_object_add(aer_capability_ir, "data", |
| 783 | json_object_new_string_len(encoded, |
| 784 | encoded_len)); |
| 785 | free(encoded); |
| 786 | } |
| 787 | |
| 788 | json_object *fields_ir; |
| 789 | |
| 790 | aer_info_registers *aer_decode; |
| 791 | aer_decode = (aer_info_registers *)&pcie_error->AerInfo.PcieAer; |
| 792 | |
| 793 | /* |
| 794 | * AER Capability Header |
| 795 | * Offset: 0x0 |
| 796 | */ |
| 797 | fields_ir = json_object_new_object(); |
| 798 | add_int(fields_ir, "capability_id", |
| 799 | aer_decode->capability_header.capability_id); |
| 800 | add_int(fields_ir, "capability_version", |
| 801 | aer_decode->capability_header.capability_version); |
| 802 | add_int(fields_ir, "next_capability_offset", |
| 803 | aer_decode->capability_header.next_capability_offset); |
| 804 | json_object_object_add(aer_capability_ir, "capability_header", |
| 805 | fields_ir); |
| 806 | |
| 807 | /* |
| 808 | * Uncorrectable Error Status Register |
| 809 | * Offset: 0x4 |
| 810 | */ |
| 811 | fields_ir = json_object_new_object(); |
| 812 | //add_bool(fields_ir, "undefined", |
| 813 | // aer_decode->uncorrectable_error_status.undefined); |
| 814 | //add_int(fields_ir, "rsvdz1", |
| 815 | // aer_decode->uncorrectable_error_status.rsvdz1); |
| 816 | add_bool(fields_ir, "data_link_protocol_error_status", |
| 817 | aer_decode->uncorrectable_error_status |
| 818 | .data_link_protocol_error_status); |
| 819 | add_bool(fields_ir, "surprise_down_error_status", |
| 820 | aer_decode->uncorrectable_error_status |
| 821 | .surprise_down_error_status); |
| 822 | //add_int(fields_ir, "rsvdz2", |
| 823 | // aer_decode->uncorrectable_error_status.rsvdz2); |
| 824 | add_bool(fields_ir, "poisoned_tlp_received", |
| 825 | aer_decode->uncorrectable_error_status.poisoned_tlp_received); |
| 826 | add_bool(fields_ir, "flow_control_protocol_error_status", |
| 827 | aer_decode->uncorrectable_error_status |
| 828 | .flow_control_protocol_error_status); |
| 829 | add_bool(fields_ir, "completion_timeout_status", |
| 830 | aer_decode->uncorrectable_error_status |
| 831 | .completion_timeout_status); |
| 832 | add_bool(fields_ir, "completer_abort_status", |
| 833 | aer_decode->uncorrectable_error_status.completer_abort_status); |
| 834 | add_bool(fields_ir, "unexpected_completion_status", |
| 835 | aer_decode->uncorrectable_error_status |
| 836 | .unexpected_completion_status); |
| 837 | add_bool( |
| 838 | fields_ir, "receiver_overflow_status", |
| 839 | aer_decode->uncorrectable_error_status.receiver_overflow_status); |
| 840 | add_bool(fields_ir, "malformed_tlp_status", |
| 841 | aer_decode->uncorrectable_error_status.malformed_tlp_status); |
| 842 | add_bool(fields_ir, "ecrc_error_status", |
| 843 | aer_decode->uncorrectable_error_status.ecrc_error_status); |
| 844 | add_bool(fields_ir, "unsupported_request_error_status", |
| 845 | aer_decode->uncorrectable_error_status |
| 846 | .unsupported_request_error_status); |
| 847 | add_bool(fields_ir, "acs_violation_status", |
| 848 | aer_decode->uncorrectable_error_status.acs_violation_status); |
| 849 | add_bool(fields_ir, "uncorrectable_internal_error_status", |
| 850 | aer_decode->uncorrectable_error_status |
| 851 | .uncorrectable_internal_error_status); |
| 852 | add_bool(fields_ir, "mc_blocked_tlp_status", |
| 853 | aer_decode->uncorrectable_error_status.mc_blocked_tlp_status); |
| 854 | add_bool(fields_ir, "atomicop_egress_blocked_status", |
| 855 | aer_decode->uncorrectable_error_status |
| 856 | .atomicop_egress_blocked_status); |
| 857 | add_bool(fields_ir, "tlp_prefix_blocked_error_status", |
| 858 | aer_decode->uncorrectable_error_status |
| 859 | .tlp_prefix_blocked_error_status); |
| 860 | add_bool(fields_ir, "poisoned_tlp_egress_blocked_status", |
| 861 | aer_decode->uncorrectable_error_status |
| 862 | .poisoned_tlp_egress_blocked_status); |
| 863 | add_bool(fields_ir, "dmwr_request_egress_blocked_status", |
| 864 | aer_decode->uncorrectable_error_status |
| 865 | .dmwr_request_egress_blocked_status); |
| 866 | add_bool( |
| 867 | fields_ir, "ide_check_failed_status", |
| 868 | aer_decode->uncorrectable_error_status.ide_check_failed_status); |
| 869 | add_bool( |
| 870 | fields_ir, "misrouted_ide_tlp_status", |
| 871 | aer_decode->uncorrectable_error_status.misrouted_ide_tlp_status); |
| 872 | add_bool( |
| 873 | fields_ir, "pcrc_check_failed_status", |
| 874 | aer_decode->uncorrectable_error_status.pcrc_check_failed_status); |
| 875 | add_bool(fields_ir, "tlp_translation_egress_blocked_status", |
| 876 | aer_decode->uncorrectable_error_status |
| 877 | .tlp_translation_egress_blocked_status); |
| 878 | json_object_object_add(aer_capability_ir, "uncorrectable_error_status", |
| 879 | fields_ir); |
| 880 | |
| 881 | /* |
| 882 | * Uncorrectable Error Mask Register |
| 883 | * Offset: 0x8 |
| 884 | */ |
| 885 | fields_ir = json_object_new_object(); |
| 886 | //add_bool(fields_ir, "undefined", |
| 887 | // aer_decode->uncorrectable_error_mask.undefined); |
| 888 | //add_int(fields_ir, "rsvdz1", |
| 889 | // aer_decode->uncorrectable_error_mask.rsvdz1); |
| 890 | add_int(fields_ir, "data_link_protocol_error_mask", |
| 891 | aer_decode->uncorrectable_error_mask |
| 892 | .data_link_protocol_error_mask); |
| 893 | add_int(fields_ir, "surprise_down_error_mask", |
| 894 | aer_decode->uncorrectable_error_mask.surprise_down_error_mask); |
| 895 | //add_int(fields_ir, "rsvdz2", |
| 896 | // aer_decode->uncorrectable_error_mask.rsvdz2); |
| 897 | add_int(fields_ir, "poisoned_tlp_received_mask", |
| 898 | aer_decode->uncorrectable_error_mask.poisoned_tlp_received_mask); |
| 899 | add_int(fields_ir, "flow_control_protocol_error_mask", |
| 900 | aer_decode->uncorrectable_error_mask |
| 901 | .flow_control_protocol_error_mask); |
| 902 | add_int(fields_ir, "completion_timeout_mask", |
| 903 | aer_decode->uncorrectable_error_mask.completion_timeout_mask); |
| 904 | add_int(fields_ir, "completer_abort_mask", |
| 905 | aer_decode->uncorrectable_error_mask.completer_abort_mask); |
| 906 | add_int(fields_ir, "unexpected_completion_mask", |
| 907 | aer_decode->uncorrectable_error_mask.unexpected_completion_mask); |
| 908 | add_int(fields_ir, "receiver_overflow_mask", |
| 909 | aer_decode->uncorrectable_error_mask.receiver_overflow_mask); |
| 910 | add_int(fields_ir, "malformed_tlp_mask", |
| 911 | aer_decode->uncorrectable_error_mask.malformed_tlp_mask); |
| 912 | add_int(fields_ir, "ecrc_error_mask", |
| 913 | aer_decode->uncorrectable_error_mask.ecrc_error_mask); |
| 914 | add_int(fields_ir, "unsupported_request_error_mask", |
| 915 | aer_decode->uncorrectable_error_mask |
| 916 | .unsupported_request_error_mask); |
| 917 | add_int(fields_ir, "acs_violation_mask", |
| 918 | aer_decode->uncorrectable_error_mask.acs_violation_mask); |
| 919 | add_int(fields_ir, "uncorrectable_internal_error_mask", |
| 920 | aer_decode->uncorrectable_error_mask |
| 921 | .uncorrectable_internal_error_mask); |
| 922 | add_int(fields_ir, "mc_blocked_tlp_mask", |
| 923 | aer_decode->uncorrectable_error_mask.mc_blocked_tlp_mask); |
| 924 | add_int(fields_ir, "atomicop_egress_blocked_mask", |
| 925 | aer_decode->uncorrectable_error_mask |
| 926 | .atomicop_egress_blocked_mask); |
| 927 | add_int(fields_ir, "tlp_prefix_blocked_error_mask", |
| 928 | aer_decode->uncorrectable_error_mask |
| 929 | .tlp_prefix_blocked_error_mask); |
| 930 | add_int(fields_ir, "poisoned_tlp_egress_blocked_mask", |
| 931 | aer_decode->uncorrectable_error_mask |
| 932 | .poisoned_tlp_egress_blocked_mask); |
| 933 | add_int(fields_ir, "dmwr_request_egress_blocked_mask", |
| 934 | aer_decode->uncorrectable_error_mask |
| 935 | .dmwr_request_egress_blocked_mask); |
| 936 | add_int(fields_ir, "ide_check_failed_mask", |
| 937 | aer_decode->uncorrectable_error_mask.ide_check_failed_mask); |
| 938 | add_int(fields_ir, "misrouted_ide_tlp_mask", |
| 939 | aer_decode->uncorrectable_error_mask.misrouted_ide_tlp_mask); |
| 940 | add_int(fields_ir, "pcrc_check_failed_mask", |
| 941 | aer_decode->uncorrectable_error_mask.pcrc_check_failed_mask); |
| 942 | add_int(fields_ir, "tlp_translation_egress_blocked_mask", |
| 943 | aer_decode->uncorrectable_error_mask |
| 944 | .tlp_translation_egress_blocked_mask); |
| 945 | json_object_object_add(aer_capability_ir, "uncorrectable_error_mask", |
| 946 | fields_ir); |
| 947 | |
| 948 | /* |
| 949 | * Uncorrectable Error Severity Register |
| 950 | * Offset: 0xC |
| 951 | */ |
| 952 | fields_ir = json_object_new_object(); |
| 953 | //add_bool(fields_ir, "undefined", |
| 954 | // aer_decode->uncorrectable_error_severity.undefined); |
| 955 | //add_int(fields_ir, "rsvdz1", |
| 956 | // aer_decode->uncorrectable_error_severity.rsvdz1); |
| 957 | add_bool_enum(fields_ir, "data_link_protocol_error_severity", |
| 958 | severity_dict, |
| 959 | aer_decode->uncorrectable_error_severity |
| 960 | .data_link_protocol_error_severity); |
| 961 | add_bool_enum(fields_ir, "surprise_down_error_severity", severity_dict, |
| 962 | aer_decode->uncorrectable_error_severity |
| 963 | .surprise_down_error_severity); |
| 964 | //add_int(fields_ir, "rsvdz2", |
| 965 | // aer_decode->uncorrectable_error_severity.rsvdz2); |
| 966 | add_bool_enum(fields_ir, "poisoned_tlp_received_severity", |
| 967 | severity_dict, |
| 968 | aer_decode->uncorrectable_error_severity |
| 969 | .poisoned_tlp_received_severity); |
| 970 | add_bool_enum(fields_ir, "flow_control_protocol_error_severity", |
| 971 | severity_dict, |
| 972 | aer_decode->uncorrectable_error_severity |
| 973 | .flow_control_protocol_error_severity); |
| 974 | add_bool_enum(fields_ir, "completion_timeout_severity", severity_dict, |
| 975 | aer_decode->uncorrectable_error_severity |
| 976 | .completion_timeout_severity); |
| 977 | add_bool_enum(fields_ir, "completer_abort_severity", severity_dict, |
| 978 | aer_decode->uncorrectable_error_severity |
| 979 | .completer_abort_severity); |
| 980 | add_bool_enum(fields_ir, "unexpected_completion_severity", |
| 981 | severity_dict, |
| 982 | aer_decode->uncorrectable_error_severity |
| 983 | .unexpected_completion_severity); |
| 984 | add_bool_enum(fields_ir, "receiver_overflow_severity", severity_dict, |
| 985 | aer_decode->uncorrectable_error_severity |
| 986 | .receiver_overflow_severity); |
| 987 | add_bool_enum( |
| 988 | fields_ir, "malformed_tlp_severity", severity_dict, |
| 989 | aer_decode->uncorrectable_error_severity.malformed_tlp_severity); |
| 990 | add_bool_enum( |
| 991 | fields_ir, "ecrc_error_severity", severity_dict, |
| 992 | aer_decode->uncorrectable_error_severity.ecrc_error_severity); |
| 993 | add_bool_enum(fields_ir, "unsupported_request_error_severity", |
| 994 | severity_dict, |
| 995 | aer_decode->uncorrectable_error_severity |
| 996 | .unsupported_request_error_severity); |
| 997 | add_bool_enum( |
| 998 | fields_ir, "acs_violation_severity", severity_dict, |
| 999 | aer_decode->uncorrectable_error_severity.acs_violation_severity); |
| 1000 | add_bool_enum(fields_ir, "uncorrectable_internal_error_severity", |
| 1001 | severity_dict, |
| 1002 | aer_decode->uncorrectable_error_severity |
| 1003 | .uncorrectable_internal_error_severity); |
| 1004 | add_bool_enum(fields_ir, "mc_blocked_tlp_severity", severity_dict, |
| 1005 | aer_decode->uncorrectable_error_severity |
| 1006 | .mc_blocked_tlp_severity); |
| 1007 | add_bool_enum(fields_ir, "atomicop_egress_blocked_severity", |
| 1008 | severity_dict, |
| 1009 | aer_decode->uncorrectable_error_severity |
| 1010 | .atomicop_egress_blocked_severity); |
| 1011 | add_bool_enum(fields_ir, "tlp_prefix_blocked_error_severity", |
| 1012 | severity_dict, |
| 1013 | aer_decode->uncorrectable_error_severity |
| 1014 | .tlp_prefix_blocked_error_severity); |
| 1015 | add_bool_enum(fields_ir, "poisoned_tlp_egress_blocked_severity", |
| 1016 | severity_dict, |
| 1017 | aer_decode->uncorrectable_error_severity |
| 1018 | .poisoned_tlp_egress_blocked_severity); |
| 1019 | add_bool_enum(fields_ir, "dmwr_request_egress_blocked_severity", |
| 1020 | severity_dict, |
| 1021 | aer_decode->uncorrectable_error_severity |
| 1022 | .dmwr_request_egress_blocked_severity); |
| 1023 | add_bool_enum(fields_ir, "ide_check_failed_severity", severity_dict, |
| 1024 | aer_decode->uncorrectable_error_severity |
| 1025 | .ide_check_failed_severity); |
| 1026 | add_bool_enum(fields_ir, "misrouted_ide_tlp_severity", severity_dict, |
| 1027 | aer_decode->uncorrectable_error_severity |
| 1028 | .misrouted_ide_tlp_severity); |
| 1029 | add_bool_enum(fields_ir, "pcrc_check_failed_severity", severity_dict, |
| 1030 | aer_decode->uncorrectable_error_severity |
| 1031 | .pcrc_check_failed_severity); |
| 1032 | add_bool_enum(fields_ir, "tlp_translation_egress_blocked_severity", |
| 1033 | severity_dict, |
| 1034 | aer_decode->uncorrectable_error_severity |
| 1035 | .tlp_translation_egress_blocked_severity); |
| 1036 | json_object_object_add(aer_capability_ir, |
| 1037 | "uncorrectable_error_severity", fields_ir); |
| 1038 | |
| 1039 | /* |
| 1040 | * Correctable Error Status Register |
| 1041 | * Offset: 0x10 |
| 1042 | */ |
| 1043 | fields_ir = json_object_new_object(); |
| 1044 | add_bool(fields_ir, "receiver_error_status", |
| 1045 | aer_decode->correctable_error_status.receiver_error_status); |
| 1046 | //add_int(fields_ir, "rsvdz1", |
| 1047 | // aer_decode->correctable_error_status.rsvdz1); |
| 1048 | add_bool(fields_ir, "bad_tlp_status", |
| 1049 | aer_decode->correctable_error_status.bad_tlp_status); |
| 1050 | add_bool(fields_ir, "bad_dllp_status", |
| 1051 | aer_decode->correctable_error_status.bad_dllp_status); |
| 1052 | add_bool( |
| 1053 | fields_ir, "replay_num_rollover_status", |
| 1054 | aer_decode->correctable_error_status.replay_num_rollover_status); |
| 1055 | //add_int(fields_ir, "rsvdz2", |
| 1056 | // aer_decode->correctable_error_status.rsvdz2); |
| 1057 | add_bool(fields_ir, "replay_timer_timeout_status", |
| 1058 | aer_decode->correctable_error_status |
| 1059 | .replay_timer_timeout_status); |
| 1060 | add_bool(fields_ir, "advisory_non_fatal_error_status", |
| 1061 | aer_decode->correctable_error_status |
| 1062 | .advisory_non_fatal_error_status); |
| 1063 | add_bool(fields_ir, "corrected_internal_error_status", |
| 1064 | aer_decode->correctable_error_status |
| 1065 | .corrected_internal_error_status); |
| 1066 | add_bool( |
| 1067 | fields_ir, "header_log_overflow_status", |
| 1068 | aer_decode->correctable_error_status.header_log_overflow_status); |
| 1069 | //add_int(fields_ir, "rsvdz3", |
| 1070 | // aer_decode->correctable_error_status.rsvdz3); |
| 1071 | json_object_object_add(aer_capability_ir, "correctable_error_status", |
| 1072 | fields_ir); |
| 1073 | |
| 1074 | /* |
| 1075 | * Correctable Error Mask Register |
| 1076 | * Offset: 0x14 |
| 1077 | */ |
| 1078 | fields_ir = json_object_new_object(); |
| 1079 | add_int(fields_ir, "receiver_error_mask", |
| 1080 | aer_decode->correctable_error_mask.receiver_error_mask); |
| 1081 | //add_int(fields_ir, "rsvdz1", aer_decode->correctable_error_mask.rsvdz1); |
| 1082 | add_int(fields_ir, "bad_tlp_mask", |
| 1083 | aer_decode->correctable_error_mask.bad_tlp_mask); |
| 1084 | add_int(fields_ir, "bad_dllp_mask", |
| 1085 | aer_decode->correctable_error_mask.bad_dllp_mask); |
| 1086 | add_int(fields_ir, "replay_num_rollover_mask", |
| 1087 | aer_decode->correctable_error_mask.replay_num_rollover_mask); |
| 1088 | //add_int(fields_ir, "rsvdz2", aer_decode->correctable_error_mask.rsvdz2); |
| 1089 | add_int(fields_ir, "replay_timer_timeout_mask", |
| 1090 | aer_decode->correctable_error_mask.replay_timer_timeout_mask); |
| 1091 | add_int(fields_ir, "advisory_non_fatal_error_mask", |
| 1092 | aer_decode->correctable_error_mask |
| 1093 | .advisory_non_fatal_error_mask); |
| 1094 | add_int(fields_ir, "corrected_internal_error_mask", |
| 1095 | aer_decode->correctable_error_mask |
| 1096 | .corrected_internal_error_mask); |
| 1097 | add_int(fields_ir, "header_log_overflow_mask", |
| 1098 | aer_decode->correctable_error_mask.header_log_overflow_mask); |
| 1099 | //add_int(fields_ir, "rsvdz3", aer_decode->correctable_error_mask.rsvdz3); |
| 1100 | json_object_object_add(aer_capability_ir, "correctable_error_mask", |
| 1101 | fields_ir); |
| 1102 | |
| 1103 | /* |
| 1104 | * Advanced Error Capabilities and Control Register |
| 1105 | * Offset: 0x18 |
| 1106 | */ |
| 1107 | fields_ir = json_object_new_object(); |
| 1108 | add_int(fields_ir, "first_error_pointer", |
| 1109 | aer_decode->advanced_error_capabilities_and_control |
| 1110 | .first_error_pointer); |
| 1111 | //add_bool(fields_ir, "ecrc_generation_capable", |
| 1112 | // aer_decode->advanced_error_capabilities_and_control |
| 1113 | // .ecrc_generation_capable); |
| 1114 | //add_bool(fields_ir, "ecrc_generation_enable", |
| 1115 | // aer_decode->advanced_error_capabilities_and_control |
| 1116 | // .ecrc_generation_enable); |
| 1117 | //add_bool(fields_ir, "ecrc_check_capable", |
| 1118 | // aer_decode->advanced_error_capabilities_and_control |
| 1119 | // .ecrc_check_capable); |
| 1120 | //add_bool(fields_ir, "ecrc_check_enable", |
| 1121 | // aer_decode->advanced_error_capabilities_and_control |
| 1122 | // .ecrc_check_enable); |
| 1123 | //add_bool(fields_ir, "multiple_header_recording_capable", |
| 1124 | // aer_decode->advanced_error_capabilities_and_control |
| 1125 | // .multiple_header_recording_capable); |
| 1126 | //add_bool(fields_ir, "multiple_header_recording_enable", |
| 1127 | // aer_decode->advanced_error_capabilities_and_control |
| 1128 | // .multiple_header_recording_enable); |
| 1129 | //add_bool(fields_ir, "tlp_prefix_log_present", |
| 1130 | // aer_decode->advanced_error_capabilities_and_control |
| 1131 | // .tlp_prefix_log_present); |
| 1132 | //add_bool(fields_ir, "completion_timeout_prefix_header_log_capable", |
| 1133 | // aer_decode->advanced_error_capabilities_and_control |
| 1134 | // .completion_timeout_prefix_header_log_capable); |
| 1135 | add_int(fields_ir, "header_log_size", |
| 1136 | aer_decode->advanced_error_capabilities_and_control |
| 1137 | .header_log_size); |
| 1138 | //add_bool(fields_ir, "logged_tlp_was_flit_mode", |
| 1139 | // aer_decode->advanced_error_capabilities_and_control |
| 1140 | // .logged_tlp_was_flit_mode); |
| 1141 | add_int(fields_ir, "logged_tlp_size", |
| 1142 | aer_decode->advanced_error_capabilities_and_control |
| 1143 | .logged_tlp_size); |
| 1144 | //add_int(fields_ir, "rsvdp", |
| 1145 | // aer_decode->advanced_error_capabilities_and_control.rsvdp); |
| 1146 | json_object_object_add(aer_capability_ir, |
| 1147 | "advanced_error_capabilities_and_control", |
| 1148 | fields_ir); |
| 1149 | |
| 1150 | /* |
| 1151 | * Root Error Command Register |
| 1152 | * Offset: 0x2C |
| 1153 | */ |
| 1154 | fields_ir = json_object_new_object(); |
| 1155 | //add_bool(fields_ir, "correctable_error_reporting_enable", |
| 1156 | // aer_decode->root_error_command |
| 1157 | // .correctable_error_reporting_enable); |
| 1158 | //add_bool( |
| 1159 | // fields_ir, "non_fatal_error_reporting_enable", |
| 1160 | // aer_decode->root_error_command.non_fatal_error_reporting_enable); |
| 1161 | //add_bool(fields_ir, "fatal_error_reporting_enable", |
| 1162 | // aer_decode->root_error_command.fatal_error_reporting_enable); |
| 1163 | //add_int(fields_ir, "rsvdp", aer_decode->root_error_command.rsvdp); |
| 1164 | json_object_object_add(aer_capability_ir, "root_error_command", |
| 1165 | fields_ir); |
| 1166 | |
| 1167 | /* |
| 1168 | * Root Error Status Register |
| 1169 | * Offset: 0x30 |
| 1170 | */ |
| 1171 | fields_ir = json_object_new_object(); |
| 1172 | //add_bool(fields_ir, "err_cor_received", |
| 1173 | // aer_decode->root_error_status.err_cor_received); |
| 1174 | //add_bool(fields_ir, "multiple_err_cor_received", |
| 1175 | // aer_decode->root_error_status.multiple_err_cor_received); |
| 1176 | //add_bool(fields_ir, "err_fatal_nonfatal_received", |
| 1177 | // aer_decode->root_error_status.err_fatal_nonfatal_received); |
| 1178 | //add_bool(fields_ir, "multiple_err_fatal_nonfatal_received", |
| 1179 | // aer_decode->root_error_status |
| 1180 | // .multiple_err_fatal_nonfatal_received); |
| 1181 | //add_bool(fields_ir, "first_uncorrectable_fatal", |
| 1182 | // aer_decode->root_error_status.first_uncorrectable_fatal); |
| 1183 | //add_bool( |
| 1184 | // fields_ir, "non_fatal_error_messages_received", |
| 1185 | // aer_decode->root_error_status.non_fatal_error_messages_received); |
| 1186 | //add_bool(fields_ir, "fatal_error_messages_received", |
| 1187 | // aer_decode->root_error_status.fatal_error_messages_received); |
| 1188 | add_int(fields_ir, "err_cor_subclass", |
| 1189 | aer_decode->root_error_status.err_cor_subclass); |
| 1190 | //add_int(fields_ir, "rsvdz", aer_decode->root_error_status.rsvdz); |
| 1191 | add_int(fields_ir, "advanced_error_interrupt_message_number", |
| 1192 | aer_decode->root_error_status |
| 1193 | .advanced_error_interrupt_message_number); |
| 1194 | json_object_object_add(aer_capability_ir, "root_error_status", |
| 1195 | fields_ir); |
| 1196 | |
| 1197 | /* |
| 1198 | * Error Source Identification Register |
| 1199 | * Offset: 0x34 |
| 1200 | */ |
| 1201 | fields_ir = json_object_new_object(); |
| 1202 | add_int(fields_ir, "err_cor_source_identification", |
| 1203 | aer_decode->error_source_id.err_cor_source_identification); |
| 1204 | add_int(fields_ir, "err_fatal_nonfatal_source_identification", |
| 1205 | aer_decode->error_source_id |
| 1206 | .err_fatal_nonfatal_source_identification); |
| 1207 | json_object_object_add(aer_capability_ir, "error_source_id", fields_ir); |
| 1208 | |
| 1209 | return aer_capability_ir; |
| 1210 | } |
| 1211 | |
Lawrence Tang | 3b7f45b | 2022-07-14 14:14:30 +0100 | [diff] [blame] | 1212 | //Converts a single CPER-JSON PCIe section into CPER binary, outputting to the given stream. |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 1213 | void ir_section_pcie_to_cper(json_object *section, FILE *out) |
Lawrence Tang | 3b7f45b | 2022-07-14 14:14:30 +0100 | [diff] [blame] | 1214 | { |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 1215 | EFI_PCIE_ERROR_DATA *section_cper = |
| 1216 | (EFI_PCIE_ERROR_DATA *)calloc(1, sizeof(EFI_PCIE_ERROR_DATA)); |
Lawrence Tang | 3b7f45b | 2022-07-14 14:14:30 +0100 | [diff] [blame] | 1217 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 1218 | //Validation bits. |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1219 | ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 }; |
| 1220 | struct json_object *obj = NULL; |
Lawrence Tang | 3b7f45b | 2022-07-14 14:14:30 +0100 | [diff] [blame] | 1221 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 1222 | //Version. |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1223 | if (json_object_object_get_ex(section, "version", &obj)) { |
Erwin Tsaur | 8870c07 | 2025-02-28 12:57:12 -0800 | [diff] [blame] | 1224 | const json_object *version = obj; |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1225 | UINT32 minor = int_to_bcd(json_object_get_int( |
| 1226 | json_object_object_get(version, "minor"))); |
| 1227 | UINT32 major = int_to_bcd(json_object_get_int( |
| 1228 | json_object_object_get(version, "major"))); |
| 1229 | section_cper->Version = minor + (major << 8); |
| 1230 | add_to_valid_bitfield(&ui64Type, 1); |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 1231 | } |
Lawrence Tang | 3b7f45b | 2022-07-14 14:14:30 +0100 | [diff] [blame] | 1232 | |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1233 | //Command/status registers. |
| 1234 | if (json_object_object_get_ex(section, "commandStatus", &obj)) { |
Erwin Tsaur | 8870c07 | 2025-02-28 12:57:12 -0800 | [diff] [blame] | 1235 | const json_object *command_status = obj; |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1236 | UINT32 command = (UINT16)json_object_get_uint64( |
| 1237 | json_object_object_get(command_status, |
| 1238 | "commandRegister")); |
| 1239 | UINT32 status = (UINT16)json_object_get_uint64( |
| 1240 | json_object_object_get(command_status, |
| 1241 | "statusRegister")); |
| 1242 | section_cper->CommandStatus = command + (status << 16); |
| 1243 | add_to_valid_bitfield(&ui64Type, 2); |
| 1244 | } |
| 1245 | |
| 1246 | //Device ID. |
| 1247 | if (json_object_object_get_ex(section, "deviceID", &obj)) { |
Erwin Tsaur | 8870c07 | 2025-02-28 12:57:12 -0800 | [diff] [blame] | 1248 | const json_object *device_id = obj; |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1249 | UINT64 class_id = json_object_get_uint64( |
| 1250 | json_object_object_get(device_id, "classCode")); |
| 1251 | section_cper->DevBridge.VendorId = |
| 1252 | (UINT16)json_object_get_uint64( |
| 1253 | json_object_object_get(device_id, "vendorID")); |
| 1254 | section_cper->DevBridge.DeviceId = |
| 1255 | (UINT16)json_object_get_uint64( |
| 1256 | json_object_object_get(device_id, "deviceID")); |
| 1257 | section_cper->DevBridge.ClassCode[0] = class_id >> 16; |
| 1258 | section_cper->DevBridge.ClassCode[1] = (class_id >> 8) & 0xFF; |
| 1259 | section_cper->DevBridge.ClassCode[2] = class_id & 0xFF; |
| 1260 | section_cper->DevBridge.Function = |
| 1261 | (UINT8)json_object_get_uint64(json_object_object_get( |
| 1262 | device_id, "functionNumber")); |
| 1263 | section_cper->DevBridge.Device = (UINT8)json_object_get_uint64( |
| 1264 | json_object_object_get(device_id, "deviceNumber")); |
| 1265 | section_cper->DevBridge.Segment = |
| 1266 | (UINT16)json_object_get_uint64(json_object_object_get( |
| 1267 | device_id, "segmentNumber")); |
| 1268 | section_cper->DevBridge.PrimaryOrDeviceBus = |
| 1269 | (UINT8)json_object_get_uint64(json_object_object_get( |
| 1270 | device_id, "primaryOrDeviceBusNumber")); |
| 1271 | section_cper->DevBridge.SecondaryBus = |
| 1272 | (UINT8)json_object_get_uint64(json_object_object_get( |
| 1273 | device_id, "secondaryBusNumber")); |
| 1274 | section_cper->DevBridge.Slot.Number = |
| 1275 | (UINT16)json_object_get_uint64(json_object_object_get( |
| 1276 | device_id, "slotNumber")); |
| 1277 | add_to_valid_bitfield(&ui64Type, 3); |
| 1278 | } |
| 1279 | |
| 1280 | //Bridge/control status. |
| 1281 | if (json_object_object_get_ex(section, "bridgeControlStatus", &obj)) { |
Erwin Tsaur | 8870c07 | 2025-02-28 12:57:12 -0800 | [diff] [blame] | 1282 | const json_object *bridge_control = obj; |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1283 | UINT32 bridge_status = (UINT16)json_object_get_uint64( |
| 1284 | json_object_object_get(bridge_control, |
| 1285 | "secondaryStatusRegister")); |
| 1286 | UINT32 control_status = (UINT16)json_object_get_uint64( |
| 1287 | json_object_object_get(bridge_control, |
| 1288 | "controlRegister")); |
| 1289 | section_cper->BridgeControlStatus = |
| 1290 | bridge_status + (control_status << 16); |
| 1291 | add_to_valid_bitfield(&ui64Type, 5); |
| 1292 | } |
| 1293 | |
| 1294 | //Capability structure. |
| 1295 | int32_t decoded_len = 0; |
| 1296 | UINT8 *decoded = NULL; |
| 1297 | json_object *encoded = NULL; |
| 1298 | if (json_object_object_get_ex(section, "capabilityStructure", &obj)) { |
Erwin Tsaur | 8870c07 | 2025-02-28 12:57:12 -0800 | [diff] [blame] | 1299 | const json_object *capability = obj; |
| 1300 | encoded = json_object_object_get(capability, "data"); |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1301 | |
Erwin Tsaur | 8870c07 | 2025-02-28 12:57:12 -0800 | [diff] [blame] | 1302 | decoded = base64_decode(json_object_get_string(encoded), |
| 1303 | json_object_get_string_len(encoded), |
| 1304 | &decoded_len); |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1305 | if (decoded == NULL) { |
Ed Tanous | 50b966f | 2025-03-11 09:06:19 -0700 | [diff] [blame] | 1306 | cper_print_log( |
| 1307 | "Failed to allocate decode output buffer. \n"); |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1308 | } else { |
| 1309 | memcpy(section_cper->Capability.PcieCap, decoded, |
| 1310 | decoded_len); |
| 1311 | free(decoded); |
| 1312 | } |
| 1313 | add_to_valid_bitfield(&ui64Type, 6); |
| 1314 | } |
| 1315 | |
| 1316 | decoded = NULL; |
| 1317 | encoded = NULL; |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 1318 | //AER capability structure. |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1319 | if (json_object_object_get_ex(section, "aerInfo", &obj)) { |
Erwin Tsaur | 8870c07 | 2025-02-28 12:57:12 -0800 | [diff] [blame] | 1320 | const json_object *aer_info = obj; |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1321 | encoded = json_object_object_get(aer_info, "data"); |
| 1322 | decoded_len = 0; |
Ed Tanous | a7d2cdd | 2024-07-15 11:07:27 -0700 | [diff] [blame] | 1323 | |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1324 | decoded = base64_decode(json_object_get_string(encoded), |
| 1325 | json_object_get_string_len(encoded), |
| 1326 | &decoded_len); |
Ed Tanous | a7d2cdd | 2024-07-15 11:07:27 -0700 | [diff] [blame] | 1327 | |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1328 | if (decoded == NULL) { |
Ed Tanous | 50b966f | 2025-03-11 09:06:19 -0700 | [diff] [blame] | 1329 | cper_print_log( |
| 1330 | "Failed to allocate decode output buffer. \n"); |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1331 | } else { |
| 1332 | memcpy(section_cper->AerInfo.PcieAer, decoded, |
| 1333 | decoded_len); |
| 1334 | free(decoded); |
| 1335 | } |
| 1336 | add_to_valid_bitfield(&ui64Type, 7); |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 1337 | } |
Lawrence Tang | 3b7f45b | 2022-07-14 14:14:30 +0100 | [diff] [blame] | 1338 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 1339 | //Miscellaneous value fields. |
Aushim Nagarkatti | ae8f6d9 | 2025-01-29 17:34:44 -0800 | [diff] [blame] | 1340 | if (json_object_object_get_ex(section, "portType", &obj)) { |
| 1341 | section_cper->PortType = (UINT32)readable_pair_to_integer(obj); |
| 1342 | add_to_valid_bitfield(&ui64Type, 0); |
| 1343 | } |
| 1344 | if (json_object_object_get_ex(section, "deviceSerialNumber", &obj)) { |
| 1345 | section_cper->SerialNo = json_object_get_uint64(obj); |
| 1346 | add_to_valid_bitfield(&ui64Type, 4); |
| 1347 | } |
| 1348 | |
| 1349 | section_cper->ValidFields = ui64Type.value.ui64; |
Lawrence Tang | 3b7f45b | 2022-07-14 14:14:30 +0100 | [diff] [blame] | 1350 | |
Lawrence Tang | e407b4c | 2022-07-21 13:54:01 +0100 | [diff] [blame] | 1351 | //Write out to stream, free resources. |
| 1352 | fwrite(section_cper, sizeof(EFI_PCIE_ERROR_DATA), 1, out); |
| 1353 | fflush(out); |
| 1354 | free(section_cper); |
John Chung | f8fc705 | 2024-05-03 20:05:29 +0800 | [diff] [blame] | 1355 | } |