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> 10*5202bbb4SLawrence 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. 16e407b4c8SLawrence Tang json_object * 17e407b4c8SLawrence Tang cper_section_generic_to_ir(void *section, 18e407b4c8SLawrence Tang EFI_ERROR_SECTION_DESCRIPTOR *descriptor) 191b0b00e3SLawrence Tang { 20e407b4c8SLawrence Tang EFI_PROCESSOR_GENERIC_ERROR_DATA *section_generic = 21e407b4c8SLawrence Tang (EFI_PROCESSOR_GENERIC_ERROR_DATA *)section; 223c43f743SLawrence Tang json_object *section_ir = json_object_new_object(); 233c43f743SLawrence Tang 243c43f743SLawrence Tang //Validation bits. 25e407b4c8SLawrence Tang json_object *validation = 26e407b4c8SLawrence Tang bitfield_to_ir(section_generic->ValidFields, 13, 27e407b4c8SLawrence Tang GENERIC_VALIDATION_BITFIELD_NAMES); 283c43f743SLawrence Tang json_object_object_add(section_ir, "validationBits", validation); 293c43f743SLawrence Tang 303c43f743SLawrence Tang //Processor type, with human readable name if possible. 31e407b4c8SLawrence Tang json_object *processor_type = integer_to_readable_pair( 32e407b4c8SLawrence Tang section_generic->Type, 333c43f743SLawrence Tang sizeof(GENERIC_PROC_TYPES_KEYS) / sizeof(int), 34e407b4c8SLawrence Tang GENERIC_PROC_TYPES_KEYS, GENERIC_PROC_TYPES_VALUES, 353c43f743SLawrence Tang "Unknown (Reserved)"); 363c43f743SLawrence Tang json_object_object_add(section_ir, "processorType", processor_type); 373c43f743SLawrence Tang 383c43f743SLawrence Tang //Processor ISA, with human readable name if possible. 39e407b4c8SLawrence Tang json_object *processor_isa = integer_to_readable_pair( 40e407b4c8SLawrence Tang section_generic->Isa, 413c43f743SLawrence Tang sizeof(GENERIC_ISA_TYPES_KEYS) / sizeof(int), 42e407b4c8SLawrence Tang GENERIC_ISA_TYPES_KEYS, GENERIC_ISA_TYPES_VALUES, 4367cbed6bSLawrence Tang "Unknown (Reserved)"); 443c43f743SLawrence Tang json_object_object_add(section_ir, "processorISA", processor_isa); 453c43f743SLawrence Tang 463c43f743SLawrence Tang //Processor error type, with human readable name if possible. 47e407b4c8SLawrence Tang json_object *processor_error_type = integer_to_readable_pair( 48e407b4c8SLawrence Tang section_generic->ErrorType, 493c43f743SLawrence Tang sizeof(GENERIC_ERROR_TYPES_KEYS) / sizeof(int), 50e407b4c8SLawrence Tang GENERIC_ERROR_TYPES_KEYS, GENERIC_ERROR_TYPES_VALUES, 5167cbed6bSLawrence Tang "Unknown (Reserved)"); 523c43f743SLawrence Tang json_object_object_add(section_ir, "errorType", processor_error_type); 533c43f743SLawrence Tang 543c43f743SLawrence Tang //The operation performed, with a human readable name if possible. 55e407b4c8SLawrence Tang json_object *operation = integer_to_readable_pair( 56e407b4c8SLawrence Tang section_generic->Operation, 573c43f743SLawrence Tang sizeof(GENERIC_OPERATION_TYPES_KEYS) / sizeof(int), 58e407b4c8SLawrence Tang GENERIC_OPERATION_TYPES_KEYS, GENERIC_OPERATION_TYPES_VALUES, 5967cbed6bSLawrence Tang "Unknown (Reserved)"); 603c43f743SLawrence Tang json_object_object_add(section_ir, "operation", operation); 613c43f743SLawrence Tang 623c43f743SLawrence Tang //Flags, additional information about the error. 63e407b4c8SLawrence Tang json_object *flags = bitfield_to_ir(section_generic->Flags, 4, 64e407b4c8SLawrence Tang GENERIC_FLAGS_BITFIELD_NAMES); 653c43f743SLawrence Tang json_object_object_add(section_ir, "flags", flags); 663c43f743SLawrence Tang 673c43f743SLawrence Tang //The level of the error. 68e407b4c8SLawrence Tang json_object_object_add(section_ir, "level", 69e407b4c8SLawrence Tang json_object_new_int(section_generic->Level)); 703c43f743SLawrence Tang 719a785c2aSLawrence Tang //CPU version information. 72e407b4c8SLawrence Tang json_object_object_add( 73e407b4c8SLawrence Tang section_ir, "cpuVersionInfo", 74e407b4c8SLawrence Tang json_object_new_uint64(section_generic->VersionInfo)); 753c43f743SLawrence Tang 763c43f743SLawrence Tang //CPU brand string. May not exist if on ARM. 77e407b4c8SLawrence Tang json_object_object_add( 78e407b4c8SLawrence Tang section_ir, "cpuBrandString", 79e407b4c8SLawrence Tang json_object_new_string(section_generic->BrandString)); 803c43f743SLawrence Tang 813c43f743SLawrence Tang //Remaining 64-bit fields. 82e407b4c8SLawrence Tang json_object_object_add(section_ir, "processorID", 83e407b4c8SLawrence Tang json_object_new_uint64(section_generic->ApicId)); 84e407b4c8SLawrence Tang json_object_object_add( 85e407b4c8SLawrence Tang section_ir, "targetAddress", 86e407b4c8SLawrence Tang json_object_new_uint64(section_generic->TargetAddr)); 87e407b4c8SLawrence Tang json_object_object_add( 88e407b4c8SLawrence Tang section_ir, "requestorID", 89e407b4c8SLawrence Tang json_object_new_uint64(section_generic->RequestorId)); 90e407b4c8SLawrence Tang json_object_object_add( 91e407b4c8SLawrence Tang section_ir, "responderID", 92e407b4c8SLawrence Tang json_object_new_uint64(section_generic->ResponderId)); 93e407b4c8SLawrence Tang json_object_object_add( 94e407b4c8SLawrence Tang section_ir, "instructionIP", 95e407b4c8SLawrence Tang json_object_new_uint64(section_generic->InstructionIP)); 963c43f743SLawrence Tang 973c43f743SLawrence Tang return section_ir; 981b0b00e3SLawrence Tang } 990cb33793SLawrence Tang 1000cb33793SLawrence Tang //Converts the given CPER-JSON processor-generic error section into CPER binary, 1010cb33793SLawrence Tang //outputting to the provided stream. 1020cb33793SLawrence Tang void ir_section_generic_to_cper(json_object *section, FILE *out) 1030cb33793SLawrence Tang { 1040cb33793SLawrence Tang EFI_PROCESSOR_GENERIC_ERROR_DATA *section_cper = 105e407b4c8SLawrence Tang (EFI_PROCESSOR_GENERIC_ERROR_DATA *)calloc( 106e407b4c8SLawrence Tang 1, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA)); 1070cb33793SLawrence Tang 1080cb33793SLawrence Tang //Validation bits. 109e407b4c8SLawrence Tang section_cper->ValidFields = ir_to_bitfield( 110e407b4c8SLawrence Tang json_object_object_get(section, "validationBits"), 13, 111e407b4c8SLawrence Tang GENERIC_VALIDATION_BITFIELD_NAMES); 1120cb33793SLawrence Tang 1130cb33793SLawrence Tang //Various name/value pair fields. 114e407b4c8SLawrence Tang section_cper->Type = (UINT8)readable_pair_to_integer( 115e407b4c8SLawrence Tang json_object_object_get(section, "processorType")); 116e407b4c8SLawrence Tang section_cper->Isa = (UINT8)readable_pair_to_integer( 117e407b4c8SLawrence Tang json_object_object_get(section, "processorISA")); 118e407b4c8SLawrence Tang section_cper->ErrorType = (UINT8)readable_pair_to_integer( 119e407b4c8SLawrence Tang json_object_object_get(section, "errorType")); 120e407b4c8SLawrence Tang section_cper->Operation = (UINT8)readable_pair_to_integer( 121e407b4c8SLawrence Tang json_object_object_get(section, "operation")); 1220cb33793SLawrence Tang 1230cb33793SLawrence Tang //Flags. 124e407b4c8SLawrence Tang section_cper->Flags = 125e407b4c8SLawrence Tang (UINT8)ir_to_bitfield(json_object_object_get(section, "flags"), 126e407b4c8SLawrence Tang 4, GENERIC_FLAGS_BITFIELD_NAMES); 1270cb33793SLawrence Tang 1280cb33793SLawrence Tang //Various numeric/string fields. 129e407b4c8SLawrence Tang section_cper->Level = (UINT8)json_object_get_int( 130e407b4c8SLawrence Tang json_object_object_get(section, "level")); 131e407b4c8SLawrence Tang section_cper->VersionInfo = json_object_get_uint64( 132e407b4c8SLawrence Tang json_object_object_get(section, "cpuVersionInfo")); 133e407b4c8SLawrence Tang section_cper->ApicId = json_object_get_uint64( 134e407b4c8SLawrence Tang json_object_object_get(section, "processorID")); 135e407b4c8SLawrence Tang section_cper->TargetAddr = json_object_get_uint64( 136e407b4c8SLawrence Tang json_object_object_get(section, "targetAddress")); 137e407b4c8SLawrence Tang section_cper->RequestorId = json_object_get_uint64( 138e407b4c8SLawrence Tang json_object_object_get(section, "requestorID")); 139e407b4c8SLawrence Tang section_cper->ResponderId = json_object_get_uint64( 140e407b4c8SLawrence Tang json_object_object_get(section, "responderID")); 141e407b4c8SLawrence Tang section_cper->InstructionIP = json_object_get_uint64( 142e407b4c8SLawrence Tang json_object_object_get(section, "instructionIP")); 1430cb33793SLawrence Tang 1440cb33793SLawrence Tang //CPU brand string. 145e407b4c8SLawrence Tang const char *brand_string = json_object_get_string( 146e407b4c8SLawrence Tang json_object_object_get(section, "cpuBrandString")); 1470cb33793SLawrence Tang if (brand_string != NULL) 1480cb33793SLawrence Tang strncpy(section_cper->BrandString, brand_string, 127); 1490cb33793SLawrence Tang 1500cb33793SLawrence Tang //Write & flush out to file, free memory. 1510cb33793SLawrence Tang fwrite(section_cper, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA), 1, out); 1520cb33793SLawrence Tang fflush(out); 1530cb33793SLawrence Tang free(section_cper); 1540cb33793SLawrence Tang }