11b0b00e3SLawrence Tang /** 21b0b00e3SLawrence Tang * Describes functions for converting processor-generic CPER sections from binary and JSON format 31b0b00e3SLawrence Tang * into an intermediate format. 41b0b00e3SLawrence Tang * 51b0b00e3SLawrence Tang * Author: Lawrence.Tang@arm.com 61b0b00e3SLawrence Tang **/ 71b0b00e3SLawrence Tang 81b0b00e3SLawrence Tang #include <stdio.h> 90cb33793SLawrence Tang #include <string.h> 105202bbb4SLawrence Tang #include <json.h> 111b0b00e3SLawrence Tang #include "../edk/Cper.h" 121b0b00e3SLawrence Tang #include "../cper-utils.h" 133c43f743SLawrence Tang #include "cper-section-generic.h" 141b0b00e3SLawrence Tang 151b0b00e3SLawrence Tang //Converts the given processor-generic CPER section into JSON IR. 16*f8fc7052SJohn Chung json_object *cper_section_generic_to_ir(void *section) 171b0b00e3SLawrence Tang { 18e407b4c8SLawrence Tang EFI_PROCESSOR_GENERIC_ERROR_DATA *section_generic = 19e407b4c8SLawrence Tang (EFI_PROCESSOR_GENERIC_ERROR_DATA *)section; 203c43f743SLawrence Tang json_object *section_ir = json_object_new_object(); 213c43f743SLawrence Tang 223c43f743SLawrence Tang //Validation bits. 23e407b4c8SLawrence Tang json_object *validation = 24e407b4c8SLawrence Tang bitfield_to_ir(section_generic->ValidFields, 13, 25e407b4c8SLawrence Tang GENERIC_VALIDATION_BITFIELD_NAMES); 263c43f743SLawrence Tang json_object_object_add(section_ir, "validationBits", validation); 273c43f743SLawrence Tang 283c43f743SLawrence Tang //Processor type, with human readable name if possible. 29e407b4c8SLawrence Tang json_object *processor_type = integer_to_readable_pair( 30e407b4c8SLawrence Tang section_generic->Type, 313c43f743SLawrence Tang sizeof(GENERIC_PROC_TYPES_KEYS) / sizeof(int), 32e407b4c8SLawrence Tang GENERIC_PROC_TYPES_KEYS, GENERIC_PROC_TYPES_VALUES, 333c43f743SLawrence Tang "Unknown (Reserved)"); 343c43f743SLawrence Tang json_object_object_add(section_ir, "processorType", processor_type); 353c43f743SLawrence Tang 363c43f743SLawrence Tang //Processor ISA, with human readable name if possible. 37e407b4c8SLawrence Tang json_object *processor_isa = integer_to_readable_pair( 38e407b4c8SLawrence Tang section_generic->Isa, 393c43f743SLawrence Tang sizeof(GENERIC_ISA_TYPES_KEYS) / sizeof(int), 40e407b4c8SLawrence Tang GENERIC_ISA_TYPES_KEYS, GENERIC_ISA_TYPES_VALUES, 4167cbed6bSLawrence Tang "Unknown (Reserved)"); 423c43f743SLawrence Tang json_object_object_add(section_ir, "processorISA", processor_isa); 433c43f743SLawrence Tang 443c43f743SLawrence Tang //Processor error type, with human readable name if possible. 45e407b4c8SLawrence Tang json_object *processor_error_type = integer_to_readable_pair( 46e407b4c8SLawrence Tang section_generic->ErrorType, 473c43f743SLawrence Tang sizeof(GENERIC_ERROR_TYPES_KEYS) / sizeof(int), 48e407b4c8SLawrence Tang GENERIC_ERROR_TYPES_KEYS, GENERIC_ERROR_TYPES_VALUES, 4967cbed6bSLawrence Tang "Unknown (Reserved)"); 503c43f743SLawrence Tang json_object_object_add(section_ir, "errorType", processor_error_type); 513c43f743SLawrence Tang 523c43f743SLawrence Tang //The operation performed, with a human readable name if possible. 53e407b4c8SLawrence Tang json_object *operation = integer_to_readable_pair( 54e407b4c8SLawrence Tang section_generic->Operation, 553c43f743SLawrence Tang sizeof(GENERIC_OPERATION_TYPES_KEYS) / sizeof(int), 56e407b4c8SLawrence Tang GENERIC_OPERATION_TYPES_KEYS, GENERIC_OPERATION_TYPES_VALUES, 5767cbed6bSLawrence Tang "Unknown (Reserved)"); 583c43f743SLawrence Tang json_object_object_add(section_ir, "operation", operation); 593c43f743SLawrence Tang 603c43f743SLawrence Tang //Flags, additional information about the error. 61e407b4c8SLawrence Tang json_object *flags = bitfield_to_ir(section_generic->Flags, 4, 62e407b4c8SLawrence Tang GENERIC_FLAGS_BITFIELD_NAMES); 633c43f743SLawrence Tang json_object_object_add(section_ir, "flags", flags); 643c43f743SLawrence Tang 653c43f743SLawrence Tang //The level of the error. 66e407b4c8SLawrence Tang json_object_object_add(section_ir, "level", 67e407b4c8SLawrence Tang json_object_new_int(section_generic->Level)); 683c43f743SLawrence Tang 699a785c2aSLawrence Tang //CPU version information. 70e407b4c8SLawrence Tang json_object_object_add( 71e407b4c8SLawrence Tang section_ir, "cpuVersionInfo", 72e407b4c8SLawrence Tang json_object_new_uint64(section_generic->VersionInfo)); 733c43f743SLawrence Tang 743c43f743SLawrence Tang //CPU brand string. May not exist if on ARM. 75e407b4c8SLawrence Tang json_object_object_add( 76e407b4c8SLawrence Tang section_ir, "cpuBrandString", 77e407b4c8SLawrence Tang json_object_new_string(section_generic->BrandString)); 783c43f743SLawrence Tang 793c43f743SLawrence Tang //Remaining 64-bit fields. 80e407b4c8SLawrence Tang json_object_object_add(section_ir, "processorID", 81e407b4c8SLawrence Tang json_object_new_uint64(section_generic->ApicId)); 82e407b4c8SLawrence Tang json_object_object_add( 83e407b4c8SLawrence Tang section_ir, "targetAddress", 84e407b4c8SLawrence Tang json_object_new_uint64(section_generic->TargetAddr)); 85e407b4c8SLawrence Tang json_object_object_add( 86e407b4c8SLawrence Tang section_ir, "requestorID", 87e407b4c8SLawrence Tang json_object_new_uint64(section_generic->RequestorId)); 88e407b4c8SLawrence Tang json_object_object_add( 89e407b4c8SLawrence Tang section_ir, "responderID", 90e407b4c8SLawrence Tang json_object_new_uint64(section_generic->ResponderId)); 91e407b4c8SLawrence Tang json_object_object_add( 92e407b4c8SLawrence Tang section_ir, "instructionIP", 93e407b4c8SLawrence Tang json_object_new_uint64(section_generic->InstructionIP)); 943c43f743SLawrence Tang 953c43f743SLawrence Tang return section_ir; 961b0b00e3SLawrence Tang } 970cb33793SLawrence Tang 980cb33793SLawrence Tang //Converts the given CPER-JSON processor-generic error section into CPER binary, 990cb33793SLawrence Tang //outputting to the provided stream. 1000cb33793SLawrence Tang void ir_section_generic_to_cper(json_object *section, FILE *out) 1010cb33793SLawrence Tang { 1020cb33793SLawrence Tang EFI_PROCESSOR_GENERIC_ERROR_DATA *section_cper = 103e407b4c8SLawrence Tang (EFI_PROCESSOR_GENERIC_ERROR_DATA *)calloc( 104e407b4c8SLawrence Tang 1, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA)); 1050cb33793SLawrence Tang 1060cb33793SLawrence Tang //Validation bits. 107e407b4c8SLawrence Tang section_cper->ValidFields = ir_to_bitfield( 108e407b4c8SLawrence Tang json_object_object_get(section, "validationBits"), 13, 109e407b4c8SLawrence Tang GENERIC_VALIDATION_BITFIELD_NAMES); 1100cb33793SLawrence Tang 1110cb33793SLawrence Tang //Various name/value pair fields. 112e407b4c8SLawrence Tang section_cper->Type = (UINT8)readable_pair_to_integer( 113e407b4c8SLawrence Tang json_object_object_get(section, "processorType")); 114e407b4c8SLawrence Tang section_cper->Isa = (UINT8)readable_pair_to_integer( 115e407b4c8SLawrence Tang json_object_object_get(section, "processorISA")); 116e407b4c8SLawrence Tang section_cper->ErrorType = (UINT8)readable_pair_to_integer( 117e407b4c8SLawrence Tang json_object_object_get(section, "errorType")); 118e407b4c8SLawrence Tang section_cper->Operation = (UINT8)readable_pair_to_integer( 119e407b4c8SLawrence Tang json_object_object_get(section, "operation")); 1200cb33793SLawrence Tang 1210cb33793SLawrence Tang //Flags. 122e407b4c8SLawrence Tang section_cper->Flags = 123e407b4c8SLawrence Tang (UINT8)ir_to_bitfield(json_object_object_get(section, "flags"), 124e407b4c8SLawrence Tang 4, GENERIC_FLAGS_BITFIELD_NAMES); 1250cb33793SLawrence Tang 1260cb33793SLawrence Tang //Various numeric/string fields. 127e407b4c8SLawrence Tang section_cper->Level = (UINT8)json_object_get_int( 128e407b4c8SLawrence Tang json_object_object_get(section, "level")); 129e407b4c8SLawrence Tang section_cper->VersionInfo = json_object_get_uint64( 130e407b4c8SLawrence Tang json_object_object_get(section, "cpuVersionInfo")); 131e407b4c8SLawrence Tang section_cper->ApicId = json_object_get_uint64( 132e407b4c8SLawrence Tang json_object_object_get(section, "processorID")); 133e407b4c8SLawrence Tang section_cper->TargetAddr = json_object_get_uint64( 134e407b4c8SLawrence Tang json_object_object_get(section, "targetAddress")); 135e407b4c8SLawrence Tang section_cper->RequestorId = json_object_get_uint64( 136e407b4c8SLawrence Tang json_object_object_get(section, "requestorID")); 137e407b4c8SLawrence Tang section_cper->ResponderId = json_object_get_uint64( 138e407b4c8SLawrence Tang json_object_object_get(section, "responderID")); 139e407b4c8SLawrence Tang section_cper->InstructionIP = json_object_get_uint64( 140e407b4c8SLawrence Tang json_object_object_get(section, "instructionIP")); 1410cb33793SLawrence Tang 1420cb33793SLawrence Tang //CPU brand string. 143e407b4c8SLawrence Tang const char *brand_string = json_object_get_string( 144e407b4c8SLawrence Tang json_object_object_get(section, "cpuBrandString")); 145*f8fc7052SJohn Chung if (brand_string != NULL) { 1460cb33793SLawrence Tang strncpy(section_cper->BrandString, brand_string, 127); 147*f8fc7052SJohn Chung } 1480cb33793SLawrence Tang 1490cb33793SLawrence Tang //Write & flush out to file, free memory. 1500cb33793SLawrence Tang fwrite(section_cper, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA), 1, out); 1510cb33793SLawrence Tang fflush(out); 1520cb33793SLawrence Tang free(section_cper); 1530cb33793SLawrence Tang } 154