Add PCIe error section parsing support.
diff --git a/cper-parse.c b/cper-parse.c
index d20a66f..ded404c 100644
--- a/cper-parse.c
+++ b/cper-parse.c
@@ -14,6 +14,7 @@
 #include "sections/cper-section-ia32x64.h"
 #include "sections/cper-section-arm.h"
 #include "sections/cper-section-memory.h"
+#include "sections/cper-section-pcie.h"
 
 //Private pre-definitions.
 json_object* cper_header_to_ir(EFI_COMMON_ERROR_RECORD_HEADER* header);
@@ -311,8 +312,8 @@
         result = cper_section_platform_memory_to_ir(section, descriptor);
     else if (guid_equal(&descriptor->SectionType, &gEfiPlatformMemoryError2SectionGuid))
         result = cper_section_platform_memory2_to_ir(section, descriptor);
-    // if (guid_equal(&descriptor->SectionType, &gEfiPcieErrorSectionGuid))
-    //     result = cper_section_pcie_to_ir(section);
+    else if (guid_equal(&descriptor->SectionType, &gEfiPcieErrorSectionGuid))
+        result = cper_section_pcie_to_ir(section, descriptor);
     // if (guid_equal(&descriptor->SectionType, &gEfiFirmwareErrorSectionGuid))
     //     result = cper_section_firmware_error_to_ir(section);
     // if (guid_equal(&descriptor->SectionType, &gEfiPciBusErrorSectionGuid))
diff --git a/cper-utils.c b/cper-utils.c
index c29b9df..e0823b2 100644
--- a/cper-utils.c
+++ b/cper-utils.c
@@ -170,4 +170,10 @@
     }
 
     return 1;
+}
+
+//Converts the given BCD byte to a standard integer.
+int bcd_to_int(UINT8 bcd)
+{
+    return ((bcd & 0xF0) >> 4) * 10 + (bcd & 0x0F);
 }
\ No newline at end of file
diff --git a/cper-utils.h b/cper-utils.h
index f7878d4..07ad20f 100644
--- a/cper-utils.h
+++ b/cper-utils.h
@@ -14,6 +14,7 @@
 const char* severity_to_string(UINT8 severity);
 void guid_to_string(char* out, EFI_GUID* guid);
 int guid_equal(EFI_GUID* a, EFI_GUID* b);
+int bcd_to_int(UINT8 bcd);
 
 //The available severity types for CPER.
 extern const char* CPER_SEVERITY_TYPES[4];
diff --git a/edk/Cper.h b/edk/Cper.h
index a73c6eb..4eb470d 100644
--- a/edk/Cper.h
+++ b/edk/Cper.h
@@ -739,271 +739,6 @@
   UINT64    Resv1           : 50;

 } EFI_IA32_X64_VALID_BITS;

 

-

-///

-/// ARM Processor Error Record

-///

-typedef struct {

-  UINT32    ValidFields;

-  UINT16    ErrInfoNum;

-  UINT16    ContextInfoNum;

-  UINT32    SectionLength;

-  UINT32  ErrorAffinityLevel;

-  UINT64  MPIDR_EL1;

-  UINT64  MIDR_EL1;

-  UINT32 RunningState;

-  UINT32 PsciState;

-} EFI_ARM_ERROR_RECORD;

-

-///

-/// ARM Processor Error Information Structure

-///

-typedef struct {

-  UINT64 ValidationBits : 16;

-  UINT64 TransactionType : 2;

-  UINT64 Operation : 4;

-  UINT64 Level : 3;

-  UINT64 ProcessorContextCorrupt : 1;

-  UINT64 Corrected : 1;

-  UINT64 PrecisePC : 1;

-  UINT64 RestartablePC : 1;

-  UINT64 Reserved : 34;

-} EFI_ARM_CACHE_ERROR_STRUCTURE;

-

-typedef struct {

-  UINT64 ValidationBits : 16;

-  UINT64 TransactionType : 2;

-  UINT64 Operation : 4;

-  UINT64 Level : 3;

-  UINT64 ProcessorContextCorrupt : 1;

-  UINT64 Corrected : 1;

-  UINT64 PrecisePC : 1;

-  UINT64 RestartablePC : 1;

-  UINT64 Reserved : 34;

-} EFI_ARM_TLB_ERROR_STRUCTURE;

