11b0b00e3SLawrence Tang /** 21b0b00e3SLawrence Tang * Describes utility functions for parsing CPER into JSON IR. 31b0b00e3SLawrence Tang * 41b0b00e3SLawrence Tang * Author: Lawrence.Tang@arm.com 51b0b00e3SLawrence Tang **/ 61b0b00e3SLawrence Tang 71b0b00e3SLawrence Tang #include <stdio.h> 81b0b00e3SLawrence Tang #include "json.h" 91b0b00e3SLawrence Tang #include "edk/Cper.h" 101b0b00e3SLawrence Tang #include "cper-utils.h" 111b0b00e3SLawrence Tang 121b0b00e3SLawrence Tang //The available severity types for CPER. 131b0b00e3SLawrence Tang const char* CPER_SEVERITY_TYPES[4] = {"Recoverable", "Fatal", "Corrected", "Informational"}; 141b0b00e3SLawrence Tang 153c43f743SLawrence Tang //Converts a single integer value to an object containing a value, and a readable name if possible. 163c43f743SLawrence Tang json_object* integer_to_readable_pair(int value, int len, int keys[], const char* values[], const char* default_value) 173c43f743SLawrence Tang { 183c43f743SLawrence Tang json_object* result = json_object_new_object(); 193c43f743SLawrence Tang json_object_object_add(result, "value", json_object_new_int(value)); 203c43f743SLawrence Tang 213c43f743SLawrence Tang //Search for human readable name, add. 22*794312c8SLawrence Tang const char* name = default_value; 233c43f743SLawrence Tang for (int i=0; i<len; i++) 243c43f743SLawrence Tang { 253c43f743SLawrence Tang if (keys[i] == value) 263c43f743SLawrence Tang name = values[i]; 273c43f743SLawrence Tang } 283c43f743SLawrence Tang 293c43f743SLawrence Tang json_object_object_add(result, "name", json_object_new_string(name)); 303c43f743SLawrence Tang return result; 313c43f743SLawrence Tang } 323c43f743SLawrence Tang 33*794312c8SLawrence Tang //Converts the given uint8 bitfield to IR, assuming bit 0 starts on the left. 34*794312c8SLawrence Tang json_object* bitfield8_to_ir(UINT8 bitfield, int num_fields, const char* names[]) 35*794312c8SLawrence Tang { 36*794312c8SLawrence Tang json_object* result = json_object_new_object(); 37*794312c8SLawrence Tang for (int i=0; i<num_fields; i++) 38*794312c8SLawrence Tang { 39*794312c8SLawrence Tang json_object_object_add(result, names[i], json_object_new_boolean((bitfield >> (7 - i)) & 0b1)); 40*794312c8SLawrence Tang } 41*794312c8SLawrence Tang 42*794312c8SLawrence Tang return result; 43*794312c8SLawrence Tang } 44*794312c8SLawrence Tang 45*794312c8SLawrence Tang //Converts the given bitfield to IR, assuming bit 0 starts on the left. 46*794312c8SLawrence Tang json_object* bitfield_to_ir(UINT32 bitfield, int num_fields, const char* names[]) 47*794312c8SLawrence Tang { 48*794312c8SLawrence Tang json_object* result = json_object_new_object(); 49*794312c8SLawrence Tang for (int i=0; i<num_fields; i++) 50*794312c8SLawrence Tang { 51*794312c8SLawrence Tang json_object_object_add(result, names[i], json_object_new_boolean((bitfield >> (31 - i)) & 0b1)); 52*794312c8SLawrence Tang } 53*794312c8SLawrence Tang 54*794312c8SLawrence Tang return result; 55*794312c8SLawrence Tang } 56*794312c8SLawrence Tang 57*794312c8SLawrence Tang //Converts the given 64 bit bitfield to IR, assuming bit 0 starts on the left. 58*794312c8SLawrence Tang json_object* bitfield64_to_ir(UINT64 bitfield, int num_fields, const char* names[]) 59*794312c8SLawrence Tang { 60*794312c8SLawrence Tang json_object* result = json_object_new_object(); 61*794312c8SLawrence Tang for (int i=0; i<num_fields; i++) 62*794312c8SLawrence Tang { 63*794312c8SLawrence Tang json_object_object_add(result, names[i], json_object_new_boolean((bitfield >> (63 - i)) & 0b1)); 64*794312c8SLawrence Tang } 65*794312c8SLawrence Tang 66*794312c8SLawrence Tang return result; 67*794312c8SLawrence Tang } 68*794312c8SLawrence Tang 69*794312c8SLawrence Tang 701b0b00e3SLawrence Tang //Converts a single UINT16 revision number into JSON IR representation. 711b0b00e3SLawrence Tang json_object* revision_to_ir(UINT16 revision) 721b0b00e3SLawrence Tang { 731b0b00e3SLawrence Tang json_object* revision_info = json_object_new_object(); 741b0b00e3SLawrence Tang json_object_object_add(revision_info, "major", json_object_new_int(revision >> 8)); 751b0b00e3SLawrence Tang json_object_object_add(revision_info, "minor", json_object_new_int(revision & 0xFF)); 761b0b00e3SLawrence Tang return revision_info; 771b0b00e3SLawrence Tang } 781b0b00e3SLawrence Tang 791b0b00e3SLawrence Tang //Returns the appropriate string for the given integer severity. 801b0b00e3SLawrence Tang const char* severity_to_string(UINT8 severity) 811b0b00e3SLawrence Tang { 821b0b00e3SLawrence Tang return severity < 4 ? CPER_SEVERITY_TYPES[severity] : "Unknown"; 831b0b00e3SLawrence Tang } 841b0b00e3SLawrence Tang 851b0b00e3SLawrence Tang //Helper function to convert an EDK EFI GUID into a string for intermediate use. 861b0b00e3SLawrence Tang void guid_to_string(char* out, EFI_GUID* guid) 871b0b00e3SLawrence Tang { 881b0b00e3SLawrence Tang sprintf(out, "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x", 891b0b00e3SLawrence Tang guid->Data1, 901b0b00e3SLawrence Tang guid->Data2, 911b0b00e3SLawrence Tang guid->Data3, 921b0b00e3SLawrence Tang guid->Data4[0], 931b0b00e3SLawrence Tang guid->Data4[1], 941b0b00e3SLawrence Tang guid->Data4[2], 951b0b00e3SLawrence Tang guid->Data4[3], 961b0b00e3SLawrence Tang guid->Data4[4], 971b0b00e3SLawrence Tang guid->Data4[5], 981b0b00e3SLawrence Tang guid->Data4[6], 991b0b00e3SLawrence Tang guid->Data4[7]); 1001b0b00e3SLawrence Tang } 1011b0b00e3SLawrence Tang 1021b0b00e3SLawrence Tang //Returns one if two EFI GUIDs are equal, zero otherwise. 1031b0b00e3SLawrence Tang int guid_equal(EFI_GUID* a, EFI_GUID* b) 1041b0b00e3SLawrence Tang { 1051b0b00e3SLawrence Tang //Check top base 3 components. 1061b0b00e3SLawrence Tang if (a->Data1 != b->Data1 1071b0b00e3SLawrence Tang || a->Data2 != b->Data2 1081b0b00e3SLawrence Tang || a->Data3 != b->Data3) 1091b0b00e3SLawrence Tang { 1101b0b00e3SLawrence Tang return 0; 1111b0b00e3SLawrence Tang } 1121b0b00e3SLawrence Tang 1131b0b00e3SLawrence Tang //Check Data4 array for equality. 1141b0b00e3SLawrence Tang for (int i=0; i<8; i++) 1151b0b00e3SLawrence Tang { 1161b0b00e3SLawrence Tang if (a->Data4[i] != b->Data4[i]) 1171b0b00e3SLawrence Tang return 0; 1181b0b00e3SLawrence Tang } 1191b0b00e3SLawrence Tang 1201b0b00e3SLawrence Tang return 1; 1211b0b00e3SLawrence Tang }