blob: 098b20db89b66368ffc54ed390ad5fd190861261 [file] [log] [blame]
Lawrence Tangd7e8ca32022-07-07 10:25:53 +01001/**
2 * Describes functions for converting CXL component error CPER sections from binary and JSON format
3 * into an intermediate format.
4 *
5 * Author: Lawrence.Tang@arm.com
6 **/
7#include <stdio.h>
Lawrence Tang5202bbb2022-08-12 14:54:36 +01008#include <json.h>
Lawrence Tang27217392022-07-07 11:55:39 +01009#include "b64.h"
Lawrence Tangd7e8ca32022-07-07 10:25:53 +010010#include "../edk/Cper.h"
11#include "../cper-utils.h"
12#include "cper-section-cxl-component.h"
13
14//Converts a single CXL component error CPER section into JSON IR.
Lawrence Tange407b4c2022-07-21 13:54:01 +010015json_object *
16cper_section_cxl_component_to_ir(void *section,
17 EFI_ERROR_SECTION_DESCRIPTOR *descriptor)
Lawrence Tangd7e8ca32022-07-07 10:25:53 +010018{
Lawrence Tange407b4c2022-07-21 13:54:01 +010019 EFI_CXL_COMPONENT_EVENT_HEADER *cxl_error =
20 (EFI_CXL_COMPONENT_EVENT_HEADER *)section;
21 json_object *section_ir = json_object_new_object();
Lawrence Tang27217392022-07-07 11:55:39 +010022
Lawrence Tange407b4c2022-07-21 13:54:01 +010023 //Length (bytes) for the entire structure.
24 json_object_object_add(section_ir, "length",
25 json_object_new_uint64(cxl_error->Length));
Lawrence Tang27217392022-07-07 11:55:39 +010026
Lawrence Tange407b4c2022-07-21 13:54:01 +010027 //Validation bits.
28 json_object *validation =
29 bitfield_to_ir(cxl_error->ValidBits, 3,
30 CXL_COMPONENT_ERROR_VALID_BITFIELD_NAMES);
31 json_object_object_add(section_ir, "validationBits", validation);
Lawrence Tang27217392022-07-07 11:55:39 +010032
Lawrence Tange407b4c2022-07-21 13:54:01 +010033 //Device ID.
34 json_object *device_id = json_object_new_object();
35 json_object_object_add(
36 device_id, "vendorID",
37 json_object_new_int(cxl_error->DeviceId.VendorId));
38 json_object_object_add(
39 device_id, "deviceID",
40 json_object_new_int(cxl_error->DeviceId.DeviceId));
41 json_object_object_add(
42 device_id, "functionNumber",
43 json_object_new_int(cxl_error->DeviceId.FunctionNumber));
44 json_object_object_add(
45 device_id, "deviceNumber",
46 json_object_new_int(cxl_error->DeviceId.DeviceNumber));
47 json_object_object_add(
48 device_id, "busNumber",
49 json_object_new_int(cxl_error->DeviceId.BusNumber));
50 json_object_object_add(
51 device_id, "segmentNumber",
52 json_object_new_int(cxl_error->DeviceId.SegmentNumber));
53 json_object_object_add(
54 device_id, "slotNumber",
55 json_object_new_int(cxl_error->DeviceId.SlotNumber));
56 json_object_object_add(section_ir, "deviceID", device_id);
Lawrence Tang27217392022-07-07 11:55:39 +010057
Lawrence Tange407b4c2022-07-21 13:54:01 +010058 //Device serial.
59 json_object_object_add(section_ir, "deviceSerial",
60 json_object_new_uint64(cxl_error->DeviceSerial));
Lawrence Tangd7e8ca32022-07-07 10:25:53 +010061
Lawrence Tange407b4c2022-07-21 13:54:01 +010062 //The specification for this is defined within the CXL Specification Section 8.2.9.1.
63 unsigned char *cur_pos = (unsigned char *)(cxl_error + 1);
64 int remaining_len = cxl_error->Length - sizeof(cxl_error);
65 if (remaining_len > 0) {
66 json_object *event_log = json_object_new_object();
67 char *encoded = b64_encode(cur_pos, remaining_len);
68 json_object_object_add(event_log, "data",
69 json_object_new_string(encoded));
70 free(encoded);
71 json_object_object_add(section_ir, "cxlComponentEventLog",
72 event_log);
73 }
74
75 return section_ir;
Lawrence Tangaec83902022-07-18 09:41:08 +010076}
77
78//Converts a single given CXL Component CPER-JSON section into CPER binary, outputting to the
79//given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +010080void ir_section_cxl_component_to_cper(json_object *section, FILE *out)
Lawrence Tangaec83902022-07-18 09:41:08 +010081{
Lawrence Tange407b4c2022-07-21 13:54:01 +010082 EFI_CXL_COMPONENT_EVENT_HEADER *section_cper =
83 (EFI_CXL_COMPONENT_EVENT_HEADER *)calloc(
84 1, sizeof(EFI_CXL_COMPONENT_EVENT_HEADER));
Lawrence Tangaec83902022-07-18 09:41:08 +010085
Lawrence Tange407b4c2022-07-21 13:54:01 +010086 //Length of the structure.
87 section_cper->Length = json_object_get_uint64(
88 json_object_object_get(section, "length"));
Lawrence Tangaec83902022-07-18 09:41:08 +010089
Lawrence Tange407b4c2022-07-21 13:54:01 +010090 //Validation bits.
91 section_cper->ValidBits = ir_to_bitfield(
92 json_object_object_get(section, "validationBits"), 3,
93 CXL_COMPONENT_ERROR_VALID_BITFIELD_NAMES);
Lawrence Tangaec83902022-07-18 09:41:08 +010094
Lawrence Tange407b4c2022-07-21 13:54:01 +010095 //Device ID information.
96 json_object *device_id = json_object_object_get(section, "deviceID");
97 section_cper->DeviceId.VendorId = json_object_get_uint64(
98 json_object_object_get(device_id, "vendorID"));
99 section_cper->DeviceId.DeviceId = json_object_get_uint64(
100 json_object_object_get(device_id, "deviceID"));
101 section_cper->DeviceId.FunctionNumber = json_object_get_uint64(
102 json_object_object_get(device_id, "functionNumber"));
103 section_cper->DeviceId.DeviceNumber = json_object_get_uint64(
104 json_object_object_get(device_id, "deviceNumber"));
105 section_cper->DeviceId.BusNumber = json_object_get_uint64(
106 json_object_object_get(device_id, "busNumber"));
107 section_cper->DeviceId.SegmentNumber = json_object_get_uint64(
108 json_object_object_get(device_id, "segmentNumber"));
109 section_cper->DeviceId.SlotNumber = json_object_get_uint64(
110 json_object_object_get(device_id, "slotNumber"));
Lawrence Tangaec83902022-07-18 09:41:08 +0100111
Lawrence Tange407b4c2022-07-21 13:54:01 +0100112 //Device serial number.
113 section_cper->DeviceSerial = json_object_get_uint64(
114 json_object_object_get(section, "deviceSerial"));
Lawrence Tangaec83902022-07-18 09:41:08 +0100115
Lawrence Tange407b4c2022-07-21 13:54:01 +0100116 //Write header out to stream.
117 fwrite(section_cper, sizeof(EFI_CXL_COMPONENT_EVENT_HEADER), 1, out);
118 fflush(out);
Lawrence Tangaec83902022-07-18 09:41:08 +0100119
Lawrence Tange407b4c2022-07-21 13:54:01 +0100120 //CXL component event log, decoded from base64.
121 json_object *event_log =
122 json_object_object_get(section, "cxlComponentEventLog");
123 json_object *encoded = json_object_object_get(event_log, "data");
124 int log_length =
125 section_cper->Length - sizeof(EFI_CXL_COMPONENT_EVENT_HEADER);
126 char *decoded = b64_decode(json_object_get_string(encoded),
127 json_object_get_string_len(encoded));
128 fwrite(decoded, log_length, 1, out);
129 fflush(out);
130 free(decoded);
Lawrence Tangaec83902022-07-18 09:41:08 +0100131
Lawrence Tange407b4c2022-07-21 13:54:01 +0100132 free(section_cper);
Lawrence Tangd7e8ca32022-07-07 10:25:53 +0100133}