-

-typedef struct {

-  UINT64 ValidationBits : 16;

-  UINT64 TransactionType : 2;

-  UINT64 Operation : 4;

-  UINT64 Level : 3;

-  UINT64 ProcessorContextCorrupt : 1;

-  UINT64 Corrected : 1;

-  UINT64 PrecisePC : 1;

-  UINT64 RestartablePC : 1;

-  UINT64 ParticipationType : 2;

-  UINT64 TimeOut : 1;

-  UINT64 AddressSpace : 2;

-  UINT64 MemoryAddressAttributes : 8;

-  UINT64 AccessMode : 1;

-  UINT64 Reserved : 19;

-} EFI_ARM_BUS_ERROR_STRUCTURE;

-

-typedef union {

-  EFI_ARM_CACHE_ERROR_STRUCTURE CacheError;

-  EFI_ARM_TLB_ERROR_STRUCTURE TlbError;

-  EFI_ARM_BUS_ERROR_STRUCTURE BusError;

-} EFI_ARM_ERROR_INFORMATION_STRUCTURE;

-

-typedef struct {

-  UINT8 Version;

-  UINT8 Length;

-  UINT16 ValidationBits;

-  UINT8 Type;

-  UINT16 MultipleError;

-  UINT8 Flags;

-  EFI_ARM_ERROR_INFORMATION_STRUCTURE ErrorInformation;

-  UINT64 VirtualFaultAddress;

-  UINT64 PhysicalFaultAddress;

-} EFI_ARM_ERROR_INFORMATION_ENTRY;

-

-///

-/// ARM Processor Context Information Structure

-///

-typedef struct {

-  UINT16 Version;

-  UINT16 RegisterContextType;

-  UINT32 RegisterArraySize;

-} EFI_ARM_CONTEXT_INFORMATION_HEADER;

-

-///

-/// ARM Processor Context Register Types

-///

-#define EFI_ARM_CONTEXT_TYPE_AARCH32_GPR 0

-#define EFI_ARM_CONTEXT_TYPE_AARCH32_EL1 1

-#define EFI_ARM_CONTEXT_TYPE_AARCH32_EL2 2

-#define EFI_ARM_CONTEXT_TYPE_AARCH32_SECURE 3

-#define EFI_ARM_CONTEXT_TYPE_AARCH64_GPR 4

-#define EFI_ARM_CONTEXT_TYPE_AARCH64_EL1 5

-#define EFI_ARM_CONTEXT_TYPE_AARCH64_EL2 6

-#define EFI_ARM_CONTEXT_TYPE_AARCH64_EL3 7

-#define EFI_ARM_CONTEXT_TYPE_MISC 8

-

-typedef struct {

-  UINT32 R0;

-  UINT32 R1;

-  UINT32 R2;

-  UINT32 R3;

-  UINT32 R4;

-  UINT32 R5;

-  UINT32 R6;

-  UINT32 R7;

-  UINT32 R8;

-  UINT32 R9;

-  UINT32 R10;

-  UINT32 R11;

-  UINT32 R12;

-  UINT32 R13_sp;

-  UINT32 R14_lr;

-  UINT32 R15_pc;

-} EFI_ARM_V8_AARCH32_GPR;

-

-typedef struct {

-  UINT32 Dfar;

-  UINT32 Dfsr;

-  UINT32 Ifar;

-  UINT32 Isr;

-  UINT32 Mair0;

-  UINT32 Mair1;

-  UINT32 Midr;

-  UINT32 Mpidr;

-  UINT32 Nmrr;

-  UINT32 Prrr;

-  UINT32 Sctlr_Ns;

-  UINT32 Spsr;

-  UINT32 Spsr_Abt;

-  UINT32 Spsr_Fiq;

-  UINT32 Spsr_Irq;

-  UINT32 Spsr_Svc;

-  UINT32 Spsr_Und;

-  UINT32 Tpidrprw;

-  UINT32 Tpidruro;

-  UINT32 Tpidrurw;

-  UINT32 Ttbcr;

-  UINT32 Ttbr0;

-  UINT32 Ttbr1;

-  UINT32 Dacr;

-} EFI_ARM_AARCH32_EL1_CONTEXT_REGISTERS;

