17f21db6cSLawrence Tang /** 27f21db6cSLawrence Tang * Describes functions for converting memory error CPER sections from binary and JSON format 37f21db6cSLawrence Tang * into an intermediate format. 47f21db6cSLawrence Tang * 57f21db6cSLawrence Tang * Author: Lawrence.Tang@arm.com 67f21db6cSLawrence Tang **/ 77f21db6cSLawrence Tang #include <stdio.h> 87f21db6cSLawrence Tang #include "json.h" 97f21db6cSLawrence Tang #include "../edk/Cper.h" 107f21db6cSLawrence Tang #include "../cper-utils.h" 117f21db6cSLawrence Tang #include "cper-section-memory.h" 127f21db6cSLawrence Tang 137f21db6cSLawrence Tang //Converts a single memory error CPER section into JSON IR. 14a0865e38SLawrence Tang json_object* cper_section_platform_memory_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor) 157f21db6cSLawrence Tang { 167f21db6cSLawrence Tang EFI_PLATFORM_MEMORY_ERROR_DATA* memory_error = (EFI_PLATFORM_MEMORY_ERROR_DATA*)section; 177f21db6cSLawrence Tang json_object* section_ir = json_object_new_object(); 187f21db6cSLawrence Tang 197f21db6cSLawrence Tang //Validation bitfield. 207f21db6cSLawrence Tang json_object* validation = bitfield_to_ir(memory_error->ValidFields, 22, MEMORY_ERROR_VALID_BITFIELD_NAMES); 217f21db6cSLawrence Tang json_object_object_add(section_ir, "validationBits", validation); 227f21db6cSLawrence Tang 237f21db6cSLawrence Tang //Error status. 24a0865e38SLawrence Tang json_object* error_status = cper_generic_error_status_to_ir(&memory_error->ErrorStatus); 25a0865e38SLawrence Tang json_object_object_add(section_ir, "errorStatus", error_status); 26a0865e38SLawrence Tang 27a0865e38SLawrence Tang //Bank. 28a0865e38SLawrence Tang json_object* bank = json_object_new_object(); 29583cdeeeSLawrence Tang if ((memory_error->ValidFields >> 5) & 0x1) 30583cdeeeSLawrence Tang { 31583cdeeeSLawrence Tang //Entire bank address mode. 32583cdeeeSLawrence Tang json_object_object_add(bank, "value", json_object_new_uint64(memory_error->Bank)); 33583cdeeeSLawrence Tang } 34583cdeeeSLawrence Tang else 35583cdeeeSLawrence Tang { 36583cdeeeSLawrence Tang //Address/group address mode. 37a0865e38SLawrence Tang json_object_object_add(bank, "address", json_object_new_uint64(memory_error->Bank & 0xFF)); 38a0865e38SLawrence Tang json_object_object_add(bank, "group", json_object_new_uint64(memory_error->Bank >> 8)); 39583cdeeeSLawrence Tang } 40a0865e38SLawrence Tang json_object_object_add(section_ir, "bank", bank); 41a0865e38SLawrence Tang 42a0865e38SLawrence Tang //Memory error type. 43a0865e38SLawrence Tang json_object* memory_error_type = integer_to_readable_pair(memory_error->ErrorType, 16, 44a0865e38SLawrence Tang MEMORY_ERROR_TYPES_KEYS, 45a0865e38SLawrence Tang MEMORY_ERROR_TYPES_VALUES, 46a0865e38SLawrence Tang "Unknown (Reserved)"); 47a0865e38SLawrence Tang json_object_object_add(section_ir, "memoryErrorType", memory_error_type); 48a0865e38SLawrence Tang 49a0865e38SLawrence Tang //"Extended" row/column indication field + misc. 50a0865e38SLawrence Tang json_object* extended = json_object_new_object(); 51a0865e38SLawrence Tang json_object_object_add(extended, "rowBit16", json_object_new_boolean(memory_error->Extended & 0b1)); 52a0865e38SLawrence Tang json_object_object_add(extended, "rowBit17", json_object_new_boolean((memory_error->Extended >> 1) & 0b1)); 53a0865e38SLawrence Tang json_object_object_add(extended, "chipIdentification", json_object_new_int(memory_error->Extended >> 5)); 54a0865e38SLawrence Tang json_object_object_add(section_ir, "extended", extended); 55a0865e38SLawrence Tang 5654da4414SLawrence Tang //Miscellaneous numeric fields. 5754da4414SLawrence Tang json_object_object_add(section_ir, "physicalAddress", json_object_new_uint64(memory_error->PhysicalAddress)); 5854da4414SLawrence Tang json_object_object_add(section_ir, "physicalAddressMask", json_object_new_uint64(memory_error->PhysicalAddressMask)); 5954da4414SLawrence Tang json_object_object_add(section_ir, "node", json_object_new_uint64(memory_error->Node)); 6054da4414SLawrence Tang json_object_object_add(section_ir, "card", json_object_new_uint64(memory_error->Card)); 6154da4414SLawrence Tang json_object_object_add(section_ir, "moduleRank", json_object_new_uint64(memory_error->ModuleRank)); 6254da4414SLawrence Tang json_object_object_add(section_ir, "device", json_object_new_uint64(memory_error->Device)); 6354da4414SLawrence Tang json_object_object_add(section_ir, "row", json_object_new_uint64(memory_error->Row)); 6454da4414SLawrence Tang json_object_object_add(section_ir, "column", json_object_new_uint64(memory_error->Column)); 6554da4414SLawrence Tang json_object_object_add(section_ir, "bitPosition", json_object_new_uint64(memory_error->BitPosition)); 6654da4414SLawrence Tang json_object_object_add(section_ir, "requestorID", json_object_new_uint64(memory_error->RequestorId)); 6754da4414SLawrence Tang json_object_object_add(section_ir, "responderID", json_object_new_uint64(memory_error->ResponderId)); 6854da4414SLawrence Tang json_object_object_add(section_ir, "targetID", json_object_new_uint64(memory_error->TargetId)); 6954da4414SLawrence Tang json_object_object_add(section_ir, "rankNumber", json_object_new_uint64(memory_error->RankNum)); 7054da4414SLawrence Tang json_object_object_add(section_ir, "cardSmbiosHandle", json_object_new_uint64(memory_error->CardHandle)); 7154da4414SLawrence Tang json_object_object_add(section_ir, "moduleSmbiosHandle", json_object_new_uint64(memory_error->ModuleHandle)); 7254da4414SLawrence Tang 73a0865e38SLawrence Tang return section_ir; 74a0865e38SLawrence Tang } 75a0865e38SLawrence Tang 76a0865e38SLawrence Tang //Converts a single memory error 2 CPER section into JSON IR. 77a0865e38SLawrence Tang json_object* cper_section_platform_memory2_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor) 78a0865e38SLawrence Tang { 79a0865e38SLawrence Tang EFI_PLATFORM_MEMORY2_ERROR_DATA* memory_error = (EFI_PLATFORM_MEMORY2_ERROR_DATA*)section; 80a0865e38SLawrence Tang json_object* section_ir = json_object_new_object(); 81a0865e38SLawrence Tang 8254da4414SLawrence Tang //Validation bits. 8354da4414SLawrence Tang json_object* validation = bitfield_to_ir(memory_error->ValidFields, 22, MEMORY_ERROR_2_VALID_BITFIELD_NAMES); 8454da4414SLawrence Tang json_object_object_add(section_ir, "validationBits", validation); 8554da4414SLawrence Tang 8654da4414SLawrence Tang //Error status. 8754da4414SLawrence Tang json_object* error_status = cper_generic_error_status_to_ir(&memory_error->ErrorStatus); 8854da4414SLawrence Tang json_object_object_add(section_ir, "errorStatus", error_status); 8954da4414SLawrence Tang 9054da4414SLawrence Tang //Bank. 9154da4414SLawrence Tang json_object* bank = json_object_new_object(); 92583cdeeeSLawrence Tang if ((memory_error->ValidFields >> 5) & 0x1) 93583cdeeeSLawrence Tang { 94583cdeeeSLawrence Tang //Entire bank address mode. 95583cdeeeSLawrence Tang json_object_object_add(bank, "value", json_object_new_uint64(memory_error->Bank)); 96583cdeeeSLawrence Tang } 97583cdeeeSLawrence Tang else 98583cdeeeSLawrence Tang { 99583cdeeeSLawrence Tang //Address/group address mode. 10054da4414SLawrence Tang json_object_object_add(bank, "address", json_object_new_uint64(memory_error->Bank & 0xFF)); 10154da4414SLawrence Tang json_object_object_add(bank, "group", json_object_new_uint64(memory_error->Bank >> 8)); 102583cdeeeSLawrence Tang } 10354da4414SLawrence Tang json_object_object_add(section_ir, "bank", bank); 10454da4414SLawrence Tang 10554da4414SLawrence Tang //Memory error type. 10654da4414SLawrence Tang json_object* memory_error_type = integer_to_readable_pair(memory_error->MemErrorType, 16, 10754da4414SLawrence Tang MEMORY_ERROR_TYPES_KEYS, 10854da4414SLawrence Tang MEMORY_ERROR_TYPES_VALUES, 10954da4414SLawrence Tang "Unknown (Reserved)"); 11054da4414SLawrence Tang json_object_object_add(section_ir, "memoryErrorType", memory_error_type); 11154da4414SLawrence Tang 11254da4414SLawrence Tang //Status. 11354da4414SLawrence Tang json_object* status = json_object_new_object(); 11454da4414SLawrence Tang json_object_object_add(status, "value", json_object_new_int(memory_error->Status)); 11554da4414SLawrence Tang json_object_object_add(status, "state", json_object_new_string(memory_error->Status & 0b1 == 0 ? "Corrected" : "Uncorrected")); 11654da4414SLawrence Tang json_object_object_add(section_ir, "status", status); 11754da4414SLawrence Tang 11854da4414SLawrence Tang //Miscellaneous numeric fields. 11954da4414SLawrence Tang json_object_object_add(section_ir, "physicalAddress", json_object_new_uint64(memory_error->PhysicalAddress)); 12054da4414SLawrence Tang json_object_object_add(section_ir, "physicalAddressMask", json_object_new_uint64(memory_error->PhysicalAddressMask)); 12154da4414SLawrence Tang json_object_object_add(section_ir, "node", json_object_new_uint64(memory_error->Node)); 12254da4414SLawrence Tang json_object_object_add(section_ir, "card", json_object_new_uint64(memory_error->Card)); 12354da4414SLawrence Tang json_object_object_add(section_ir, "module", json_object_new_uint64(memory_error->Module)); 12454da4414SLawrence Tang json_object_object_add(section_ir, "device", json_object_new_uint64(memory_error->Device)); 12554da4414SLawrence Tang json_object_object_add(section_ir, "row", json_object_new_uint64(memory_error->Row)); 12654da4414SLawrence Tang json_object_object_add(section_ir, "column", json_object_new_uint64(memory_error->Column)); 12754da4414SLawrence Tang json_object_object_add(section_ir, "rank", json_object_new_uint64(memory_error->Rank)); 12854da4414SLawrence Tang json_object_object_add(section_ir, "bitPosition", json_object_new_uint64(memory_error->BitPosition)); 12954da4414SLawrence Tang json_object_object_add(section_ir, "chipID", json_object_new_uint64(memory_error->ChipId)); 13054da4414SLawrence Tang json_object_object_add(section_ir, "requestorID", json_object_new_uint64(memory_error->RequestorId)); 13154da4414SLawrence Tang json_object_object_add(section_ir, "responderID", json_object_new_uint64(memory_error->ResponderId)); 13254da4414SLawrence Tang json_object_object_add(section_ir, "targetID", json_object_new_uint64(memory_error->TargetId)); 13354da4414SLawrence Tang json_object_object_add(section_ir, "cardSmbiosHandle", json_object_new_uint64(memory_error->CardHandle)); 13454da4414SLawrence Tang json_object_object_add(section_ir, "moduleSmbiosHandle", json_object_new_uint64(memory_error->ModuleHandle)); 135a0865e38SLawrence Tang 136a0865e38SLawrence Tang return section_ir; 1377f21db6cSLawrence Tang } 138*3b7f45b5SLawrence Tang 139*3b7f45b5SLawrence Tang //Converts a single Memory Error IR section into CPER binary, outputting to the provided stream. 140*3b7f45b5SLawrence Tang void ir_section_memory_to_cper(json_object* section, FILE* out) 141*3b7f45b5SLawrence Tang { 142*3b7f45b5SLawrence Tang EFI_PLATFORM_MEMORY_ERROR_DATA* section_cper = 143*3b7f45b5SLawrence Tang (EFI_PLATFORM_MEMORY_ERROR_DATA*)calloc(1, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA)); 144*3b7f45b5SLawrence Tang 145*3b7f45b5SLawrence Tang //Validation bits. 146*3b7f45b5SLawrence Tang section_cper->ValidFields = ir_to_bitfield(json_object_object_get(section, "validationBits"), 147*3b7f45b5SLawrence Tang 22, MEMORY_ERROR_VALID_BITFIELD_NAMES); 148*3b7f45b5SLawrence Tang 149*3b7f45b5SLawrence Tang //Error status. 150*3b7f45b5SLawrence Tang ir_generic_error_status_to_cper(json_object_object_get(section, "errorStatus"), §ion_cper->ErrorStatus); 151*3b7f45b5SLawrence Tang 152*3b7f45b5SLawrence Tang //Bank. 153*3b7f45b5SLawrence Tang json_object* bank = json_object_object_get(section, "bank"); 154*3b7f45b5SLawrence Tang if ((section_cper->ValidFields >> 5) & 0x1) 155*3b7f45b5SLawrence Tang { 156*3b7f45b5SLawrence Tang //Bank just uses simple address. 157*3b7f45b5SLawrence Tang section_cper->Bank = (UINT16)json_object_get_uint64(json_object_object_get(bank, "value")); 158*3b7f45b5SLawrence Tang } 159*3b7f45b5SLawrence Tang else 160*3b7f45b5SLawrence Tang { 161*3b7f45b5SLawrence Tang //Bank uses address/group style address. 162*3b7f45b5SLawrence Tang UINT16 address = (UINT8)json_object_get_uint64(json_object_object_get(bank, "address")); 163*3b7f45b5SLawrence Tang UINT16 group = (UINT8)json_object_get_uint64(json_object_object_get(bank, "group")); 164*3b7f45b5SLawrence Tang section_cper->Bank = address + (group << 8); 165*3b7f45b5SLawrence Tang } 166*3b7f45b5SLawrence Tang 167*3b7f45b5SLawrence Tang //"Extended" field. 168*3b7f45b5SLawrence Tang json_object* extended = json_object_object_get(section, "extended"); 169*3b7f45b5SLawrence Tang section_cper->Extended = 0; 170*3b7f45b5SLawrence Tang section_cper->Extended |= json_object_get_boolean(json_object_object_get(extended, "rowBit16")); 171*3b7f45b5SLawrence Tang section_cper->Extended |= json_object_get_boolean(json_object_object_get(extended, "rowBit17")) << 1; 172*3b7f45b5SLawrence Tang section_cper->Extended |= json_object_get_int(json_object_object_get(extended, "chipIdentification")) << 5; 173*3b7f45b5SLawrence Tang 174*3b7f45b5SLawrence Tang //Miscellaneous value fields. 175*3b7f45b5SLawrence Tang section_cper->ErrorType = readable_pair_to_integer(json_object_object_get(section, "memoryErrorType")); 176*3b7f45b5SLawrence Tang section_cper->PhysicalAddress = json_object_get_uint64(json_object_object_get(section, "physicalAddress")); 177*3b7f45b5SLawrence Tang section_cper->PhysicalAddressMask = json_object_get_uint64(json_object_object_get(section, "physicalAddressMask")); 178*3b7f45b5SLawrence Tang section_cper->Node = (UINT16)json_object_get_uint64(json_object_object_get(section, "node")); 179*3b7f45b5SLawrence Tang section_cper->Card = (UINT16)json_object_get_uint64(json_object_object_get(section, "card")); 180*3b7f45b5SLawrence Tang section_cper->ModuleRank = (UINT16)json_object_get_uint64(json_object_object_get(section, "moduleRank")); 181*3b7f45b5SLawrence Tang section_cper->Device = (UINT16)json_object_get_uint64(json_object_object_get(section, "device")); 182*3b7f45b5SLawrence Tang section_cper->Row = (UINT16)json_object_get_uint64(json_object_object_get(section, "row")); 183*3b7f45b5SLawrence Tang section_cper->Column = (UINT16)json_object_get_uint64(json_object_object_get(section, "column")); 184*3b7f45b5SLawrence Tang section_cper->BitPosition = (UINT16)json_object_get_uint64(json_object_object_get(section, "bitPosition")); 185*3b7f45b5SLawrence Tang section_cper->RequestorId = json_object_get_uint64(json_object_object_get(section, "requestorID")); 186*3b7f45b5SLawrence Tang section_cper->ResponderId = json_object_get_uint64(json_object_object_get(section, "responderID")); 187*3b7f45b5SLawrence Tang section_cper->TargetId = json_object_get_uint64(json_object_object_get(section, "targetID")); 188*3b7f45b5SLawrence Tang section_cper->RankNum = (UINT16)json_object_get_uint64(json_object_object_get(section, "rankNumber")); 189*3b7f45b5SLawrence Tang section_cper->CardHandle = (UINT16)json_object_get_uint64(json_object_object_get(section, "cardSmbiosHandle")); 190*3b7f45b5SLawrence Tang section_cper->ModuleHandle = (UINT16)json_object_get_uint64(json_object_object_get(section, "moduleSmbiosHandle")); 191*3b7f45b5SLawrence Tang 192*3b7f45b5SLawrence Tang //Write to stream, free up resources. 193*3b7f45b5SLawrence Tang fwrite(§ion_cper, sizeof(section_cper), 1, out); 194*3b7f45b5SLawrence Tang fflush(out); 195*3b7f45b5SLawrence Tang free(section_cper); 196*3b7f45b5SLawrence Tang } 197*3b7f45b5SLawrence Tang 198*3b7f45b5SLawrence Tang //Converts a single Memory Error 2 IR section into CPER binary, outputting to the provided stream. 199*3b7f45b5SLawrence Tang void ir_section_memory2_to_cper(json_object* section, FILE* out) 200*3b7f45b5SLawrence Tang { 201*3b7f45b5SLawrence Tang EFI_PLATFORM_MEMORY2_ERROR_DATA* section_cper = 202*3b7f45b5SLawrence Tang (EFI_PLATFORM_MEMORY2_ERROR_DATA*)calloc(1, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA)); 203*3b7f45b5SLawrence Tang 204*3b7f45b5SLawrence Tang //Validation bits. 205*3b7f45b5SLawrence Tang section_cper->ValidFields = ir_to_bitfield(json_object_object_get(section, "validationBits"), 206*3b7f45b5SLawrence Tang 22, MEMORY_ERROR_2_VALID_BITFIELD_NAMES); 207*3b7f45b5SLawrence Tang 208*3b7f45b5SLawrence Tang //Error status. 209*3b7f45b5SLawrence Tang ir_generic_error_status_to_cper(json_object_object_get(section, "errorStatus"), §ion_cper->ErrorStatus); 210*3b7f45b5SLawrence Tang 211*3b7f45b5SLawrence Tang //Bank. 212*3b7f45b5SLawrence Tang json_object* bank = json_object_object_get(section, "bank"); 213*3b7f45b5SLawrence Tang if ((section_cper->ValidFields >> 5) & 0x1) 214*3b7f45b5SLawrence Tang { 215*3b7f45b5SLawrence Tang //Bank just uses simple address. 216*3b7f45b5SLawrence Tang section_cper->Bank = (UINT16)json_object_get_uint64(json_object_object_get(bank, "value")); 217*3b7f45b5SLawrence Tang } 218*3b7f45b5SLawrence Tang else 219*3b7f45b5SLawrence Tang { 220*3b7f45b5SLawrence Tang //Bank uses address/group style address. 221*3b7f45b5SLawrence Tang UINT16 address = (UINT8)json_object_get_uint64(json_object_object_get(bank, "address")); 222*3b7f45b5SLawrence Tang UINT16 group = (UINT8)json_object_get_uint64(json_object_object_get(bank, "group")); 223*3b7f45b5SLawrence Tang section_cper->Bank = address + (group << 8); 224*3b7f45b5SLawrence Tang } 225*3b7f45b5SLawrence Tang 226*3b7f45b5SLawrence Tang //Miscellaneous value fields. 227*3b7f45b5SLawrence Tang section_cper->MemErrorType = readable_pair_to_integer(json_object_object_get(section, "memoryErrorType")); 228*3b7f45b5SLawrence Tang section_cper->Status = (UINT8)readable_pair_to_integer(json_object_object_get(section, "status")); 229*3b7f45b5SLawrence Tang section_cper->PhysicalAddress = json_object_get_uint64(json_object_object_get(section, "physicalAddress")); 230*3b7f45b5SLawrence Tang section_cper->PhysicalAddressMask = json_object_get_uint64(json_object_object_get(section, "physicalAddressMask")); 231*3b7f45b5SLawrence Tang section_cper->Node = (UINT16)json_object_get_uint64(json_object_object_get(section, "node")); 232*3b7f45b5SLawrence Tang section_cper->Card = (UINT16)json_object_get_uint64(json_object_object_get(section, "card")); 233*3b7f45b5SLawrence Tang section_cper->Module = (UINT32)json_object_get_uint64(json_object_object_get(section, "module")); 234*3b7f45b5SLawrence Tang section_cper->Device = (UINT32)json_object_get_uint64(json_object_object_get(section, "device")); 235*3b7f45b5SLawrence Tang section_cper->Row = (UINT32)json_object_get_uint64(json_object_object_get(section, "row")); 236*3b7f45b5SLawrence Tang section_cper->Column = (UINT32)json_object_get_uint64(json_object_object_get(section, "column")); 237*3b7f45b5SLawrence Tang section_cper->Rank = (UINT32)json_object_get_uint64(json_object_object_get(section, "rank")); 238*3b7f45b5SLawrence Tang section_cper->BitPosition = (UINT32)json_object_get_uint64(json_object_object_get(section, "bitPosition")); 239*3b7f45b5SLawrence Tang section_cper->ChipId = (UINT8)json_object_get_uint64(json_object_object_get(section, "chipID")); 240*3b7f45b5SLawrence Tang section_cper->RequestorId = json_object_get_uint64(json_object_object_get(section, "requestorID")); 241*3b7f45b5SLawrence Tang section_cper->ResponderId = json_object_get_uint64(json_object_object_get(section, "responderID")); 242*3b7f45b5SLawrence Tang section_cper->TargetId = json_object_get_uint64(json_object_object_get(section, "targetID")); 243*3b7f45b5SLawrence Tang section_cper->CardHandle = (UINT32)json_object_get_uint64(json_object_object_get(section, "cardSmbiosHandle")); 244*3b7f45b5SLawrence Tang section_cper->ModuleHandle = (UINT32)json_object_get_uint64(json_object_object_get(section, "moduleSmbiosHandle")); 245*3b7f45b5SLawrence Tang 246*3b7f45b5SLawrence Tang //Write to stream, free up resources. 247*3b7f45b5SLawrence Tang fwrite(§ion_cper, sizeof(section_cper), 1, out); 248*3b7f45b5SLawrence Tang fflush(out); 249*3b7f45b5SLawrence Tang free(section_cper); 250*3b7f45b5SLawrence Tang }