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