blob: c127e930179fbaeb778a711ebd3f5c81157d11ec [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))) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800121 json_object_put(record_ir);
122 printf("Invalid CPER file: Invalid processor context info num.\n");
123 return NULL;
124 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100125 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *current_context_info =
126 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)current_error_info;
127 void *cur_pos = (void *)current_context_info;
128 json_object *context_info_array = json_object_new_array();
129 for (int i = 0; i < processor_context_info_num; i++) {
130 json_object_array_add(context_info_array,
131 cper_ia32x64_processor_context_info_to_ir(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800132 current_context_info, &cur_pos,
133 &remaining_size));
Lawrence Tange407b4c2022-07-21 13:54:01 +0100134 current_context_info =
135 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)cur_pos;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800136
Lawrence Tange407b4c2022-07-21 13:54:01 +0100137 //The context array is a non-fixed size, pointer is shifted within the above function.
138 }
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800139
Lawrence Tange407b4c2022-07-21 13:54:01 +0100140 json_object_object_add(record_ir, "processorContextInfo",
141 context_info_array);
Lawrence Tang794312c2022-07-05 14:46:10 +0100142
Lawrence Tange407b4c2022-07-21 13:54:01 +0100143 return record_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100144}
145
146//Converts a single IA32/x64 processor error info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100147json_object *cper_ia32x64_processor_error_info_to_ir(
148 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info)
Lawrence Tang794312c2022-07-05 14:46:10 +0100149{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100150 json_object *error_info_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100151
Lawrence Tange407b4c2022-07-21 13:54:01 +0100152 //Error structure type (as GUID).
153 char error_type[GUID_STRING_LENGTH];
154 guid_to_string(error_type, &error_info->ErrorType);
Lawrence Tang3592da72022-07-21 16:50:07 +0100155 json_object *type = json_object_new_object();
156 json_object_object_add(type, "guid",
Lawrence Tange407b4c2022-07-21 13:54:01 +0100157 json_object_new_string(error_type));
Lawrence Tang794312c2022-07-05 14:46:10 +0100158
Lawrence Tang3592da72022-07-21 16:50:07 +0100159 //Get the error structure type as a readable string.
160 const char *readable_type = "Unknown";
161 if (guid_equal(&error_info->ErrorType,
John Chungf8fc7052024-05-03 20:05:29 +0800162 &gEfiIa32x64ErrorTypeCacheCheckGuid)) {
Lawrence Tang3592da72022-07-21 16:50:07 +0100163 readable_type = "Cache Check Error";
John Chungf8fc7052024-05-03 20:05:29 +0800164 } else if (guid_equal(&error_info->ErrorType,
165 &gEfiIa32x64ErrorTypeTlbCheckGuid)) {
Lawrence Tang3592da72022-07-21 16:50:07 +0100166 readable_type = "TLB Check Error";
John Chungf8fc7052024-05-03 20:05:29 +0800167 } else if (guid_equal(&error_info->ErrorType,
168 &gEfiIa32x64ErrorTypeBusCheckGuid)) {
Lawrence Tang3592da72022-07-21 16:50:07 +0100169 readable_type = "Bus Check Error";
John Chungf8fc7052024-05-03 20:05:29 +0800170 } else if (guid_equal(&error_info->ErrorType,
171 &gEfiIa32x64ErrorTypeMsCheckGuid)) {
Lawrence Tang3592da72022-07-21 16:50:07 +0100172 readable_type = "MS Check Error";
John Chungf8fc7052024-05-03 20:05:29 +0800173 }
174 json_object_object_add(type, "name",
175 json_object_new_string(readable_type));
Lawrence Tang3592da72022-07-21 16:50:07 +0100176 json_object_object_add(error_info_ir, "type", type);
177
Lawrence Tange407b4c2022-07-21 13:54:01 +0100178 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800179 ValidationTypes ui64Type = { UINT_64T,
180 .value.ui64 = error_info->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +0100181
Lawrence Tange407b4c2022-07-21 13:54:01 +0100182 //Add the check information on a per-structure basis.
183 //Cache and TLB check information are identical, so can be equated.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800184 if (isvalid_prop_to_ir(&ui64Type, 0)) {
185 json_object *check_information = NULL;
186 if (guid_equal(&error_info->ErrorType,
187 &gEfiIa32x64ErrorTypeCacheCheckGuid) ||
188 guid_equal(&error_info->ErrorType,
189 &gEfiIa32x64ErrorTypeTlbCheckGuid)) {
190 check_information = cper_ia32x64_cache_tlb_check_to_ir(
191 (EFI_IA32_X64_CACHE_CHECK_INFO *)&error_info
192 ->CheckInfo);
193 } else if (guid_equal(&error_info->ErrorType,
194 &gEfiIa32x64ErrorTypeBusCheckGuid)) {
195 check_information = cper_ia32x64_bus_check_to_ir(
196 (EFI_IA32_X64_BUS_CHECK_INFO *)&error_info
197 ->CheckInfo);
198 } else if (guid_equal(&error_info->ErrorType,
199 &gEfiIa32x64ErrorTypeMsCheckGuid)) {
200 check_information = cper_ia32x64_ms_check_to_ir(
201 (EFI_IA32_X64_MS_CHECK_INFO *)&error_info
202 ->CheckInfo);
203
204 } else {
205 //Unknown check information.
206 printf("WARN: Invalid/unknown check information GUID found in IA32/x64 CPER section. Ignoring.\n");
207 }
208 json_object_object_add(error_info_ir, "checkInfo",
209 check_information);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100210 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100211
Lawrence Tange407b4c2022-07-21 13:54:01 +0100212 //Target, requestor, and responder identifiers.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800213 if (isvalid_prop_to_ir(&ui64Type, 1)) {
214 json_object_object_add(
215 error_info_ir, "targetAddressID",
216 json_object_new_uint64(error_info->TargetId));
217 }
218 if (isvalid_prop_to_ir(&ui64Type, 2)) {
219 json_object_object_add(
220 error_info_ir, "requestorID",
221 json_object_new_uint64(error_info->RequestorId));
222 }
223 if (isvalid_prop_to_ir(&ui64Type, 3)) {
224 json_object_object_add(
225 error_info_ir, "responderID",
226 json_object_new_uint64(error_info->ResponderId));
227 }
228 if (isvalid_prop_to_ir(&ui64Type, 4)) {
229 json_object_object_add(
230 error_info_ir, "instructionPointer",
231 json_object_new_uint64(error_info->InstructionIP));
232 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100233
Lawrence Tange407b4c2022-07-21 13:54:01 +0100234 return error_info_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100235}
236
237//Converts a single IA32/x64 cache or TLB check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100238json_object *cper_ia32x64_cache_tlb_check_to_ir(
239 EFI_IA32_X64_CACHE_CHECK_INFO *cache_tlb_check)
Lawrence Tang794312c2022-07-05 14:46:10 +0100240{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100241 json_object *cache_tlb_check_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100242
Lawrence Tange407b4c2022-07-21 13:54:01 +0100243 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800244 ValidationTypes ui64Type = {
245 UINT_64T, .value.ui64 = cache_tlb_check->ValidFields
246 };
Lawrence Tang794312c2022-07-05 14:46:10 +0100247
Lawrence Tange407b4c2022-07-21 13:54:01 +0100248 //Transaction type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800249 if (isvalid_prop_to_ir(&ui64Type, 0)) {
250 json_object *transaction_type = integer_to_readable_pair(
251 cache_tlb_check->TransactionType, 3,
252 IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
253 IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
254 "Unknown (Reserved)");
255 json_object_object_add(cache_tlb_check_ir, "transactionType",
256 transaction_type);
257 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100258
Lawrence Tange407b4c2022-07-21 13:54:01 +0100259 //Operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800260 if (isvalid_prop_to_ir(&ui64Type, 1)) {
261 json_object *operation = integer_to_readable_pair(
262 cache_tlb_check->Operation, 9,
263 IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
264 IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
265 "Unknown (Reserved)");
266 json_object_object_add(cache_tlb_check_ir, "operation",
267 operation);
268 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100269
Lawrence Tange407b4c2022-07-21 13:54:01 +0100270 //Affected cache/TLB level.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800271 if (isvalid_prop_to_ir(&ui64Type, 2)) {
272 json_object_object_add(
273 cache_tlb_check_ir, "level",
274 json_object_new_uint64(cache_tlb_check->Level));
275 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100276
Lawrence Tange407b4c2022-07-21 13:54:01 +0100277 //Miscellaneous boolean fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800278 if (isvalid_prop_to_ir(&ui64Type, 3)) {
279 json_object_object_add(
280 cache_tlb_check_ir, "processorContextCorrupt",
281 json_object_new_boolean(
282 cache_tlb_check->ContextCorrupt));
283 }
284 if (isvalid_prop_to_ir(&ui64Type, 4)) {
285 json_object_object_add(
286 cache_tlb_check_ir, "uncorrected",
287 json_object_new_boolean(
288 cache_tlb_check->ErrorUncorrected));
289 }
290 if (isvalid_prop_to_ir(&ui64Type, 5)) {
291 json_object_object_add(
292 cache_tlb_check_ir, "preciseIP",
293 json_object_new_boolean(cache_tlb_check->PreciseIp));
294 }
295 if (isvalid_prop_to_ir(&ui64Type, 6)) {
296 json_object_object_add(cache_tlb_check_ir, "restartableIP",
297 json_object_new_boolean(
298 cache_tlb_check->RestartableIp));
299 }
300 if (isvalid_prop_to_ir(&ui64Type, 7)) {
301 json_object_object_add(
302 cache_tlb_check_ir, "overflow",
303 json_object_new_boolean(cache_tlb_check->Overflow));
304 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100305
Lawrence Tange407b4c2022-07-21 13:54:01 +0100306 return cache_tlb_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100307}
308
309//Converts a single IA32/x64 bus check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100310json_object *
311cper_ia32x64_bus_check_to_ir(EFI_IA32_X64_BUS_CHECK_INFO *bus_check)
312{
313 json_object *bus_check_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100314
Lawrence Tange407b4c2022-07-21 13:54:01 +0100315 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800316 ValidationTypes ui64Type = { UINT_64T,
317 .value.ui64 = bus_check->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +0100318
Lawrence Tange407b4c2022-07-21 13:54:01 +0100319 //Transaction type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800320 if (isvalid_prop_to_ir(&ui64Type, 0)) {
321 json_object *transaction_type = integer_to_readable_pair(
322 bus_check->TransactionType, 3,
323 IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
324 IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
325 "Unknown (Reserved)");
326 json_object_object_add(bus_check_ir, "transactionType",
327 transaction_type);
328 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100329
Lawrence Tange407b4c2022-07-21 13:54:01 +0100330 //Operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800331 if (isvalid_prop_to_ir(&ui64Type, 1)) {
332 json_object *operation = integer_to_readable_pair(
333 bus_check->Operation, 9,
334 IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
335 IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
336 "Unknown (Reserved)");
337 json_object_object_add(bus_check_ir, "operation", operation);
338 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100339
Lawrence Tange407b4c2022-07-21 13:54:01 +0100340 //Affected bus level.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800341 if (isvalid_prop_to_ir(&ui64Type, 2)) {
342 json_object_object_add(
343 bus_check_ir, "level",
344 json_object_new_uint64(bus_check->Level));
345 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100346
Lawrence Tange407b4c2022-07-21 13:54:01 +0100347 //Miscellaneous boolean fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800348 if (isvalid_prop_to_ir(&ui64Type, 3)) {
349 json_object_object_add(
350 bus_check_ir, "processorContextCorrupt",
351 json_object_new_boolean(bus_check->ContextCorrupt));
352 }
353 if (isvalid_prop_to_ir(&ui64Type, 4)) {
354 json_object_object_add(
355 bus_check_ir, "uncorrected",
356 json_object_new_boolean(bus_check->ErrorUncorrected));
357 }
358 if (isvalid_prop_to_ir(&ui64Type, 5)) {
359 json_object_object_add(
360 bus_check_ir, "preciseIP",
361 json_object_new_boolean(bus_check->PreciseIp));
362 }
363 if (isvalid_prop_to_ir(&ui64Type, 6)) {
364 json_object_object_add(
365 bus_check_ir, "restartableIP",
366 json_object_new_boolean(bus_check->RestartableIp));
367 }
368 if (isvalid_prop_to_ir(&ui64Type, 7)) {
369 json_object_object_add(
370 bus_check_ir, "overflow",
371 json_object_new_boolean(bus_check->Overflow));
372 }
373 if (isvalid_prop_to_ir(&ui64Type, 9)) {
374 json_object_object_add(
375 bus_check_ir, "timedOut",
376 json_object_new_boolean(bus_check->TimeOut));
377 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100378
Lawrence Tange407b4c2022-07-21 13:54:01 +0100379 //Participation type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800380 if (isvalid_prop_to_ir(&ui64Type, 8)) {
381 json_object *participation_type = integer_to_readable_pair(
382 bus_check->ParticipationType, 4,
383 IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_KEYS,
384 IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_VALUES,
385 "Unknown");
386 json_object_object_add(bus_check_ir, "participationType",
387 participation_type);
388 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100389
Lawrence Tange407b4c2022-07-21 13:54:01 +0100390 //Address space.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800391 if (isvalid_prop_to_ir(&ui64Type, 10)) {
392 json_object *address_space = integer_to_readable_pair(
393 bus_check->AddressSpace, 4,
394 IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_KEYS,
395 IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_VALUES,
396 "Unknown");
397 json_object_object_add(bus_check_ir, "addressSpace",
398 address_space);
399 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100400
401 return bus_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100402}
403
404//Converts a single IA32/x64 MS check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100405json_object *cper_ia32x64_ms_check_to_ir(EFI_IA32_X64_MS_CHECK_INFO *ms_check)
Lawrence Tang794312c2022-07-05 14:46:10 +0100406{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100407 json_object *ms_check_ir = json_object_new_object();
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800408 ValidationTypes ui64Type = { UINT_64T,
409 .value.ui64 = ms_check->ValidFields };
Lawrence Tange407b4c2022-07-21 13:54:01 +0100410 //Validation bits.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100411 //Error type (operation that caused the error).
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800412 if (isvalid_prop_to_ir(&ui64Type, 0)) {
413 json_object *error_type = integer_to_readable_pair(
414 ms_check->ErrorType, 4,
415 IA32X64_MS_CHECK_INFO_ERROR_TYPES_KEYS,
416 IA32X64_MS_CHECK_INFO_ERROR_TYPES_VALUES,
417 "Unknown (Processor Specific)");
418 json_object_object_add(ms_check_ir, "errorType", error_type);
419 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100420
Lawrence Tange407b4c2022-07-21 13:54:01 +0100421 //Miscellaneous fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800422 if (isvalid_prop_to_ir(&ui64Type, 1)) {
423 json_object_object_add(
424 ms_check_ir, "processorContextCorrupt",
425 json_object_new_boolean(ms_check->ContextCorrupt));
426 }
427 if (isvalid_prop_to_ir(&ui64Type, 2)) {
428 json_object_object_add(
429 ms_check_ir, "uncorrected",
430 json_object_new_boolean(ms_check->ErrorUncorrected));
431 }
432 if (isvalid_prop_to_ir(&ui64Type, 3)) {
433 json_object_object_add(
434 ms_check_ir, "preciseIP",
435 json_object_new_boolean(ms_check->PreciseIp));
436 }
437 if (isvalid_prop_to_ir(&ui64Type, 4)) {
438 json_object_object_add(
439 ms_check_ir, "restartableIP",
440 json_object_new_boolean(ms_check->RestartableIp));
441 }
442 if (isvalid_prop_to_ir(&ui64Type, 5)) {
443 json_object_object_add(
444 ms_check_ir, "overflow",
445 json_object_new_boolean(ms_check->Overflow));
446 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100447
448 return ms_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100449}
450
451//Converts a single IA32/x64 processor context info entry into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100452json_object *cper_ia32x64_processor_context_info_to_ir(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800453 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos,
454 UINT32 *remaining_size)
Lawrence Tang794312c2022-07-05 14:46:10 +0100455{
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800456 if (*remaining_size < sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO)) {
457 return NULL;
458 }
459 *remaining_size -= sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100460 json_object *context_info_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100461
Lawrence Tange407b4c2022-07-21 13:54:01 +0100462 //Register context type.
463 json_object *context_type = integer_to_readable_pair(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800464 context_info->RegisterType, IA32X64_REGISTER_CONTEXT_TYPES_SIZE,
Lawrence Tange407b4c2022-07-21 13:54:01 +0100465 IA32X64_REGISTER_CONTEXT_TYPES_KEYS,
466 IA32X64_REGISTER_CONTEXT_TYPES_VALUES, "Unknown (Reserved)");
467 json_object_object_add(context_info_ir, "registerContextType",
468 context_type);
Lawrence Tang794312c2022-07-05 14:46:10 +0100469
Lawrence Tange407b4c2022-07-21 13:54:01 +0100470 //Register array size, MSR and MM address.
471 json_object_object_add(context_info_ir, "registerArraySize",
472 json_object_new_uint64(context_info->ArraySize));
473 json_object_object_add(
474 context_info_ir, "msrAddress",
475 json_object_new_uint64(context_info->MsrAddress));
476 json_object_object_add(
477 context_info_ir, "mmRegisterAddress",
478 json_object_new_uint64(context_info->MmRegisterAddress));
Lawrence Tang794312c2022-07-05 14:46:10 +0100479
Lawrence Tange407b4c2022-07-21 13:54:01 +0100480 //Register array.
481 json_object *register_array = NULL;
482 if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800483 if (*remaining_size < sizeof(EFI_CONTEXT_IA32_REGISTER_STATE)) {
484 json_object_put(context_info_ir);
485 return NULL;
486 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100487 EFI_CONTEXT_IA32_REGISTER_STATE *register_state =
488 (EFI_CONTEXT_IA32_REGISTER_STATE *)(context_info + 1);
489 register_array =
490 cper_ia32x64_register_32bit_to_ir(register_state);
491 *cur_pos = (void *)(register_state + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800492 *remaining_size -= sizeof(EFI_CONTEXT_IA32_REGISTER_STATE);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100493 } else if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_X64) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800494 if (*remaining_size < sizeof(EFI_CONTEXT_X64_REGISTER_STATE)) {
495 json_object_put(context_info_ir);
496 return NULL;
497 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100498 EFI_CONTEXT_X64_REGISTER_STATE *register_state =
499 (EFI_CONTEXT_X64_REGISTER_STATE *)(context_info + 1);
500 register_array =
501 cper_ia32x64_register_64bit_to_ir(register_state);
502 *cur_pos = (void *)(register_state + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800503 *remaining_size -= sizeof(EFI_CONTEXT_X64_REGISTER_STATE);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100504 } else {
505 //No parseable data, just dump as base64 and shift the head to the next item.
506 *cur_pos = (void *)(context_info + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800507 if (*remaining_size < context_info->ArraySize) {
508 json_object_put(context_info_ir);
509 return NULL;
510 }
Ed Tanousa7d2cdd2024-07-15 11:07:27 -0700511 int32_t encoded_len = 0;
512 char *encoded = base64_encode((UINT8 *)*cur_pos,
513 context_info->ArraySize,
514 &encoded_len);
515 if (encoded == NULL) {
John Chungf8fc7052024-05-03 20:05:29 +0800516 printf("Failed to allocate encode output buffer. \n");
517 } else {
John Chungf8fc7052024-05-03 20:05:29 +0800518 register_array = json_object_new_object();
519 json_object_object_add(register_array, "data",
520 json_object_new_string_len(
521 encoded, encoded_len));
522 free(encoded);
523 }
Lawrence Tangd7e8ca32022-07-07 10:25:53 +0100524
Lawrence Tange407b4c2022-07-21 13:54:01 +0100525 *cur_pos =
526 (void *)(((char *)*cur_pos) + context_info->ArraySize);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800527 *remaining_size -= context_info->ArraySize;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100528 }
529 json_object_object_add(context_info_ir, "registerArray",
530 register_array);
Lawrence Tang794312c2022-07-05 14:46:10 +0100531
Lawrence Tange407b4c2022-07-21 13:54:01 +0100532 return context_info_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100533}
534
535//Converts a single CPER IA32 register state into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100536json_object *
537cper_ia32x64_register_32bit_to_ir(EFI_CONTEXT_IA32_REGISTER_STATE *registers)
Lawrence Tang794312c2022-07-05 14:46:10 +0100538{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100539 json_object *ia32_registers = json_object_new_object();
540 json_object_object_add(ia32_registers, "eax",
541 json_object_new_uint64(registers->Eax));
542 json_object_object_add(ia32_registers, "ebx",
543 json_object_new_uint64(registers->Ebx));
544 json_object_object_add(ia32_registers, "ecx",
545 json_object_new_uint64(registers->Ecx));
546 json_object_object_add(ia32_registers, "edx",
547 json_object_new_uint64(registers->Edx));
548 json_object_object_add(ia32_registers, "esi",
549 json_object_new_uint64(registers->Esi));
550 json_object_object_add(ia32_registers, "edi",
551 json_object_new_uint64(registers->Edi));
552 json_object_object_add(ia32_registers, "ebp",
553 json_object_new_uint64(registers->Ebp));
554 json_object_object_add(ia32_registers, "esp",
555 json_object_new_uint64(registers->Esp));
556 json_object_object_add(ia32_registers, "cs",
557 json_object_new_uint64(registers->Cs));
558 json_object_object_add(ia32_registers, "ds",
559 json_object_new_uint64(registers->Ds));
560 json_object_object_add(ia32_registers, "ss",
561 json_object_new_uint64(registers->Ss));
562 json_object_object_add(ia32_registers, "es",
563 json_object_new_uint64(registers->Es));
564 json_object_object_add(ia32_registers, "fs",
565 json_object_new_uint64(registers->Fs));
566 json_object_object_add(ia32_registers, "gs",
567 json_object_new_uint64(registers->Gs));
568 json_object_object_add(ia32_registers, "eflags",
569 json_object_new_uint64(registers->Eflags));
570 json_object_object_add(ia32_registers, "eip",
571 json_object_new_uint64(registers->Eip));
572 json_object_object_add(ia32_registers, "cr0",
573 json_object_new_uint64(registers->Cr0));
574 json_object_object_add(ia32_registers, "cr1",
575 json_object_new_uint64(registers->Cr1));
576 json_object_object_add(ia32_registers, "cr2",
577 json_object_new_uint64(registers->Cr2));
578 json_object_object_add(ia32_registers, "cr3",
579 json_object_new_uint64(registers->Cr3));
580 json_object_object_add(ia32_registers, "cr4",
581 json_object_new_uint64(registers->Cr4));
582 json_object_object_add(
583 ia32_registers, "gdtr",
584 json_object_new_uint64(registers->Gdtr[0] +
585 ((UINT64)registers->Gdtr[1] << 32)));
586 json_object_object_add(
587 ia32_registers, "idtr",
588 json_object_new_uint64(registers->Idtr[0] +
589 ((UINT64)registers->Idtr[1] << 32)));
590 json_object_object_add(ia32_registers, "ldtr",
591 json_object_new_uint64(registers->Ldtr));
592 json_object_object_add(ia32_registers, "tr",
593 json_object_new_uint64(registers->Tr));
Lawrence Tang794312c2022-07-05 14:46:10 +0100594
Lawrence Tange407b4c2022-07-21 13:54:01 +0100595 return ia32_registers;
Lawrence Tang794312c2022-07-05 14:46:10 +0100596}
597
598//Converts a single CPER x64 register state into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100599json_object *
600cper_ia32x64_register_64bit_to_ir(EFI_CONTEXT_X64_REGISTER_STATE *registers)
Lawrence Tang794312c2022-07-05 14:46:10 +0100601{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100602 json_object *x64_registers = json_object_new_object();
603 json_object_object_add(x64_registers, "rax",
604 json_object_new_uint64(registers->Rax));
605 json_object_object_add(x64_registers, "rbx",
606 json_object_new_uint64(registers->Rbx));
607 json_object_object_add(x64_registers, "rcx",
608 json_object_new_uint64(registers->Rcx));
609 json_object_object_add(x64_registers, "rdx",
610 json_object_new_uint64(registers->Rdx));
611 json_object_object_add(x64_registers, "rsi",
612 json_object_new_uint64(registers->Rsi));
613 json_object_object_add(x64_registers, "rdi",
614 json_object_new_uint64(registers->Rdi));
615 json_object_object_add(x64_registers, "rbp",
616 json_object_new_uint64(registers->Rbp));
617 json_object_object_add(x64_registers, "rsp",
618 json_object_new_uint64(registers->Rsp));
619 json_object_object_add(x64_registers, "r8",
620 json_object_new_uint64(registers->R8));
621 json_object_object_add(x64_registers, "r9",
622 json_object_new_uint64(registers->R9));
623 json_object_object_add(x64_registers, "r10",
624 json_object_new_uint64(registers->R10));
625 json_object_object_add(x64_registers, "r11",
626 json_object_new_uint64(registers->R11));
627 json_object_object_add(x64_registers, "r12",
628 json_object_new_uint64(registers->R12));
629 json_object_object_add(x64_registers, "r13",
630 json_object_new_uint64(registers->R13));
631 json_object_object_add(x64_registers, "r14",
632 json_object_new_uint64(registers->R14));
633 json_object_object_add(x64_registers, "r15",
634 json_object_new_uint64(registers->R15));
635 json_object_object_add(x64_registers, "cs",
636 json_object_new_int(registers->Cs));
637 json_object_object_add(x64_registers, "ds",
638 json_object_new_int(registers->Ds));
639 json_object_object_add(x64_registers, "ss",
640 json_object_new_int(registers->Ss));
641 json_object_object_add(x64_registers, "es",
642 json_object_new_int(registers->Es));
643 json_object_object_add(x64_registers, "fs",
644 json_object_new_int(registers->Fs));
645 json_object_object_add(x64_registers, "gs",
646 json_object_new_int(registers->Gs));
647 json_object_object_add(x64_registers, "rflags",
648 json_object_new_uint64(registers->Rflags));
649 json_object_object_add(x64_registers, "eip",
650 json_object_new_uint64(registers->Rip));
651 json_object_object_add(x64_registers, "cr0",
652 json_object_new_uint64(registers->Cr0));
653 json_object_object_add(x64_registers, "cr1",
654 json_object_new_uint64(registers->Cr1));
655 json_object_object_add(x64_registers, "cr2",
656 json_object_new_uint64(registers->Cr2));
657 json_object_object_add(x64_registers, "cr3",
658 json_object_new_uint64(registers->Cr3));
659 json_object_object_add(x64_registers, "cr4",
660 json_object_new_uint64(registers->Cr4));
661 json_object_object_add(x64_registers, "cr8",
662 json_object_new_uint64(registers->Cr8));
663 json_object_object_add(x64_registers, "gdtr_0",
664 json_object_new_uint64(registers->Gdtr[0]));
665 json_object_object_add(x64_registers, "gdtr_1",
666 json_object_new_uint64(registers->Gdtr[1]));
667 json_object_object_add(x64_registers, "idtr_0",
668 json_object_new_uint64(registers->Idtr[0]));
669 json_object_object_add(x64_registers, "idtr_1",
670 json_object_new_uint64(registers->Idtr[1]));
671 json_object_object_add(x64_registers, "ldtr",
672 json_object_new_int(registers->Ldtr));
673 json_object_object_add(x64_registers, "tr",
674 json_object_new_int(registers->Tr));
Lawrence Tang794312c2022-07-05 14:46:10 +0100675
Lawrence Tange407b4c2022-07-21 13:54:01 +0100676 return x64_registers;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100677}
678
679//////////////////
680/// IR TO CPER ///
681//////////////////
682
683//Converts a single IA32/x64 CPER-JSON section into CPER binary, outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100684void ir_section_ia32x64_to_cper(json_object *section, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100685{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100686 EFI_IA32_X64_PROCESSOR_ERROR_RECORD *section_cper =
687 (EFI_IA32_X64_PROCESSOR_ERROR_RECORD *)calloc(
688 1, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100689
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800690 uint64_t valid = 0x0;
691
692 int proc_error_info_num = json_object_get_int(json_object_object_get(
693 section, "processorErrorInfoNum")) &
694 0x3F;
695 int proc_ctx_info_num = json_object_get_int(json_object_object_get(
696 section, "processorContextInfoNum")) &
697 0x3F;
698 valid |= proc_error_info_num << 2;
699 valid |= proc_ctx_info_num << 8;
700
701 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = valid };
702 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100703
Lawrence Tange407b4c2022-07-21 13:54:01 +0100704 //Local APIC ID.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800705 if (json_object_object_get_ex(section, "localAPICID", &obj)) {
706 section_cper->ApicId = json_object_get_uint64(obj);
707 add_to_valid_bitfield(&ui64Type, 0);
708 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100709
Lawrence Tange407b4c2022-07-21 13:54:01 +0100710 //CPUID info.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800711 if (json_object_object_get_ex(section, "cpuidInfo", &obj)) {
712 json_object *cpuid_info = obj;
713 EFI_IA32_X64_CPU_ID *cpuid_info_cper =
714 (EFI_IA32_X64_CPU_ID *)section_cper->CpuIdInfo;
715 cpuid_info_cper->Eax = json_object_get_uint64(
716 json_object_object_get(cpuid_info, "eax"));
717 cpuid_info_cper->Ebx = json_object_get_uint64(
718 json_object_object_get(cpuid_info, "ebx"));
719 cpuid_info_cper->Ecx = json_object_get_uint64(
720 json_object_object_get(cpuid_info, "ecx"));
721 cpuid_info_cper->Edx = json_object_get_uint64(
722 json_object_object_get(cpuid_info, "edx"));
723 add_to_valid_bitfield(&ui64Type, 1);
724 }
725 section_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100726
Lawrence Tange407b4c2022-07-21 13:54:01 +0100727 //Flush the header to file before dealing w/ info sections.
728 fwrite(section_cper, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD), 1,
729 out);
730 fflush(out);
731 free(section_cper);
732
733 //Iterate and deal with sections.
734 json_object *error_info =
735 json_object_object_get(section, "processorErrorInfo");
736 json_object *context_info =
737 json_object_object_get(section, "processorContextInfo");
John Chungf8fc7052024-05-03 20:05:29 +0800738 for (int i = 0; i < proc_error_info_num; i++) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100739 ir_ia32x64_error_info_to_cper(
740 json_object_array_get_idx(error_info, i), out);
John Chungf8fc7052024-05-03 20:05:29 +0800741 }
742 for (int i = 0; i < proc_ctx_info_num; i++) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100743 ir_ia32x64_context_info_to_cper(
744 json_object_array_get_idx(context_info, i), out);
John Chungf8fc7052024-05-03 20:05:29 +0800745 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100746}
747
748//Converts a single CPER-JSON IA32/x64 error information structure into CPER binary, outputting to the
749//provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100750void ir_ia32x64_error_info_to_cper(json_object *error_info, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100751{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100752 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info_cper =
753 (EFI_IA32_X64_PROCESS_ERROR_INFO *)calloc(
754 1, sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100755
Lawrence Tange407b4c2022-07-21 13:54:01 +0100756 //Error structure type.
Lawrence Tang3592da72022-07-21 16:50:07 +0100757 json_object *type = json_object_object_get(error_info, "type");
758 string_to_guid(
759 &error_info_cper->ErrorType,
760 json_object_get_string(json_object_object_get(type, "guid")));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100761
Lawrence Tange407b4c2022-07-21 13:54:01 +0100762 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800763 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
764 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100765
Lawrence Tange407b4c2022-07-21 13:54:01 +0100766 //Check information, parsed based on the error type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800767 if (json_object_object_get_ex(error_info, "checkInfo", &obj)) {
768 json_object *check_info = obj;
769 if (guid_equal(&error_info_cper->ErrorType,
770 &gEfiIa32x64ErrorTypeCacheCheckGuid) ||
771 guid_equal(&error_info_cper->ErrorType,
772 &gEfiIa32x64ErrorTypeTlbCheckGuid)) {
773 ir_ia32x64_cache_tlb_check_error_to_cper(
774 check_info,
775 (EFI_IA32_X64_CACHE_CHECK_INFO
776 *)&error_info_cper->CheckInfo);
777 } else if (guid_equal(&error_info_cper->ErrorType,
778 &gEfiIa32x64ErrorTypeBusCheckGuid)) {
779 ir_ia32x64_bus_check_error_to_cper(
780 check_info,
781 (EFI_IA32_X64_BUS_CHECK_INFO *)&error_info_cper
782 ->CheckInfo);
783 } else if (guid_equal(&error_info_cper->ErrorType,
784 &gEfiIa32x64ErrorTypeMsCheckGuid)) {
785 ir_ia32x64_ms_check_error_to_cper(
786 check_info,
787 (EFI_IA32_X64_MS_CHECK_INFO *)&error_info_cper
788 ->CheckInfo);
789 }
790 add_to_valid_bitfield(&ui64Type, 0);
John Chungf8fc7052024-05-03 20:05:29 +0800791 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100792
Lawrence Tange407b4c2022-07-21 13:54:01 +0100793 //Miscellaneous numeric fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800794 if (json_object_object_get_ex(error_info, "targetAddressID", &obj)) {
795 error_info_cper->TargetId = json_object_get_uint64(obj);
796 add_to_valid_bitfield(&ui64Type, 1);
797 }
798 if (json_object_object_get_ex(error_info, "requestorID", &obj)) {
799 error_info_cper->RequestorId = json_object_get_uint64(obj);
800 add_to_valid_bitfield(&ui64Type, 2);
801 }
802 if (json_object_object_get_ex(error_info, "responderID", &obj)) {
803 error_info_cper->ResponderId = json_object_get_uint64(obj);
804 add_to_valid_bitfield(&ui64Type, 3);
805 }
806 if (json_object_object_get_ex(error_info, "instructionPointer", &obj)) {
807 error_info_cper->InstructionIP = json_object_get_uint64(obj);
808 add_to_valid_bitfield(&ui64Type, 4);
809 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100810
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800811 error_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100812 //Write out to stream, then free resources.
813 fwrite(error_info_cper, sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO), 1,
814 out);
815 fflush(out);
816 free(error_info_cper);
Lawrence Tangd0c88842022-07-13 14:51:17 +0100817}
818
819//Converts a single CPER-JSON IA32/x64 cache/TLB check error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100820void ir_ia32x64_cache_tlb_check_error_to_cper(
821 json_object *check_info, EFI_IA32_X64_CACHE_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100822{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100823 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800824 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
825 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100826
Lawrence Tange407b4c2022-07-21 13:54:01 +0100827 //Transaction type, operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800828 if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
829 check_info_cper->TransactionType =
830 readable_pair_to_integer(obj);
831 add_to_valid_bitfield(&ui64Type, 0);
832 }
833 if (json_object_object_get_ex(check_info, "operation", &obj)) {
834 check_info_cper->Operation = readable_pair_to_integer(obj);
835 add_to_valid_bitfield(&ui64Type, 1);
836 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100837
Lawrence Tange407b4c2022-07-21 13:54:01 +0100838 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800839 if (json_object_object_get_ex(check_info, "level", &obj)) {
840 check_info_cper->Level = json_object_get_uint64(obj);
841 add_to_valid_bitfield(&ui64Type, 2);
842 }
843 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
844 &obj)) {
845 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
846 add_to_valid_bitfield(&ui64Type, 3);
847 }
848 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
849 check_info_cper->ErrorUncorrected =
850 json_object_get_boolean(obj);
851 add_to_valid_bitfield(&ui64Type, 4);
852 }
853 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
854 check_info_cper->PreciseIp = json_object_get_boolean(obj);
855 add_to_valid_bitfield(&ui64Type, 5);
856 }
857 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
858 check_info_cper->RestartableIp = json_object_get_boolean(obj);
859 add_to_valid_bitfield(&ui64Type, 6);
860 }
861 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
862 check_info_cper->Overflow = json_object_get_boolean(obj);
863 add_to_valid_bitfield(&ui64Type, 7);
864 }
865 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100866}
867
868//Converts a single CPER-JSON IA32/x64 bus error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100869void ir_ia32x64_bus_check_error_to_cper(
870 json_object *check_info, EFI_IA32_X64_BUS_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100871{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100872 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800873 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
874 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100875
Lawrence Tange407b4c2022-07-21 13:54:01 +0100876 //Readable pair fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800877 if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
878 check_info_cper->TransactionType =
879 readable_pair_to_integer(obj);
880 add_to_valid_bitfield(&ui64Type, 0);
881 }
882 if (json_object_object_get_ex(check_info, "operation", &obj)) {
883 check_info_cper->Operation = readable_pair_to_integer(obj);
884 add_to_valid_bitfield(&ui64Type, 1);
885 }
886 if (json_object_object_get_ex(check_info, "participationType", &obj)) {
887 check_info_cper->ParticipationType =
888 readable_pair_to_integer(obj);
889 add_to_valid_bitfield(&ui64Type, 8);
890 }
891
892 if (json_object_object_get_ex(check_info, "addressSpace", &obj)) {
893 check_info_cper->AddressSpace = readable_pair_to_integer(obj);
894 add_to_valid_bitfield(&ui64Type, 10);
895 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100896
Lawrence Tange407b4c2022-07-21 13:54:01 +0100897 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800898 if (json_object_object_get_ex(check_info, "level", &obj)) {
899 check_info_cper->Level = json_object_get_uint64(obj);
900 add_to_valid_bitfield(&ui64Type, 2);
901 }
902 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
903 &obj)) {
904 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
905 add_to_valid_bitfield(&ui64Type, 3);
906 }
907 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
908 check_info_cper->ErrorUncorrected =
909 json_object_get_boolean(obj);
910 add_to_valid_bitfield(&ui64Type, 4);
911 }
912 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
913 check_info_cper->PreciseIp = json_object_get_boolean(obj);
914 add_to_valid_bitfield(&ui64Type, 5);
915 }
916 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
917 check_info_cper->RestartableIp = json_object_get_boolean(obj);
918 add_to_valid_bitfield(&ui64Type, 6);
919 }
920 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
921 check_info_cper->Overflow = json_object_get_boolean(obj);
922 add_to_valid_bitfield(&ui64Type, 7);
923 }
924 if (json_object_object_get_ex(check_info, "timedOut", &obj)) {
925 check_info_cper->TimeOut = json_object_get_boolean(obj);
926 add_to_valid_bitfield(&ui64Type, 9);
927 }
928 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100929}
930
931//Converts a single CPER-JSON IA32/x64 MS error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100932void ir_ia32x64_ms_check_error_to_cper(
933 json_object *check_info, EFI_IA32_X64_MS_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100934{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100935 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800936 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
937 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100938
Lawrence Tange407b4c2022-07-21 13:54:01 +0100939 //Type of MS check error.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800940 if (json_object_object_get_ex(check_info, "errorType", &obj)) {
941 check_info_cper->ErrorType = readable_pair_to_integer(obj);
942 add_to_valid_bitfield(&ui64Type, 0);
943 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100944
Lawrence Tange407b4c2022-07-21 13:54:01 +0100945 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800946 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
947 &obj)) {
948 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
949 add_to_valid_bitfield(&ui64Type, 1);
950 }
951 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
952 check_info_cper->ErrorUncorrected =
953 json_object_get_boolean(obj);
954 add_to_valid_bitfield(&ui64Type, 2);
955 }
956 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
957 check_info_cper->PreciseIp = json_object_get_boolean(obj);
958 add_to_valid_bitfield(&ui64Type, 3);
959 }
960 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
961 check_info_cper->RestartableIp = json_object_get_boolean(obj);
962 add_to_valid_bitfield(&ui64Type, 4);
963 }
964 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
965 check_info_cper->Overflow = json_object_get_boolean(obj);
966 add_to_valid_bitfield(&ui64Type, 5);
967 }
968 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100969}
970
971//Converts a single CPER-JSON IA32/x64 context information structure into CPER binary, outputting to the
972//provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100973void ir_ia32x64_context_info_to_cper(json_object *context_info, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100974{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100975 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info_cper =
976 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)calloc(
977 1, sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100978
Lawrence Tange407b4c2022-07-21 13:54:01 +0100979 //Register context type.
980 context_info_cper->RegisterType = (UINT16)readable_pair_to_integer(
981 json_object_object_get(context_info, "registerContextType"));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100982
Lawrence Tange407b4c2022-07-21 13:54:01 +0100983 //Miscellaneous numeric fields.
984 context_info_cper->ArraySize = (UINT16)json_object_get_uint64(
985 json_object_object_get(context_info, "registerArraySize"));
986 context_info_cper->MsrAddress = (UINT32)json_object_get_uint64(
987 json_object_object_get(context_info, "msrAddress"));
988 context_info_cper->MmRegisterAddress = json_object_get_uint64(
989 json_object_object_get(context_info, "mmRegisterAddress"));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100990
Lawrence Tange407b4c2022-07-21 13:54:01 +0100991 //Flush header to stream.
992 fwrite(context_info_cper, sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO),
993 1, out);
994 fflush(out);
Lawrence Tangd0c88842022-07-13 14:51:17 +0100995
Lawrence Tange407b4c2022-07-21 13:54:01 +0100996 //Handle the register array, depending on type provided.
997 json_object *register_array =
998 json_object_object_get(context_info, "registerArray");
999 if (context_info_cper->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
1000 ir_ia32x64_ia32_registers_to_cper(register_array, out);
1001 } else if (context_info_cper->RegisterType ==
1002 EFI_REG_CONTEXT_TYPE_X64) {
1003 ir_ia32x64_x64_registers_to_cper(register_array, out);
1004 } else {
1005 //Unknown/structure is not defined.
1006 json_object *encoded =
1007 json_object_object_get(register_array, "data");
Ed Tanousa7d2cdd2024-07-15 11:07:27 -07001008 int32_t decoded_len = 0;
1009 const char *j_string = json_object_get_string(encoded);
1010 int j_size = json_object_get_string_len(encoded);
1011 UINT8 *decoded = base64_decode(j_string, j_size, &decoded_len);
1012 if (decoded == NULL) {
John Chungf8fc7052024-05-03 20:05:29 +08001013 printf("Failed to allocate decode output buffer. \n");
1014 } else {
John Chungf8fc7052024-05-03 20:05:29 +08001015 fwrite(decoded, decoded_len, 1, out);
1016 fflush(out);
1017 free(decoded);
1018 }
Lawrence Tange407b4c2022-07-21 13:54:01 +01001019 }
Lawrence Tangd0c88842022-07-13 14:51:17 +01001020
Lawrence Tange407b4c2022-07-21 13:54:01 +01001021 //Free remaining resources.
1022 free(context_info_cper);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001023}
1024
1025//Converts a single CPER-JSON IA32 register array into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001026void ir_ia32x64_ia32_registers_to_cper(json_object *registers, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001027{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001028 EFI_CONTEXT_IA32_REGISTER_STATE register_state;
1029 register_state.Eax = (UINT32)json_object_get_uint64(
1030 json_object_object_get(registers, "eax"));
1031 register_state.Ebx = (UINT32)json_object_get_uint64(
1032 json_object_object_get(registers, "ebx"));
1033 register_state.Ecx = (UINT32)json_object_get_uint64(
1034 json_object_object_get(registers, "ecx"));
1035 register_state.Edx = (UINT32)json_object_get_uint64(
1036 json_object_object_get(registers, "edx"));
1037 register_state.Esi = (UINT32)json_object_get_uint64(
1038 json_object_object_get(registers, "esi"));
1039 register_state.Edi = (UINT32)json_object_get_uint64(
1040 json_object_object_get(registers, "edi"));
1041 register_state.Ebp = (UINT32)json_object_get_uint64(
1042 json_object_object_get(registers, "ebp"));
1043 register_state.Esp = (UINT32)json_object_get_uint64(
1044 json_object_object_get(registers, "esp"));
1045 register_state.Cs = (UINT16)json_object_get_uint64(
1046 json_object_object_get(registers, "cs"));
1047 register_state.Ds = (UINT32)json_object_get_uint64(
1048 json_object_object_get(registers, "ds"));
1049 register_state.Ss = (UINT16)json_object_get_uint64(
1050 json_object_object_get(registers, "ss"));
1051 register_state.Es = (UINT16)json_object_get_uint64(
1052 json_object_object_get(registers, "es"));
1053 register_state.Fs = (UINT16)json_object_get_uint64(
1054 json_object_object_get(registers, "fs"));
1055 register_state.Gs = (UINT16)json_object_get_uint64(
1056 json_object_object_get(registers, "gs"));
1057 register_state.Eflags = (UINT32)json_object_get_uint64(
1058 json_object_object_get(registers, "eflags"));
1059 register_state.Eip = (UINT32)json_object_get_uint64(
1060 json_object_object_get(registers, "eip"));
1061 register_state.Cr0 = (UINT32)json_object_get_uint64(
1062 json_object_object_get(registers, "cr0"));
1063 register_state.Cr1 = (UINT32)json_object_get_uint64(
1064 json_object_object_get(registers, "cr1"));
1065 register_state.Cr2 = (UINT32)json_object_get_uint64(
1066 json_object_object_get(registers, "cr2"));
1067 register_state.Cr3 = (UINT32)json_object_get_uint64(
1068 json_object_object_get(registers, "cr3"));
1069 register_state.Cr4 = (UINT32)json_object_get_uint64(
1070 json_object_object_get(registers, "cr4"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001071
Lawrence Tange407b4c2022-07-21 13:54:01 +01001072 //64-bit registers are split into two 32-bit parts.
1073 UINT64 gdtr = json_object_get_uint64(
1074 json_object_object_get(registers, "gdtr"));
1075 register_state.Gdtr[0] = gdtr & 0xFFFFFFFF;
1076 register_state.Gdtr[1] = gdtr >> 32;
1077 UINT64 idtr = json_object_get_uint64(
1078 json_object_object_get(registers, "idtr"));
1079 register_state.Idtr[0] = idtr & 0xFFFFFFFF;
1080 register_state.Idtr[1] = idtr >> 32;
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001081
Lawrence Tange407b4c2022-07-21 13:54:01 +01001082 //16-bit registers.
1083 register_state.Ldtr = (UINT16)json_object_get_uint64(
1084 json_object_object_get(registers, "ldtr"));
1085 register_state.Tr = (UINT16)json_object_get_uint64(
1086 json_object_object_get(registers, "tr"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001087
Lawrence Tange407b4c2022-07-21 13:54:01 +01001088 //Write out to stream.
1089 fwrite(&register_state, sizeof(EFI_CONTEXT_IA32_REGISTER_STATE), 1,
1090 out);
1091 fflush(out);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001092}
1093
1094//Converts a single CPER-JSON x64 register array into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001095void ir_ia32x64_x64_registers_to_cper(json_object *registers, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001096{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001097 EFI_CONTEXT_X64_REGISTER_STATE register_state;
1098 register_state.Rax = json_object_get_uint64(
1099 json_object_object_get(registers, "rax"));
1100 register_state.Rbx = json_object_get_uint64(
1101 json_object_object_get(registers, "rbx"));
1102 register_state.Rcx = json_object_get_uint64(
1103 json_object_object_get(registers, "rcx"));
1104 register_state.Rdx = json_object_get_uint64(
1105 json_object_object_get(registers, "rdx"));
1106 register_state.Rsi = json_object_get_uint64(
1107 json_object_object_get(registers, "rsi"));
1108 register_state.Rdi = json_object_get_uint64(
1109 json_object_object_get(registers, "rdi"));
1110 register_state.Rbp = json_object_get_uint64(
1111 json_object_object_get(registers, "rbp"));
1112 register_state.Rsp = json_object_get_uint64(
1113 json_object_object_get(registers, "rsp"));
1114 register_state.R8 =
1115 json_object_get_uint64(json_object_object_get(registers, "r8"));
1116 register_state.R9 =
1117 json_object_get_uint64(json_object_object_get(registers, "r9"));
1118 register_state.R10 = json_object_get_uint64(
1119 json_object_object_get(registers, "r10"));
1120 register_state.R11 = json_object_get_uint64(
1121 json_object_object_get(registers, "r11"));
1122 register_state.R12 = json_object_get_uint64(
1123 json_object_object_get(registers, "r12"));
1124 register_state.R13 = json_object_get_uint64(
1125 json_object_object_get(registers, "r13"));
1126 register_state.R14 = json_object_get_uint64(
1127 json_object_object_get(registers, "r14"));
1128 register_state.R15 = json_object_get_uint64(
1129 json_object_object_get(registers, "r15"));
1130 register_state.Cs = (UINT16)json_object_get_int(
1131 json_object_object_get(registers, "cs"));
1132 register_state.Ds = (UINT16)json_object_get_int(
1133 json_object_object_get(registers, "ds"));
1134 register_state.Ss = (UINT16)json_object_get_int(
1135 json_object_object_get(registers, "ss"));
1136 register_state.Es = (UINT16)json_object_get_int(
1137 json_object_object_get(registers, "es"));
1138 register_state.Fs = (UINT16)json_object_get_int(
1139 json_object_object_get(registers, "fs"));
1140 register_state.Gs = (UINT16)json_object_get_int(
1141 json_object_object_get(registers, "gs"));
1142 register_state.Resv1 = 0;
1143 register_state.Rflags = json_object_get_uint64(
1144 json_object_object_get(registers, "rflags"));
1145 register_state.Rip = json_object_get_uint64(
1146 json_object_object_get(registers, "eip"));
1147 register_state.Cr0 = json_object_get_uint64(
1148 json_object_object_get(registers, "cr0"));
1149 register_state.Cr1 = json_object_get_uint64(
1150 json_object_object_get(registers, "cr1"));
1151 register_state.Cr2 = json_object_get_uint64(
1152 json_object_object_get(registers, "cr2"));
1153 register_state.Cr3 = json_object_get_uint64(
1154 json_object_object_get(registers, "cr3"));
1155 register_state.Cr4 = json_object_get_uint64(
1156 json_object_object_get(registers, "cr4"));
1157 register_state.Cr8 = json_object_get_uint64(
1158 json_object_object_get(registers, "cr8"));
1159 register_state.Gdtr[0] = json_object_get_uint64(
1160 json_object_object_get(registers, "gdtr_0"));
1161 register_state.Gdtr[1] = json_object_get_uint64(
1162 json_object_object_get(registers, "gdtr_1"));
1163 register_state.Idtr[0] = json_object_get_uint64(
1164 json_object_object_get(registers, "idtr_0"));
1165 register_state.Idtr[1] = json_object_get_uint64(
1166 json_object_object_get(registers, "idtr_1"));
1167 register_state.Ldtr = (UINT16)json_object_get_int(
1168 json_object_object_get(registers, "ldtr"));
1169 register_state.Tr = (UINT16)json_object_get_int(
1170 json_object_object_get(registers, "tr"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001171
Lawrence Tange407b4c2022-07-21 13:54:01 +01001172 //Write out to stream.
1173 fwrite(&register_state, sizeof(EFI_CONTEXT_X64_REGISTER_STATE), 1, out);
1174 fflush(out);
John Chungf8fc7052024-05-03 20:05:29 +08001175}