Add CXL component GUIDs, b64 dumps for unknown.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 134d7cf..d1a284a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,7 +14,14 @@
GIT_REPOSITORY https://github.com/json-c/json-c.git
GIT_TAG d28ac67dde77566f53a97f22b4ea7cb36afe6582 # 4/6/2022
)
-FetchContent_MakeAvailable(json-c)
+
+# Fetch b64-c from git repository.
+FetchContent_Declare(
+ b64-c
+ GIT_REPOSITORY https://github.com/jwerle/b64.c.git
+ GIT_TAG c33188cd541f19b072ee4988d8224ea6c964bed1 # 9/2/2021
+)
+FetchContent_MakeAvailable(json-c b64-c)
# Add library and test executable.
file(GLOB SectionSources sections/*.c)
@@ -23,5 +30,5 @@
add_executable(CPERParseTest cper-test.c)
# Link library.
-target_link_libraries(CPERParseLibrary json-c)
+target_link_libraries(CPERParseLibrary json-c b64c)
target_link_libraries(CPERParseTest CPERParseLibrary)
\ No newline at end of file
diff --git a/cper-parse.c b/cper-parse.c
index f80feb7..2bfb3cf 100644
--- a/cper-parse.c
+++ b/cper-parse.c
@@ -7,6 +7,7 @@
#include <stdio.h>
#include "json.h"
+#include "b64.h"
#include "edk/Cper.h"
#include "cper-parse.h"
#include "cper-utils.h"
@@ -24,6 +25,7 @@
#include "sections/cper-section-ccix-per.h"
#include "sections/cper-section-cxl-protocol.h"
#include "sections/cper-section-ipf.h"
+#include "sections/cper-section-cxl-component.h"
//Private pre-definitions.
json_object* cper_header_to_ir(EFI_COMMON_ERROR_RECORD_HEADER* header);
@@ -268,6 +270,16 @@
section_type_readable = "CCIX PER Log Error";
else if (guid_equal(§ion_descriptor->SectionType, &gEfiCxlProtocolErrorSectionGuid))
section_type_readable = "CXL Protocol Error";
+ else if (guid_equal(§ion_descriptor->SectionType, &gEfiCxlGeneralMediaErrorSectionGuid))
+ section_type_readable = "CXL General Media Component Error";
+ else if (guid_equal(§ion_descriptor->SectionType, &gEfiCxlDramEventErrorSectionGuid))
+ section_type_readable = "CXL DRAM Component Error";
+ else if (guid_equal(§ion_descriptor->SectionType, &gEfiCxlPhysicalSwitchErrorSectionGuid))
+ section_type_readable = "CXL Physical Switch Component Error";
+ else if (guid_equal(§ion_descriptor->SectionType, &gEfiCxlVirtualSwitchErrorSectionGuid))
+ section_type_readable = "CXL Virtual Switch Component Error";
+ else if (guid_equal(§ion_descriptor->SectionType, &gEfiCxlMldPortErrorSectionGuid))
+ section_type_readable = "CXL MLD Port Component Error";
//todo: How do you determine if this is a CXL component event?
//perhaps refer to CXL Specification, Rev 2.0
@@ -346,10 +358,22 @@
result = cper_section_ccix_per_to_ir(section, descriptor);
else if (guid_equal(&descriptor->SectionType, &gEfiCxlProtocolErrorSectionGuid))
result = cper_section_cxl_protocol_to_ir(section, descriptor);
+ else if (guid_equal(&descriptor->SectionType, &gEfiCxlGeneralMediaErrorSectionGuid)
+ || guid_equal(&descriptor->SectionType, &gEfiCxlDramEventErrorSectionGuid)
+ || guid_equal(&descriptor->SectionType, &gEfiCxlPhysicalSwitchErrorSectionGuid)
+ || guid_equal(&descriptor->SectionType, &gEfiCxlVirtualSwitchErrorSectionGuid)
+ || guid_equal(&descriptor->SectionType, &gEfiCxlMldPortErrorSectionGuid))
+ {
+ result = cper_section_cxl_component_to_ir(section, descriptor);
+ }
else
{
//Failed read, unknown GUID.
- //todo: dump the binary data out to b64.
+ //Output the data as formatted base64.
+ result = json_object_new_object();
+ char* encoded = b64_encode((unsigned char*)section, descriptor->SectionLength);
+ json_object_object_add(result, "data", json_object_new_string(encoded));
+ free(encoded);
}
//Free section memory, return result.
diff --git a/edk/Cper.c b/edk/Cper.c
index 2d2614d..0ccf08b 100644
--- a/edk/Cper.c
+++ b/edk/Cper.c
@@ -36,6 +36,12 @@
EFI_GUID gEfiIommuDMArErrorSectionGuid = { 0x036f84e1, 0x7f37, 0x428c, { 0xa7, 0x9e, 0x57, 0x5f, 0xdf, 0xaa, 0x84, 0xec }};
EFI_GUID gEfiCcixPerLogErrorSectionGuid = { 0x91335EF6, 0xEBFB, 0x4478, {0xA6, 0xA6, 0x88, 0xB7, 0x28, 0xCF, 0x75, 0xD7 }};
EFI_GUID gEfiCxlProtocolErrorSectionGuid = { 0x80B9EFB4, 0x52B5, 0x4DE3, { 0xA7, 0x77, 0x68, 0x78, 0x4B, 0x77, 0x10, 0x48 }};
+EFI_GUID gEfiCxlGeneralMediaErrorSectionGuid = { 0xfbcd0a77, 0xc260, 0x417f, { 0x85, 0xa9, 0x08, 0x8b, 0x16, 0x21, 0xeb, 0xa6 }};
+EFI_GUID gEfiCxlDramEventErrorSectionGuid = { 0x601dcbb3, 0x9c06, 0x4eab, { 0xb8, 0xaf, 0x4e, 0x9b, 0xfb, 0x5c, 0x96, 0x24 }};
+EFI_GUID gEfiCxlMemoryModuleErrorSectionGuid = { 0xfe927475, 0xdd59, 0x4339, { 0xa5, 0x86, 0x79, 0xba, 0xb1, 0x13, 0xb7, 0x74 }};
+EFI_GUID gEfiCxlPhysicalSwitchErrorSectionGuid = { 0x77cf9271, 0x9c02, 0x470b, { 0x9f, 0xe4, 0xbc, 0x7b, 0x75, 0xf2, 0xda, 0x97 }};
+EFI_GUID gEfiCxlVirtualSwitchErrorSectionGuid = { 0x40d26425, 0x3396, 0x4c4d, { 0xa5, 0xda, 0x3d, 0x47, 0x26, 0x3a, 0xf4, 0x25 }};
+EFI_GUID gEfiCxlMldPortErrorSectionGuid = { 0x8dc44363, 0x0c96, 0x4710, { 0xb7, 0xbf, 0x04, 0xbb, 0x99, 0x53, 0x4c, 0x3f }};
//IA32/x64 error segment GUIDs.
EFI_GUID gEfiIa32x64ErrorTypeCacheCheckGuid = { 0xA55701F5, 0xE3EF, 0x43de, {0xAC, 0x72, 0x24, 0x9B, 0x57, 0x3F, 0xAD, 0x2C } };
diff --git a/edk/Cper.h b/edk/Cper.h
index 5a6d2b2..0fcc967 100644
--- a/edk/Cper.h
+++ b/edk/Cper.h
@@ -1266,6 +1266,12 @@
extern EFI_GUID gEfiIommuDMArErrorSectionGuid;
extern EFI_GUID gEfiCcixPerLogErrorSectionGuid;
extern EFI_GUID gEfiCxlProtocolErrorSectionGuid;
+extern EFI_GUID gEfiCxlGeneralMediaErrorSectionGuid;
+extern EFI_GUID gEfiCxlDramEventErrorSectionGuid;
+extern EFI_GUID gEfiCxlMemoryModuleErrorSectionGuid;
+extern EFI_GUID gEfiCxlPhysicalSwitchErrorSectionGuid;
+extern EFI_GUID gEfiCxlVirtualSwitchErrorSectionGuid;
+extern EFI_GUID gEfiCxlMldPortErrorSectionGuid;
#pragma pack()
#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
diff --git a/sections/cper-section-arm.c b/sections/cper-section-arm.c
index b8def2b..58e97bf 100644
--- a/sections/cper-section-arm.c
+++ b/sections/cper-section-arm.c
@@ -7,6 +7,7 @@
#include <stdio.h>
#include "json.h"
+#include "b64.h"
#include "../edk/Cper.h"
#include "../cper-utils.h"
#include "cper-section-arm.h"
@@ -72,7 +73,12 @@
//Is there any vendor-specific information following?
if (cur_pos < section + record->SectionLength)
{
- //todo: b64 and tag on vendor-specific binary info.
+ json_object* vendor_specific = json_object_new_object();
+ char* encoded = b64_encode((unsigned char*)cur_pos, section + record->SectionLength - cur_pos);
+ json_object_object_add(vendor_specific, "data", json_object_new_string(encoded));
+ free(encoded);
+
+ json_object_object_add(section_ir, "vendorSpecificInfo", vendor_specific);
}
return section_ir;
@@ -291,9 +297,11 @@
register_array = cper_arm_misc_register_array_to_ir((EFI_ARM_MISC_CONTEXT_REGISTER*)cur_pos);
break;
default:
- //Unknown register array type.
- //todo: Format raw binary data and add instead of blank.
+ //Unknown register array type, add as base64 data instead.
register_array = json_object_new_object();
+ char* encoded = b64_encode((unsigned char*)cur_pos, header->RegisterArraySize);
+ json_object_object_add(register_array, "data", json_object_new_string(encoded));
+ free(encoded);
break;
}
diff --git a/sections/cper-section-cxl-component.c b/sections/cper-section-cxl-component.c
new file mode 100644
index 0000000..ab3b34f
--- /dev/null
+++ b/sections/cper-section-cxl-component.c
@@ -0,0 +1,23 @@
+/**
+ * Describes functions for converting CXL component error 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-cxl-component.h"
+
+//Converts a single CXL component error CPER section into JSON IR.
+json_object* cper_section_cxl_component_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor)
+{
+ //The length of the structure (bytes).
+ EFI_CXL_COMPONENT_EVENT_HEADER* cxl_error = (EFI_CXL_COMPONENT_EVENT_HEADER*)section;
+ json_object* section_ir = json_object_new_object();
+
+ //todo: Figure out structure for CXL Component Event log (UEFI spec is a bit vague)
+
+ return section_ir;
+}
\ No newline at end of file
diff --git a/sections/cper-section-cxl-component.h b/sections/cper-section-cxl-component.h
new file mode 100644
index 0000000..17dcedf
--- /dev/null
+++ b/sections/cper-section-cxl-component.h
@@ -0,0 +1,35 @@
+#ifndef CPER_SECTION_CXL_COMPONENT_H
+#define CPER_SECTION_CXL_COMPONENT_H
+
+#include "json.h"
+#include "../edk/Cper.h"
+
+///
+/// CXL Generic Component Error Section
+///
+typedef struct {
+ UINT64 VendorId : 16;
+ UINT64 DeviceId : 16;
+ UINT64 FunctionNumber : 8;
+ UINT64 DeviceNumber : 8;
+ UINT64 BusNumber : 8;
+ UINT64 SegmentNumber : 16;
+ UINT64 Resv1 : 3;
+ UINT64 SlotNumber : 13;
+ UINT64 Resv2 : 8;
+} EFI_CXL_DEVICE_ID_INFO;
+
+typedef struct {
+ UINT32 Length;
+ UINT64 ValidBits;
+ EFI_CXL_DEVICE_ID_INFO DeviceId;
+ UINT64 DeviceSerial;
+} EFI_CXL_COMPONENT_EVENT_HEADER;
+
+typedef struct {
+ //todo: What is the structure for this? The UEFI spec is a bit vague.
+} EFI_CXL_COMPONENT_COMMON_RECORD_HEAD;
+
+json_object* cper_section_cxl_component_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor);
+
+#endif
\ No newline at end of file
diff --git a/sections/cper-section-dmar-iommu.c b/sections/cper-section-dmar-iommu.c
index 14d66a3..1f479aa 100644
--- a/sections/cper-section-dmar-iommu.c
+++ b/sections/cper-section-dmar-iommu.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-dmar-iommu.h"
@@ -26,8 +27,10 @@
//IOMMU event log entry.
//todo: implement as specified in the IOMMU specification
- //Device table entry.
- //todo: dump as b64
+ //Device table entry (as base64).
+ char* encoded = b64_encode((unsigned char*)iommu_error->DeviceTableEntry, 32);
+ json_object_object_add(section_ir, "deviceTableEntry", json_object_new_string(encoded));
+ free(encoded);
//Page table entries.
json_object_object_add(section_ir, "pageTableEntry_Level6", json_object_new_uint64(iommu_error->PteL6));
diff --git a/sections/cper-section-ia32x64.c b/sections/cper-section-ia32x64.c
index bfe7d6e..5dbad18 100644
--- a/sections/cper-section-ia32x64.c
+++ b/sections/cper-section-ia32x64.c
@@ -7,6 +7,7 @@
#include <stdio.h>
#include "json.h"
+#include "b64.h"
#include "../edk/Cper.h"
#include "../cper-utils.h"
#include "cper-section-ia32x64.h"
@@ -248,9 +249,14 @@
}
else
{
- //No parseable data, just shift the head to the next item.
- //todo: Dump the unparseable data into JSON IR anyway
+ //No parseable data, just dump as base64 and shift the head to the next item.
*cur_pos = (void*)(context_info + 1);
+
+ char* encoded = b64_encode((unsigned char*)cur_pos, context_info->ArraySize);
+ register_array = json_object_new_object();
+ json_object_object_add(register_array, "data", json_object_new_string(encoded));
+ free(encoded);
+
*cur_pos = (void*)(((char*)*cur_pos) + context_info->ArraySize);
}
json_object_object_add(context_info_ir, "registerArray", register_array);
diff --git a/sections/cper-section-pci-dev.h b/sections/cper-section-pci-dev.h
index 43d36ea..02c6b4f 100644
--- a/sections/cper-section-pci-dev.h
+++ b/sections/cper-section-pci-dev.h
@@ -11,14 +11,14 @@
/// PCI/PCI-X Device Error Section
///
typedef struct {
- UINT64 VendorId : 2;
- UINT64 DeviceId : 2;
- UINT64 ClassCode : 3;
- UINT64 FunctionNumber : 1;
- UINT64 DeviceNumber : 1;
- UINT64 BusNumber : 1;
- UINT64 SegmentNumber : 1;
- UINT64 Reserved : 5;
+ UINT64 VendorId : 16;
+ UINT64 DeviceId : 16;
+ UINT64 ClassCode : 24;
+ UINT64 FunctionNumber : 8;
+ UINT64 DeviceNumber : 8;
+ UINT64 BusNumber : 8;
+ UINT64 SegmentNumber : 8;
+ UINT64 Reserved : 40;
} EFI_PCI_PCIX_DEVICE_ID_INFO;
typedef struct {