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