Add conversion for CXL protocol/component.
diff --git a/sections/cper-section-cxl-protocol.c b/sections/cper-section-cxl-protocol.c
index d7fbf0a..c8c2c09 100644
--- a/sections/cper-section-cxl-protocol.c
+++ b/sections/cper-section-cxl-protocol.c
@@ -5,6 +5,7 @@
  * Author: Lawrence.Tang@arm.com
  **/
 #include <stdio.h>
+#include <string.h>
 #include "json.h"
 #include "b64.h"
 #include "../edk/Cper.h"
@@ -99,4 +100,85 @@
     free(encoded);
     
     return section_ir;
+}
+
+//Converts a single CXL protocol CPER-JSON section into CPER binary, outputting to the given stream.
+void ir_section_cxl_protocol_to_cper(json_object* section, FILE* out)
+{
+    EFI_CXL_PROTOCOL_ERROR_DATA* section_cper =
+        (EFI_CXL_PROTOCOL_ERROR_DATA*)calloc(1, sizeof(EFI_CXL_PROTOCOL_ERROR_DATA));
+
+    //Validation bits.
+    section_cper->ValidBits = ir_to_bitfield(json_object_object_get(section, "validationBits"), 
+        7, CXL_PROTOCOL_ERROR_VALID_BITFIELD_NAMES);
+
+    //Detecting agent type.
+    section_cper->CxlAgentType = readable_pair_to_integer(json_object_object_get(section, "agentType"));
+
+    //Based on the agent type, set the address.
+    json_object* address = json_object_object_get(section, "cxlAgentAddress");
+    if (section_cper->CxlAgentType == CXL_PROTOCOL_ERROR_DEVICE_AGENT)
+    {
+        //Address is split by function, device, bus & segment.
+        UINT64 function = json_object_get_uint64(json_object_object_get(address, "functionNumber"));
+        UINT64 device = json_object_get_uint64(json_object_object_get(address, "deviceNumber"));
+        UINT64 bus = json_object_get_uint64(json_object_object_get(address, "busNumber"));
+        UINT64 segment = json_object_get_uint64(json_object_object_get(address, "segmentNumber"));
+        section_cper->CxlAgentAddress.DeviceAddress.FunctionNumber = function;
+        section_cper->CxlAgentAddress.DeviceAddress.DeviceNumber = device;
+        section_cper->CxlAgentAddress.DeviceAddress.BusNumber = bus;
+        section_cper->CxlAgentAddress.DeviceAddress.SegmentNumber = segment;
+    }
+    else if (section_cper->CxlAgentType == CXL_PROTOCOL_ERROR_HOST_DOWNSTREAM_PORT_AGENT)
+    {
+        //Plain RCRB base address.
+        section_cper->CxlAgentAddress.PortRcrbBaseAddress = 
+            json_object_get_uint64(json_object_object_get(address, "value"));
+    }
+
+    //Device ID information.
+    json_object* device_id = json_object_object_get(section, "deviceID");
+    section_cper->DeviceId.VendorId = json_object_get_uint64(json_object_object_get(device_id, "vendorID"));
+    section_cper->DeviceId.DeviceId = json_object_get_uint64(json_object_object_get(device_id, "deviceID"));
+    section_cper->DeviceId.SubsystemVendorId = 
+        json_object_get_uint64(json_object_object_get(device_id, "subsystemVendorID"));
+    section_cper->DeviceId.SubsystemDeviceId = 
+        json_object_get_uint64(json_object_object_get(device_id, "subsystemDeviceID"));
+    section_cper->DeviceId.ClassCode = json_object_get_uint64(json_object_object_get(device_id, "classCode"));
+    section_cper->DeviceId.SlotNumber = json_object_get_uint64(json_object_object_get(device_id, "slotNumber"));
+
+    //If CXL 1.1 device, the serial number & PCI capability structure.
+    if (section_cper->CxlAgentType == CXL_PROTOCOL_ERROR_DEVICE_AGENT)
+    {
+        section_cper->DeviceSerial = json_object_get_uint64(json_object_object_get(section, "deviceSerial"));
+
+        json_object* encoded = json_object_object_get(section, "capabilityStructure");
+        char* decoded = b64_decode(json_object_get_string(encoded), json_object_get_string_len(encoded));
+        memcpy(section_cper->CapabilityStructure.PcieCap, decoded, 60);
+        free(decoded);
+    }
+
+    //DVSEC length & error log length.
+    section_cper->CxlDvsecLength = (UINT16)json_object_get_int(json_object_object_get(section, "dvsecLength"));
+    section_cper->CxlErrorLogLength = (UINT16)json_object_get_int(json_object_object_get(section, "errorLogLength"));
+
+    //Write header to stream.
+    fwrite(section_cper, sizeof(section_cper), 1, out);
+    fflush(out);
+
+    //DVSEC out to stream.
+    json_object* encoded = json_object_object_get(section, "cxlDVSEC");
+    char* decoded = b64_decode(json_object_get_string(encoded), json_object_get_string_len(encoded));
+    fwrite(decoded, section_cper->CxlDvsecLength, 1, out);
+    fflush(out);
+    free(decoded);
+
+    //Error log out to stream.
+    encoded = json_object_object_get(section, "cxlErrorLog");
+    decoded = b64_decode(json_object_get_string(encoded), json_object_get_string_len(encoded));
+    fwrite(decoded, section_cper->CxlErrorLogLength, 1, out);
+    fflush(out);
+    free(decoded);
+
+    free(section_cper);
 }
\ No newline at end of file