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