/**
 * 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 <libcper/base64.h>
#include <libcper/Cper.h>
#include <libcper/cper-utils.h>
#include <libcper/sections/cper-section-arm.h>

//Private pre-definitions.
json_object *
cper_arm_error_info_to_ir(EFI_ARM_ERROR_INFORMATION_ENTRY *error_info);
json_object *
cper_arm_processor_context_to_ir(EFI_ARM_CONTEXT_INFORMATION_HEADER *header,
				 void **cur_pos);
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(void *section)
{
	EFI_ARM_ERROR_RECORD *record = (EFI_ARM_ERROR_RECORD *)section;
	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));
	}

	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);
	for (int i = 0; i < record->ErrInfoNum; i++) {
		json_object_array_add(error_info_array,
				      cper_arm_error_info_to_ir(cur_error));
		cur_error++;
	}
	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.
	uint8_t *cur_pos = (uint8_t *)cur_error;
	json_object *context_info_array = json_object_new_array();
	for (int i = 0; i < record->ContextInfoNum; i++) {
		EFI_ARM_CONTEXT_INFORMATION_HEADER *header =
			(EFI_ARM_CONTEXT_INFORMATION_HEADER *)cur_pos;
		json_object *processor_context =
			cper_arm_processor_context_to_ir(header,
							 (void **)&cur_pos);
		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;
			int32_t encoded_len = 0;
			char *encoded = base64_encode(cur_pos, input_size,
						      &encoded_len);
			if (encoded == NULL) {
				printf("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 {
			printf("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)
{
	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, "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
		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);
			break;
		case ARM_ERROR_INFORMATION_TYPE_BUS: //Bus
			error_subinfo = cper_arm_bus_error_to_ir(
				(EFI_ARM_BUS_ERROR_STRUCTURE *)&error_info
					->ErrorInformation);
			break;

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

	//Virtual fault address, physical fault address.
	if (isvalid_prop_to_ir(&ui16Type, 3)) {
		json_object_object_add(
			error_info_ir, "virtualFaultAddress",
			json_object_new_uint64(
				error_info->VirtualFaultAddress));
	}
	if (isvalid_prop_to_ir(&ui16Type, 4)) {
		json_object_object_add(
			error_info_ir, "physicalFaultAddress",
			json_object_new_uint64(
				error_info->PhysicalFaultAddress));
	}

	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,
				 void **cur_pos)
{
	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, 9,
		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.
	*cur_pos = (void *)(header + 1);
	json_object *register_array = NULL;
	switch (header->RegisterContextType) {
	case EFI_ARM_CONTEXT_TYPE_AARCH32_GPR:
		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:
		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:
		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:
		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:
		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:
		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:
		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:
		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:
		register_array = cper_arm_misc_register_array_to_ir(
			(EFI_ARM_MISC_CONTEXT_REGISTER *)*cur_pos);
		break;
	default:
		//Unknown register array type, add as base64 data instead.
		register_array = json_object_new_object();
		int32_t encoded_len = 0;
		char *encoded = base64_encode((UINT8 *)*cur_pos,
					      header->RegisterArraySize,
					      &encoded_len);
		if (encoded == NULL) {
			printf("Failed to allocate encode output buffer. \n");
			return NULL;
		}
		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;

	return context_ir;
}

//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) {
		printf("Failed to allocate decode output buffer. \n");
	} else {
		//Flush out to stream.
		fwrite(&decoded, decoded_len, 1, out);
		fflush(out);
		free(decoded);
	}
}
