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> 101b0b00e3SLawrence 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. 161b0b00e3SLawrence Tang json_object* cper_section_generic_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor) 171b0b00e3SLawrence Tang { 183c43f743SLawrence Tang EFI_PROCESSOR_GENERIC_ERROR_DATA* section_generic = (EFI_PROCESSOR_GENERIC_ERROR_DATA*)section; 193c43f743SLawrence Tang json_object* section_ir = json_object_new_object(); 203c43f743SLawrence Tang 213c43f743SLawrence Tang //Validation bits. 2222a467ceSLawrence Tang json_object* validation = bitfield_to_ir(section_generic->ValidFields, 13, GENERIC_VALIDATION_BITFIELD_NAMES); 233c43f743SLawrence Tang json_object_object_add(section_ir, "validationBits", validation); 243c43f743SLawrence Tang 253c43f743SLawrence Tang //Processor type, with human readable name if possible. 263c43f743SLawrence Tang json_object* processor_type = integer_to_readable_pair(section_generic->Type, 273c43f743SLawrence Tang sizeof(GENERIC_PROC_TYPES_KEYS) / sizeof(int), 283c43f743SLawrence Tang GENERIC_PROC_TYPES_KEYS, 293c43f743SLawrence Tang GENERIC_PROC_TYPES_VALUES, 303c43f743SLawrence Tang "Unknown (Reserved)"); 313c43f743SLawrence Tang json_object_object_add(section_ir, "processorType", processor_type); 323c43f743SLawrence Tang 333c43f743SLawrence Tang //Processor ISA, with human readable name if possible. 343c43f743SLawrence Tang json_object* processor_isa = integer_to_readable_pair(section_generic->Isa, 353c43f743SLawrence Tang sizeof(GENERIC_ISA_TYPES_KEYS) / sizeof(int), 363c43f743SLawrence Tang GENERIC_ISA_TYPES_KEYS, 373c43f743SLawrence Tang GENERIC_ISA_TYPES_VALUES, 38*67cbed6bSLawrence Tang "Unknown (Reserved)"); 393c43f743SLawrence Tang json_object_object_add(section_ir, "processorISA", processor_isa); 403c43f743SLawrence Tang 413c43f743SLawrence Tang //Processor error type, with human readable name if possible. 423c43f743SLawrence Tang json_object* processor_error_type = integer_to_readable_pair(section_generic->ErrorType, 433c43f743SLawrence Tang sizeof(GENERIC_ERROR_TYPES_KEYS) / sizeof(int), 443c43f743SLawrence Tang GENERIC_ERROR_TYPES_KEYS, 453c43f743SLawrence Tang GENERIC_ERROR_TYPES_VALUES, 46*67cbed6bSLawrence Tang "Unknown (Reserved)"); 473c43f743SLawrence Tang json_object_object_add(section_ir, "errorType", processor_error_type); 483c43f743SLawrence Tang 493c43f743SLawrence Tang //The operation performed, with a human readable name if possible. 503c43f743SLawrence Tang json_object* operation = integer_to_readable_pair(section_generic->Operation, 513c43f743SLawrence Tang sizeof(GENERIC_OPERATION_TYPES_KEYS) / sizeof(int), 523c43f743SLawrence Tang GENERIC_OPERATION_TYPES_KEYS, 533c43f743SLawrence Tang GENERIC_OPERATION_TYPES_VALUES, 54*67cbed6bSLawrence Tang "Unknown (Reserved)"); 553c43f743SLawrence Tang json_object_object_add(section_ir, "operation", operation); 563c43f743SLawrence Tang 573c43f743SLawrence Tang //Flags, additional information about the error. 5822a467ceSLawrence Tang json_object* flags = bitfield_to_ir(section_generic->Flags, 4, GENERIC_FLAGS_BITFIELD_NAMES); 593c43f743SLawrence Tang json_object_object_add(section_ir, "flags", flags); 603c43f743SLawrence Tang 613c43f743SLawrence Tang //The level of the error. 623c43f743SLawrence Tang json_object_object_add(section_ir, "level", json_object_new_int(section_generic->Level)); 633c43f743SLawrence Tang 649a785c2aSLawrence Tang //CPU version information. 659a785c2aSLawrence Tang json_object_object_add(section_ir, "cpuVersionInfo", json_object_new_uint64(section_generic->VersionInfo)); 663c43f743SLawrence Tang 673c43f743SLawrence Tang //CPU brand string. May not exist if on ARM. 683c43f743SLawrence Tang json_object_object_add(section_ir, "cpuBrandString", json_object_new_string(section_generic->BrandString)); 693c43f743SLawrence Tang 703c43f743SLawrence Tang //Remaining 64-bit fields. 713c43f743SLawrence Tang json_object_object_add(section_ir, "processorID", json_object_new_uint64(section_generic->ApicId)); 723c43f743SLawrence Tang json_object_object_add(section_ir, "targetAddress", json_object_new_uint64(section_generic->TargetAddr)); 733c43f743SLawrence Tang json_object_object_add(section_ir, "requestorID", json_object_new_uint64(section_generic->RequestorId)); 743c43f743SLawrence Tang json_object_object_add(section_ir, "responderID", json_object_new_uint64(section_generic->ResponderId)); 753c43f743SLawrence Tang json_object_object_add(section_ir, "instructionIP", json_object_new_uint64(section_generic->InstructionIP)); 763c43f743SLawrence Tang 773c43f743SLawrence Tang return section_ir; 781b0b00e3SLawrence Tang } 790cb33793SLawrence Tang 800cb33793SLawrence Tang //Converts the given CPER-JSON processor-generic error section into CPER binary, 810cb33793SLawrence Tang //outputting to the provided stream. 820cb33793SLawrence Tang void ir_section_generic_to_cper(json_object* section, FILE* out) 830cb33793SLawrence Tang { 840cb33793SLawrence Tang EFI_PROCESSOR_GENERIC_ERROR_DATA* section_cper = 850cb33793SLawrence Tang (EFI_PROCESSOR_GENERIC_ERROR_DATA*)calloc(1, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA)); 860cb33793SLawrence Tang 870cb33793SLawrence Tang //Validation bits. 880cb33793SLawrence Tang section_cper->ValidFields = ir_to_bitfield(json_object_object_get(section, "validationBits"), 890cb33793SLawrence Tang 11, GENERIC_VALIDATION_BITFIELD_NAMES); 900cb33793SLawrence Tang 910cb33793SLawrence Tang //Various name/value pair fields. 920cb33793SLawrence Tang section_cper->Type = (UINT8)readable_pair_to_integer(json_object_object_get(section, "processorType")); 930cb33793SLawrence Tang section_cper->Isa = (UINT8)readable_pair_to_integer(json_object_object_get(section, "processorISA")); 940cb33793SLawrence Tang section_cper->ErrorType = (UINT8)readable_pair_to_integer(json_object_object_get(section, "errorType")); 950cb33793SLawrence Tang section_cper->Operation = (UINT8)readable_pair_to_integer(json_object_object_get(section, "operation")); 960cb33793SLawrence Tang 970cb33793SLawrence Tang //Flags. 980cb33793SLawrence Tang section_cper->Flags = (UINT8)ir_to_bitfield(json_object_object_get(section, "flags"), 4, GENERIC_FLAGS_BITFIELD_NAMES); 990cb33793SLawrence Tang 1000cb33793SLawrence Tang //Various numeric/string fields. 1010cb33793SLawrence Tang section_cper->Level = (UINT8)json_object_get_int(json_object_object_get(section, "level")); 1020cb33793SLawrence Tang section_cper->VersionInfo = json_object_get_uint64(json_object_object_get(section, "cpuVersionInfo")); 1030cb33793SLawrence Tang section_cper->ApicId = json_object_get_uint64(json_object_object_get(section, "processorID")); 1040cb33793SLawrence Tang section_cper->TargetAddr = json_object_get_uint64(json_object_object_get(section, "targetAddress")); 1050cb33793SLawrence Tang section_cper->RequestorId = json_object_get_uint64(json_object_object_get(section, "requestorID")); 1060cb33793SLawrence Tang section_cper->ResponderId = json_object_get_uint64(json_object_object_get(section, "responderID")); 1070cb33793SLawrence Tang section_cper->InstructionIP = json_object_get_uint64(json_object_object_get(section, "instructionIP")); 1080cb33793SLawrence Tang 1090cb33793SLawrence Tang //CPU brand string. 1100cb33793SLawrence Tang const char* brand_string = json_object_get_string(json_object_object_get(section, "cpuBrandString")); 1110cb33793SLawrence Tang if (brand_string != NULL) 1120cb33793SLawrence Tang strncpy(section_cper->BrandString, brand_string, 127); 1130cb33793SLawrence Tang 1140cb33793SLawrence Tang //Write & flush out to file, free memory. 1150cb33793SLawrence Tang fwrite(section_cper, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA), 1, out); 1160cb33793SLawrence Tang fflush(out); 1170cb33793SLawrence Tang free(section_cper); 1180cb33793SLawrence Tang }