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