blob: 1dd14480a9f9044d48cd3f5b75659a689cda6ddb [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;
Aushim Nagarkattif1251422026-01-09 10:12:20 -0800301 *desc_string = NULL;
302 if (size < sizeof(EFI_PCIE_ERROR_DATA)) {
303 cper_print_log("Error: PCIe section too small\n");
304 return NULL;
305 }
306
Aushim Nagarkatti991ebf22025-11-14 15:26:06 -0800307 *desc_string = calloc(1, SECTION_DESC_STRING_SIZE);
Aushim Nagarkattif1251422026-01-09 10:12:20 -0800308 if (*desc_string == NULL) {
309 cper_print_log("Error: Failed to allocate PCIe desc string\n");
310 return NULL;
311 }
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -0700312 outstr_len = snprintf(*desc_string, SECTION_DESC_STRING_SIZE,
313 "A PCIe Error occurred");
314 if (outstr_len < 0) {
315 cper_print_log(
316 "Error: Could not write to PCIe description string\n");
317 } else if (outstr_len > SECTION_DESC_STRING_SIZE) {
318 cper_print_log("Error: PCIe description string truncated\n");
319 }
320
Lawrence Tange407b4c2022-07-21 13:54:01 +0100321 EFI_PCIE_ERROR_DATA *pcie_error = (EFI_PCIE_ERROR_DATA *)section;
322 json_object *section_ir = json_object_new_object();
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100323
Lawrence Tange407b4c2022-07-21 13:54:01 +0100324 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800325 ValidationTypes ui64Type = { UINT_64T,
326 .value.ui64 = pcie_error->ValidFields };
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100327
Lawrence Tange407b4c2022-07-21 13:54:01 +0100328 //Port type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800329 if (isvalid_prop_to_ir(&ui64Type, 0)) {
330 json_object *port_type = integer_to_readable_pair(
331 pcie_error->PortType, 9, PCIE_ERROR_PORT_TYPES_KEYS,
332 PCIE_ERROR_PORT_TYPES_VALUES, "Unknown");
333 json_object_object_add(section_ir, "portType", port_type);
334 }
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100335
Lawrence Tange407b4c2022-07-21 13:54:01 +0100336 //Version, provided each half in BCD.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800337 if (isvalid_prop_to_ir(&ui64Type, 1)) {
338 json_object *version = json_object_new_object();
Ed Tanous6c5d2f32026-02-02 15:18:15 -0800339 add_int(version, "minor",
340 bcd_to_int(pcie_error->Version & 0xFF));
341 add_int(version, "major", bcd_to_int(pcie_error->Version >> 8));
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800342 json_object_object_add(section_ir, "version", version);
343 }
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100344
Lawrence Tange407b4c2022-07-21 13:54:01 +0100345 //Command & status.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800346 if (isvalid_prop_to_ir(&ui64Type, 2)) {
347 json_object *command_status = json_object_new_object();
Ed Tanous6c5d2f32026-02-02 15:18:15 -0800348 add_uint(command_status, "commandRegister",
349 pcie_error->CommandStatus & 0xFFFF);
350 add_uint(command_status, "statusRegister",
351 pcie_error->CommandStatus >> 16);
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800352 json_object_object_add(section_ir, "commandStatus",
353 command_status);
354 }
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100355
Lawrence Tange407b4c2022-07-21 13:54:01 +0100356 //PCIe Device ID.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800357 if (isvalid_prop_to_ir(&ui64Type, 3)) {
358 json_object *device_id = json_object_new_object();
Ed Tanous9f260e52025-04-24 09:37:59 -0700359
360 UINT64 class_id = (pcie_error->DevBridge.ClassCode[2] << 16) +
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800361 (pcie_error->DevBridge.ClassCode[1] << 8) +
Ed Tanous9f260e52025-04-24 09:37:59 -0700362 pcie_error->DevBridge.ClassCode[0];
363 const char *class_name =
364 get_class_code_name(pcie_error->DevBridge.ClassCode[2],
365 pcie_error->DevBridge.ClassCode[1],
366 pcie_error->DevBridge.ClassCode[0]);
367 if (class_name != NULL) {
Ed Tanous6c5d2f32026-02-02 15:18:15 -0800368 add_string(device_id, "class", class_name);
Ed Tanous9f260e52025-04-24 09:37:59 -0700369 }
370 add_int_hex_16(device_id, "deviceID_Hex",
371 pcie_error->DevBridge.DeviceId);
372 add_int_hex_16(device_id, "vendorID_Hex",
373 pcie_error->DevBridge.VendorId);
374 add_int_hex_24(device_id, "classCode_Hex", class_id);
375 add_int_hex_8(device_id, "functionNumber_Hex",
376 pcie_error->DevBridge.Function);
377 add_int_hex_8(device_id, "deviceNumber_Hex",
378 pcie_error->DevBridge.Device);
379 add_int_hex_8(device_id, "segmentNumber_Hex",
380 pcie_error->DevBridge.Segment);
381 add_int_hex_8(device_id, "primaryOrDeviceBusNumber_Hex",
382 pcie_error->DevBridge.PrimaryOrDeviceBus);
383 add_int_hex_8(device_id, "secondaryBusNumber_Hex",
384 pcie_error->DevBridge.SecondaryBus);
385 add_int_hex_8(device_id, "slotNumber_Hex",
386 pcie_error->DevBridge.Slot.Number);
387 add_int(device_id, "deviceID", pcie_error->DevBridge.DeviceId);
Aushim Nagarkatticc367012024-12-05 18:17:27 -0800388
Ed Tanous9f260e52025-04-24 09:37:59 -0700389 add_int(device_id, "vendorID", pcie_error->DevBridge.VendorId);
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800390
Ed Tanous9f260e52025-04-24 09:37:59 -0700391 add_int(device_id, "classCode", class_id);
392
393 add_int(device_id, "functionNumber",
394 pcie_error->DevBridge.Function);
395
396 add_int(device_id, "deviceNumber",
397 pcie_error->DevBridge.Device);
398
399 add_int(device_id, "segmentNumber",
400 pcie_error->DevBridge.Segment);
401
402 add_int(device_id, "primaryOrDeviceBusNumber",
403 pcie_error->DevBridge.PrimaryOrDeviceBus);
404
405 add_int(device_id, "secondaryBusNumber",
406 pcie_error->DevBridge.SecondaryBus);
407
408 add_int(device_id, "slotNumber",
409 pcie_error->DevBridge.Slot.Number);
410
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800411 json_object_object_add(section_ir, "deviceID", device_id);
412 }
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100413
Lawrence Tange407b4c2022-07-21 13:54:01 +0100414 //Device serial number.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800415 if (isvalid_prop_to_ir(&ui64Type, 4)) {
Ed Tanous6c5d2f32026-02-02 15:18:15 -0800416 add_uint(section_ir, "deviceSerialNumber",
417 pcie_error->SerialNo);
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800418 }
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100419
Lawrence Tange407b4c2022-07-21 13:54:01 +0100420 //Bridge control status.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800421 if (isvalid_prop_to_ir(&ui64Type, 5)) {
422 json_object *bridge_control_status = json_object_new_object();
Ed Tanous6c5d2f32026-02-02 15:18:15 -0800423 add_uint(bridge_control_status, "secondaryStatusRegister",
424 pcie_error->BridgeControlStatus & 0xFFFF);
425 add_uint(bridge_control_status, "controlRegister",
426 pcie_error->BridgeControlStatus >> 16);
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800427 json_object_object_add(section_ir, "bridgeControlStatus",
428 bridge_control_status);
429 }
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100430
Lawrence Tange407b4c2022-07-21 13:54:01 +0100431 //Capability structure.
432 //The PCIe capability structure provided here could either be PCIe 1.1 Capability Structure
Erwin Tsaur8870c072025-02-28 12:57:12 -0800433 //(36-byte, padded to 60 bytes) or PCIe 2.0 Capability Structure (60-byte).
434 //Check the PCIe Capabilities Registers (offset 0x2) to determine the capability version.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800435 if (isvalid_prop_to_ir(&ui64Type, 6)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -0800436 json_object_object_add(section_ir, "capabilityStructure",
437 pcie_capability_to_ir(pcie_error));
John Chungf8fc7052024-05-03 20:05:29 +0800438 }
Lawrence Tang4dbe3d72022-07-06 13:51:01 +0100439
Lawrence Tange407b4c2022-07-21 13:54:01 +0100440 //AER information.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800441 if (isvalid_prop_to_ir(&ui64Type, 7)) {
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800442 json_object_object_add(section_ir, "aerInfo",
Erwin Tsaur8870c072025-02-28 12:57:12 -0800443 pcie_aer_to_ir(pcie_error));
John Chungf8fc7052024-05-03 20:05:29 +0800444 }
Andrew Adriance3cebfc22024-11-20 12:57:04 -0800445
Lawrence Tange407b4c2022-07-21 13:54:01 +0100446 return section_ir;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100447}
448
Erwin Tsaur8870c072025-02-28 12:57:12 -0800449//Converts PCIe Capability Structure section into JSON IR.
450json_object *pcie_capability_to_ir(EFI_PCIE_ERROR_DATA *pcie_error)
451{
Erwin Tsaur8870c072025-02-28 12:57:12 -0800452 json_object *pcie_capability_ir = json_object_new_object();
453
Ed Tanous3f810e52026-02-04 12:04:10 -0800454 add_binary_base64(pcie_capability_ir, "data",
455 pcie_error->Capability.PcieCap,
456 sizeof(pcie_error->Capability.PcieCap));
Erwin Tsaur8870c072025-02-28 12:57:12 -0800457
458 json_object *fields_ir;
459 capability_registers *cap_decode;
460 cap_decode = (capability_registers *)&pcie_error->Capability.PcieCap;
461
462 /*
463 * PCI Express Capability Structure Header
464 * Offset: 0x0
465 */
466 fields_ir = json_object_new_object();
467 pcie_capability_header_t *pcie_cap_header =
468 &cap_decode->pcie_capability_header;
469 add_dict(fields_ir, "capability_id", pcie_cap_header->capability_id,
470 NULL, 0);
471 add_int(fields_ir, "next_capability_pointer",
472 pcie_cap_header->next_capability_pointer);
473 json_object_object_add(pcie_capability_ir, "pcie_capability_header",
474 fields_ir);
475
476 /*
477 * PCI Express Capabilities Register
478 * Offset: 0x2
479 */
480 fields_ir = json_object_new_object();
481 pcie_capabilities_t *pcie_cap = &cap_decode->pcie_capabilities;
482 add_int(fields_ir, "capability_version", pcie_cap->capability_version);
483 add_dict(fields_ir, "device_port_type", pcie_cap->device_port_type,
484 device_port_type_dict, device_port_type_dict_size);
485 add_bool(fields_ir, "slot_implemented", pcie_cap->slot_implemented);
486 add_int(fields_ir, "interrupt_message_number",
487 pcie_cap->interrupt_message_number);
488 //add_int(fields_ir, "undefined", pcie_cap->undefined);
489 add_bool_enum(fields_ir, "flit_mode_supported", supported_dict,
490 pcie_cap->flit_mode_supported);
491 json_object_object_add(pcie_capability_ir, "pcie_capabilities",
492 fields_ir);
493
494 /*
495 * Device Capabilities Register
496 * Offset: 0x4
497 */
498 fields_ir = json_object_new_object();
499 add_int(fields_ir, "max_payload_size_supported",
500 cap_decode->device_capabilities.max_payload_size_supported);
501 add_bool_enum(
502 fields_ir, "phantom_functions_supported", supported_dict,
503 cap_decode->device_capabilities.phantom_functions_supported);
504 add_bool_enum(
505 fields_ir, "extended_tag_field_supported", supported_dict,
506 cap_decode->device_capabilities.extended_tag_field_supported);
507 add_dict(
508 fields_ir, "endpoint_l0s_acceptable_latency",
509 cap_decode->device_capabilities.endpoint_l0s_acceptable_latency,
510 NULL, 0);
511 add_dict(fields_ir, "endpoint_l1_acceptable_latency",
512 cap_decode->device_capabilities.endpoint_l1_acceptable_latency,
513 NULL, 0);
514 //add_int(fields_ir, "undefined",
515 // cap_decode->device_capabilities.undefined);
516 add_bool(fields_ir, "role_based_error_reporting",
517 cap_decode->device_capabilities.role_based_error_reporting);
518 add_bool(fields_ir, "err_cor_subclass_capable",
519 cap_decode->device_capabilities.err_cor_subclass_capable);
520 add_int(fields_ir, "rx_mps_fixed",
521 cap_decode->device_capabilities.rx_mps_fixed);
522 add_int(fields_ir, "captured_slot_power_limit_value",
523 cap_decode->device_capabilities.captured_slot_power_limit_value);
524 add_int(fields_ir, "captured_slot_power_limit_scale",
525 cap_decode->device_capabilities.captured_slot_power_limit_scale);
526 add_bool_enum(
527 fields_ir, "function_level_reset_capability_supported",
528 supported_dict,
529 cap_decode->device_capabilities.function_level_reset_capability);
530 add_bool_enum(fields_ir, "mixed_mps_supported", supported_dict,
531 cap_decode->device_capabilities.mixed_mps_supported);
532 add_bool_enum(fields_ir, "tee_io_supported", supported_dict,
533 cap_decode->device_capabilities.tee_io_supported);
534 //add_int(fields_ir, "rsvdp", cap_decode->device_capabilities.rsvdp);
535 json_object_object_add(pcie_capability_ir, "device_capabilities",
536 fields_ir);
537
538 /*
539 * Device Control Register
540 * Offset: 0x8
541 */
542 fields_ir = json_object_new_object();
543 add_bool_enum(
544 fields_ir, "correctable_error_reporting_enable", enabled_dict,
545 cap_decode->device_control.correctable_error_reporting_enable);
546 add_bool_enum(
547 fields_ir, "non_fatal_error_reporting_enable", enabled_dict,
548 cap_decode->device_control.non_fatal_error_reporting_enable);
549 add_bool_enum(fields_ir, "fatal_error_reporting_enable", enabled_dict,
550 cap_decode->device_control.fatal_error_reporting_enable);
551 add_bool_enum(
552 fields_ir, "unsupported_request_reporting_enabled",
553 enabled_dict,
554 cap_decode->device_control.unsupported_request_reporting_enable);
555 add_bool_enum(fields_ir, "relaxed_ordering_enable", enabled_dict,
556 cap_decode->device_control.enable_relaxed_ordering);
557 add_int(fields_ir, "max_payload_size",
558 cap_decode->device_control.max_payload_size);
559 add_bool_enum(fields_ir, "extended_tag_field_enable", enabled_dict,
560 cap_decode->device_control.extended_tag_field_enable);
561 add_bool_enum(fields_ir, "phantom_functions_enable", enabled_dict,
562 cap_decode->device_control.phantom_functions_enable);
563 add_bool_enum(fields_ir, "aux_power_pm_enable", enabled_dict,
564 cap_decode->device_control.aux_power_pm_enable);
565 add_int(fields_ir, "enable_no_snoop",
566 cap_decode->device_control.enable_no_snoop);
567 add_int(fields_ir, "max_read_request_size",
568 cap_decode->device_control.max_read_request_size);
569 add_bool(fields_ir, "function_level_reset",
570 cap_decode->device_control.function_level_reset);
571 json_object_object_add(pcie_capability_ir, "device_control", fields_ir);
572
573 /*
574 * Device Status Register
575 * Offset: 0xA
576 */
577 fields_ir = json_object_new_object();
578 add_bool(fields_ir, "correctable_error_detected",
579 cap_decode->device_status.correctable_error_detected);
580 add_bool(fields_ir, "non_fatal_error_detected",
581 cap_decode->device_status.non_fatal_error_detected);
582 add_bool(fields_ir, "fatal_error_detected",
583 cap_decode->device_status.fatal_error_detected);
584 add_bool(fields_ir, "unsupported_request_detected",
585 cap_decode->device_status.unsupported_request_detected);
586 add_bool(fields_ir, "aux_power_detected",
587 cap_decode->device_status.aux_power_detected);
588 add_bool(fields_ir, "transactions_pending",
589 cap_decode->device_status.transactions_pending);
590 add_int(fields_ir, "emergency_power_reduction",
591 cap_decode->device_status.emergency_power_reduction);
592 //add_int(fields_ir, "rsvdz", cap_decode->device_status.rsvdz);
593 json_object_object_add(pcie_capability_ir, "device_status", fields_ir);
594
595 /*
596 * Link Capabilities Register
597 * Offset: 0xC
598 */
599 fields_ir = json_object_new_object();
600 add_int(fields_ir, "max_link_speed",
601 cap_decode->link_capabilities.max_link_speed);
602 add_int(fields_ir, "maximum_link_width",
603 cap_decode->link_capabilities.maximum_link_width);
604 add_int(fields_ir, "aspm_support",
605 cap_decode->link_capabilities.aspm_support);
606 add_int(fields_ir, "l0s_exit_latency",
607 cap_decode->link_capabilities.l0s_exit_latency);
608 add_int(fields_ir, "l1_exit_latency",
609 cap_decode->link_capabilities.l1_exit_latency);
610 add_bool(fields_ir, "clock_power_management",
611 cap_decode->link_capabilities.clock_power_management);
612 add_bool(fields_ir, "surprise_down_error_reporting_capable",
613 cap_decode->link_capabilities
614 .surprise_down_error_reporting_capable);
615 add_bool(fields_ir, "data_link_layer_link_active_reporting_capable",
616 cap_decode->link_capabilities
617 .data_link_layer_link_active_reporting_capable);
618 add_bool(fields_ir, "link_bandwidth_notification_capability",
619 cap_decode->link_capabilities
620 .link_bandwidth_notification_capability);
621 add_bool(fields_ir, "aspm_optionality_compliance",
622 cap_decode->link_capabilities.aspm_optionality_compliance);
623 //add_int(fields_ir, "rsvdp", cap_decode->link_capabilities.rsvdp);
624 add_int(fields_ir, "port_number",
625 cap_decode->link_capabilities.port_number);
626 json_object_object_add(pcie_capability_ir, "link_capabilities",
627 fields_ir);
628
629 /*
630 * Link Control Register
631 * Offset: 0x10
632 */
633 fields_ir = json_object_new_object();
634 add_int(fields_ir, "aspm_control",
635 cap_decode->link_control.aspm_control);
636 add_bool(fields_ir, "ptm_prop_delay_adaptation_interpretation",
637 cap_decode->link_control
638 .ptm_prop_delay_adaptation_interpretation);
639 //add_bool(fields_ir, "read_completion_boundary",
640 // cap_decode->link_control.read_completion_boundary);
641 add_int(fields_ir, "link_disable",
642 cap_decode->link_control.link_disable);
643 add_int(fields_ir, "retrain_link",
644 cap_decode->link_control.retrain_link);
645 //add_bool(fields_ir, "common_clock_configuration",
646 // cap_decode->link_control.common_clock_configuration);
647 add_int(fields_ir, "extended_synch",
648 cap_decode->link_control.extended_synch);
649 //add_bool(fields_ir, "enable_clock_power_management",
650 // cap_decode->link_control.enable_clock_power_management);
651 //add_bool(fields_ir, "hardware_autonomous_width_disable",
652 // cap_decode->link_control.hardware_autonomous_width_disable);
653 //add_bool(fields_ir, "link_bandwidth_management_interrupt_enable",
654 // cap_decode->link_control
655 // .link_bandwidth_management_interrupt_enable);
656 //add_bool(fields_ir, "link_autonomous_bandwidth_interrupt_enable",
657 // cap_decode->link_control
658 // .link_autonomous_bandwidth_interrupt_enable);
659 add_int(fields_ir, "sris_clocking",
660 cap_decode->link_control.sris_clocking);
661 add_int(fields_ir, "flit_mode_disable",
662 cap_decode->link_control.flit_mode_disable);
663 //add_bool(fields_ir, "drs_signaling_control",
664 // cap_decode->link_control.drs_signaling_control);
665 json_object_object_add(pcie_capability_ir, "link_control", fields_ir);
666
667 /*
668 * Link Status Register
669 * Offset: 0x12
670 */
671 fields_ir = json_object_new_object();
672 add_int(fields_ir, "current_link_speed",
673 cap_decode->link_status.current_link_speed);
674 add_int(fields_ir, "negotiated_link_width",
675 cap_decode->link_status.negotiated_link_width);
676 //add_int(fields_ir, "undefined", cap_decode->link_status.undefined);
677 add_int(fields_ir, "link_training",
678 cap_decode->link_status.link_training);
679 //add_bool(fields_ir, "slot_clock_configuration",
680 // cap_decode->link_status.slot_clock_configuration);
681 //add_bool(fields_ir, "data_link_layer_link_active",
682 // cap_decode->link_status.data_link_layer_link_active);
683 //add_bool(fields_ir, "link_bandwidth_management_status",
684 // cap_decode->link_status.link_bandwidth_management_status);
685 //add_bool(fields_ir, "link_autonomous_bandwidth_status",
686 // cap_decode->link_status.link_autonomous_bandwidth_status);
687 json_object_object_add(pcie_capability_ir, "link_status", fields_ir);
688
689 /*
690 * Slot Capabilities Register
691 * Offset: 0x14
692 */
693 fields_ir = json_object_new_object();
694 //add_bool(fields_ir, "attention_button_present",
695 // cap_decode->slot_capabilities.attention_button_present);
696 //add_bool(fields_ir, "power_controller_present",
697 // cap_decode->slot_capabilities.power_controller_present);
698 //add_bool(fields_ir, "mrl_sensor_present",
699 // cap_decode->slot_capabilities.mrl_sensor_present);
700 //add_bool(fields_ir, "attention_indicator_present",
701 // cap_decode->slot_capabilities.attention_indicator_present);
702 //add_bool(fields_ir, "power_indicator_present",
703 // cap_decode->slot_capabilities.power_indicator_present);
704 //add_bool(fields_ir, "hot_plug_surprise",
705 // cap_decode->slot_capabilities.hot_plug_surprise);
706 //add_bool(fields_ir, "hot_plug_capable",
707 // cap_decode->slot_capabilities.hot_plug_capable);
708 add_dict(fields_ir, "slot_power_limit_value",
709 cap_decode->slot_capabilities.slot_power_limit_value, NULL, 0);
710 add_int(fields_ir, "slot_power_limit_scale",
711 cap_decode->slot_capabilities.slot_power_limit_scale);
712 //add_bool(fields_ir, "electromechanical_interlock_present",
713 // cap_decode->slot_capabilities
714 // .electromechanical_interlock_present);
715 //add_bool(fields_ir, "no_command_completed_support",
716 // cap_decode->slot_capabilities.no_command_completed_support);
717 add_int(fields_ir, "physical_slot_number",
718 cap_decode->slot_capabilities.physical_slot_number);
719 json_object_object_add(pcie_capability_ir, "slot_capabilities",
720 fields_ir);
721
722 /*
723 * Slot Control Register
724 * Offset: 0x18
725 */
726 fields_ir = json_object_new_object();
727 //add_bool(fields_ir, "attention_button_pressed_enable",
728 // cap_decode->slot_control.attention_button_pressed_enable);
729 //add_bool(fields_ir, "power_fault_detected_enable",
730 // cap_decode->slot_control.power_fault_detected_enable);
731 //add_bool(fields_ir, "mrl_sensor_changed_enable",
732 // cap_decode->slot_control.mrl_sensor_changed_enable);
733 //add_bool(fields_ir, "presence_detect_changed_enable",
734 // cap_decode->slot_control.presence_detect_changed_enable);
735 //add_bool(fields_ir, "command_completed_interrupt_enable",
736 // cap_decode->slot_control.command_completed_interrupt_enable);
737 //add_bool(fields_ir, "hot_plug_interrupt_enable",
738 // cap_decode->slot_control.hot_plug_interrupt_enable);
739 add_int(fields_ir, "attention_indicator_control",
740 cap_decode->slot_control.attention_indicator_control);
741 add_int(fields_ir, "power_indicator_control",
742 cap_decode->slot_control.power_indicator_control);
743 //add_bool(fields_ir, "power_controller_control",
744 // cap_decode->slot_control.power_controller_control);
745 //add_bool(fields_ir, "electromechanical_interlock_control",
746 // cap_decode->slot_control.electromechanical_interlock_control);
747 //add_bool(fields_ir, "data_link_layer_state_changed_enable",
748 // cap_decode->slot_control.data_link_layer_state_changed_enable);
749 //add_bool(fields_ir, "auto_slot_power_limit_disable",
750 // cap_decode->slot_control.auto_slot_power_limit_disable);
751 //add_bool(fields_ir, "in_band_pd_disable",
752 // cap_decode->slot_control.in_band_pd_disable);
753 add_int(fields_ir, "rsvdp", cap_decode->slot_control.rsvdp);
754 json_object_object_add(pcie_capability_ir, "slot_control", fields_ir);
755
756 /*
757 * Slot Status Register
758 * Offset: 0x1A
759 */
760 fields_ir = json_object_new_object();
761 //add_bool(fields_ir, "attention_button_pressed",
762 // cap_decode->slot_status.attention_button_pressed);
763 //add_bool(fields_ir, "power_fault_detected",
764 // cap_decode->slot_status.power_fault_detected);
765 add_int(fields_ir, "mrl_sensor_changed",
766 cap_decode->slot_status.mrl_sensor_changed);
767 //add_bool(fields_ir, "presence_detect_changed",
768 // cap_decode->slot_status.presence_detect_changed);
769 add_int(fields_ir, "command_completed",
770 cap_decode->slot_status.command_completed);
771 add_int(fields_ir, "mrl_sensor_state",
772 cap_decode->slot_status.mrl_sensor_state);
773 //add_bool(fields_ir, "presence_detect_state",
774 // cap_decode->slot_status.presence_detect_state);
775 //add_bool(fields_ir, "electromechanical_interlock_status",
776 // cap_decode->slot_status.electromechanical_interlock_status);
777 //add_bool(fields_ir, "data_link_layer_state_changed",
778 // cap_decode->slot_status.data_link_layer_state_changed);
779 //add_int(fields_ir, "rsvdz", cap_decode->slot_status.rsvdz);
780 json_object_object_add(pcie_capability_ir, "slot_status", fields_ir);
781
782 /*
783 * Root Control Register
784 * Offset: 0x1C
785 */
Ed Tanousffa7e172025-05-29 16:01:49 -0700786 //fields_ir = json_object_new_object();
Erwin Tsaur8870c072025-02-28 12:57:12 -0800787 //add_bool(fields_ir, "system_error_on_correctable_error_enable",
788 // cap_decode->root_control
789 // .system_error_on_correctable_error_enable);
790 //add_bool(
791 // fields_ir, "system_error_on_non_fatal_error_enable",
792 // cap_decode->root_control.system_error_on_non_fatal_error_enable);
793 //add_bool(fields_ir, "system_error_on_fatal_error_enable",
794 // cap_decode->root_control.system_error_on_fatal_error_enable);
795 //add_bool(fields_ir, "pme_interrupt_enable",
796 // cap_decode->root_control.pme_interrupt_enable);
797 //add_bool(fields_ir, "configuration_rrs_software_visibility_enable",
798 // cap_decode->root_control
799 // .configuration_rrs_software_visibility_enable);
800 //add_bool(fields_ir, "no_nfm_subtree_below_this_root_port",
801 // cap_decode->root_control.no_nfm_subtree_below_this_root_port);
802 //add_int(fields_ir, "rsvdp", cap_decode->root_control.rsvdp);
Ed Tanousffa7e172025-05-29 16:01:49 -0700803 //json_object_object_add(pcie_capability_ir, "root_control", fields_ir);
Erwin Tsaur8870c072025-02-28 12:57:12 -0800804
805 /*
806 * Root Capabilities Register
807 * Offset: 0x1E
808 */
Ed Tanousffa7e172025-05-29 16:01:49 -0700809 //fields_ir = json_object_new_object();
Erwin Tsaur8870c072025-02-28 12:57:12 -0800810 //add_bool(fields_ir, "configuraton_rrs_software_visibility",
811 // cap_decode->root_capabilities
812 // .configuraton_rrs_software_visibility);
813 //add_int(fields_ir, "rsvdp", cap_decode->root_capabilities.rsvdp);
Ed Tanousffa7e172025-05-29 16:01:49 -0700814 //json_object_object_add(pcie_capability_ir, "root_capabilities",
815 // fields_ir);
Erwin Tsaur8870c072025-02-28 12:57:12 -0800816
817 /*
818 * Root Status Register
819 * Offset: 0x20
820 */
821 fields_ir = json_object_new_object();
822 add_int(fields_ir, "pme_requester_id",
823 cap_decode->root_status.pme_requester_id);
824 add_int(fields_ir, "pme_status", cap_decode->root_status.pme_status);
825 add_int(fields_ir, "pme_pending", cap_decode->root_status.pme_pending);
826 //add_int(fields_ir, "rsvdp", cap_decode->root_status.rsvdp);
827 json_object_object_add(pcie_capability_ir, "root_status", fields_ir);
828
829 if (cap_decode->pcie_capabilities.capability_version < 2) {
830 return pcie_capability_ir;
831 }
832
833 /*
834 * Device Capabilities 2 Register
835 * Offset: 0x24
836 */
837 fields_ir = json_object_new_object();
838 add_int(fields_ir, "completion_timeout_ranges_supported",
839 cap_decode->device_capabilities2
840 .completion_timeout_ranges_supported);
841 add_bool_enum(fields_ir, "completion_timeout_disable_supported",
842 supported_dict,
843 cap_decode->device_capabilities2
844 .completion_timeout_disable_supported);
845 add_bool_enum(
846 fields_ir, "ari_forwarding_supported", supported_dict,
847 cap_decode->device_capabilities2.ari_forwarding_supported);
848 add_bool_enum(
849 fields_ir, "atomic_op_routing_supported", supported_dict,
850 cap_decode->device_capabilities2.atomic_op_routing_supported);
851 add_bool_enum(fields_ir, "_32_bit_atomicop_completer_supported",
852 supported_dict,
853 cap_decode->device_capabilities2
854 ._32_bit_atomicop_completer_supported);
855 add_bool_enum(fields_ir, "_64_bit_atomicop_completer_supported",
856 supported_dict,
857 cap_decode->device_capabilities2
858 ._64_bit_atomicop_completer_supported);
859 add_bool_enum(fields_ir, "_128_bit_cas_completer_supported",
860 supported_dict,
861 cap_decode->device_capabilities2
862 ._128_bit_cas_completer_supported);
863 add_bool_enum(
864 fields_ir, "no_ro_enabled_pr_pr_passing", passing_dict,
865 cap_decode->device_capabilities2.no_ro_enabled_pr_pr_passing);
866 add_bool_enum(fields_ir, "ltr_mechanism_supported", supported_dict,
867 cap_decode->device_capabilities2.ltr_mechanism_supported);
868 add_bool_enum(fields_ir, "tph_completer_supported", supported_dict,
869 cap_decode->device_capabilities2.tph_completer_supported);
870 //add_int(fields_ir, "undefined",
871 // cap_decode->device_capabilities2.undefined);
872 //add_bool(fields_ir, "_10_bit_tag_completer_supported",
873 // cap_decode->device_capabilities2
874 // ._10_bit_tag_completer_supported);
875 //add_bool(fields_ir, "_10_bit_tag_requester_supported",
876 // cap_decode->device_capabilities2
877 // ._10_bit_tag_requester_supported);
878 add_bool_enum(fields_ir, "obff_supported", supported_dict,
879 cap_decode->device_capabilities2.obff_supported);
880 //add_bool(fields_ir, "extended_fmt_field_supported",
881 // cap_decode->device_capabilities2.extended_fmt_field_supported);
882 //add_bool(fields_ir, "end_end_tlp_prefix_supported",
883 // cap_decode->device_capabilities2.end_end_tlp_prefix_supported);
884 add_dict(fields_ir, "max_end_end_tlp_prefixes",
885 cap_decode->device_capabilities2.max_end_end_tlp_prefixes,
886 NULL, 0);
887 add_bool_enum(fields_ir, "emergency_power_reduction_supported",
888 supported_dict,
889 cap_decode->device_capabilities2
890 .emergency_power_reduction_supported);
891 //add_bool(fields_ir, "emergency_power_reduction_init_required",
892 // cap_decode->device_capabilities2
893 // .emergency_power_reduction_init_required);
894 //add_int(fields_ir, "rsvdp", cap_decode->device_capabilities2.rsvdp);
895 //add_bool(fields_ir, "dmwr_completer_supported",
896 // cap_decode->device_capabilities2.dmwr_completer_supported);
897 add_int(fields_ir, "dmwr_lengths_supported",
898 cap_decode->device_capabilities2.dmwr_lengths_supported);
899 //add_bool(fields_ir, "frs_supported",
900 // cap_decode->device_capabilities2.frs_supported);
901 json_object_object_add(pcie_capability_ir, "device_capabilities2",
902 fields_ir);
903
904 /*
905 * Device Control 2 Register
906 * Offset: 0x28
907 */
908 fields_ir = json_object_new_object();
909 add_int(fields_ir, "completion_timeout_value",
910 cap_decode->device_control2.completion_timeout_value);
911 //add_bool(fields_ir, "completion_timeout_disable",
912 // cap_decode->device_control2.completion_timeout_disable);
913 add_bool(fields_ir, "ari_forwarding_enable",
914 cap_decode->device_control2.ari_forwarding_enable);
915 add_bool(fields_ir, "atomicop_requester_enable",
916 cap_decode->device_control2.atomicop_requester_enable);
917 add_bool(fields_ir, "atomicop_egress_blocking",
918 cap_decode->device_control2.atomicop_egress_blocking);
919 add_bool(fields_ir, "ido_request_enable",
920 cap_decode->device_control2.ido_request_enable);
921 add_bool(fields_ir, "ido_completion_enable",
922 cap_decode->device_control2.ido_completion_enable);
923 add_bool(fields_ir, "ltr_mechanism_enable",
924 cap_decode->device_control2.ltr_mechanism_enable);
925 add_bool(fields_ir, "emergency_power_reduction_request",
926 cap_decode->device_control2.emergency_power_reduction_request);
Aushim Nagarkattieda19ff2025-06-10 12:34:48 -0700927 add_bool(fields_ir, "bit_tag_requester_10_enable",
928 cap_decode->device_control2.bit_tag_requester_10_enable);
Erwin Tsaur8870c072025-02-28 12:57:12 -0800929 add_int(fields_ir, "obff_enable",
930 cap_decode->device_control2.obff_enable);
931 //add_bool(fields_ir, "end_end_tlp_prefix_blocking",
932 // cap_decode->device_control2.end_end_tlp_prefix_blocking);
933 json_object_object_add(pcie_capability_ir, "device_control2",
934 fields_ir);
935
936 /*
937 * Device Status 2 Register
938 * Offset: 0x2A
939 */
Ed Tanousffa7e172025-05-29 16:01:49 -0700940 //fields_ir = json_object_new_object();
Erwin Tsaur8870c072025-02-28 12:57:12 -0800941 //add_int(fields_ir, "rsvdz", cap_decode->device_status2.rsvdz);
Ed Tanousffa7e172025-05-29 16:01:49 -0700942 //json_object_object_add(pcie_capability_ir, "device_status2", fields_ir);
Erwin Tsaur8870c072025-02-28 12:57:12 -0800943
944 /*
945 * Link Capabilities 2 Register
946 * Offset: 0x2C
947 */
948 fields_ir = json_object_new_object();
949 //add_int(fields_ir, "rsvdp", cap_decode->link_capabilities2.rsvdp);
950 add_int(fields_ir, "supported_link_speeds",
951 cap_decode->link_capabilities2.supported_link_speeds_register);
952 add_bool_enum(fields_ir, "crosslink_supported", supported_dict,
953 cap_decode->link_capabilities2.crosslink_supported);
954 add_int(fields_ir, "lower_skp_os_generation_supported",
955 cap_decode->link_capabilities2
956 .lower_skp_os_generation_supported);
957 add_int(fields_ir, "lower_skp_os_reception_supported",
958 cap_decode->link_capabilities2.lower_skp_os_reception_supported);
959 add_bool_enum(fields_ir, "retimer_presence_detect_supported",
960 supported_dict,
961 cap_decode->link_capabilities2
962 .retimer_presence_detect_supported);
963 add_bool_enum(fields_ir, "two_retimers_presence_detect_supported",
964 supported_dict,
965 cap_decode->link_capabilities2
966 .two_retimers_presence_detect_supported);
967 //add_int(fields_ir, "reserved", cap_decode->link_capabilities2.reserved);
968 add_bool_enum(fields_ir, "drs_supported", supported_dict,
969 cap_decode->link_capabilities2.drs_supported);
970 json_object_object_add(pcie_capability_ir, "link_capabilities2",
971 fields_ir);
972
973 /*
974 * Link Control 2 Register
975 * Offset: 0x30
976 */
977 fields_ir = json_object_new_object();
978 add_dict(fields_ir, "target_link_speed",
979 cap_decode->link_control2.target_link_speed, NULL, 0);
980 add_bool_enum(fields_ir, "enter_compliance", supported_dict,
981 cap_decode->link_control2.enter_compliance);
982 add_dict(fields_ir, "hardware_autonomous_speed_disable",
983 cap_decode->link_control2.hardware_autonomous_speed_disable,
984 NULL, 0);
985 add_bool(fields_ir, "selectable_de_emphasis",
986 cap_decode->link_control2.selectable_de_emphasis);
987 add_int(fields_ir, "transmit_margin",
988 cap_decode->link_control2.transmit_margin);
989 add_bool(fields_ir, "enter_modified_compliance",
990 cap_decode->link_control2.enter_modified_compliance);
991 add_bool(fields_ir, "compliance_sos",
992 cap_decode->link_control2.compliance_sos);
993 add_int(fields_ir, "compliance_preset_de_emphasis",
994 cap_decode->link_control2.compliance_preset_de_emphasis);
995 json_object_object_add(pcie_capability_ir, "link_control2", fields_ir);
996
997 /*
998 * Link Status 2 Register
999 * Offset: 0x32
1000 */
1001 fields_ir = json_object_new_object();
1002 add_int(fields_ir, "current_de_emphasis_level",
1003 cap_decode->link_status2.current_de_emphasis_level);
1004 add_bool(fields_ir, "equalization_8gts_complete",
1005 cap_decode->link_status2.equalization_8gts_complete);
1006 add_bool(fields_ir, "equalization_8gts_phase1_successful",
1007 cap_decode->link_status2.equalization_8gts_phase1_successful);
1008 add_bool(fields_ir, "equalization_8gts_phase2_successful",
1009 cap_decode->link_status2.equalization_8gts_phase2_successful);
1010 add_bool(fields_ir, "equalization_8gts_phase3_successful",
1011 cap_decode->link_status2.equalization_8gts_phase3_successful);
1012 add_bool(fields_ir, "link_equalization_request_8gts",
1013 cap_decode->link_status2.link_equalization_request_8gts);
1014 add_bool(fields_ir, "retimer_presence_detected",
1015 cap_decode->link_status2.retimer_presence_detected);
1016 add_bool(fields_ir, "two_retimers_presence_detected",
1017 cap_decode->link_status2.two_retimers_presence_detected);
1018 add_int(fields_ir, "crosslink_resolution",
1019 cap_decode->link_status2.crosslink_resolution);
1020 add_int(fields_ir, "flit_mode_status",
1021 cap_decode->link_status2.flit_mode_status);
1022 //add_int(fields_ir, "rsvdz", cap_decode->link_status2.rsvdz);
1023 add_int(fields_ir, "downstream_component_presence",
1024 cap_decode->link_status2.downstream_component_presence);
1025 add_bool(fields_ir, "drs_message_received",
1026 cap_decode->link_status2.drs_message_received);
1027 json_object_object_add(pcie_capability_ir, "link_status2", fields_ir);
1028
1029 /*
1030 * Slot Capabilities 2 Register
1031 * Offset: 0x34
1032 */
Ed Tanousffa7e172025-05-29 16:01:49 -07001033 //fields_ir = json_object_new_object();
Erwin Tsaur8870c072025-02-28 12:57:12 -08001034 //add_int(fields_ir, "rsvdp", cap_decode->slot_capabilities2.rsvdp);
Ed Tanousffa7e172025-05-29 16:01:49 -07001035 //json_object_object_add(pcie_capability_ir, "slot_capabilities2",
1036 // fields_ir);
Erwin Tsaur8870c072025-02-28 12:57:12 -08001037
1038 /*
1039 * Slot Control 2 Register
1040 * Offset: 0x38
1041 */
Ed Tanousffa7e172025-05-29 16:01:49 -07001042 //fields_ir = json_object_new_object();
Erwin Tsaur8870c072025-02-28 12:57:12 -08001043 //add_int(fields_ir, "rsvdp", cap_decode->slot_control2.rsvdp);
Ed Tanousffa7e172025-05-29 16:01:49 -07001044 //json_object_object_add(pcie_capability_ir, "slot_control2", fields_ir);
Erwin Tsaur8870c072025-02-28 12:57:12 -08001045
1046 /*
1047 * Slot Status 2 Register
1048 * Offset: 0x3A
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_status2.rsvdp);
Ed Tanousffa7e172025-05-29 16:01:49 -07001052 //json_object_object_add(pcie_capability_ir, "slot_status2", fields_ir);
Erwin Tsaur8870c072025-02-28 12:57:12 -08001053
1054 return pcie_capability_ir;
1055}
1056
1057//Converts PCIe Capability Structure section into JSON IR.
1058json_object *pcie_aer_to_ir(EFI_PCIE_ERROR_DATA *pcie_error)
1059{
Erwin Tsaur8870c072025-02-28 12:57:12 -08001060 json_object *aer_capability_ir = json_object_new_object();
1061
Ed Tanous3f810e52026-02-04 12:04:10 -08001062 add_binary_base64(aer_capability_ir, "data",
1063 pcie_error->AerInfo.PcieAer,
1064 sizeof(pcie_error->AerInfo.PcieAer));
Erwin Tsaur8870c072025-02-28 12:57:12 -08001065
1066 json_object *fields_ir;
1067
1068 aer_info_registers *aer_decode;
1069 aer_decode = (aer_info_registers *)&pcie_error->AerInfo.PcieAer;
1070
1071 /*
1072 * AER Capability Header
1073 * Offset: 0x0
1074 */
1075 fields_ir = json_object_new_object();
1076 add_int(fields_ir, "capability_id",
1077 aer_decode->capability_header.capability_id);
1078 add_int(fields_ir, "capability_version",
1079 aer_decode->capability_header.capability_version);
1080 add_int(fields_ir, "next_capability_offset",
1081 aer_decode->capability_header.next_capability_offset);
1082 json_object_object_add(aer_capability_ir, "capability_header",
1083 fields_ir);
1084
1085 /*
1086 * Uncorrectable Error Status Register
1087 * Offset: 0x4
1088 */
1089 fields_ir = json_object_new_object();
1090 //add_bool(fields_ir, "undefined",
1091 // aer_decode->uncorrectable_error_status.undefined);
1092 //add_int(fields_ir, "rsvdz1",
1093 // aer_decode->uncorrectable_error_status.rsvdz1);
1094 add_bool(fields_ir, "data_link_protocol_error_status",
1095 aer_decode->uncorrectable_error_status
1096 .data_link_protocol_error_status);
1097 add_bool(fields_ir, "surprise_down_error_status",
1098 aer_decode->uncorrectable_error_status
1099 .surprise_down_error_status);
1100 //add_int(fields_ir, "rsvdz2",
1101 // aer_decode->uncorrectable_error_status.rsvdz2);
1102 add_bool(fields_ir, "poisoned_tlp_received",
1103 aer_decode->uncorrectable_error_status.poisoned_tlp_received);
1104 add_bool(fields_ir, "flow_control_protocol_error_status",
1105 aer_decode->uncorrectable_error_status
1106 .flow_control_protocol_error_status);
1107 add_bool(fields_ir, "completion_timeout_status",
1108 aer_decode->uncorrectable_error_status
1109 .completion_timeout_status);
1110 add_bool(fields_ir, "completer_abort_status",
1111 aer_decode->uncorrectable_error_status.completer_abort_status);
1112 add_bool(fields_ir, "unexpected_completion_status",
1113 aer_decode->uncorrectable_error_status
1114 .unexpected_completion_status);
1115 add_bool(
1116 fields_ir, "receiver_overflow_status",
1117 aer_decode->uncorrectable_error_status.receiver_overflow_status);
1118 add_bool(fields_ir, "malformed_tlp_status",
1119 aer_decode->uncorrectable_error_status.malformed_tlp_status);
1120 add_bool(fields_ir, "ecrc_error_status",
1121 aer_decode->uncorrectable_error_status.ecrc_error_status);
1122 add_bool(fields_ir, "unsupported_request_error_status",
1123 aer_decode->uncorrectable_error_status
1124 .unsupported_request_error_status);
1125 add_bool(fields_ir, "acs_violation_status",
1126 aer_decode->uncorrectable_error_status.acs_violation_status);
1127 add_bool(fields_ir, "uncorrectable_internal_error_status",
1128 aer_decode->uncorrectable_error_status
1129 .uncorrectable_internal_error_status);
1130 add_bool(fields_ir, "mc_blocked_tlp_status",
1131 aer_decode->uncorrectable_error_status.mc_blocked_tlp_status);
1132 add_bool(fields_ir, "atomicop_egress_blocked_status",
1133 aer_decode->uncorrectable_error_status
1134 .atomicop_egress_blocked_status);
1135 add_bool(fields_ir, "tlp_prefix_blocked_error_status",
1136 aer_decode->uncorrectable_error_status
1137 .tlp_prefix_blocked_error_status);
1138 add_bool(fields_ir, "poisoned_tlp_egress_blocked_status",
1139 aer_decode->uncorrectable_error_status
1140 .poisoned_tlp_egress_blocked_status);
1141 add_bool(fields_ir, "dmwr_request_egress_blocked_status",
1142 aer_decode->uncorrectable_error_status
1143 .dmwr_request_egress_blocked_status);
1144 add_bool(
1145 fields_ir, "ide_check_failed_status",
1146 aer_decode->uncorrectable_error_status.ide_check_failed_status);
1147 add_bool(
1148 fields_ir, "misrouted_ide_tlp_status",
1149 aer_decode->uncorrectable_error_status.misrouted_ide_tlp_status);
1150 add_bool(
1151 fields_ir, "pcrc_check_failed_status",
1152 aer_decode->uncorrectable_error_status.pcrc_check_failed_status);
1153 add_bool(fields_ir, "tlp_translation_egress_blocked_status",
1154 aer_decode->uncorrectable_error_status
1155 .tlp_translation_egress_blocked_status);
1156 json_object_object_add(aer_capability_ir, "uncorrectable_error_status",
1157 fields_ir);
1158
1159 /*
1160 * Uncorrectable Error Mask Register
1161 * Offset: 0x8
1162 */
1163 fields_ir = json_object_new_object();
1164 //add_bool(fields_ir, "undefined",
1165 // aer_decode->uncorrectable_error_mask.undefined);
1166 //add_int(fields_ir, "rsvdz1",
1167 // aer_decode->uncorrectable_error_mask.rsvdz1);
1168 add_int(fields_ir, "data_link_protocol_error_mask",
1169 aer_decode->uncorrectable_error_mask
1170 .data_link_protocol_error_mask);
1171 add_int(fields_ir, "surprise_down_error_mask",
1172 aer_decode->uncorrectable_error_mask.surprise_down_error_mask);
1173 //add_int(fields_ir, "rsvdz2",
1174 // aer_decode->uncorrectable_error_mask.rsvdz2);
1175 add_int(fields_ir, "poisoned_tlp_received_mask",
1176 aer_decode->uncorrectable_error_mask.poisoned_tlp_received_mask);
1177 add_int(fields_ir, "flow_control_protocol_error_mask",
1178 aer_decode->uncorrectable_error_mask
1179 .flow_control_protocol_error_mask);
1180 add_int(fields_ir, "completion_timeout_mask",
1181 aer_decode->uncorrectable_error_mask.completion_timeout_mask);
1182 add_int(fields_ir, "completer_abort_mask",
1183 aer_decode->uncorrectable_error_mask.completer_abort_mask);
1184 add_int(fields_ir, "unexpected_completion_mask",
1185 aer_decode->uncorrectable_error_mask.unexpected_completion_mask);
1186 add_int(fields_ir, "receiver_overflow_mask",
1187 aer_decode->uncorrectable_error_mask.receiver_overflow_mask);
1188 add_int(fields_ir, "malformed_tlp_mask",
1189 aer_decode->uncorrectable_error_mask.malformed_tlp_mask);
1190 add_int(fields_ir, "ecrc_error_mask",
1191 aer_decode->uncorrectable_error_mask.ecrc_error_mask);
1192 add_int(fields_ir, "unsupported_request_error_mask",
1193 aer_decode->uncorrectable_error_mask
1194 .unsupported_request_error_mask);
1195 add_int(fields_ir, "acs_violation_mask",
1196 aer_decode->uncorrectable_error_mask.acs_violation_mask);
1197 add_int(fields_ir, "uncorrectable_internal_error_mask",
1198 aer_decode->uncorrectable_error_mask
1199 .uncorrectable_internal_error_mask);
1200 add_int(fields_ir, "mc_blocked_tlp_mask",
1201 aer_decode->uncorrectable_error_mask.mc_blocked_tlp_mask);
1202 add_int(fields_ir, "atomicop_egress_blocked_mask",
1203 aer_decode->uncorrectable_error_mask
1204 .atomicop_egress_blocked_mask);
1205 add_int(fields_ir, "tlp_prefix_blocked_error_mask",
1206 aer_decode->uncorrectable_error_mask
1207 .tlp_prefix_blocked_error_mask);
1208 add_int(fields_ir, "poisoned_tlp_egress_blocked_mask",
1209 aer_decode->uncorrectable_error_mask
1210 .poisoned_tlp_egress_blocked_mask);
1211 add_int(fields_ir, "dmwr_request_egress_blocked_mask",
1212 aer_decode->uncorrectable_error_mask
1213 .dmwr_request_egress_blocked_mask);
1214 add_int(fields_ir, "ide_check_failed_mask",
1215 aer_decode->uncorrectable_error_mask.ide_check_failed_mask);
1216 add_int(fields_ir, "misrouted_ide_tlp_mask",
1217 aer_decode->uncorrectable_error_mask.misrouted_ide_tlp_mask);
1218 add_int(fields_ir, "pcrc_check_failed_mask",
1219 aer_decode->uncorrectable_error_mask.pcrc_check_failed_mask);
1220 add_int(fields_ir, "tlp_translation_egress_blocked_mask",
1221 aer_decode->uncorrectable_error_mask
1222 .tlp_translation_egress_blocked_mask);
1223 json_object_object_add(aer_capability_ir, "uncorrectable_error_mask",
1224 fields_ir);
1225
1226 /*
1227 * Uncorrectable Error Severity Register
1228 * Offset: 0xC
1229 */
1230 fields_ir = json_object_new_object();
1231 //add_bool(fields_ir, "undefined",
1232 // aer_decode->uncorrectable_error_severity.undefined);
1233 //add_int(fields_ir, "rsvdz1",
1234 // aer_decode->uncorrectable_error_severity.rsvdz1);
1235 add_bool_enum(fields_ir, "data_link_protocol_error_severity",
1236 severity_dict,
1237 aer_decode->uncorrectable_error_severity
1238 .data_link_protocol_error_severity);
1239 add_bool_enum(fields_ir, "surprise_down_error_severity", severity_dict,
1240 aer_decode->uncorrectable_error_severity
1241 .surprise_down_error_severity);
1242 //add_int(fields_ir, "rsvdz2",
1243 // aer_decode->uncorrectable_error_severity.rsvdz2);
1244 add_bool_enum(fields_ir, "poisoned_tlp_received_severity",
1245 severity_dict,
1246 aer_decode->uncorrectable_error_severity
1247 .poisoned_tlp_received_severity);
1248 add_bool_enum(fields_ir, "flow_control_protocol_error_severity",
1249 severity_dict,
1250 aer_decode->uncorrectable_error_severity
1251 .flow_control_protocol_error_severity);
1252 add_bool_enum(fields_ir, "completion_timeout_severity", severity_dict,
1253 aer_decode->uncorrectable_error_severity
1254 .completion_timeout_severity);
1255 add_bool_enum(fields_ir, "completer_abort_severity", severity_dict,
1256 aer_decode->uncorrectable_error_severity
1257 .completer_abort_severity);
1258 add_bool_enum(fields_ir, "unexpected_completion_severity",
1259 severity_dict,
1260 aer_decode->uncorrectable_error_severity
1261 .unexpected_completion_severity);
1262 add_bool_enum(fields_ir, "receiver_overflow_severity", severity_dict,
1263 aer_decode->uncorrectable_error_severity
1264 .receiver_overflow_severity);
1265 add_bool_enum(
1266 fields_ir, "malformed_tlp_severity", severity_dict,
1267 aer_decode->uncorrectable_error_severity.malformed_tlp_severity);
1268 add_bool_enum(
1269 fields_ir, "ecrc_error_severity", severity_dict,
1270 aer_decode->uncorrectable_error_severity.ecrc_error_severity);
1271 add_bool_enum(fields_ir, "unsupported_request_error_severity",
1272 severity_dict,
1273 aer_decode->uncorrectable_error_severity
1274 .unsupported_request_error_severity);
1275 add_bool_enum(
1276 fields_ir, "acs_violation_severity", severity_dict,
1277 aer_decode->uncorrectable_error_severity.acs_violation_severity);
1278 add_bool_enum(fields_ir, "uncorrectable_internal_error_severity",
1279 severity_dict,
1280 aer_decode->uncorrectable_error_severity
1281 .uncorrectable_internal_error_severity);
1282 add_bool_enum(fields_ir, "mc_blocked_tlp_severity", severity_dict,
1283 aer_decode->uncorrectable_error_severity
1284 .mc_blocked_tlp_severity);
1285 add_bool_enum(fields_ir, "atomicop_egress_blocked_severity",
1286 severity_dict,
1287 aer_decode->uncorrectable_error_severity
1288 .atomicop_egress_blocked_severity);
1289 add_bool_enum(fields_ir, "tlp_prefix_blocked_error_severity",
1290 severity_dict,
1291 aer_decode->uncorrectable_error_severity
1292 .tlp_prefix_blocked_error_severity);
1293 add_bool_enum(fields_ir, "poisoned_tlp_egress_blocked_severity",
1294 severity_dict,
1295 aer_decode->uncorrectable_error_severity
1296 .poisoned_tlp_egress_blocked_severity);
1297 add_bool_enum(fields_ir, "dmwr_request_egress_blocked_severity",
1298 severity_dict,
1299 aer_decode->uncorrectable_error_severity
1300 .dmwr_request_egress_blocked_severity);
1301 add_bool_enum(fields_ir, "ide_check_failed_severity", severity_dict,
1302 aer_decode->uncorrectable_error_severity
1303 .ide_check_failed_severity);
1304 add_bool_enum(fields_ir, "misrouted_ide_tlp_severity", severity_dict,
1305 aer_decode->uncorrectable_error_severity
1306 .misrouted_ide_tlp_severity);
1307 add_bool_enum(fields_ir, "pcrc_check_failed_severity", severity_dict,
1308 aer_decode->uncorrectable_error_severity
1309 .pcrc_check_failed_severity);
1310 add_bool_enum(fields_ir, "tlp_translation_egress_blocked_severity",
1311 severity_dict,
1312 aer_decode->uncorrectable_error_severity
1313 .tlp_translation_egress_blocked_severity);
1314 json_object_object_add(aer_capability_ir,
1315 "uncorrectable_error_severity", fields_ir);
1316
1317 /*
1318 * Correctable Error Status Register
1319 * Offset: 0x10
1320 */
1321 fields_ir = json_object_new_object();
1322 add_bool(fields_ir, "receiver_error_status",
1323 aer_decode->correctable_error_status.receiver_error_status);
1324 //add_int(fields_ir, "rsvdz1",
1325 // aer_decode->correctable_error_status.rsvdz1);
1326 add_bool(fields_ir, "bad_tlp_status",
1327 aer_decode->correctable_error_status.bad_tlp_status);
1328 add_bool(fields_ir, "bad_dllp_status",
1329 aer_decode->correctable_error_status.bad_dllp_status);
1330 add_bool(
1331 fields_ir, "replay_num_rollover_status",
1332 aer_decode->correctable_error_status.replay_num_rollover_status);
1333 //add_int(fields_ir, "rsvdz2",
1334 // aer_decode->correctable_error_status.rsvdz2);
1335 add_bool(fields_ir, "replay_timer_timeout_status",
1336 aer_decode->correctable_error_status
1337 .replay_timer_timeout_status);
1338 add_bool(fields_ir, "advisory_non_fatal_error_status",
1339 aer_decode->correctable_error_status
1340 .advisory_non_fatal_error_status);
1341 add_bool(fields_ir, "corrected_internal_error_status",
1342 aer_decode->correctable_error_status
1343 .corrected_internal_error_status);
1344 add_bool(
1345 fields_ir, "header_log_overflow_status",
1346 aer_decode->correctable_error_status.header_log_overflow_status);
1347 //add_int(fields_ir, "rsvdz3",
1348 // aer_decode->correctable_error_status.rsvdz3);
1349 json_object_object_add(aer_capability_ir, "correctable_error_status",
1350 fields_ir);
1351
1352 /*
1353 * Correctable Error Mask Register
1354 * Offset: 0x14
1355 */
1356 fields_ir = json_object_new_object();
1357 add_int(fields_ir, "receiver_error_mask",
1358 aer_decode->correctable_error_mask.receiver_error_mask);
1359 //add_int(fields_ir, "rsvdz1", aer_decode->correctable_error_mask.rsvdz1);
1360 add_int(fields_ir, "bad_tlp_mask",
1361 aer_decode->correctable_error_mask.bad_tlp_mask);
1362 add_int(fields_ir, "bad_dllp_mask",
1363 aer_decode->correctable_error_mask.bad_dllp_mask);
1364 add_int(fields_ir, "replay_num_rollover_mask",
1365 aer_decode->correctable_error_mask.replay_num_rollover_mask);
1366 //add_int(fields_ir, "rsvdz2", aer_decode->correctable_error_mask.rsvdz2);
1367 add_int(fields_ir, "replay_timer_timeout_mask",
1368 aer_decode->correctable_error_mask.replay_timer_timeout_mask);
1369 add_int(fields_ir, "advisory_non_fatal_error_mask",
1370 aer_decode->correctable_error_mask
1371 .advisory_non_fatal_error_mask);
1372 add_int(fields_ir, "corrected_internal_error_mask",
1373 aer_decode->correctable_error_mask
1374 .corrected_internal_error_mask);
1375 add_int(fields_ir, "header_log_overflow_mask",
1376 aer_decode->correctable_error_mask.header_log_overflow_mask);
1377 //add_int(fields_ir, "rsvdz3", aer_decode->correctable_error_mask.rsvdz3);
1378 json_object_object_add(aer_capability_ir, "correctable_error_mask",
1379 fields_ir);
1380
1381 /*
1382 * Advanced Error Capabilities and Control Register
1383 * Offset: 0x18
1384 */
1385 fields_ir = json_object_new_object();
1386 add_int(fields_ir, "first_error_pointer",
1387 aer_decode->advanced_error_capabilities_and_control
1388 .first_error_pointer);
1389 //add_bool(fields_ir, "ecrc_generation_capable",
1390 // aer_decode->advanced_error_capabilities_and_control
1391 // .ecrc_generation_capable);
1392 //add_bool(fields_ir, "ecrc_generation_enable",
1393 // aer_decode->advanced_error_capabilities_and_control
1394 // .ecrc_generation_enable);
1395 //add_bool(fields_ir, "ecrc_check_capable",
1396 // aer_decode->advanced_error_capabilities_and_control
1397 // .ecrc_check_capable);
1398 //add_bool(fields_ir, "ecrc_check_enable",
1399 // aer_decode->advanced_error_capabilities_and_control
1400 // .ecrc_check_enable);
1401 //add_bool(fields_ir, "multiple_header_recording_capable",
1402 // aer_decode->advanced_error_capabilities_and_control
1403 // .multiple_header_recording_capable);
1404 //add_bool(fields_ir, "multiple_header_recording_enable",
1405 // aer_decode->advanced_error_capabilities_and_control
1406 // .multiple_header_recording_enable);
1407 //add_bool(fields_ir, "tlp_prefix_log_present",
1408 // aer_decode->advanced_error_capabilities_and_control
1409 // .tlp_prefix_log_present);
1410 //add_bool(fields_ir, "completion_timeout_prefix_header_log_capable",
1411 // aer_decode->advanced_error_capabilities_and_control
1412 // .completion_timeout_prefix_header_log_capable);
1413 add_int(fields_ir, "header_log_size",
1414 aer_decode->advanced_error_capabilities_and_control
1415 .header_log_size);
1416 //add_bool(fields_ir, "logged_tlp_was_flit_mode",
1417 // aer_decode->advanced_error_capabilities_and_control
1418 // .logged_tlp_was_flit_mode);
1419 add_int(fields_ir, "logged_tlp_size",
1420 aer_decode->advanced_error_capabilities_and_control
1421 .logged_tlp_size);
1422 //add_int(fields_ir, "rsvdp",
1423 // aer_decode->advanced_error_capabilities_and_control.rsvdp);
1424 json_object_object_add(aer_capability_ir,
1425 "advanced_error_capabilities_and_control",
1426 fields_ir);
1427
1428 /*
1429 * Root Error Command Register
1430 * Offset: 0x2C
1431 */
Ed Tanousffa7e172025-05-29 16:01:49 -07001432 //fields_ir = json_object_new_object();
Erwin Tsaur8870c072025-02-28 12:57:12 -08001433 //add_bool(fields_ir, "correctable_error_reporting_enable",
1434 // aer_decode->root_error_command
1435 // .correctable_error_reporting_enable);
1436 //add_bool(
1437 // fields_ir, "non_fatal_error_reporting_enable",
1438 // aer_decode->root_error_command.non_fatal_error_reporting_enable);
1439 //add_bool(fields_ir, "fatal_error_reporting_enable",
1440 // aer_decode->root_error_command.fatal_error_reporting_enable);
1441 //add_int(fields_ir, "rsvdp", aer_decode->root_error_command.rsvdp);
Ed Tanousffa7e172025-05-29 16:01:49 -07001442 ///json_object_object_add(aer_capability_ir, "root_error_command",
1443 // fields_ir);
Erwin Tsaur8870c072025-02-28 12:57:12 -08001444
1445 /*
1446 * Root Error Status Register
1447 * Offset: 0x30
1448 */
1449 fields_ir = json_object_new_object();
1450 //add_bool(fields_ir, "err_cor_received",
1451 // aer_decode->root_error_status.err_cor_received);
1452 //add_bool(fields_ir, "multiple_err_cor_received",
1453 // aer_decode->root_error_status.multiple_err_cor_received);
1454 //add_bool(fields_ir, "err_fatal_nonfatal_received",
1455 // aer_decode->root_error_status.err_fatal_nonfatal_received);
1456 //add_bool(fields_ir, "multiple_err_fatal_nonfatal_received",
1457 // aer_decode->root_error_status
1458 // .multiple_err_fatal_nonfatal_received);
1459 //add_bool(fields_ir, "first_uncorrectable_fatal",
1460 // aer_decode->root_error_status.first_uncorrectable_fatal);
1461 //add_bool(
1462 // fields_ir, "non_fatal_error_messages_received",
1463 // aer_decode->root_error_status.non_fatal_error_messages_received);
1464 //add_bool(fields_ir, "fatal_error_messages_received",
1465 // aer_decode->root_error_status.fatal_error_messages_received);
1466 add_int(fields_ir, "err_cor_subclass",
1467 aer_decode->root_error_status.err_cor_subclass);
1468 //add_int(fields_ir, "rsvdz", aer_decode->root_error_status.rsvdz);
1469 add_int(fields_ir, "advanced_error_interrupt_message_number",
1470 aer_decode->root_error_status
1471 .advanced_error_interrupt_message_number);
1472 json_object_object_add(aer_capability_ir, "root_error_status",
1473 fields_ir);
1474
1475 /*
1476 * Error Source Identification Register
1477 * Offset: 0x34
1478 */
1479 fields_ir = json_object_new_object();
1480 add_int(fields_ir, "err_cor_source_identification",
1481 aer_decode->error_source_id.err_cor_source_identification);
1482 add_int(fields_ir, "err_fatal_nonfatal_source_identification",
1483 aer_decode->error_source_id
1484 .err_fatal_nonfatal_source_identification);
1485 json_object_object_add(aer_capability_ir, "error_source_id", fields_ir);
1486
1487 return aer_capability_ir;
1488}
1489
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001490//Converts a single CPER-JSON PCIe section into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001491void ir_section_pcie_to_cper(json_object *section, FILE *out)
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001492{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001493 EFI_PCIE_ERROR_DATA *section_cper =
1494 (EFI_PCIE_ERROR_DATA *)calloc(1, sizeof(EFI_PCIE_ERROR_DATA));
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001495
Lawrence Tange407b4c2022-07-21 13:54:01 +01001496 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001497 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
1498 struct json_object *obj = NULL;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001499
Lawrence Tange407b4c2022-07-21 13:54:01 +01001500 //Version.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001501 if (json_object_object_get_ex(section, "version", &obj)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -08001502 const json_object *version = obj;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001503 UINT32 minor = int_to_bcd(json_object_get_int(
1504 json_object_object_get(version, "minor")));
1505 UINT32 major = int_to_bcd(json_object_get_int(
1506 json_object_object_get(version, "major")));
1507 section_cper->Version = minor + (major << 8);
1508 add_to_valid_bitfield(&ui64Type, 1);
John Chungf8fc7052024-05-03 20:05:29 +08001509 }
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001510
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001511 //Command/status registers.
1512 if (json_object_object_get_ex(section, "commandStatus", &obj)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -08001513 const json_object *command_status = obj;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001514 UINT32 command = (UINT16)json_object_get_uint64(
1515 json_object_object_get(command_status,
1516 "commandRegister"));
1517 UINT32 status = (UINT16)json_object_get_uint64(
1518 json_object_object_get(command_status,
1519 "statusRegister"));
1520 section_cper->CommandStatus = command + (status << 16);
1521 add_to_valid_bitfield(&ui64Type, 2);
1522 }
1523
1524 //Device ID.
1525 if (json_object_object_get_ex(section, "deviceID", &obj)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -08001526 const json_object *device_id = obj;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001527 UINT64 class_id = json_object_get_uint64(
1528 json_object_object_get(device_id, "classCode"));
1529 section_cper->DevBridge.VendorId =
1530 (UINT16)json_object_get_uint64(
1531 json_object_object_get(device_id, "vendorID"));
1532 section_cper->DevBridge.DeviceId =
1533 (UINT16)json_object_get_uint64(
1534 json_object_object_get(device_id, "deviceID"));
Ed Tanous9f260e52025-04-24 09:37:59 -07001535 section_cper->DevBridge.ClassCode[2] = class_id >> 16;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001536 section_cper->DevBridge.ClassCode[1] = (class_id >> 8) & 0xFF;
Ed Tanous9f260e52025-04-24 09:37:59 -07001537 section_cper->DevBridge.ClassCode[0] = class_id & 0xFF;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001538 section_cper->DevBridge.Function =
1539 (UINT8)json_object_get_uint64(json_object_object_get(
1540 device_id, "functionNumber"));
1541 section_cper->DevBridge.Device = (UINT8)json_object_get_uint64(
1542 json_object_object_get(device_id, "deviceNumber"));
1543 section_cper->DevBridge.Segment =
1544 (UINT16)json_object_get_uint64(json_object_object_get(
1545 device_id, "segmentNumber"));
1546 section_cper->DevBridge.PrimaryOrDeviceBus =
1547 (UINT8)json_object_get_uint64(json_object_object_get(
1548 device_id, "primaryOrDeviceBusNumber"));
1549 section_cper->DevBridge.SecondaryBus =
1550 (UINT8)json_object_get_uint64(json_object_object_get(
1551 device_id, "secondaryBusNumber"));
1552 section_cper->DevBridge.Slot.Number =
1553 (UINT16)json_object_get_uint64(json_object_object_get(
1554 device_id, "slotNumber"));
1555 add_to_valid_bitfield(&ui64Type, 3);
1556 }
1557
1558 //Bridge/control status.
1559 if (json_object_object_get_ex(section, "bridgeControlStatus", &obj)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -08001560 const json_object *bridge_control = obj;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001561 UINT32 bridge_status = (UINT16)json_object_get_uint64(
1562 json_object_object_get(bridge_control,
1563 "secondaryStatusRegister"));
1564 UINT32 control_status = (UINT16)json_object_get_uint64(
1565 json_object_object_get(bridge_control,
1566 "controlRegister"));
1567 section_cper->BridgeControlStatus =
1568 bridge_status + (control_status << 16);
1569 add_to_valid_bitfield(&ui64Type, 5);
1570 }
1571
1572 //Capability structure.
1573 int32_t decoded_len = 0;
1574 UINT8 *decoded = NULL;
1575 json_object *encoded = NULL;
1576 if (json_object_object_get_ex(section, "capabilityStructure", &obj)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -08001577 const json_object *capability = obj;
1578 encoded = json_object_object_get(capability, "data");
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001579
Erwin Tsaur8870c072025-02-28 12:57:12 -08001580 decoded = base64_decode(json_object_get_string(encoded),
1581 json_object_get_string_len(encoded),
1582 &decoded_len);
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001583 if (decoded == NULL) {
Ed Tanous50b966f2025-03-11 09:06:19 -07001584 cper_print_log(
1585 "Failed to allocate decode output buffer. \n");
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001586 } else {
1587 memcpy(section_cper->Capability.PcieCap, decoded,
1588 decoded_len);
1589 free(decoded);
1590 }
1591 add_to_valid_bitfield(&ui64Type, 6);
1592 }
1593
1594 decoded = NULL;
1595 encoded = NULL;
Lawrence Tange407b4c2022-07-21 13:54:01 +01001596 //AER capability structure.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001597 if (json_object_object_get_ex(section, "aerInfo", &obj)) {
Erwin Tsaur8870c072025-02-28 12:57:12 -08001598 const json_object *aer_info = obj;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001599 encoded = json_object_object_get(aer_info, "data");
1600 decoded_len = 0;
Ed Tanousa7d2cdd2024-07-15 11:07:27 -07001601
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001602 decoded = base64_decode(json_object_get_string(encoded),
1603 json_object_get_string_len(encoded),
1604 &decoded_len);
Ed Tanousa7d2cdd2024-07-15 11:07:27 -07001605
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001606 if (decoded == NULL) {
Ed Tanous50b966f2025-03-11 09:06:19 -07001607 cper_print_log(
1608 "Failed to allocate decode output buffer. \n");
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001609 } else {
1610 memcpy(section_cper->AerInfo.PcieAer, decoded,
1611 decoded_len);
1612 free(decoded);
1613 }
1614 add_to_valid_bitfield(&ui64Type, 7);
John Chungf8fc7052024-05-03 20:05:29 +08001615 }
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001616
Lawrence Tange407b4c2022-07-21 13:54:01 +01001617 //Miscellaneous value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -08001618 if (json_object_object_get_ex(section, "portType", &obj)) {
1619 section_cper->PortType = (UINT32)readable_pair_to_integer(obj);
1620 add_to_valid_bitfield(&ui64Type, 0);
1621 }
1622 if (json_object_object_get_ex(section, "deviceSerialNumber", &obj)) {
1623 section_cper->SerialNo = json_object_get_uint64(obj);
1624 add_to_valid_bitfield(&ui64Type, 4);
1625 }
1626
1627 section_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +01001628
Lawrence Tange407b4c2022-07-21 13:54:01 +01001629 //Write out to stream, free resources.
1630 fwrite(section_cper, sizeof(EFI_PCIE_ERROR_DATA), 1, out);
1631 fflush(out);
1632 free(section_cper);
John Chungf8fc7052024-05-03 20:05:29 +08001633}