/**
 * Describes functions for converting ARM CPER sections from binary and JSON format
 * into an intermediate format.
 *
 * Author: Lawrence.Tang@arm.com
 **/

#include <stdio.h>
#include <string.h>
#include <json.h>
#include <inttypes.h>
#include <libcper/base64.h>
#include <libcper/Cper.h>
#include <libcper/cper-utils.h>
#include <libcper/sections/cper-section-arm.h>
#include <libcper/log.h>
#include <string.h>

//Private pre-definitions.
json_object *
cper_arm_error_info_to_ir(EFI_ARM_ERROR_INFORMATION_ENTRY *error_info,
			  char **err_info_desc_i);
json_object *
cper_arm_processor_context_to_ir(EFI_ARM_CONTEXT_INFORMATION_HEADER *header,
				 const UINT8 **cur_pos, UINT32 *remaining_size);
json_object *
cper_arm_cache_tlb_error_to_ir(EFI_ARM_CACHE_ERROR_STRUCTURE *cache_tlb_error,
			       EFI_ARM_ERROR_INFORMATION_ENTRY *error_info);
json_object *cper_arm_bus_error_to_ir(EFI_ARM_BUS_ERROR_STRUCTURE *bus_error);
json_object *cper_arm_misc_register_array_to_ir(
	EFI_ARM_MISC_CONTEXT_REGISTER *misc_register);
void ir_arm_error_info_to_cper(json_object *error_info, FILE *out);
void ir_arm_context_info_to_cper(json_object *context_info, FILE *out);
void ir_arm_error_cache_tlb_info_to_cper(
	json_object *error_information,
	EFI_ARM_CACHE_ERROR_STRUCTURE *error_info_cper);
void ir_arm_error_bus_info_to_cper(json_object *error_information,
				   EFI_ARM_BUS_ERROR_STRUCTURE *error_info_cper);
void ir_arm_aarch32_gpr_to_cper(json_object *registers, FILE *out);
void ir_arm_aarch32_el1_to_cper(json_object *registers, FILE *out);
void ir_arm_aarch32_el2_to_cper(json_object *registers, FILE *out);
void ir_arm_aarch32_secure_to_cper(json_object *registers, FILE *out);
void ir_arm_aarch64_gpr_to_cper(json_object *registers, FILE *out);
void ir_arm_aarch64_el1_to_cper(json_object *registers, FILE *out);
void ir_arm_aarch64_el2_to_cper(json_object *registers, FILE *out);
void ir_arm_aarch64_el3_to_cper(json_object *registers, FILE *out);
void ir_arm_misc_registers_to_cper(json_object *registers, FILE *out);
void ir_arm_unknown_register_to_cper(json_object *registers, FILE *out);

//Converts the given processor-generic CPER section into JSON IR.
json_object *cper_section_arm_to_ir(const UINT8 *section, UINT32 size,
				    char **desc_string)
{
	*desc_string = malloc(SECTION_DESC_STRING_SIZE);
	int outstr_len = 0;
	outstr_len = snprintf(*desc_string, SECTION_DESC_STRING_SIZE,
			      "An ARM Processor Error occurred");
	if (outstr_len < 0) {
		cper_print_log(
			"Error: Could not write to ARM description string\n");
	} else if (outstr_len > SECTION_DESC_STRING_SIZE) {
		cper_print_log("Error: ARM description string truncated: %s\n",
			       *desc_string);
	}

	const UINT8 *cur_pos = section;
	UINT32 remaining_size = size;

	if (remaining_size < sizeof(EFI_ARM_ERROR_RECORD)) {
		return NULL;
	}
	EFI_ARM_ERROR_RECORD *record = (EFI_ARM_ERROR_RECORD *)cur_pos;
	cur_pos += sizeof(EFI_ARM_ERROR_RECORD);
	remaining_size -= sizeof(EFI_ARM_ERROR_RECORD);
	json_object *section_ir = json_object_new_object();

	//Length of ValidationBits from spec
	ValidationTypes ui64Type = { UINT_64T,
				     .value.ui64 = record->ValidFields };

	//Number of error info and context info structures, and length.
	json_object_object_add(section_ir, "errorInfoNum",
			       json_object_new_int(record->ErrInfoNum));
	json_object_object_add(section_ir, "contextInfoNum",
			       json_object_new_int(record->ContextInfoNum));
	json_object_object_add(section_ir, "sectionLength",
			       json_object_new_uint64(record->SectionLength));

	//Error affinity.
	if (isvalid_prop_to_ir(&ui64Type, 1)) {
		json_object *error_affinity = json_object_new_object();
		json_object_object_add(
			error_affinity, "value",
			json_object_new_int(record->ErrorAffinityLevel));
		json_object_object_add(
			error_affinity, "type",
			json_object_new_string(record->ErrorAffinityLevel < 4 ?
						       "Vendor Defined" :
						       "Reserved"));
		json_object_object_add(section_ir, "errorAffinity",
				       error_affinity);
	}

	//Processor ID (MPIDR_EL1) and chip ID (MIDR_EL1).
	if (isvalid_prop_to_ir(&ui64Type, 0)) {
		uint64_t mpidr_eli1 = record->MPIDR_EL1;
		uint64_t sock;
		json_object_object_add(section_ir, "mpidrEl1",
				       json_object_new_uint64(mpidr_eli1));

		//Arm Processor socket info dependes on mpidr_eli1
		sock = (mpidr_eli1 & ARM_SOCK_MASK) >> 32;
		json_object_object_add(section_ir, "affinity3",
				       json_object_new_uint64(sock));
		char *node_desc_str = malloc(EFI_ERROR_DESCRIPTION_STRING_LEN);
		outstr_len = snprintf(node_desc_str,
				      EFI_ERROR_DESCRIPTION_STRING_LEN,
				      " on CPU %" PRIu64, sock);
		if (outstr_len < 0) {
			cper_print_log(
				"Error: Could not write to node description string\n");
		} else if (outstr_len > EFI_ERROR_DESCRIPTION_STRING_LEN) {
			cper_print_log(
				"Error: Node description string truncated: %s\n",
				node_desc_str);
		} else {
			if (strlen(node_desc_str) + strlen(*desc_string) <
			    SECTION_DESC_STRING_SIZE) {
				strncat(*desc_string, node_desc_str,
					outstr_len);
			} else {
				cper_print_log(
					"Error: Node description string too long, not added to description string: %s\n",
					node_desc_str);
			}
		}
		free(node_desc_str);
	}

	json_object_object_add(section_ir, "midrEl1",
			       json_object_new_uint64(record->MIDR_EL1));

	if (isvalid_prop_to_ir(&ui64Type, 2)) {
		//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 & 0x1));
	}
	if (!(record->RunningState >> 31)) {
		//Bit 32 of running state is on, so PSCI state information is included.
		//This can't be made human readable, as it is unknown whether this will be the pre-PSCI 1.0 format
		//or the newer Extended StateID format.
		json_object_object_add(
			section_ir, "psciState",
			json_object_new_uint64(record->PsciState));
	}

	//Processor error structures.
	json_object *error_info_array = json_object_new_array();
	EFI_ARM_ERROR_INFORMATION_ENTRY *cur_error =
		(EFI_ARM_ERROR_INFORMATION_ENTRY *)(record + 1);
	if (remaining_size <
	    (record->ErrInfoNum * sizeof(EFI_ARM_ERROR_INFORMATION_ENTRY))) {
		json_object_put(error_info_array);
		json_object_put(section_ir);
		cper_print_log(
			"Invalid CPER file: Invalid processor error info num.\n");
		return NULL;
	}
	strncat(*desc_string, "; Error Type(s): {",
		EFI_ERROR_DESCRIPTION_STRING_LEN);
	char *err_info_desc_i =
		malloc(EFI_ERROR_INFORMATION_DESCRIPTION_STRING_LEN);
	size_t err_info_desc_i_len = 0;
	for (int i = 0; i < record->ErrInfoNum; i++) {
		json_object_array_add(
			error_info_array,
			cper_arm_error_info_to_ir(cur_error, &err_info_desc_i));
		err_info_desc_i_len = strlen(err_info_desc_i);
		if (err_info_desc_i_len > 0 &&
		    strlen(*desc_string) + err_info_desc_i_len <
			    SECTION_DESC_STRING_SIZE) {
			strncat(*desc_string, err_info_desc_i,
				SECTION_DESC_STRING_SIZE -
					strlen(*desc_string) - 1);
		} else {
			cper_print_log(
				"Error: Error info description string too long, not added to description string: %s\n",
				err_info_desc_i);
		}
		cur_error++;
		if (i == record->ErrInfoNum - 1) {
			if (strlen(*desc_string) + 2 <
			    SECTION_DESC_STRING_SIZE) {
				strncat(*desc_string, "}", 2);
			} else {
				cper_print_log(
					"Error: Description string too long, not added '}'to description string: %s\n",
					*desc_string);
			}
			break;
		}
		if (strlen(*desc_string) + 3 < SECTION_DESC_STRING_SIZE) {
			strncat(*desc_string, ", ", 3);
		} else {
			cper_print_log(
				"Error: Description string too long, not added ',' to description string: %s\n",
				*desc_string);
		}
	}
	free(err_info_desc_i);

	cur_pos += (UINT32)(record->ErrInfoNum *
			    sizeof(EFI_ARM_ERROR_INFORMATION_ENTRY));
	remaining_size -= (UINT32)(record->ErrInfoNum *
				   sizeof(EFI_ARM_ERROR_INFORMATION_ENTRY));

	json_object_object_add(section_ir, "errorInfo", error_info_array);

	//Processor context structures.
	//The current position is moved within the processing, as it is a dynamic size structure.
	json_object *context_info_array = json_object_new_array();
	for (int i = 0; i < record->ContextInfoNum; i++) {
		if (remaining_size <
		    sizeof(EFI_ARM_CONTEXT_INFORMATION_HEADER)) {
			json_object_put(context_info_array);
			json_object_put(section_ir);
			cper_print_log(
				"Invalid CPER file: Invalid processor context info num.\n");
			return NULL;
		}
		EFI_ARM_CONTEXT_INFORMATION_HEADER *header =
			(EFI_ARM_CONTEXT_INFORMATION_HEADER *)cur_pos;

		cur_pos += sizeof(EFI_ARM_CONTEXT_INFORMATION_HEADER);
		remaining_size -= sizeof(EFI_ARM_CONTEXT_INFORMATION_HEADER);
		json_object *processor_context =
			cper_arm_processor_context_to_ir(header, &cur_pos,
							 &remaining_size);
		if (processor_context == NULL) {
			json_object_put(context_info_array);
			json_object_put(section_ir);
			cper_print_log(
				"Invalid CPER file: Invalid processor context info num.\n");
			return NULL;
		}
		json_object_array_add(context_info_array, processor_context);
	}
	json_object_object_add(section_ir, "contextInfo", context_info_array);

	//Is there any vendor-specific information following?
	if (isvalid_prop_to_ir(&ui64Type, 3)) {
		if (cur_pos < (uint8_t *)section + record->SectionLength) {
			json_object *vendor_specific = json_object_new_object();
			size_t input_size = (uint8_t *)section +
					    record->SectionLength - cur_pos;
			if (remaining_size < input_size) {
				json_object_put(vendor_specific);
				json_object_put(section_ir);
				cper_print_log(
					"Invalid CPER file: Invalid vendor-specific info length.\n");
				return NULL;
			}
			int32_t encoded_len = 0;
			char *encoded = base64_encode(cur_pos, input_size,
						      &encoded_len);
			if (encoded == NULL) {
				json_object_put(vendor_specific);
				json_object_put(section_ir);
				cper_print_log(
					"base64 encode of vendorSpecificInfo failed\n");
				return NULL;
			}
			json_object_object_add(vendor_specific, "data",
					       json_object_new_string_len(
						       encoded, encoded_len));
			free(encoded);

			json_object_object_add(section_ir, "vendorSpecificInfo",
					       vendor_specific);
		} else {
			cper_print_log(
				"vendorSpecificInfo is marked valid but not present in binary\n");
		}
	}

	return section_ir;
}

