Add fault record, root/context entry to VTD.
diff --git a/sections/cper-section-dmar-iommu.c b/sections/cper-section-dmar-iommu.c
index 1f479aa..69b150a 100644
--- a/sections/cper-section-dmar-iommu.c
+++ b/sections/cper-section-dmar-iommu.c
@@ -25,10 +25,13 @@
     json_object_object_add(section_ir, "statusRegister", json_object_new_uint64(iommu_error->Status));
 
     //IOMMU event log entry.
-    //todo: implement as specified in the IOMMU specification
+    //The format of these entries differ widely by the type of error.
+    char* encoded = b64_encode((unsigned char*)iommu_error->EventLogEntry, 16);
+    json_object_object_add(section_ir, "eventLogEntry", json_object_new_string(encoded));
+    free(encoded);
 
     //Device table entry (as base64).
-    char* encoded = b64_encode((unsigned char*)iommu_error->DeviceTableEntry, 32);
+    encoded = b64_encode((unsigned char*)iommu_error->DeviceTableEntry, 32);
     json_object_object_add(section_ir, "deviceTableEntry", json_object_new_string(encoded));
     free(encoded);
 
diff --git a/sections/cper-section-dmar-vtd.c b/sections/cper-section-dmar-vtd.c
index a7e13a7..734e88a 100644
--- a/sections/cper-section-dmar-vtd.c
+++ b/sections/cper-section-dmar-vtd.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-vtd.h"
@@ -29,8 +30,37 @@
     json_object_object_add(section_ir, "globalStatusRegister", json_object_new_uint64(vtd_error->GlobalStatus));
     json_object_object_add(section_ir, "faultStatusRegister", json_object_new_uint64(vtd_error->FaultStatus));
 
-    //Fault record, root and context entry.
-    //todo: Look at the VT-d specification and implement
+    //Fault record basic fields.
+    json_object* fault_record_ir = json_object_new_object();
+    EFI_VTD_FAULT_RECORD* fault_record = (EFI_VTD_FAULT_RECORD*)vtd_error->FaultRecord;
+    json_object_object_add(fault_record_ir, "faultInformation", json_object_new_uint64(fault_record->FaultInformation));
+    json_object_object_add(fault_record_ir, "sourceIdentifier", json_object_new_uint64(fault_record->SourceIdentifier));
+    json_object_object_add(fault_record_ir, "privelegeModeRequested", 
+        json_object_new_boolean(fault_record->PrivelegeModeRequested));
+    json_object_object_add(fault_record_ir, "executePermissionRequested", 
+        json_object_new_boolean(fault_record->ExecutePermissionRequested));
+    json_object_object_add(fault_record_ir, "pasidPresent", json_object_new_boolean(fault_record->PasidPresent));
+    json_object_object_add(fault_record_ir, "faultReason", json_object_new_uint64(fault_record->FaultReason));
+    json_object_object_add(fault_record_ir, "pasidValue", json_object_new_uint64(fault_record->PasidValue));
+    json_object_object_add(fault_record_ir, "addressType", json_object_new_uint64(fault_record->AddressType));
+
+    //Fault record address type.
+    json_object* fault_record_type = integer_to_readable_pair(fault_record->Type, 2,
+        VTD_FAULT_RECORD_TYPES_KEYS,
+        VTD_FAULT_RECORD_TYPES_VALUES,
+        "Unknown");
+    json_object_object_add(fault_record_ir, "type", fault_record_type);
+    json_object_object_add(section_ir, "faultRecord", fault_record_ir);
+
+    //Root entry.
+    char* encoded = b64_encode((unsigned char*)vtd_error->RootEntry, 16);
+    json_object_object_add(section_ir, "rootEntry", json_object_new_string(encoded));
+    free(encoded);
+
+    //Context entry.
+    encoded = b64_encode((unsigned char*)vtd_error->ContextEntry, 16);
+    json_object_object_add(section_ir, "contextEntry", json_object_new_string(encoded));
+    free(encoded);
 
     //PTE entry for all page levels.
     json_object_object_add(section_ir, "pageTableEntry_Level6", json_object_new_uint64(vtd_error->PteL6));
diff --git a/sections/cper-section-dmar-vtd.h b/sections/cper-section-dmar-vtd.h
index 48be0d2..54e2082 100644
--- a/sections/cper-section-dmar-vtd.h
+++ b/sections/cper-section-dmar-vtd.h
@@ -4,6 +4,24 @@
 #include "json.h"
 #include "../edk/Cper.h"
 
+#define VTD_FAULT_RECORD_TYPES_KEYS (int []){0, 1}
+#define VTD_FAULT_RECORD_TYPES_VALUES (const char*[]){"Write Request", "Read/AtomicOp Request"}
+
+typedef struct {
+    UINT64 Resv1 : 12;
+    UINT64 FaultInformation : 52;
+    UINT64 SourceIdentifier : 16;
+    UINT64 Resv2 : 13;
+    UINT64 PrivelegeModeRequested : 1;
+    UINT64 ExecutePermissionRequested : 1;
+    UINT64 PasidPresent : 1;
+    UINT64 FaultReason : 8;
+    UINT64 PasidValue : 20;
+    UINT64 AddressType : 2;
+    UINT64 Type : 1;
+    UINT64 Resv3 : 1;
+} EFI_VTD_FAULT_RECORD;
+
 json_object* cper_section_dmar_vtd_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor);
 
 #endif
\ No newline at end of file