blob: 0bbe40e75ec28ce98a131d2fa7fdd22ea23d1e24 [file] [log] [blame]
Lawrence Tang1b0b00e2022-07-05 10:33:10 +01001/**
2 * Describes functions for converting processor-generic CPER sections from binary and JSON format
3 * into an intermediate format.
Ed Tanousfedd4572024-07-12 13:56:00 -07004 *
Lawrence Tang1b0b00e2022-07-05 10:33:10 +01005 * Author: Lawrence.Tang@arm.com
6 **/
7
8#include <stdio.h>
Lawrence Tang0cb33792022-07-13 13:51:39 +01009#include <string.h>
Lawrence Tang5202bbb2022-08-12 14:54:36 +010010#include <json.h>
Thu Nguyene42fb482024-10-15 14:43:11 +000011#include <libcper/Cper.h>
12#include <libcper/cper-utils.h>
13#include <libcper/sections/cper-section-generic.h>
Ed Tanous50b966f2025-03-11 09:06:19 -070014#include <libcper/log.h>
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -070015#include <string.h>
Lawrence Tang1b0b00e2022-07-05 10:33:10 +010016
17//Converts the given processor-generic CPER section into JSON IR.
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -070018json_object *cper_section_generic_to_ir(const UINT8 *section, UINT32 size,
19 char **desc_string)
Lawrence Tang1b0b00e2022-07-05 10:33:10 +010020{
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -070021 int outstr_len = 0;
22 *desc_string = malloc(SECTION_DESC_STRING_SIZE);
23 outstr_len = snprintf(*desc_string, SECTION_DESC_STRING_SIZE,
24 "A Generic Processor Error occurred");
25 if (outstr_len < 0) {
26 cper_print_log(
27 "Error: Could not write to Generic description string\n");
28 } else if (outstr_len > SECTION_DESC_STRING_SIZE) {
29 cper_print_log("Error: Generic description string truncated\n");
30 }
31
Ed Tanous12dbd4f2025-03-08 19:05:01 -080032 if (size < sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA)) {
33 return NULL;
34 }
35
Lawrence Tange407b4c2022-07-21 13:54:01 +010036 EFI_PROCESSOR_GENERIC_ERROR_DATA *section_generic =
37 (EFI_PROCESSOR_GENERIC_ERROR_DATA *)section;
38 json_object *section_ir = json_object_new_object();
Lawrence Tang3c43f742022-07-05 11:37:17 +010039
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080040 ValidationTypes ui64Type = {
41 UINT_64T, .value.ui64 = section_generic->ValidFields
42 };
Lawrence Tang3c43f742022-07-05 11:37:17 +010043
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080044 if (isvalid_prop_to_ir(&ui64Type, 0)) {
45 //Processor type, with human readable name if possible.
46 json_object *processor_type = integer_to_readable_pair(
47 section_generic->Type,
48 sizeof(GENERIC_PROC_TYPES_KEYS) / sizeof(int),
49 GENERIC_PROC_TYPES_KEYS, GENERIC_PROC_TYPES_VALUES,
50 "Unknown (Reserved)");
51 json_object_object_add(section_ir, "processorType",
52 processor_type);
53 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010054
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080055 if (isvalid_prop_to_ir(&ui64Type, 1)) {
56 //Processor ISA, with human readable name if possible.
57 json_object *processor_isa = integer_to_readable_pair(
58 section_generic->Isa,
59 sizeof(GENERIC_ISA_TYPES_KEYS) / sizeof(int),
60 GENERIC_ISA_TYPES_KEYS, GENERIC_ISA_TYPES_VALUES,
61 "Unknown (Reserved)");
62 json_object_object_add(section_ir, "processorISA",
63 processor_isa);
64 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010065
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080066 if (isvalid_prop_to_ir(&ui64Type, 2)) {
67 //Processor error type, with human readable name if possible.
68 json_object *processor_error_type = integer_to_readable_pair(
69 section_generic->ErrorType,
70 sizeof(GENERIC_ERROR_TYPES_KEYS) / sizeof(int),
71 GENERIC_ERROR_TYPES_KEYS, GENERIC_ERROR_TYPES_VALUES,
72 "Unknown (Reserved)");
73 json_object_object_add(section_ir, "errorType",
74 processor_error_type);
75 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010076
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080077 if (isvalid_prop_to_ir(&ui64Type, 3)) {
78 //The operation performed, with a human readable name if possible.
79 json_object *operation = integer_to_readable_pair(
80 section_generic->Operation,
81 sizeof(GENERIC_OPERATION_TYPES_KEYS) / sizeof(int),
82 GENERIC_OPERATION_TYPES_KEYS,
83 GENERIC_OPERATION_TYPES_VALUES, "Unknown (Reserved)");
84 json_object_object_add(section_ir, "operation", operation);
85 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010086
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080087 if (isvalid_prop_to_ir(&ui64Type, 4)) {
88 //Flags, additional information about the error.
89 json_object *flags =
90 bitfield_to_ir(section_generic->Flags, 4,
91 GENERIC_FLAGS_BITFIELD_NAMES);
92 json_object_object_add(section_ir, "flags", flags);
93 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010094
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080095 if (isvalid_prop_to_ir(&ui64Type, 5)) {
96 //The level of the error.
97 json_object_object_add(
98 section_ir, "level",
99 json_object_new_int(section_generic->Level));
100 }
Lawrence Tang3c43f742022-07-05 11:37:17 +0100101
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800102 if (isvalid_prop_to_ir(&ui64Type, 6)) {
103 //CPU version information.
104 json_object_object_add(
105 section_ir, "cpuVersionInfo",
106 json_object_new_uint64(section_generic->VersionInfo));
107 }
Lawrence Tang3c43f742022-07-05 11:37:17 +0100108
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800109 if (isvalid_prop_to_ir(&ui64Type, 7)) {
110 //CPU brand string. May not exist if on ARM.
Ed Tanous5e2164a2025-03-09 09:20:44 -0700111 add_untrusted_string(section_ir, "cpuBrandString",
112 section_generic->BrandString,
113 sizeof(section_generic->BrandString));
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800114 }
Lawrence Tang3c43f742022-07-05 11:37:17 +0100115
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800116 if (isvalid_prop_to_ir(&ui64Type, 8)) {
117 //Remaining 64-bit fields.
118 json_object_object_add(
119 section_ir, "processorID",
120 json_object_new_uint64(section_generic->ApicId));
121 }
122
123 if (isvalid_prop_to_ir(&ui64Type, 9)) {
124 json_object_object_add(
125 section_ir, "targetAddress",
126 json_object_new_uint64(section_generic->TargetAddr));
127 }
128
129 if (isvalid_prop_to_ir(&ui64Type, 10)) {
130 json_object_object_add(
131 section_ir, "requestorID",
132 json_object_new_uint64(section_generic->RequestorId));
133 }
134
135 if (isvalid_prop_to_ir(&ui64Type, 11)) {
136 json_object_object_add(
137 section_ir, "responderID",
138 json_object_new_uint64(section_generic->ResponderId));
139 }
140
141 if (isvalid_prop_to_ir(&ui64Type, 12)) {
142 json_object_object_add(
143 section_ir, "instructionIP",
144 json_object_new_uint64(section_generic->InstructionIP));
145 }
Lawrence Tang3c43f742022-07-05 11:37:17 +0100146
Lawrence Tange407b4c2022-07-21 13:54:01 +0100147 return section_ir;
Lawrence Tang0cb33792022-07-13 13:51:39 +0100148}
149
150//Converts the given CPER-JSON processor-generic error section into CPER binary,
151//outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100152void ir_section_generic_to_cper(json_object *section, FILE *out)
Lawrence Tang0cb33792022-07-13 13:51:39 +0100153{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100154 EFI_PROCESSOR_GENERIC_ERROR_DATA *section_cper =
155 (EFI_PROCESSOR_GENERIC_ERROR_DATA *)calloc(
156 1, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA));
Lawrence Tang0cb33792022-07-13 13:51:39 +0100157
Lawrence Tange407b4c2022-07-21 13:54:01 +0100158 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800159 //Remove
160 // section_cper->ValidFields = ir_to_bitfield(
161 // json_object_object_get(section, "validationBits"), 13,
162 // GENERIC_VALIDATION_BITFIELD_NAMES);
163 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
164 struct json_object *obj = NULL;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100165 //Various name/value pair fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800166 if (json_object_object_get_ex(section, "processorType", &obj)) {
167 section_cper->Type = (UINT8)readable_pair_to_integer(obj);
168 add_to_valid_bitfield(&ui64Type, 0);
169 }
170 if (json_object_object_get_ex(section, "processorISA", &obj)) {
171 section_cper->Isa = (UINT8)readable_pair_to_integer(obj);
172 add_to_valid_bitfield(&ui64Type, 1);
173 }
174 if (json_object_object_get_ex(section, "errorType", &obj)) {
175 section_cper->ErrorType = (UINT8)readable_pair_to_integer(obj);
176 add_to_valid_bitfield(&ui64Type, 2);
177 }
178 if (json_object_object_get_ex(section, "operation", &obj)) {
179 section_cper->Operation = (UINT8)readable_pair_to_integer(obj);
180 add_to_valid_bitfield(&ui64Type, 3);
181 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100182 //Flags.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800183 if (json_object_object_get_ex(section, "flags", &obj)) {
184 section_cper->Flags = (UINT8)ir_to_bitfield(
185 obj, 4, GENERIC_FLAGS_BITFIELD_NAMES);
186 add_to_valid_bitfield(&ui64Type, 4);
187 }
Lawrence Tang0cb33792022-07-13 13:51:39 +0100188
Lawrence Tange407b4c2022-07-21 13:54:01 +0100189 //Various numeric/string fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800190 if (json_object_object_get_ex(section, "level", &obj)) {
191 section_cper->Level = (UINT8)json_object_get_int(obj);
192 add_to_valid_bitfield(&ui64Type, 5);
193 }
194 if (json_object_object_get_ex(section, "cpuVersionInfo", &obj)) {
195 section_cper->VersionInfo = json_object_get_uint64(obj);
196 add_to_valid_bitfield(&ui64Type, 6);
197 }
198 if (json_object_object_get_ex(section, "processorID", &obj)) {
199 section_cper->ApicId = json_object_get_uint64(obj);
200 add_to_valid_bitfield(&ui64Type, 8);
201 }
202 if (json_object_object_get_ex(section, "targetAddress", &obj)) {
203 section_cper->TargetAddr = json_object_get_uint64(obj);
204 add_to_valid_bitfield(&ui64Type, 9);
205 }
206 if (json_object_object_get_ex(section, "requestorID", &obj)) {
207 section_cper->RequestorId = json_object_get_uint64(obj);
208 add_to_valid_bitfield(&ui64Type, 10);
209 }
210 if (json_object_object_get_ex(section, "responderID", &obj)) {
211 section_cper->ResponderId = json_object_get_uint64(obj);
212 add_to_valid_bitfield(&ui64Type, 11);
213 }
214 if (json_object_object_get_ex(section, "instructionIP", &obj)) {
215 section_cper->InstructionIP = json_object_get_uint64(obj);
216 add_to_valid_bitfield(&ui64Type, 12);
217 }
Lawrence Tang0cb33792022-07-13 13:51:39 +0100218
Lawrence Tange407b4c2022-07-21 13:54:01 +0100219 //CPU brand string.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800220 if (json_object_object_get_ex(section, "cpuBrandString", &obj)) {
221 const char *brand_string = json_object_get_string(obj);
222 if (brand_string != NULL) {
223 strncpy(section_cper->BrandString, brand_string,
224 sizeof(section_cper->BrandString) - 1);
225 section_cper
226 ->BrandString[sizeof(section_cper->BrandString) -
227 1] = '\0';
228 }
229 add_to_valid_bitfield(&ui64Type, 7);
John Chungf8fc7052024-05-03 20:05:29 +0800230 }
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800231 section_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100232
233 //Write & flush out to file, free memory.
234 fwrite(section_cper, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA), 1, out);
235 fflush(out);
236 free(section_cper);
John Chungf8fc7052024-05-03 20:05:29 +0800237}