blob: 81d124827016b556fcfcbcff4cd20d4430db54c9 [file] [log] [blame]
Lawrence Tang794312c2022-07-05 14:46:10 +01001/**
2 * Describes functions for converting IA32/x64 CPER sections from binary and JSON format
3 * into an intermediate format.
Ed Tanousfedd4572024-07-12 13:56:00 -07004 *
Lawrence Tang794312c2022-07-05 14:46:10 +01005 * Author: Lawrence.Tang@arm.com
6 **/
7
8#include <stdio.h>
Lawrence Tang5202bbb2022-08-12 14:54:36 +01009#include <json.h>
Thu Nguyene42fb482024-10-15 14:43:11 +000010#include <libcper/base64.h>
11#include <libcper/Cper.h>
12#include <libcper/cper-utils.h>
13#include <libcper/sections/cper-section-ia32x64.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 Tang794312c2022-07-05 14:46:10 +010016
17//Private pre-definitions.
Lawrence Tange407b4c2022-07-21 13:54:01 +010018json_object *cper_ia32x64_processor_error_info_to_ir(
19 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info);
20json_object *cper_ia32x64_cache_tlb_check_to_ir(
21 EFI_IA32_X64_CACHE_CHECK_INFO *cache_tlb_check);
22json_object *
23cper_ia32x64_bus_check_to_ir(EFI_IA32_X64_BUS_CHECK_INFO *bus_check);
24json_object *cper_ia32x64_ms_check_to_ir(EFI_IA32_X64_MS_CHECK_INFO *ms_check);
25json_object *cper_ia32x64_processor_context_info_to_ir(
Ed Tanous12dbd4f2025-03-08 19:05:01 -080026 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos,
27 UINT32 *remaining_size);
Lawrence Tange407b4c2022-07-21 13:54:01 +010028json_object *
29cper_ia32x64_register_32bit_to_ir(EFI_CONTEXT_IA32_REGISTER_STATE *registers);
30json_object *
31cper_ia32x64_register_64bit_to_ir(EFI_CONTEXT_X64_REGISTER_STATE *registers);
32void ir_ia32x64_error_info_to_cper(json_object *error_info, FILE *out);
33void ir_ia32x64_context_info_to_cper(json_object *context_info, FILE *out);
34void ir_ia32x64_cache_tlb_check_error_to_cper(
35 json_object *check_info,
36 EFI_IA32_X64_CACHE_CHECK_INFO *check_info_cper);
37void ir_ia32x64_bus_check_error_to_cper(
38 json_object *check_info, EFI_IA32_X64_BUS_CHECK_INFO *check_info_cper);
39void ir_ia32x64_ms_check_error_to_cper(
40 json_object *check_info, EFI_IA32_X64_MS_CHECK_INFO *check_info_cper);
41void ir_ia32x64_ia32_registers_to_cper(json_object *registers, FILE *out);
42void ir_ia32x64_x64_registers_to_cper(json_object *registers, FILE *out);
Lawrence Tangd0c88842022-07-13 14:51:17 +010043
44//////////////////
45/// CPER TO IR ///
46//////////////////
Lawrence Tang794312c2022-07-05 14:46:10 +010047
48//Converts the IA32/x64 error section described in the given descriptor into intermediate format.
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -070049json_object *cper_section_ia32x64_to_ir(const UINT8 *section, UINT32 size,
50 char **desc_string)
Lawrence Tang794312c2022-07-05 14:46:10 +010051{
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -070052 int outstr_len = 0;
53 *desc_string = malloc(SECTION_DESC_STRING_SIZE);
54 outstr_len = snprintf(*desc_string, SECTION_DESC_STRING_SIZE,
55 "An IA32/x64 Processor Error occurred");
56 if (outstr_len < 0) {
57 cper_print_log(
58 "Error: Could not write to IA32/x64 description string\n");
59 } else if (outstr_len > SECTION_DESC_STRING_SIZE) {
60 cper_print_log(
61 "Error: IA32/x64 description string truncated\n");
62 }
63
Ed Tanous12dbd4f2025-03-08 19:05:01 -080064 if (size < sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD)) {
65 return NULL;
66 }
Lawrence Tange407b4c2022-07-21 13:54:01 +010067 EFI_IA32_X64_PROCESSOR_ERROR_RECORD *record =
68 (EFI_IA32_X64_PROCESSOR_ERROR_RECORD *)section;
Ed Tanous12dbd4f2025-03-08 19:05:01 -080069 UINT32 remaining_size =
70 size - sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD);
Lawrence Tange407b4c2022-07-21 13:54:01 +010071 json_object *record_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +010072
Lawrence Tange407b4c2022-07-21 13:54:01 +010073 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080074 //validation bits contain information
75 //about processorErrorInfoNum and processorContextInfoNum.
76 //Ensure this is decoded properly in IR->CPER
John Chungf8fc7052024-05-03 20:05:29 +080077 int processor_error_info_num = (record->ValidFields >> 2) & 0x3F;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080078 json_object_object_add(record_ir, "processorErrorInfoNum",
Lawrence Tange407b4c2022-07-21 13:54:01 +010079 json_object_new_int(processor_error_info_num));
John Chungf8fc7052024-05-03 20:05:29 +080080 int processor_context_info_num = (record->ValidFields >> 8) & 0x3F;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080081 json_object_object_add(record_ir, "processorContextInfoNum",
Lawrence Tange407b4c2022-07-21 13:54:01 +010082 json_object_new_int(processor_context_info_num));
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080083
84 ValidationTypes ui64Type = { UINT_64T,
85 .value.ui64 = record->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +010086
Lawrence Tange407b4c2022-07-21 13:54:01 +010087 //APIC ID.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080088 if (isvalid_prop_to_ir(&ui64Type, 0)) {
89 json_object_object_add(record_ir, "localAPICID",
90 json_object_new_uint64(record->ApicId));
91 }
Lawrence Tang794312c2022-07-05 14:46:10 +010092
Lawrence Tange407b4c2022-07-21 13:54:01 +010093 //CPUID information.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080094 if (isvalid_prop_to_ir(&ui64Type, 1)) {
95 json_object *cpuid_info_ir = json_object_new_object();
96 EFI_IA32_X64_CPU_ID *cpuid_info =
97 (EFI_IA32_X64_CPU_ID *)record->CpuIdInfo;
98 json_object_object_add(cpuid_info_ir, "eax",
99 json_object_new_uint64(cpuid_info->Eax));
100 json_object_object_add(cpuid_info_ir, "ebx",
101 json_object_new_uint64(cpuid_info->Ebx));
102 json_object_object_add(cpuid_info_ir, "ecx",
103 json_object_new_uint64(cpuid_info->Ecx));
104 json_object_object_add(cpuid_info_ir, "edx",
105 json_object_new_uint64(cpuid_info->Edx));
106 json_object_object_add(record_ir, "cpuidInfo", cpuid_info_ir);
107 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100108
Lawrence Tange407b4c2022-07-21 13:54:01 +0100109 //Processor error information, of the amount described above.
110 EFI_IA32_X64_PROCESS_ERROR_INFO *current_error_info =
111 (EFI_IA32_X64_PROCESS_ERROR_INFO *)(record + 1);
112 json_object *error_info_array = json_object_new_array();
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800113 if (remaining_size < (processor_error_info_num *
114 sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO))) {
115 json_object_put(error_info_array);
116 json_object_put(record_ir);
Ed Tanous50b966f2025-03-11 09:06:19 -0700117 cper_print_log(
118 "Invalid CPER file: Invalid processor error info num.\n");
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800119 return NULL;
120 }
121
Lawrence Tange407b4c2022-07-21 13:54:01 +0100122 for (int i = 0; i < processor_error_info_num; i++) {
123 json_object_array_add(error_info_array,
124 cper_ia32x64_processor_error_info_to_ir(
125 current_error_info));
126 current_error_info++;
127 }
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800128 remaining_size -= processor_error_info_num *
129 sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO);
130
Lawrence Tange407b4c2022-07-21 13:54:01 +0100131 json_object_object_add(record_ir, "processorErrorInfo",
132 error_info_array);
Lawrence Tang794312c2022-07-05 14:46:10 +0100133
Lawrence Tange407b4c2022-07-21 13:54:01 +0100134 //Processor context information, of the amount described above.
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800135 if (remaining_size < (processor_context_info_num *
136 sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO))) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800137 json_object_put(record_ir);
Ed Tanous50b966f2025-03-11 09:06:19 -0700138 cper_print_log(
139 "Invalid CPER file: Invalid processor context info num.\n");
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800140 return NULL;
141 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100142 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *current_context_info =
143 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)current_error_info;
144 void *cur_pos = (void *)current_context_info;
145 json_object *context_info_array = json_object_new_array();
146 for (int i = 0; i < processor_context_info_num; i++) {
Ed Tanousd6b62632025-03-14 15:30:07 -0700147 json_object *context_info =
148 cper_ia32x64_processor_context_info_to_ir(
149 current_context_info, &cur_pos,
150 &remaining_size);
Ed Tanousd6b62632025-03-14 15:30:07 -0700151 json_object_array_add(context_info_array, context_info);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100152 current_context_info =
153 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)cur_pos;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800154
Lawrence Tange407b4c2022-07-21 13:54:01 +0100155 //The context array is a non-fixed size, pointer is shifted within the above function.
156 }
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800157
Lawrence Tange407b4c2022-07-21 13:54:01 +0100158 json_object_object_add(record_ir, "processorContextInfo",
159 context_info_array);
Lawrence Tang794312c2022-07-05 14:46:10 +0100160
Lawrence Tange407b4c2022-07-21 13:54:01 +0100161 return record_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100162}
163
Ed Tanous1a648562025-03-10 15:23:38 -0700164EFI_GUID *gEfiIa32x64ErrorTypeGuids[] = {
165 &gEfiIa32x64ErrorTypeCacheCheckGuid,
166 &gEfiIa32x64ErrorTypeTlbCheckGuid,
167 &gEfiIa32x64ErrorTypeBusCheckGuid,
168 &gEfiIa32x64ErrorTypeMsCheckGuid,
169};
170
Lawrence Tang794312c2022-07-05 14:46:10 +0100171//Converts a single IA32/x64 processor error info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100172json_object *cper_ia32x64_processor_error_info_to_ir(
173 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info)
Lawrence Tang794312c2022-07-05 14:46:10 +0100174{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100175 json_object *error_info_ir = json_object_new_object();
Ed Tanousc2ebddd2025-03-09 10:07:01 -0700176 json_object *type = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100177
Lawrence Tange407b4c2022-07-21 13:54:01 +0100178 //Error structure type (as GUID).
Ed Tanousc2ebddd2025-03-09 10:07:01 -0700179 add_guid(type, "guid", &error_info->ErrorType);
Lawrence Tang794312c2022-07-05 14:46:10 +0100180
Lawrence Tang3592da72022-07-21 16:50:07 +0100181 //Get the error structure type as a readable string.
182 const char *readable_type = "Unknown";
Ed Tanous1a648562025-03-10 15:23:38 -0700183
184 const char *readable_names[] = {
185 "Cache Check Error",
186 "TLB Check Error",
187 "Bus Check Error",
188 "MS Check Error",
189 };
190
191 int index = select_guid_from_list(
192 &error_info->ErrorType, gEfiIa32x64ErrorTypeGuids,
193 sizeof(gEfiIa32x64ErrorTypeGuids) / sizeof(EFI_GUID *));
194
195 if (index < (int)(sizeof(readable_names) / sizeof(char *))) {
196 readable_type = readable_names[index];
John Chungf8fc7052024-05-03 20:05:29 +0800197 }
Ed Tanous1a648562025-03-10 15:23:38 -0700198
John Chungf8fc7052024-05-03 20:05:29 +0800199 json_object_object_add(type, "name",
200 json_object_new_string(readable_type));
Lawrence Tang3592da72022-07-21 16:50:07 +0100201 json_object_object_add(error_info_ir, "type", type);
202
Lawrence Tange407b4c2022-07-21 13:54:01 +0100203 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800204 ValidationTypes ui64Type = { UINT_64T,
205 .value.ui64 = error_info->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +0100206
Lawrence Tange407b4c2022-07-21 13:54:01 +0100207 //Add the check information on a per-structure basis.
208 //Cache and TLB check information are identical, so can be equated.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800209 if (isvalid_prop_to_ir(&ui64Type, 0)) {
210 json_object *check_information = NULL;
Ed Tanous1a648562025-03-10 15:23:38 -0700211
212 switch (index) {
213 case 0:
214 case 1:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800215 check_information = cper_ia32x64_cache_tlb_check_to_ir(
216 (EFI_IA32_X64_CACHE_CHECK_INFO *)&error_info
217 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700218 break;
219 case 2:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800220 check_information = cper_ia32x64_bus_check_to_ir(
221 (EFI_IA32_X64_BUS_CHECK_INFO *)&error_info
222 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700223 break;
224 case 3:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800225 check_information = cper_ia32x64_ms_check_to_ir(
226 (EFI_IA32_X64_MS_CHECK_INFO *)&error_info
227 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700228 break;
229 default:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800230 //Unknown check information.
Ed Tanous50b966f2025-03-11 09:06:19 -0700231 cper_print_log(
232 "WARN: Invalid/unknown check information GUID found in IA32/x64 CPER section. Ignoring.\n");
Ed Tanous1a648562025-03-10 15:23:38 -0700233 break;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800234 }
Ed Tanous8e423942025-03-14 23:11:06 -0700235 if (check_information != NULL) {
236 json_object_object_add(error_info_ir, "checkInfo",
237 check_information);
238 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100239 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100240
Lawrence Tange407b4c2022-07-21 13:54:01 +0100241 //Target, requestor, and responder identifiers.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800242 if (isvalid_prop_to_ir(&ui64Type, 1)) {
243 json_object_object_add(
244 error_info_ir, "targetAddressID",
245 json_object_new_uint64(error_info->TargetId));
246 }
247 if (isvalid_prop_to_ir(&ui64Type, 2)) {
248 json_object_object_add(
249 error_info_ir, "requestorID",
250 json_object_new_uint64(error_info->RequestorId));
251 }
252 if (isvalid_prop_to_ir(&ui64Type, 3)) {
253 json_object_object_add(
254 error_info_ir, "responderID",
255 json_object_new_uint64(error_info->ResponderId));
256 }
257 if (isvalid_prop_to_ir(&ui64Type, 4)) {
258 json_object_object_add(
259 error_info_ir, "instructionPointer",
260 json_object_new_uint64(error_info->InstructionIP));
261 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100262
Lawrence Tange407b4c2022-07-21 13:54:01 +0100263 return error_info_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100264}
265
266//Converts a single IA32/x64 cache or TLB check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100267json_object *cper_ia32x64_cache_tlb_check_to_ir(
268 EFI_IA32_X64_CACHE_CHECK_INFO *cache_tlb_check)
Lawrence Tang794312c2022-07-05 14:46:10 +0100269{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100270 json_object *cache_tlb_check_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100271
Lawrence Tange407b4c2022-07-21 13:54:01 +0100272 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800273 ValidationTypes ui64Type = {
274 UINT_64T, .value.ui64 = cache_tlb_check->ValidFields
275 };
Lawrence Tang794312c2022-07-05 14:46:10 +0100276
Lawrence Tange407b4c2022-07-21 13:54:01 +0100277 //Transaction type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800278 if (isvalid_prop_to_ir(&ui64Type, 0)) {
279 json_object *transaction_type = integer_to_readable_pair(
280 cache_tlb_check->TransactionType, 3,
281 IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
282 IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
283 "Unknown (Reserved)");
284 json_object_object_add(cache_tlb_check_ir, "transactionType",
285 transaction_type);
286 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100287
Lawrence Tange407b4c2022-07-21 13:54:01 +0100288 //Operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800289 if (isvalid_prop_to_ir(&ui64Type, 1)) {
290 json_object *operation = integer_to_readable_pair(
291 cache_tlb_check->Operation, 9,
292 IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
293 IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
294 "Unknown (Reserved)");
295 json_object_object_add(cache_tlb_check_ir, "operation",
296 operation);
297 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100298
Lawrence Tange407b4c2022-07-21 13:54:01 +0100299 //Affected cache/TLB level.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800300 if (isvalid_prop_to_ir(&ui64Type, 2)) {
301 json_object_object_add(
302 cache_tlb_check_ir, "level",
303 json_object_new_uint64(cache_tlb_check->Level));
304 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100305
Lawrence Tange407b4c2022-07-21 13:54:01 +0100306 //Miscellaneous boolean fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800307 if (isvalid_prop_to_ir(&ui64Type, 3)) {
308 json_object_object_add(
309 cache_tlb_check_ir, "processorContextCorrupt",
310 json_object_new_boolean(
311 cache_tlb_check->ContextCorrupt));
312 }
313 if (isvalid_prop_to_ir(&ui64Type, 4)) {
314 json_object_object_add(
315 cache_tlb_check_ir, "uncorrected",
316 json_object_new_boolean(
317 cache_tlb_check->ErrorUncorrected));
318 }
319 if (isvalid_prop_to_ir(&ui64Type, 5)) {
320 json_object_object_add(
321 cache_tlb_check_ir, "preciseIP",
322 json_object_new_boolean(cache_tlb_check->PreciseIp));
323 }
324 if (isvalid_prop_to_ir(&ui64Type, 6)) {
325 json_object_object_add(cache_tlb_check_ir, "restartableIP",
326 json_object_new_boolean(
327 cache_tlb_check->RestartableIp));
328 }
329 if (isvalid_prop_to_ir(&ui64Type, 7)) {
330 json_object_object_add(
331 cache_tlb_check_ir, "overflow",
332 json_object_new_boolean(cache_tlb_check->Overflow));
333 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100334
Lawrence Tange407b4c2022-07-21 13:54:01 +0100335 return cache_tlb_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100336}
337
338//Converts a single IA32/x64 bus check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100339json_object *
340cper_ia32x64_bus_check_to_ir(EFI_IA32_X64_BUS_CHECK_INFO *bus_check)
341{
342 json_object *bus_check_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100343
Lawrence Tange407b4c2022-07-21 13:54:01 +0100344 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800345 ValidationTypes ui64Type = { UINT_64T,
346 .value.ui64 = bus_check->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +0100347
Lawrence Tange407b4c2022-07-21 13:54:01 +0100348 //Transaction type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800349 if (isvalid_prop_to_ir(&ui64Type, 0)) {
350 json_object *transaction_type = integer_to_readable_pair(
351 bus_check->TransactionType, 3,
352 IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
353 IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
354 "Unknown (Reserved)");
355 json_object_object_add(bus_check_ir, "transactionType",
356 transaction_type);
357 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100358
Lawrence Tange407b4c2022-07-21 13:54:01 +0100359 //Operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800360 if (isvalid_prop_to_ir(&ui64Type, 1)) {
361 json_object *operation = integer_to_readable_pair(
362 bus_check->Operation, 9,
363 IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
364 IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
365 "Unknown (Reserved)");
366 json_object_object_add(bus_check_ir, "operation", operation);
367 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100368
Lawrence Tange407b4c2022-07-21 13:54:01 +0100369 //Affected bus level.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800370 if (isvalid_prop_to_ir(&ui64Type, 2)) {
371 json_object_object_add(
372 bus_check_ir, "level",
373 json_object_new_uint64(bus_check->Level));
374 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100375
Lawrence Tange407b4c2022-07-21 13:54:01 +0100376 //Miscellaneous boolean fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800377 if (isvalid_prop_to_ir(&ui64Type, 3)) {
378 json_object_object_add(
379 bus_check_ir, "processorContextCorrupt",
380 json_object_new_boolean(bus_check->ContextCorrupt));
381 }
382 if (isvalid_prop_to_ir(&ui64Type, 4)) {
383 json_object_object_add(
384 bus_check_ir, "uncorrected",
385 json_object_new_boolean(bus_check->ErrorUncorrected));
386 }
387 if (isvalid_prop_to_ir(&ui64Type, 5)) {
388 json_object_object_add(
389 bus_check_ir, "preciseIP",
390 json_object_new_boolean(bus_check->PreciseIp));
391 }
392 if (isvalid_prop_to_ir(&ui64Type, 6)) {
393 json_object_object_add(
394 bus_check_ir, "restartableIP",
395 json_object_new_boolean(bus_check->RestartableIp));
396 }
397 if (isvalid_prop_to_ir(&ui64Type, 7)) {
398 json_object_object_add(
399 bus_check_ir, "overflow",
400 json_object_new_boolean(bus_check->Overflow));
401 }
402 if (isvalid_prop_to_ir(&ui64Type, 9)) {
403 json_object_object_add(
404 bus_check_ir, "timedOut",
405 json_object_new_boolean(bus_check->TimeOut));
406 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100407
Lawrence Tange407b4c2022-07-21 13:54:01 +0100408 //Participation type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800409 if (isvalid_prop_to_ir(&ui64Type, 8)) {
410 json_object *participation_type = integer_to_readable_pair(
411 bus_check->ParticipationType, 4,
412 IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_KEYS,
413 IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_VALUES,
414 "Unknown");
415 json_object_object_add(bus_check_ir, "participationType",
416 participation_type);
417 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100418
Lawrence Tange407b4c2022-07-21 13:54:01 +0100419 //Address space.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800420 if (isvalid_prop_to_ir(&ui64Type, 10)) {
421 json_object *address_space = integer_to_readable_pair(
422 bus_check->AddressSpace, 4,
423 IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_KEYS,
424 IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_VALUES,
425 "Unknown");
426 json_object_object_add(bus_check_ir, "addressSpace",
427 address_space);
428 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100429
430 return bus_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100431}
432
433//Converts a single IA32/x64 MS check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100434json_object *cper_ia32x64_ms_check_to_ir(EFI_IA32_X64_MS_CHECK_INFO *ms_check)
Lawrence Tang794312c2022-07-05 14:46:10 +0100435{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100436 json_object *ms_check_ir = json_object_new_object();
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800437 ValidationTypes ui64Type = { UINT_64T,
438 .value.ui64 = ms_check->ValidFields };
Lawrence Tange407b4c2022-07-21 13:54:01 +0100439 //Validation bits.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100440 //Error type (operation that caused the error).
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800441 if (isvalid_prop_to_ir(&ui64Type, 0)) {
442 json_object *error_type = integer_to_readable_pair(
443 ms_check->ErrorType, 4,
444 IA32X64_MS_CHECK_INFO_ERROR_TYPES_KEYS,
445 IA32X64_MS_CHECK_INFO_ERROR_TYPES_VALUES,
446 "Unknown (Processor Specific)");
447 json_object_object_add(ms_check_ir, "errorType", error_type);
448 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100449
Lawrence Tange407b4c2022-07-21 13:54:01 +0100450 //Miscellaneous fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800451 if (isvalid_prop_to_ir(&ui64Type, 1)) {
452 json_object_object_add(
453 ms_check_ir, "processorContextCorrupt",
454 json_object_new_boolean(ms_check->ContextCorrupt));
455 }
456 if (isvalid_prop_to_ir(&ui64Type, 2)) {
457 json_object_object_add(
458 ms_check_ir, "uncorrected",
459 json_object_new_boolean(ms_check->ErrorUncorrected));
460 }
461 if (isvalid_prop_to_ir(&ui64Type, 3)) {
462 json_object_object_add(
463 ms_check_ir, "preciseIP",
464 json_object_new_boolean(ms_check->PreciseIp));
465 }
466 if (isvalid_prop_to_ir(&ui64Type, 4)) {
467 json_object_object_add(
468 ms_check_ir, "restartableIP",
469 json_object_new_boolean(ms_check->RestartableIp));
470 }
471 if (isvalid_prop_to_ir(&ui64Type, 5)) {
472 json_object_object_add(
473 ms_check_ir, "overflow",
474 json_object_new_boolean(ms_check->Overflow));
475 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100476
477 return ms_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100478}
479
480//Converts a single IA32/x64 processor context info entry into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100481json_object *cper_ia32x64_processor_context_info_to_ir(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800482 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos,
483 UINT32 *remaining_size)
Lawrence Tang794312c2022-07-05 14:46:10 +0100484{
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800485 if (*remaining_size < sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO)) {
Ed Tanous8e423942025-03-14 23:11:06 -0700486 return NULL;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800487 }
488 *remaining_size -= sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO);
Ed Tanous8e423942025-03-14 23:11:06 -0700489 json_object *context_info_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100490
Lawrence Tange407b4c2022-07-21 13:54:01 +0100491 //Register context type.
492 json_object *context_type = integer_to_readable_pair(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800493 context_info->RegisterType, IA32X64_REGISTER_CONTEXT_TYPES_SIZE,
Lawrence Tange407b4c2022-07-21 13:54:01 +0100494 IA32X64_REGISTER_CONTEXT_TYPES_KEYS,
495 IA32X64_REGISTER_CONTEXT_TYPES_VALUES, "Unknown (Reserved)");
496 json_object_object_add(context_info_ir, "registerContextType",
497 context_type);
Lawrence Tang794312c2022-07-05 14:46:10 +0100498
Lawrence Tange407b4c2022-07-21 13:54:01 +0100499 //Register array size, MSR and MM address.
500 json_object_object_add(context_info_ir, "registerArraySize",
501 json_object_new_uint64(context_info->ArraySize));
502 json_object_object_add(
503 context_info_ir, "msrAddress",
504 json_object_new_uint64(context_info->MsrAddress));
505 json_object_object_add(
506 context_info_ir, "mmRegisterAddress",
507 json_object_new_uint64(context_info->MmRegisterAddress));
Lawrence Tang794312c2022-07-05 14:46:10 +0100508
Lawrence Tange407b4c2022-07-21 13:54:01 +0100509 //Register array.
510 json_object *register_array = NULL;
511 if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800512 if (*remaining_size < sizeof(EFI_CONTEXT_IA32_REGISTER_STATE)) {
Ed Tanousd6b62632025-03-14 15:30:07 -0700513 return context_info_ir;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800514 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100515 EFI_CONTEXT_IA32_REGISTER_STATE *register_state =
516 (EFI_CONTEXT_IA32_REGISTER_STATE *)(context_info + 1);
517 register_array =
518 cper_ia32x64_register_32bit_to_ir(register_state);
519 *cur_pos = (void *)(register_state + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800520 *remaining_size -= sizeof(EFI_CONTEXT_IA32_REGISTER_STATE);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100521 } else if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_X64) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800522 if (*remaining_size < sizeof(EFI_CONTEXT_X64_REGISTER_STATE)) {
Ed Tanousd6b62632025-03-14 15:30:07 -0700523 return context_info_ir;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800524 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100525 EFI_CONTEXT_X64_REGISTER_STATE *register_state =
526 (EFI_CONTEXT_X64_REGISTER_STATE *)(context_info + 1);
527 register_array =
528 cper_ia32x64_register_64bit_to_ir(register_state);
529 *cur_pos = (void *)(register_state + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800530 *remaining_size -= sizeof(EFI_CONTEXT_X64_REGISTER_STATE);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100531 } else {
532 //No parseable data, just dump as base64 and shift the head to the next item.
533 *cur_pos = (void *)(context_info + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800534 if (*remaining_size < context_info->ArraySize) {
Ed Tanousd6b62632025-03-14 15:30:07 -0700535 return context_info_ir;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800536 }
Ed Tanousa7d2cdd2024-07-15 11:07:27 -0700537 int32_t encoded_len = 0;
538 char *encoded = base64_encode((UINT8 *)*cur_pos,
539 context_info->ArraySize,
540 &encoded_len);
541 if (encoded == NULL) {
Ed Tanous50b966f2025-03-11 09:06:19 -0700542 cper_print_log(
543 "Failed to allocate encode output buffer. \n");
John Chungf8fc7052024-05-03 20:05:29 +0800544 } else {
John Chungf8fc7052024-05-03 20:05:29 +0800545 register_array = json_object_new_object();
546 json_object_object_add(register_array, "data",
547 json_object_new_string_len(
548 encoded, encoded_len));
549 free(encoded);
550 }
Lawrence Tangd7e8ca32022-07-07 10:25:53 +0100551
Lawrence Tange407b4c2022-07-21 13:54:01 +0100552 *cur_pos =
553 (void *)(((char *)*cur_pos) + context_info->ArraySize);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800554 *remaining_size -= context_info->ArraySize;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100555 }
Ed Tanous8e423942025-03-14 23:11:06 -0700556 if (register_array != NULL) {
557 json_object_object_add(context_info_ir, "registerArray",
558 register_array);
559 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100560
Lawrence Tange407b4c2022-07-21 13:54:01 +0100561 return context_info_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100562}
563
564//Converts a single CPER IA32 register state into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100565json_object *
566cper_ia32x64_register_32bit_to_ir(EFI_CONTEXT_IA32_REGISTER_STATE *registers)
Lawrence Tang794312c2022-07-05 14:46:10 +0100567{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100568 json_object *ia32_registers = json_object_new_object();
569 json_object_object_add(ia32_registers, "eax",
570 json_object_new_uint64(registers->Eax));
571 json_object_object_add(ia32_registers, "ebx",
572 json_object_new_uint64(registers->Ebx));
573 json_object_object_add(ia32_registers, "ecx",
574 json_object_new_uint64(registers->Ecx));
575 json_object_object_add(ia32_registers, "edx",
576 json_object_new_uint64(registers->Edx));
577 json_object_object_add(ia32_registers, "esi",
578 json_object_new_uint64(registers->Esi));
579 json_object_object_add(ia32_registers, "edi",
580 json_object_new_uint64(registers->Edi));
581 json_object_object_add(ia32_registers, "ebp",
582 json_object_new_uint64(registers->Ebp));
583 json_object_object_add(ia32_registers, "esp",
584 json_object_new_uint64(registers->Esp));
585 json_object_object_add(ia32_registers, "cs",
586 json_object_new_uint64(registers->Cs));
587 json_object_object_add(ia32_registers, "ds",
588 json_object_new_uint64(registers->Ds));
589 json_object_object_add(ia32_registers, "ss",
590 json_object_new_uint64(registers->Ss));
591 json_object_object_add(ia32_registers, "es",
592 json_object_new_uint64(registers->Es));
593 json_object_object_add(ia32_registers, "fs",
594 json_object_new_uint64(registers->Fs));
595 json_object_object_add(ia32_registers, "gs",
596 json_object_new_uint64(registers->Gs));
597 json_object_object_add(ia32_registers, "eflags",
598 json_object_new_uint64(registers->Eflags));
599 json_object_object_add(ia32_registers, "eip",
600 json_object_new_uint64(registers->Eip));
601 json_object_object_add(ia32_registers, "cr0",
602 json_object_new_uint64(registers->Cr0));
603 json_object_object_add(ia32_registers, "cr1",
604 json_object_new_uint64(registers->Cr1));
605 json_object_object_add(ia32_registers, "cr2",
606 json_object_new_uint64(registers->Cr2));
607 json_object_object_add(ia32_registers, "cr3",
608 json_object_new_uint64(registers->Cr3));
609 json_object_object_add(ia32_registers, "cr4",
610 json_object_new_uint64(registers->Cr4));
611 json_object_object_add(
612 ia32_registers, "gdtr",
613 json_object_new_uint64(registers->Gdtr[0] +
614 ((UINT64)registers->Gdtr[1] << 32)));
615 json_object_object_add(
616 ia32_registers, "idtr",
617 json_object_new_uint64(registers->Idtr[0] +
618 ((UINT64)registers->Idtr[1] << 32)));
619 json_object_object_add(ia32_registers, "ldtr",
620 json_object_new_uint64(registers->Ldtr));
621 json_object_object_add(ia32_registers, "tr",
622 json_object_new_uint64(registers->Tr));
Lawrence Tang794312c2022-07-05 14:46:10 +0100623
Lawrence Tange407b4c2022-07-21 13:54:01 +0100624 return ia32_registers;
Lawrence Tang794312c2022-07-05 14:46:10 +0100625}
626
627//Converts a single CPER x64 register state into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100628json_object *
629cper_ia32x64_register_64bit_to_ir(EFI_CONTEXT_X64_REGISTER_STATE *registers)
Lawrence Tang794312c2022-07-05 14:46:10 +0100630{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100631 json_object *x64_registers = json_object_new_object();
632 json_object_object_add(x64_registers, "rax",
633 json_object_new_uint64(registers->Rax));
634 json_object_object_add(x64_registers, "rbx",
635 json_object_new_uint64(registers->Rbx));
636 json_object_object_add(x64_registers, "rcx",
637 json_object_new_uint64(registers->Rcx));
638 json_object_object_add(x64_registers, "rdx",
639 json_object_new_uint64(registers->Rdx));
640 json_object_object_add(x64_registers, "rsi",
641 json_object_new_uint64(registers->Rsi));
642 json_object_object_add(x64_registers, "rdi",
643 json_object_new_uint64(registers->Rdi));
644 json_object_object_add(x64_registers, "rbp",
645 json_object_new_uint64(registers->Rbp));
646 json_object_object_add(x64_registers, "rsp",
647 json_object_new_uint64(registers->Rsp));
648 json_object_object_add(x64_registers, "r8",
649 json_object_new_uint64(registers->R8));
650 json_object_object_add(x64_registers, "r9",
651 json_object_new_uint64(registers->R9));
652 json_object_object_add(x64_registers, "r10",
653 json_object_new_uint64(registers->R10));
654 json_object_object_add(x64_registers, "r11",
655 json_object_new_uint64(registers->R11));
656 json_object_object_add(x64_registers, "r12",
657 json_object_new_uint64(registers->R12));
658 json_object_object_add(x64_registers, "r13",
659 json_object_new_uint64(registers->R13));
660 json_object_object_add(x64_registers, "r14",
661 json_object_new_uint64(registers->R14));
662 json_object_object_add(x64_registers, "r15",
663 json_object_new_uint64(registers->R15));
664 json_object_object_add(x64_registers, "cs",
665 json_object_new_int(registers->Cs));
666 json_object_object_add(x64_registers, "ds",
667 json_object_new_int(registers->Ds));
668 json_object_object_add(x64_registers, "ss",
669 json_object_new_int(registers->Ss));
670 json_object_object_add(x64_registers, "es",
671 json_object_new_int(registers->Es));
672 json_object_object_add(x64_registers, "fs",
673 json_object_new_int(registers->Fs));
674 json_object_object_add(x64_registers, "gs",
675 json_object_new_int(registers->Gs));
676 json_object_object_add(x64_registers, "rflags",
677 json_object_new_uint64(registers->Rflags));
678 json_object_object_add(x64_registers, "eip",
679 json_object_new_uint64(registers->Rip));
680 json_object_object_add(x64_registers, "cr0",
681 json_object_new_uint64(registers->Cr0));
682 json_object_object_add(x64_registers, "cr1",
683 json_object_new_uint64(registers->Cr1));
684 json_object_object_add(x64_registers, "cr2",
685 json_object_new_uint64(registers->Cr2));
686 json_object_object_add(x64_registers, "cr3",
687 json_object_new_uint64(registers->Cr3));
688 json_object_object_add(x64_registers, "cr4",
689 json_object_new_uint64(registers->Cr4));
690 json_object_object_add(x64_registers, "cr8",
691 json_object_new_uint64(registers->Cr8));
692 json_object_object_add(x64_registers, "gdtr_0",
693 json_object_new_uint64(registers->Gdtr[0]));
694 json_object_object_add(x64_registers, "gdtr_1",
695 json_object_new_uint64(registers->Gdtr[1]));
696 json_object_object_add(x64_registers, "idtr_0",
697 json_object_new_uint64(registers->Idtr[0]));
698 json_object_object_add(x64_registers, "idtr_1",
699 json_object_new_uint64(registers->Idtr[1]));
700 json_object_object_add(x64_registers, "ldtr",
701 json_object_new_int(registers->Ldtr));
702 json_object_object_add(x64_registers, "tr",
703 json_object_new_int(registers->Tr));
Lawrence Tang794312c2022-07-05 14:46:10 +0100704
Lawrence Tange407b4c2022-07-21 13:54:01 +0100705 return x64_registers;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100706}
707
708//////////////////
709/// IR TO CPER ///
710//////////////////
711
712//Converts a single IA32/x64 CPER-JSON section into CPER binary, outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100713void ir_section_ia32x64_to_cper(json_object *section, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100714{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100715 EFI_IA32_X64_PROCESSOR_ERROR_RECORD *section_cper =
716 (EFI_IA32_X64_PROCESSOR_ERROR_RECORD *)calloc(
717 1, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100718
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800719 uint64_t valid = 0x0;
720
721 int proc_error_info_num = json_object_get_int(json_object_object_get(
722 section, "processorErrorInfoNum")) &
723 0x3F;
724 int proc_ctx_info_num = json_object_get_int(json_object_object_get(
725 section, "processorContextInfoNum")) &
726 0x3F;
727 valid |= proc_error_info_num << 2;
728 valid |= proc_ctx_info_num << 8;
729
730 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = valid };
731 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100732
Lawrence Tange407b4c2022-07-21 13:54:01 +0100733 //Local APIC ID.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800734 if (json_object_object_get_ex(section, "localAPICID", &obj)) {
735 section_cper->ApicId = json_object_get_uint64(obj);
736 add_to_valid_bitfield(&ui64Type, 0);
737 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100738
Lawrence Tange407b4c2022-07-21 13:54:01 +0100739 //CPUID info.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800740 if (json_object_object_get_ex(section, "cpuidInfo", &obj)) {
741 json_object *cpuid_info = obj;
742 EFI_IA32_X64_CPU_ID *cpuid_info_cper =
743 (EFI_IA32_X64_CPU_ID *)section_cper->CpuIdInfo;
744 cpuid_info_cper->Eax = json_object_get_uint64(
745 json_object_object_get(cpuid_info, "eax"));
746 cpuid_info_cper->Ebx = json_object_get_uint64(
747 json_object_object_get(cpuid_info, "ebx"));
748 cpuid_info_cper->Ecx = json_object_get_uint64(
749 json_object_object_get(cpuid_info, "ecx"));
750 cpuid_info_cper->Edx = json_object_get_uint64(
751 json_object_object_get(cpuid_info, "edx"));
752 add_to_valid_bitfield(&ui64Type, 1);
753 }
754 section_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100755
Lawrence Tange407b4c2022-07-21 13:54:01 +0100756 //Flush the header to file before dealing w/ info sections.
757 fwrite(section_cper, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD), 1,
758 out);
759 fflush(out);
760 free(section_cper);
761
762 //Iterate and deal with sections.
763 json_object *error_info =
764 json_object_object_get(section, "processorErrorInfo");
765 json_object *context_info =
766 json_object_object_get(section, "processorContextInfo");
John Chungf8fc7052024-05-03 20:05:29 +0800767 for (int i = 0; i < proc_error_info_num; i++) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100768 ir_ia32x64_error_info_to_cper(
769 json_object_array_get_idx(error_info, i), out);
John Chungf8fc7052024-05-03 20:05:29 +0800770 }
771 for (int i = 0; i < proc_ctx_info_num; i++) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100772 ir_ia32x64_context_info_to_cper(
773 json_object_array_get_idx(context_info, i), out);
John Chungf8fc7052024-05-03 20:05:29 +0800774 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100775}
776
777//Converts a single CPER-JSON IA32/x64 error information structure into CPER binary, outputting to the
778//provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100779void ir_ia32x64_error_info_to_cper(json_object *error_info, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100780{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100781 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info_cper =
782 (EFI_IA32_X64_PROCESS_ERROR_INFO *)calloc(
783 1, sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100784
Lawrence Tange407b4c2022-07-21 13:54:01 +0100785 //Error structure type.
Lawrence Tang3592da72022-07-21 16:50:07 +0100786 json_object *type = json_object_object_get(error_info, "type");
787 string_to_guid(
788 &error_info_cper->ErrorType,
789 json_object_get_string(json_object_object_get(type, "guid")));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100790
Lawrence Tange407b4c2022-07-21 13:54:01 +0100791 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800792 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
793 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100794
Lawrence Tange407b4c2022-07-21 13:54:01 +0100795 //Check information, parsed based on the error type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800796 if (json_object_object_get_ex(error_info, "checkInfo", &obj)) {
797 json_object *check_info = obj;
Ed Tanous1a648562025-03-10 15:23:38 -0700798
799 int index = select_guid_from_list(
800 &error_info_cper->ErrorType, gEfiIa32x64ErrorTypeGuids,
801 sizeof(gEfiIa32x64ErrorTypeGuids) / sizeof(EFI_GUID *));
802
803 switch (index) {
804 case 0:
805 case 1:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800806 ir_ia32x64_cache_tlb_check_error_to_cper(
807 check_info,
808 (EFI_IA32_X64_CACHE_CHECK_INFO
809 *)&error_info_cper->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700810 break;
811 case 2:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800812 ir_ia32x64_bus_check_error_to_cper(
813 check_info,
814 (EFI_IA32_X64_BUS_CHECK_INFO *)&error_info_cper
815 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700816 break;
817 case 3:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800818 ir_ia32x64_ms_check_error_to_cper(
819 check_info,
820 (EFI_IA32_X64_MS_CHECK_INFO *)&error_info_cper
821 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700822 break;
823 default:
824 //Unknown check information.
Ed Tanous50b966f2025-03-11 09:06:19 -0700825 cper_print_log(
826 "WARN: Invalid/unknown check information GUID found in IA32/x64 CPER section. Ignoring.\n");
Ed Tanous1a648562025-03-10 15:23:38 -0700827 break;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800828 }
829 add_to_valid_bitfield(&ui64Type, 0);
John Chungf8fc7052024-05-03 20:05:29 +0800830 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100831
Lawrence Tange407b4c2022-07-21 13:54:01 +0100832 //Miscellaneous numeric fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800833 if (json_object_object_get_ex(error_info, "targetAddressID", &obj)) {
834 error_info_cper->TargetId = json_object_get_uint64(obj);
835 add_to_valid_bitfield(&ui64Type, 1);
836 }
837 if (json_object_object_get_ex(error_info, "requestorID", &obj)) {
838 error_info_cper->RequestorId = json_object_get_uint64(obj);
839 add_to_valid_bitfield(&ui64Type, 2);
840 }
841 if (json_object_object_get_ex(error_info, "responderID", &obj)) {
842 error_info_cper->ResponderId = json_object_get_uint64(obj);
843 add_to_valid_bitfield(&ui64Type, 3);
844 }
845 if (json_object_object_get_ex(error_info, "instructionPointer", &obj)) {
846 error_info_cper->InstructionIP = json_object_get_uint64(obj);
847 add_to_valid_bitfield(&ui64Type, 4);
848 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100849
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800850 error_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100851 //Write out to stream, then free resources.
852 fwrite(error_info_cper, sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO), 1,
853 out);
854 fflush(out);
855 free(error_info_cper);
Lawrence Tangd0c88842022-07-13 14:51:17 +0100856}
857
858//Converts a single CPER-JSON IA32/x64 cache/TLB check error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100859void ir_ia32x64_cache_tlb_check_error_to_cper(
860 json_object *check_info, EFI_IA32_X64_CACHE_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100861{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100862 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800863 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
864 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100865
Lawrence Tange407b4c2022-07-21 13:54:01 +0100866 //Transaction type, operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800867 if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
868 check_info_cper->TransactionType =
869 readable_pair_to_integer(obj);
870 add_to_valid_bitfield(&ui64Type, 0);
871 }
872 if (json_object_object_get_ex(check_info, "operation", &obj)) {
873 check_info_cper->Operation = readable_pair_to_integer(obj);
874 add_to_valid_bitfield(&ui64Type, 1);
875 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100876
Lawrence Tange407b4c2022-07-21 13:54:01 +0100877 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800878 if (json_object_object_get_ex(check_info, "level", &obj)) {
879 check_info_cper->Level = json_object_get_uint64(obj);
880 add_to_valid_bitfield(&ui64Type, 2);
881 }
882 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
883 &obj)) {
884 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
885 add_to_valid_bitfield(&ui64Type, 3);
886 }
887 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
888 check_info_cper->ErrorUncorrected =
889 json_object_get_boolean(obj);
890 add_to_valid_bitfield(&ui64Type, 4);
891 }
892 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
893 check_info_cper->PreciseIp = json_object_get_boolean(obj);
894 add_to_valid_bitfield(&ui64Type, 5);
895 }
896 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
897 check_info_cper->RestartableIp = json_object_get_boolean(obj);
898 add_to_valid_bitfield(&ui64Type, 6);
899 }
900 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
901 check_info_cper->Overflow = json_object_get_boolean(obj);
902 add_to_valid_bitfield(&ui64Type, 7);
903 }
904 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100905}
906
907//Converts a single CPER-JSON IA32/x64 bus error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100908void ir_ia32x64_bus_check_error_to_cper(
909 json_object *check_info, EFI_IA32_X64_BUS_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100910{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100911 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800912 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
913 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100914
Lawrence Tange407b4c2022-07-21 13:54:01 +0100915 //Readable pair fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800916 if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
917 check_info_cper->TransactionType =
918 readable_pair_to_integer(obj);
919 add_to_valid_bitfield(&ui64Type, 0);
920 }
921 if (json_object_object_get_ex(check_info, "operation", &obj)) {
922 check_info_cper->Operation = readable_pair_to_integer(obj);
923 add_to_valid_bitfield(&ui64Type, 1);
924 }
925 if (json_object_object_get_ex(check_info, "participationType", &obj)) {
926 check_info_cper->ParticipationType =
927 readable_pair_to_integer(obj);
928 add_to_valid_bitfield(&ui64Type, 8);
929 }
930
931 if (json_object_object_get_ex(check_info, "addressSpace", &obj)) {
932 check_info_cper->AddressSpace = readable_pair_to_integer(obj);
933 add_to_valid_bitfield(&ui64Type, 10);
934 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100935
Lawrence Tange407b4c2022-07-21 13:54:01 +0100936 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800937 if (json_object_object_get_ex(check_info, "level", &obj)) {
938 check_info_cper->Level = json_object_get_uint64(obj);
939 add_to_valid_bitfield(&ui64Type, 2);
940 }
941 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
942 &obj)) {
943 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
944 add_to_valid_bitfield(&ui64Type, 3);
945 }
946 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
947 check_info_cper->ErrorUncorrected =
948 json_object_get_boolean(obj);
949 add_to_valid_bitfield(&ui64Type, 4);
950 }
951 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
952 check_info_cper->PreciseIp = json_object_get_boolean(obj);
953 add_to_valid_bitfield(&ui64Type, 5);
954 }
955 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
956 check_info_cper->RestartableIp = json_object_get_boolean(obj);
957 add_to_valid_bitfield(&ui64Type, 6);
958 }
959 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
960 check_info_cper->Overflow = json_object_get_boolean(obj);
961 add_to_valid_bitfield(&ui64Type, 7);
962 }
963 if (json_object_object_get_ex(check_info, "timedOut", &obj)) {
964 check_info_cper->TimeOut = json_object_get_boolean(obj);
965 add_to_valid_bitfield(&ui64Type, 9);
966 }
967 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100968}
969
970//Converts a single CPER-JSON IA32/x64 MS error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100971void ir_ia32x64_ms_check_error_to_cper(
972 json_object *check_info, EFI_IA32_X64_MS_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100973{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100974 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800975 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
976 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100977
Lawrence Tange407b4c2022-07-21 13:54:01 +0100978 //Type of MS check error.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800979 if (json_object_object_get_ex(check_info, "errorType", &obj)) {
980 check_info_cper->ErrorType = readable_pair_to_integer(obj);
981 add_to_valid_bitfield(&ui64Type, 0);
982 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100983
Lawrence Tange407b4c2022-07-21 13:54:01 +0100984 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800985 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
986 &obj)) {
987 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
988 add_to_valid_bitfield(&ui64Type, 1);
989 }
990 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
991 check_info_cper->ErrorUncorrected =
992 json_object_get_boolean(obj);
993 add_to_valid_bitfield(&ui64Type, 2);
994 }
995 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
996 check_info_cper->PreciseIp = json_object_get_boolean(obj);
997 add_to_valid_bitfield(&ui64Type, 3);
998 }
999 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
1000 check_info_cper->RestartableIp = json_object_get_boolean(obj);
1001 add_to_valid_bitfield(&ui64Type, 4);
1002 }
1003 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
1004 check_info_cper->Overflow = json_object_get_boolean(obj);
1005 add_to_valid_bitfield(&ui64Type, 5);
1006 }
1007 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +01001008}
1009
1010//Converts a single CPER-JSON IA32/x64 context information structure into CPER binary, outputting to the
1011//provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001012void ir_ia32x64_context_info_to_cper(json_object *context_info, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001013{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001014 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info_cper =
1015 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)calloc(
1016 1, sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO));
Lawrence Tangd0c88842022-07-13 14:51:17 +01001017
Lawrence Tange407b4c2022-07-21 13:54:01 +01001018 //Register context type.
1019 context_info_cper->RegisterType = (UINT16)readable_pair_to_integer(
1020 json_object_object_get(context_info, "registerContextType"));
Lawrence Tangd0c88842022-07-13 14:51:17 +01001021
Lawrence Tange407b4c2022-07-21 13:54:01 +01001022 //Miscellaneous numeric fields.
1023 context_info_cper->ArraySize = (UINT16)json_object_get_uint64(
1024 json_object_object_get(context_info, "registerArraySize"));
1025 context_info_cper->MsrAddress = (UINT32)json_object_get_uint64(
1026 json_object_object_get(context_info, "msrAddress"));
1027 context_info_cper->MmRegisterAddress = json_object_get_uint64(
1028 json_object_object_get(context_info, "mmRegisterAddress"));
Lawrence Tangd0c88842022-07-13 14:51:17 +01001029
Lawrence Tange407b4c2022-07-21 13:54:01 +01001030 //Flush header to stream.
1031 fwrite(context_info_cper, sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO),
1032 1, out);
1033 fflush(out);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001034
Lawrence Tange407b4c2022-07-21 13:54:01 +01001035 //Handle the register array, depending on type provided.
1036 json_object *register_array =
1037 json_object_object_get(context_info, "registerArray");
1038 if (context_info_cper->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
1039 ir_ia32x64_ia32_registers_to_cper(register_array, out);
1040 } else if (context_info_cper->RegisterType ==
1041 EFI_REG_CONTEXT_TYPE_X64) {
1042 ir_ia32x64_x64_registers_to_cper(register_array, out);
1043 } else {
1044 //Unknown/structure is not defined.
1045 json_object *encoded =
1046 json_object_object_get(register_array, "data");
Ed Tanousa7d2cdd2024-07-15 11:07:27 -07001047 int32_t decoded_len = 0;
1048 const char *j_string = json_object_get_string(encoded);
1049 int j_size = json_object_get_string_len(encoded);
1050 UINT8 *decoded = base64_decode(j_string, j_size, &decoded_len);
1051 if (decoded == NULL) {
Ed Tanous50b966f2025-03-11 09:06:19 -07001052 cper_print_log(
1053 "Failed to allocate decode output buffer. \n");
John Chungf8fc7052024-05-03 20:05:29 +08001054 } else {
John Chungf8fc7052024-05-03 20:05:29 +08001055 fwrite(decoded, decoded_len, 1, out);
1056 fflush(out);
1057 free(decoded);
1058 }
Lawrence Tange407b4c2022-07-21 13:54:01 +01001059 }
Lawrence Tangd0c88842022-07-13 14:51:17 +01001060
Lawrence Tange407b4c2022-07-21 13:54:01 +01001061 //Free remaining resources.
1062 free(context_info_cper);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001063}
1064
1065//Converts a single CPER-JSON IA32 register array into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001066void ir_ia32x64_ia32_registers_to_cper(json_object *registers, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001067{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001068 EFI_CONTEXT_IA32_REGISTER_STATE register_state;
1069 register_state.Eax = (UINT32)json_object_get_uint64(
1070 json_object_object_get(registers, "eax"));
1071 register_state.Ebx = (UINT32)json_object_get_uint64(
1072 json_object_object_get(registers, "ebx"));
1073 register_state.Ecx = (UINT32)json_object_get_uint64(
1074 json_object_object_get(registers, "ecx"));
1075 register_state.Edx = (UINT32)json_object_get_uint64(
1076 json_object_object_get(registers, "edx"));
1077 register_state.Esi = (UINT32)json_object_get_uint64(
1078 json_object_object_get(registers, "esi"));
1079 register_state.Edi = (UINT32)json_object_get_uint64(
1080 json_object_object_get(registers, "edi"));
1081 register_state.Ebp = (UINT32)json_object_get_uint64(
1082 json_object_object_get(registers, "ebp"));
1083 register_state.Esp = (UINT32)json_object_get_uint64(
1084 json_object_object_get(registers, "esp"));
1085 register_state.Cs = (UINT16)json_object_get_uint64(
1086 json_object_object_get(registers, "cs"));
1087 register_state.Ds = (UINT32)json_object_get_uint64(
1088 json_object_object_get(registers, "ds"));
1089 register_state.Ss = (UINT16)json_object_get_uint64(
1090 json_object_object_get(registers, "ss"));
1091 register_state.Es = (UINT16)json_object_get_uint64(
1092 json_object_object_get(registers, "es"));
1093 register_state.Fs = (UINT16)json_object_get_uint64(
1094 json_object_object_get(registers, "fs"));
1095 register_state.Gs = (UINT16)json_object_get_uint64(
1096 json_object_object_get(registers, "gs"));
1097 register_state.Eflags = (UINT32)json_object_get_uint64(
1098 json_object_object_get(registers, "eflags"));
1099 register_state.Eip = (UINT32)json_object_get_uint64(
1100 json_object_object_get(registers, "eip"));
1101 register_state.Cr0 = (UINT32)json_object_get_uint64(
1102 json_object_object_get(registers, "cr0"));
1103 register_state.Cr1 = (UINT32)json_object_get_uint64(
1104 json_object_object_get(registers, "cr1"));
1105 register_state.Cr2 = (UINT32)json_object_get_uint64(
1106 json_object_object_get(registers, "cr2"));
1107 register_state.Cr3 = (UINT32)json_object_get_uint64(
1108 json_object_object_get(registers, "cr3"));
1109 register_state.Cr4 = (UINT32)json_object_get_uint64(
1110 json_object_object_get(registers, "cr4"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001111
Lawrence Tange407b4c2022-07-21 13:54:01 +01001112 //64-bit registers are split into two 32-bit parts.
1113 UINT64 gdtr = json_object_get_uint64(
1114 json_object_object_get(registers, "gdtr"));
1115 register_state.Gdtr[0] = gdtr & 0xFFFFFFFF;
1116 register_state.Gdtr[1] = gdtr >> 32;
1117 UINT64 idtr = json_object_get_uint64(
1118 json_object_object_get(registers, "idtr"));
1119 register_state.Idtr[0] = idtr & 0xFFFFFFFF;
1120 register_state.Idtr[1] = idtr >> 32;
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001121
Lawrence Tange407b4c2022-07-21 13:54:01 +01001122 //16-bit registers.
1123 register_state.Ldtr = (UINT16)json_object_get_uint64(
1124 json_object_object_get(registers, "ldtr"));
1125 register_state.Tr = (UINT16)json_object_get_uint64(
1126 json_object_object_get(registers, "tr"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001127
Lawrence Tange407b4c2022-07-21 13:54:01 +01001128 //Write out to stream.
1129 fwrite(&register_state, sizeof(EFI_CONTEXT_IA32_REGISTER_STATE), 1,
1130 out);
1131 fflush(out);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001132}
1133
1134//Converts a single CPER-JSON x64 register array into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001135void ir_ia32x64_x64_registers_to_cper(json_object *registers, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001136{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001137 EFI_CONTEXT_X64_REGISTER_STATE register_state;
1138 register_state.Rax = json_object_get_uint64(
1139 json_object_object_get(registers, "rax"));
1140 register_state.Rbx = json_object_get_uint64(
1141 json_object_object_get(registers, "rbx"));
1142 register_state.Rcx = json_object_get_uint64(
1143 json_object_object_get(registers, "rcx"));
1144 register_state.Rdx = json_object_get_uint64(
1145 json_object_object_get(registers, "rdx"));
1146 register_state.Rsi = json_object_get_uint64(
1147 json_object_object_get(registers, "rsi"));
1148 register_state.Rdi = json_object_get_uint64(
1149 json_object_object_get(registers, "rdi"));
1150 register_state.Rbp = json_object_get_uint64(
1151 json_object_object_get(registers, "rbp"));
1152 register_state.Rsp = json_object_get_uint64(
1153 json_object_object_get(registers, "rsp"));
1154 register_state.R8 =
1155 json_object_get_uint64(json_object_object_get(registers, "r8"));
1156 register_state.R9 =
1157 json_object_get_uint64(json_object_object_get(registers, "r9"));
1158 register_state.R10 = json_object_get_uint64(
1159 json_object_object_get(registers, "r10"));
1160 register_state.R11 = json_object_get_uint64(
1161 json_object_object_get(registers, "r11"));
1162 register_state.R12 = json_object_get_uint64(
1163 json_object_object_get(registers, "r12"));
1164 register_state.R13 = json_object_get_uint64(
1165 json_object_object_get(registers, "r13"));
1166 register_state.R14 = json_object_get_uint64(
1167 json_object_object_get(registers, "r14"));
1168 register_state.R15 = json_object_get_uint64(
1169 json_object_object_get(registers, "r15"));
1170 register_state.Cs = (UINT16)json_object_get_int(
1171 json_object_object_get(registers, "cs"));
1172 register_state.Ds = (UINT16)json_object_get_int(
1173 json_object_object_get(registers, "ds"));
1174 register_state.Ss = (UINT16)json_object_get_int(
1175 json_object_object_get(registers, "ss"));
1176 register_state.Es = (UINT16)json_object_get_int(
1177 json_object_object_get(registers, "es"));
1178 register_state.Fs = (UINT16)json_object_get_int(
1179 json_object_object_get(registers, "fs"));
1180 register_state.Gs = (UINT16)json_object_get_int(
1181 json_object_object_get(registers, "gs"));
1182 register_state.Resv1 = 0;
1183 register_state.Rflags = json_object_get_uint64(
1184 json_object_object_get(registers, "rflags"));
1185 register_state.Rip = json_object_get_uint64(
1186 json_object_object_get(registers, "eip"));
1187 register_state.Cr0 = json_object_get_uint64(
1188 json_object_object_get(registers, "cr0"));
1189 register_state.Cr1 = json_object_get_uint64(
1190 json_object_object_get(registers, "cr1"));
1191 register_state.Cr2 = json_object_get_uint64(
1192 json_object_object_get(registers, "cr2"));
1193 register_state.Cr3 = json_object_get_uint64(
1194 json_object_object_get(registers, "cr3"));
1195 register_state.Cr4 = json_object_get_uint64(
1196 json_object_object_get(registers, "cr4"));
1197 register_state.Cr8 = json_object_get_uint64(
1198 json_object_object_get(registers, "cr8"));
1199 register_state.Gdtr[0] = json_object_get_uint64(
1200 json_object_object_get(registers, "gdtr_0"));
1201 register_state.Gdtr[1] = json_object_get_uint64(
1202 json_object_object_get(registers, "gdtr_1"));
1203 register_state.Idtr[0] = json_object_get_uint64(
1204 json_object_object_get(registers, "idtr_0"));
1205 register_state.Idtr[1] = json_object_get_uint64(
1206 json_object_object_get(registers, "idtr_1"));
1207 register_state.Ldtr = (UINT16)json_object_get_int(
1208 json_object_object_get(registers, "ldtr"));
1209 register_state.Tr = (UINT16)json_object_get_int(
1210 json_object_object_get(registers, "tr"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001211
Lawrence Tange407b4c2022-07-21 13:54:01 +01001212 //Write out to stream.
1213 fwrite(&register_state, sizeof(EFI_CONTEXT_X64_REGISTER_STATE), 1, out);
1214 fflush(out);
John Chungf8fc7052024-05-03 20:05:29 +08001215}