-

-typedef struct {

-  UINT32 Elr_Hyp;

-  UINT32 Hamair0;

-  UINT32 Hamair1;

-  UINT32 Hcr;

-  UINT32 Hcr2;

-  UINT32 Hdfar;

-  UINT32 Hifar;

-  UINT32 Hpfar;

-  UINT32 Hsr;

-  UINT32 Htcr;

-  UINT32 Htpidr;

-  UINT32 Httbr;

-  UINT32 Spsr_Hyp;

-  UINT32 Vtcr;

-  UINT32 Vttbr;

-  UINT32 Dacr32_El2;

-} EFI_ARM_AARCH32_EL2_CONTEXT_REGISTERS;

-

-typedef struct {

-  UINT32 Sctlr_S;

-  UINT32 Spsr_Mon;

-} EFI_ARM_AARCH32_SECURE_CONTEXT_REGISTERS;

-

-typedef struct {

-  UINT64 X0;

-  UINT64 X1;

-  UINT64 X2;

-  UINT64 X3;

-  UINT64 X4;

-  UINT64 X5;

-  UINT64 X6;

-  UINT64 X7;

-  UINT64 X8;

-  UINT64 X9;

-  UINT64 X10;

-  UINT64 X11;

-  UINT64 X12;

-  UINT64 X13;

-  UINT64 X14;

-  UINT64 X15;

-  UINT64 X16;

-  UINT64 X17;

-  UINT64 X18;

-  UINT64 X19;

-  UINT64 X20;

-  UINT64 X21;

-  UINT64 X22;

-  UINT64 X23;

-  UINT64 X24;

-  UINT64 X25;

-  UINT64 X26;

-  UINT64 X27;

-  UINT64 X28;

-  UINT64 X29;

-  UINT64 X30;

-  UINT64 Sp;

-} EFI_ARM_V8_AARCH64_GPR;

-

-typedef struct {

-  UINT64 Elr_El1;

-  UINT64 Esr_El1;

-  UINT64 Far_El1;

-  UINT64 Isr_El1;

-  UINT64 Mair_El1;

-  UINT64 Midr_El1;

-  UINT64 Mpidr_El1;

-  UINT64 Sctlr_El1;

-  UINT64 Sp_El0;

-  UINT64 Sp_El1;

-  UINT64 Spsr_El1;

-  UINT64 Tcr_El1;

-  UINT64 Tpidr_El0;

-  UINT64 Tpidr_El1;

-  UINT64 Tpidrro_El0;

-  UINT64 Ttbr0_El1;

-  UINT64 Ttbr1_El1;

-} EFI_ARM_AARCH64_EL1_CONTEXT_REGISTERS;

-

-typedef struct {

-  UINT64 Elr_El2;

-  UINT64 Esr_El2;

-  UINT64 Far_El2;

-  UINT64 Hacr_El2;

-  UINT64 Hcr_El2;

-  UINT64 Hpfar_El2;

-  UINT64 Mair_El2;

-  UINT64 Sctlr_El2;

-  UINT64 Sp_El2;

-  UINT64 Spsr_El2;

-  UINT64 Tcr_El2;

-  UINT64 Tpidr_El2;

-  UINT64 Ttbr0_El2;

-  UINT64 Vtcr_El2;

-  UINT64 Vttbr_El2;

-} EFI_ARM_AARCH64_EL2_CONTEXT_REGISTERS;

-

-typedef struct {

-  UINT64 Elr_El3;

-  UINT64 Esr_El3;

-  UINT64 Far_El3;

-  UINT64 Mair_El3;

-  UINT64 Sctlr_El3;

-  UINT64 Sp_El3;

-  UINT64 Spsr_El3;

-  UINT64 Tcr_El3;

-  UINT64 Tpidr_El3;

-  UINT64 Ttbr0_El3;

-} EFI_ARM_AARCH64_EL3_CONTEXT_REGISTERS;

-