//Converts a single ARM Process Error Information structure into JSON IR.
json_object *
cper_arm_error_info_to_ir(EFI_ARM_ERROR_INFORMATION_ENTRY *error_info,
			  char **err_info_desc_i)
{
	json_object *error_info_ir = json_object_new_object();
	int outstr_len = 0;

	//Version, length.
	json_object_object_add(error_info_ir, "version",
			       json_object_new_int(error_info->Version));
	json_object_object_add(error_info_ir, "length",
			       json_object_new_int(error_info->Length));

	//Validation bitfield.
	ValidationTypes ui16Type = { UINT_16T,
				     .value.ui16 = error_info->ValidationBits };

	//The type of error information in this log.
	json_object *error_type = integer_to_readable_pair(
		error_info->Type, 4, ARM_ERROR_INFO_ENTRY_INFO_TYPES_KEYS,
		ARM_ERROR_INFO_ENTRY_INFO_TYPES_VALUES, "Unknown (Reserved)");
	json_object_object_add(error_info_ir, "errorType", error_type);

	//Multiple error count.
	if (isvalid_prop_to_ir(&ui16Type, 0)) {
		json_object *multiple_error = json_object_new_object();
		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.
	if (isvalid_prop_to_ir(&ui16Type, 1)) {
		json_object *flags = bitfield_to_ir(
			error_info->Flags, 4, ARM_ERROR_INFO_ENTRY_FLAGS_NAMES);
		json_object_object_add(error_info_ir, "flags", flags);
	}

	//Error information, split by type.
	if (isvalid_prop_to_ir(&ui16Type, 2)) {
		json_object *error_subinfo = NULL;
		switch (error_info->Type) {
		case ARM_ERROR_INFORMATION_TYPE_CACHE: //Cache
			error_subinfo = cper_arm_cache_tlb_error_to_ir(
				(EFI_ARM_CACHE_ERROR_STRUCTURE *)&error_info
					->ErrorInformation,
				error_info);
			const char *cache_error_desc = "Cache Error";
			if (strlen(cache_error_desc) >=
			    EFI_ERROR_INFORMATION_DESCRIPTION_STRING_LEN) {
				cper_print_log(
					"Error: Cache Error Description too long %s\n",
					cache_error_desc);
			} else {
				strncpy(*err_info_desc_i, cache_error_desc,
					strlen(cache_error_desc) + 1);
			}
			break;
		case ARM_ERROR_INFORMATION_TYPE_TLB: //TLB
			error_subinfo = cper_arm_cache_tlb_error_to_ir(
				(EFI_ARM_CACHE_ERROR_STRUCTURE *)&error_info
					->ErrorInformation,
				error_info);
			const char *tlb_error_desc = "TLB Error";
			if (strlen(tlb_error_desc) >=
			    EFI_ERROR_INFORMATION_DESCRIPTION_STRING_LEN) {
				cper_print_log(
					"Error: TLB Error Description too long %s\n",
					tlb_error_desc);
			} else {
				strncpy(*err_info_desc_i, tlb_error_desc,
					strlen(tlb_error_desc) + 1);
			}
			break;
		case ARM_ERROR_INFORMATION_TYPE_BUS: //Bus
			error_subinfo = cper_arm_bus_error_to_ir(
				(EFI_ARM_BUS_ERROR_STRUCTURE *)&error_info
					->ErrorInformation);
			const char *bus_error_desc = "Bus Error";
			if (strlen(bus_error_desc) >=
			    EFI_ERROR_INFORMATION_DESCRIPTION_STRING_LEN) {
				cper_print_log(
					"Error: Bus Error Description too long %s\n",
					bus_error_desc);
			} else {
				strncpy(*err_info_desc_i, bus_error_desc,
					strlen(bus_error_desc) + 1);
			}
			break;

		default:
			//Unknown/microarch, will not support.
			break;
		}
		if (error_subinfo != NULL) {
			json_object_object_add(error_info_ir,
					       "errorInformation",
					       error_subinfo);
		}
	}

	//Virtual fault address, physical fault address.
	char *fault_address_desc = malloc(EFI_ERROR_DESCRIPTION_STRING_LEN);
	if (isvalid_prop_to_ir(&ui16Type, 3)) {
		outstr_len = snprintf(fault_address_desc,
				      EFI_ERROR_DESCRIPTION_STRING_LEN,
				      " at Virtual Addr=0x%llX",
				      error_info->VirtualFaultAddress);
		if (outstr_len < 0) {
			cper_print_log(
				"Error: Could not write to fault address description string\n");
		} else if (outstr_len > EFI_ERROR_DESCRIPTION_STRING_LEN) {
			cper_print_log(
				"Error: Virtual fault address description string truncated: %s\n",
				fault_address_desc);
		} else {
			if (strlen(fault_address_desc) +
				    strlen(*err_info_desc_i) <
			    EFI_ERROR_INFORMATION_DESCRIPTION_STRING_LEN) {
				strncat(*err_info_desc_i, fault_address_desc,
					outstr_len);
			} else {
				cper_print_log(
					"Error: Virtual fault address description string too long, not added to description string: %s\n",
					fault_address_desc);
			}
		}
		json_object_object_add(
			error_info_ir, "virtualFaultAddress",
			json_object_new_uint64(
				error_info->VirtualFaultAddress));
	}
	if (isvalid_prop_to_ir(&ui16Type, 4)) {
		outstr_len = snprintf(fault_address_desc,
				      EFI_ERROR_DESCRIPTION_STRING_LEN,
				      " Physical Addr=0x%llX",
				      error_info->PhysicalFaultAddress);
		if (outstr_len < 0) {
			cper_print_log(
				"Error: Could not write to physical fault address description string\n");
		} else if (outstr_len > EFI_ERROR_DESCRIPTION_STRING_LEN) {
			cper_print_log(
				"Error: Physical fault address description string truncated: %s\n",
				fault_address_desc);
		} else {
			if (strlen(fault_address_desc) +
				    strlen(*err_info_desc_i) <
			    EFI_ERROR_INFORMATION_DESCRIPTION_STRING_LEN) {
				strncat(*err_info_desc_i, fault_address_desc,
					outstr_len);
			} else {
				cper_print_log(
					"Error:Physical fault address description string too long, not added to description string: %s\n",
					fault_address_desc);
			}
		}
		json_object_object_add(
			error_info_ir, "physicalFaultAddress",
			json_object_new_uint64(
				error_info->PhysicalFaultAddress));
	}

	free(fault_address_desc);

	return error_info_ir;
}

//Converts a single ARM cache/TLB error information structure into JSON IR format.
json_object *
cper_arm_cache_tlb_error_to_ir(EFI_ARM_CACHE_ERROR_STRUCTURE *cache_tlb_error,
			       EFI_ARM_ERROR_INFORMATION_ENTRY *error_info)
{
	json_object *cache_tlb_error_ir = json_object_new_object();
	json_object *cache_tlb_prop = json_object_new_object();
	char *cache_tlb_propname;

	//Validation bitfield.
	ValidationTypes ui64Type = {
		UINT_64T, .value.ui64 = cache_tlb_error->ValidationBits
	};

	//Transaction type.
	if (isvalid_prop_to_ir(&ui64Type, 0)) {
		json_object *transaction_type = integer_to_readable_pair(
			cache_tlb_error->TransactionType, 3,
			ARM_ERROR_TRANSACTION_TYPES_KEYS,
			ARM_ERROR_TRANSACTION_TYPES_VALUES,
			"Unknown (Reserved)");
		json_object_object_add(cache_tlb_error_ir, "transactionType",
				       transaction_type);
	}

	//Operation.
	bool cacheErrorFlag = 1;
	if (error_info->Type == 0) {
		cache_tlb_propname = "cacheError";
	} else {
		//TLB operation.
		cache_tlb_propname = "tlbError";
		cacheErrorFlag = 0;
	}

	if (isvalid_prop_to_ir(&ui64Type, 1)) {
		json_object *operation;

		if (cacheErrorFlag) {
			//Cache operation.
			operation = integer_to_readable_pair(
				cache_tlb_error->Operation, 11,
				ARM_CACHE_BUS_OPERATION_TYPES_KEYS,
				ARM_CACHE_BUS_OPERATION_TYPES_VALUES,
				"Unknown (Reserved)");
		} else {
			operation = integer_to_readable_pair(
				cache_tlb_error->Operation, 9,
				ARM_TLB_OPERATION_TYPES_KEYS,
				ARM_TLB_OPERATION_TYPES_VALUES,
				"Unknown (Reserved)");
		}
		json_object_object_add(cache_tlb_error_ir, "operation",
				       operation);
	}

	//Miscellaneous remaining fields.
	if (isvalid_prop_to_ir(&ui64Type, 2)) {
		json_object_object_add(
			cache_tlb_error_ir, "level",
			json_object_new_int(cache_tlb_error->Level));
	}
	if (isvalid_prop_to_ir(&ui64Type, 3)) {
		json_object_object_add(
			cache_tlb_error_ir, "processorContextCorrupt",
			json_object_new_boolean(
				cache_tlb_error->ProcessorContextCorrupt));
	}
	if (isvalid_prop_to_ir(&ui64Type, 4)) {
		json_object_object_add(
			cache_tlb_error_ir, "corrected",
			json_object_new_boolean(cache_tlb_error->Corrected));
	}
	if (isvalid_prop_to_ir(&ui64Type, 5)) {
		json_object_object_add(
			cache_tlb_error_ir, "precisePC",
			json_object_new_boolean(cache_tlb_error->PrecisePC));
	}
	if (isvalid_prop_to_ir(&ui64Type, 6)) {
		json_object_object_add(cache_tlb_error_ir, "restartablePC",
				       json_object_new_boolean(
					       cache_tlb_error->RestartablePC));
	}

	json_object_object_add(cache_tlb_prop, cache_tlb_propname,
			       cache_tlb_error_ir);

	return cache_tlb_prop;
}

//Converts a single ARM bus error information structure into JSON IR format.
json_object *cper_arm_bus_error_to_ir(EFI_ARM_BUS_ERROR_STRUCTURE *bus_error)
{
	json_object *bus_error_ir = json_object_new_object();
	json_object *bus_prop = json_object_new_object();
	char *bus_propname = "busError";

	//Validation bits.
	ValidationTypes ui64Type = { UINT_64T,
				     .value.ui64 = bus_error->ValidationBits };

	//Transaction type.
	if (isvalid_prop_to_ir(&ui64Type, 0)) {
		json_object *transaction_type = integer_to_readable_pair(
			bus_error->TransactionType, 3,
			ARM_ERROR_TRANSACTION_TYPES_KEYS,
			ARM_ERROR_TRANSACTION_TYPES_VALUES,
			"Unknown (Reserved)");
		json_object_object_add(bus_error_ir, "transactionType",
				       transaction_type);
	}

	//Operation.
	if (isvalid_prop_to_ir(&ui64Type, 1)) {
		json_object *operation = integer_to_readable_pair(
			bus_error->Operation, 7,
			ARM_CACHE_BUS_OPERATION_TYPES_KEYS,
			ARM_CACHE_BUS_OPERATION_TYPES_VALUES,
			"Unknown (Reserved)");
		json_object_object_add(bus_error_ir, "operation", operation);
	}

	if (isvalid_prop_to_ir(&ui64Type, 2)) {
		//Affinity level of bus error, + miscellaneous fields.
		json_object_object_add(bus_error_ir, "level",
				       json_object_new_int(bus_error->Level));
	}
	if (isvalid_prop_to_ir(&ui64Type, 3)) {
		json_object_object_add(
			bus_error_ir, "processorContextCorrupt",
			json_object_new_boolean(
				bus_error->ProcessorContextCorrupt));
	}
	if (isvalid_prop_to_ir(&ui64Type, 4)) {
		json_object_object_add(
			bus_error_ir, "corrected",
			json_object_new_boolean(bus_error->Corrected));
	}
	if (isvalid_prop_to_ir(&ui64Type, 5)) {
		json_object_object_add(
			bus_error_ir, "precisePC",
			json_object_new_boolean(bus_error->PrecisePC));
	}
	if (isvalid_prop_to_ir(&ui64Type, 6)) {
		json_object_object_add(
			bus_error_ir, "restartablePC",
			json_object_new_boolean(bus_error->RestartablePC));
	}

	//Participation type.
	if (isvalid_prop_to_ir(&ui64Type, 7)) {
		json_object *participation_type = integer_to_readable_pair(
			bus_error->ParticipationType, 4,
			ARM_BUS_PARTICIPATION_TYPES_KEYS,
			ARM_BUS_PARTICIPATION_TYPES_VALUES, "Unknown");
		json_object_object_add(bus_error_ir, "participationType",
				       participation_type);
	}
	if (isvalid_prop_to_ir(&ui64Type, 8)) {
		json_object_object_add(
			bus_error_ir, "timedOut",
			json_object_new_boolean(bus_error->TimeOut));
	}

	//Address space.
	if (isvalid_prop_to_ir(&ui64Type, 9)) {
		json_object *address_space = integer_to_readable_pair(
			bus_error->AddressSpace, 3,
			ARM_BUS_ADDRESS_SPACE_TYPES_KEYS,
			ARM_BUS_ADDRESS_SPACE_TYPES_VALUES, "Unknown");
		json_object_object_add(bus_error_ir, "addressSpace",
				       address_space);
	}

	//Memory access attributes.
	//todo: find the specification of these in the ARM ARM
	if (isvalid_prop_to_ir(&ui64Type, 10)) {
		json_object_object_add(
			bus_error_ir, "memoryAttributes",
			json_object_new_int(
				bus_error->MemoryAddressAttributes));
	}

	//Access Mode
	if (isvalid_prop_to_ir(&ui64Type, 8)) {
		json_object *access_mode = json_object_new_object();
		json_object_object_add(
			access_mode, "value",
			json_object_new_int(bus_error->AccessMode));
		json_object_object_add(
			access_mode, "name",
			json_object_new_string(bus_error->AccessMode == 0 ?
						       "Secure" :
						       "Normal"));
		json_object_object_add(bus_error_ir, "accessMode", access_mode);
	}
	json_object_object_add(bus_prop, bus_propname, bus_error_ir);

	return bus_prop;
}

//Converts a single ARM processor context block into JSON IR.
json_object *
cper_arm_processor_context_to_ir(EFI_ARM_CONTEXT_INFORMATION_HEADER *header,
				 const UINT8 **cur_pos, UINT32 *remaining_size)
{
	if (header->RegisterArraySize > *remaining_size) {
		cper_print_log(
			"Invalid CPER file: Invalid processor context info num.\n");
		return NULL;
	}

	json_object *context_ir = json_object_new_object();

	//Version.
	json_object_object_add(context_ir, "version",
			       json_object_new_int(header->Version));

	//Add the context type.
	json_object *context_type = integer_to_readable_pair(
		header->RegisterContextType,
		ARM_PROCESSOR_INFO_REGISTER_CONTEXT_TYPES_COUNT,
		ARM_PROCESSOR_INFO_REGISTER_CONTEXT_TYPES_KEYS,
		ARM_PROCESSOR_INFO_REGISTER_CONTEXT_TYPES_VALUES,
		"Unknown (Reserved)");
	json_object_object_add(context_ir, "registerContextType", context_type);

	//Register array size (bytes).
	json_object_object_add(
		context_ir, "registerArraySize",
		json_object_new_uint64(header->RegisterArraySize));

	//The register array itself.
	json_object *register_array = NULL;
	switch (header->RegisterContextType) {
	case EFI_ARM_CONTEXT_TYPE_AARCH32_GPR:
		if (*remaining_size < sizeof(EFI_ARM_V8_AARCH32_GPR)) {
			cper_print_log(
				"Invalid CPER file: Invalid processor context info num.\n");
			goto fail;
		}
		if (header->RegisterArraySize <
		    sizeof(EFI_ARM_V8_AARCH32_GPR)) {
			cper_print_log(
				"Invalid CPER file: Not enough bytes for aarch32 gpr\n");
			goto fail;
		}
		register_array = uniform_struct_to_ir(
			(UINT32 *)*cur_pos,
			sizeof(EFI_ARM_V8_AARCH32_GPR) / sizeof(UINT32),
			ARM_AARCH32_GPR_NAMES);
		break;
	case EFI_ARM_CONTEXT_TYPE_AARCH32_EL1:
		if (*remaining_size <
		    sizeof(EFI_ARM_AARCH32_EL1_CONTEXT_REGISTERS)) {
			cper_print_log(
				"Invalid CPER file: Invalid processor context info num.\n");
			goto fail;
		}
		if (header->RegisterArraySize <
		    sizeof(EFI_ARM_AARCH32_EL1_CONTEXT_REGISTERS)) {
			cper_print_log(
				"Invalid CPER file: Not enough bytes for aarch32 el1\n");
			goto fail;
		}
		register_array = uniform_struct_to_ir(
			(UINT32 *)*cur_pos,
			sizeof(EFI_ARM_AARCH32_EL1_CONTEXT_REGISTERS) /
				sizeof(UINT32),
			ARM_AARCH32_EL1_REGISTER_NAMES);
		break;
	case EFI_ARM_CONTEXT_TYPE_AARCH32_EL2:
		if (*remaining_size <
		    sizeof(EFI_ARM_AARCH32_EL2_CONTEXT_REGISTERS)) {
			cper_print_log(
				"Invalid CPER file: Invalid processor context info num.\n");
			goto fail;
		}
		if (header->RegisterArraySize <
		    sizeof(EFI_ARM_AARCH32_EL2_CONTEXT_REGISTERS)) {
			cper_print_log(
				"Invalid CPER file: Not enough bytes for aarch32 el2\n");
			goto fail;
		}
		register_array = uniform_struct_to_ir(
			(UINT32 *)*cur_pos,
			sizeof(EFI_ARM_AARCH32_EL2_CONTEXT_REGISTERS) /
				sizeof(UINT32),
			ARM_AARCH32_EL2_REGISTER_NAMES);

		break;
	case EFI_ARM_CONTEXT_TYPE_AARCH32_SECURE:
		if (*remaining_size <
		    sizeof(EFI_ARM_AARCH32_SECURE_CONTEXT_REGISTERS)) {
			json_object_put(context_ir);
			cper_print_log(
				"Invalid CPER file: Invalid processor context info num.\n");
			return NULL;
		}
		if (header->RegisterArraySize <
		    sizeof(EFI_ARM_AARCH32_SECURE_CONTEXT_REGISTERS)) {
			cper_print_log(
				"Invalid CPER file: Not enough bytes for aarch32 secure\n");
			goto fail;
		}
		register_array = uniform_struct_to_ir(
			(UINT32 *)*cur_pos,
			sizeof(EFI_ARM_AARCH32_SECURE_CONTEXT_REGISTERS) /
				sizeof(UINT32),
			ARM_AARCH32_SECURE_REGISTER_NAMES);
		break;
	case EFI_ARM_CONTEXT_TYPE_AARCH64_GPR:
		if (*remaining_size < sizeof(EFI_ARM_V8_AARCH64_GPR)) {
			cper_print_log(
				"Invalid CPER file: Invalid processor context info num.\n");
			goto fail;
		}
		if (header->RegisterArraySize <
		    sizeof(EFI_ARM_V8_AARCH64_GPR)) {
			cper_print_log(
				"Invalid CPER file: Not enough bytes for aarch64 gpr\n");
			goto fail;
		}
		register_array = uniform_struct64_to_ir(
			(UINT64 *)*cur_pos,
			sizeof(EFI_ARM_V8_AARCH64_GPR) / sizeof(UINT64),
			ARM_AARCH64_GPR_NAMES);
		break;
	case EFI_ARM_CONTEXT_TYPE_AARCH64_EL1:
		if (*remaining_size <
		    sizeof(EFI_ARM_AARCH64_EL1_CONTEXT_REGISTERS)) {
			cper_print_log(
				"Invalid CPER file: Invalid processor context info num.\n");
			goto fail;
		}
		if (header->RegisterArraySize <
		    sizeof(EFI_ARM_AARCH64_EL1_CONTEXT_REGISTERS)) {
			cper_print_log(
				"Invalid CPER file: Not enough bytes for aarch64 el1\n");
			goto fail;
		}
		register_array = uniform_struct64_to_ir(
			(UINT64 *)*cur_pos,
			sizeof(EFI_ARM_AARCH64_EL1_CONTEXT_REGISTERS) /
				sizeof(UINT64),
			ARM_AARCH64_EL1_REGISTER_NAMES);
		break;
	case EFI_ARM_CONTEXT_TYPE_AARCH64_EL2:
		if (*remaining_size <
		    sizeof(EFI_ARM_AARCH64_EL2_CONTEXT_REGISTERS)) {
			cper_print_log(
				"Invalid CPER file: Invalid processor context info num.\n");
			goto fail;
		}
		if (header->RegisterArraySize <
		    sizeof(EFI_ARM_AARCH64_EL2_CONTEXT_REGISTERS)) {
			cper_print_log(
				"Invalid CPER file: Not enough bytes for aarch64 el2\n");
			goto fail;
		}
		register_array = uniform_struct64_to_ir(
			(UINT64 *)*cur_pos,
			sizeof(EFI_ARM_AARCH64_EL2_CONTEXT_REGISTERS) /
				sizeof(UINT64),
			ARM_AARCH64_EL2_REGISTER_NAMES);
		break;
	case EFI_ARM_CONTEXT_TYPE_AARCH64_EL3:
		if (*remaining_size <
		    sizeof(EFI_ARM_AARCH64_EL3_CONTEXT_REGISTERS)) {
			cper_print_log(
				"Invalid CPER file: Invalid processor context info num.\n");
			goto fail;
		}
		if (header->RegisterArraySize <
		    sizeof(EFI_ARM_AARCH64_EL3_CONTEXT_REGISTERS)) {
			cper_print_log(
				"Invalid CPER file: Not enough bytes for aarch64 el3\n");
			goto fail;
		}
		register_array = uniform_struct64_to_ir(
			(UINT64 *)*cur_pos,
			sizeof(EFI_ARM_AARCH64_EL3_CONTEXT_REGISTERS) /
				sizeof(UINT64),
			ARM_AARCH64_EL3_REGISTER_NAMES);
		break;
	case EFI_ARM_CONTEXT_TYPE_MISC:
		if (*remaining_size < sizeof(EFI_ARM_MISC_CONTEXT_REGISTER)) {
			cper_print_log(
				"Invalid CPER file: Invalid processor context info num.\n");
			goto fail;
		}
		if (header->RegisterArraySize <
		    sizeof(EFI_ARM_MISC_CONTEXT_REGISTER)) {
			cper_print_log(
				"Invalid CPER file: Not enough bytes for misc\n");
			goto fail;
		}
		register_array = cper_arm_misc_register_array_to_ir(
			(EFI_ARM_MISC_CONTEXT_REGISTER *)*cur_pos);
		break;
	default:
		if (*remaining_size < header->RegisterArraySize) {
			cper_print_log(
				"Invalid CPER file: Invalid processor context info num.\n");
			goto fail;
		}
		//Unknown register array type, add as base64 data instead.
		int32_t encoded_len = 0;
		char *encoded = base64_encode((UINT8 *)*cur_pos,
					      header->RegisterArraySize,
					      &encoded_len);
		if (encoded == NULL) {
			goto fail;
		}
		register_array = json_object_new_object();
		json_object_object_add(register_array, "data",
				       json_object_new_string_len(encoded,
								  encoded_len));
		free(encoded);

		break;
	}
	json_object_object_add(context_ir, "registerArray", register_array);

	//Set the current position to after the processor context structure.
	*cur_pos = (UINT8 *)(*cur_pos) + header->RegisterArraySize;
	*remaining_size -= header->RegisterArraySize;

	return context_ir;

fail:
	json_object_put(context_ir);
	return NULL;
}

//Converts a single CPER ARM miscellaneous register array to JSON IR format.
json_object *
cper_arm_misc_register_array_to_ir(EFI_ARM_MISC_CONTEXT_REGISTER *misc_register)
{
	json_object *register_array = json_object_new_object();
	json_object *mrs_encoding = json_object_new_object();
	json_object_object_add(mrs_encoding, "op2",
			       json_object_new_uint64(misc_register->MrsOp2));
	json_object_object_add(mrs_encoding, "crm",
			       json_object_new_uint64(misc_register->MrsCrm));
	json_object_object_add(mrs_encoding, "crn",
			       json_object_new_uint64(misc_register->MrsCrn));
	json_object_object_add(mrs_encoding, "op1",
			       json_object_new_uint64(misc_register->MrsOp1));
	json_object_object_add(mrs_encoding, "o0",
			       json_object_new_uint64(misc_register->MrsO0));
	json_object_object_add(register_array, "mrsEncoding", mrs_encoding);
	json_object_object_add(register_array, "value",
			       json_object_new_uint64(misc_register->Value));

	return register_array;
}

//Converts a single CPER-JSON ARM error section into CPER binary, outputting to the given stream.
void ir_section_arm_to_cper(json_object *section, FILE *out)
{
	EFI_ARM_ERROR_RECORD section_cper;
	memset(&section_cper, 0, sizeof(section_cper));

	//Validation bits.
	struct json_object *obj = NULL;
	ValidationTypes u32Type = { UINT_32T, .value.ui32 = 0 };

	//Count of error/context info structures.
	section_cper.ErrInfoNum = json_object_get_int(
		json_object_object_get(section, "errorInfoNum"));
	section_cper.ContextInfoNum = json_object_get_int(
		json_object_object_get(section, "contextInfoNum"));

	//Miscellaneous raw value fields.
	section_cper.SectionLength = json_object_get_uint64(
		json_object_object_get(section, "sectionLength"));
	if (json_object_object_get_ex(section, "mpidrEl1", &obj)) {
		section_cper.MPIDR_EL1 = json_object_get_uint64(obj);
		add_to_valid_bitfield(&u32Type, 0);
	}
	if (json_object_object_get_ex(section, "errorAffinity", &obj)) {
		section_cper.ErrorAffinityLevel = readable_pair_to_integer(obj);
		add_to_valid_bitfield(&u32Type, 1);
	}
	section_cper.MIDR_EL1 = json_object_get_uint64(
		json_object_object_get(section, "midrEl1"));
	if (json_object_object_get_ex(section, "running", &obj)) {
		section_cper.RunningState = json_object_get_boolean(obj);
		add_to_valid_bitfield(&u32Type, 2);
	}

	//Optional PSCI state.
	json_object *psci_state = json_object_object_get(section, "psciState");
	if (psci_state != NULL) {
		section_cper.PsciState = json_object_get_uint64(psci_state);
	}

	//Validationbits for EFI_ARM_ERROR_RECORD should also consider vendorSpecificInfo
	bool vendorSpecificPresent =
		json_object_object_get_ex(section, "vendorSpecificInfo", &obj);
	json_object *vendor_specific_info = obj;
	if (vendorSpecificPresent) {
		add_to_valid_bitfield(&u32Type, 3);
	}

	section_cper.ValidFields = u32Type.value.ui32;

	//Flush header to stream.
	fwrite(&section_cper, sizeof(section_cper), 1, out);

	//Error info structure array.

	json_object *error_info = json_object_object_get(section, "errorInfo");
	for (int i = 0; i < section_cper.ErrInfoNum; i++) {
		ir_arm_error_info_to_cper(
			json_object_array_get_idx(error_info, i), out);
	}

	//Context info structure array.
	json_object *context_info =
		json_object_object_get(section, "contextInfo");
	for (int i = 0; i < section_cper.ContextInfoNum; i++) {
		ir_arm_context_info_to_cper(
			json_object_array_get_idx(context_info, i), out);
	}

	//Vendor specific error info.
	if (vendorSpecificPresent) {
		json_object *vendor_info_string =
			json_object_object_get(vendor_specific_info, "data");
		int vendor_specific_len =
			json_object_get_string_len(vendor_info_string);

		int32_t decoded_len = 0;

		UINT8 *decoded = base64_decode(
			json_object_get_string(vendor_info_string),
			vendor_specific_len, &decoded_len);

		//Write out to file.
		fwrite(decoded, decoded_len, 1, out);
		free(decoded);
	}

	fflush(out);
}

//Converts a single ARM error information structure into CPER binary, outputting to the given stream.
void ir_arm_error_info_to_cper(json_object *error_info, FILE *out)
{
	EFI_ARM_ERROR_INFORMATION_ENTRY error_info_cper;
	memset(&error_info_cper, 0, sizeof(error_info_cper));
	struct json_object *obj = NULL;
	ValidationTypes ui16Type = { UINT_16T, .value.ui16 = 0 };

	//Version, length.
	error_info_cper.Version = json_object_get_int(
		json_object_object_get(error_info, "version"));
	error_info_cper.Length = json_object_get_int(
		json_object_object_get(error_info, "length"));

	//Type, multiple error.
	error_info_cper.Type = (UINT8)readable_pair_to_integer(
		json_object_object_get(error_info, "errorType"));

	if (json_object_object_get_ex(error_info, "multipleError", &obj)) {
		error_info_cper.MultipleError =
			(UINT16)readable_pair_to_integer(obj);
		add_to_valid_bitfield(&ui16Type, 0);
	} else {
		error_info_cper.MultipleError = 0;
	}

	//Flags object.
	if (json_object_object_get_ex(error_info, "flags", &obj)) {
		error_info_cper.Flags = (UINT8)ir_to_bitfield(
			obj, 4, ARM_ERROR_INFO_ENTRY_FLAGS_NAMES);
		add_to_valid_bitfield(&ui16Type, 1);
	} else {
		error_info_cper.Flags = 0;
	}

	//Error information.
	if (json_object_object_get_ex(error_info, "errorInformation", &obj)) {
		json_object *error_info_information = obj;
		json_object *error_info_prop = NULL;
		switch (error_info_cper.Type) {
		case ARM_ERROR_INFORMATION_TYPE_CACHE:
			error_info_cper.ErrorInformation.Value = 0;
			error_info_prop = json_object_object_get(
				error_info_information, "cacheError");
			ir_arm_error_cache_tlb_info_to_cper(
				error_info_prop,
				&error_info_cper.ErrorInformation.CacheError);
			break;
		case ARM_ERROR_INFORMATION_TYPE_TLB:
			error_info_cper.ErrorInformation.Value = 0;
			error_info_prop = json_object_object_get(
				error_info_information, "tlbError");
			ir_arm_error_cache_tlb_info_to_cper(
				error_info_prop,
				&error_info_cper.ErrorInformation.CacheError);
			break;

		case ARM_ERROR_INFORMATION_TYPE_BUS:
			error_info_cper.ErrorInformation.Value = 0;
			error_info_prop = json_object_object_get(
				error_info_information, "busError");
			ir_arm_error_bus_info_to_cper(
				error_info_prop,
				&error_info_cper.ErrorInformation.BusError);
			break;

		default:
			//Unknown error information type.
			break;
		}
		add_to_valid_bitfield(&ui16Type, 2);
	}

	//Virtual/physical fault address.
	if (json_object_object_get_ex(error_info, "virtualFaultAddress",
				      &obj)) {
		error_info_cper.VirtualFaultAddress =
			json_object_get_uint64(obj);
		add_to_valid_bitfield(&ui16Type, 3);
	} else {
		error_info_cper.VirtualFaultAddress = 0;
	}

	if (json_object_object_get_ex(error_info, "physicalFaultAddress",
				      &obj)) {
		error_info_cper.PhysicalFaultAddress =
			json_object_get_uint64(obj);
		add_to_valid_bitfield(&ui16Type, 4);
	} else {
		error_info_cper.PhysicalFaultAddress = 0;
	}
	error_info_cper.ValidationBits = ui16Type.value.ui16;

	//Write out to stream.
	fwrite(&error_info_cper, sizeof(EFI_ARM_ERROR_INFORMATION_ENTRY), 1,
	       out);
}

//Converts a single ARM cache/TLB error information structure into a CPER structure.
void ir_arm_error_cache_tlb_info_to_cper(
	json_object *error_information,
	EFI_ARM_CACHE_ERROR_STRUCTURE *error_info_cper)
{
	// //Validation bits.
	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
	struct json_object *obj = NULL;

	//Miscellaneous value fields.
	if (json_object_object_get_ex(error_information, "transactionType",
				      &obj)) {
		error_info_cper->TransactionType =
			readable_pair_to_integer(obj);
		add_to_valid_bitfield(&ui64Type, 0);
	}
	if (json_object_object_get_ex(error_information, "operation", &obj)) {
		error_info_cper->Operation = readable_pair_to_integer(obj);
		add_to_valid_bitfield(&ui64Type, 1);
	}
	if (json_object_object_get_ex(error_information, "level", &obj)) {
		error_info_cper->Level = json_object_get_uint64(obj);
		add_to_valid_bitfield(&ui64Type, 2);
	}
	if (json_object_object_get_ex(error_information,
				      "processorContextCorrupt", &obj)) {
		error_info_cper->ProcessorContextCorrupt =
			json_object_get_boolean(obj);
		add_to_valid_bitfield(&ui64Type, 3);
	}
	if (json_object_object_get_ex(error_information, "corrected", &obj)) {
		error_info_cper->Corrected = json_object_get_boolean(obj);
		add_to_valid_bitfield(&ui64Type, 4);
	}
	if (json_object_object_get_ex(error_information, "precisePC", &obj)) {
		error_info_cper->PrecisePC = json_object_get_boolean(obj);
		add_to_valid_bitfield(&ui64Type, 5);
	}
	if (json_object_object_get_ex(error_information, "restartablePC",
				      &obj)) {
		error_info_cper->RestartablePC = json_object_get_boolean(obj);
		add_to_valid_bitfield(&ui64Type, 6);
	}
	error_info_cper->Reserved = 0;
	error_info_cper->ValidationBits = ui64Type.value.ui64;
}

//Converts a single ARM bus error information structure into a CPER structure.
void ir_arm_error_bus_info_to_cper(json_object *error_information,
				   EFI_ARM_BUS_ERROR_STRUCTURE *error_info_cper)
{
	//Validation bits.
	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
	struct json_object *obj = NULL;

	memset(error_info_cper, 0, sizeof(EFI_ARM_BUS_ERROR_STRUCTURE));

	//Miscellaneous value fields.
	if (json_object_object_get_ex(error_information, "transactionType",
				      &obj)) {
		error_info_cper->TransactionType =
			readable_pair_to_integer(obj);
		add_to_valid_bitfield(&ui64Type, 0);
	} else {
		error_info_cper->TransactionType = 0;
	}
	if (json_object_object_get_ex(error_information, "operation", &obj)) {
		error_info_cper->Operation = readable_pair_to_integer(obj);
		add_to_valid_bitfield(&ui64Type, 1);
	} else {
		error_info_cper->Operation = 0;
	}
	if (json_object_object_get_ex(error_information, "level", &obj)) {
		error_info_cper->Level = json_object_get_uint64(obj);
		add_to_valid_bitfield(&ui64Type, 2);
	} else {
		error_info_cper->Level = 0;
	}
	if (json_object_object_get_ex(error_information,
				      "processorContextCorrupt", &obj)) {
		error_info_cper->ProcessorContextCorrupt =
			json_object_get_boolean(obj);
		add_to_valid_bitfield(&ui64Type, 3);
	} else {
		error_info_cper->ProcessorContextCorrupt = 0;
	}
	if (json_object_object_get_ex(error_information, "corrected", &obj)) {
		error_info_cper->Corrected = json_object_get_boolean(obj);
		add_to_valid_bitfield(&ui64Type, 4);
	} else {
		error_info_cper->Corrected = 0;
	}
	if (json_object_object_get_ex(error_information, "precisePC", &obj)) {
		error_info_cper->PrecisePC = json_object_get_boolean(obj);
		add_to_valid_bitfield(&ui64Type, 5);
	} else {
		error_info_cper->PrecisePC = 0;
	}
	if (json_object_object_get_ex(error_information, "restartablePC",
				      &obj)) {
		error_info_cper->RestartablePC = json_object_get_boolean(obj);
		add_to_valid_bitfield(&ui64Type, 6);
	} else {
		error_info_cper->RestartablePC = 0;
	}
	if (json_object_object_get_ex(error_information, "participationType",
				      &obj)) {
		error_info_cper->ParticipationType =
			readable_pair_to_integer(obj);
		add_to_valid_bitfield(&ui64Type, 7);
	} else {
		error_info_cper->ParticipationType = 0;
	}
	if (json_object_object_get_ex(error_information, "timedOut", &obj)) {
		error_info_cper->TimeOut = json_object_get_boolean(obj);
		add_to_valid_bitfield(&ui64Type, 8);
	} else {
		error_info_cper->TimeOut = 0;
	}
	if (json_object_object_get_ex(error_information, "addressSpace",
				      &obj)) {
		error_info_cper->AddressSpace = readable_pair_to_integer(obj);
		add_to_valid_bitfield(&ui64Type, 9);
	} else {
		error_info_cper->AddressSpace = 0;
	}
	if (json_object_object_get_ex(error_information, "accessMode", &obj)) {
		error_info_cper->AccessMode = readable_pair_to_integer(obj);
		add_to_valid_bitfield(&ui64Type, 11);
	} else {
		error_info_cper->AccessMode = 0;
	}
	if (json_object_object_get_ex(error_information, "memoryAttributes",
				      &obj)) {
		error_info_cper->MemoryAddressAttributes =
			json_object_get_uint64(obj);
		add_to_valid_bitfield(&ui64Type, 10);
	} else {
		error_info_cper->MemoryAddressAttributes = 0;
	}
	error_info_cper->Reserved = 0;
	error_info_cper->ValidationBits = ui64Type.value.ui64;
}

//Converts a single ARM context information structure into CPER binary, outputting to the given stream.
void ir_arm_context_info_to_cper(json_object *context_info, FILE *out)
{
	EFI_ARM_CONTEXT_INFORMATION_HEADER info_header;

	//Version, array size, context type.
	info_header.Version = json_object_get_int(
		json_object_object_get(context_info, "version"));
	info_header.RegisterArraySize = json_object_get_int(
		json_object_object_get(context_info, "registerArraySize"));
	info_header.RegisterContextType = readable_pair_to_integer(
		json_object_object_get(context_info, "registerContextType"));

	//Flush to stream, write the register array itself.
	fwrite(&info_header, sizeof(EFI_ARM_CONTEXT_INFORMATION_HEADER), 1,
	       out);
	fflush(out);

	json_object *register_array =
		json_object_object_get(context_info, "registerArray");
	switch (info_header.RegisterContextType) {
	case EFI_ARM_CONTEXT_TYPE_AARCH32_GPR:
		ir_arm_aarch32_gpr_to_cper(register_array, out);
		break;
	case EFI_ARM_CONTEXT_TYPE_AARCH32_EL1:
		ir_arm_aarch32_el1_to_cper(register_array, out);
		break;
	case EFI_ARM_CONTEXT_TYPE_AARCH32_EL2:
		ir_arm_aarch32_el2_to_cper(register_array, out);
		break;
	case EFI_ARM_CONTEXT_TYPE_AARCH32_SECURE:
		ir_arm_aarch32_secure_to_cper(register_array, out);
		break;
	case EFI_ARM_CONTEXT_TYPE_AARCH64_GPR:
		ir_arm_aarch64_gpr_to_cper(register_array, out);
		break;
	case EFI_ARM_CONTEXT_TYPE_AARCH64_EL1:
		ir_arm_aarch64_el1_to_cper(register_array, out);
		break;
	case EFI_ARM_CONTEXT_TYPE_AARCH64_EL2:
		ir_arm_aarch64_el2_to_cper(register_array, out);
		break;
	case EFI_ARM_CONTEXT_TYPE_AARCH64_EL3:
		ir_arm_aarch64_el3_to_cper(register_array, out);
		break;
	case EFI_ARM_CONTEXT_TYPE_MISC:
		ir_arm_misc_registers_to_cper(register_array, out);
		break;
	default:
		//Unknown register structure.
		ir_arm_unknown_register_to_cper(register_array, out);
		break;
	}
}

//Converts a single AARCH32 GPR CPER-JSON object to CPER binary, outputting to the given stream.
void ir_arm_aarch32_gpr_to_cper(json_object *registers, FILE *out)
{
	//Get uniform register array.
	EFI_ARM_V8_AARCH32_GPR reg_array;
	ir_to_uniform_struct(registers, (UINT32 *)&reg_array,
			     sizeof(EFI_ARM_V8_AARCH32_GPR) / sizeof(UINT32),
			     ARM_AARCH32_GPR_NAMES);

	//Flush to stream.
	fwrite(&reg_array, sizeof(reg_array), 1, out);
	fflush(out);
}

//Converts a single AARCH32 EL1 register set CPER-JSON object to CPER binary, outputting to the given stream.
void ir_arm_aarch32_el1_to_cper(json_object *registers, FILE *out)
{
	//Get uniform register array.
	EFI_ARM_AARCH32_EL1_CONTEXT_REGISTERS reg_array;
	ir_to_uniform_struct(registers, (UINT32 *)&reg_array,
			     sizeof(EFI_ARM_AARCH32_EL1_CONTEXT_REGISTERS) /
				     sizeof(UINT32),
			     ARM_AARCH32_EL1_REGISTER_NAMES);

	//Flush to stream.
	fwrite(&reg_array, sizeof(reg_array), 1, out);
	fflush(out);
}

//Converts a single AARCH32 EL2 register set CPER-JSON object to CPER binary, outputting to the given stream.
void ir_arm_aarch32_el2_to_cper(json_object *registers, FILE *out)
{
	//Get uniform register array.
	EFI_ARM_AARCH32_EL2_CONTEXT_REGISTERS reg_array;
	ir_to_uniform_struct(registers, (UINT32 *)&reg_array,
			     sizeof(EFI_ARM_AARCH32_EL2_CONTEXT_REGISTERS) /
				     sizeof(UINT32),
			     ARM_AARCH32_EL2_REGISTER_NAMES);

	//Flush to stream.
	fwrite(&reg_array, sizeof(reg_array), 1, out);
	fflush(out);
}

//Converts a single AARCH32 secure register set CPER-JSON object to CPER binary, outputting to the given stream.
void ir_arm_aarch32_secure_to_cper(json_object *registers, FILE *out)
{
	//Get uniform register array.
	EFI_ARM_AARCH32_SECURE_CONTEXT_REGISTERS reg_array;
	ir_to_uniform_struct(registers, (UINT32 *)&reg_array,
			     sizeof(EFI_ARM_AARCH32_SECURE_CONTEXT_REGISTERS) /
				     sizeof(UINT32),
			     ARM_AARCH32_SECURE_REGISTER_NAMES);

	//Flush to stream.
	fwrite(&reg_array, sizeof(reg_array), 1, out);
	fflush(out);
}

//Converts a single AARCH64 GPR CPER-JSON object to CPER binary, outputting to the given stream.
void ir_arm_aarch64_gpr_to_cper(json_object *registers, FILE *out)
{
	//Get uniform register array.
	EFI_ARM_V8_AARCH64_GPR reg_array;
	ir_to_uniform_struct64(registers, (UINT64 *)&reg_array,
			       sizeof(EFI_ARM_V8_AARCH64_GPR) / sizeof(UINT64),
			       ARM_AARCH64_GPR_NAMES);

	//Flush to stream.
	fwrite(&reg_array, sizeof(reg_array), 1, out);
	fflush(out);
}

//Converts a single AARCH64 EL1 register set CPER-JSON object to CPER binary, outputting to the given stream.
void ir_arm_aarch64_el1_to_cper(json_object *registers, FILE *out)
{
	//Get uniform register array.
	EFI_ARM_AARCH64_EL1_CONTEXT_REGISTERS reg_array;
	ir_to_uniform_struct64(registers, (UINT64 *)&reg_array,
			       sizeof(EFI_ARM_AARCH64_EL1_CONTEXT_REGISTERS) /
				       sizeof(UINT64),
			       ARM_AARCH64_EL1_REGISTER_NAMES);

	//Flush to stream.
	fwrite(&reg_array, sizeof(reg_array), 1, out);
	fflush(out);
}

//Converts a single AARCH64 EL2 register set CPER-JSON object to CPER binary, outputting to the given stream.
void ir_arm_aarch64_el2_to_cper(json_object *registers, FILE *out)
{
	//Get uniform register array.
	EFI_ARM_AARCH64_EL2_CONTEXT_REGISTERS reg_array;
	ir_to_uniform_struct64(registers, (UINT64 *)&reg_array,
			       sizeof(EFI_ARM_AARCH64_EL2_CONTEXT_REGISTERS) /
				       sizeof(UINT64),
			       ARM_AARCH64_EL2_REGISTER_NAMES);

	//Flush to stream.
	fwrite(&reg_array, sizeof(reg_array), 1, out);
	fflush(out);
}

//Converts a single AARCH64 EL3 register set CPER-JSON object to CPER binary, outputting to the given stream.
void ir_arm_aarch64_el3_to_cper(json_object *registers, FILE *out)
{
	//Get uniform register array.
	EFI_ARM_AARCH64_EL3_CONTEXT_REGISTERS reg_array;
	ir_to_uniform_struct64(registers, (UINT64 *)&reg_array,
			       sizeof(EFI_ARM_AARCH64_EL3_CONTEXT_REGISTERS) /
				       sizeof(UINT64),
			       ARM_AARCH64_EL3_REGISTER_NAMES);

	//Flush to stream.
	fwrite(&reg_array, sizeof(reg_array), 1, out);
	fflush(out);
}

//Converts a single ARM miscellaneous register set CPER-JSON object to CPER binary, outputting to the given stream.
void ir_arm_misc_registers_to_cper(json_object *registers, FILE *out)
{
	EFI_ARM_MISC_CONTEXT_REGISTER reg_array;

	//MRS encoding information.
	json_object *mrs_encoding =
		json_object_object_get(registers, "mrsEncoding");
	reg_array.MrsOp2 = json_object_get_uint64(
		json_object_object_get(mrs_encoding, "op2"));
	reg_array.MrsCrm = json_object_get_uint64(
		json_object_object_get(mrs_encoding, "crm"));
	reg_array.MrsCrn = json_object_get_uint64(
		json_object_object_get(mrs_encoding, "crn"));
	reg_array.MrsOp1 = json_object_get_uint64(
		json_object_object_get(mrs_encoding, "op1"));
	reg_array.MrsO0 = json_object_get_uint64(
		json_object_object_get(mrs_encoding, "o0"));

	//Actual register value.
	reg_array.Value = json_object_get_uint64(
		json_object_object_get(registers, "value"));

	//Flush to stream.
	fwrite(&reg_array, sizeof(reg_array), 1, out);
	fflush(out);
}

//Converts a single ARM unknown register CPER-JSON object to CPER binary, outputting to the given stream.
void ir_arm_unknown_register_to_cper(json_object *registers, FILE *out)
{
	//Get base64 represented data.
	json_object *encoded = json_object_object_get(registers, "data");

	int32_t decoded_len = 0;

	UINT8 *decoded = base64_decode(json_object_get_string(encoded),
				       json_object_get_string_len(encoded),
				       &decoded_len);

	if (decoded == NULL) {
		cper_print_log("Failed to allocate decode output buffer. \n");
	} else {
		//Flush out to stream.
		fwrite(&decoded, decoded_len, 1, out);
		fflush(out);
		free(decoded);
	}
}
