blob: 508b05fffa204fc0ab1e248e77e8c57129b59d5c [file] [log] [blame]
Lawrence Tang4dbe3d72022-07-06 13:51:01 +01001/**
2 * Describes functions for converting PCIe CPER sections from binary and JSON format
3 * into an intermediate format.
Ed Tanousfedd4572024-07-12 13:56:00 -07004 *
Lawrence Tang4dbe3d72022-07-06 13:51:01 +01005 * Author: Lawrence.Tang@arm.com
6 **/
7#include <stdio.h>
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01008#include <string.h>
Lawrence Tang5202bbb2022-08-12 14:54:36 +01009#include <json.h>
Thu Nguyene42fb482024-10-15 14:43:11 +000010#include <libcper/base64.h>
11#include <libcper/Cper.h>
12#include <libcper/cper-utils.h>
13#include <libcper/sections/cper-section-pcie.h>
Ed Tanous50b966f2025-03-11 09:06:19 -070014#include <libcper/log.h>
Lawrence Tang4dbe3d72022-07-06 13:51:01 +010015
Erwin Tsaur8870c072025-02-28 12:57:12 -080016json_object *pcie_capability_to_ir(EFI_PCIE_ERROR_DATA *pcie_error);
17json_object *pcie_aer_to_ir(EFI_PCIE_ERROR_DATA *pcie_error);
Andrew Adriance3cebfc22024-11-20 12:57:04 -080018
Lawrence Tang4dbe3d72022-07-06 13:51:01 +010019//Converts a single PCIe CPER section into JSON IR.
Ed Tanous12dbd4f2025-03-08 19:05:01 -080020json_object *cper_section_pcie_to_ir(const UINT8 *section, UINT32 size)
Lawrence Tang4dbe3d72022-07-06 13:51:01 +010021{
Ed Tanous12dbd4f2025-03-08 19:05:01 -080022 if (size < sizeof(EFI_PCIE_ERROR_DATA)) {
23 return NULL;
24 }
25
Lawrence Tange407b4c2022-07-21 13:54:01 +010026 EFI_PCIE_ERROR_DATA *pcie_error = (EFI_PCIE_ERROR_DATA *)section;
27 json_object *section_ir = json_object_new_object();
Lawrence Tang4dbe3d72022-07-06 13:51:01 +010028
Lawrence Tange407b4c2022-07-21 13:54:01 +010029 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080030 ValidationTypes ui64Type = { UINT_64T,
31 .value.ui64 = pcie_error->ValidFields };
Lawrence Tang4dbe3d72022-07-06 13:51:01 +010032
Lawrence Tange407b4c2022-07-21 13:54:01 +010033 //Port type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080034 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 Tang4dbe3d72022-07-06 13:51:01 +010040
Lawrence Tange407b4c2022-07-21 13:54:01 +010041 //Version, provided each half in BCD.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080042 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 Tang4dbe3d72022-07-06 13:51:01 +010052
Lawrence Tange407b4c2022-07-21 13:54:01 +010053 //Command & status.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080054 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 Tang4dbe3d72022-07-06 13:51:01 +010067
Lawrence Tange407b4c2022-07-21 13:54:01 +010068 //PCIe Device ID.
Aushim Nagarkatticc367012024-12-05 18:17:27 -080069 char hexstring_buf[EFI_UINT64_HEX_STRING_LEN];
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080070 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 Nagarkatticc367012024-12-05 18:17:27 -080081
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080082 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 Tang4dbe3d72022-07-06 13:51:01 +0100112
Lawrence Tange407b4c2022-07-21 13:54:01 +0100113 //Device serial number.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800114 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 Tang4dbe3d72022-07-06 13:51:01 +0100119
Lawrence Tange407b4c2022-07-21 13:54:01 +0100120 //Bridge control status.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800121 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 Tang4dbe3d72022-07-06 13:51:01 +0100134
Lawrence Tange407b4c2022-07-21 13:54:01 +0100135 //Capability structure.
136 //The PCIe capability structure provided here could either be PCIe 1.1 Capability Structure
Erwin Tsaur8870c072025-02-28 12:57:12 -0800137 //(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 Nagarkattiae8f6d92025-01-29 17:34:44 -0800139 if (isvalid_prop_to_ir(&ui64Type, 6)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -0800140 json_object_object_add(section_ir, "capabilityStructure",
141 pcie_capability_to_ir(pcie_error));
John Chungf8fc7052024-05-03 20:05:29 +0800142 }
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100143
Lawrence Tange407b4c2022-07-21 13:54:01 +0100144 //AER information.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800145 if (isvalid_prop_to_ir(&ui64Type, 7)) {
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800146 json_object_object_add(section_ir, "aerInfo",
Erwin Tsaur8870c072025-02-28 12:57:12 -0800147 pcie_aer_to_ir(pcie_error));
John Chungf8fc7052024-05-03 20:05:29 +0800148 }
Andrew Adriance3cebfc22024-11-20 12:57:04 -0800149
Lawrence Tange407b4c2022-07-21 13:54:01 +0100150 return section_ir;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100151}
152
Erwin Tsaur8870c072025-02-28 12:57:12 -0800153//Converts PCIe Capability Structure section into JSON IR.
154json_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.
771json_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 Tang3b7f45b2022-07-14 14:14:30 +01001212//Converts a single CPER-JSON PCIe section into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001213void ir_section_pcie_to_cper(json_object *section, FILE *out)
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001214{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001215 EFI_PCIE_ERROR_DATA *section_cper =
1216 (EFI_PCIE_ERROR_DATA *)calloc(1, sizeof(EFI_PCIE_ERROR_DATA));
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001217
Lawrence Tange407b4c2022-07-21 13:54:01 +01001218 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001219 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
1220 struct json_object *obj = NULL;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001221
Lawrence Tange407b4c2022-07-21 13:54:01 +01001222 //Version.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001223 if (json_object_object_get_ex(section, "version", &obj)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -08001224 const json_object *version = obj;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001225 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 Chungf8fc7052024-05-03 20:05:29 +08001231 }
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001232
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001233 //Command/status registers.
1234 if (json_object_object_get_ex(section, "commandStatus", &obj)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -08001235 const json_object *command_status = obj;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001236 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 Tsaur8870c072025-02-28 12:57:12 -08001248 const json_object *device_id = obj;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001249 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 Tsaur8870c072025-02-28 12:57:12 -08001282 const json_object *bridge_control = obj;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001283 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 Tsaur8870c072025-02-28 12:57:12 -08001299 const json_object *capability = obj;
1300 encoded = json_object_object_get(capability, "data");
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001301
Erwin Tsaur8870c072025-02-28 12:57:12 -08001302 decoded = base64_decode(json_object_get_string(encoded),
1303 json_object_get_string_len(encoded),
1304 &decoded_len);
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001305 if (decoded == NULL) {
Ed Tanous50b966f2025-03-11 09:06:19 -07001306 cper_print_log(
1307 "Failed to allocate decode output buffer. \n");
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001308 } 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 Tange407b4c2022-07-21 13:54:01 +01001318 //AER capability structure.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001319 if (json_object_object_get_ex(section, "aerInfo", &obj)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -08001320 const json_object *aer_info = obj;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001321 encoded = json_object_object_get(aer_info, "data");
1322 decoded_len = 0;
Ed Tanousa7d2cdd2024-07-15 11:07:27 -07001323
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001324 decoded = base64_decode(json_object_get_string(encoded),
1325 json_object_get_string_len(encoded),
1326 &decoded_len);
Ed Tanousa7d2cdd2024-07-15 11:07:27 -07001327
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001328 if (decoded == NULL) {
Ed Tanous50b966f2025-03-11 09:06:19 -07001329 cper_print_log(
1330 "Failed to allocate decode output buffer. \n");
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001331 } else {
1332 memcpy(section_cper->AerInfo.PcieAer, decoded,
1333 decoded_len);
1334 free(decoded);
1335 }
1336 add_to_valid_bitfield(&ui64Type, 7);
John Chungf8fc7052024-05-03 20:05:29 +08001337 }
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001338
Lawrence Tange407b4c2022-07-21 13:54:01 +01001339 //Miscellaneous value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001340 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 Tang3b7f45b2022-07-14 14:14:30 +01001350
Lawrence Tange407b4c2022-07-21 13:54:01 +01001351 //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 Chungf8fc7052024-05-03 20:05:29 +08001355}