Add support for PCIe AER parsing.
diff --git a/sections/cper-section-ipf.h b/sections/cper-section-ipf.h
index 2ba4182..ccd016c 100644
--- a/sections/cper-section-ipf.h
+++ b/sections/cper-section-ipf.h
@@ -38,8 +38,8 @@
     UINT64 ValidBits;
     UINT64 ModCheckInfo;
     UINT64 ModTargetId;
-    UINT64 ModRequestorId; //todo: Which way around are these? Spec has a typo
-    UINT64 ModResponderId;
+    UINT64 ModRequestorId; //NOTE: The Intel Itanium specification contains a typo which makes the order
+    UINT64 ModResponderId; // of these two fields undefined. This is a best guess and could be wrong.
     UINT64 ModPreciseIp;
 } EFI_IPF_MOD_ERROR_INFO;
 
diff --git a/sections/cper-section-pcie.c b/sections/cper-section-pcie.c
index 6074839..3e3e502 100644
--- a/sections/cper-section-pcie.c
+++ b/sections/cper-section-pcie.c
@@ -6,6 +6,7 @@
  **/
 #include <stdio.h>
 #include "json.h"
+#include "b64.h"
 #include "../edk/Cper.h"
 #include "../cper-utils.h"
 #include "cper-section-pcie.h"
@@ -67,10 +68,49 @@
     json_object_object_add(section_ir, "bridgeControlStatus", bridge_control_status);
 
     //Capability structure.
-    //todo: See Figure 6-9 of the PCIe 2.0 Base Specification to implement this
+    //The PCIe capability structure provided here could either be PCIe 1.1 Capability Structure 
+    //(36-byte, padded to 60 bytes) or PCIe 2.0 Capability Structure (60-byte). There does not seem
+    //to be a way to differentiate these, so this is left as a b64 dump.
+    char* encoded = b64_encode((unsigned char*)pcie_error->Capability.PcieCap, 60);
+    json_object* capability = json_object_new_object();
+    json_object_object_add(capability, "data", json_object_new_string(encoded));
+    free(encoded);
+    json_object_object_add(section_ir, "capabilityStructure", capability);
 
     //AER information.
-    //todo: See the PCIe 2.0 Base Specification to implement this.
+    json_object* aer_capability_ir = json_object_new_object();
+    EFI_PCIE_ADV_ERROR_EXT_CAPABILITY* aer_capability = (EFI_PCIE_ADV_ERROR_EXT_CAPABILITY*)pcie_error->AerInfo.PcieAer;
+    json_object_object_add(aer_capability_ir, "capabilityID", 
+        json_object_new_uint64(aer_capability->Header.PcieExtendedCapabilityId));
+    json_object_object_add(aer_capability_ir, "capabilityVersion", 
+        json_object_new_uint64(aer_capability->Header.CapabilityVersion));
+    json_object_object_add(aer_capability_ir, "uncorrectableErrorStatusRegister", 
+        json_object_new_uint64(aer_capability->UncorrectableErrorStatusReg));
+    json_object_object_add(aer_capability_ir, "uncorrectableErrorMaskRegister", 
+        json_object_new_uint64(aer_capability->UncorrectableErrorMaskReg));
+    json_object_object_add(aer_capability_ir, "uncorrectableErrorSeverityRegister", 
+        json_object_new_uint64(aer_capability->UncorrectableErrorSeverityReg));
+    json_object_object_add(aer_capability_ir, "correctableErrorStatusRegister", 
+        json_object_new_uint64(aer_capability->CorrectableErrorStatusReg));
+    json_object_object_add(aer_capability_ir, "correctableErrorMaskRegister", 
+        json_object_new_uint64(aer_capability->CorrectableErrorMaskReg));
+    json_object_object_add(aer_capability_ir, "aeccReg", json_object_new_uint64(aer_capability->AeccReg));
 
+    //Header log register (b64).
+    encoded = b64_encode((unsigned char*)aer_capability->HeaderLogReg, 16);
+    json_object_object_add(aer_capability_ir, "headerLogRegister", json_object_new_string(encoded));
+    free(encoded);
+
+    //Remaining AER fields.
+    json_object_object_add(aer_capability_ir, "rootErrorCommand", 
+        json_object_new_uint64(aer_capability->RootErrorCommand));
+    json_object_object_add(aer_capability_ir, "rootErrorStatus", 
+        json_object_new_uint64(aer_capability->RootErrorStatus));
+    json_object_object_add(aer_capability_ir, "errorSourceIDRegister", 
+        json_object_new_uint64(aer_capability->ErrorSourceIdReg));
+    json_object_object_add(aer_capability_ir, "correctableErrorSourceIDRegister", 
+        json_object_new_uint64(aer_capability->CorrectableSourceIdReg));
+
+    json_object_object_add(section_ir, "aerInfo", aer_capability_ir);
     return section_ir;
 }
\ No newline at end of file
diff --git a/sections/cper-section-pcie.h b/sections/cper-section-pcie.h
index 4a1713e..987fa6c 100644
--- a/sections/cper-section-pcie.h
+++ b/sections/cper-section-pcie.h
@@ -12,6 +12,27 @@
     "Root Port", "Upstream Switch Port", "Downstream Switch Port", "PCI Express to PCI/PCI-X Bridge", \
     "PCI/PCI-X Bridge to PCI Express Bridge", "Root Complex Integrated Endpoint Device", "Root Complex Event Collector"}
 
+typedef struct {
+    UINT64 PcieExtendedCapabilityId : 16;
+    UINT64 CapabilityVersion : 4;
+    UINT64 NextCapabilityOffset : 12; 
+} EFI_PCIE_ADV_ERROR_EXT_CAPABILITY_HEADER;
+
+typedef struct {
+    EFI_PCIE_ADV_ERROR_EXT_CAPABILITY_HEADER Header;
+    UINT32 UncorrectableErrorStatusReg;
+    UINT32 UncorrectableErrorMaskReg;
+    UINT32 UncorrectableErrorSeverityReg;
+    UINT32 CorrectableErrorStatusReg;
+    UINT32 CorrectableErrorMaskReg;
+    UINT32 AeccReg;
+    UINT8 HeaderLogReg[16];
+    UINT32 RootErrorCommand;
+    UINT32 RootErrorStatus;
+    UINT16 CorrectableSourceIdReg;
+    UINT16 ErrorSourceIdReg;
+} EFI_PCIE_ADV_ERROR_EXT_CAPABILITY;
+
 json_object* cper_section_pcie_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor);
 
 #endif
\ No newline at end of file