-typedef struct {

-  UINT64 MrsOp2 : 3;

-  UINT64 MrsCrm : 4;

-  UINT64 MrsCrn : 4;

-  UINT64 MrsOp1 : 3;

-  UINT64 MrsO0 : 1;

-  UINT64 Value : 64;

-} EFI_ARM_MISC_CONTEXT_REGISTER;

-

 ///

 /// Error Status Fields

 ///

diff --git a/sections/cper-section-arm.h b/sections/cper-section-arm.h
index 5e1c17e..a283efd 100644
--- a/sections/cper-section-arm.h
+++ b/sections/cper-section-arm.h
@@ -60,6 +60,270 @@
 #define ARM_AARCH64_EL3_REGISTER_NAMES (const char*[]){"elr_el3", "esr_el3", "far_el3", "mair_el3", "sctlr_el3", \
     "sp_el3", "spsr_el3", "tcr_el3", "tpidr_el3", "ttbr0_el3"}
 
+///
+/// ARM Processor Error Record
+///
+typedef struct {
+  UINT32    ValidFields;
+  UINT16    ErrInfoNum;
+  UINT16    ContextInfoNum;
+  UINT32    SectionLength;
+  UINT32  ErrorAffinityLevel;
+  UINT64  MPIDR_EL1;
+  UINT64  MIDR_EL1;
+  UINT32 RunningState;
+  UINT32 PsciState;
+} EFI_ARM_ERROR_RECORD;
+
+///
+/// ARM Processor Error Information Structure
+///
+typedef struct {
+  UINT64 ValidationBits : 16;
+  UINT64 TransactionType : 2;
+  UINT64 Operation : 4;
+  UINT64 Level : 3;
+  UINT64 ProcessorContextCorrupt : 1;
+  UINT64 Corrected : 1;
+  UINT64 PrecisePC : 1;
+  UINT64 RestartablePC : 1;
+  UINT64 Reserved : 34;
+} EFI_ARM_CACHE_ERROR_STRUCTURE;
+
+typedef struct {
+  UINT64 ValidationBits : 16;
+  UINT64 TransactionType : 2;
+  UINT64 Operation : 4;
+  UINT64 Level : 3;
+  UINT64 ProcessorContextCorrupt : 1;
+  UINT64 Corrected : 1;
+  UINT64 PrecisePC : 1;
+  UINT64 RestartablePC : 1;
+  UINT64 Reserved : 34;
+} EFI_ARM_TLB_ERROR_STRUCTURE;
+
+typedef struct {
+  UINT64 ValidationBits : 16;
+  UINT64 TransactionType : 2;
+  UINT64 Operation : 4;
+  UINT64 Level : 3;
+  UINT64 ProcessorContextCorrupt : 1;
+  UINT64 Corrected : 1;
+  UINT64 PrecisePC : 1;
+  UINT64 RestartablePC : 1;
+  UINT64 ParticipationType : 2;
+  UINT64 TimeOut : 1;
+  UINT64 AddressSpace : 2;
+  UINT64 MemoryAddressAttributes : 8;
+  UINT64 AccessMode : 1;
+  UINT64 Reserved : 19;
+} EFI_ARM_BUS_ERROR_STRUCTURE;
+
+typedef union {
+  EFI_ARM_CACHE_ERROR_STRUCTURE CacheError;
+  EFI_ARM_TLB_ERROR_STRUCTURE TlbError;
+  EFI_ARM_BUS_ERROR_STRUCTURE BusError;
+} EFI_ARM_ERROR_INFORMATION_STRUCTURE;
+
+typedef struct {
+  UINT8 Version;
+  UINT8 Length;
+  UINT16 ValidationBits;
+  UINT8 Type;
+  UINT16 MultipleError;
+  UINT8 Flags;
+  EFI_ARM_ERROR_INFORMATION_STRUCTURE ErrorInformation;
+  UINT64 VirtualFaultAddress;
+  UINT64 PhysicalFaultAddress;
+} EFI_ARM_ERROR_INFORMATION_ENTRY;
+
+///
+/// ARM Processor Context Information Structure
+///
+typedef struct {
+  UINT16 Version;
+  UINT16 RegisterContextType;
+  UINT32 RegisterArraySize;
+} EFI_ARM_CONTEXT_INFORMATION_HEADER;
+
+///
+/// ARM Processor Context Register Types
+///
+#define EFI_ARM_CONTEXT_TYPE_AARCH32_GPR 0
+#define EFI_ARM_CONTEXT_TYPE_AARCH32_EL1 1
+#define EFI_ARM_CONTEXT_TYPE_AARCH32_EL2 2
+#define EFI_ARM_CONTEXT_TYPE_AARCH32_SECURE 3
+#define EFI_ARM_CONTEXT_TYPE_AARCH64_GPR 4
+#define EFI_ARM_CONTEXT_TYPE_AARCH64_EL1 5
+#define EFI_ARM_CONTEXT_TYPE_AARCH64_EL2 6
+#define EFI_ARM_CONTEXT_TYPE_AARCH64_EL3 7
+#define EFI_ARM_CONTEXT_TYPE_MISC 8
+
+typedef struct {
+  UINT32 R0;
+  UINT32 R1;
+  UINT32 R2;
+  UINT32 R3;
+  UINT32 R4;
+  UINT32 R5;
+  UINT32 R6;
+  UINT32 R7;
+  UINT32 R8;
+  UINT32 R9;
+  UINT32 R10;
+  UINT32 R11;
+  UINT32 R12;
+  UINT32 R13_sp;
+  UINT32 R14_lr;
+  UINT32 R15_pc;
+} EFI_ARM_V8_AARCH32_GPR;
+
+typedef struct {
+  UINT32 Dfar;
+  UINT32 Dfsr;
+  UINT32 Ifar;
+  UINT32 Isr;
+  UINT32 Mair0;
+  UINT32 Mair1;
+  UINT32 Midr;
+  UINT32 Mpidr;
+  UINT32 Nmrr;
+  UINT32 Prrr;
+  UINT32 Sctlr_Ns;
+  UINT32 Spsr;
+  UINT32 Spsr_Abt;
+  UINT32 Spsr_Fiq;
+  UINT32 Spsr_Irq;
+  UINT32 Spsr_Svc;
+  UINT32 Spsr_Und;
+  UINT32 Tpidrprw;
+  UINT32 Tpidruro;
+  UINT32 Tpidrurw;
+  UINT32 Ttbcr;
+  UINT32 Ttbr0;
+  UINT32 Ttbr1;
+  UINT32 Dacr;
+} EFI_ARM_AARCH32_EL1_CONTEXT_REGISTERS;
+
+typedef struct {
+  UINT32 Elr_Hyp;
+  UINT32 Hamair0;
+  UINT32 Hamair1;
+  UINT32 Hcr;
+  UINT32 Hcr2;
+  UINT32 Hdfar;
+  UINT32 Hifar;
+  UINT32 Hpfar;
+  UINT32 Hsr;
+  UINT32 Htcr;
+  UINT32 Htpidr;
+  UINT32 Httbr;
+  UINT32 Spsr_Hyp;
+  UINT32 Vtcr;
+  UINT32 Vttbr;
+  UINT32 Dacr32_El2;
+} EFI_ARM_AARCH32_EL2_CONTEXT_REGISTERS;
+
+typedef struct {
+  UINT32 Sctlr_S;
+  UINT32 Spsr_Mon;
+} EFI_ARM_AARCH32_SECURE_CONTEXT_REGISTERS;
+
+typedef struct {
+  UINT64 X0;
+  UINT64 X1;
+  UINT64 X2;
+  UINT64 X3;
+  UINT64 X4;
+  UINT64 X5;
+  UINT64 X6;
+  UINT64 X7;
+  UINT64 X8;
+  UINT64 X9;
+  UINT64 X10;
+  UINT64 X11;
+  UINT64 X12;
+  UINT64 X13;
+  UINT64 X14;
+  UINT64 X15;
+  UINT64 X16;
+  UINT64 X17;
+  UINT64 X18;
+  UINT64 X19;
+  UINT64 X20;
+  UINT64 X21;
+  UINT64 X22;
+  UINT64 X23;
+  UINT64 X24;
+  UINT64 X25;
+  UINT64 X26;
+  UINT64 X27;
+  UINT64 X28;
+  UINT64 X29;
+  UINT64 X30;
+  UINT64 Sp;
+} EFI_ARM_V8_AARCH64_GPR;
+
+typedef struct {
+  UINT64 Elr_El1;
+  UINT64 Esr_El1;
+  UINT64 Far_El1;
+  UINT64 Isr_El1;
+  UINT64 Mair_El1;
+  UINT64 Midr_El1;
+  UINT64 Mpidr_El1;
+  UINT64 Sctlr_El1;
+  UINT64 Sp_El0;
+  UINT64 Sp_El1;
+  UINT64 Spsr_El1;
+  UINT64 Tcr_El1;
+  UINT64 Tpidr_El0;
+  UINT64 Tpidr_El1;
+  UINT64 Tpidrro_El0;
+  UINT64 Ttbr0_El1;
+  UINT64 Ttbr1_El1;
+} EFI_ARM_AARCH64_EL1_CONTEXT_REGISTERS;
+
+typedef struct {
+  UINT64 Elr_El2;
+  UINT64 Esr_El2;
+  UINT64 Far_El2;
+  UINT64 Hacr_El2;
+  UINT64 Hcr_El2;
+  UINT64 Hpfar_El2;
+  UINT64 Mair_El2;
+  UINT64 Sctlr_El2;
+  UINT64 Sp_El2;
+  UINT64 Spsr_El2;
+  UINT64 Tcr_El2;
+  UINT64 Tpidr_El2;
+  UINT64 Ttbr0_El2;
+  UINT64 Vtcr_El2;
+  UINT64 Vttbr_El2;
+} EFI_ARM_AARCH64_EL2_CONTEXT_REGISTERS;
+
+typedef struct {
+  UINT64 Elr_El3;
+  UINT64 Esr_El3;
+  UINT64 Far_El3;
+  UINT64 Mair_El3;
+  UINT64 Sctlr_El3;
+  UINT64 Sp_El3;
+  UINT64 Spsr_El3;
+  UINT64 Tcr_El3;
+  UINT64 Tpidr_El3;
+  UINT64 Ttbr0_El3;
+} EFI_ARM_AARCH64_EL3_CONTEXT_REGISTERS;
+
+typedef struct {
+  UINT64 MrsOp2 : 3;
+  UINT64 MrsCrm : 4;
+  UINT64 MrsCrn : 4;
+  UINT64 MrsOp1 : 3;
+  UINT64 MrsO0 : 1;
+  UINT64 Value : 64;
+} EFI_ARM_MISC_CONTEXT_REGISTER;
+
 json_object* cper_section_arm_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor);
 
 #endif
