1 /** 2 * Describes functions for converting generic DMAr CPER sections from binary and JSON format 3 * into an intermediate format. 4 * 5 * Author: Lawrence.Tang@arm.com 6 **/ 7 #include <stdio.h> 8 #include <json.h> 9 #include <libcper/Cper.h> 10 #include <libcper/cper-utils.h> 11 #include <libcper/sections/cper-section-dmar-generic.h> 12 #include <libcper/log.h> 13 14 //Converts a single generic DMAr CPER section into JSON IR. 15 json_object *cper_section_dmar_generic_to_ir(const UINT8 *section, UINT32 size) 16 { 17 if (size < sizeof(EFI_DMAR_GENERIC_ERROR_DATA)) { 18 return NULL; 19 } 20 21 EFI_DMAR_GENERIC_ERROR_DATA *firmware_error = 22 (EFI_DMAR_GENERIC_ERROR_DATA *)section; 23 json_object *section_ir = json_object_new_object(); 24 25 //Requester ID, segment. 26 json_object_object_add( 27 section_ir, "requesterID", 28 json_object_new_int(firmware_error->RequesterId)); 29 json_object_object_add( 30 section_ir, "segmentNumber", 31 json_object_new_int(firmware_error->SegmentNumber)); 32 33 //Fault reason. 34 json_object *fault_reason = integer_to_readable_pair_with_desc( 35 firmware_error->FaultReason, 11, 36 DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_KEYS, 37 DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_VALUES, 38 DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_DESCRIPTIONS, 39 "Unknown (Reserved)"); 40 json_object_object_add(section_ir, "faultReason", fault_reason); 41 42 //Access type. 43 json_object *access_type = integer_to_readable_pair( 44 firmware_error->AccessType, 2, 45 DMAR_GENERIC_ERROR_ACCESS_TYPES_KEYS, 46 DMAR_GENERIC_ERROR_ACCESS_TYPES_VALUES, "Unknown (Reserved)"); 47 json_object_object_add(section_ir, "accessType", access_type); 48 49 //Address type. 50 json_object *address_type = integer_to_readable_pair( 51 firmware_error->AddressType, 2, 52 DMAR_GENERIC_ERROR_ADDRESS_TYPES_KEYS, 53 DMAR_GENERIC_ERROR_ADDRESS_TYPES_VALUES, "Unknown (Reserved)"); 54 json_object_object_add(section_ir, "addressType", address_type); 55 56 //Architecture type. 57 json_object *arch_type = integer_to_readable_pair( 58 firmware_error->ArchType, 2, DMAR_GENERIC_ERROR_ARCH_TYPES_KEYS, 59 DMAR_GENERIC_ERROR_ARCH_TYPES_VALUES, "Unknown (Reserved)"); 60 json_object_object_add(section_ir, "architectureType", arch_type); 61 62 //Device address. 63 json_object_object_add( 64 section_ir, "deviceAddress", 65 json_object_new_uint64(firmware_error->DeviceAddr)); 66 67 return section_ir; 68 } 69 70 //Converts a single generic DMAR CPER-JSON section into CPER binary, outputting to the given stream. 71 void ir_section_dmar_generic_to_cper(json_object *section, FILE *out) 72 { 73 EFI_DMAR_GENERIC_ERROR_DATA *section_cper = 74 (EFI_DMAR_GENERIC_ERROR_DATA *)calloc( 75 1, sizeof(EFI_DMAR_GENERIC_ERROR_DATA)); 76 77 //Record fields. 78 section_cper->RequesterId = (UINT16)json_object_get_int( 79 json_object_object_get(section, "requesterID")); 80 section_cper->SegmentNumber = (UINT16)json_object_get_int( 81 json_object_object_get(section, "segmentNumber")); 82 section_cper->FaultReason = (UINT8)readable_pair_to_integer( 83 json_object_object_get(section, "faultReason")); 84 section_cper->AccessType = (UINT8)readable_pair_to_integer( 85 json_object_object_get(section, "accessType")); 86 section_cper->AddressType = (UINT8)readable_pair_to_integer( 87 json_object_object_get(section, "addressType")); 88 section_cper->ArchType = (UINT8)readable_pair_to_integer( 89 json_object_object_get(section, "architectureType")); 90 section_cper->DeviceAddr = json_object_get_uint64( 91 json_object_object_get(section, "deviceAddress")); 92 93 //Write to stream, free resources. 94 fwrite(section_cper, sizeof(EFI_DMAR_GENERIC_ERROR_DATA), 1, out); 95 fflush(out); 96 free(section_cper); 97 } 98