xref: /openbmc/libcper/cper-utils.c (revision 794312c8)
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 }