Add more detailed ARM error structures.
diff --git a/cper-utils.c b/cper-utils.c
index 00581e2..f70cf54 100644
--- a/cper-utils.c
+++ b/cper-utils.c
@@ -30,32 +30,8 @@
     return result;
 }
 
-//Converts the given uint8 bitfield to IR, assuming bit 0 starts on the left.
-json_object* bitfield8_to_ir(UINT8 bitfield, int num_fields, const char* names[])
-{
-    json_object* result = json_object_new_object();
-    for (int i=0; i<num_fields; i++)
-    {
-        json_object_object_add(result, names[i], json_object_new_boolean((bitfield >> i) & 0b1));
-    }
-
-    return result;
-}
-
-//Converts the given bitfield to IR, assuming bit 0 starts on the left.
-json_object* bitfield_to_ir(UINT32 bitfield, int num_fields, const char* names[])
-{
-    json_object* result = json_object_new_object();
-    for (int i=0; i<num_fields; i++)
-    {
-        json_object_object_add(result, names[i], json_object_new_boolean((bitfield >> i) & 0b1));
-    }
-
-    return result;
-}
-
 //Converts the given 64 bit bitfield to IR, assuming bit 0 starts on the left.
-json_object* bitfield64_to_ir(UINT64 bitfield, int num_fields, const char* names[])
+json_object* bitfield_to_ir(UINT64 bitfield, int num_fields, const char* names[])
 {
     json_object* result = json_object_new_object();
     for (int i=0; i<num_fields; i++)
diff --git a/cper-utils.h b/cper-utils.h
index 9446237..c38a4a8 100644
--- a/cper-utils.h
+++ b/cper-utils.h
@@ -5,9 +5,7 @@
 #define TIMESTAMP_LENGTH 24
 
 json_object* integer_to_readable_pair(int value, int len, int keys[], const char* values[], const char* default_value);
-json_object* bitfield8_to_ir(UINT8 bitfield, int num_fields, const char* names[]);
-json_object* bitfield_to_ir(UINT32 bitfield, int num_fields, const char* names[]);
-json_object* bitfield64_to_ir(UINT64 bitfield, int num_fields, const char* names[]);
+json_object* bitfield_to_ir(UINT64 bitfield, int num_fields, const char* names[]);
 json_object* revision_to_ir(UINT16 revision);
 const char* severity_to_string(UINT8 severity);
 void guid_to_string(char* out, EFI_GUID* guid);
diff --git a/edk/Cper.h b/edk/Cper.h
index d8d0f41..7d14d23 100644
--- a/edk/Cper.h
+++ b/edk/Cper.h
@@ -741,7 +741,7 @@
 

 

 ///

-/// ARM Processor Error Structure

+/// ARM Processor Error Record

 ///

 typedef struct {

   UINT32    ValidFields;

@@ -756,6 +756,68 @@
 } EFI_ARM_PROCESSOR_ERROR_RECORD;

 

 ///

+/// ARM Processor Error Information Structure

+///

+typedef struct {

+  UINT8 Version;

+  UINT8 Length;

+  UINT16 ValidationBits;

+  UINT8 Type;

+  UINT16 MultipleError;

+  UINT8 Flags;

+  EFI_ARM_PROCESSOR_ERROR_INFORMATION_STRUCTURE ErrorInformation;

+  UINT64 VirtualFaultAddress;

+  UINT64 PhysicalFaultAddress;

+} EFI_ARM_PROCESSOR_ERROR_INFORMATION_ENTRY;

+

+typedef union {

+  EFI_ARM_PROCESSOR_CACHE_ERROR_STRUCTURE CacheError;

+  EFI_ARM_PROCESSOR_TLB_ERROR_STRUCTURE TlbError;

+  EFI_ARM_PROCESSOR_BUS_ERROR_STRUCTURE BusError;

+} EFI_ARM_PROCESSOR_ERROR_INFORMATION_STRUCTURE;

+

+typedef struct {

+  UINT64 ValidationBits : 16;

+  UINT64 TransactionType : 2;

+  UINT64 Operation : 4;

+  UINT64 Level : 3;

+  UINT64 ProcessorContextInterrupt : 1;

+  UINT64 Corrected : 1;

+  UINT64 PrecisePC : 1;

+  UINT64 RestartablePC : 1;

+  UINT64 Reserved : 34;

+} EFI_ARM_PROCESSOR_CACHE_ERROR_STRUCTURE;

+

+typedef struct {

+  UINT64 ValidationBits : 16;

+  UINT64 TransactionType : 2;

+  UINT64 Operation : 4;

+  UINT64 Level : 3;

+  UINT64 ProcessorContextInterrupt : 1;

+  UINT64 Corrected : 1;

+  UINT64 PrecisePC : 1;

+  UINT64 RestartablePC : 1;

+  UINT64 Reserved : 34;

+} EFI_ARM_PROCESSOR_TLB_ERROR_STRUCTURE;

+

+typedef struct {

+  UINT64 ValidationBits : 16;

+  UINT64 TransactionType : 2;

+  UINT64 Operation : 4;

+  UINT64 Level : 3;

+  UINT64 ProcessorContextInterrupt : 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_PROCESSOR_BUS_ERROR_STRUCTURE;

+

+///

 /// Error Status Fields

 ///

 typedef struct {

diff --git a/sections/cper-section-arm.c b/sections/cper-section-arm.c
index 4dcb6c3..cda8252 100644
--- a/sections/cper-section-arm.c
+++ b/sections/cper-section-arm.c
@@ -11,6 +11,12 @@
 #include "../cper-utils.h"
 #include "cper-section-arm.h"
 
+//Private pre-definitions.
+json_object* cper_arm_error_info_to_ir(EFI_ARM_PROCESSOR_ERROR_INFORMATION_ENTRY* error_info, void** cur_pos);
+json_object* cper_arm_cache_error_to_ir(EFI_ARM_PROCESSOR_CACHE_ERROR_STRUCTURE* cache_error);
+json_object* cper_arm_tlb_error_to_ir(EFI_ARM_PROCESSOR_TLB_ERROR_STRUCTURE* tlb_error);
+json_object* cper_arm_bus_error_to_ir(EFI_ARM_PROCESSOR_BUS_ERROR_STRUCTURE* bus_error);
+
 //Converts the given processor-generic CPER section into JSON IR.
 json_object* cper_section_arm_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor)
 {
@@ -39,10 +45,89 @@
 
     //Whether the processor is running, and the state of it if so.
     json_object_object_add(section_ir, "running", json_object_new_boolean(record->RunningState));
-    if (record->RunningState)
+    if (record->RunningState >> 31)
     {
-        //...       
+        //Bit 32 of running state is on, so PSCI state information is included.
+        //todo: Look at how to make this human readable from the ARM PSCI document.
+        json_object_object_add(section_ir, "psciState", json_object_new_int(record->PsciState));
     }
 
+    //Processor error structures.
+    json_object* error_info_array = json_object_new_array();
+    EFI_ARM_PROCESSOR_ERROR_INFORMATION_ENTRY* cur_error = (EFI_ARM_PROCESSOR_ERROR_INFORMATION_ENTRY*)(record + 1);
+    for (int i=0; i<record->ErrInfoNum; i++) 
+    {
+        json_object_array_add(error_info_array, cper_arm_error_info_to_ir(cur_error, (void*)&cur_error));
+        //Dynamically sized structure, so pointer is controlled within the above function.
+    }
     return section_ir;
+}
+
+//Converts a single ARM Process Error Information structure into JSON IR.
+json_object* cper_arm_error_info_to_ir(EFI_ARM_PROCESSOR_ERROR_INFORMATION_ENTRY* error_info, void** cur_pos)
+{
+    json_object* error_info_ir = json_object_new_object();
+
+    //Version, length.
+    json_object_object_add(error_info_ir, "version", json_object_new_int(error_info->Version));
+    json_object_object_add(error_info_ir, "version", json_object_new_int(error_info->Length));
+
+    //Validation bitfield.
+    json_object* validation = bitfield_to_ir(error_info->ValidationBits, 5, ARM_PROCESSOR_ERROR_INFO_ENTRY_VALID_BITFIELD_NAMES);
+    json_object_object_add(error_info_ir, "validationBits", validation);
+
+    //The type of error information in this log.
+    //todo: The UEFI spec is ambiguous, what are the values for these??
+    json_object* error_type = integer_to_readable_pair(error_info->Type, 4,
+        ARM_PROCESSOR_ERROR_INFO_ENTRY_INFO_TYPES_KEYS,
+        ARM_PROCESSOR_ERROR_INFO_ENTRY_INFO_TYPES_VALUES,
+        "Unknown (Reserved)");
+    json_object_object_add(error_info_ir, "errorType", error_type);
+
+    //Multiple error count.
+    json_object* multiple_error = json_object_object_create();
+    json_object_object_add(multiple_error, "value", json_object_new_int(error_info->MultipleError));
+    json_object_object_add(multiple_error, "type", 
+        json_object_new_string(error_info->MultipleError < 1 ? "Single Error" : "Multiple Errors"));
+    json_object_object_add(error_info_ir, "multipleError", multiple_error);
+
+    //Flags.
+    json_object* flags = bitfield_to_ir(error_info->Flags, 4, ARM_PROCESSOR_ERROR_INFO_ENTRY_FLAGS_NAMES);
+    json_object_object_add(error_info_ir, "flags", flags);
+
+    //Error information, split by type.
+    json_object* error_subinfo = NULL;
+    switch (error_info->Type)
+    {
+        case 0: //Cache
+            error_subinfo = cper_arm_cache_error_to_ir((EFI_ARM_PROCESSOR_CACHE_ERROR_STRUCTURE*)error_info->ErrorInformation);
+            break;
+        case 1: //TLB
+            error_subinfo = cper_arm_tlb_error_to_ir((EFI_ARM_PROCESSOR_TLB_ERROR_STRUCTURE*)error_info->ErrorInformation);
+            break;
+        case 2: //Bus
+            error_subinfo = cper_arm_bus_error_to_ir((EFI_ARM_PROCESSOR_BUS_ERROR_STRUCTURE*)error_info->ErrorInformation);
+            break;
+    }
+    json_object_object_add(error_info_ir, "errorInformation", error_subinfo);
+
+    return error_info_ir;
+}
+
+//Converts a single ARM cache error information structure into JSON IR format.
+json_object* cper_arm_cache_error_to_ir(EFI_ARM_PROCESSOR_CACHE_ERROR_STRUCTURE* cache_error)
+{
+    //todo
+}
+
+//Converts a single ARM TLB error information structure into JSON IR format.
+json_object* cper_arm_tlb_error_to_ir(EFI_ARM_PROCESSOR_TLB_ERROR_STRUCTURE* tlb_error)
+{
+    //todo
+}
+
+//Converts a single ARM bus error information structure into JSON IR format.
+json_object* cper_arm_bus_error_to_ir(EFI_ARM_PROCESSOR_BUS_ERROR_STRUCTURE* bus_error)
+{
+    //todo
 }
\ No newline at end of file
diff --git a/sections/cper-section-arm.h b/sections/cper-section-arm.h
index 2112442..98dd36c 100644
--- a/sections/cper-section-arm.h
+++ b/sections/cper-section-arm.h
@@ -6,7 +6,14 @@
 
 #define ARM_PROCESSOR_ERROR_VALID_BITFIELD_NAMES (const char*[]) \
     {"mpidrValid", "errorAffinityLevelValid", "runningStateValid", "vendorSpecificInfoValid"}
-    
+#define ARM_PROCESSOR_ERROR_INFO_ENTRY_VALID_BITFIELD_NAMES (const char*[]) \
+    {"multipleErrorValid", "flagsValid", "errorInformationValid", "virtualFaultAddressValid", "physicalFaultAddressValid"}
+#define ARM_PROCESSOR_ERROR_INFO_ENTRY_FLAGS_NAMES (const char*[]) \
+    {"firstErrorCaptured", "lastErrorCaptured", "propagated", "overflow"}
+#define ARM_PROCESSOR_ERROR_INFO_ENTRY_INFO_TYPES_KEYS (int []){0, 1, 2, 3}
+#define ARM_PROCESSOR_ERROR_INFO_ENTRY_INFO_TYPES_VALUES (const char*[]){"Cache Error", "TLB Error", \
+    "Bus Error", "Micro-Architectural Error"}
+
 json_object* cper_section_arm_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor);
 
 #endif
\ No newline at end of file