blob: 45f89eb1d31634ecafa2ce0b9aa3545ad7970e9f [file] [log] [blame] [edit]
/**
* Describes functions for converting memory error CPER sections from binary and JSON format
* into an intermediate format.
*
* Author: Lawrence.Tang@arm.com
**/
#include <stdio.h>
#include <json.h>
#include <libcper/Cper.h>
#include <libcper/cper-utils.h>
#include <libcper/sections/cper-section-memory.h>
#include <libcper/log.h>
#include <string.h>
//Converts a single memory error CPER section into JSON IR.
json_object *cper_section_platform_memory_to_ir(const UINT8 *section,
UINT32 size, char **desc_string)
{
int outstr_len = 0;
*desc_string = NULL;
if (size < sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA)) {
cper_print_log("Error: Platform memory section too small\n");
return NULL;
}
*desc_string = calloc(1, SECTION_DESC_STRING_SIZE);
if (*desc_string == NULL) {
cper_print_log(
"Error: Failed to allocate Platform memory desc string\n");
return NULL;
}
EFI_PLATFORM_MEMORY_ERROR_DATA *memory_error =
(EFI_PLATFORM_MEMORY_ERROR_DATA *)section;
json_object *section_ir = json_object_new_object();
ValidationTypes ui64Type = { UINT_64T,
.value.ui64 = memory_error->ValidFields };
//Error status.
if (isvalid_prop_to_ir(&ui64Type, 0)) {
json_object *error_status = cper_generic_error_status_to_ir(
&memory_error->ErrorStatus);
json_object_object_add(section_ir, "errorStatus", error_status);
}
//Bank
json_object *bank = json_object_new_object();
if (isvalid_prop_to_ir(&ui64Type, 6)) {
//Entire bank address mode.
add_uint(bank, "value", memory_error->Bank);
} else {
//Address/group address mode.
add_uint(bank, "address", memory_error->Bank & 0xFF);
add_uint(bank, "group", memory_error->Bank >> 8);
}
json_object_object_add(section_ir, "bank", bank);
//Memory error type.
const char *mem_type_str = NULL;
if (isvalid_prop_to_ir(&ui64Type, 14)) {
json_object *memory_error_type = integer_to_readable_pair(
memory_error->ErrorType, 16, MEMORY_ERROR_TYPES_KEYS,
MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)");
json_object_object_add(section_ir, "memoryErrorType",
memory_error_type);
mem_type_str = json_object_get_string(
json_object_object_get(memory_error_type, "name"));
}
if (mem_type_str != NULL) {
outstr_len = snprintf(*desc_string, SECTION_DESC_STRING_SIZE,
"A %s Memory Error occurred",
mem_type_str);
} else {
outstr_len = snprintf(*desc_string, SECTION_DESC_STRING_SIZE,
"An Unknown Memory Error occurred");
}
if (outstr_len < 0) {
cper_print_log(
"Error: Could not write to Memory description string\n");
} else if (outstr_len > SECTION_DESC_STRING_SIZE) {
cper_print_log(
"Error: Memory description string truncated: %s\n",
*desc_string);
}
//"Extended" row/column indication field + misc.
if (isvalid_prop_to_ir(&ui64Type, 18)) {
json_object *extended = json_object_new_object();
add_bool(extended, "rowBit16", memory_error->Extended & 0x1);
add_bool(extended, "rowBit17",
(memory_error->Extended >> 1) & 0x1);
if (isvalid_prop_to_ir(&ui64Type, 21)) {
add_int(extended, "chipIdentification",
memory_error->Extended >> 5);
}
json_object_object_add(section_ir, "extended", extended);
}
if (isvalid_prop_to_ir(&ui64Type, 16)) {
add_uint(section_ir, "cardSmbiosHandle",
memory_error->CardHandle);
}
if (isvalid_prop_to_ir(&ui64Type, 17)) {
add_uint(section_ir, "moduleSmbiosHandle",
memory_error->ModuleHandle);
}
//Miscellaneous numeric fields.
if (isvalid_prop_to_ir(&ui64Type, 1)) {
add_uint(section_ir, "physicalAddress",
memory_error->PhysicalAddress);
char hexstring_buf[EFI_UINT64_HEX_STRING_LEN];
snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%016llX",
memory_error->PhysicalAddress);
add_string(section_ir, "physicalAddressHex", hexstring_buf);
char physical_address_desc[EFI_ERROR_DESCRIPTION_STRING_LEN];
outstr_len = snprintf(physical_address_desc,
EFI_ERROR_DESCRIPTION_STRING_LEN,
" at address 0x%016llX",
memory_error->PhysicalAddress);
if (outstr_len < 0) {
cper_print_log(
"Error: Could not write to physical address description string\n");
} else if (outstr_len > EFI_ERROR_DESCRIPTION_STRING_LEN) {
cper_print_log(
"Error: Physical address description string truncated: %s\n",
physical_address_desc);
} else {
if (strlen(physical_address_desc) +
strlen(*desc_string) <
SECTION_DESC_STRING_SIZE) {
strncat(*desc_string, physical_address_desc,
outstr_len);
} else {
cper_print_log(
"Error: Memory description string too long, not added to description string: %s\n",
physical_address_desc);
}
}
}
if (isvalid_prop_to_ir(&ui64Type, 2)) {
add_uint(section_ir, "physicalAddressMask",
memory_error->PhysicalAddressMask);
}
if (isvalid_prop_to_ir(&ui64Type, 3)) {
add_uint(section_ir, "node", memory_error->Node);
char node_desc[EFI_ERROR_DESCRIPTION_STRING_LEN];
outstr_len = snprintf(node_desc,
EFI_ERROR_DESCRIPTION_STRING_LEN,
" at node %d", memory_error->Node);
if (outstr_len < 0) {
cper_print_log(
"Error: Could not write to node description string\n");
} else if (outstr_len > EFI_ERROR_DESCRIPTION_STRING_LEN) {
cper_print_log(
"Error: Node description string truncated: %s\n",
node_desc);
} else {
if (strlen(node_desc) + strlen(*desc_string) <
SECTION_DESC_STRING_SIZE) {
strncat(*desc_string, node_desc, outstr_len);
} else {
cper_print_log(
"Error: Memory description string too long, not added to description string: %s\n",
node_desc);
}
}
}
if (isvalid_prop_to_ir(&ui64Type, 4)) {
add_uint(section_ir, "card", memory_error->Card);
}
if (isvalid_prop_to_ir(&ui64Type, 5)) {
add_uint(section_ir, "moduleRank", memory_error->ModuleRank);
}
if (isvalid_prop_to_ir(&ui64Type, 7)) {
add_uint(section_ir, "device", memory_error->Device);
}
if (isvalid_prop_to_ir(&ui64Type, 8)) {
add_uint(section_ir, "row", memory_error->Row);
}
if (isvalid_prop_to_ir(&ui64Type, 9)) {
add_uint(section_ir, "column", memory_error->Column);
}
if (isvalid_prop_to_ir(&ui64Type, 10)) {
add_uint(section_ir, "bitPosition", memory_error->BitPosition);
}
if (isvalid_prop_to_ir(&ui64Type, 11)) {
add_uint(section_ir, "requestorID", memory_error->RequestorId);
}
if (isvalid_prop_to_ir(&ui64Type, 12)) {
add_uint(section_ir, "responderID", memory_error->ResponderId);
}
if (isvalid_prop_to_ir(&ui64Type, 13)) {
add_uint(section_ir, "targetID", memory_error->TargetId);
}
if (isvalid_prop_to_ir(&ui64Type, 15)) {
add_uint(section_ir, "rankNumber", memory_error->RankNum);
}
return section_ir;
}
//Converts a single memory error 2 CPER section into JSON IR.
json_object *cper_section_platform_memory2_to_ir(const UINT8 *section,
UINT32 size,
char **desc_string)
{
int outstr_len = 0;
*desc_string = NULL;
if (size < sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA)) {
cper_print_log("Error: Platform memory2 section too small\n");
return NULL;
}
*desc_string = calloc(1, SECTION_DESC_STRING_SIZE);
if (*desc_string == NULL) {
cper_print_log(
"Error: Failed to allocate Platform memory2 desc string\n");
return NULL;
}
EFI_PLATFORM_MEMORY2_ERROR_DATA *memory_error =
(EFI_PLATFORM_MEMORY2_ERROR_DATA *)section;
json_object *section_ir = json_object_new_object();
ValidationTypes ui64Type = { UINT_64T,
.value.ui64 = memory_error->ValidFields };
//Error status.
if (isvalid_prop_to_ir(&ui64Type, 0)) {
json_object *error_status = cper_generic_error_status_to_ir(
&memory_error->ErrorStatus);
json_object_object_add(section_ir, "errorStatus", error_status);
}
//Bank.
json_object *bank = json_object_new_object();
if (isvalid_prop_to_ir(&ui64Type, 6)) {
//Entire bank address mode.
add_uint(bank, "value", memory_error->Bank);
} else {
//Address/group address mode.
add_uint(bank, "address", memory_error->Bank & 0xFF);
add_uint(bank, "group", memory_error->Bank >> 8);
}
json_object_object_add(section_ir, "bank", bank);
//Memory error type.
const char *mem_type_str = NULL;
if (isvalid_prop_to_ir(&ui64Type, 13)) {
json_object *memory_error_type = integer_to_readable_pair(
memory_error->MemErrorType, 16, MEMORY_ERROR_TYPES_KEYS,
MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)");
json_object_object_add(section_ir, "memoryErrorType",
memory_error_type);
mem_type_str = json_object_get_string(
json_object_object_get(memory_error_type, "name"));
}
if (mem_type_str != NULL) {
outstr_len = snprintf(*desc_string, SECTION_DESC_STRING_SIZE,
"A %s Memory Error occurred",
mem_type_str);
} else {
outstr_len = snprintf(*desc_string, SECTION_DESC_STRING_SIZE,
"An Unknown Memory Error occurred");
}
if (outstr_len < 0) {
cper_print_log(
"Error: Could not write to Memory2 description string\n");
} else if (outstr_len > SECTION_DESC_STRING_SIZE) {
cper_print_log(
"Error: Memory2 description string truncated: %s\n",
*desc_string);
}
//Status.
if (isvalid_prop_to_ir(&ui64Type, 14)) {
json_object *status = json_object_new_object();
add_int(status, "value", memory_error->Status);
add_string(status, "state",
(memory_error->Status & 0x1) == 0 ? "Corrected" :
"Uncorrected");
json_object_object_add(section_ir, "status", status);
}
//Miscellaneous numeric fields.
if (isvalid_prop_to_ir(&ui64Type, 0)) {
add_uint(section_ir, "physicalAddress",
memory_error->PhysicalAddress);
char physical_address_desc[EFI_ERROR_DESCRIPTION_STRING_LEN];
outstr_len = snprintf(physical_address_desc,
EFI_ERROR_DESCRIPTION_STRING_LEN,
" at address 0x%016llX",
memory_error->PhysicalAddress);
if (outstr_len < 0) {
cper_print_log(
"Error: Could not write to physical address description string\n");
} else if (outstr_len > EFI_ERROR_DESCRIPTION_STRING_LEN) {
cper_print_log(
"Error: Physical address description string truncated: %s\n",
physical_address_desc);
} else {
if (strlen(physical_address_desc) +
strlen(*desc_string) <
SECTION_DESC_STRING_SIZE) {
strncat(*desc_string, physical_address_desc,
outstr_len);
} else {
cper_print_log(
"Error: Memory2 description string too long, not added to description string: %s\n",
physical_address_desc);
}
}
}
char hexstring_buf[EFI_UINT64_HEX_STRING_LEN];
snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%016llX",
memory_error->PhysicalAddress);
add_string(section_ir, "physicalAddressHex", hexstring_buf);
if (isvalid_prop_to_ir(&ui64Type, 2)) {
add_uint(section_ir, "physicalAddressMask",
memory_error->PhysicalAddressMask);
}
if (isvalid_prop_to_ir(&ui64Type, 3)) {
add_uint(section_ir, "node", memory_error->Node);
char node_desc[EFI_ERROR_DESCRIPTION_STRING_LEN];
outstr_len = snprintf(node_desc,
EFI_ERROR_DESCRIPTION_STRING_LEN,
" on node %d", memory_error->Node);
if (outstr_len < 0) {
cper_print_log(
"Error: Could not write to node description string\n");
} else if (outstr_len > EFI_ERROR_DESCRIPTION_STRING_LEN) {
cper_print_log(
"Error: Node description string truncated: %s\n",
node_desc);
} else {
if (strlen(node_desc) + strlen(*desc_string) <
SECTION_DESC_STRING_SIZE) {
strncat(*desc_string, node_desc, outstr_len);
} else {
cper_print_log(
"Error: Memory2 description string too long, not added to description string: %s\n",
node_desc);
}
}
}
if (isvalid_prop_to_ir(&ui64Type, 4)) {
add_uint(section_ir, "card", memory_error->Card);
}
if (isvalid_prop_to_ir(&ui64Type, 5)) {
add_uint(section_ir, "module", memory_error->Module);
}
if (isvalid_prop_to_ir(&ui64Type, 7)) {
add_uint(section_ir, "device", memory_error->Device);
}
if (isvalid_prop_to_ir(&ui64Type, 8)) {
add_uint(section_ir, "row", memory_error->Row);
}
if (isvalid_prop_to_ir(&ui64Type, 9)) {
add_uint(section_ir, "column", memory_error->Column);
}
if (isvalid_prop_to_ir(&ui64Type, 10)) {
add_uint(section_ir, "rank", memory_error->Rank);
}
if (isvalid_prop_to_ir(&ui64Type, 11)) {
add_uint(section_ir, "bitPosition", memory_error->BitPosition);
}
if (isvalid_prop_to_ir(&ui64Type, 12)) {
add_uint(section_ir, "chipID", memory_error->ChipId);
}
if (isvalid_prop_to_ir(&ui64Type, 15)) {
add_uint(section_ir, "requestorID", memory_error->RequestorId);
}
if (isvalid_prop_to_ir(&ui64Type, 16)) {
add_uint(section_ir, "responderID", memory_error->ResponderId);
}
if (isvalid_prop_to_ir(&ui64Type, 17)) {
add_uint(section_ir, "targetID", memory_error->TargetId);
}
if (isvalid_prop_to_ir(&ui64Type, 18)) {
add_uint(section_ir, "cardSmbiosHandle",
memory_error->CardHandle);
}
if (isvalid_prop_to_ir(&ui64Type, 19)) {
add_uint(section_ir, "moduleSmbiosHandle",
memory_error->ModuleHandle);
}
return section_ir;
}
//Converts a single Memory Error IR section into CPER binary, outputting to the provided stream.
void ir_section_memory_to_cper(json_object *section, FILE *out)
{
EFI_PLATFORM_MEMORY_ERROR_DATA *section_cper =
(EFI_PLATFORM_MEMORY_ERROR_DATA *)calloc(
1, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA));
ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
struct json_object *obj = NULL;
//Error status.
if (json_object_object_get_ex(section, "errorStatus", &obj)) {
ir_generic_error_status_to_cper(obj,
&section_cper->ErrorStatus);
add_to_valid_bitfield(&ui64Type, 0);
}
//Bank.
if (json_object_object_get_ex(section, "bank", &obj)) {
json_object *bank = obj;
if (json_object_object_get_ex(bank, "value", &obj)) {
//Bank just uses simple address.
section_cper->Bank =
(UINT16)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 6);
} else {
//Bank uses address/group style address.
UINT16 address = (UINT8)json_object_get_uint64(
json_object_object_get(bank, "address"));
UINT16 group = (UINT8)json_object_get_uint64(
json_object_object_get(bank, "group"));
section_cper->Bank = address + (group << 8);
add_to_valid_bitfield(&ui64Type, 19);
add_to_valid_bitfield(&ui64Type, 20);
}
}
//"Extended" field.
if (json_object_object_get_ex(section, "extended", &obj)) {
json_object *extended = obj;
section_cper->Extended = 0;
section_cper->Extended |= json_object_get_boolean(
json_object_object_get(extended, "rowBit16"));
section_cper->Extended |=
json_object_get_boolean(
json_object_object_get(extended, "rowBit17"))
<< 1;
if (json_object_object_get_ex(extended, "chipIdentification",
&obj)) {
section_cper->Extended |= json_object_get_int(obj) << 5;
add_to_valid_bitfield(&ui64Type, 21);
}
add_to_valid_bitfield(&ui64Type, 18);
}
//Miscellaneous value fields.
if (json_object_object_get_ex(section, "memoryErrorType", &obj)) {
section_cper->ErrorType = (UINT8)readable_pair_to_integer(obj);
add_to_valid_bitfield(&ui64Type, 14);
}
if (json_object_object_get_ex(section, "physicalAddress", &obj)) {
section_cper->PhysicalAddress = json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 1);
}
if (json_object_object_get_ex(section, "physicalAddressMask", &obj)) {
section_cper->PhysicalAddressMask = json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 2);
}
if (json_object_object_get_ex(section, "node", &obj)) {
section_cper->Node = (UINT16)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 3);
}
if (json_object_object_get_ex(section, "card", &obj)) {
section_cper->Card = (UINT16)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 4);
}
if (json_object_object_get_ex(section, "moduleRank", &obj)) {
section_cper->ModuleRank = (UINT16)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 5);
}
if (json_object_object_get_ex(section, "device", &obj)) {
section_cper->Device = (UINT16)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 7);
}
if (json_object_object_get_ex(section, "row", &obj)) {
section_cper->Row = (UINT16)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 8);
}
if (json_object_object_get_ex(section, "column", &obj)) {
section_cper->Column = (UINT16)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 9);
}
if (json_object_object_get_ex(section, "bitPosition", &obj)) {
section_cper->BitPosition = (UINT16)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 10);
}
if (json_object_object_get_ex(section, "requestorID", &obj)) {
section_cper->RequestorId = json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 11);
}
if (json_object_object_get_ex(section, "responderID", &obj)) {
section_cper->ResponderId = json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 12);
}
if (json_object_object_get_ex(section, "targetID", &obj)) {
section_cper->TargetId = json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 13);
}
if (json_object_object_get_ex(section, "rankNumber", &obj)) {
section_cper->RankNum = (UINT16)json_object_get_uint64(
json_object_object_get(section, "rankNumber"));
add_to_valid_bitfield(&ui64Type, 15);
}
if (json_object_object_get_ex(section, "cardSmbiosHandle", &obj)) {
section_cper->CardHandle = (UINT16)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 16);
}
if (json_object_object_get_ex(section, "moduleSmbiosHandle", &obj)) {
section_cper->ModuleHandle =
(UINT16)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 17);
}
section_cper->ValidFields = ui64Type.value.ui64;
//Write to stream, free up resources.
fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA), 1, out);
fflush(out);
free(section_cper);
}
//Converts a single Memory Error 2 IR section into CPER binary, outputting to the provided stream.
void ir_section_memory2_to_cper(json_object *section, FILE *out)
{
EFI_PLATFORM_MEMORY2_ERROR_DATA *section_cper =
(EFI_PLATFORM_MEMORY2_ERROR_DATA *)calloc(
1, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA));
//Validation bits.
ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
struct json_object *obj = NULL;
//Error status.
if (json_object_object_get_ex(section, "errorStatus", &obj)) {
ir_generic_error_status_to_cper(obj,
&section_cper->ErrorStatus);
add_to_valid_bitfield(&ui64Type, 0);
}
//Bank.
json_object *bank = json_object_object_get(section, "bank");
if (json_object_object_get_ex(bank, "value", &obj)) {
//Bank just uses simple address.
section_cper->Bank = (UINT16)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 6);
} else {
//Bank uses address/group style address.
UINT16 address = (UINT8)json_object_get_uint64(
json_object_object_get(bank, "address"));
UINT16 group = (UINT8)json_object_get_uint64(
json_object_object_get(bank, "group"));
section_cper->Bank = address + (group << 8);
add_to_valid_bitfield(&ui64Type, 20);
add_to_valid_bitfield(&ui64Type, 21);
}
//Miscellaneous value fields.
if (json_object_object_get_ex(section, "memoryErrorType", &obj)) {
section_cper->MemErrorType = readable_pair_to_integer(obj);
add_to_valid_bitfield(&ui64Type, 13);
}
if (json_object_object_get_ex(section, "status", &obj)) {
section_cper->Status = (UINT8)readable_pair_to_integer(obj);
add_to_valid_bitfield(&ui64Type, 14);
}
if (json_object_object_get_ex(section, "physicalAddress", &obj)) {
section_cper->PhysicalAddress = json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 1);
}
if (json_object_object_get_ex(section, "physicalAddressMask", &obj)) {
section_cper->PhysicalAddressMask = json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 2);
}
if (json_object_object_get_ex(section, "node", &obj)) {
section_cper->Node = (UINT16)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 3);
}
if (json_object_object_get_ex(section, "card", &obj)) {
section_cper->Card = (UINT16)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 4);
}
if (json_object_object_get_ex(section, "module", &obj)) {
section_cper->Module = (UINT32)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 5);
}
if (json_object_object_get_ex(section, "device", &obj)) {
section_cper->Device = (UINT32)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 7);
}
if (json_object_object_get_ex(section, "row", &obj)) {
section_cper->Row = (UINT32)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 8);
}
if (json_object_object_get_ex(section, "column", &obj)) {
section_cper->Column = (UINT32)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 9);
}
if (json_object_object_get_ex(section, "rank", &obj)) {
section_cper->Rank = (UINT32)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 10);
}
if (json_object_object_get_ex(section, "bitPosition", &obj)) {
section_cper->BitPosition = (UINT32)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 11);
}
if (json_object_object_get_ex(section, "chipID", &obj)) {
section_cper->ChipId = (UINT8)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 12);
}
if (json_object_object_get_ex(section, "requestorID", &obj)) {
section_cper->RequestorId = json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 15);
}
if (json_object_object_get_ex(section, "responderID", &obj)) {
section_cper->ResponderId = json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 16);
}
if (json_object_object_get_ex(section, "targetID", &obj)) {
section_cper->TargetId = json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 17);
}
if (json_object_object_get_ex(section, "cardSmbiosHandle", &obj)) {
section_cper->CardHandle = (UINT32)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 18);
}
if (json_object_object_get_ex(section, "moduleSmbiosHandle", &obj)) {
section_cper->ModuleHandle =
(UINT32)json_object_get_uint64(obj);
add_to_valid_bitfield(&ui64Type, 19);
}
section_cper->ValidFields = ui64Type.value.ui64;
//Write to stream, free up resources.
fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA), 1, out);
fflush(out);
free(section_cper);
}