xref: /openbmc/libcper/ir-parse.c (revision b44314c7)
1f0f95574SLawrence Tang /**
2f0f95574SLawrence Tang  * Describes functions for parsing JSON IR CPER data into binary CPER format.
3f0f95574SLawrence Tang  *
4f0f95574SLawrence Tang  * Author: Lawrence.Tang@arm.com
5f0f95574SLawrence Tang  **/
6f0f95574SLawrence Tang 
7f0f95574SLawrence Tang #include <stdio.h>
8f0f95574SLawrence Tang #include "json.h"
9*b44314c7SLawrence Tang #include "edk/Cper.h"
10f0f95574SLawrence Tang #include "cper-parse.h"
11*b44314c7SLawrence Tang #include "cper-utils.h"
12*b44314c7SLawrence Tang 
13*b44314c7SLawrence Tang //Private pre-declarations.
14*b44314c7SLawrence Tang void ir_header_to_cper(json_object* header_ir, EFI_COMMON_ERROR_RECORD_HEADER* header);
15f0f95574SLawrence Tang 
16f0f95574SLawrence Tang //Converts the given JSON IR CPER representation into CPER binary format, piped to the provided file stream.
17*b44314c7SLawrence Tang //This function performs no validation of the IR against the CPER-JSON specification. For this, call
18*b44314c7SLawrence Tang //validate_schema() from json-schema.h before attempting to call this function.
19f0f95574SLawrence Tang void ir_to_cper(json_object* ir, FILE* out)
20f0f95574SLawrence Tang {
21*b44314c7SLawrence Tang     //Create the CPER header.
22*b44314c7SLawrence Tang     EFI_COMMON_ERROR_RECORD_HEADER* header = (EFI_COMMON_ERROR_RECORD_HEADER*)calloc(1, sizeof(EFI_COMMON_ERROR_RECORD_HEADER));
23*b44314c7SLawrence Tang     ir_header_to_cper(json_object_object_get(ir, "header"), header);
24*b44314c7SLawrence Tang     fwrite(header, sizeof(EFI_COMMON_ERROR_RECORD_HEADER), 1, out);
25*b44314c7SLawrence Tang 
26f0f95574SLawrence Tang     //...
27*b44314c7SLawrence Tang 
28*b44314c7SLawrence Tang     //Free all resources.
29*b44314c7SLawrence Tang     fflush(out);
30*b44314c7SLawrence Tang     free(header);
31*b44314c7SLawrence Tang }
32*b44314c7SLawrence Tang 
33*b44314c7SLawrence Tang //Converts a CPER-JSON IR header to a CPER header structure.
34*b44314c7SLawrence Tang void ir_header_to_cper(json_object* header_ir, EFI_COMMON_ERROR_RECORD_HEADER* header)
35*b44314c7SLawrence Tang {
36*b44314c7SLawrence Tang     header->SignatureStart = 0x52455043; //CPER
37*b44314c7SLawrence Tang     printf("beginning write.\n");
38*b44314c7SLawrence Tang 
39*b44314c7SLawrence Tang     //Revision.
40*b44314c7SLawrence Tang     json_object* revision = json_object_object_get(header_ir, "revision");
41*b44314c7SLawrence Tang     int minor = json_object_get_int(json_object_object_get(revision, "minor"));
42*b44314c7SLawrence Tang     int major = json_object_get_int(json_object_object_get(revision, "major"));
43*b44314c7SLawrence Tang     header->Revision = minor + (major << 8);
44*b44314c7SLawrence Tang 
45*b44314c7SLawrence Tang     header->SignatureEnd = 0xFFFFFFFF;
46*b44314c7SLawrence Tang 
47*b44314c7SLawrence Tang     //Section count.
48*b44314c7SLawrence Tang     int section_count = json_object_get_int(json_object_object_get(header_ir, "sectionCount"));
49*b44314c7SLawrence Tang     header->SectionCount = (UINT16)section_count;
50*b44314c7SLawrence Tang 
51*b44314c7SLawrence Tang     //Error severity.
52*b44314c7SLawrence Tang     json_object* severity = json_object_object_get(header_ir, "severity");
53*b44314c7SLawrence Tang     header->ErrorSeverity = (UINT32)json_object_get_uint64(json_object_object_get(severity, "code"));
54*b44314c7SLawrence Tang 
55*b44314c7SLawrence Tang     //Validation bits.
56*b44314c7SLawrence Tang     header->ValidationBits = ir_to_bitfield(json_object_object_get(header_ir, "validationBits"),
57*b44314c7SLawrence Tang         3, CPER_HEADER_VALID_BITFIELD_NAMES);
58*b44314c7SLawrence Tang 
59*b44314c7SLawrence Tang     //Record length.
60*b44314c7SLawrence Tang     header->RecordLength = (UINT32)json_object_get_uint64(json_object_object_get(header_ir, "recordLength"));
61*b44314c7SLawrence Tang 
62*b44314c7SLawrence Tang     //Timestamp, if present.
63*b44314c7SLawrence Tang     printf("timestamp write.\n");
64*b44314c7SLawrence Tang     json_object* timestamp = json_object_object_get(header_ir, "timestamp");
65*b44314c7SLawrence Tang     if (timestamp != NULL)
66*b44314c7SLawrence Tang     {
67*b44314c7SLawrence Tang         string_to_timestamp(&header->TimeStamp, json_object_get_string(timestamp));
68*b44314c7SLawrence Tang         header->TimeStamp.Flag = json_object_get_boolean(json_object_object_get(header_ir, "timestampIsPrecise"));
69*b44314c7SLawrence Tang     }
70*b44314c7SLawrence Tang 
71*b44314c7SLawrence Tang     //Various GUIDs.
72*b44314c7SLawrence Tang     printf("guid write.\n");
73*b44314c7SLawrence Tang     json_object* platform_id = json_object_object_get(header_ir, "platformID");
74*b44314c7SLawrence Tang     json_object* partition_id = json_object_object_get(header_ir, "partitionID");
75*b44314c7SLawrence Tang     if (platform_id != NULL)
76*b44314c7SLawrence Tang         string_to_guid(&header->PlatformID, json_object_get_string(platform_id));
77*b44314c7SLawrence Tang     if (partition_id != NULL)
78*b44314c7SLawrence Tang         string_to_guid(&header->PartitionID, json_object_get_string(partition_id));
79*b44314c7SLawrence Tang     string_to_guid(&header->CreatorID, json_object_get_string(json_object_object_get(header_ir, "creatorID")));
80*b44314c7SLawrence Tang 
81*b44314c7SLawrence Tang     //Notification type.
82*b44314c7SLawrence Tang     printf("notif type write.\n");
83*b44314c7SLawrence Tang     json_object* notification_type = json_object_object_get(header_ir, "notificationType");
84*b44314c7SLawrence Tang     string_to_guid(&header->NotificationType, json_object_get_string(json_object_object_get(notification_type, "guid")));
85*b44314c7SLawrence Tang 
86*b44314c7SLawrence Tang     //Record ID, persistence info.
87*b44314c7SLawrence Tang     header->RecordID = json_object_get_uint64(json_object_object_get(header_ir, "recordID"));
88*b44314c7SLawrence Tang     header->PersistenceInfo = json_object_get_uint64(json_object_object_get(header_ir, "persistenceInfo"));
89*b44314c7SLawrence Tang 
90*b44314c7SLawrence Tang     //Flags.
91*b44314c7SLawrence Tang     printf("flag write.\n");
92*b44314c7SLawrence Tang     json_object* flags = json_object_object_get(header_ir, "flags");
93*b44314c7SLawrence Tang     header->Flags = (UINT32)json_object_get_uint64(json_object_object_get(flags, "value"));
94f0f95574SLawrence Tang }