xref: /openbmc/libcper/sections/cper-section-pcie.c (revision a3663051b36d33dc4b102109666ee31b0c23582f)
1 /**
2  * Describes functions for converting PCIe CPER sections from binary and JSON format
3  * into an intermediate format.
4  *
5  * Author: Lawrence.Tang@arm.com
6  **/
7 #include <stdio.h>
8 #include <string.h>
9 #include <json.h>
10 #include <libcper/base64.h>
11 #include <libcper/Cper.h>
12 #include <libcper/cper-utils.h>
13 #include <libcper/sections/cper-section-pcie.h>
14 #include <libcper/log.h>
15 
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);
18 
19 //Converts a single PCIe CPER section into JSON IR.
20 json_object *cper_section_pcie_to_ir(const UINT8 *section, UINT32 size)
21 {
22 	if (size < sizeof(EFI_PCIE_ERROR_DATA)) {
23 		return NULL;
24 	}
25 
26 	EFI_PCIE_ERROR_DATA *pcie_error = (EFI_PCIE_ERROR_DATA *)section;
27 	json_object *section_ir = json_object_new_object();
28 
29 	//Validation bits.
30 	ValidationTypes ui64Type = { UINT_64T,
31 				     .value.ui64 = pcie_error->ValidFields };
32 
33 	//Port type.
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 	}
40 
41 	//Version, provided each half in BCD.
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 	}
52 
53 	//Command & status.
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 	}
67 
68 	//PCIe Device ID.
69 	char hexstring_buf[EFI_UINT64_HEX_STRING_LEN];
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));
81 
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 	}
112 
113 	//Device serial number.
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 	}
119 
120 	//Bridge control status.
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 	}
134 
135 	//Capability structure.
136 	//The PCIe capability structure provided here could either be PCIe 1.1 Capability Structure
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.
139 	if (isvalid_prop_to_ir(&ui64Type, 6)) {
140 		json_object_object_add(section_ir, "capabilityStructure",
141 				       pcie_capability_to_ir(pcie_error));
142 	}
143 
144 	//AER information.
145 	if (isvalid_prop_to_ir(&ui64Type, 7)) {
146 		json_object_object_add(section_ir, "aerInfo",
147 				       pcie_aer_to_ir(pcie_error));
148 	}
149 
150 	return section_ir;
151 }
152 
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 
1212 //Converts a single CPER-JSON PCIe section into CPER binary, outputting to the given stream.
1213 void ir_section_pcie_to_cper(json_object *section, FILE *out)
1214 {
1215 	EFI_PCIE_ERROR_DATA *section_cper =
1216 		(EFI_PCIE_ERROR_DATA *)calloc(1, sizeof(EFI_PCIE_ERROR_DATA));
1217 
1218 	//Validation bits.
1219 	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
1220 	struct json_object *obj = NULL;
1221 
1222 	//Version.
1223 	if (json_object_object_get_ex(section, "version", &obj)) {
1224 		const json_object *version = obj;
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);
1231 	}
1232 
1233 	//Command/status registers.
1234 	if (json_object_object_get_ex(section, "commandStatus", &obj)) {
1235 		const json_object *command_status = obj;
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)) {
1248 		const json_object *device_id = obj;
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)) {
1282 		const json_object *bridge_control = obj;
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)) {
1299 		const json_object *capability = obj;
1300 		encoded = json_object_object_get(capability, "data");
1301 
1302 		decoded = base64_decode(json_object_get_string(encoded),
1303 					json_object_get_string_len(encoded),
1304 					&decoded_len);
1305 		if (decoded == NULL) {
1306 			cper_print_log(
1307 				"Failed to allocate decode output buffer. \n");
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;
1318 	//AER capability structure.
1319 	if (json_object_object_get_ex(section, "aerInfo", &obj)) {
1320 		const json_object *aer_info = obj;
1321 		encoded = json_object_object_get(aer_info, "data");
1322 		decoded_len = 0;
1323 
1324 		decoded = base64_decode(json_object_get_string(encoded),
1325 					json_object_get_string_len(encoded),
1326 					&decoded_len);
1327 
1328 		if (decoded == NULL) {
1329 			cper_print_log(
1330 				"Failed to allocate decode output buffer. \n");
1331 		} else {
1332 			memcpy(section_cper->AerInfo.PcieAer, decoded,
1333 			       decoded_len);
1334 			free(decoded);
1335 		}
1336 		add_to_valid_bitfield(&ui64Type, 7);
1337 	}
1338 
1339 	//Miscellaneous value fields.
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;
1350 
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);
1355 }
1356