14795d4aeSLawrence Tang /** 24795d4aeSLawrence Tang * Describes functions for converting generic DMAr CPER sections from binary and JSON format 34795d4aeSLawrence Tang * into an intermediate format. 44795d4aeSLawrence Tang * 54795d4aeSLawrence Tang * Author: Lawrence.Tang@arm.com 64795d4aeSLawrence Tang **/ 74795d4aeSLawrence Tang #include <stdio.h> 84795d4aeSLawrence Tang #include "json.h" 94795d4aeSLawrence Tang #include "../edk/Cper.h" 104795d4aeSLawrence Tang #include "../cper-utils.h" 114795d4aeSLawrence Tang #include "cper-section-dmar-generic.h" 124795d4aeSLawrence Tang 134795d4aeSLawrence Tang //Converts a single generic DMAr CPER section into JSON IR. 144795d4aeSLawrence Tang json_object* cper_section_dmar_generic_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor) 154795d4aeSLawrence Tang { 164795d4aeSLawrence Tang EFI_DMAR_GENERIC_ERROR_DATA* firmware_error = (EFI_DMAR_GENERIC_ERROR_DATA*)section; 174795d4aeSLawrence Tang json_object* section_ir = json_object_new_object(); 184795d4aeSLawrence Tang 194795d4aeSLawrence Tang //Requester ID, segment. 204795d4aeSLawrence Tang json_object_object_add(section_ir, "requesterID", json_object_new_int(firmware_error->RequesterId)); 214795d4aeSLawrence Tang json_object_object_add(section_ir, "segmentNumber", json_object_new_int(firmware_error->SegmentNumber)); 224795d4aeSLawrence Tang 234795d4aeSLawrence Tang //Fault reason. 244795d4aeSLawrence Tang json_object* fault_reason = integer_to_readable_pair_with_desc(firmware_error->FaultReason, 11, 254795d4aeSLawrence Tang DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_KEYS, 264795d4aeSLawrence Tang DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_VALUES, 274795d4aeSLawrence Tang DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_DESCRIPTIONS, 284795d4aeSLawrence Tang "Unknown (Reserved)"); 294795d4aeSLawrence Tang json_object_object_add(section_ir, "faultReason", fault_reason); 304795d4aeSLawrence Tang 314795d4aeSLawrence Tang //Access type. 324795d4aeSLawrence Tang json_object* access_type = integer_to_readable_pair(firmware_error->AccessType, 2, 334795d4aeSLawrence Tang DMAR_GENERIC_ERROR_ACCESS_TYPES_KEYS, 344795d4aeSLawrence Tang DMAR_GENERIC_ERROR_ACCESS_TYPES_VALUES, 354795d4aeSLawrence Tang "Unknown (Reserved)"); 364795d4aeSLawrence Tang json_object_object_add(section_ir, "accessType", access_type); 374795d4aeSLawrence Tang 384795d4aeSLawrence Tang //Address type. 394795d4aeSLawrence Tang json_object* address_type = integer_to_readable_pair(firmware_error->AddressType, 2, 404795d4aeSLawrence Tang DMAR_GENERIC_ERROR_ADDRESS_TYPES_KEYS, 414795d4aeSLawrence Tang DMAR_GENERIC_ERROR_ADDRESS_TYPES_VALUES, 424795d4aeSLawrence Tang "Unknown (Reserved)"); 434795d4aeSLawrence Tang json_object_object_add(section_ir, "addressType", address_type); 444795d4aeSLawrence Tang 454795d4aeSLawrence Tang //Architecture type. 464795d4aeSLawrence Tang json_object* arch_type = integer_to_readable_pair(firmware_error->ArchType, 2, 474795d4aeSLawrence Tang DMAR_GENERIC_ERROR_ARCH_TYPES_KEYS, 484795d4aeSLawrence Tang DMAR_GENERIC_ERROR_ARCH_TYPES_VALUES, 494795d4aeSLawrence Tang "Unknown (Reserved)"); 504795d4aeSLawrence Tang json_object_object_add(section_ir, "architectureType", arch_type); 514795d4aeSLawrence Tang 524795d4aeSLawrence Tang //Device address. 534795d4aeSLawrence Tang json_object_object_add(section_ir, "deviceAddress", json_object_new_uint64(firmware_error->DeviceAddr)); 544795d4aeSLawrence Tang 554795d4aeSLawrence Tang return section_ir; 564795d4aeSLawrence Tang } 57*205dd1d7SLawrence Tang 58*205dd1d7SLawrence Tang //Converts a single generic DMAR CPER-JSON section into CPER binary, outputting to the given stream. 59*205dd1d7SLawrence Tang void ir_section_dmar_generic_to_cper(json_object* section, FILE* out) 60*205dd1d7SLawrence Tang { 61*205dd1d7SLawrence Tang EFI_DMAR_GENERIC_ERROR_DATA* section_cper = 62*205dd1d7SLawrence Tang (EFI_DMAR_GENERIC_ERROR_DATA*)calloc(1, sizeof(EFI_DMAR_GENERIC_ERROR_DATA)); 63*205dd1d7SLawrence Tang 64*205dd1d7SLawrence Tang //Record fields. 65*205dd1d7SLawrence Tang section_cper->RequesterId = (UINT16)json_object_get_int(json_object_object_get(section, "requesterID")); 66*205dd1d7SLawrence Tang section_cper->SegmentNumber = (UINT16)json_object_get_int(json_object_object_get(section, "segmentNumber")); 67*205dd1d7SLawrence Tang section_cper->FaultReason = (UINT8)readable_pair_to_integer(json_object_object_get(section, "faultReason")); 68*205dd1d7SLawrence Tang section_cper->AccessType = (UINT8)readable_pair_to_integer(json_object_object_get(section, "accessType")); 69*205dd1d7SLawrence Tang section_cper->AddressType = (UINT8)readable_pair_to_integer(json_object_object_get(section, "addressType")); 70*205dd1d7SLawrence Tang section_cper->ArchType = (UINT8)readable_pair_to_integer(json_object_object_get(section, "archType")); 71*205dd1d7SLawrence Tang section_cper->DeviceAddr = json_object_get_uint64(json_object_object_get(section, "deviceAddress")); 72*205dd1d7SLawrence Tang 73*205dd1d7SLawrence Tang //Write to stream, free resources. 74*205dd1d7SLawrence Tang fwrite(§ion_cper, sizeof(section_cper), 1, out); 75*205dd1d7SLawrence Tang fflush(out); 76*205dd1d7SLawrence Tang free(section_cper); 77*205dd1d7SLawrence Tang }