xref: /openbmc/libcper/sections/cper-section-pcie.c (revision ad6c880fc739b6ca750c3ab594e270efd972c2ac)
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 #include <string.h>
16 
17 json_object *pcie_capability_to_ir(EFI_PCIE_ERROR_DATA *pcie_error);
18 json_object *pcie_aer_to_ir(EFI_PCIE_ERROR_DATA *pcie_error);
19 
20 #define ANYP 0xFF
21 
22 struct class_code pci_class_codes[] = {
23 	// Base Class 00h - Legacy devices
24 	{ 0x00, 0x00, 0x00,
25 	  "All currently implemented devices except VGA-compatible devices" },
26 	{ 0x00, 0x01, 0x00, "VGA-compatible device" },
27 
28 	// Base Class 01h - Mass storage controllers
29 	{ 0x01, 0x00, 0x00, "SCSI controller - vendor-specific interface" },
30 	{ 0x01, 0x00, 0x11,
31 	  "SCSI storage device - SCSI over PCI Express (SOP) with PQI" },
32 	{ 0x01, 0x00, 0x12,
33 	  "SCSI controller - SCSI over PCI Express (SOP) with PQI" },
34 	{ 0x01, 0x00, 0x13,
35 	  "SCSI storage device and SCSI controller - SOP with PQI" },
36 	{ 0x01, 0x00, 0x21,
37 	  "SCSI storage device - SOP with NVM Express interface" },
38 	{ 0x01, 0x01, ANYP, "IDE controller" },
39 	{ 0x01, 0x02, 0x00,
40 	  "Floppy disk controller - vendor-specific interface" },
41 	{ 0x01, 0x03, 0x00, "IPI bus controller - vendor-specific interface" },
42 	{ 0x01, 0x04, 0x00, "RAID controller - vendor-specific interface" },
43 	{ 0x01, 0x05, 0x20,
44 	  "ATA controller with ADMA interface - single stepping" },
45 	{ 0x01, 0x05, 0x30,
46 	  "ATA controller with ADMA interface - continuous operation" },
47 	{ 0x01, 0x06, 0x00,
48 	  "Serial ATA controller - vendor-specific interface" },
49 	{ 0x01, 0x06, 0x01, "Serial ATA controller - AHCI interface" },
50 	{ 0x01, 0x06, 0x02, "Serial Storage Bus Interface" },
51 	{ 0x01, 0x07, 0x00,
52 	  "Serial Attached SCSI (SAS) controller - vendor specific interface" },
53 	{ 0x01, 0x08, 0x00,
54 	  "Non-volatile memory subsystem - vendor-specific interface" },
55 	{ 0x01, 0x08, 0x01,
56 	  "Non-volatile memory subsystem - NVMHCI interface" },
57 	{ 0x01, 0x08, 0x02, "NVM Express (NVMe) I/O controller" },
58 	{ 0x01, 0x08, 0x03, "NVM Express (NVMe) administrative controller" },
59 	{ 0x01, 0x09, 0x00,
60 	  "Universal Flash Storage (UFS) controller - vendor specific interface" },
61 	{ 0x01, 0x09, 0x01,
62 	  "Universal Flash Storage (UFS) controller - UFSHCI" },
63 	{ 0x01, 0x80, 0x00,
64 	  "Other mass storage controller - vendor-specific interface" },
65 
66 	// Base Class 02h - Network controllers
67 	{ 0x02, 0x00, 0x00, "Ethernet controller" },
68 	{ 0x02, 0x00, 0x01,
69 	  "Ethernet Controller with IDPF compliant Interface" },
70 	{ 0x02, 0x01, 0x00, "Token Ring controller" },
71 	{ 0x02, 0x02, 0x00, "FDDI controller" },
72 	{ 0x02, 0x03, 0x00, "ATM controller" },
73 	{ 0x02, 0x04, 0x00, "ISDN controller" },
74 	{ 0x02, 0x05, 0x00, "WorldFip controller" },
75 	{ 0x02, 0x06, ANYP, "PICMG 2.14 Multi Computing" },
76 	{ 0x02, 0x07, 0x00, "InfiniBand Controller" },
77 	{ 0x02, 0x08, 0x00, "Host fabric controller - vendor-specific" },
78 	{ 0x02, 0x80, 0x00, "Other network controller" },
79 
80 	// Base Class 03h - Display controllers
81 	{ 0x03, 0x00, 0x00, "VGA-compatible controller" },
82 	{ 0x03, 0x00, 0x01, "8514-compatible controller" },
83 	{ 0x03, 0x01, 0x00, "XGA controller" },
84 	{ 0x03, 0x02, 0x00, "3D controller" },
85 	{ 0x03, 0x80, 0x00, "Other display controller" },
86 
87 	// Base Class 04h - Multimedia devices
88 	{ 0x04, 0x00, 0x00, "Video device - vendor specific interface" },
89 	{ 0x04, 0x01, 0x00, "Audio device - vendor specific interface" },
90 	{ 0x04, 0x02, 0x00,
91 	  "Computer telephony device - vendor specific interface" },
92 	{ 0x04, 0x03, 0x00, "High Definition Audio (HD-A) 1.0 compatible" },
93 	{ 0x04, 0x03, 0x80,
94 	  "High Definition Audio (HD-A) 1.0 compatible with vendor extensions" },
95 	{ 0x04, 0x80, 0x00,
96 	  "Other multimedia device - vendor specific interface" },
97 	// Base Class 05h - Memory controllers
98 	{ 0x05, 0x00, 0x00, "RAM" },
99 	{ 0x05, 0x01, 0x00, "Flash" },
100 	{ 0x05, 0x02, 0x00, "CXL Memory Device - vendor specific interface" },
101 	{ 0x05, 0x02, 0x10,
102 	  "CXL Memory Device following CXL 2.0 or later specification" },
103 	{ 0x05, 0x80, 0x00, "Other memory controller" },
104 
105 	// Base Class 06h - Bridge devices
106 	{ 0x06, 0x00, 0x00, "Host bridge" },
107 	{ 0x06, 0x01, 0x00, "ISA bridge" },
108 	{ 0x06, 0x02, 0x00, "EISA bridge" },
109 	{ 0x06, 0x03, 0x00, "MCA bridge" },
110 	{ 0x06, 0x04, 0x00, "PCI-to-PCI bridge" },
111 	{ 0x06, 0x04, 0x01, "Subtractive Decode PCI-to-PCI bridge" },
112 	{ 0x06, 0x05, 0x00, "PCMCIA bridge" },
113 	{ 0x06, 0x06, 0x00, "NuBus bridge" },
114 	{ 0x06, 0x07, 0x00, "CardBus bridge" },
115 	{ 0x06, 0x08, ANYP, "RACEway bridge" },
116 	{ 0x06, 0x09, 0x40,
117 	  "Semi-transparent PCI-to-PCI bridge - primary bus towards host" },
118 	{ 0x06, 0x09, 0x80,
119 	  "Semi-transparent PCI-to-PCI bridge - secondary bus towards host" },
120 	{ 0x06, 0x0A, 0x00, "InfiniBand-to-PCI host bridge" },
121 	{ 0x06, 0x0B, 0x00,
122 	  "Advanced Switching to PCI host bridge - Custom Interface" },
123 	{ 0x06, 0x0B, 0x01,
124 	  "Advanced Switching to PCI host bridge - ASI-SIG Defined Portal Interface" },
125 	{ 0x06, 0x80, 0x00, "Other bridge device" },
126 
127 	// Base Class 07h - Simple communication controllers
128 	{ 0x07, 0x00, 0x00, "Generic XT-compatible serial controller" },
129 	{ 0x07, 0x00, 0x01, "16450-compatible serial controller" },
130 	{ 0x07, 0x00, 0x02, "16550-compatible serial controller" },
131 	{ 0x07, 0x00, 0x03, "16650-compatible serial controller" },
132 	{ 0x07, 0x00, 0x04, "16750-compatible serial controller" },
133 	{ 0x07, 0x00, 0x05, "16850-compatible serial controller" },
134 	{ 0x07, 0x00, 0x06, "16950-compatible serial controller" },
135 	{ 0x07, 0x01, 0x00, "Parallel port" },
136 	{ 0x07, 0x01, 0x01, "Bi-directional parallel port" },
137 	{ 0x07, 0x01, 0x02, "ECP 1.X compliant parallel port" },
138 	{ 0x07, 0x01, 0x03, "IEEE1284 controller" },
139 	{ 0x07, 0x01, 0xFE, "IEEE1284 target device" },
140 	{ 0x07, 0x02, 0x00, "Multiport serial controller" },
141 	{ 0x07, 0x03, 0x00, "Generic modem" },
142 	{ 0x07, 0x03, 0x01,
143 	  "Hayes compatible modem - 16450-compatible interface" },
144 	{ 0x07, 0x03, 0x02,
145 	  "Hayes compatible modem - 16550-compatible interface" },
146 	{ 0x07, 0x03, 0x03,
147 	  "Hayes compatible modem - 16650-compatible interface" },
148 	{ 0x07, 0x03, 0x04,
149 	  "Hayes compatible modem - 16750-compatible interface" },
150 	{ 0x07, 0x04, 0x00, "GPIB (IEEE 488.1/2) controller" },
151 	{ 0x07, 0x05, 0x00, "Smart Card" },
152 	{ 0x07, 0x80, 0x00, "Other communications device" },
153 
154 	// Base Class 08h - Base system peripherals
155 	{ 0x08, 0x00, 0x00, "Generic 8259 PIC" },
156 	{ 0x08, 0x00, 0x01, "ISA PIC" },
157 	{ 0x08, 0x00, 0x02, "EISA PIC" },
158 	{ 0x08, 0x00, 0x10, "I/O APIC interrupt controller" },
159 	{ 0x08, 0x00, 0x20, "I/O(x) APIC interrupt controller" },
160 	{ 0x08, 0x01, 0x00, "Generic 8237 DMA controller" },
161 	{ 0x08, 0x01, 0x01, "ISA DMA controller" },
162 	{ 0x08, 0x01, 0x02, "EISA DMA controller" },
163 	{ 0x08, 0x02, 0x00, "Generic 8254 system timer" },
164 	{ 0x08, 0x02, 0x01, "ISA system timer" },
165 	{ 0x08, 0x02, 0x02, "EISA system timers" },
166 	{ 0x08, 0x02, 0x03, "High Performance Event Timer" },
167 	{ 0x08, 0x03, 0x00, "Generic RTC controller" },
168 	{ 0x08, 0x03, 0x01, "ISA RTC controller" },
169 	{ 0x08, 0x04, 0x00, "Generic PCI Hot-Plug controller" },
170 	{ 0x08, 0x05, 0x00, "SD Host controller" },
171 	{ 0x08, 0x06, 0x00, "IOMMU" },
172 	{ 0x08, 0x07, 0x00, "Root Complex Event Collector" },
173 	{ 0x08, 0x08, 0x00, "Time Card - vendor-specific interface" },
174 	{ 0x08, 0x08, 0x01, "Time Card - OCP TAP interface" },
175 	{ 0x08, 0x80, 0x00, "Other system peripheral" },
176 
177 	// Base Class 09h - Input devices
178 	{ 0x09, 0x00, 0x00, "Keyboard controller" },
179 	{ 0x09, 0x01, 0x00, "Digitizer (pen)" },
180 	{ 0x09, 0x02, 0x00, "Mouse controller" },
181 	{ 0x09, 0x03, 0x00, "Scanner controller" },
182 	{ 0x09, 0x04, 0x00, "Gameport controller (generic)" },
183 	{ 0x09, 0x04, 0x10, "Gameport controller - legacy ports" },
184 	{ 0x09, 0x80, 0x00, "Other input controller" },
185 
186 	// Base Class 0Ah - Docking stations
187 	{ 0x0A, 0x00, 0x00, "Generic docking station" },
188 	{ 0x0A, 0x80, 0x00, "Other type of docking station" },
189 
190 	// Base Class 0Bh - Processors
191 	{ 0x0B, 0x00, 0x00, "386" },
192 	{ 0x0B, 0x01, 0x00, "486" },
193 	{ 0x0B, 0x02, 0x00, "Pentium" },
194 	{ 0x0B, 0x10, 0x00, "Alpha" },
195 	{ 0x0B, 0x20, 0x00, "PowerPC" },
196 	{ 0x0B, 0x30, 0x00, "MIPS" },
197 	{ 0x0B, 0x40, 0x00, "Co-processor" },
198 	{ 0x0B, 0x80, 0x00, "Other processors" },
199 
200 	// Base Class 0Ch - Serial bus controllers
201 	{ 0x0C, 0x00, 0x00, "IEEE 1394 (FireWire)" },
202 	{ 0x0C, 0x00, 0x10, "IEEE 1394 following 1394 OpenHCI specification" },
203 	{ 0x0C, 0x01, 0x00, "ACCESS.bus" },
204 	{ 0x0C, 0x02, 0x00, "SSA" },
205 	{ 0x0C, 0x03, 0x00, "USB - Universal Host Controller Specification" },
206 	{ 0x0C, 0x03, 0x10, "USB - Open Host Controller Specification" },
207 	{ 0x0C, 0x03, 0x20, "USB2 host controller - Intel EHCI" },
208 	{ 0x0C, 0x03, 0x30, "USB3 host controller - Intel xHCI" },
209 	{ 0x0C, 0x03, 0x40, "USB4 Host Interface" },
210 	{ 0x0C, 0x03, 0x80, "USB - no specific Programming Interface" },
211 	{ 0x0C, 0x03, 0xFE, "USB device (not host controller)" },
212 	{ 0x0C, 0x04, 0x00, "Fibre Channel" },
213 	{ 0x0C, 0x05, 0x00, "SMBus (System Management Bus)" },
214 	{ 0x0C, 0x07, 0x00, "IPMI SMIC Interface" },
215 	{ 0x0C, 0x07, 0x01, "IPMI Keyboard Controller Style Interface" },
216 	{ 0x0C, 0x07, 0x02, "IPMI Block Transfer Interface" },
217 	{ 0x0C, 0x08, 0x00, "SERCOS Interface Standard" },
218 	{ 0x0C, 0x09, 0x00, "CANbus" },
219 	{ 0x0C, 0x0A, 0x00, "MIPI I3C Host Controller Interface" },
220 	{ 0x0C, 0x0B, 0x00, "CXL Fabric Management Host Interface controller" },
221 	{ 0x0C, 0x0C, 0x00, "Memory Mapped Buffer Interface (MMBI) endpoint" },
222 	{ 0x0C, 0x80, 0x00, "Other Serial Bus Controllers" },
223 
224 	// Base Class 0Dh - Wireless controllers
225 	{ 0x0D, 0x00, 0x00, "iRDA compatible controller" },
226 	{ 0x0D, 0x01, 0x00, "Consumer IR controller" },
227 	{ 0x0D, 0x01, 0x10, "UWB Radio controller" },
228 	{ 0x0D, 0x10, 0x00, "RF controller" },
229 	{ 0x0D, 0x11, 0x00, "Bluetooth" },
230 	{ 0x0D, 0x12, 0x00, "Broadband" },
231 	{ 0x0D, 0x20, 0x00, "Ethernet (802.11a - 5 GHz)" },
232 	{ 0x0D, 0x21, 0x00, "Ethernet (802.11b - 2.4 GHz)" },
233 	{ 0x0D, 0x40, 0x00, "Cellular controller/modem" },
234 	{ 0x0D, 0x41, 0x00,
235 	  "Cellular controller/modem plus Ethernet (802.11)" },
236 	{ 0x0D, 0x80, 0x00, "Other type of wireless controller" },
237 
238 	// Base Class 0Eh - Intelligent I/O controllers
239 	{ 0x0E, 0x00, 0x00,
240 	  "I2O Architecture Specification 1.0 Message FIFO at offset 040h" },
241 	{ 0x0E, 0x00, ANYP, "Message FIFO at offset 040h" },
242 
243 	// Base Class 0Fh - Satellite communication controllers
244 	{ 0x0F, 0x01, 0x00, "TV" },
245 	{ 0x0F, 0x02, 0x00, "Audio" },
246 	{ 0x0F, 0x03, 0x00, "Voice" },
247 	{ 0x0F, 0x04, 0x00, "Data" },
248 	{ 0x0F, 0x80, 0x00, "Other satellite communication controller" },
249 
250 	// Base Class 10h - Encryption/Decryption controllers
251 	{ 0x10, 0x00, 0x00,
252 	  "Network and computing encryption and decryption controller" },
253 	{ 0x10, 0x10, 0x00,
254 	  "Entertainment encryption and decryption controller" },
255 	{ 0x10, 0x20, 0x00, "Trusted Platform Module (TPM)" },
256 	{ 0x10, 0x80, 0x00, "Other encryption and decryption controller" },
257 
258 	// Base Class 11h - Data acquisition and signal processing controllers
259 	{ 0x11, 0x00, 0x00, "DPIO modules" },
260 	{ 0x11, 0x01, 0x00, "Performance counters" },
261 	{ 0x11, 0x10, 0x00,
262 	  "Communications synchronization plus time and frequency test/measurement" },
263 	{ 0x11, 0x20, 0x00, "Management card" },
264 	{ 0x11, 0x80, 0x00,
265 	  "Other data acquisition/signal processing controllers" },
266 
267 	// Base Class 12h - Processing accelerators
268 	{ 0x12, 0x00, 0x00,
269 	  "Processing Accelerator - vendor-specific interface" },
270 	{ 0x12, 0x01, 0x00,
271 	  "SNIA Smart Data Accelerator Interface (SDXI) controller" },
272 
273 	// Base Class 13h - Non-Essential Instrumentation
274 	{ 0x13, 0x00, 0x00,
275 	  "Non-Essential Instrumentation Function - Vendor specific interface" },
276 
277 	// Base Class FFh - Device does not fit in any defined classes
278 	{ 0xFF, 0x00, 0x00, "Device does not fit in any defined classes" }
279 };
280 
get_class_code_name(UINT8 base,UINT8 sub,UINT8 programming)281 const char *get_class_code_name(UINT8 base, UINT8 sub, UINT8 programming)
282 {
283 	for (size_t i = 0;
284 	     i < sizeof(pci_class_codes) / sizeof(pci_class_codes[0]); i++) {
285 		if (pci_class_codes[i].base == base &&
286 		    pci_class_codes[i].sub == sub) {
287 			if (pci_class_codes[i].programming == programming ||
288 			    pci_class_codes[i].programming == ANYP) {
289 				return pci_class_codes[i].name;
290 			}
291 		}
292 	}
293 	return NULL;
294 }
295 
296 //Converts a single PCIe CPER section into JSON IR.
cper_section_pcie_to_ir(const UINT8 * section,UINT32 size,char ** desc_string)297 json_object *cper_section_pcie_to_ir(const UINT8 *section, UINT32 size,
298 				     char **desc_string)
299 {
300 	int outstr_len = 0;
301 	*desc_string = malloc(SECTION_DESC_STRING_SIZE);
302 	outstr_len = snprintf(*desc_string, SECTION_DESC_STRING_SIZE,
303 			      "A PCIe Error occurred");
304 	if (outstr_len < 0) {
305 		cper_print_log(
306 			"Error: Could not write to PCIe description string\n");
307 	} else if (outstr_len > SECTION_DESC_STRING_SIZE) {
308 		cper_print_log("Error: PCIe description string truncated\n");
309 	}
310 
311 	if (size < sizeof(EFI_PCIE_ERROR_DATA)) {
312 		return NULL;
313 	}
314 
315 	EFI_PCIE_ERROR_DATA *pcie_error = (EFI_PCIE_ERROR_DATA *)section;
316 	json_object *section_ir = json_object_new_object();
317 
318 	//Validation bits.
319 	ValidationTypes ui64Type = { UINT_64T,
320 				     .value.ui64 = pcie_error->ValidFields };
321 
322 	//Port type.
323 	if (isvalid_prop_to_ir(&ui64Type, 0)) {
324 		json_object *port_type = integer_to_readable_pair(
325 			pcie_error->PortType, 9, PCIE_ERROR_PORT_TYPES_KEYS,
326 			PCIE_ERROR_PORT_TYPES_VALUES, "Unknown");
327 		json_object_object_add(section_ir, "portType", port_type);
328 	}
329 
330 	//Version, provided each half in BCD.
331 	if (isvalid_prop_to_ir(&ui64Type, 1)) {
332 		json_object *version = json_object_new_object();
333 		json_object_object_add(version, "minor",
334 				       json_object_new_int(bcd_to_int(
335 					       pcie_error->Version & 0xFF)));
336 		json_object_object_add(version, "major",
337 				       json_object_new_int(bcd_to_int(
338 					       pcie_error->Version >> 8)));
339 		json_object_object_add(section_ir, "version", version);
340 	}
341 
342 	//Command & status.
343 	if (isvalid_prop_to_ir(&ui64Type, 2)) {
344 		json_object *command_status = json_object_new_object();
345 		json_object_object_add(
346 			command_status, "commandRegister",
347 			json_object_new_uint64(pcie_error->CommandStatus &
348 					       0xFFFF));
349 		json_object_object_add(
350 			command_status, "statusRegister",
351 			json_object_new_uint64(pcie_error->CommandStatus >>
352 					       16));
353 		json_object_object_add(section_ir, "commandStatus",
354 				       command_status);
355 	}
356 
357 	//PCIe Device ID.
358 	if (isvalid_prop_to_ir(&ui64Type, 3)) {
359 		json_object *device_id = json_object_new_object();
360 
361 		UINT64 class_id = (pcie_error->DevBridge.ClassCode[2] << 16) +
362 				  (pcie_error->DevBridge.ClassCode[1] << 8) +
363 				  pcie_error->DevBridge.ClassCode[0];
364 		const char *class_name =
365 			get_class_code_name(pcie_error->DevBridge.ClassCode[2],
366 					    pcie_error->DevBridge.ClassCode[1],
367 					    pcie_error->DevBridge.ClassCode[0]);
368 		if (class_name != NULL) {
369 			json_object_object_add(
370 				device_id, "class",
371 				json_object_new_string(class_name));
372 		}
373 		add_int_hex_16(device_id, "deviceID_Hex",
374 			       pcie_error->DevBridge.DeviceId);
375 		add_int_hex_16(device_id, "vendorID_Hex",
376 			       pcie_error->DevBridge.VendorId);
377 		add_int_hex_24(device_id, "classCode_Hex", class_id);
378 		add_int_hex_8(device_id, "functionNumber_Hex",
379 			      pcie_error->DevBridge.Function);
380 		add_int_hex_8(device_id, "deviceNumber_Hex",
381 			      pcie_error->DevBridge.Device);
382 		add_int_hex_8(device_id, "segmentNumber_Hex",
383 			      pcie_error->DevBridge.Segment);
384 		add_int_hex_8(device_id, "primaryOrDeviceBusNumber_Hex",
385 			      pcie_error->DevBridge.PrimaryOrDeviceBus);
386 		add_int_hex_8(device_id, "secondaryBusNumber_Hex",
387 			      pcie_error->DevBridge.SecondaryBus);
388 		add_int_hex_8(device_id, "slotNumber_Hex",
389 			      pcie_error->DevBridge.Slot.Number);
390 		add_int(device_id, "deviceID", pcie_error->DevBridge.DeviceId);
391 
392 		add_int(device_id, "vendorID", pcie_error->DevBridge.VendorId);
393 
394 		add_int(device_id, "classCode", class_id);
395 
396 		add_int(device_id, "functionNumber",
397 			pcie_error->DevBridge.Function);
398 
399 		add_int(device_id, "deviceNumber",
400 			pcie_error->DevBridge.Device);
401 
402 		add_int(device_id, "segmentNumber",
403 			pcie_error->DevBridge.Segment);
404 
405 		add_int(device_id, "primaryOrDeviceBusNumber",
406 			pcie_error->DevBridge.PrimaryOrDeviceBus);
407 
408 		add_int(device_id, "secondaryBusNumber",
409 			pcie_error->DevBridge.SecondaryBus);
410 
411 		add_int(device_id, "slotNumber",
412 			pcie_error->DevBridge.Slot.Number);
413 
414 		json_object_object_add(section_ir, "deviceID", device_id);
415 	}
416 
417 	//Device serial number.
418 	if (isvalid_prop_to_ir(&ui64Type, 4)) {
419 		json_object_object_add(
420 			section_ir, "deviceSerialNumber",
421 			json_object_new_uint64(pcie_error->SerialNo));
422 	}
423 
424 	//Bridge control status.
425 	if (isvalid_prop_to_ir(&ui64Type, 5)) {
426 		json_object *bridge_control_status = json_object_new_object();
427 		json_object_object_add(
428 			bridge_control_status, "secondaryStatusRegister",
429 			json_object_new_uint64(pcie_error->BridgeControlStatus &
430 					       0xFFFF));
431 		json_object_object_add(
432 			bridge_control_status, "controlRegister",
433 			json_object_new_uint64(
434 				pcie_error->BridgeControlStatus >> 16));
435 		json_object_object_add(section_ir, "bridgeControlStatus",
436 				       bridge_control_status);
437 	}
438 
439 	//Capability structure.
440 	//The PCIe capability structure provided here could either be PCIe 1.1 Capability Structure
441 	//(36-byte, padded to 60 bytes) or PCIe 2.0 Capability Structure (60-byte).
442 	//Check the PCIe Capabilities Registers (offset 0x2) to determine the capability version.
443 	if (isvalid_prop_to_ir(&ui64Type, 6)) {
444 		json_object_object_add(section_ir, "capabilityStructure",
445 				       pcie_capability_to_ir(pcie_error));
446 	}
447 
448 	//AER information.
449 	if (isvalid_prop_to_ir(&ui64Type, 7)) {
450 		json_object_object_add(section_ir, "aerInfo",
451 				       pcie_aer_to_ir(pcie_error));
452 	}
453 
454 	return section_ir;
455 }
456 
457 //Converts PCIe Capability Structure section into JSON IR.
pcie_capability_to_ir(EFI_PCIE_ERROR_DATA * pcie_error)458 json_object *pcie_capability_to_ir(EFI_PCIE_ERROR_DATA *pcie_error)
459 {
460 	int32_t encoded_len = 0;
461 	char *encoded = NULL;
462 	json_object *pcie_capability_ir = json_object_new_object();
463 
464 	encoded = base64_encode((UINT8 *)pcie_error->Capability.PcieCap, 60,
465 				&encoded_len);
466 	if (encoded == NULL) {
467 		printf("Failed to allocate encode output buffer. \n");
468 	} else {
469 		json_object_object_add(pcie_capability_ir, "data",
470 				       json_object_new_string_len(encoded,
471 								  encoded_len));
472 		free(encoded);
473 	}
474 
475 	json_object *fields_ir;
476 	capability_registers *cap_decode;
477 	cap_decode = (capability_registers *)&pcie_error->Capability.PcieCap;
478 
479 	/*
480 	 * PCI Express Capability Structure Header
481 	 * Offset: 0x0
482 	 */
483 	fields_ir = json_object_new_object();
484 	pcie_capability_header_t *pcie_cap_header =
485 		&cap_decode->pcie_capability_header;
486 	add_dict(fields_ir, "capability_id", pcie_cap_header->capability_id,
487 		 NULL, 0);
488 	add_int(fields_ir, "next_capability_pointer",
489 		pcie_cap_header->next_capability_pointer);
490 	json_object_object_add(pcie_capability_ir, "pcie_capability_header",
491 			       fields_ir);
492 
493 	/*
494 	 * PCI Express Capabilities Register
495 	 * Offset: 0x2
496 	 */
497 	fields_ir = json_object_new_object();
498 	pcie_capabilities_t *pcie_cap = &cap_decode->pcie_capabilities;
499 	add_int(fields_ir, "capability_version", pcie_cap->capability_version);
500 	add_dict(fields_ir, "device_port_type", pcie_cap->device_port_type,
501 		 device_port_type_dict, device_port_type_dict_size);
502 	add_bool(fields_ir, "slot_implemented", pcie_cap->slot_implemented);
503 	add_int(fields_ir, "interrupt_message_number",
504 		pcie_cap->interrupt_message_number);
505 	//add_int(fields_ir, "undefined", pcie_cap->undefined);
506 	add_bool_enum(fields_ir, "flit_mode_supported", supported_dict,
507 		      pcie_cap->flit_mode_supported);
508 	json_object_object_add(pcie_capability_ir, "pcie_capabilities",
509 			       fields_ir);
510 
511 	/*
512 	 * Device Capabilities Register
513 	 * Offset: 0x4
514 	 */
515 	fields_ir = json_object_new_object();
516 	add_int(fields_ir, "max_payload_size_supported",
517 		cap_decode->device_capabilities.max_payload_size_supported);
518 	add_bool_enum(
519 		fields_ir, "phantom_functions_supported", supported_dict,
520 		cap_decode->device_capabilities.phantom_functions_supported);
521 	add_bool_enum(
522 		fields_ir, "extended_tag_field_supported", supported_dict,
523 		cap_decode->device_capabilities.extended_tag_field_supported);
524 	add_dict(
525 		fields_ir, "endpoint_l0s_acceptable_latency",
526 		cap_decode->device_capabilities.endpoint_l0s_acceptable_latency,
527 		NULL, 0);
528 	add_dict(fields_ir, "endpoint_l1_acceptable_latency",
529 		 cap_decode->device_capabilities.endpoint_l1_acceptable_latency,
530 		 NULL, 0);
531 	//add_int(fields_ir, "undefined",
532 	//	cap_decode->device_capabilities.undefined);
533 	add_bool(fields_ir, "role_based_error_reporting",
534 		 cap_decode->device_capabilities.role_based_error_reporting);
535 	add_bool(fields_ir, "err_cor_subclass_capable",
536 		 cap_decode->device_capabilities.err_cor_subclass_capable);
537 	add_int(fields_ir, "rx_mps_fixed",
538 		cap_decode->device_capabilities.rx_mps_fixed);
539 	add_int(fields_ir, "captured_slot_power_limit_value",
540 		cap_decode->device_capabilities.captured_slot_power_limit_value);
541 	add_int(fields_ir, "captured_slot_power_limit_scale",
542 		cap_decode->device_capabilities.captured_slot_power_limit_scale);
543 	add_bool_enum(
544 		fields_ir, "function_level_reset_capability_supported",
545 		supported_dict,
546 		cap_decode->device_capabilities.function_level_reset_capability);
547 	add_bool_enum(fields_ir, "mixed_mps_supported", supported_dict,
548 		      cap_decode->device_capabilities.mixed_mps_supported);
549 	add_bool_enum(fields_ir, "tee_io_supported", supported_dict,
550 		      cap_decode->device_capabilities.tee_io_supported);
551 	//add_int(fields_ir, "rsvdp", cap_decode->device_capabilities.rsvdp);
552 	json_object_object_add(pcie_capability_ir, "device_capabilities",
553 			       fields_ir);
554 
555 	/*
556 	 * Device Control Register
557 	 * Offset: 0x8
558 	 */
559 	fields_ir = json_object_new_object();
560 	add_bool_enum(
561 		fields_ir, "correctable_error_reporting_enable", enabled_dict,
562 		cap_decode->device_control.correctable_error_reporting_enable);
563 	add_bool_enum(
564 		fields_ir, "non_fatal_error_reporting_enable", enabled_dict,
565 		cap_decode->device_control.non_fatal_error_reporting_enable);
566 	add_bool_enum(fields_ir, "fatal_error_reporting_enable", enabled_dict,
567 		      cap_decode->device_control.fatal_error_reporting_enable);
568 	add_bool_enum(
569 		fields_ir, "unsupported_request_reporting_enabled",
570 		enabled_dict,
571 		cap_decode->device_control.unsupported_request_reporting_enable);
572 	add_bool_enum(fields_ir, "relaxed_ordering_enable", enabled_dict,
573 		      cap_decode->device_control.enable_relaxed_ordering);
574 	add_int(fields_ir, "max_payload_size",
575 		cap_decode->device_control.max_payload_size);
576 	add_bool_enum(fields_ir, "extended_tag_field_enable", enabled_dict,
577 		      cap_decode->device_control.extended_tag_field_enable);
578 	add_bool_enum(fields_ir, "phantom_functions_enable", enabled_dict,
579 		      cap_decode->device_control.phantom_functions_enable);
580 	add_bool_enum(fields_ir, "aux_power_pm_enable", enabled_dict,
581 		      cap_decode->device_control.aux_power_pm_enable);
582 	add_int(fields_ir, "enable_no_snoop",
583 		cap_decode->device_control.enable_no_snoop);
584 	add_int(fields_ir, "max_read_request_size",
585 		cap_decode->device_control.max_read_request_size);
586 	add_bool(fields_ir, "function_level_reset",
587 		 cap_decode->device_control.function_level_reset);
588 	json_object_object_add(pcie_capability_ir, "device_control", fields_ir);
589 
590 	/*
591 	 * Device Status Register
592 	 * Offset: 0xA
593 	 */
594 	fields_ir = json_object_new_object();
595 	add_bool(fields_ir, "correctable_error_detected",
596 		 cap_decode->device_status.correctable_error_detected);
597 	add_bool(fields_ir, "non_fatal_error_detected",
598 		 cap_decode->device_status.non_fatal_error_detected);
599 	add_bool(fields_ir, "fatal_error_detected",
600 		 cap_decode->device_status.fatal_error_detected);
601 	add_bool(fields_ir, "unsupported_request_detected",
602 		 cap_decode->device_status.unsupported_request_detected);
603 	add_bool(fields_ir, "aux_power_detected",
604 		 cap_decode->device_status.aux_power_detected);
605 	add_bool(fields_ir, "transactions_pending",
606 		 cap_decode->device_status.transactions_pending);
607 	add_int(fields_ir, "emergency_power_reduction",
608 		cap_decode->device_status.emergency_power_reduction);
609 	//add_int(fields_ir, "rsvdz", cap_decode->device_status.rsvdz);
610 	json_object_object_add(pcie_capability_ir, "device_status", fields_ir);
611 
612 	/*
613 	 * Link Capabilities Register
614 	 * Offset: 0xC
615 	 */
616 	fields_ir = json_object_new_object();
617 	add_int(fields_ir, "max_link_speed",
618 		cap_decode->link_capabilities.max_link_speed);
619 	add_int(fields_ir, "maximum_link_width",
620 		cap_decode->link_capabilities.maximum_link_width);
621 	add_int(fields_ir, "aspm_support",
622 		cap_decode->link_capabilities.aspm_support);
623 	add_int(fields_ir, "l0s_exit_latency",
624 		cap_decode->link_capabilities.l0s_exit_latency);
625 	add_int(fields_ir, "l1_exit_latency",
626 		cap_decode->link_capabilities.l1_exit_latency);
627 	add_bool(fields_ir, "clock_power_management",
628 		 cap_decode->link_capabilities.clock_power_management);
629 	add_bool(fields_ir, "surprise_down_error_reporting_capable",
630 		 cap_decode->link_capabilities
631 			 .surprise_down_error_reporting_capable);
632 	add_bool(fields_ir, "data_link_layer_link_active_reporting_capable",
633 		 cap_decode->link_capabilities
634 			 .data_link_layer_link_active_reporting_capable);
635 	add_bool(fields_ir, "link_bandwidth_notification_capability",
636 		 cap_decode->link_capabilities
637 			 .link_bandwidth_notification_capability);
638 	add_bool(fields_ir, "aspm_optionality_compliance",
639 		 cap_decode->link_capabilities.aspm_optionality_compliance);
640 	//add_int(fields_ir, "rsvdp", cap_decode->link_capabilities.rsvdp);
641 	add_int(fields_ir, "port_number",
642 		cap_decode->link_capabilities.port_number);
643 	json_object_object_add(pcie_capability_ir, "link_capabilities",
644 			       fields_ir);
645 
646 	/*
647 	 * Link Control Register
648 	 * Offset: 0x10
649 	 */
650 	fields_ir = json_object_new_object();
651 	add_int(fields_ir, "aspm_control",
652 		cap_decode->link_control.aspm_control);
653 	add_bool(fields_ir, "ptm_prop_delay_adaptation_interpretation",
654 		 cap_decode->link_control
655 			 .ptm_prop_delay_adaptation_interpretation);
656 	//add_bool(fields_ir, "read_completion_boundary",
657 	//	 cap_decode->link_control.read_completion_boundary);
658 	add_int(fields_ir, "link_disable",
659 		cap_decode->link_control.link_disable);
660 	add_int(fields_ir, "retrain_link",
661 		cap_decode->link_control.retrain_link);
662 	//add_bool(fields_ir, "common_clock_configuration",
663 	//	 cap_decode->link_control.common_clock_configuration);
664 	add_int(fields_ir, "extended_synch",
665 		cap_decode->link_control.extended_synch);
666 	//add_bool(fields_ir, "enable_clock_power_management",
667 	//	 cap_decode->link_control.enable_clock_power_management);
668 	//add_bool(fields_ir, "hardware_autonomous_width_disable",
669 	//	 cap_decode->link_control.hardware_autonomous_width_disable);
670 	//add_bool(fields_ir, "link_bandwidth_management_interrupt_enable",
671 	//	 cap_decode->link_control
672 	//		 .link_bandwidth_management_interrupt_enable);
673 	//add_bool(fields_ir, "link_autonomous_bandwidth_interrupt_enable",
674 	//	 cap_decode->link_control
675 	//		 .link_autonomous_bandwidth_interrupt_enable);
676 	add_int(fields_ir, "sris_clocking",
677 		cap_decode->link_control.sris_clocking);
678 	add_int(fields_ir, "flit_mode_disable",
679 		cap_decode->link_control.flit_mode_disable);
680 	//add_bool(fields_ir, "drs_signaling_control",
681 	//	 cap_decode->link_control.drs_signaling_control);
682 	json_object_object_add(pcie_capability_ir, "link_control", fields_ir);
683 
684 	/*
685 	 * Link Status Register
686 	 * Offset: 0x12
687 	 */
688 	fields_ir = json_object_new_object();
689 	add_int(fields_ir, "current_link_speed",
690 		cap_decode->link_status.current_link_speed);
691 	add_int(fields_ir, "negotiated_link_width",
692 		cap_decode->link_status.negotiated_link_width);
693 	//add_int(fields_ir, "undefined", cap_decode->link_status.undefined);
694 	add_int(fields_ir, "link_training",
695 		cap_decode->link_status.link_training);
696 	//add_bool(fields_ir, "slot_clock_configuration",
697 	//	 cap_decode->link_status.slot_clock_configuration);
698 	//add_bool(fields_ir, "data_link_layer_link_active",
699 	//	 cap_decode->link_status.data_link_layer_link_active);
700 	//add_bool(fields_ir, "link_bandwidth_management_status",
701 	//	 cap_decode->link_status.link_bandwidth_management_status);
702 	//add_bool(fields_ir, "link_autonomous_bandwidth_status",
703 	//	 cap_decode->link_status.link_autonomous_bandwidth_status);
704 	json_object_object_add(pcie_capability_ir, "link_status", fields_ir);
705 
706 	/*
707 	 * Slot Capabilities Register
708 	 * Offset: 0x14
709 	 */
710 	fields_ir = json_object_new_object();
711 	//add_bool(fields_ir, "attention_button_present",
712 	//	 cap_decode->slot_capabilities.attention_button_present);
713 	//add_bool(fields_ir, "power_controller_present",
714 	//	 cap_decode->slot_capabilities.power_controller_present);
715 	//add_bool(fields_ir, "mrl_sensor_present",
716 	//	 cap_decode->slot_capabilities.mrl_sensor_present);
717 	//add_bool(fields_ir, "attention_indicator_present",
718 	//	 cap_decode->slot_capabilities.attention_indicator_present);
719 	//add_bool(fields_ir, "power_indicator_present",
720 	//	 cap_decode->slot_capabilities.power_indicator_present);
721 	//add_bool(fields_ir, "hot_plug_surprise",
722 	//	 cap_decode->slot_capabilities.hot_plug_surprise);
723 	//add_bool(fields_ir, "hot_plug_capable",
724 	//	 cap_decode->slot_capabilities.hot_plug_capable);
725 	add_dict(fields_ir, "slot_power_limit_value",
726 		 cap_decode->slot_capabilities.slot_power_limit_value, NULL, 0);
727 	add_int(fields_ir, "slot_power_limit_scale",
728 		cap_decode->slot_capabilities.slot_power_limit_scale);
729 	//add_bool(fields_ir, "electromechanical_interlock_present",
730 	//	 cap_decode->slot_capabilities
731 	//		 .electromechanical_interlock_present);
732 	//add_bool(fields_ir, "no_command_completed_support",
733 	//	 cap_decode->slot_capabilities.no_command_completed_support);
734 	add_int(fields_ir, "physical_slot_number",
735 		cap_decode->slot_capabilities.physical_slot_number);
736 	json_object_object_add(pcie_capability_ir, "slot_capabilities",
737 			       fields_ir);
738 
739 	/*
740 	 * Slot Control Register
741 	 * Offset: 0x18
742 	 */
743 	fields_ir = json_object_new_object();
744 	//add_bool(fields_ir, "attention_button_pressed_enable",
745 	//	 cap_decode->slot_control.attention_button_pressed_enable);
746 	//add_bool(fields_ir, "power_fault_detected_enable",
747 	//	 cap_decode->slot_control.power_fault_detected_enable);
748 	//add_bool(fields_ir, "mrl_sensor_changed_enable",
749 	//	 cap_decode->slot_control.mrl_sensor_changed_enable);
750 	//add_bool(fields_ir, "presence_detect_changed_enable",
751 	//	 cap_decode->slot_control.presence_detect_changed_enable);
752 	//add_bool(fields_ir, "command_completed_interrupt_enable",
753 	//	 cap_decode->slot_control.command_completed_interrupt_enable);
754 	//add_bool(fields_ir, "hot_plug_interrupt_enable",
755 	//	 cap_decode->slot_control.hot_plug_interrupt_enable);
756 	add_int(fields_ir, "attention_indicator_control",
757 		cap_decode->slot_control.attention_indicator_control);
758 	add_int(fields_ir, "power_indicator_control",
759 		cap_decode->slot_control.power_indicator_control);
760 	//add_bool(fields_ir, "power_controller_control",
761 	//	 cap_decode->slot_control.power_controller_control);
762 	//add_bool(fields_ir, "electromechanical_interlock_control",
763 	//	 cap_decode->slot_control.electromechanical_interlock_control);
764 	//add_bool(fields_ir, "data_link_layer_state_changed_enable",
765 	//	 cap_decode->slot_control.data_link_layer_state_changed_enable);
766 	//add_bool(fields_ir, "auto_slot_power_limit_disable",
767 	//	 cap_decode->slot_control.auto_slot_power_limit_disable);
768 	//add_bool(fields_ir, "in_band_pd_disable",
769 	//	 cap_decode->slot_control.in_band_pd_disable);
770 	add_int(fields_ir, "rsvdp", cap_decode->slot_control.rsvdp);
771 	json_object_object_add(pcie_capability_ir, "slot_control", fields_ir);
772 
773 	/*
774 	 * Slot Status Register
775 	 * Offset: 0x1A
776 	 */
777 	fields_ir = json_object_new_object();
778 	//add_bool(fields_ir, "attention_button_pressed",
779 	//	 cap_decode->slot_status.attention_button_pressed);
780 	//add_bool(fields_ir, "power_fault_detected",
781 	//	 cap_decode->slot_status.power_fault_detected);
782 	add_int(fields_ir, "mrl_sensor_changed",
783 		cap_decode->slot_status.mrl_sensor_changed);
784 	//add_bool(fields_ir, "presence_detect_changed",
785 	//	 cap_decode->slot_status.presence_detect_changed);
786 	add_int(fields_ir, "command_completed",
787 		cap_decode->slot_status.command_completed);
788 	add_int(fields_ir, "mrl_sensor_state",
789 		cap_decode->slot_status.mrl_sensor_state);
790 	//add_bool(fields_ir, "presence_detect_state",
791 	//	 cap_decode->slot_status.presence_detect_state);
792 	//add_bool(fields_ir, "electromechanical_interlock_status",
793 	//	 cap_decode->slot_status.electromechanical_interlock_status);
794 	//add_bool(fields_ir, "data_link_layer_state_changed",
795 	//	 cap_decode->slot_status.data_link_layer_state_changed);
796 	//add_int(fields_ir, "rsvdz", cap_decode->slot_status.rsvdz);
797 	json_object_object_add(pcie_capability_ir, "slot_status", fields_ir);
798 
799 	/*
800 	 * Root Control Register
801 	 * Offset: 0x1C
802 	 */
803 	//fields_ir = json_object_new_object();
804 	//add_bool(fields_ir, "system_error_on_correctable_error_enable",
805 	//	 cap_decode->root_control
806 	//		 .system_error_on_correctable_error_enable);
807 	//add_bool(
808 	//	fields_ir, "system_error_on_non_fatal_error_enable",
809 	//	cap_decode->root_control.system_error_on_non_fatal_error_enable);
810 	//add_bool(fields_ir, "system_error_on_fatal_error_enable",
811 	//	 cap_decode->root_control.system_error_on_fatal_error_enable);
812 	//add_bool(fields_ir, "pme_interrupt_enable",
813 	//	 cap_decode->root_control.pme_interrupt_enable);
814 	//add_bool(fields_ir, "configuration_rrs_software_visibility_enable",
815 	//	 cap_decode->root_control
816 	//		 .configuration_rrs_software_visibility_enable);
817 	//add_bool(fields_ir, "no_nfm_subtree_below_this_root_port",
818 	//	 cap_decode->root_control.no_nfm_subtree_below_this_root_port);
819 	//add_int(fields_ir, "rsvdp", cap_decode->root_control.rsvdp);
820 	//json_object_object_add(pcie_capability_ir, "root_control", fields_ir);
821 
822 	/*
823 	 * Root Capabilities Register
824 	 * Offset: 0x1E
825 	 */
826 	//fields_ir = json_object_new_object();
827 	//add_bool(fields_ir, "configuraton_rrs_software_visibility",
828 	//	 cap_decode->root_capabilities
829 	//		 .configuraton_rrs_software_visibility);
830 	//add_int(fields_ir, "rsvdp", cap_decode->root_capabilities.rsvdp);
831 	//json_object_object_add(pcie_capability_ir, "root_capabilities",
832 	//		       fields_ir);
833 
834 	/*
835 	 * Root Status Register
836 	 * Offset: 0x20
837 	 */
838 	fields_ir = json_object_new_object();
839 	add_int(fields_ir, "pme_requester_id",
840 		cap_decode->root_status.pme_requester_id);
841 	add_int(fields_ir, "pme_status", cap_decode->root_status.pme_status);
842 	add_int(fields_ir, "pme_pending", cap_decode->root_status.pme_pending);
843 	//add_int(fields_ir, "rsvdp", cap_decode->root_status.rsvdp);
844 	json_object_object_add(pcie_capability_ir, "root_status", fields_ir);
845 
846 	if (cap_decode->pcie_capabilities.capability_version < 2) {
847 		return pcie_capability_ir;
848 	}
849 
850 	/*
851 	 * Device Capabilities 2 Register
852 	 * Offset: 0x24
853 	 */
854 	fields_ir = json_object_new_object();
855 	add_int(fields_ir, "completion_timeout_ranges_supported",
856 		cap_decode->device_capabilities2
857 			.completion_timeout_ranges_supported);
858 	add_bool_enum(fields_ir, "completion_timeout_disable_supported",
859 		      supported_dict,
860 		      cap_decode->device_capabilities2
861 			      .completion_timeout_disable_supported);
862 	add_bool_enum(
863 		fields_ir, "ari_forwarding_supported", supported_dict,
864 		cap_decode->device_capabilities2.ari_forwarding_supported);
865 	add_bool_enum(
866 		fields_ir, "atomic_op_routing_supported", supported_dict,
867 		cap_decode->device_capabilities2.atomic_op_routing_supported);
868 	add_bool_enum(fields_ir, "_32_bit_atomicop_completer_supported",
869 		      supported_dict,
870 		      cap_decode->device_capabilities2
871 			      ._32_bit_atomicop_completer_supported);
872 	add_bool_enum(fields_ir, "_64_bit_atomicop_completer_supported",
873 		      supported_dict,
874 		      cap_decode->device_capabilities2
875 			      ._64_bit_atomicop_completer_supported);
876 	add_bool_enum(fields_ir, "_128_bit_cas_completer_supported",
877 		      supported_dict,
878 		      cap_decode->device_capabilities2
879 			      ._128_bit_cas_completer_supported);
880 	add_bool_enum(
881 		fields_ir, "no_ro_enabled_pr_pr_passing", passing_dict,
882 		cap_decode->device_capabilities2.no_ro_enabled_pr_pr_passing);
883 	add_bool_enum(fields_ir, "ltr_mechanism_supported", supported_dict,
884 		      cap_decode->device_capabilities2.ltr_mechanism_supported);
885 	add_bool_enum(fields_ir, "tph_completer_supported", supported_dict,
886 		      cap_decode->device_capabilities2.tph_completer_supported);
887 	//add_int(fields_ir, "undefined",
888 	//	cap_decode->device_capabilities2.undefined);
889 	//add_bool(fields_ir, "_10_bit_tag_completer_supported",
890 	//	 cap_decode->device_capabilities2
891 	//		 ._10_bit_tag_completer_supported);
892 	//add_bool(fields_ir, "_10_bit_tag_requester_supported",
893 	//	 cap_decode->device_capabilities2
894 	//		 ._10_bit_tag_requester_supported);
895 	add_bool_enum(fields_ir, "obff_supported", supported_dict,
896 		      cap_decode->device_capabilities2.obff_supported);
897 	//add_bool(fields_ir, "extended_fmt_field_supported",
898 	//	 cap_decode->device_capabilities2.extended_fmt_field_supported);
899 	//add_bool(fields_ir, "end_end_tlp_prefix_supported",
900 	//	 cap_decode->device_capabilities2.end_end_tlp_prefix_supported);
901 	add_dict(fields_ir, "max_end_end_tlp_prefixes",
902 		 cap_decode->device_capabilities2.max_end_end_tlp_prefixes,
903 		 NULL, 0);
904 	add_bool_enum(fields_ir, "emergency_power_reduction_supported",
905 		      supported_dict,
906 		      cap_decode->device_capabilities2
907 			      .emergency_power_reduction_supported);
908 	//add_bool(fields_ir, "emergency_power_reduction_init_required",
909 	//	 cap_decode->device_capabilities2
910 	//		 .emergency_power_reduction_init_required);
911 	//add_int(fields_ir, "rsvdp", cap_decode->device_capabilities2.rsvdp);
912 	//add_bool(fields_ir, "dmwr_completer_supported",
913 	//	 cap_decode->device_capabilities2.dmwr_completer_supported);
914 	add_int(fields_ir, "dmwr_lengths_supported",
915 		cap_decode->device_capabilities2.dmwr_lengths_supported);
916 	//add_bool(fields_ir, "frs_supported",
917 	//	 cap_decode->device_capabilities2.frs_supported);
918 	json_object_object_add(pcie_capability_ir, "device_capabilities2",
919 			       fields_ir);
920 
921 	/*
922 	 * Device Control 2 Register
923 	 * Offset: 0x28
924 	 */
925 	fields_ir = json_object_new_object();
926 	add_int(fields_ir, "completion_timeout_value",
927 		cap_decode->device_control2.completion_timeout_value);
928 	//add_bool(fields_ir, "completion_timeout_disable",
929 	//	 cap_decode->device_control2.completion_timeout_disable);
930 	add_bool(fields_ir, "ari_forwarding_enable",
931 		 cap_decode->device_control2.ari_forwarding_enable);
932 	add_bool(fields_ir, "atomicop_requester_enable",
933 		 cap_decode->device_control2.atomicop_requester_enable);
934 	add_bool(fields_ir, "atomicop_egress_blocking",
935 		 cap_decode->device_control2.atomicop_egress_blocking);
936 	add_bool(fields_ir, "ido_request_enable",
937 		 cap_decode->device_control2.ido_request_enable);
938 	add_bool(fields_ir, "ido_completion_enable",
939 		 cap_decode->device_control2.ido_completion_enable);
940 	add_bool(fields_ir, "ltr_mechanism_enable",
941 		 cap_decode->device_control2.ltr_mechanism_enable);
942 	add_bool(fields_ir, "emergency_power_reduction_request",
943 		 cap_decode->device_control2.emergency_power_reduction_request);
944 	add_bool(fields_ir, "bit_tag_requester_10_enable",
945 		 cap_decode->device_control2.bit_tag_requester_10_enable);
946 	add_int(fields_ir, "obff_enable",
947 		cap_decode->device_control2.obff_enable);
948 	//add_bool(fields_ir, "end_end_tlp_prefix_blocking",
949 	//	 cap_decode->device_control2.end_end_tlp_prefix_blocking);
950 	json_object_object_add(pcie_capability_ir, "device_control2",
951 			       fields_ir);
952 
953 	/*
954 	 * Device Status 2 Register
955 	 * Offset: 0x2A
956 	 */
957 	//fields_ir = json_object_new_object();
958 	//add_int(fields_ir, "rsvdz", cap_decode->device_status2.rsvdz);
959 	//json_object_object_add(pcie_capability_ir, "device_status2", fields_ir);
960 
961 	/*
962 	 * Link Capabilities 2 Register
963 	 * Offset: 0x2C
964 	 */
965 	fields_ir = json_object_new_object();
966 	//add_int(fields_ir, "rsvdp", cap_decode->link_capabilities2.rsvdp);
967 	add_int(fields_ir, "supported_link_speeds",
968 		cap_decode->link_capabilities2.supported_link_speeds_register);
969 	add_bool_enum(fields_ir, "crosslink_supported", supported_dict,
970 		      cap_decode->link_capabilities2.crosslink_supported);
971 	add_int(fields_ir, "lower_skp_os_generation_supported",
972 		cap_decode->link_capabilities2
973 			.lower_skp_os_generation_supported);
974 	add_int(fields_ir, "lower_skp_os_reception_supported",
975 		cap_decode->link_capabilities2.lower_skp_os_reception_supported);
976 	add_bool_enum(fields_ir, "retimer_presence_detect_supported",
977 		      supported_dict,
978 		      cap_decode->link_capabilities2
979 			      .retimer_presence_detect_supported);
980 	add_bool_enum(fields_ir, "two_retimers_presence_detect_supported",
981 		      supported_dict,
982 		      cap_decode->link_capabilities2
983 			      .two_retimers_presence_detect_supported);
984 	//add_int(fields_ir, "reserved", cap_decode->link_capabilities2.reserved);
985 	add_bool_enum(fields_ir, "drs_supported", supported_dict,
986 		      cap_decode->link_capabilities2.drs_supported);
987 	json_object_object_add(pcie_capability_ir, "link_capabilities2",
988 			       fields_ir);
989 
990 	/*
991 	 * Link Control 2 Register
992 	 * Offset: 0x30
993 	 */
994 	fields_ir = json_object_new_object();
995 	add_dict(fields_ir, "target_link_speed",
996 		 cap_decode->link_control2.target_link_speed, NULL, 0);
997 	add_bool_enum(fields_ir, "enter_compliance", supported_dict,
998 		      cap_decode->link_control2.enter_compliance);
999 	add_dict(fields_ir, "hardware_autonomous_speed_disable",
1000 		 cap_decode->link_control2.hardware_autonomous_speed_disable,
1001 		 NULL, 0);
1002 	add_bool(fields_ir, "selectable_de_emphasis",
1003 		 cap_decode->link_control2.selectable_de_emphasis);
1004 	add_int(fields_ir, "transmit_margin",
1005 		cap_decode->link_control2.transmit_margin);
1006 	add_bool(fields_ir, "enter_modified_compliance",
1007 		 cap_decode->link_control2.enter_modified_compliance);
1008 	add_bool(fields_ir, "compliance_sos",
1009 		 cap_decode->link_control2.compliance_sos);
1010 	add_int(fields_ir, "compliance_preset_de_emphasis",
1011 		cap_decode->link_control2.compliance_preset_de_emphasis);
1012 	json_object_object_add(pcie_capability_ir, "link_control2", fields_ir);
1013 
1014 	/*
1015 	 * Link Status 2 Register
1016 	 * Offset: 0x32
1017 	 */
1018 	fields_ir = json_object_new_object();
1019 	add_int(fields_ir, "current_de_emphasis_level",
1020 		cap_decode->link_status2.current_de_emphasis_level);
1021 	add_bool(fields_ir, "equalization_8gts_complete",
1022 		 cap_decode->link_status2.equalization_8gts_complete);
1023 	add_bool(fields_ir, "equalization_8gts_phase1_successful",
1024 		 cap_decode->link_status2.equalization_8gts_phase1_successful);
1025 	add_bool(fields_ir, "equalization_8gts_phase2_successful",
1026 		 cap_decode->link_status2.equalization_8gts_phase2_successful);
1027 	add_bool(fields_ir, "equalization_8gts_phase3_successful",
1028 		 cap_decode->link_status2.equalization_8gts_phase3_successful);
1029 	add_bool(fields_ir, "link_equalization_request_8gts",
1030 		 cap_decode->link_status2.link_equalization_request_8gts);
1031 	add_bool(fields_ir, "retimer_presence_detected",
1032 		 cap_decode->link_status2.retimer_presence_detected);
1033 	add_bool(fields_ir, "two_retimers_presence_detected",
1034 		 cap_decode->link_status2.two_retimers_presence_detected);
1035 	add_int(fields_ir, "crosslink_resolution",
1036 		cap_decode->link_status2.crosslink_resolution);
1037 	add_int(fields_ir, "flit_mode_status",
1038 		cap_decode->link_status2.flit_mode_status);
1039 	//add_int(fields_ir, "rsvdz", cap_decode->link_status2.rsvdz);
1040 	add_int(fields_ir, "downstream_component_presence",
1041 		cap_decode->link_status2.downstream_component_presence);
1042 	add_bool(fields_ir, "drs_message_received",
1043 		 cap_decode->link_status2.drs_message_received);
1044 	json_object_object_add(pcie_capability_ir, "link_status2", fields_ir);
1045 
1046 	/*
1047 	 * Slot Capabilities 2 Register
1048 	 * Offset: 0x34
1049 	 */
1050 	//fields_ir = json_object_new_object();
1051 	//add_int(fields_ir, "rsvdp", cap_decode->slot_capabilities2.rsvdp);
1052 	//json_object_object_add(pcie_capability_ir, "slot_capabilities2",
1053 	//		       fields_ir);
1054 
1055 	/*
1056 	 * Slot Control 2 Register
1057 	 * Offset: 0x38
1058 	 */
1059 	//fields_ir = json_object_new_object();
1060 	//add_int(fields_ir, "rsvdp", cap_decode->slot_control2.rsvdp);
1061 	//json_object_object_add(pcie_capability_ir, "slot_control2", fields_ir);
1062 
1063 	/*
1064 	 * Slot Status 2 Register
1065 	 * Offset: 0x3A
1066 	 */
1067 	//fields_ir = json_object_new_object();
1068 	//add_int(fields_ir, "rsvdp", cap_decode->slot_status2.rsvdp);
1069 	//json_object_object_add(pcie_capability_ir, "slot_status2", fields_ir);
1070 
1071 	return pcie_capability_ir;
1072 }
1073 
1074 //Converts PCIe Capability Structure section into JSON IR.
pcie_aer_to_ir(EFI_PCIE_ERROR_DATA * pcie_error)1075 json_object *pcie_aer_to_ir(EFI_PCIE_ERROR_DATA *pcie_error)
1076 {
1077 	int32_t encoded_len = 0;
1078 	char *encoded = NULL;
1079 	json_object *aer_capability_ir = json_object_new_object();
1080 
1081 	encoded = base64_encode((UINT8 *)pcie_error->AerInfo.PcieAer, 96,
1082 				&encoded_len);
1083 	if (encoded == NULL) {
1084 		printf("Failed to allocate encode output buffer. \n");
1085 	} else {
1086 		json_object_object_add(aer_capability_ir, "data",
1087 				       json_object_new_string_len(encoded,
1088 								  encoded_len));
1089 		free(encoded);
1090 	}
1091 
1092 	json_object *fields_ir;
1093 
1094 	aer_info_registers *aer_decode;
1095 	aer_decode = (aer_info_registers *)&pcie_error->AerInfo.PcieAer;
1096 
1097 	/*
1098 	 * AER Capability Header
1099 	 * Offset: 0x0
1100 	 */
1101 	fields_ir = json_object_new_object();
1102 	add_int(fields_ir, "capability_id",
1103 		aer_decode->capability_header.capability_id);
1104 	add_int(fields_ir, "capability_version",
1105 		aer_decode->capability_header.capability_version);
1106 	add_int(fields_ir, "next_capability_offset",
1107 		aer_decode->capability_header.next_capability_offset);
1108 	json_object_object_add(aer_capability_ir, "capability_header",
1109 			       fields_ir);
1110 
1111 	/*
1112 	 * Uncorrectable Error Status Register
1113 	 * Offset: 0x4
1114 	 */
1115 	fields_ir = json_object_new_object();
1116 	//add_bool(fields_ir, "undefined",
1117 	//	 aer_decode->uncorrectable_error_status.undefined);
1118 	//add_int(fields_ir, "rsvdz1",
1119 	//	aer_decode->uncorrectable_error_status.rsvdz1);
1120 	add_bool(fields_ir, "data_link_protocol_error_status",
1121 		 aer_decode->uncorrectable_error_status
1122 			 .data_link_protocol_error_status);
1123 	add_bool(fields_ir, "surprise_down_error_status",
1124 		 aer_decode->uncorrectable_error_status
1125 			 .surprise_down_error_status);
1126 	//add_int(fields_ir, "rsvdz2",
1127 	//	aer_decode->uncorrectable_error_status.rsvdz2);
1128 	add_bool(fields_ir, "poisoned_tlp_received",
1129 		 aer_decode->uncorrectable_error_status.poisoned_tlp_received);
1130 	add_bool(fields_ir, "flow_control_protocol_error_status",
1131 		 aer_decode->uncorrectable_error_status
1132 			 .flow_control_protocol_error_status);
1133 	add_bool(fields_ir, "completion_timeout_status",
1134 		 aer_decode->uncorrectable_error_status
1135 			 .completion_timeout_status);
1136 	add_bool(fields_ir, "completer_abort_status",
1137 		 aer_decode->uncorrectable_error_status.completer_abort_status);
1138 	add_bool(fields_ir, "unexpected_completion_status",
1139 		 aer_decode->uncorrectable_error_status
1140 			 .unexpected_completion_status);
1141 	add_bool(
1142 		fields_ir, "receiver_overflow_status",
1143 		aer_decode->uncorrectable_error_status.receiver_overflow_status);
1144 	add_bool(fields_ir, "malformed_tlp_status",
1145 		 aer_decode->uncorrectable_error_status.malformed_tlp_status);
1146 	add_bool(fields_ir, "ecrc_error_status",
1147 		 aer_decode->uncorrectable_error_status.ecrc_error_status);
1148 	add_bool(fields_ir, "unsupported_request_error_status",
1149 		 aer_decode->uncorrectable_error_status
1150 			 .unsupported_request_error_status);
1151 	add_bool(fields_ir, "acs_violation_status",
1152 		 aer_decode->uncorrectable_error_status.acs_violation_status);
1153 	add_bool(fields_ir, "uncorrectable_internal_error_status",
1154 		 aer_decode->uncorrectable_error_status
1155 			 .uncorrectable_internal_error_status);
1156 	add_bool(fields_ir, "mc_blocked_tlp_status",
1157 		 aer_decode->uncorrectable_error_status.mc_blocked_tlp_status);
1158 	add_bool(fields_ir, "atomicop_egress_blocked_status",
1159 		 aer_decode->uncorrectable_error_status
1160 			 .atomicop_egress_blocked_status);
1161 	add_bool(fields_ir, "tlp_prefix_blocked_error_status",
1162 		 aer_decode->uncorrectable_error_status
1163 			 .tlp_prefix_blocked_error_status);
1164 	add_bool(fields_ir, "poisoned_tlp_egress_blocked_status",
1165 		 aer_decode->uncorrectable_error_status
1166 			 .poisoned_tlp_egress_blocked_status);
1167 	add_bool(fields_ir, "dmwr_request_egress_blocked_status",
1168 		 aer_decode->uncorrectable_error_status
1169 			 .dmwr_request_egress_blocked_status);
1170 	add_bool(
1171 		fields_ir, "ide_check_failed_status",
1172 		aer_decode->uncorrectable_error_status.ide_check_failed_status);
1173 	add_bool(
1174 		fields_ir, "misrouted_ide_tlp_status",
1175 		aer_decode->uncorrectable_error_status.misrouted_ide_tlp_status);
1176 	add_bool(
1177 		fields_ir, "pcrc_check_failed_status",
1178 		aer_decode->uncorrectable_error_status.pcrc_check_failed_status);
1179 	add_bool(fields_ir, "tlp_translation_egress_blocked_status",
1180 		 aer_decode->uncorrectable_error_status
1181 			 .tlp_translation_egress_blocked_status);
1182 	json_object_object_add(aer_capability_ir, "uncorrectable_error_status",
1183 			       fields_ir);
1184 
1185 	/*
1186 	 * Uncorrectable Error Mask Register
1187 	 * Offset: 0x8
1188 	 */
1189 	fields_ir = json_object_new_object();
1190 	//add_bool(fields_ir, "undefined",
1191 	//	 aer_decode->uncorrectable_error_mask.undefined);
1192 	//add_int(fields_ir, "rsvdz1",
1193 	//	aer_decode->uncorrectable_error_mask.rsvdz1);
1194 	add_int(fields_ir, "data_link_protocol_error_mask",
1195 		aer_decode->uncorrectable_error_mask
1196 			.data_link_protocol_error_mask);
1197 	add_int(fields_ir, "surprise_down_error_mask",
1198 		aer_decode->uncorrectable_error_mask.surprise_down_error_mask);
1199 	//add_int(fields_ir, "rsvdz2",
1200 	//	aer_decode->uncorrectable_error_mask.rsvdz2);
1201 	add_int(fields_ir, "poisoned_tlp_received_mask",
1202 		aer_decode->uncorrectable_error_mask.poisoned_tlp_received_mask);
1203 	add_int(fields_ir, "flow_control_protocol_error_mask",
1204 		aer_decode->uncorrectable_error_mask
1205 			.flow_control_protocol_error_mask);
1206 	add_int(fields_ir, "completion_timeout_mask",
1207 		aer_decode->uncorrectable_error_mask.completion_timeout_mask);
1208 	add_int(fields_ir, "completer_abort_mask",
1209 		aer_decode->uncorrectable_error_mask.completer_abort_mask);
1210 	add_int(fields_ir, "unexpected_completion_mask",
1211 		aer_decode->uncorrectable_error_mask.unexpected_completion_mask);
1212 	add_int(fields_ir, "receiver_overflow_mask",
1213 		aer_decode->uncorrectable_error_mask.receiver_overflow_mask);
1214 	add_int(fields_ir, "malformed_tlp_mask",
1215 		aer_decode->uncorrectable_error_mask.malformed_tlp_mask);
1216 	add_int(fields_ir, "ecrc_error_mask",
1217 		aer_decode->uncorrectable_error_mask.ecrc_error_mask);
1218 	add_int(fields_ir, "unsupported_request_error_mask",
1219 		aer_decode->uncorrectable_error_mask
1220 			.unsupported_request_error_mask);
1221 	add_int(fields_ir, "acs_violation_mask",
1222 		aer_decode->uncorrectable_error_mask.acs_violation_mask);
1223 	add_int(fields_ir, "uncorrectable_internal_error_mask",
1224 		aer_decode->uncorrectable_error_mask
1225 			.uncorrectable_internal_error_mask);
1226 	add_int(fields_ir, "mc_blocked_tlp_mask",
1227 		aer_decode->uncorrectable_error_mask.mc_blocked_tlp_mask);
1228 	add_int(fields_ir, "atomicop_egress_blocked_mask",
1229 		aer_decode->uncorrectable_error_mask
1230 			.atomicop_egress_blocked_mask);
1231 	add_int(fields_ir, "tlp_prefix_blocked_error_mask",
1232 		aer_decode->uncorrectable_error_mask
1233 			.tlp_prefix_blocked_error_mask);
1234 	add_int(fields_ir, "poisoned_tlp_egress_blocked_mask",
1235 		aer_decode->uncorrectable_error_mask
1236 			.poisoned_tlp_egress_blocked_mask);
1237 	add_int(fields_ir, "dmwr_request_egress_blocked_mask",
1238 		aer_decode->uncorrectable_error_mask
1239 			.dmwr_request_egress_blocked_mask);
1240 	add_int(fields_ir, "ide_check_failed_mask",
1241 		aer_decode->uncorrectable_error_mask.ide_check_failed_mask);
1242 	add_int(fields_ir, "misrouted_ide_tlp_mask",
1243 		aer_decode->uncorrectable_error_mask.misrouted_ide_tlp_mask);
1244 	add_int(fields_ir, "pcrc_check_failed_mask",
1245 		aer_decode->uncorrectable_error_mask.pcrc_check_failed_mask);
1246 	add_int(fields_ir, "tlp_translation_egress_blocked_mask",
1247 		aer_decode->uncorrectable_error_mask
1248 			.tlp_translation_egress_blocked_mask);
1249 	json_object_object_add(aer_capability_ir, "uncorrectable_error_mask",
1250 			       fields_ir);
1251 
1252 	/*
1253 	 * Uncorrectable Error Severity Register
1254 	 * Offset: 0xC
1255 	 */
1256 	fields_ir = json_object_new_object();
1257 	//add_bool(fields_ir, "undefined",
1258 	//	 aer_decode->uncorrectable_error_severity.undefined);
1259 	//add_int(fields_ir, "rsvdz1",
1260 	//	aer_decode->uncorrectable_error_severity.rsvdz1);
1261 	add_bool_enum(fields_ir, "data_link_protocol_error_severity",
1262 		      severity_dict,
1263 		      aer_decode->uncorrectable_error_severity
1264 			      .data_link_protocol_error_severity);
1265 	add_bool_enum(fields_ir, "surprise_down_error_severity", severity_dict,
1266 		      aer_decode->uncorrectable_error_severity
1267 			      .surprise_down_error_severity);
1268 	//add_int(fields_ir, "rsvdz2",
1269 	//	aer_decode->uncorrectable_error_severity.rsvdz2);
1270 	add_bool_enum(fields_ir, "poisoned_tlp_received_severity",
1271 		      severity_dict,
1272 		      aer_decode->uncorrectable_error_severity
1273 			      .poisoned_tlp_received_severity);
1274 	add_bool_enum(fields_ir, "flow_control_protocol_error_severity",
1275 		      severity_dict,
1276 		      aer_decode->uncorrectable_error_severity
1277 			      .flow_control_protocol_error_severity);
1278 	add_bool_enum(fields_ir, "completion_timeout_severity", severity_dict,
1279 		      aer_decode->uncorrectable_error_severity
1280 			      .completion_timeout_severity);
1281 	add_bool_enum(fields_ir, "completer_abort_severity", severity_dict,
1282 		      aer_decode->uncorrectable_error_severity
1283 			      .completer_abort_severity);
1284 	add_bool_enum(fields_ir, "unexpected_completion_severity",
1285 		      severity_dict,
1286 		      aer_decode->uncorrectable_error_severity
1287 			      .unexpected_completion_severity);
1288 	add_bool_enum(fields_ir, "receiver_overflow_severity", severity_dict,
1289 		      aer_decode->uncorrectable_error_severity
1290 			      .receiver_overflow_severity);
1291 	add_bool_enum(
1292 		fields_ir, "malformed_tlp_severity", severity_dict,
1293 		aer_decode->uncorrectable_error_severity.malformed_tlp_severity);
1294 	add_bool_enum(
1295 		fields_ir, "ecrc_error_severity", severity_dict,
1296 		aer_decode->uncorrectable_error_severity.ecrc_error_severity);
1297 	add_bool_enum(fields_ir, "unsupported_request_error_severity",
1298 		      severity_dict,
1299 		      aer_decode->uncorrectable_error_severity
1300 			      .unsupported_request_error_severity);
1301 	add_bool_enum(
1302 		fields_ir, "acs_violation_severity", severity_dict,
1303 		aer_decode->uncorrectable_error_severity.acs_violation_severity);
1304 	add_bool_enum(fields_ir, "uncorrectable_internal_error_severity",
1305 		      severity_dict,
1306 		      aer_decode->uncorrectable_error_severity
1307 			      .uncorrectable_internal_error_severity);
1308 	add_bool_enum(fields_ir, "mc_blocked_tlp_severity", severity_dict,
1309 		      aer_decode->uncorrectable_error_severity
1310 			      .mc_blocked_tlp_severity);
1311 	add_bool_enum(fields_ir, "atomicop_egress_blocked_severity",
1312 		      severity_dict,
1313 		      aer_decode->uncorrectable_error_severity
1314 			      .atomicop_egress_blocked_severity);
1315 	add_bool_enum(fields_ir, "tlp_prefix_blocked_error_severity",
1316 		      severity_dict,
1317 		      aer_decode->uncorrectable_error_severity
1318 			      .tlp_prefix_blocked_error_severity);
1319 	add_bool_enum(fields_ir, "poisoned_tlp_egress_blocked_severity",
1320 		      severity_dict,
1321 		      aer_decode->uncorrectable_error_severity
1322 			      .poisoned_tlp_egress_blocked_severity);
1323 	add_bool_enum(fields_ir, "dmwr_request_egress_blocked_severity",
1324 		      severity_dict,
1325 		      aer_decode->uncorrectable_error_severity
1326 			      .dmwr_request_egress_blocked_severity);
1327 	add_bool_enum(fields_ir, "ide_check_failed_severity", severity_dict,
1328 		      aer_decode->uncorrectable_error_severity
1329 			      .ide_check_failed_severity);
1330 	add_bool_enum(fields_ir, "misrouted_ide_tlp_severity", severity_dict,
1331 		      aer_decode->uncorrectable_error_severity
1332 			      .misrouted_ide_tlp_severity);
1333 	add_bool_enum(fields_ir, "pcrc_check_failed_severity", severity_dict,
1334 		      aer_decode->uncorrectable_error_severity
1335 			      .pcrc_check_failed_severity);
1336 	add_bool_enum(fields_ir, "tlp_translation_egress_blocked_severity",
1337 		      severity_dict,
1338 		      aer_decode->uncorrectable_error_severity
1339 			      .tlp_translation_egress_blocked_severity);
1340 	json_object_object_add(aer_capability_ir,
1341 			       "uncorrectable_error_severity", fields_ir);
1342 
1343 	/*
1344 	 * Correctable Error Status Register
1345 	 * Offset: 0x10
1346 	 */
1347 	fields_ir = json_object_new_object();
1348 	add_bool(fields_ir, "receiver_error_status",
1349 		 aer_decode->correctable_error_status.receiver_error_status);
1350 	//add_int(fields_ir, "rsvdz1",
1351 	//	aer_decode->correctable_error_status.rsvdz1);
1352 	add_bool(fields_ir, "bad_tlp_status",
1353 		 aer_decode->correctable_error_status.bad_tlp_status);
1354 	add_bool(fields_ir, "bad_dllp_status",
1355 		 aer_decode->correctable_error_status.bad_dllp_status);
1356 	add_bool(
1357 		fields_ir, "replay_num_rollover_status",
1358 		aer_decode->correctable_error_status.replay_num_rollover_status);
1359 	//add_int(fields_ir, "rsvdz2",
1360 	//	aer_decode->correctable_error_status.rsvdz2);
1361 	add_bool(fields_ir, "replay_timer_timeout_status",
1362 		 aer_decode->correctable_error_status
1363 			 .replay_timer_timeout_status);
1364 	add_bool(fields_ir, "advisory_non_fatal_error_status",
1365 		 aer_decode->correctable_error_status
1366 			 .advisory_non_fatal_error_status);
1367 	add_bool(fields_ir, "corrected_internal_error_status",
1368 		 aer_decode->correctable_error_status
1369 			 .corrected_internal_error_status);
1370 	add_bool(
1371 		fields_ir, "header_log_overflow_status",
1372 		aer_decode->correctable_error_status.header_log_overflow_status);
1373 	//add_int(fields_ir, "rsvdz3",
1374 	//	aer_decode->correctable_error_status.rsvdz3);
1375 	json_object_object_add(aer_capability_ir, "correctable_error_status",
1376 			       fields_ir);
1377 
1378 	/*
1379 	 * Correctable Error Mask Register
1380 	 * Offset: 0x14
1381 	 */
1382 	fields_ir = json_object_new_object();
1383 	add_int(fields_ir, "receiver_error_mask",
1384 		aer_decode->correctable_error_mask.receiver_error_mask);
1385 	//add_int(fields_ir, "rsvdz1", aer_decode->correctable_error_mask.rsvdz1);
1386 	add_int(fields_ir, "bad_tlp_mask",
1387 		aer_decode->correctable_error_mask.bad_tlp_mask);
1388 	add_int(fields_ir, "bad_dllp_mask",
1389 		aer_decode->correctable_error_mask.bad_dllp_mask);
1390 	add_int(fields_ir, "replay_num_rollover_mask",
1391 		aer_decode->correctable_error_mask.replay_num_rollover_mask);
1392 	//add_int(fields_ir, "rsvdz2", aer_decode->correctable_error_mask.rsvdz2);
1393 	add_int(fields_ir, "replay_timer_timeout_mask",
1394 		aer_decode->correctable_error_mask.replay_timer_timeout_mask);
1395 	add_int(fields_ir, "advisory_non_fatal_error_mask",
1396 		aer_decode->correctable_error_mask
1397 			.advisory_non_fatal_error_mask);
1398 	add_int(fields_ir, "corrected_internal_error_mask",
1399 		aer_decode->correctable_error_mask
1400 			.corrected_internal_error_mask);
1401 	add_int(fields_ir, "header_log_overflow_mask",
1402 		aer_decode->correctable_error_mask.header_log_overflow_mask);
1403 	//add_int(fields_ir, "rsvdz3", aer_decode->correctable_error_mask.rsvdz3);
1404 	json_object_object_add(aer_capability_ir, "correctable_error_mask",
1405 			       fields_ir);
1406 
1407 	/*
1408 	 * Advanced Error Capabilities and Control Register
1409 	 * Offset: 0x18
1410 	 */
1411 	fields_ir = json_object_new_object();
1412 	add_int(fields_ir, "first_error_pointer",
1413 		aer_decode->advanced_error_capabilities_and_control
1414 			.first_error_pointer);
1415 	//add_bool(fields_ir, "ecrc_generation_capable",
1416 	//	 aer_decode->advanced_error_capabilities_and_control
1417 	//		 .ecrc_generation_capable);
1418 	//add_bool(fields_ir, "ecrc_generation_enable",
1419 	//	 aer_decode->advanced_error_capabilities_and_control
1420 	//		 .ecrc_generation_enable);
1421 	//add_bool(fields_ir, "ecrc_check_capable",
1422 	//	 aer_decode->advanced_error_capabilities_and_control
1423 	//		 .ecrc_check_capable);
1424 	//add_bool(fields_ir, "ecrc_check_enable",
1425 	//	 aer_decode->advanced_error_capabilities_and_control
1426 	//		 .ecrc_check_enable);
1427 	//add_bool(fields_ir, "multiple_header_recording_capable",
1428 	//	 aer_decode->advanced_error_capabilities_and_control
1429 	//		 .multiple_header_recording_capable);
1430 	//add_bool(fields_ir, "multiple_header_recording_enable",
1431 	//	 aer_decode->advanced_error_capabilities_and_control
1432 	//		 .multiple_header_recording_enable);
1433 	//add_bool(fields_ir, "tlp_prefix_log_present",
1434 	//	 aer_decode->advanced_error_capabilities_and_control
1435 	//		 .tlp_prefix_log_present);
1436 	//add_bool(fields_ir, "completion_timeout_prefix_header_log_capable",
1437 	//	 aer_decode->advanced_error_capabilities_and_control
1438 	//		 .completion_timeout_prefix_header_log_capable);
1439 	add_int(fields_ir, "header_log_size",
1440 		aer_decode->advanced_error_capabilities_and_control
1441 			.header_log_size);
1442 	//add_bool(fields_ir, "logged_tlp_was_flit_mode",
1443 	//	 aer_decode->advanced_error_capabilities_and_control
1444 	//		 .logged_tlp_was_flit_mode);
1445 	add_int(fields_ir, "logged_tlp_size",
1446 		aer_decode->advanced_error_capabilities_and_control
1447 			.logged_tlp_size);
1448 	//add_int(fields_ir, "rsvdp",
1449 	//	aer_decode->advanced_error_capabilities_and_control.rsvdp);
1450 	json_object_object_add(aer_capability_ir,
1451 			       "advanced_error_capabilities_and_control",
1452 			       fields_ir);
1453 
1454 	/*
1455 	 * Root Error Command Register
1456 	 * Offset: 0x2C
1457 	 */
1458 	//fields_ir = json_object_new_object();
1459 	//add_bool(fields_ir, "correctable_error_reporting_enable",
1460 	//	 aer_decode->root_error_command
1461 	//		 .correctable_error_reporting_enable);
1462 	//add_bool(
1463 	//	fields_ir, "non_fatal_error_reporting_enable",
1464 	//	aer_decode->root_error_command.non_fatal_error_reporting_enable);
1465 	//add_bool(fields_ir, "fatal_error_reporting_enable",
1466 	//	 aer_decode->root_error_command.fatal_error_reporting_enable);
1467 	//add_int(fields_ir, "rsvdp", aer_decode->root_error_command.rsvdp);
1468 	///json_object_object_add(aer_capability_ir, "root_error_command",
1469 	//		       fields_ir);
1470 
1471 	/*
1472 	 * Root Error Status Register
1473 	 * Offset: 0x30
1474 	 */
1475 	fields_ir = json_object_new_object();
1476 	//add_bool(fields_ir, "err_cor_received",
1477 	//	 aer_decode->root_error_status.err_cor_received);
1478 	//add_bool(fields_ir, "multiple_err_cor_received",
1479 	//	 aer_decode->root_error_status.multiple_err_cor_received);
1480 	//add_bool(fields_ir, "err_fatal_nonfatal_received",
1481 	//	 aer_decode->root_error_status.err_fatal_nonfatal_received);
1482 	//add_bool(fields_ir, "multiple_err_fatal_nonfatal_received",
1483 	//	 aer_decode->root_error_status
1484 	//		 .multiple_err_fatal_nonfatal_received);
1485 	//add_bool(fields_ir, "first_uncorrectable_fatal",
1486 	//	 aer_decode->root_error_status.first_uncorrectable_fatal);
1487 	//add_bool(
1488 	//	fields_ir, "non_fatal_error_messages_received",
1489 	//	aer_decode->root_error_status.non_fatal_error_messages_received);
1490 	//add_bool(fields_ir, "fatal_error_messages_received",
1491 	//	 aer_decode->root_error_status.fatal_error_messages_received);
1492 	add_int(fields_ir, "err_cor_subclass",
1493 		aer_decode->root_error_status.err_cor_subclass);
1494 	//add_int(fields_ir, "rsvdz", aer_decode->root_error_status.rsvdz);
1495 	add_int(fields_ir, "advanced_error_interrupt_message_number",
1496 		aer_decode->root_error_status
1497 			.advanced_error_interrupt_message_number);
1498 	json_object_object_add(aer_capability_ir, "root_error_status",
1499 			       fields_ir);
1500 
1501 	/*
1502 	 * Error Source Identification Register
1503 	 * Offset: 0x34
1504 	 */
1505 	fields_ir = json_object_new_object();
1506 	add_int(fields_ir, "err_cor_source_identification",
1507 		aer_decode->error_source_id.err_cor_source_identification);
1508 	add_int(fields_ir, "err_fatal_nonfatal_source_identification",
1509 		aer_decode->error_source_id
1510 			.err_fatal_nonfatal_source_identification);
1511 	json_object_object_add(aer_capability_ir, "error_source_id", fields_ir);
1512 
1513 	return aer_capability_ir;
1514 }
1515 
1516 //Converts a single CPER-JSON PCIe section into CPER binary, outputting to the given stream.
ir_section_pcie_to_cper(json_object * section,FILE * out)1517 void ir_section_pcie_to_cper(json_object *section, FILE *out)
1518 {
1519 	EFI_PCIE_ERROR_DATA *section_cper =
1520 		(EFI_PCIE_ERROR_DATA *)calloc(1, sizeof(EFI_PCIE_ERROR_DATA));
1521 
1522 	//Validation bits.
1523 	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
1524 	struct json_object *obj = NULL;
1525 
1526 	//Version.
1527 	if (json_object_object_get_ex(section, "version", &obj)) {
1528 		const json_object *version = obj;
1529 		UINT32 minor = int_to_bcd(json_object_get_int(
1530 			json_object_object_get(version, "minor")));
1531 		UINT32 major = int_to_bcd(json_object_get_int(
1532 			json_object_object_get(version, "major")));
1533 		section_cper->Version = minor + (major << 8);
1534 		add_to_valid_bitfield(&ui64Type, 1);
1535 	}
1536 
1537 	//Command/status registers.
1538 	if (json_object_object_get_ex(section, "commandStatus", &obj)) {
1539 		const json_object *command_status = obj;
1540 		UINT32 command = (UINT16)json_object_get_uint64(
1541 			json_object_object_get(command_status,
1542 					       "commandRegister"));
1543 		UINT32 status = (UINT16)json_object_get_uint64(
1544 			json_object_object_get(command_status,
1545 					       "statusRegister"));
1546 		section_cper->CommandStatus = command + (status << 16);
1547 		add_to_valid_bitfield(&ui64Type, 2);
1548 	}
1549 
1550 	//Device ID.
1551 	if (json_object_object_get_ex(section, "deviceID", &obj)) {
1552 		const json_object *device_id = obj;
1553 		UINT64 class_id = json_object_get_uint64(
1554 			json_object_object_get(device_id, "classCode"));
1555 		section_cper->DevBridge.VendorId =
1556 			(UINT16)json_object_get_uint64(
1557 				json_object_object_get(device_id, "vendorID"));
1558 		section_cper->DevBridge.DeviceId =
1559 			(UINT16)json_object_get_uint64(
1560 				json_object_object_get(device_id, "deviceID"));
1561 		section_cper->DevBridge.ClassCode[2] = class_id >> 16;
1562 		section_cper->DevBridge.ClassCode[1] = (class_id >> 8) & 0xFF;
1563 		section_cper->DevBridge.ClassCode[0] = class_id & 0xFF;
1564 		section_cper->DevBridge.Function =
1565 			(UINT8)json_object_get_uint64(json_object_object_get(
1566 				device_id, "functionNumber"));
1567 		section_cper->DevBridge.Device = (UINT8)json_object_get_uint64(
1568 			json_object_object_get(device_id, "deviceNumber"));
1569 		section_cper->DevBridge.Segment =
1570 			(UINT16)json_object_get_uint64(json_object_object_get(
1571 				device_id, "segmentNumber"));
1572 		section_cper->DevBridge.PrimaryOrDeviceBus =
1573 			(UINT8)json_object_get_uint64(json_object_object_get(
1574 				device_id, "primaryOrDeviceBusNumber"));
1575 		section_cper->DevBridge.SecondaryBus =
1576 			(UINT8)json_object_get_uint64(json_object_object_get(
1577 				device_id, "secondaryBusNumber"));
1578 		section_cper->DevBridge.Slot.Number =
1579 			(UINT16)json_object_get_uint64(json_object_object_get(
1580 				device_id, "slotNumber"));
1581 		add_to_valid_bitfield(&ui64Type, 3);
1582 	}
1583 
1584 	//Bridge/control status.
1585 	if (json_object_object_get_ex(section, "bridgeControlStatus", &obj)) {
1586 		const json_object *bridge_control = obj;
1587 		UINT32 bridge_status = (UINT16)json_object_get_uint64(
1588 			json_object_object_get(bridge_control,
1589 					       "secondaryStatusRegister"));
1590 		UINT32 control_status = (UINT16)json_object_get_uint64(
1591 			json_object_object_get(bridge_control,
1592 					       "controlRegister"));
1593 		section_cper->BridgeControlStatus =
1594 			bridge_status + (control_status << 16);
1595 		add_to_valid_bitfield(&ui64Type, 5);
1596 	}
1597 
1598 	//Capability structure.
1599 	int32_t decoded_len = 0;
1600 	UINT8 *decoded = NULL;
1601 	json_object *encoded = NULL;
1602 	if (json_object_object_get_ex(section, "capabilityStructure", &obj)) {
1603 		const json_object *capability = obj;
1604 		encoded = json_object_object_get(capability, "data");
1605 
1606 		decoded = base64_decode(json_object_get_string(encoded),
1607 					json_object_get_string_len(encoded),
1608 					&decoded_len);
1609 		if (decoded == NULL) {
1610 			cper_print_log(
1611 				"Failed to allocate decode output buffer. \n");
1612 		} else {
1613 			memcpy(section_cper->Capability.PcieCap, decoded,
1614 			       decoded_len);
1615 			free(decoded);
1616 		}
1617 		add_to_valid_bitfield(&ui64Type, 6);
1618 	}
1619 
1620 	decoded = NULL;
1621 	encoded = NULL;
1622 	//AER capability structure.
1623 	if (json_object_object_get_ex(section, "aerInfo", &obj)) {
1624 		const json_object *aer_info = obj;
1625 		encoded = json_object_object_get(aer_info, "data");
1626 		decoded_len = 0;
1627 
1628 		decoded = base64_decode(json_object_get_string(encoded),
1629 					json_object_get_string_len(encoded),
1630 					&decoded_len);
1631 
1632 		if (decoded == NULL) {
1633 			cper_print_log(
1634 				"Failed to allocate decode output buffer. \n");
1635 		} else {
1636 			memcpy(section_cper->AerInfo.PcieAer, decoded,
1637 			       decoded_len);
1638 			free(decoded);
1639 		}
1640 		add_to_valid_bitfield(&ui64Type, 7);
1641 	}
1642 
1643 	//Miscellaneous value fields.
1644 	if (json_object_object_get_ex(section, "portType", &obj)) {
1645 		section_cper->PortType = (UINT32)readable_pair_to_integer(obj);
1646 		add_to_valid_bitfield(&ui64Type, 0);
1647 	}
1648 	if (json_object_object_get_ex(section, "deviceSerialNumber", &obj)) {
1649 		section_cper->SerialNo = json_object_get_uint64(obj);
1650 		add_to_valid_bitfield(&ui64Type, 4);
1651 	}
1652 
1653 	section_cper->ValidFields = ui64Type.value.ui64;
1654 
1655 	//Write out to stream, free resources.
1656 	fwrite(section_cper, sizeof(EFI_PCIE_ERROR_DATA), 1, out);
1657 	fflush(out);
1658 	free(section_cper);
1659 }
1660