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. 14*e407b4c8SLawrence Tang json_object * 15*e407b4c8SLawrence Tang cper_section_dmar_generic_to_ir(void *section, 16*e407b4c8SLawrence Tang EFI_ERROR_SECTION_DESCRIPTOR *descriptor) 174795d4aeSLawrence Tang { 18*e407b4c8SLawrence Tang EFI_DMAR_GENERIC_ERROR_DATA *firmware_error = 19*e407b4c8SLawrence Tang (EFI_DMAR_GENERIC_ERROR_DATA *)section; 204795d4aeSLawrence Tang json_object *section_ir = json_object_new_object(); 214795d4aeSLawrence Tang 224795d4aeSLawrence Tang //Requester ID, segment. 23*e407b4c8SLawrence Tang json_object_object_add( 24*e407b4c8SLawrence Tang section_ir, "requesterID", 25*e407b4c8SLawrence Tang json_object_new_int(firmware_error->RequesterId)); 26*e407b4c8SLawrence Tang json_object_object_add( 27*e407b4c8SLawrence Tang section_ir, "segmentNumber", 28*e407b4c8SLawrence Tang json_object_new_int(firmware_error->SegmentNumber)); 294795d4aeSLawrence Tang 304795d4aeSLawrence Tang //Fault reason. 31*e407b4c8SLawrence Tang json_object *fault_reason = integer_to_readable_pair_with_desc( 32*e407b4c8SLawrence Tang firmware_error->FaultReason, 11, 334795d4aeSLawrence Tang DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_KEYS, 344795d4aeSLawrence Tang DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_VALUES, 354795d4aeSLawrence Tang DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_DESCRIPTIONS, 364795d4aeSLawrence Tang "Unknown (Reserved)"); 374795d4aeSLawrence Tang json_object_object_add(section_ir, "faultReason", fault_reason); 384795d4aeSLawrence Tang 394795d4aeSLawrence Tang //Access type. 40*e407b4c8SLawrence Tang json_object *access_type = integer_to_readable_pair( 41*e407b4c8SLawrence Tang firmware_error->AccessType, 2, 424795d4aeSLawrence Tang DMAR_GENERIC_ERROR_ACCESS_TYPES_KEYS, 43*e407b4c8SLawrence Tang DMAR_GENERIC_ERROR_ACCESS_TYPES_VALUES, "Unknown (Reserved)"); 444795d4aeSLawrence Tang json_object_object_add(section_ir, "accessType", access_type); 454795d4aeSLawrence Tang 464795d4aeSLawrence Tang //Address type. 47*e407b4c8SLawrence Tang json_object *address_type = integer_to_readable_pair( 48*e407b4c8SLawrence Tang firmware_error->AddressType, 2, 494795d4aeSLawrence Tang DMAR_GENERIC_ERROR_ADDRESS_TYPES_KEYS, 50*e407b4c8SLawrence Tang DMAR_GENERIC_ERROR_ADDRESS_TYPES_VALUES, "Unknown (Reserved)"); 514795d4aeSLawrence Tang json_object_object_add(section_ir, "addressType", address_type); 524795d4aeSLawrence Tang 534795d4aeSLawrence Tang //Architecture type. 54*e407b4c8SLawrence Tang json_object *arch_type = integer_to_readable_pair( 55*e407b4c8SLawrence Tang firmware_error->ArchType, 2, DMAR_GENERIC_ERROR_ARCH_TYPES_KEYS, 56*e407b4c8SLawrence Tang DMAR_GENERIC_ERROR_ARCH_TYPES_VALUES, "Unknown (Reserved)"); 574795d4aeSLawrence Tang json_object_object_add(section_ir, "architectureType", arch_type); 584795d4aeSLawrence Tang 594795d4aeSLawrence Tang //Device address. 60*e407b4c8SLawrence Tang json_object_object_add( 61*e407b4c8SLawrence Tang section_ir, "deviceAddress", 62*e407b4c8SLawrence Tang json_object_new_uint64(firmware_error->DeviceAddr)); 634795d4aeSLawrence Tang 644795d4aeSLawrence Tang return section_ir; 654795d4aeSLawrence Tang } 66205dd1d7SLawrence Tang 67205dd1d7SLawrence Tang //Converts a single generic DMAR CPER-JSON section into CPER binary, outputting to the given stream. 68205dd1d7SLawrence Tang void ir_section_dmar_generic_to_cper(json_object *section, FILE *out) 69205dd1d7SLawrence Tang { 70205dd1d7SLawrence Tang EFI_DMAR_GENERIC_ERROR_DATA *section_cper = 71*e407b4c8SLawrence Tang (EFI_DMAR_GENERIC_ERROR_DATA *)calloc( 72*e407b4c8SLawrence Tang 1, sizeof(EFI_DMAR_GENERIC_ERROR_DATA)); 73205dd1d7SLawrence Tang 74205dd1d7SLawrence Tang //Record fields. 75*e407b4c8SLawrence Tang section_cper->RequesterId = (UINT16)json_object_get_int( 76*e407b4c8SLawrence Tang json_object_object_get(section, "requesterID")); 77*e407b4c8SLawrence Tang section_cper->SegmentNumber = (UINT16)json_object_get_int( 78*e407b4c8SLawrence Tang json_object_object_get(section, "segmentNumber")); 79*e407b4c8SLawrence Tang section_cper->FaultReason = (UINT8)readable_pair_to_integer( 80*e407b4c8SLawrence Tang json_object_object_get(section, "faultReason")); 81*e407b4c8SLawrence Tang section_cper->AccessType = (UINT8)readable_pair_to_integer( 82*e407b4c8SLawrence Tang json_object_object_get(section, "accessType")); 83*e407b4c8SLawrence Tang section_cper->AddressType = (UINT8)readable_pair_to_integer( 84*e407b4c8SLawrence Tang json_object_object_get(section, "addressType")); 85*e407b4c8SLawrence Tang section_cper->ArchType = (UINT8)readable_pair_to_integer( 86*e407b4c8SLawrence Tang json_object_object_get(section, "architectureType")); 87*e407b4c8SLawrence Tang section_cper->DeviceAddr = json_object_get_uint64( 88*e407b4c8SLawrence Tang json_object_object_get(section, "deviceAddress")); 89205dd1d7SLawrence Tang 90205dd1d7SLawrence Tang //Write to stream, free resources. 913ab351feSLawrence Tang fwrite(section_cper, sizeof(EFI_DMAR_GENERIC_ERROR_DATA), 1, out); 92205dd1d7SLawrence Tang fflush(out); 93205dd1d7SLawrence Tang free(section_cper); 94205dd1d7SLawrence Tang }