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