1 /** 2 * Describes functions for converting processor-generic CPER sections from binary and JSON format 3 * into an intermediate format. 4 * 5 * Author: Lawrence.Tang@arm.com 6 **/ 7 8 #include <stdio.h> 9 #include <string.h> 10 #include <json.h> 11 #include "../edk/Cper.h" 12 #include "../cper-utils.h" 13 #include "cper-section-generic.h" 14 15 //Converts the given processor-generic CPER section into JSON IR. 16 json_object * 17 cper_section_generic_to_ir(void *section, 18 EFI_ERROR_SECTION_DESCRIPTOR *descriptor) 19 { 20 EFI_PROCESSOR_GENERIC_ERROR_DATA *section_generic = 21 (EFI_PROCESSOR_GENERIC_ERROR_DATA *)section; 22 json_object *section_ir = json_object_new_object(); 23 24 //Validation bits. 25 json_object *validation = 26 bitfield_to_ir(section_generic->ValidFields, 13, 27 GENERIC_VALIDATION_BITFIELD_NAMES); 28 json_object_object_add(section_ir, "validationBits", validation); 29 30 //Processor type, with human readable name if possible. 31 json_object *processor_type = integer_to_readable_pair( 32 section_generic->Type, 33 sizeof(GENERIC_PROC_TYPES_KEYS) / sizeof(int), 34 GENERIC_PROC_TYPES_KEYS, GENERIC_PROC_TYPES_VALUES, 35 "Unknown (Reserved)"); 36 json_object_object_add(section_ir, "processorType", processor_type); 37 38 //Processor ISA, with human readable name if possible. 39 json_object *processor_isa = integer_to_readable_pair( 40 section_generic->Isa, 41 sizeof(GENERIC_ISA_TYPES_KEYS) / sizeof(int), 42 GENERIC_ISA_TYPES_KEYS, GENERIC_ISA_TYPES_VALUES, 43 "Unknown (Reserved)"); 44 json_object_object_add(section_ir, "processorISA", processor_isa); 45 46 //Processor error type, with human readable name if possible. 47 json_object *processor_error_type = integer_to_readable_pair( 48 section_generic->ErrorType, 49 sizeof(GENERIC_ERROR_TYPES_KEYS) / sizeof(int), 50 GENERIC_ERROR_TYPES_KEYS, GENERIC_ERROR_TYPES_VALUES, 51 "Unknown (Reserved)"); 52 json_object_object_add(section_ir, "errorType", processor_error_type); 53 54 //The operation performed, with a human readable name if possible. 55 json_object *operation = integer_to_readable_pair( 56 section_generic->Operation, 57 sizeof(GENERIC_OPERATION_TYPES_KEYS) / sizeof(int), 58 GENERIC_OPERATION_TYPES_KEYS, GENERIC_OPERATION_TYPES_VALUES, 59 "Unknown (Reserved)"); 60 json_object_object_add(section_ir, "operation", operation); 61 62 //Flags, additional information about the error. 63 json_object *flags = bitfield_to_ir(section_generic->Flags, 4, 64 GENERIC_FLAGS_BITFIELD_NAMES); 65 json_object_object_add(section_ir, "flags", flags); 66 67 //The level of the error. 68 json_object_object_add(section_ir, "level", 69 json_object_new_int(section_generic->Level)); 70 71 //CPU version information. 72 json_object_object_add( 73 section_ir, "cpuVersionInfo", 74 json_object_new_uint64(section_generic->VersionInfo)); 75 76 //CPU brand string. May not exist if on ARM. 77 json_object_object_add( 78 section_ir, "cpuBrandString", 79 json_object_new_string(section_generic->BrandString)); 80 81 //Remaining 64-bit fields. 82 json_object_object_add(section_ir, "processorID", 83 json_object_new_uint64(section_generic->ApicId)); 84 json_object_object_add( 85 section_ir, "targetAddress", 86 json_object_new_uint64(section_generic->TargetAddr)); 87 json_object_object_add( 88 section_ir, "requestorID", 89 json_object_new_uint64(section_generic->RequestorId)); 90 json_object_object_add( 91 section_ir, "responderID", 92 json_object_new_uint64(section_generic->ResponderId)); 93 json_object_object_add( 94 section_ir, "instructionIP", 95 json_object_new_uint64(section_generic->InstructionIP)); 96 97 return section_ir; 98 } 99 100 //Converts the given CPER-JSON processor-generic error section into CPER binary, 101 //outputting to the provided stream. 102 void ir_section_generic_to_cper(json_object *section, FILE *out) 103 { 104 EFI_PROCESSOR_GENERIC_ERROR_DATA *section_cper = 105 (EFI_PROCESSOR_GENERIC_ERROR_DATA *)calloc( 106 1, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA)); 107 108 //Validation bits. 109 section_cper->ValidFields = ir_to_bitfield( 110 json_object_object_get(section, "validationBits"), 13, 111 GENERIC_VALIDATION_BITFIELD_NAMES); 112 113 //Various name/value pair fields. 114 section_cper->Type = (UINT8)readable_pair_to_integer( 115 json_object_object_get(section, "processorType")); 116 section_cper->Isa = (UINT8)readable_pair_to_integer( 117 json_object_object_get(section, "processorISA")); 118 section_cper->ErrorType = (UINT8)readable_pair_to_integer( 119 json_object_object_get(section, "errorType")); 120 section_cper->Operation = (UINT8)readable_pair_to_integer( 121 json_object_object_get(section, "operation")); 122 123 //Flags. 124 section_cper->Flags = 125 (UINT8)ir_to_bitfield(json_object_object_get(section, "flags"), 126 4, GENERIC_FLAGS_BITFIELD_NAMES); 127 128 //Various numeric/string fields. 129 section_cper->Level = (UINT8)json_object_get_int( 130 json_object_object_get(section, "level")); 131 section_cper->VersionInfo = json_object_get_uint64( 132 json_object_object_get(section, "cpuVersionInfo")); 133 section_cper->ApicId = json_object_get_uint64( 134 json_object_object_get(section, "processorID")); 135 section_cper->TargetAddr = json_object_get_uint64( 136 json_object_object_get(section, "targetAddress")); 137 section_cper->RequestorId = json_object_get_uint64( 138 json_object_object_get(section, "requestorID")); 139 section_cper->ResponderId = json_object_get_uint64( 140 json_object_object_get(section, "responderID")); 141 section_cper->InstructionIP = json_object_get_uint64( 142 json_object_object_get(section, "instructionIP")); 143 144 //CPU brand string. 145 const char *brand_string = json_object_get_string( 146 json_object_object_get(section, "cpuBrandString")); 147 if (brand_string != NULL) 148 strncpy(section_cper->BrandString, brand_string, 127); 149 150 //Write & flush out to file, free memory. 151 fwrite(section_cper, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA), 1, out); 152 fflush(out); 153 free(section_cper); 154 }