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