blob: bf7f56560cfbb195faade29c8b9acf3b527754b2 [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>
Lawrence Tang794312c2022-07-05 14:46:10 +010014
15//Private pre-definitions.
Lawrence Tange407b4c2022-07-21 13:54:01 +010016json_object *cper_ia32x64_processor_error_info_to_ir(
17 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info);
18json_object *cper_ia32x64_cache_tlb_check_to_ir(
19 EFI_IA32_X64_CACHE_CHECK_INFO *cache_tlb_check);
20json_object *
21cper_ia32x64_bus_check_to_ir(EFI_IA32_X64_BUS_CHECK_INFO *bus_check);
22json_object *cper_ia32x64_ms_check_to_ir(EFI_IA32_X64_MS_CHECK_INFO *ms_check);
23json_object *cper_ia32x64_processor_context_info_to_ir(
Ed Tanous12dbd4f2025-03-08 19:05:01 -080024 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos,
25 UINT32 *remaining_size);
Lawrence Tange407b4c2022-07-21 13:54:01 +010026json_object *
27cper_ia32x64_register_32bit_to_ir(EFI_CONTEXT_IA32_REGISTER_STATE *registers);
28json_object *
29cper_ia32x64_register_64bit_to_ir(EFI_CONTEXT_X64_REGISTER_STATE *registers);
30void ir_ia32x64_error_info_to_cper(json_object *error_info, FILE *out);
31void ir_ia32x64_context_info_to_cper(json_object *context_info, FILE *out);
32void ir_ia32x64_cache_tlb_check_error_to_cper(
33 json_object *check_info,
34 EFI_IA32_X64_CACHE_CHECK_INFO *check_info_cper);
35void ir_ia32x64_bus_check_error_to_cper(
36 json_object *check_info, EFI_IA32_X64_BUS_CHECK_INFO *check_info_cper);
37void ir_ia32x64_ms_check_error_to_cper(
38 json_object *check_info, EFI_IA32_X64_MS_CHECK_INFO *check_info_cper);
39void ir_ia32x64_ia32_registers_to_cper(json_object *registers, FILE *out);
40void ir_ia32x64_x64_registers_to_cper(json_object *registers, FILE *out);
Lawrence Tangd0c88842022-07-13 14:51:17 +010041
42//////////////////
43/// CPER TO IR ///
44//////////////////
Lawrence Tang794312c2022-07-05 14:46:10 +010045
46//Converts the IA32/x64 error section described in the given descriptor into intermediate format.
Ed Tanous12dbd4f2025-03-08 19:05:01 -080047json_object *cper_section_ia32x64_to_ir(const UINT8 *section, UINT32 size)
Lawrence Tang794312c2022-07-05 14:46:10 +010048{
Ed Tanous12dbd4f2025-03-08 19:05:01 -080049 if (size < sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD)) {
50 return NULL;
51 }
Lawrence Tange407b4c2022-07-21 13:54:01 +010052 EFI_IA32_X64_PROCESSOR_ERROR_RECORD *record =
53 (EFI_IA32_X64_PROCESSOR_ERROR_RECORD *)section;
Ed Tanous12dbd4f2025-03-08 19:05:01 -080054 UINT32 remaining_size =
55 size - sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD);
Lawrence Tange407b4c2022-07-21 13:54:01 +010056 json_object *record_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +010057
Lawrence Tange407b4c2022-07-21 13:54:01 +010058 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080059 //validation bits contain information
60 //about processorErrorInfoNum and processorContextInfoNum.
61 //Ensure this is decoded properly in IR->CPER
John Chungf8fc7052024-05-03 20:05:29 +080062 int processor_error_info_num = (record->ValidFields >> 2) & 0x3F;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080063 json_object_object_add(record_ir, "processorErrorInfoNum",
Lawrence Tange407b4c2022-07-21 13:54:01 +010064 json_object_new_int(processor_error_info_num));
John Chungf8fc7052024-05-03 20:05:29 +080065 int processor_context_info_num = (record->ValidFields >> 8) & 0x3F;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080066 json_object_object_add(record_ir, "processorContextInfoNum",
Lawrence Tange407b4c2022-07-21 13:54:01 +010067 json_object_new_int(processor_context_info_num));
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080068
69 ValidationTypes ui64Type = { UINT_64T,
70 .value.ui64 = record->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +010071
Lawrence Tange407b4c2022-07-21 13:54:01 +010072 //APIC ID.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080073 if (isvalid_prop_to_ir(&ui64Type, 0)) {
74 json_object_object_add(record_ir, "localAPICID",
75 json_object_new_uint64(record->ApicId));
76 }
Lawrence Tang794312c2022-07-05 14:46:10 +010077
Lawrence Tange407b4c2022-07-21 13:54:01 +010078 //CPUID information.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080079 if (isvalid_prop_to_ir(&ui64Type, 1)) {
80 json_object *cpuid_info_ir = json_object_new_object();
81 EFI_IA32_X64_CPU_ID *cpuid_info =
82 (EFI_IA32_X64_CPU_ID *)record->CpuIdInfo;
83 json_object_object_add(cpuid_info_ir, "eax",
84 json_object_new_uint64(cpuid_info->Eax));
85 json_object_object_add(cpuid_info_ir, "ebx",
86 json_object_new_uint64(cpuid_info->Ebx));
87 json_object_object_add(cpuid_info_ir, "ecx",
88 json_object_new_uint64(cpuid_info->Ecx));
89 json_object_object_add(cpuid_info_ir, "edx",
90 json_object_new_uint64(cpuid_info->Edx));
91 json_object_object_add(record_ir, "cpuidInfo", cpuid_info_ir);
92 }
Lawrence Tang794312c2022-07-05 14:46:10 +010093
Lawrence Tange407b4c2022-07-21 13:54:01 +010094 //Processor error information, of the amount described above.
95 EFI_IA32_X64_PROCESS_ERROR_INFO *current_error_info =
96 (EFI_IA32_X64_PROCESS_ERROR_INFO *)(record + 1);
97 json_object *error_info_array = json_object_new_array();
Ed Tanous12dbd4f2025-03-08 19:05:01 -080098 if (remaining_size < (processor_error_info_num *
99 sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO))) {
100 json_object_put(error_info_array);
101 json_object_put(record_ir);
102 printf("Invalid CPER file: Invalid processor error info num.\n");
103 return NULL;
104 }
105
Lawrence Tange407b4c2022-07-21 13:54:01 +0100106 for (int i = 0; i < processor_error_info_num; i++) {
107 json_object_array_add(error_info_array,
108 cper_ia32x64_processor_error_info_to_ir(
109 current_error_info));
110 current_error_info++;
111 }
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800112 remaining_size -= processor_error_info_num *
113 sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO);
114
Lawrence Tange407b4c2022-07-21 13:54:01 +0100115 json_object_object_add(record_ir, "processorErrorInfo",
116 error_info_array);
Lawrence Tang794312c2022-07-05 14:46:10 +0100117
Lawrence Tange407b4c2022-07-21 13:54:01 +0100118 //Processor context information, of the amount described above.
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800119 if (remaining_size < (processor_context_info_num *
120 sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO))) {
121 json_object_put(error_info_array);
122 json_object_put(record_ir);
123 printf("Invalid CPER file: Invalid processor context info num.\n");
124 return NULL;
125 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100126 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *current_context_info =
127 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)current_error_info;
128 void *cur_pos = (void *)current_context_info;
129 json_object *context_info_array = json_object_new_array();
130 for (int i = 0; i < processor_context_info_num; i++) {
131 json_object_array_add(context_info_array,
132 cper_ia32x64_processor_context_info_to_ir(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800133 current_context_info, &cur_pos,
134 &remaining_size));
Lawrence Tange407b4c2022-07-21 13:54:01 +0100135 current_context_info =
136 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)cur_pos;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800137
Lawrence Tange407b4c2022-07-21 13:54:01 +0100138 //The context array is a non-fixed size, pointer is shifted within the above function.
139 }
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800140
Lawrence Tange407b4c2022-07-21 13:54:01 +0100141 json_object_object_add(record_ir, "processorContextInfo",
142 context_info_array);
Lawrence Tang794312c2022-07-05 14:46:10 +0100143
Lawrence Tange407b4c2022-07-21 13:54:01 +0100144 return record_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100145}
146
147//Converts a single IA32/x64 processor error info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100148json_object *cper_ia32x64_processor_error_info_to_ir(
149 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info)
Lawrence Tang794312c2022-07-05 14:46:10 +0100150{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100151 json_object *error_info_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100152
Lawrence Tange407b4c2022-07-21 13:54:01 +0100153 //Error structure type (as GUID).
154 char error_type[GUID_STRING_LENGTH];
155 guid_to_string(error_type, &error_info->ErrorType);
Lawrence Tang3592da72022-07-21 16:50:07 +0100156 json_object *type = json_object_new_object();
157 json_object_object_add(type, "guid",
Lawrence Tange407b4c2022-07-21 13:54:01 +0100158 json_object_new_string(error_type));
Lawrence Tang794312c2022-07-05 14:46:10 +0100159
Lawrence Tang3592da72022-07-21 16:50:07 +0100160 //Get the error structure type as a readable string.
161 const char *readable_type = "Unknown";
162 if (guid_equal(&error_info->ErrorType,
John Chungf8fc7052024-05-03 20:05:29 +0800163 &gEfiIa32x64ErrorTypeCacheCheckGuid)) {
Lawrence Tang3592da72022-07-21 16:50:07 +0100164 readable_type = "Cache Check Error";
John Chungf8fc7052024-05-03 20:05:29 +0800165 } else if (guid_equal(&error_info->ErrorType,
166 &gEfiIa32x64ErrorTypeTlbCheckGuid)) {
Lawrence Tang3592da72022-07-21 16:50:07 +0100167 readable_type = "TLB Check Error";
John Chungf8fc7052024-05-03 20:05:29 +0800168 } else if (guid_equal(&error_info->ErrorType,
169 &gEfiIa32x64ErrorTypeBusCheckGuid)) {
Lawrence Tang3592da72022-07-21 16:50:07 +0100170 readable_type = "Bus Check Error";
John Chungf8fc7052024-05-03 20:05:29 +0800171 } else if (guid_equal(&error_info->ErrorType,
172 &gEfiIa32x64ErrorTypeMsCheckGuid)) {
Lawrence Tang3592da72022-07-21 16:50:07 +0100173 readable_type = "MS Check Error";
John Chungf8fc7052024-05-03 20:05:29 +0800174 }
175 json_object_object_add(type, "name",
176 json_object_new_string(readable_type));
Lawrence Tang3592da72022-07-21 16:50:07 +0100177 json_object_object_add(error_info_ir, "type", type);
178
Lawrence Tange407b4c2022-07-21 13:54:01 +0100179 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800180 ValidationTypes ui64Type = { UINT_64T,
181 .value.ui64 = error_info->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +0100182
Lawrence Tange407b4c2022-07-21 13:54:01 +0100183 //Add the check information on a per-structure basis.
184 //Cache and TLB check information are identical, so can be equated.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800185 if (isvalid_prop_to_ir(&ui64Type, 0)) {
186 json_object *check_information = NULL;
187 if (guid_equal(&error_info->ErrorType,
188 &gEfiIa32x64ErrorTypeCacheCheckGuid) ||
189 guid_equal(&error_info->ErrorType,
190 &gEfiIa32x64ErrorTypeTlbCheckGuid)) {
191 check_information = cper_ia32x64_cache_tlb_check_to_ir(
192 (EFI_IA32_X64_CACHE_CHECK_INFO *)&error_info
193 ->CheckInfo);
194 } else if (guid_equal(&error_info->ErrorType,
195 &gEfiIa32x64ErrorTypeBusCheckGuid)) {
196 check_information = cper_ia32x64_bus_check_to_ir(
197 (EFI_IA32_X64_BUS_CHECK_INFO *)&error_info
198 ->CheckInfo);
199 } else if (guid_equal(&error_info->ErrorType,
200 &gEfiIa32x64ErrorTypeMsCheckGuid)) {
201 check_information = cper_ia32x64_ms_check_to_ir(
202 (EFI_IA32_X64_MS_CHECK_INFO *)&error_info
203 ->CheckInfo);
204
205 } else {
206 //Unknown check information.
207 printf("WARN: Invalid/unknown check information GUID found in IA32/x64 CPER section. Ignoring.\n");
208 }
209 json_object_object_add(error_info_ir, "checkInfo",
210 check_information);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100211 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100212
Lawrence Tange407b4c2022-07-21 13:54:01 +0100213 //Target, requestor, and responder identifiers.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800214 if (isvalid_prop_to_ir(&ui64Type, 1)) {
215 json_object_object_add(
216 error_info_ir, "targetAddressID",
217 json_object_new_uint64(error_info->TargetId));
218 }
219 if (isvalid_prop_to_ir(&ui64Type, 2)) {
220 json_object_object_add(
221 error_info_ir, "requestorID",
222 json_object_new_uint64(error_info->RequestorId));
223 }
224 if (isvalid_prop_to_ir(&ui64Type, 3)) {
225 json_object_object_add(
226 error_info_ir, "responderID",
227 json_object_new_uint64(error_info->ResponderId));
228 }
229 if (isvalid_prop_to_ir(&ui64Type, 4)) {
230 json_object_object_add(
231 error_info_ir, "instructionPointer",
232 json_object_new_uint64(error_info->InstructionIP));
233 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100234
Lawrence Tange407b4c2022-07-21 13:54:01 +0100235 return error_info_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100236}
237
238//Converts a single IA32/x64 cache or TLB check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100239json_object *cper_ia32x64_cache_tlb_check_to_ir(
240 EFI_IA32_X64_CACHE_CHECK_INFO *cache_tlb_check)
Lawrence Tang794312c2022-07-05 14:46:10 +0100241{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100242 json_object *cache_tlb_check_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100243
Lawrence Tange407b4c2022-07-21 13:54:01 +0100244 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800245 ValidationTypes ui64Type = {
246 UINT_64T, .value.ui64 = cache_tlb_check->ValidFields
247 };
Lawrence Tang794312c2022-07-05 14:46:10 +0100248
Lawrence Tange407b4c2022-07-21 13:54:01 +0100249 //Transaction type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800250 if (isvalid_prop_to_ir(&ui64Type, 0)) {
251 json_object *transaction_type = integer_to_readable_pair(
252 cache_tlb_check->TransactionType, 3,
253 IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
254 IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
255 "Unknown (Reserved)");
256 json_object_object_add(cache_tlb_check_ir, "transactionType",
257 transaction_type);
258 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100259
Lawrence Tange407b4c2022-07-21 13:54:01 +0100260 //Operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800261 if (isvalid_prop_to_ir(&ui64Type, 1)) {
262 json_object *operation = integer_to_readable_pair(
263 cache_tlb_check->Operation, 9,
264 IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
265 IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
266 "Unknown (Reserved)");
267 json_object_object_add(cache_tlb_check_ir, "operation",
268 operation);
269 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100270
Lawrence Tange407b4c2022-07-21 13:54:01 +0100271 //Affected cache/TLB level.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800272 if (isvalid_prop_to_ir(&ui64Type, 2)) {
273 json_object_object_add(
274 cache_tlb_check_ir, "level",
275 json_object_new_uint64(cache_tlb_check->Level));
276 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100277
Lawrence Tange407b4c2022-07-21 13:54:01 +0100278 //Miscellaneous boolean fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800279 if (isvalid_prop_to_ir(&ui64Type, 3)) {
280 json_object_object_add(
281 cache_tlb_check_ir, "processorContextCorrupt",
282 json_object_new_boolean(
283 cache_tlb_check->ContextCorrupt));
284 }
285 if (isvalid_prop_to_ir(&ui64Type, 4)) {
286 json_object_object_add(
287 cache_tlb_check_ir, "uncorrected",
288 json_object_new_boolean(
289 cache_tlb_check->ErrorUncorrected));
290 }
291 if (isvalid_prop_to_ir(&ui64Type, 5)) {
292 json_object_object_add(
293 cache_tlb_check_ir, "preciseIP",
294 json_object_new_boolean(cache_tlb_check->PreciseIp));
295 }
296 if (isvalid_prop_to_ir(&ui64Type, 6)) {
297 json_object_object_add(cache_tlb_check_ir, "restartableIP",
298 json_object_new_boolean(
299 cache_tlb_check->RestartableIp));
300 }
301 if (isvalid_prop_to_ir(&ui64Type, 7)) {
302 json_object_object_add(
303 cache_tlb_check_ir, "overflow",
304 json_object_new_boolean(cache_tlb_check->Overflow));
305 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100306
Lawrence Tange407b4c2022-07-21 13:54:01 +0100307 return cache_tlb_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100308}
309
310//Converts a single IA32/x64 bus check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100311json_object *
312cper_ia32x64_bus_check_to_ir(EFI_IA32_X64_BUS_CHECK_INFO *bus_check)
313{
314 json_object *bus_check_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100315
Lawrence Tange407b4c2022-07-21 13:54:01 +0100316 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800317 ValidationTypes ui64Type = { UINT_64T,
318 .value.ui64 = bus_check->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +0100319
Lawrence Tange407b4c2022-07-21 13:54:01 +0100320 //Transaction type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800321 if (isvalid_prop_to_ir(&ui64Type, 0)) {
322 json_object *transaction_type = integer_to_readable_pair(
323 bus_check->TransactionType, 3,
324 IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
325 IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
326 "Unknown (Reserved)");
327 json_object_object_add(bus_check_ir, "transactionType",
328 transaction_type);
329 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100330
Lawrence Tange407b4c2022-07-21 13:54:01 +0100331 //Operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800332 if (isvalid_prop_to_ir(&ui64Type, 1)) {
333 json_object *operation = integer_to_readable_pair(
334 bus_check->Operation, 9,
335 IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
336 IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
337 "Unknown (Reserved)");
338 json_object_object_add(bus_check_ir, "operation", operation);
339 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100340
Lawrence Tange407b4c2022-07-21 13:54:01 +0100341 //Affected bus level.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800342 if (isvalid_prop_to_ir(&ui64Type, 2)) {
343 json_object_object_add(
344 bus_check_ir, "level",
345 json_object_new_uint64(bus_check->Level));
346 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100347
Lawrence Tange407b4c2022-07-21 13:54:01 +0100348 //Miscellaneous boolean fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800349 if (isvalid_prop_to_ir(&ui64Type, 3)) {
350 json_object_object_add(
351 bus_check_ir, "processorContextCorrupt",
352 json_object_new_boolean(bus_check->ContextCorrupt));
353 }
354 if (isvalid_prop_to_ir(&ui64Type, 4)) {
355 json_object_object_add(
356 bus_check_ir, "uncorrected",
357 json_object_new_boolean(bus_check->ErrorUncorrected));
358 }
359 if (isvalid_prop_to_ir(&ui64Type, 5)) {
360 json_object_object_add(
361 bus_check_ir, "preciseIP",
362 json_object_new_boolean(bus_check->PreciseIp));
363 }
364 if (isvalid_prop_to_ir(&ui64Type, 6)) {
365 json_object_object_add(
366 bus_check_ir, "restartableIP",
367 json_object_new_boolean(bus_check->RestartableIp));
368 }
369 if (isvalid_prop_to_ir(&ui64Type, 7)) {
370 json_object_object_add(
371 bus_check_ir, "overflow",
372 json_object_new_boolean(bus_check->Overflow));
373 }
374 if (isvalid_prop_to_ir(&ui64Type, 9)) {
375 json_object_object_add(
376 bus_check_ir, "timedOut",
377 json_object_new_boolean(bus_check->TimeOut));
378 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100379
Lawrence Tange407b4c2022-07-21 13:54:01 +0100380 //Participation type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800381 if (isvalid_prop_to_ir(&ui64Type, 8)) {
382 json_object *participation_type = integer_to_readable_pair(
383 bus_check->ParticipationType, 4,
384 IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_KEYS,
385 IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_VALUES,
386 "Unknown");
387 json_object_object_add(bus_check_ir, "participationType",
388 participation_type);
389 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100390
Lawrence Tange407b4c2022-07-21 13:54:01 +0100391 //Address space.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800392 if (isvalid_prop_to_ir(&ui64Type, 10)) {
393 json_object *address_space = integer_to_readable_pair(
394 bus_check->AddressSpace, 4,
395 IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_KEYS,
396 IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_VALUES,
397 "Unknown");
398 json_object_object_add(bus_check_ir, "addressSpace",
399 address_space);
400 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100401
402 return bus_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100403}
404
405//Converts a single IA32/x64 MS check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100406json_object *cper_ia32x64_ms_check_to_ir(EFI_IA32_X64_MS_CHECK_INFO *ms_check)
Lawrence Tang794312c2022-07-05 14:46:10 +0100407{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100408 json_object *ms_check_ir = json_object_new_object();
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800409 ValidationTypes ui64Type = { UINT_64T,
410 .value.ui64 = ms_check->ValidFields };
Lawrence Tange407b4c2022-07-21 13:54:01 +0100411 //Validation bits.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100412 //Error type (operation that caused the error).
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800413 if (isvalid_prop_to_ir(&ui64Type, 0)) {
414 json_object *error_type = integer_to_readable_pair(
415 ms_check->ErrorType, 4,
416 IA32X64_MS_CHECK_INFO_ERROR_TYPES_KEYS,
417 IA32X64_MS_CHECK_INFO_ERROR_TYPES_VALUES,
418 "Unknown (Processor Specific)");
419 json_object_object_add(ms_check_ir, "errorType", error_type);
420 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100421
Lawrence Tange407b4c2022-07-21 13:54:01 +0100422 //Miscellaneous fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800423 if (isvalid_prop_to_ir(&ui64Type, 1)) {
424 json_object_object_add(
425 ms_check_ir, "processorContextCorrupt",
426 json_object_new_boolean(ms_check->ContextCorrupt));
427 }
428 if (isvalid_prop_to_ir(&ui64Type, 2)) {
429 json_object_object_add(
430 ms_check_ir, "uncorrected",
431 json_object_new_boolean(ms_check->ErrorUncorrected));
432 }
433 if (isvalid_prop_to_ir(&ui64Type, 3)) {
434 json_object_object_add(
435 ms_check_ir, "preciseIP",
436 json_object_new_boolean(ms_check->PreciseIp));
437 }
438 if (isvalid_prop_to_ir(&ui64Type, 4)) {
439 json_object_object_add(
440 ms_check_ir, "restartableIP",
441 json_object_new_boolean(ms_check->RestartableIp));
442 }
443 if (isvalid_prop_to_ir(&ui64Type, 5)) {
444 json_object_object_add(
445 ms_check_ir, "overflow",
446 json_object_new_boolean(ms_check->Overflow));
447 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100448
449 return ms_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100450}
451
452//Converts a single IA32/x64 processor context info entry into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100453json_object *cper_ia32x64_processor_context_info_to_ir(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800454 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos,
455 UINT32 *remaining_size)
Lawrence Tang794312c2022-07-05 14:46:10 +0100456{
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800457 if (*remaining_size < sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO)) {
458 return NULL;
459 }
460 *remaining_size -= sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100461 json_object *context_info_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100462
Lawrence Tange407b4c2022-07-21 13:54:01 +0100463 //Register context type.
464 json_object *context_type = integer_to_readable_pair(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800465 context_info->RegisterType, IA32X64_REGISTER_CONTEXT_TYPES_SIZE,
Lawrence Tange407b4c2022-07-21 13:54:01 +0100466 IA32X64_REGISTER_CONTEXT_TYPES_KEYS,
467 IA32X64_REGISTER_CONTEXT_TYPES_VALUES, "Unknown (Reserved)");
468 json_object_object_add(context_info_ir, "registerContextType",
469 context_type);
Lawrence Tang794312c2022-07-05 14:46:10 +0100470
Lawrence Tange407b4c2022-07-21 13:54:01 +0100471 //Register array size, MSR and MM address.
472 json_object_object_add(context_info_ir, "registerArraySize",
473 json_object_new_uint64(context_info->ArraySize));
474 json_object_object_add(
475 context_info_ir, "msrAddress",
476 json_object_new_uint64(context_info->MsrAddress));
477 json_object_object_add(
478 context_info_ir, "mmRegisterAddress",
479 json_object_new_uint64(context_info->MmRegisterAddress));
Lawrence Tang794312c2022-07-05 14:46:10 +0100480
Lawrence Tange407b4c2022-07-21 13:54:01 +0100481 //Register array.
482 json_object *register_array = NULL;
483 if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800484 if (*remaining_size < sizeof(EFI_CONTEXT_IA32_REGISTER_STATE)) {
485 json_object_put(context_info_ir);
486 return NULL;
487 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100488 EFI_CONTEXT_IA32_REGISTER_STATE *register_state =
489 (EFI_CONTEXT_IA32_REGISTER_STATE *)(context_info + 1);
490 register_array =
491 cper_ia32x64_register_32bit_to_ir(register_state);
492 *cur_pos = (void *)(register_state + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800493 *remaining_size -= sizeof(EFI_CONTEXT_IA32_REGISTER_STATE);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100494 } else if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_X64) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800495 if (*remaining_size < sizeof(EFI_CONTEXT_X64_REGISTER_STATE)) {
496 json_object_put(context_info_ir);
497 return NULL;
498 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100499 EFI_CONTEXT_X64_REGISTER_STATE *register_state =
500 (EFI_CONTEXT_X64_REGISTER_STATE *)(context_info + 1);
501 register_array =
502 cper_ia32x64_register_64bit_to_ir(register_state);
503 *cur_pos = (void *)(register_state + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800504 *remaining_size -= sizeof(EFI_CONTEXT_X64_REGISTER_STATE);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100505 } else {
506 //No parseable data, just dump as base64 and shift the head to the next item.
507 *cur_pos = (void *)(context_info + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800508 if (*remaining_size < context_info->ArraySize) {
509 json_object_put(context_info_ir);
510 return NULL;
511 }
Ed Tanousa7d2cdd2024-07-15 11:07:27 -0700512 int32_t encoded_len = 0;
513 char *encoded = base64_encode((UINT8 *)*cur_pos,
514 context_info->ArraySize,
515 &encoded_len);
516 if (encoded == NULL) {
John Chungf8fc7052024-05-03 20:05:29 +0800517 printf("Failed to allocate encode output buffer. \n");
518 } else {
John Chungf8fc7052024-05-03 20:05:29 +0800519 register_array = json_object_new_object();
520 json_object_object_add(register_array, "data",
521 json_object_new_string_len(
522 encoded, encoded_len));
523 free(encoded);
524 }
Lawrence Tangd7e8ca32022-07-07 10:25:53 +0100525
Lawrence Tange407b4c2022-07-21 13:54:01 +0100526 *cur_pos =
527 (void *)(((char *)*cur_pos) + context_info->ArraySize);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800528 *remaining_size -= context_info->ArraySize;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100529 }
530 json_object_object_add(context_info_ir, "registerArray",
531 register_array);
Lawrence Tang794312c2022-07-05 14:46:10 +0100532
Lawrence Tange407b4c2022-07-21 13:54:01 +0100533 return context_info_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100534}
535
536//Converts a single CPER IA32 register state into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100537json_object *
538cper_ia32x64_register_32bit_to_ir(EFI_CONTEXT_IA32_REGISTER_STATE *registers)
Lawrence Tang794312c2022-07-05 14:46:10 +0100539{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100540 json_object *ia32_registers = json_object_new_object();
541 json_object_object_add(ia32_registers, "eax",
542 json_object_new_uint64(registers->Eax));
543 json_object_object_add(ia32_registers, "ebx",
544 json_object_new_uint64(registers->Ebx));
545 json_object_object_add(ia32_registers, "ecx",
546 json_object_new_uint64(registers->Ecx));
547 json_object_object_add(ia32_registers, "edx",
548 json_object_new_uint64(registers->Edx));
549 json_object_object_add(ia32_registers, "esi",
550 json_object_new_uint64(registers->Esi));
551 json_object_object_add(ia32_registers, "edi",
552 json_object_new_uint64(registers->Edi));
553 json_object_object_add(ia32_registers, "ebp",
554 json_object_new_uint64(registers->Ebp));
555 json_object_object_add(ia32_registers, "esp",
556 json_object_new_uint64(registers->Esp));
557 json_object_object_add(ia32_registers, "cs",
558 json_object_new_uint64(registers->Cs));
559 json_object_object_add(ia32_registers, "ds",
560 json_object_new_uint64(registers->Ds));
561 json_object_object_add(ia32_registers, "ss",
562 json_object_new_uint64(registers->Ss));
563 json_object_object_add(ia32_registers, "es",
564 json_object_new_uint64(registers->Es));
565 json_object_object_add(ia32_registers, "fs",
566 json_object_new_uint64(registers->Fs));
567 json_object_object_add(ia32_registers, "gs",
568 json_object_new_uint64(registers->Gs));
569 json_object_object_add(ia32_registers, "eflags",
570 json_object_new_uint64(registers->Eflags));
571 json_object_object_add(ia32_registers, "eip",
572 json_object_new_uint64(registers->Eip));
573 json_object_object_add(ia32_registers, "cr0",
574 json_object_new_uint64(registers->Cr0));
575 json_object_object_add(ia32_registers, "cr1",
576 json_object_new_uint64(registers->Cr1));
577 json_object_object_add(ia32_registers, "cr2",
578 json_object_new_uint64(registers->Cr2));
579 json_object_object_add(ia32_registers, "cr3",
580 json_object_new_uint64(registers->Cr3));
581 json_object_object_add(ia32_registers, "cr4",
582 json_object_new_uint64(registers->Cr4));
583 json_object_object_add(
584 ia32_registers, "gdtr",
585 json_object_new_uint64(registers->Gdtr[0] +
586 ((UINT64)registers->Gdtr[1] << 32)));
587 json_object_object_add(
588 ia32_registers, "idtr",
589 json_object_new_uint64(registers->Idtr[0] +
590 ((UINT64)registers->Idtr[1] << 32)));
591 json_object_object_add(ia32_registers, "ldtr",
592 json_object_new_uint64(registers->Ldtr));
593 json_object_object_add(ia32_registers, "tr",
594 json_object_new_uint64(registers->Tr));
Lawrence Tang794312c2022-07-05 14:46:10 +0100595
Lawrence Tange407b4c2022-07-21 13:54:01 +0100596 return ia32_registers;
Lawrence Tang794312c2022-07-05 14:46:10 +0100597}
598
599//Converts a single CPER x64 register state into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100600json_object *
601cper_ia32x64_register_64bit_to_ir(EFI_CONTEXT_X64_REGISTER_STATE *registers)
Lawrence Tang794312c2022-07-05 14:46:10 +0100602{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100603 json_object *x64_registers = json_object_new_object();
604 json_object_object_add(x64_registers, "rax",
605 json_object_new_uint64(registers->Rax));
606 json_object_object_add(x64_registers, "rbx",
607 json_object_new_uint64(registers->Rbx));
608 json_object_object_add(x64_registers, "rcx",
609 json_object_new_uint64(registers->Rcx));
610 json_object_object_add(x64_registers, "rdx",
611 json_object_new_uint64(registers->Rdx));
612 json_object_object_add(x64_registers, "rsi",
613 json_object_new_uint64(registers->Rsi));
614 json_object_object_add(x64_registers, "rdi",
615 json_object_new_uint64(registers->Rdi));
616 json_object_object_add(x64_registers, "rbp",
617 json_object_new_uint64(registers->Rbp));
618 json_object_object_add(x64_registers, "rsp",
619 json_object_new_uint64(registers->Rsp));
620 json_object_object_add(x64_registers, "r8",
621 json_object_new_uint64(registers->R8));
622 json_object_object_add(x64_registers, "r9",
623 json_object_new_uint64(registers->R9));
624 json_object_object_add(x64_registers, "r10",
625 json_object_new_uint64(registers->R10));
626 json_object_object_add(x64_registers, "r11",
627 json_object_new_uint64(registers->R11));
628 json_object_object_add(x64_registers, "r12",
629 json_object_new_uint64(registers->R12));
630 json_object_object_add(x64_registers, "r13",
631 json_object_new_uint64(registers->R13));
632 json_object_object_add(x64_registers, "r14",
633 json_object_new_uint64(registers->R14));
634 json_object_object_add(x64_registers, "r15",
635 json_object_new_uint64(registers->R15));
636 json_object_object_add(x64_registers, "cs",
637 json_object_new_int(registers->Cs));
638 json_object_object_add(x64_registers, "ds",
639 json_object_new_int(registers->Ds));
640 json_object_object_add(x64_registers, "ss",
641 json_object_new_int(registers->Ss));
642 json_object_object_add(x64_registers, "es",
643 json_object_new_int(registers->Es));
644 json_object_object_add(x64_registers, "fs",
645 json_object_new_int(registers->Fs));
646 json_object_object_add(x64_registers, "gs",
647 json_object_new_int(registers->Gs));
648 json_object_object_add(x64_registers, "rflags",
649 json_object_new_uint64(registers->Rflags));
650 json_object_object_add(x64_registers, "eip",
651 json_object_new_uint64(registers->Rip));
652 json_object_object_add(x64_registers, "cr0",
653 json_object_new_uint64(registers->Cr0));
654 json_object_object_add(x64_registers, "cr1",
655 json_object_new_uint64(registers->Cr1));
656 json_object_object_add(x64_registers, "cr2",
657 json_object_new_uint64(registers->Cr2));
658 json_object_object_add(x64_registers, "cr3",
659 json_object_new_uint64(registers->Cr3));
660 json_object_object_add(x64_registers, "cr4",
661 json_object_new_uint64(registers->Cr4));
662 json_object_object_add(x64_registers, "cr8",
663 json_object_new_uint64(registers->Cr8));
664 json_object_object_add(x64_registers, "gdtr_0",
665 json_object_new_uint64(registers->Gdtr[0]));
666 json_object_object_add(x64_registers, "gdtr_1",
667 json_object_new_uint64(registers->Gdtr[1]));
668 json_object_object_add(x64_registers, "idtr_0",
669 json_object_new_uint64(registers->Idtr[0]));
670 json_object_object_add(x64_registers, "idtr_1",
671 json_object_new_uint64(registers->Idtr[1]));
672 json_object_object_add(x64_registers, "ldtr",
673 json_object_new_int(registers->Ldtr));
674 json_object_object_add(x64_registers, "tr",
675 json_object_new_int(registers->Tr));
Lawrence Tang794312c2022-07-05 14:46:10 +0100676
Lawrence Tange407b4c2022-07-21 13:54:01 +0100677 return x64_registers;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100678}
679
680//////////////////
681/// IR TO CPER ///
682//////////////////
683
684//Converts a single IA32/x64 CPER-JSON section into CPER binary, outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100685void ir_section_ia32x64_to_cper(json_object *section, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100686{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100687 EFI_IA32_X64_PROCESSOR_ERROR_RECORD *section_cper =
688 (EFI_IA32_X64_PROCESSOR_ERROR_RECORD *)calloc(
689 1, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100690
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800691 uint64_t valid = 0x0;
692
693 int proc_error_info_num = json_object_get_int(json_object_object_get(
694 section, "processorErrorInfoNum")) &
695 0x3F;
696 int proc_ctx_info_num = json_object_get_int(json_object_object_get(
697 section, "processorContextInfoNum")) &
698 0x3F;
699 valid |= proc_error_info_num << 2;
700 valid |= proc_ctx_info_num << 8;
701
702 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = valid };
703 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100704
Lawrence Tange407b4c2022-07-21 13:54:01 +0100705 //Local APIC ID.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800706 if (json_object_object_get_ex(section, "localAPICID", &obj)) {
707 section_cper->ApicId = json_object_get_uint64(obj);
708 add_to_valid_bitfield(&ui64Type, 0);
709 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100710
Lawrence Tange407b4c2022-07-21 13:54:01 +0100711 //CPUID info.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800712 if (json_object_object_get_ex(section, "cpuidInfo", &obj)) {
713 json_object *cpuid_info = obj;
714 EFI_IA32_X64_CPU_ID *cpuid_info_cper =
715 (EFI_IA32_X64_CPU_ID *)section_cper->CpuIdInfo;
716 cpuid_info_cper->Eax = json_object_get_uint64(
717 json_object_object_get(cpuid_info, "eax"));
718 cpuid_info_cper->Ebx = json_object_get_uint64(
719 json_object_object_get(cpuid_info, "ebx"));
720 cpuid_info_cper->Ecx = json_object_get_uint64(
721 json_object_object_get(cpuid_info, "ecx"));
722 cpuid_info_cper->Edx = json_object_get_uint64(
723 json_object_object_get(cpuid_info, "edx"));
724 add_to_valid_bitfield(&ui64Type, 1);
725 }
726 section_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100727
Lawrence Tange407b4c2022-07-21 13:54:01 +0100728 //Flush the header to file before dealing w/ info sections.
729 fwrite(section_cper, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD), 1,
730 out);
731 fflush(out);
732 free(section_cper);
733
734 //Iterate and deal with sections.
735 json_object *error_info =
736 json_object_object_get(section, "processorErrorInfo");
737 json_object *context_info =
738 json_object_object_get(section, "processorContextInfo");
John Chungf8fc7052024-05-03 20:05:29 +0800739 for (int i = 0; i < proc_error_info_num; i++) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100740 ir_ia32x64_error_info_to_cper(
741 json_object_array_get_idx(error_info, i), out);
John Chungf8fc7052024-05-03 20:05:29 +0800742 }
743 for (int i = 0; i < proc_ctx_info_num; i++) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100744 ir_ia32x64_context_info_to_cper(
745 json_object_array_get_idx(context_info, i), out);
John Chungf8fc7052024-05-03 20:05:29 +0800746 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100747}
748
749//Converts a single CPER-JSON IA32/x64 error information structure into CPER binary, outputting to the
750//provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100751void ir_ia32x64_error_info_to_cper(json_object *error_info, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100752{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100753 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info_cper =
754 (EFI_IA32_X64_PROCESS_ERROR_INFO *)calloc(
755 1, sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100756
Lawrence Tange407b4c2022-07-21 13:54:01 +0100757 //Error structure type.
Lawrence Tang3592da72022-07-21 16:50:07 +0100758 json_object *type = json_object_object_get(error_info, "type");
759 string_to_guid(
760 &error_info_cper->ErrorType,
761 json_object_get_string(json_object_object_get(type, "guid")));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100762
Lawrence Tange407b4c2022-07-21 13:54:01 +0100763 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800764 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
765 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100766
Lawrence Tange407b4c2022-07-21 13:54:01 +0100767 //Check information, parsed based on the error type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800768 if (json_object_object_get_ex(error_info, "checkInfo", &obj)) {
769 json_object *check_info = obj;
770 if (guid_equal(&error_info_cper->ErrorType,
771 &gEfiIa32x64ErrorTypeCacheCheckGuid) ||
772 guid_equal(&error_info_cper->ErrorType,
773 &gEfiIa32x64ErrorTypeTlbCheckGuid)) {
774 ir_ia32x64_cache_tlb_check_error_to_cper(
775 check_info,
776 (EFI_IA32_X64_CACHE_CHECK_INFO
777 *)&error_info_cper->CheckInfo);
778 } else if (guid_equal(&error_info_cper->ErrorType,
779 &gEfiIa32x64ErrorTypeBusCheckGuid)) {
780 ir_ia32x64_bus_check_error_to_cper(
781 check_info,
782 (EFI_IA32_X64_BUS_CHECK_INFO *)&error_info_cper
783 ->CheckInfo);
784 } else if (guid_equal(&error_info_cper->ErrorType,
785 &gEfiIa32x64ErrorTypeMsCheckGuid)) {
786 ir_ia32x64_ms_check_error_to_cper(
787 check_info,
788 (EFI_IA32_X64_MS_CHECK_INFO *)&error_info_cper
789 ->CheckInfo);
790 }
791 add_to_valid_bitfield(&ui64Type, 0);
John Chungf8fc7052024-05-03 20:05:29 +0800792 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100793
Lawrence Tange407b4c2022-07-21 13:54:01 +0100794 //Miscellaneous numeric fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800795 if (json_object_object_get_ex(error_info, "targetAddressID", &obj)) {
796 error_info_cper->TargetId = json_object_get_uint64(obj);
797 add_to_valid_bitfield(&ui64Type, 1);
798 }
799 if (json_object_object_get_ex(error_info, "requestorID", &obj)) {
800 error_info_cper->RequestorId = json_object_get_uint64(obj);
801 add_to_valid_bitfield(&ui64Type, 2);
802 }
803 if (json_object_object_get_ex(error_info, "responderID", &obj)) {
804 error_info_cper->ResponderId = json_object_get_uint64(obj);
805 add_to_valid_bitfield(&ui64Type, 3);
806 }
807 if (json_object_object_get_ex(error_info, "instructionPointer", &obj)) {
808 error_info_cper->InstructionIP = json_object_get_uint64(obj);
809 add_to_valid_bitfield(&ui64Type, 4);
810 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100811
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800812 error_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100813 //Write out to stream, then free resources.
814 fwrite(error_info_cper, sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO), 1,
815 out);
816 fflush(out);
817 free(error_info_cper);
Lawrence Tangd0c88842022-07-13 14:51:17 +0100818}
819
820//Converts a single CPER-JSON IA32/x64 cache/TLB check error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100821void ir_ia32x64_cache_tlb_check_error_to_cper(
822 json_object *check_info, EFI_IA32_X64_CACHE_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100823{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100824 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800825 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
826 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100827
Lawrence Tange407b4c2022-07-21 13:54:01 +0100828 //Transaction type, operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800829 if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
830 check_info_cper->TransactionType =
831 readable_pair_to_integer(obj);
832 add_to_valid_bitfield(&ui64Type, 0);
833 }
834 if (json_object_object_get_ex(check_info, "operation", &obj)) {
835 check_info_cper->Operation = readable_pair_to_integer(obj);
836 add_to_valid_bitfield(&ui64Type, 1);
837 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100838
Lawrence Tange407b4c2022-07-21 13:54:01 +0100839 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800840 if (json_object_object_get_ex(check_info, "level", &obj)) {
841 check_info_cper->Level = json_object_get_uint64(obj);
842 add_to_valid_bitfield(&ui64Type, 2);
843 }
844 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
845 &obj)) {
846 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
847 add_to_valid_bitfield(&ui64Type, 3);
848 }
849 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
850 check_info_cper->ErrorUncorrected =
851 json_object_get_boolean(obj);
852 add_to_valid_bitfield(&ui64Type, 4);
853 }
854 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
855 check_info_cper->PreciseIp = json_object_get_boolean(obj);
856 add_to_valid_bitfield(&ui64Type, 5);
857 }
858 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
859 check_info_cper->RestartableIp = json_object_get_boolean(obj);
860 add_to_valid_bitfield(&ui64Type, 6);
861 }
862 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
863 check_info_cper->Overflow = json_object_get_boolean(obj);
864 add_to_valid_bitfield(&ui64Type, 7);
865 }
866 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100867}
868
869//Converts a single CPER-JSON IA32/x64 bus error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100870void ir_ia32x64_bus_check_error_to_cper(
871 json_object *check_info, EFI_IA32_X64_BUS_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100872{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100873 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800874 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
875 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100876
Lawrence Tange407b4c2022-07-21 13:54:01 +0100877 //Readable pair fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800878 if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
879 check_info_cper->TransactionType =
880 readable_pair_to_integer(obj);
881 add_to_valid_bitfield(&ui64Type, 0);
882 }
883 if (json_object_object_get_ex(check_info, "operation", &obj)) {
884 check_info_cper->Operation = readable_pair_to_integer(obj);
885 add_to_valid_bitfield(&ui64Type, 1);
886 }
887 if (json_object_object_get_ex(check_info, "participationType", &obj)) {
888 check_info_cper->ParticipationType =
889 readable_pair_to_integer(obj);
890 add_to_valid_bitfield(&ui64Type, 8);
891 }
892
893 if (json_object_object_get_ex(check_info, "addressSpace", &obj)) {
894 check_info_cper->AddressSpace = readable_pair_to_integer(obj);
895 add_to_valid_bitfield(&ui64Type, 10);
896 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100897
Lawrence Tange407b4c2022-07-21 13:54:01 +0100898 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800899 if (json_object_object_get_ex(check_info, "level", &obj)) {
900 check_info_cper->Level = json_object_get_uint64(obj);
901 add_to_valid_bitfield(&ui64Type, 2);
902 }
903 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
904 &obj)) {
905 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
906 add_to_valid_bitfield(&ui64Type, 3);
907 }
908 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
909 check_info_cper->ErrorUncorrected =
910 json_object_get_boolean(obj);
911 add_to_valid_bitfield(&ui64Type, 4);
912 }
913 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
914 check_info_cper->PreciseIp = json_object_get_boolean(obj);
915 add_to_valid_bitfield(&ui64Type, 5);
916 }
917 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
918 check_info_cper->RestartableIp = json_object_get_boolean(obj);
919 add_to_valid_bitfield(&ui64Type, 6);
920 }
921 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
922 check_info_cper->Overflow = json_object_get_boolean(obj);
923 add_to_valid_bitfield(&ui64Type, 7);
924 }
925 if (json_object_object_get_ex(check_info, "timedOut", &obj)) {
926 check_info_cper->TimeOut = json_object_get_boolean(obj);
927 add_to_valid_bitfield(&ui64Type, 9);
928 }
929 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100930}
931
932//Converts a single CPER-JSON IA32/x64 MS error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100933void ir_ia32x64_ms_check_error_to_cper(
934 json_object *check_info, EFI_IA32_X64_MS_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100935{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100936 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800937 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
938 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100939
Lawrence Tange407b4c2022-07-21 13:54:01 +0100940 //Type of MS check error.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800941 if (json_object_object_get_ex(check_info, "errorType", &obj)) {
942 check_info_cper->ErrorType = readable_pair_to_integer(obj);
943 add_to_valid_bitfield(&ui64Type, 0);
944 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100945
Lawrence Tange407b4c2022-07-21 13:54:01 +0100946 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800947 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
948 &obj)) {
949 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
950 add_to_valid_bitfield(&ui64Type, 1);
951 }
952 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
953 check_info_cper->ErrorUncorrected =
954 json_object_get_boolean(obj);
955 add_to_valid_bitfield(&ui64Type, 2);
956 }
957 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
958 check_info_cper->PreciseIp = json_object_get_boolean(obj);
959 add_to_valid_bitfield(&ui64Type, 3);
960 }
961 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
962 check_info_cper->RestartableIp = json_object_get_boolean(obj);
963 add_to_valid_bitfield(&ui64Type, 4);
964 }
965 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
966 check_info_cper->Overflow = json_object_get_boolean(obj);
967 add_to_valid_bitfield(&ui64Type, 5);
968 }
969 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100970}
971
972//Converts a single CPER-JSON IA32/x64 context information structure into CPER binary, outputting to the
973//provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100974void ir_ia32x64_context_info_to_cper(json_object *context_info, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100975{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100976 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info_cper =
977 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)calloc(
978 1, sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100979
Lawrence Tange407b4c2022-07-21 13:54:01 +0100980 //Register context type.
981 context_info_cper->RegisterType = (UINT16)readable_pair_to_integer(
982 json_object_object_get(context_info, "registerContextType"));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100983
Lawrence Tange407b4c2022-07-21 13:54:01 +0100984 //Miscellaneous numeric fields.
985 context_info_cper->ArraySize = (UINT16)json_object_get_uint64(
986 json_object_object_get(context_info, "registerArraySize"));
987 context_info_cper->MsrAddress = (UINT32)json_object_get_uint64(
988 json_object_object_get(context_info, "msrAddress"));
989 context_info_cper->MmRegisterAddress = json_object_get_uint64(
990 json_object_object_get(context_info, "mmRegisterAddress"));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100991
Lawrence Tange407b4c2022-07-21 13:54:01 +0100992 //Flush header to stream.
993 fwrite(context_info_cper, sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO),
994 1, out);
995 fflush(out);
Lawrence Tangd0c88842022-07-13 14:51:17 +0100996
Lawrence Tange407b4c2022-07-21 13:54:01 +0100997 //Handle the register array, depending on type provided.
998 json_object *register_array =
999 json_object_object_get(context_info, "registerArray");
1000 if (context_info_cper->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
1001 ir_ia32x64_ia32_registers_to_cper(register_array, out);
1002 } else if (context_info_cper->RegisterType ==
1003 EFI_REG_CONTEXT_TYPE_X64) {
1004 ir_ia32x64_x64_registers_to_cper(register_array, out);
1005 } else {
1006 //Unknown/structure is not defined.
1007 json_object *encoded =
1008 json_object_object_get(register_array, "data");
Ed Tanousa7d2cdd2024-07-15 11:07:27 -07001009 int32_t decoded_len = 0;
1010 const char *j_string = json_object_get_string(encoded);
1011 int j_size = json_object_get_string_len(encoded);
1012 UINT8 *decoded = base64_decode(j_string, j_size, &decoded_len);
1013 if (decoded == NULL) {
John Chungf8fc7052024-05-03 20:05:29 +08001014 printf("Failed to allocate decode output buffer. \n");
1015 } else {
John Chungf8fc7052024-05-03 20:05:29 +08001016 fwrite(decoded, decoded_len, 1, out);
1017 fflush(out);
1018 free(decoded);
1019 }
Lawrence Tange407b4c2022-07-21 13:54:01 +01001020 }
Lawrence Tangd0c88842022-07-13 14:51:17 +01001021
Lawrence Tange407b4c2022-07-21 13:54:01 +01001022 //Free remaining resources.
1023 free(context_info_cper);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001024}
1025
1026//Converts a single CPER-JSON IA32 register array into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001027void ir_ia32x64_ia32_registers_to_cper(json_object *registers, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001028{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001029 EFI_CONTEXT_IA32_REGISTER_STATE register_state;
1030 register_state.Eax = (UINT32)json_object_get_uint64(
1031 json_object_object_get(registers, "eax"));
1032 register_state.Ebx = (UINT32)json_object_get_uint64(
1033 json_object_object_get(registers, "ebx"));
1034 register_state.Ecx = (UINT32)json_object_get_uint64(
1035 json_object_object_get(registers, "ecx"));
1036 register_state.Edx = (UINT32)json_object_get_uint64(
1037 json_object_object_get(registers, "edx"));
1038 register_state.Esi = (UINT32)json_object_get_uint64(
1039 json_object_object_get(registers, "esi"));
1040 register_state.Edi = (UINT32)json_object_get_uint64(
1041 json_object_object_get(registers, "edi"));
1042 register_state.Ebp = (UINT32)json_object_get_uint64(
1043 json_object_object_get(registers, "ebp"));
1044 register_state.Esp = (UINT32)json_object_get_uint64(
1045 json_object_object_get(registers, "esp"));
1046 register_state.Cs = (UINT16)json_object_get_uint64(
1047 json_object_object_get(registers, "cs"));
1048 register_state.Ds = (UINT32)json_object_get_uint64(
1049 json_object_object_get(registers, "ds"));
1050 register_state.Ss = (UINT16)json_object_get_uint64(
1051 json_object_object_get(registers, "ss"));
1052 register_state.Es = (UINT16)json_object_get_uint64(
1053 json_object_object_get(registers, "es"));
1054 register_state.Fs = (UINT16)json_object_get_uint64(
1055 json_object_object_get(registers, "fs"));
1056 register_state.Gs = (UINT16)json_object_get_uint64(
1057 json_object_object_get(registers, "gs"));
1058 register_state.Eflags = (UINT32)json_object_get_uint64(
1059 json_object_object_get(registers, "eflags"));
1060 register_state.Eip = (UINT32)json_object_get_uint64(
1061 json_object_object_get(registers, "eip"));
1062 register_state.Cr0 = (UINT32)json_object_get_uint64(
1063 json_object_object_get(registers, "cr0"));
1064 register_state.Cr1 = (UINT32)json_object_get_uint64(
1065 json_object_object_get(registers, "cr1"));
1066 register_state.Cr2 = (UINT32)json_object_get_uint64(
1067 json_object_object_get(registers, "cr2"));
1068 register_state.Cr3 = (UINT32)json_object_get_uint64(
1069 json_object_object_get(registers, "cr3"));
1070 register_state.Cr4 = (UINT32)json_object_get_uint64(
1071 json_object_object_get(registers, "cr4"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001072
Lawrence Tange407b4c2022-07-21 13:54:01 +01001073 //64-bit registers are split into two 32-bit parts.
1074 UINT64 gdtr = json_object_get_uint64(
1075 json_object_object_get(registers, "gdtr"));
1076 register_state.Gdtr[0] = gdtr & 0xFFFFFFFF;
1077 register_state.Gdtr[1] = gdtr >> 32;
1078 UINT64 idtr = json_object_get_uint64(
1079 json_object_object_get(registers, "idtr"));
1080 register_state.Idtr[0] = idtr & 0xFFFFFFFF;
1081 register_state.Idtr[1] = idtr >> 32;
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001082
Lawrence Tange407b4c2022-07-21 13:54:01 +01001083 //16-bit registers.
1084 register_state.Ldtr = (UINT16)json_object_get_uint64(
1085 json_object_object_get(registers, "ldtr"));
1086 register_state.Tr = (UINT16)json_object_get_uint64(
1087 json_object_object_get(registers, "tr"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001088
Lawrence Tange407b4c2022-07-21 13:54:01 +01001089 //Write out to stream.
1090 fwrite(&register_state, sizeof(EFI_CONTEXT_IA32_REGISTER_STATE), 1,
1091 out);
1092 fflush(out);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001093}
1094
1095//Converts a single CPER-JSON x64 register array into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001096void ir_ia32x64_x64_registers_to_cper(json_object *registers, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001097{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001098 EFI_CONTEXT_X64_REGISTER_STATE register_state;
1099 register_state.Rax = json_object_get_uint64(
1100 json_object_object_get(registers, "rax"));
1101 register_state.Rbx = json_object_get_uint64(
1102 json_object_object_get(registers, "rbx"));
1103 register_state.Rcx = json_object_get_uint64(
1104 json_object_object_get(registers, "rcx"));
1105 register_state.Rdx = json_object_get_uint64(
1106 json_object_object_get(registers, "rdx"));
1107 register_state.Rsi = json_object_get_uint64(
1108 json_object_object_get(registers, "rsi"));
1109 register_state.Rdi = json_object_get_uint64(
1110 json_object_object_get(registers, "rdi"));
1111 register_state.Rbp = json_object_get_uint64(
1112 json_object_object_get(registers, "rbp"));
1113 register_state.Rsp = json_object_get_uint64(
1114 json_object_object_get(registers, "rsp"));
1115 register_state.R8 =
1116 json_object_get_uint64(json_object_object_get(registers, "r8"));
1117 register_state.R9 =
1118 json_object_get_uint64(json_object_object_get(registers, "r9"));
1119 register_state.R10 = json_object_get_uint64(
1120 json_object_object_get(registers, "r10"));
1121 register_state.R11 = json_object_get_uint64(
1122 json_object_object_get(registers, "r11"));
1123 register_state.R12 = json_object_get_uint64(
1124 json_object_object_get(registers, "r12"));
1125 register_state.R13 = json_object_get_uint64(
1126 json_object_object_get(registers, "r13"));
1127 register_state.R14 = json_object_get_uint64(
1128 json_object_object_get(registers, "r14"));
1129 register_state.R15 = json_object_get_uint64(
1130 json_object_object_get(registers, "r15"));
1131 register_state.Cs = (UINT16)json_object_get_int(
1132 json_object_object_get(registers, "cs"));
1133 register_state.Ds = (UINT16)json_object_get_int(
1134 json_object_object_get(registers, "ds"));
1135 register_state.Ss = (UINT16)json_object_get_int(
1136 json_object_object_get(registers, "ss"));
1137 register_state.Es = (UINT16)json_object_get_int(
1138 json_object_object_get(registers, "es"));
1139 register_state.Fs = (UINT16)json_object_get_int(
1140 json_object_object_get(registers, "fs"));
1141 register_state.Gs = (UINT16)json_object_get_int(
1142 json_object_object_get(registers, "gs"));
1143 register_state.Resv1 = 0;
1144 register_state.Rflags = json_object_get_uint64(
1145 json_object_object_get(registers, "rflags"));
1146 register_state.Rip = json_object_get_uint64(
1147 json_object_object_get(registers, "eip"));
1148 register_state.Cr0 = json_object_get_uint64(
1149 json_object_object_get(registers, "cr0"));
1150 register_state.Cr1 = json_object_get_uint64(
1151 json_object_object_get(registers, "cr1"));
1152 register_state.Cr2 = json_object_get_uint64(
1153 json_object_object_get(registers, "cr2"));
1154 register_state.Cr3 = json_object_get_uint64(
1155 json_object_object_get(registers, "cr3"));
1156 register_state.Cr4 = json_object_get_uint64(
1157 json_object_object_get(registers, "cr4"));
1158 register_state.Cr8 = json_object_get_uint64(
1159 json_object_object_get(registers, "cr8"));
1160 register_state.Gdtr[0] = json_object_get_uint64(
1161 json_object_object_get(registers, "gdtr_0"));
1162 register_state.Gdtr[1] = json_object_get_uint64(
1163 json_object_object_get(registers, "gdtr_1"));
1164 register_state.Idtr[0] = json_object_get_uint64(
1165 json_object_object_get(registers, "idtr_0"));
1166 register_state.Idtr[1] = json_object_get_uint64(
1167 json_object_object_get(registers, "idtr_1"));
1168 register_state.Ldtr = (UINT16)json_object_get_int(
1169 json_object_object_get(registers, "ldtr"));
1170 register_state.Tr = (UINT16)json_object_get_int(
1171 json_object_object_get(registers, "tr"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001172
Lawrence Tange407b4c2022-07-21 13:54:01 +01001173 //Write out to stream.
1174 fwrite(&register_state, sizeof(EFI_CONTEXT_X64_REGISTER_STATE), 1, out);
1175 fflush(out);
John Chungf8fc7052024-05-03 20:05:29 +08001176}