\ No newline at end of file
diff --git a/sections/cper-section-pcie.c b/sections/cper-section-pcie.c
new file mode 100644
index 0000000..4298889
--- /dev/null
+++ b/sections/cper-section-pcie.c
@@ -0,0 +1,76 @@
+/**
+ * Describes functions for converting PCIe CPER sections from binary and JSON format
+ * into an intermediate format.
+ * 
+ * Author: Lawrence.Tang@arm.com
+ **/
+#include <stdio.h>
+#include "json.h"
+#include "../edk/Cper.h"
+#include "../cper-utils.h"
+#include "cper-section-pcie.h"
+
+//Converts a single PCIe CPER section into JSON IR.
+json_object* cper_section_pcie_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor)
+{
+    EFI_PCIE_ERROR_DATA* pcie_error = (EFI_PCIE_ERROR_DATA*)section;
+    json_object* section_ir = json_object_new_object();
+
+    //Validation bits.
+    json_object* validation = bitfield_to_ir(pcie_error->ValidFields, 8, PCIE_ERROR_VALID_BITFIELD_NAMES);
+    json_object_object_add(section_ir, "validationBits", validation);
+
+    //Port type.
+    json_object* port_type = integer_to_readable_pair(pcie_error->PortType, 9,
+        PCIE_ERROR_PORT_TYPES_KEYS,
+        PCIE_ERROR_PORT_TYPES_VALUES,
+        "Unknown");
+    json_object_object_add(section_ir, "portType", port_type);
+
+    //Version, provided each half in BCD.
+    json_object* version = json_object_new_object();
+    json_object_object_add(version, "minor", json_object_new_int(bcd_to_int(pcie_error->Version & 0xFF)));
+    json_object_object_add(version, "major", json_object_new_int(bcd_to_int(pcie_error->Version >> 8)));
+    json_object_object_add(section_ir, "version", version);
+
+    //Command & status.
+    json_object* command_status = json_object_new_object();
+    json_object_object_add(command_status, "commandRegister", json_object_new_uint64(pcie_error->CommandStatus & 0xFFFF));
+    json_object_object_add(command_status, "statusRegister", json_object_new_uint64(pcie_error->CommandStatus >> 16));
+    json_object_object_add(section_ir, "commandStatus", command_status);
+
+    //PCIe Device ID.
+    json_object* device_id = json_object_new_object();
+    UINT64 class_id =  pcie_error->DevBridge.ClassCode[0] + 
+                      (pcie_error->DevBridge.ClassCode[1] << 8) +
+                      (pcie_error->DevBridge.ClassCode[2] << 16);
+    json_object_object_add(device_id, "vendorID", json_object_new_uint64(pcie_error->DevBridge.VendorId));
+    json_object_object_add(device_id, "deviceID", json_object_new_uint64(pcie_error->DevBridge.DeviceId));
+    json_object_object_add(device_id, "classCode", json_object_new_uint64(class_id));
+    json_object_object_add(device_id, "functionNumber", json_object_new_uint64(pcie_error->DevBridge.Function));
+    json_object_object_add(device_id, "deviceNumber", json_object_new_uint64(pcie_error->DevBridge.Device));
+    json_object_object_add(device_id, "segmentNumber", json_object_new_uint64(pcie_error->DevBridge.Segment));
+    json_object_object_add(device_id, "primaryOrDeviceBusNumber", json_object_new_uint64(pcie_error->DevBridge.PrimaryOrDeviceBus));
+    json_object_object_add(device_id, "secondaryBusNumber", json_object_new_uint64(pcie_error->DevBridge.SecondaryBus));
+    json_object_object_add(device_id, "slotNumber", json_object_new_uint64(pcie_error->DevBridge.Slot.Number));
+    json_object_object_add(section_ir, "deviceID", device_id);
+
+    //Device serial number.
+    json_object_object_add(section_ir, "deviceSerialNumber", json_object_new_uint64(pcie_error->SerialNo));
+
+    //Bridge control status.
+    json_object* bridge_control_status = json_object_new_object();
+    json_object_object_add(bridge_control_status, "secondaryStatusRegister", 
+        json_object_new_uint64(pcie_error->BridgeControlStatus & 0xFFFF));
+    json_object_object_add(bridge_control_status, "controlRegister", 
+        json_object_new_uint64(pcie_error->BridgeControlStatus >> 16));
+    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
+
+    //AER information.
+    //todo: See the PCIe 2.0 Base Specification to implement this.
+
+    return section_ir;
+}
\ No newline at end of file
diff --git a/sections/cper-section-pcie.h b/sections/cper-section-pcie.h
new file mode 100644
index 0000000..4a1713e
--- /dev/null
+++ b/sections/cper-section-pcie.h
@@ -0,0 +1,17 @@
+#ifndef CPER_SECTION_PCIE_H
+#define CPER_SECTION_PCIE_H
+
+#include "json.h"
+#include "../edk/Cper.h"
+
+#define PCIE_ERROR_VALID_BITFIELD_NAMES (const char*[]) {"portTypeValid", "versionValid", "commandStatusValid", \
+    "deviceIDValid", "deviceSerialNumberValid", "bridgeControlStatusValid", "capabilityStructureStatusValid", \
+    "aerInfoValid"}
+#define PCIE_ERROR_PORT_TYPES_KEYS (int []){0, 1, 4, 5, 6, 7, 8, 9, 10}
+#define PCIE_ERROR_PORT_TYPES_VALUES (const char*[]){"PCI Express End Point", "Legacy PCI End Point Device", \
+    "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"}
+
+json_object* cper_section_pcie_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor);
+
+#endif
\ No newline at end of file