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 } 1383b7f45b5SLawrence Tang 1393b7f45b5SLawrence Tang //Converts a single Memory Error IR section into CPER binary, outputting to the provided stream. 1403b7f45b5SLawrence Tang void ir_section_memory_to_cper(json_object* section, FILE* out) 1413b7f45b5SLawrence Tang { 1423b7f45b5SLawrence Tang EFI_PLATFORM_MEMORY_ERROR_DATA* section_cper = 1433b7f45b5SLawrence Tang (EFI_PLATFORM_MEMORY_ERROR_DATA*)calloc(1, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA)); 1443b7f45b5SLawrence Tang 1453b7f45b5SLawrence Tang //Validation bits. 1463b7f45b5SLawrence Tang section_cper->ValidFields = ir_to_bitfield(json_object_object_get(section, "validationBits"), 1473b7f45b5SLawrence Tang 22, MEMORY_ERROR_VALID_BITFIELD_NAMES); 1483b7f45b5SLawrence Tang 1493b7f45b5SLawrence Tang //Error status. 1503b7f45b5SLawrence Tang ir_generic_error_status_to_cper(json_object_object_get(section, "errorStatus"), §ion_cper->ErrorStatus); 1513b7f45b5SLawrence Tang 1523b7f45b5SLawrence Tang //Bank. 1533b7f45b5SLawrence Tang json_object* bank = json_object_object_get(section, "bank"); 1543b7f45b5SLawrence Tang if ((section_cper->ValidFields >> 5) & 0x1) 1553b7f45b5SLawrence Tang { 1563b7f45b5SLawrence Tang //Bank just uses simple address. 1573b7f45b5SLawrence Tang section_cper->Bank = (UINT16)json_object_get_uint64(json_object_object_get(bank, "value")); 1583b7f45b5SLawrence Tang } 1593b7f45b5SLawrence Tang else 1603b7f45b5SLawrence Tang { 1613b7f45b5SLawrence Tang //Bank uses address/group style address. 1623b7f45b5SLawrence Tang UINT16 address = (UINT8)json_object_get_uint64(json_object_object_get(bank, "address")); 1633b7f45b5SLawrence Tang UINT16 group = (UINT8)json_object_get_uint64(json_object_object_get(bank, "group")); 1643b7f45b5SLawrence Tang section_cper->Bank = address + (group << 8); 1653b7f45b5SLawrence Tang } 1663b7f45b5SLawrence Tang 1673b7f45b5SLawrence Tang //"Extended" field. 1683b7f45b5SLawrence Tang json_object* extended = json_object_object_get(section, "extended"); 1693b7f45b5SLawrence Tang section_cper->Extended = 0; 1703b7f45b5SLawrence Tang section_cper->Extended |= json_object_get_boolean(json_object_object_get(extended, "rowBit16")); 1713b7f45b5SLawrence Tang section_cper->Extended |= json_object_get_boolean(json_object_object_get(extended, "rowBit17")) << 1; 1723b7f45b5SLawrence Tang section_cper->Extended |= json_object_get_int(json_object_object_get(extended, "chipIdentification")) << 5; 1733b7f45b5SLawrence Tang 1743b7f45b5SLawrence Tang //Miscellaneous value fields. 175*3ab351feSLawrence Tang section_cper->ErrorType = (UINT8)readable_pair_to_integer(json_object_object_get(section, "memoryErrorType")); 1763b7f45b5SLawrence Tang section_cper->PhysicalAddress = json_object_get_uint64(json_object_object_get(section, "physicalAddress")); 1773b7f45b5SLawrence Tang section_cper->PhysicalAddressMask = json_object_get_uint64(json_object_object_get(section, "physicalAddressMask")); 1783b7f45b5SLawrence Tang section_cper->Node = (UINT16)json_object_get_uint64(json_object_object_get(section, "node")); 1793b7f45b5SLawrence Tang section_cper->Card = (UINT16)json_object_get_uint64(json_object_object_get(section, "card")); 1803b7f45b5SLawrence Tang section_cper->ModuleRank = (UINT16)json_object_get_uint64(json_object_object_get(section, "moduleRank")); 1813b7f45b5SLawrence Tang section_cper->Device = (UINT16)json_object_get_uint64(json_object_object_get(section, "device")); 1823b7f45b5SLawrence Tang section_cper->Row = (UINT16)json_object_get_uint64(json_object_object_get(section, "row")); 1833b7f45b5SLawrence Tang section_cper->Column = (UINT16)json_object_get_uint64(json_object_object_get(section, "column")); 1843b7f45b5SLawrence Tang section_cper->BitPosition = (UINT16)json_object_get_uint64(json_object_object_get(section, "bitPosition")); 1853b7f45b5SLawrence Tang section_cper->RequestorId = json_object_get_uint64(json_object_object_get(section, "requestorID")); 1863b7f45b5SLawrence Tang section_cper->ResponderId = json_object_get_uint64(json_object_object_get(section, "responderID")); 1873b7f45b5SLawrence Tang section_cper->TargetId = json_object_get_uint64(json_object_object_get(section, "targetID")); 1883b7f45b5SLawrence Tang section_cper->RankNum = (UINT16)json_object_get_uint64(json_object_object_get(section, "rankNumber")); 1893b7f45b5SLawrence Tang section_cper->CardHandle = (UINT16)json_object_get_uint64(json_object_object_get(section, "cardSmbiosHandle")); 1903b7f45b5SLawrence Tang section_cper->ModuleHandle = (UINT16)json_object_get_uint64(json_object_object_get(section, "moduleSmbiosHandle")); 1913b7f45b5SLawrence Tang 1923b7f45b5SLawrence Tang //Write to stream, free up resources. 193*3ab351feSLawrence Tang fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA), 1, out); 1943b7f45b5SLawrence Tang fflush(out); 1953b7f45b5SLawrence Tang free(section_cper); 1963b7f45b5SLawrence Tang } 1973b7f45b5SLawrence Tang 1983b7f45b5SLawrence Tang //Converts a single Memory Error 2 IR section into CPER binary, outputting to the provided stream. 1993b7f45b5SLawrence Tang void ir_section_memory2_to_cper(json_object* section, FILE* out) 2003b7f45b5SLawrence Tang { 2013b7f45b5SLawrence Tang EFI_PLATFORM_MEMORY2_ERROR_DATA* section_cper = 2023b7f45b5SLawrence Tang (EFI_PLATFORM_MEMORY2_ERROR_DATA*)calloc(1, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA)); 2033b7f45b5SLawrence Tang 2043b7f45b5SLawrence Tang //Validation bits. 2053b7f45b5SLawrence Tang section_cper->ValidFields = ir_to_bitfield(json_object_object_get(section, "validationBits"), 2063b7f45b5SLawrence Tang 22, MEMORY_ERROR_2_VALID_BITFIELD_NAMES); 2073b7f45b5SLawrence Tang 2083b7f45b5SLawrence Tang //Error status. 2093b7f45b5SLawrence Tang ir_generic_error_status_to_cper(json_object_object_get(section, "errorStatus"), §ion_cper->ErrorStatus); 2103b7f45b5SLawrence Tang 2113b7f45b5SLawrence Tang //Bank. 2123b7f45b5SLawrence Tang json_object* bank = json_object_object_get(section, "bank"); 2133b7f45b5SLawrence Tang if ((section_cper->ValidFields >> 5) & 0x1) 2143b7f45b5SLawrence Tang { 2153b7f45b5SLawrence Tang //Bank just uses simple address. 2163b7f45b5SLawrence Tang section_cper->Bank = (UINT16)json_object_get_uint64(json_object_object_get(bank, "value")); 2173b7f45b5SLawrence Tang } 2183b7f45b5SLawrence Tang else 2193b7f45b5SLawrence Tang { 2203b7f45b5SLawrence Tang //Bank uses address/group style address. 2213b7f45b5SLawrence Tang UINT16 address = (UINT8)json_object_get_uint64(json_object_object_get(bank, "address")); 2223b7f45b5SLawrence Tang UINT16 group = (UINT8)json_object_get_uint64(json_object_object_get(bank, "group")); 2233b7f45b5SLawrence Tang section_cper->Bank = address + (group << 8); 2243b7f45b5SLawrence Tang } 2253b7f45b5SLawrence Tang 2263b7f45b5SLawrence Tang //Miscellaneous value fields. 2273b7f45b5SLawrence Tang section_cper->MemErrorType = readable_pair_to_integer(json_object_object_get(section, "memoryErrorType")); 2283b7f45b5SLawrence Tang section_cper->Status = (UINT8)readable_pair_to_integer(json_object_object_get(section, "status")); 2293b7f45b5SLawrence Tang section_cper->PhysicalAddress = json_object_get_uint64(json_object_object_get(section, "physicalAddress")); 2303b7f45b5SLawrence Tang section_cper->PhysicalAddressMask = json_object_get_uint64(json_object_object_get(section, "physicalAddressMask")); 2313b7f45b5SLawrence Tang section_cper->Node = (UINT16)json_object_get_uint64(json_object_object_get(section, "node")); 2323b7f45b5SLawrence Tang section_cper->Card = (UINT16)json_object_get_uint64(json_object_object_get(section, "card")); 2333b7f45b5SLawrence Tang section_cper->Module = (UINT32)json_object_get_uint64(json_object_object_get(section, "module")); 2343b7f45b5SLawrence Tang section_cper->Device = (UINT32)json_object_get_uint64(json_object_object_get(section, "device")); 2353b7f45b5SLawrence Tang section_cper->Row = (UINT32)json_object_get_uint64(json_object_object_get(section, "row")); 2363b7f45b5SLawrence Tang section_cper->Column = (UINT32)json_object_get_uint64(json_object_object_get(section, "column")); 2373b7f45b5SLawrence Tang section_cper->Rank = (UINT32)json_object_get_uint64(json_object_object_get(section, "rank")); 2383b7f45b5SLawrence Tang section_cper->BitPosition = (UINT32)json_object_get_uint64(json_object_object_get(section, "bitPosition")); 2393b7f45b5SLawrence Tang section_cper->ChipId = (UINT8)json_object_get_uint64(json_object_object_get(section, "chipID")); 2403b7f45b5SLawrence Tang section_cper->RequestorId = json_object_get_uint64(json_object_object_get(section, "requestorID")); 2413b7f45b5SLawrence Tang section_cper->ResponderId = json_object_get_uint64(json_object_object_get(section, "responderID")); 2423b7f45b5SLawrence Tang section_cper->TargetId = json_object_get_uint64(json_object_object_get(section, "targetID")); 2433b7f45b5SLawrence Tang section_cper->CardHandle = (UINT32)json_object_get_uint64(json_object_object_get(section, "cardSmbiosHandle")); 2443b7f45b5SLawrence Tang section_cper->ModuleHandle = (UINT32)json_object_get_uint64(json_object_object_get(section, "moduleSmbiosHandle")); 2453b7f45b5SLawrence Tang 2463b7f45b5SLawrence Tang //Write to stream, free up resources. 247*3ab351feSLawrence Tang fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA), 1, out); 2483b7f45b5SLawrence Tang fflush(out); 2493b7f45b5SLawrence Tang free(section_cper); 2503b7f45b5SLawrence Tang }