blob: ee00a022f0799f850762ba2278f3d431173af3e1 [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>
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -070015#include <string.h>
Lawrence Tang4dbe3d72022-07-06 13:51:01 +010016
Erwin Tsaur8870c072025-02-28 12:57:12 -080017json_object *pcie_capability_to_ir(EFI_PCIE_ERROR_DATA *pcie_error);
18json_object *pcie_aer_to_ir(EFI_PCIE_ERROR_DATA *pcie_error);
Andrew Adriance3cebfc22024-11-20 12:57:04 -080019
Ed Tanous9f260e52025-04-24 09:37:59 -070020#define ANYP 0xFF
21
22struct 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
281const 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
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100296//Converts a single PCIe CPER section into JSON IR.
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -0700297json_object *cper_section_pcie_to_ir(const UINT8 *section, UINT32 size,
298 char **desc_string)
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100299{
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -0700300 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
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800311 if (size < sizeof(EFI_PCIE_ERROR_DATA)) {
312 return NULL;
313 }
314
Lawrence Tange407b4c2022-07-21 13:54:01 +0100315 EFI_PCIE_ERROR_DATA *pcie_error = (EFI_PCIE_ERROR_DATA *)section;
316 json_object *section_ir = json_object_new_object();
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100317
Lawrence Tange407b4c2022-07-21 13:54:01 +0100318 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800319 ValidationTypes ui64Type = { UINT_64T,
320 .value.ui64 = pcie_error->ValidFields };
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100321
Lawrence Tange407b4c2022-07-21 13:54:01 +0100322 //Port type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800323 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 }
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100329
Lawrence Tange407b4c2022-07-21 13:54:01 +0100330 //Version, provided each half in BCD.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800331 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 }
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100341
Lawrence Tange407b4c2022-07-21 13:54:01 +0100342 //Command & status.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800343 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 }
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100356
Lawrence Tange407b4c2022-07-21 13:54:01 +0100357 //PCIe Device ID.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800358 if (isvalid_prop_to_ir(&ui64Type, 3)) {
359 json_object *device_id = json_object_new_object();
Ed Tanous9f260e52025-04-24 09:37:59 -0700360
361 UINT64 class_id = (pcie_error->DevBridge.ClassCode[2] << 16) +
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800362 (pcie_error->DevBridge.ClassCode[1] << 8) +
Ed Tanous9f260e52025-04-24 09:37:59 -0700363 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);
Aushim Nagarkatticc367012024-12-05 18:17:27 -0800391
Ed Tanous9f260e52025-04-24 09:37:59 -0700392 add_int(device_id, "vendorID", pcie_error->DevBridge.VendorId);
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800393
Ed Tanous9f260e52025-04-24 09:37:59 -0700394 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
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800414 json_object_object_add(section_ir, "deviceID", device_id);
415 }
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100416
Lawrence Tange407b4c2022-07-21 13:54:01 +0100417 //Device serial number.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800418 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 }
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100423
Lawrence Tange407b4c2022-07-21 13:54:01 +0100424 //Bridge control status.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800425 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 }
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100438
Lawrence Tange407b4c2022-07-21 13:54:01 +0100439 //Capability structure.
440 //The PCIe capability structure provided here could either be PCIe 1.1 Capability Structure
Erwin Tsaur8870c072025-02-28 12:57:12 -0800441 //(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.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800443 if (isvalid_prop_to_ir(&ui64Type, 6)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -0800444 json_object_object_add(section_ir, "capabilityStructure",
445 pcie_capability_to_ir(pcie_error));
John Chungf8fc7052024-05-03 20:05:29 +0800446 }
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100447
Lawrence Tange407b4c2022-07-21 13:54:01 +0100448 //AER information.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800449 if (isvalid_prop_to_ir(&ui64Type, 7)) {
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800450 json_object_object_add(section_ir, "aerInfo",
Erwin Tsaur8870c072025-02-28 12:57:12 -0800451 pcie_aer_to_ir(pcie_error));
John Chungf8fc7052024-05-03 20:05:29 +0800452 }
Andrew Adriance3cebfc22024-11-20 12:57:04 -0800453
Lawrence Tange407b4c2022-07-21 13:54:01 +0100454 return section_ir;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100455}
456
Erwin Tsaur8870c072025-02-28 12:57:12 -0800457//Converts PCIe Capability Structure section into JSON IR.
458json_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 */
Ed Tanousffa7e172025-05-29 16:01:49 -0700803 //fields_ir = json_object_new_object();
Erwin Tsaur8870c072025-02-28 12:57:12 -0800804 //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);
Ed Tanousffa7e172025-05-29 16:01:49 -0700820 //json_object_object_add(pcie_capability_ir, "root_control", fields_ir);
Erwin Tsaur8870c072025-02-28 12:57:12 -0800821
822 /*
823 * Root Capabilities Register
824 * Offset: 0x1E
825 */
Ed Tanousffa7e172025-05-29 16:01:49 -0700826 //fields_ir = json_object_new_object();
Erwin Tsaur8870c072025-02-28 12:57:12 -0800827 //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);
Ed Tanousffa7e172025-05-29 16:01:49 -0700831 //json_object_object_add(pcie_capability_ir, "root_capabilities",
832 // fields_ir);
Erwin Tsaur8870c072025-02-28 12:57:12 -0800833
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);
Aushim Nagarkattieda19ff2025-06-10 12:34:48 -0700944 add_bool(fields_ir, "bit_tag_requester_10_enable",
945 cap_decode->device_control2.bit_tag_requester_10_enable);
Erwin Tsaur8870c072025-02-28 12:57:12 -0800946 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 */
Ed Tanousffa7e172025-05-29 16:01:49 -0700957 //fields_ir = json_object_new_object();
Erwin Tsaur8870c072025-02-28 12:57:12 -0800958 //add_int(fields_ir, "rsvdz", cap_decode->device_status2.rsvdz);
Ed Tanousffa7e172025-05-29 16:01:49 -0700959 //json_object_object_add(pcie_capability_ir, "device_status2", fields_ir);
Erwin Tsaur8870c072025-02-28 12:57:12 -0800960
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 */
Ed Tanousffa7e172025-05-29 16:01:49 -07001050 //fields_ir = json_object_new_object();
Erwin Tsaur8870c072025-02-28 12:57:12 -08001051 //add_int(fields_ir, "rsvdp", cap_decode->slot_capabilities2.rsvdp);
Ed Tanousffa7e172025-05-29 16:01:49 -07001052 //json_object_object_add(pcie_capability_ir, "slot_capabilities2",
1053 // fields_ir);
Erwin Tsaur8870c072025-02-28 12:57:12 -08001054
1055 /*
1056 * Slot Control 2 Register
1057 * Offset: 0x38
1058 */
Ed Tanousffa7e172025-05-29 16:01:49 -07001059 //fields_ir = json_object_new_object();
Erwin Tsaur8870c072025-02-28 12:57:12 -08001060 //add_int(fields_ir, "rsvdp", cap_decode->slot_control2.rsvdp);
Ed Tanousffa7e172025-05-29 16:01:49 -07001061 //json_object_object_add(pcie_capability_ir, "slot_control2", fields_ir);
Erwin Tsaur8870c072025-02-28 12:57:12 -08001062
1063 /*
1064 * Slot Status 2 Register
1065 * Offset: 0x3A
1066 */
Ed Tanousffa7e172025-05-29 16:01:49 -07001067 //fields_ir = json_object_new_object();
Erwin Tsaur8870c072025-02-28 12:57:12 -08001068 //add_int(fields_ir, "rsvdp", cap_decode->slot_status2.rsvdp);
Ed Tanousffa7e172025-05-29 16:01:49 -07001069 //json_object_object_add(pcie_capability_ir, "slot_status2", fields_ir);
Erwin Tsaur8870c072025-02-28 12:57:12 -08001070
1071 return pcie_capability_ir;
1072}
1073
1074//Converts PCIe Capability Structure section into JSON IR.
1075json_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 */
Ed Tanousffa7e172025-05-29 16:01:49 -07001458 //fields_ir = json_object_new_object();
Erwin Tsaur8870c072025-02-28 12:57:12 -08001459 //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);
Ed Tanousffa7e172025-05-29 16:01:49 -07001468 ///json_object_object_add(aer_capability_ir, "root_error_command",
1469 // fields_ir);
Erwin Tsaur8870c072025-02-28 12:57:12 -08001470
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
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001516//Converts a single CPER-JSON PCIe section into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001517void ir_section_pcie_to_cper(json_object *section, FILE *out)
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001518{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001519 EFI_PCIE_ERROR_DATA *section_cper =
1520 (EFI_PCIE_ERROR_DATA *)calloc(1, sizeof(EFI_PCIE_ERROR_DATA));
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001521
Lawrence Tange407b4c2022-07-21 13:54:01 +01001522 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001523 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
1524 struct json_object *obj = NULL;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001525
Lawrence Tange407b4c2022-07-21 13:54:01 +01001526 //Version.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001527 if (json_object_object_get_ex(section, "version", &obj)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -08001528 const json_object *version = obj;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001529 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);
John Chungf8fc7052024-05-03 20:05:29 +08001535 }
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001536
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001537 //Command/status registers.
1538 if (json_object_object_get_ex(section, "commandStatus", &obj)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -08001539 const json_object *command_status = obj;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001540 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)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -08001552 const json_object *device_id = obj;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001553 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"));
Ed Tanous9f260e52025-04-24 09:37:59 -07001561 section_cper->DevBridge.ClassCode[2] = class_id >> 16;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001562 section_cper->DevBridge.ClassCode[1] = (class_id >> 8) & 0xFF;
Ed Tanous9f260e52025-04-24 09:37:59 -07001563 section_cper->DevBridge.ClassCode[0] = class_id & 0xFF;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001564 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)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -08001586 const json_object *bridge_control = obj;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001587 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)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -08001603 const json_object *capability = obj;
1604 encoded = json_object_object_get(capability, "data");
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001605
Erwin Tsaur8870c072025-02-28 12:57:12 -08001606 decoded = base64_decode(json_object_get_string(encoded),
1607 json_object_get_string_len(encoded),
1608 &decoded_len);
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001609 if (decoded == NULL) {
Ed Tanous50b966f2025-03-11 09:06:19 -07001610 cper_print_log(
1611 "Failed to allocate decode output buffer. \n");
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001612 } 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;
Lawrence Tange407b4c2022-07-21 13:54:01 +01001622 //AER capability structure.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001623 if (json_object_object_get_ex(section, "aerInfo", &obj)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -08001624 const json_object *aer_info = obj;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001625 encoded = json_object_object_get(aer_info, "data");
1626 decoded_len = 0;
Ed Tanousa7d2cdd2024-07-15 11:07:27 -07001627
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001628 decoded = base64_decode(json_object_get_string(encoded),
1629 json_object_get_string_len(encoded),
1630 &decoded_len);
Ed Tanousa7d2cdd2024-07-15 11:07:27 -07001631
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001632 if (decoded == NULL) {
Ed Tanous50b966f2025-03-11 09:06:19 -07001633 cper_print_log(
1634 "Failed to allocate decode output buffer. \n");
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001635 } else {
1636 memcpy(section_cper->AerInfo.PcieAer, decoded,
1637 decoded_len);
1638 free(decoded);
1639 }
1640 add_to_valid_bitfield(&ui64Type, 7);
John Chungf8fc7052024-05-03 20:05:29 +08001641 }
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001642
Lawrence Tange407b4c2022-07-21 13:54:01 +01001643 //Miscellaneous value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001644 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;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001654
Lawrence Tange407b4c2022-07-21 13:54:01 +01001655 //Write out to stream, free resources.
1656 fwrite(section_cper, sizeof(EFI_PCIE_ERROR_DATA), 1, out);
1657 fflush(out);
1658 free(section_cper);
John Chungf8fc7052024-05-03 20:05:29 +08001659}